ld-elf.so.2 がうまくビルドできない
ソースとってくる
git clone git://git.dragonflybsd.org/dragonfly.git git checkout v2.6.3
コンパイルしてインストール。
cd lib/libc_rtld make cd ../../libexec/rtld-elf make cp ld-elf.so.2 /usr/libexec
こうするとほとんど全てのプログラム(ようするに dynamic link なプログラム)が SEGV するようになる。 元の ld-elf.so.2 に戻してやるとOK。
core を探っても 0x00000 resident_start にこけている。これは ld-elf.so.2 の中でこけているんですよねぇ…。
いろいろ試してみる。
file /usr/libexec/ld-elf.so.2 ld-elf.so.2 ld-elf.so.2: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), statically linked, not stripped /usr/libexec/ld-elf.so.2: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped
手元のは "statically linked" になっているけどなにか関係が…?
gcc のバージョンなど。
Target: i686-gentoo-dragonfly2.6 Configured with: /home/tmp/portage/sys-devel/gcc-4.4.3-r2/work/gcc-4.4.3/configure --prefix=/usr --bindir=/usr/i686-gentoo-dragonfly2.6/gcc-bin/4.4.3 --includedir=/usr/lib/gcc/i686-gentoo-dragonfly2.6/4.4.3/include --datadir=/usr/share/gcc-data/i686-gentoo-dragonfly2.6/4.4.3 --mandir=/usr/share/gcc-data/i686-gentoo-dragonfly2.6/4.4.3/man --infodir=/usr/share/gcc-data/i686-gentoo-dragonfly2.6/4.4.3/info --with-gxx-include-dir=/usr/lib/gcc/i686-gentoo-dragonfly2.6/4.4.3/include/g++-v4 --host=i686-gentoo-dragonfly2.6 --build=i686-gentoo-dragonfly2.6 --disable-altivec --disable-fixed-point --without-ppl --without-cloog --enable-nls --without-included-gettext --with-system-zlib --disable-checking --disable-werror --enable-secureplt --disable-libmudflap --disable-libssp --disable-libgomp --enable-cld --with-python-dir=/share/gcc-data/i686-gentoo-dragonfly2.6/4.4.3/python --disable-libgcj --with-arch=i686 --enable-languages=c,c++ --enable-shared --enable-threads=posix --with-bugurl=http://bugs.gentoo.org/ --with-pkgversion='Gentoo 4.4.3-r2 p1.2' Thread model: posix gcc version 4.4.3 (Gentoo 4.4.3-r2 p1.2)
CC=/usr/libexec/cc make しても変わらず。 (/usr/libexec/cc は多分 DragonFly の元のコンパイラ)
とりあえず dynamic linker にカレントディレクトリのものを使った ELF バイナリを作る。 hoge.c は "int main { return 0; }" これだけ。
gcc hoge.c -ggdb -Wl,--dynamic-linker=./ld-elf.so.2
gdb で実行すると多少の back trace がとれる
Program received signal SIGSEGV, Segmentation fault. 0x2804b5a2 in ?? () (gdb) bt #0 0x2804b5a2 in ?? () #1 0x28049e07 in ?? () #2 0x28049b62 in ?? ()
この時に ps aux|grep a.out で a.out の process number 調べて /proc/
08048000-08049000 r-xp 00002000 00:00 328124 /home/gentoo/dragonflybsd/libexec/rtld-elf/a.out 08049000-0804a000 rw-p 00002000 00:00 328124 /home/gentoo/dragonflybsd/libexec/rtld-elf/a.out 0804a000-0804b000 rw-p 00001000 00:00 0 28049000-28070000 r-xp 0007c000 00:00 328132 /home/gentoo/dragonflybsd/libexec/rtld-elf/ld-elf.so.2 28070000-28072000 rw-p 0007c000 00:00 328132 /home/gentoo/dragonflybsd/libexec/rtld-elf/ld-elf.so.2 28072000-2807e000 rw-p 00014000 00:00 0 2807e000-28086000 rwxp 00014000 00:00 0 bfbe0000-bfc00000 rwxp 00020000 00:00 0 [stack]
0x2804b5a2 - 0x2804900 = 0x25a2 である。 nm ld-elf.so |sort してみると
00002323 t init_dag 000023b4 t init_dag1 00002447 t init_rtld 000025af t initlist_add_neededs 00002600 t initlist_add_objects
なので、多分 init_rtld の中で落ちているのでしょうよ。
実際、 init_rtld() の中で assert(0==1); をしかけてやるとどこで落ちているかどうか判定できます。
結局、このアクセスの部分で落ちていて。
r_debug.r_brk = r_debug_state; r_debug.r_state = RT_CONSISTENT;
% nm ld-elf.so.2|grep r_debug 00034988 B r_debug 0000429a T r_debug_state
0x28049000 + 0x00034988 = 0x2807d988 で map されてない領域? BSS だからそれはいいのかな???
よくわかりません。助言いただけるとうれしいです。