過去2回に渡ってPlamo Linuxのインストーラで生じたglibcのNSS回りのトラブルを調べてきました。その結果、
このトラブル自体は"--enable-static-nss"というオプションを与えてglibc-2.
libc.
libc_nonshared.aとは
多くの人にはその存在自体知られていないように思うものの、
というのも、
加えて、
たとえばglibc-2.
$ ls usr/lib/lib*a usr/lib/libBrokenLocale.a usr/lib/libdl.a usr/lib/libmvec.a usr/lib/libanl.a usr/lib/libg.a usr/lib/libpthread.a usr/lib/libc.a usr/lib/libm-2.32.a usr/lib/libresolv.a usr/lib/libc_nonshared.a usr/lib/libm.a usr/lib/librt.a usr/lib/libcrypt.a usr/lib/libmcheck.a usr/lib/libutil.a
それに対し/lib/にインストールされる共有ライブラリはこうなります。
$ ls lib/lib*so lib/libBrokenLocale-2.32.so* lib/libmemusage.so* lib/libnss_hesiod-2.32.so* lib/libSegFault.so* lib/libmvec-2.32.so* lib/libpcprofile.so* lib/libanl-2.32.so* lib/libnsl-2.32.so* lib/libpthread-2.32.so* lib/libc-2.32.so* lib/libnss_compat-2.32.so* lib/libresolv-2.32.so* lib/libcrypt-2.32.so* lib/libnss_db-2.32.so* lib/librt-2.32.so* lib/libdl-2.32.so* lib/libnss_dns-2.32.so* lib/libthread_db-1.0.so* lib/libm-2.32.so* lib/libnss_files-2.32.so* lib/libutil-2.32.so*
両者を見比べると、
一方、
1 /* GNU ld script
2 Use the shared library, but some functions are only in
3 the static library, so try that secondarily. */
4 OUTPUT_FORMAT(elf64-x86-64)
5 GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a AS_NEEDED ( /lib/ld-linux-x86-64.so.2 ) )
これを見ると、
このようにlibc_
libc_noshared.aの中身
後述するように"--enable-static-nss"を指定すると機能が増えて複雑になるので、
arやnmを使ってlibc_
$ ar t libc_nonshared.a | cat -n 1 elf-init.oS 2 atexit.oS 3 at_quick_exit.oS 4 pthread_atfork.oS 5 stat.oS 6 fstat.oS 7 lstat.oS 8 stat64.oS 9 fstat64.oS 10 lstat64.oS 11 fstatat.oS 12 fstatat64.oS 13 mknod.oS 14 mknodat.oS 15 warning-nop.oS 16 stack_chk_fail_local.oS $ nm libc_nonshared.a | grep 000000 | cat -n 1 0000000000000060 T __libc_csu_fini 2 0000000000000000 T __libc_csu_init 3 0000000000000000 T atexit 4 0000000000000000 T at_quick_exit 5 0000000000000000 T __pthread_atfork 6 0000000000000000 W pthread_atfork 7 0000000000000000 T __stat 8 0000000000000000 W stat 9 0000000000000000 T __fstat 10 0000000000000000 W fstat 11 0000000000000000 T __lstat 12 0000000000000000 W lstat 13 0000000000000000 T stat64 14 0000000000000000 T fstat64 15 0000000000000000 T lstat64 16 0000000000000000 T fstatat 17 0000000000000000 T fstatat64 18 0000000000000000 T __mknod 19 0000000000000000 W mknod 20 0000000000000000 T mknodat 21 0000000000000000 t nop 22 0000000000000000 T __stack_chk_fail_local
機能的な関連性からまとめられたのだろうか、
glibcのドキュメントやソースコードを眺めてみても、
はてさて、
きっかけはobjdumpを用いたライブラリの逆アセンブルです。objdumpはバイナリファイルを操作するためのbinutilsパッケージに含まれるコマンドで、
$ objdump -d libc_nonshared.a | cat -n 1 書庫 libc_nonshared.a 内: 2 3 elf-init.oS: ファイル形式 elf64-x86-64 4 5 6 セクション .text の逆アセンブル: 7 8 0000000000000000 <__libc_csu_init>: 9 0: 41 57 push %r15 10 2: 4c 8d 3d 00 00 00 00 lea 0x0(%rip),%r15 # 9 <__libc_csu_init+0x9> 11 9: 41 56 push %r14 12 b: 49 89 d6 mov %rdx,%r14 ... 42 5d: 0f 1f 00 nopl (%rax) 43 44 0000000000000060 <__libc_csu_fini>: 45 60: c3 retq 46 ... 52 0000000000000000 <atexit>: 53 0: 48 8b 15 00 00 00 00 mov 0x0(%rip),%rdx # 7 <atexit+0x7> 54 7: 31 f6 xor %esi,%esi 55 9: e9 00 00 00 00 jmpq e <atexit+0xe> 56 ... 62 0000000000000000 <at_quick_exit>: 63 0: 48 8b 35 00 00 00 00 mov 0x0(%rip),%rsi # 7 <at_quick_exit+0x7> 64 7: e9 00 00 00 00 jmpq c <at_quick_exit+0xc> 65 ... 102 0000000000000000 <__lstat>: 103 0: 48 89 f2 mov %rsi,%rdx 104 3: 48 89 fe mov %rdi,%rsi 105 6: bf 01 00 00 00 mov $0x1,%edi 106 b: e9 00 00 00 00 jmpq 10 <__lstat+0x10> 107 ... 213 0000000000000000 <__stack_chk_fail_local>: 214 0: 48 83 ec 08 sub $0x8,%rsp 215 4: e8 00 00 00 00 callq 9 <__stack_chk_fail_local+0x9>
この結果を見ると、
"--enable-static-nss"とlibc_nonshared.a
一方、
$ ls -lh static_nss/usr/lib/libc_nonshared.a -rw-r--r-- 1 kojima users 266K 8月 16日 08:36 static_nss/usr/lib/libc_nonshared.a
含まれているオブジェクトファイルを見てもNSS関連のファイルが多数追加されていました。
$ ar t static_nss/usr/lib/libc_nonshared.a | cat -n 1 elf-init.oS 2 atexit.oS 3 at_quick_exit.oS ... 15 warning-nop.oS 16 stack_chk_fail_local.oS 17 dns-host.oS 18 dns-network.oS 19 dns-canon.oS 20 res_comp.oS ... 52 files-initgroups.oS 53 files-init.oS
もちろん、
$ nm static_nss/usr/lib/libc_nonshared.a | cat -n 1 2 elf-init.oS: 3 U _GLOBAL_OFFSET_TABLE_ 4 U __init_array_end 5 U __init_array_start 6 0000000000000060 T __libc_csu_fini 7 0000000000000000 T __libc_csu_init ... 86 stack_chk_fail_local.oS: 87 U _GLOBAL_OFFSET_TABLE_ 88 U __stack_chk_fail 89 0000000000000000 T __stack_chk_fail_local 90 91 dns-host.oS: 92 0000000000000000 r .LC1 93 U _GLOBAL_OFFSET_TABLE_ 94 U __dn_expand ... 108 0000000000001e90 T _nss_dns_gethostbyaddr2_r 109 0000000000002650 T _nss_dns_gethostbyaddr_r 110 00000000000019c0 T _nss_dns_gethostbyname2_r 111 0000000000001920 T _nss_dns_gethostbyname3_r 112 0000000000001af0 T _nss_dns_gethostbyname4_r 113 0000000000001a40 T _nss_dns_gethostbyname_r ... 944 files-init.oS: ... 955 0000000000000000 b netgr_traced_file 956 0000000000005140 b pwd_traced_file 957 0000000000002080 b resolv_traced_file 958 0000000000001040 b serv_traced_file
この結果を見ると、
前回紹介したNSSの特長である
NSS回りの機能を静的リンクしてglibcのバージョンに依存しないインストーラ用ツールは作成できたので、
今回辿りついた