bad*_*ack 4 linux linker dynamic libc
如果gcc编译的程序正在调用dlopen,则必须在启用-ldl选项的情况下编译它.这意味着这样的程序依赖于库libdl.so上的运行时.事实上,通过对它执行ldd,我们看到了这一行:
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2
Run Code Online (Sandbox Code Playgroud)
libc.so反过来使用dlopen(例如,处理libnss.so),但是没有出现在libldl.so上执行ldd:
/lib64/ld-linux-x86-64.so.2 (0x00007f5a488e4000)
linux-vdso.so.1 => (0x00007fff7bdfe000)
Run Code Online (Sandbox Code Playgroud)
为何如此区别?
libdl只展示libc中已存在的私有 dl函数以及一些包装器,以便更轻松地使用库.您可以通过查看符号表来查看一些此行为libdl.
如果您使用readelf libdl,则限制为PRIVATE符号:
readelf -s /usr/lib/x86_64-linux-gnu/libdl.so | grep PRIVATE
13: 0000000000000000 0 OBJECT GLOBAL DEFAULT UND _rtld_global_ro@GLIBC_PRIVATE (7)
14: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _dl_vsym@GLIBC_PRIVATE (8)
16: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _dl_addr@GLIBC_PRIVATE (8)
18: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _dl_sym@GLIBC_PRIVATE (8)
20: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _dl_rtld_di_serinfo@GLIBC_PRIVATE (7)
25: 0000000000000000 0 OBJECT GLOBAL DEFAULT UND _rtld_global@GLIBC_PRIVATE (7)
34: 00000000002030c0 8 OBJECT GLOBAL DEFAULT 27 _dlfcn_hook@@GLIBC_PRIVATE
39: 0000000000000000 0 OBJECT GLOBAL DEFAULT ABS GLIBC_PRIVATE
Run Code Online (Sandbox Code Playgroud)
您可以看到所有条目,UND从GLIBC_PRIVATE列出?这些都是引用libc中的实现.
定义的libc本身的API未被声明为将dl函数实现为公开的API,但是在glibclibdl中是紧密绑定的libc,并且它公开了已知的API.在这种情况下,glibc可以使用其自身内的私有例程来完成运行时打开和使用相关.so文件的nss例程.