如果一个由gcc编译的程序正在调用dlopen,那么它必须在编译时启用-ldl选项。这意味着这样的程序在运行时依赖于库libdl.so。实际上,通过对它执行ldd,我们可以看到这一行:
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2libc.so反过来使用dlopen (例如,处理libnss.so),但在libldl.so上执行ldd不会出现:
/lib64/ld-linux-x86-64.so.2 (0x00007f5a488e4000)
linux-vdso.so.1 => (0x00007fff7bdfe000)为什么会有这样的差异?
发布于 2015-07-01 18:57:33
libdl只公开了libc中已经存在的私有libc dl函数以及一些包装器,以便更容易地使用这些库。通过查看libdl的符号表,您可以看到其中的一些行为。
如果您在libdl上使用readelf,则限制为私有符号:
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您看到GLIBC_PRIVATE中列出的所有UND条目了吗?这些都引用了libc中的实现。
libc本身定义的API没有声明为将dl函数实现为公开的API,但是在glibc中,libdl与libc紧密绑定,并且它公开了已知的API。在这种情况下,glibc可以使用其内部的私有例程来完成nss例程的相关.so文件的运行时打开和使用。
https://stackoverflow.com/questions/31155824
复制相似问题