過去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のバージョンに依存しないインストーラ用ツールは作成できたので、
今回辿りついた
