home ホーム search 検索 -  login ログイン  | reload edit datainfo version cmd icon diff delete  | help ヘルプ

日記/2011/04/10/uClibcを動的リンク出来ない・・・。x86(32bit)。

日記/2011/04/10/uClibcを動的リンク出来ない・・・。x86(32bit)。

日記 / 2011 / 04 / 10 / uClibcを動的リンク出来ない・・・。x86(32bit)。
id: 946 所有者: msakamoto-sf    作成日: 2011-04-10 19:46:57
カテゴリ: Linux 

CentOS5.5, x86(32bit), VMware上でここ数日、ず~っとはまってるのが uClibc で動的リンクに失敗する問題。

ret1.c:

int main(void) { return 1; }

たったこれだけ。つまり、uClibcのローダとスタートアップルーチンしか使わない最小のプログラム。

が、どうにも動かない。デバッグ有効でLD_DEBUGもONにしたところ、こんな出力が:

$ LD_DEBUG=y ./ret1_dyn
argc=1 argv=0xbfb37034 envp=0xbfb3703c
ELF header=0x363000
First Dynamic section entry=0x36aeec
Scanning DYNAMIC section
Done scanning DYNAMIC section
About to do library loader relocations
Done relocating ldso; we can now use globals and make function calls!
_dl_get_ready_to_run:317: Cool, ldso survived making function calls
_dl_malloc:194: mmapping more memory
_dl_get_ready_to_run:501: Lib Loader: (0x363000) /home/msakamoto/reduced.linux/uclibc_test/runtime/lib/ld-uClibc.so.0
_dl_get_ready_to_run:440: calling mprotect on the application program
_dl_get_ready_to_run:786:       file='libc.so.0';  needed by './ret1_dyn'
_dl_load_shared_library:212:    find library='libc.so.0'; searching
_dl_load_shared_library:289:    searching ldso dir='/home/msakamoto/reduced.linux/uclibc_test/runtime/lib'
_dl_load_elf_shared_library:803:
        file='/home/msakamoto/reduced.linux/uclibc_test/runtime/lib/libc.so.0';  generating link map
_dl_load_elf_shared_library:804:                dynamic: 0xb7f26ed8  base: 0xb7ede000
_dl_load_elf_shared_library:806:                  entry: 0xb7ee5490  phdr: 0xb7ede034  phnum: 0x8

_dl_get_ready_to_run:808: Loading: (0xb7ede000) /home/msakamoto/reduced.linux/uclibc_test/runtime/lib/libc.so.0

INIT/FINI order and dependencies:
lib: /home/msakamoto/reduced.linux/uclibc_test/runtime/lib/libc.so.0 has deps:

_dl_get_ready_to_run:948: Beginning relocation fixups
_dl_fixup:828: relocation processing: /home/msakamoto/reduced.linux/uclibc_test/runtime/lib/libc.so.0

./ret1_dyn: symbol 'stdout': can't resolve symbol in lib '/home/msakamoto/reduced.linux/uclibc_test/runtime/lib/libc.so.0'.

どうしても "symbol 'stdout': can't resolve symbol in lib ..." になってしまう。
ローダの ld-uClibc-0.9.31.so は動いているらしい。でないと上記メッセージの出力まで到達しない。
で、

/uClibc-0.9.31/ldso/elfinterp.c


static int _dl_parse(...)

の中の

res = reloc_fnc(tpnt, scope, rpnt, symtab, strtab);

これが 0 より 大きい場合に上記メッセージが出力される。0だと正常ルート、マイナス値だと "can't handle reloc type..."みたいなメッセージになる(筈)。

でreloc_fnc()とゆーのは _dl_parse() にコールバックとして渡された関数ポインタ。この中がおかしい・・・というか、まぁ自分のコンパイルオプションだのインストール先がおかしいだのでエラーになっちゃったのかも。

素直にBuildroot使えって?
Buildroot使ってみたけれど、なんでtoolchainビルドするのにLinuxKernel落としてくるんだよ、ソレくらい自前で用意したの使えるようにしとけよ、というか全般的にあそこまでお仕着せになってしまうと、気持ち悪くて使いたくない。全部中身を理解した上でのショートカットとしてなら使えるけど、今回試しているのはまさに、中身を全部分解した上で、必要な部分だけ手動でつなぎあわせていく作業なのだから、せっかくの楽しみを奪うなよコンチキショーってところ。

ってか、Buildroot使わずに全部手動でuClibc, BusyBox使ってユーザーランド構築する記事もWeb上ではちらほらあるんだけど、Kernel-2.4.x時代の内容ばかりで、2011年4月時点の最新stableバージョンのuclibc, busyboxでは適用できない。

さらに言うと、色々原因を追い詰めていくにも、「今のmsakamoto-sfだからこそ」なんとか追い詰められないでもない程度で、というのはつまるところ、ELFのローダーであるとかELFファイルのフォーマットであるとかgccって結局binutilsのドライバだよね、でもどのcrtX.oをリンクするのかを知ってるのはgccになっちゃうから、だから面倒でもBuildrootはtoolchainでgccをビルドしなくちゃイカンよなぁ、いや単にCrossCompilerで必要だからというだけじゃなくてね、とか、gccのインクルードパスとかオプションとか調べるにも"-v"とか"--verbose"とか"--save-temps"とか知ってないと中身を分解できないし、そもそもMakefile.inとかそこら辺の周辺技術もひと通り頭に入れていないとそもそもビルドするときなにやってるのかが分からないよな、とかとか。

よーするにソースがオープンだということと、じゃぁそのソースの内容を理解して、Makefileによるビルドが何をどうコピーしてコンパイルしてリンクして移動したりinstallしてるのか、とか、さらにじゃぁビルドしたバイナリはどういうもので、Kernelによりどうやってメモリ上にロードされるのか、とか、トラブったときにobjdumpとかreadelfでELFファイルの中身を解析したり、gdbでマシン語レベルでデバッグしてCのソースと人力で対応付けられるのかとか、その辺のもろもろの胡乱な下準備なしに、トラブったときにその原因を調べられるわけねーだろ、的な感じなのですよ奥様!!

ってゆーかld-uClibcのローダ、どうやってデバッグしてるんだ?ld-linux.soの場合は単体で実行できるからそこからgdbでデバッグできそうだが、ld-uClibcはstandaloneでの起動が出来ないからそのテクニックもおそらく使えない・・・。
やべ、詰まった・・・?

glibcの動的リンクローダー:

$ LD_DEBUG=all /lib/ld-linux.so.2 /bin/ls -l /lib/ld-linux.so.2
...
6130:     binding file /bin/ls [0] to /lib/libc.so.6 [0]: ...
lrwxrwxrwx 1 root root 9  4月  2 18:18 /lib/ld-linux.so.2 -> ld-2.5.so
6130:     symbol=exit;  lookup in file=/bin/ls [0]
...

uClibcの動的リンクローダー:

$ LD_DEBUG=all ./ld-uClibc-0.9.31.so ../../ret1_dyn
argc=2 argv=0xbfb3bea4 envp=0xbfb3beb0
ELF header=0x6f5000
First Dynamic section entry=0x6fceec
Scanning DYNAMIC section
Done scanning DYNAMIC section
About to do library loader relocations
Done relocating ldso; we can now use globals and make function calls!
_dl_get_ready_to_run:317: Cool, ldso survived making function calls
Standalone execution is not supported yet

→ Oooops!!!


プレーンテキスト形式でダウンロード
現在のバージョン : 1
更新者: msakamoto-sf
更新日: 2011-04-10 20:07:37
md5:c416a6c952d94b4e3460284370da05c1
sha1:0fc25a37f3c96b50ccc19b4945f41226fcace916
コメント
コメントを投稿するにはログインして下さい。