dlopen在libc和libdl中

时间:2015-07-01 08:06:08

标签: linux dynamic linker libc

如果gcc编译的程序正在调用dlopen,则必须在启用-ldl选项的情况下编译它。这意味着这样的程序依赖于库libdl.so上的运行时。事实上,通过对它执行ldd,我们看到了这一行:

libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2

libc.so反过来使用dlopen(例如,处理libnss.so),但是没有出现在libldl.so上的ldd:

/lib64/ld-linux-x86-64.so.2 (0x00007f5a488e4000)
linux-vdso.so.1 =>  (0x00007fff7bdfe000)

为什么会出现这种差异?

1 个答案:

答案 0 :(得分:7)

libdl仅公开libc中已存在的私有 dl函数以及一些包装器,以便更轻松地使用库。您可以通过查看libdl的符号表来查看此行为。

如果您在libdl上使用readelf,则限制为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

您会看到所有UND的条目,列在GLIBC_PRIVATE中吗?这些都是引用libc中的实现。

libc本身的已定义API未声明为将dl函数实现为公开的API,但在glibc中,libdl与libc紧密绑定,并且它公开了已知的API 。在这种情况下,glibc可以使用自身内部的私有例程来完成运行时打开和使用.so例程的相关nss文件。