PEでのweakシンボルサポートを利用しようとしたが・・・
monapiの crt で
extern int init_libc _attribute__((weak)); if (init_libc) { init_libc(); }
のように書いておけば、libcがリンクされたときだけ init_libcで libcの初期化コードを実行できます。
weakシンボルを利用して良い方法だ!と盛り上がったのですが、採用を見送りました。
gnuのbinutilsのld/gasなどが、ライブラリ内からのweakシンボルのルックアップに対応していないので、 *.aや*.dllを利用したリンクでは weak シンボルは0になってしまうのです。
PEの規格自体では
- IMAGE_WEAK_EXTERN_SEARCH_LIBRARY・・・weak参照を外部ライブラリからでも検索する
- IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY・・・weak参照を外部ライブラリからは検索しない
の2通りがあるのですが、以下のように binutils では IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY の決め打ちのようです。
nobita% fxg "c" "IMAGE_WEAK" ./bfd/cofflink.c: characteristic IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY (1). ./gas/config/obj-coff.c: SA_SET_SYM_FSIZE (symbolP, IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY);
今回の調査では2chの某スレの皆さんの御助力を頂きました。ありがとうございます。