蝉は、やがて死ぬる午後に気づいた。ああ、私たち、もっと仕合せになってよかったのだ。:2008年03月29日分

2008/03/29(Sat)

[NetBSD] tech-userlevel

64bit time_t化に伴うlibc major crunkネタ。

dholland氏のポストを超訳してみた。

まず第一に、僕らは共有ライブラリをビルドするする時
リンカに-lcフラグを与えて依存関係を記録していないんだよね。
だからこの共有ライブラリはどのlibcのバージョンとの組み合わせで
まともに動作するかなんて簡単には言えないのさ。
もっと悪いのは、正にこのことが原因で、libcのメジャー繰上げの後で
(新しいlibcで再コンパイルしてない)古いライブラリと新しいlibcをリンクして
コンパイルしたプログラムは、一見まともなようで実は壊れてるんだ。

僕らは絶対にこれは直さなきゃ、例えtime_tに関連する修正以外
なにもしないとしても、この修正は5.0に(できれば4.1も)つっこまないとダメ。
なんだけれどそれをしたからといって、この古いライブラリの
は続けて事にあたらなきゃならない。
僕らがどんな対策を(ソースツリーや配布物に)したとしても
こういうの(=古いライブラリ)は/usr/local/libなんかにもあるかもしれなくて
ユーザやシステム管理者は例えそれらを再コンパイル*できる*(できないかも)
としたって、彼らが必要性に気づかなければ忘れてそののままかもしれないじゃないか。

だから(libcを使わないので)libcへの依存関係を記録してないことが
正しいライブラリ -- 例えば何かのアプリケーションのプラグインかも
しれないけど -- なんかもあるけど、libcのメジャー繰上げ後には
これらも実際にはlibc.so.12に依存してるけど同じように記録のない
安全ではない共有ライブラリたちと、まったく同一に扱うしかなくなってしまうんだ。

続きはめんどくさいのでパス、ツール作るとか現実的でないし。

共有ライブラリが-lcなしでビルドされてようがいまいが
major crunkは賽の河原だから、本来は芋蔓で全てのshlibのmajorをcrunkしないとダメ(通称:親亀子亀)。
# libcの昨日を一切使わないshlibなら別だけども。
#それに/lib, /usr/libはまだしも/usr/pkg/libなんかは事実上無理なんだけどさ…)
だから-lcの有無は*全く*関係ないことに注意しよう。
#問題のあるライブラリの捜索には役に立つけどね。
(2008/05/29 追記)
libcやlibpthreadのようにどの共有ライブラリよりも先に.iniセクションを実行する
必要がある特別なライブラリの為に、DF_1_INITFIRSTフラグを使うような場合は
依存関係を記録しておく必要があるみたいです。
このへん参照。

そんで共有ライブラリに-lcをつけない理由はむしろウイークシンボルを使った
名前空間保護を有効にするため、libcは常に最後にリンクしないとならないから。
ここ参照。

だからdholland氏やjoerg氏が「これはバグ」といってる通りにして
共有ライブラリも-lcつきでビルドした場合、ld(1)がそれを意識して
libcのリンク順を常に最後に持ってきてくれないとおっかないことになる。
でもGNU ld(1)ってその辺だいじょうぶなんだろか?
手元で試したらダメっぽいのだが。
(2008/05/29 追記)
-lcが最初に表示されてしまうのはどうやらNetBSDのldd(1)のバグです、 ここ参照。

$ ldd libfoo.so
libfoo.so:
        -lc.12 => /usr/lib/libc.so.12
$ ldd libbar.so
libbar.so:
        -lc.12 => /usr/lib/libc.so.12
$ gcc -Wl,-rpath,./ -L. -lfoo -lbar test_foobar test_foobar.c
$ ldd test_foobar
test_foobar:
        -lc.12 => /usr/lib/libc.so.12
        -lfoo.0 => ./libfoo.so.0
        -lbar.0 => ./libbar.so.0

まあ面倒くさいことしないで__RENAME()続行 or
ELF symbol versioningでいいと思うんだけど。
# ELF化されてないportsもgcc4化でさよならしたよね?

まあ最悪

とでもすればCOMPAT_AOUTと同じ、あるいはexecveいじって
linux emulationのようなchroot環境で動かせば、問題なく
共存できる気はするけど移行手順がとてつもなく面倒くさい罠。

そろそろ

Only one ABI change in libc, in more than 15 years!

のバナー貼らね? # 1回はaout -> ELFね。