PEでのweakシンボルサポートを利用しようとしたが・・・

monapiの crt で

extern int init_libc _attribute__((weak));
if (init_libc) {
    init_libc();
}

のように書いておけば、libcがリンクされたときだけ init_libcで libcの初期化コードを実行できます。
weakシンボルを利用して良い方法だ!と盛り上がったのですが、採用を見送りました。


gnubinutilsの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の某スレの皆さんの御助力を頂きました。ありがとうございます。