2

我们可以使用 ldd 来确定依赖关系,例如:

 sjwang@delpe02-179: ldd `which date`
        linux-vdso.so.1 =>  (0x00007fff0f5fd000)
        librt.so.1 => /lib64/librt.so.1 (0x00002b2f7ea50000)
        libc.so.6 => /lib64/libc.so.6 (0x00002b2f7ec59000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00002b2f7efb1000)
        /lib64/ld-linux-x86-64.so.2 (0x00002b2f7e832000)

由于“日期”依赖于“libc.so”,我假设“日期”调用“libc.so”中的某个函数,并且我们知道 ldd 可以从可执行文件的 .dynamic 部分确定“日期”的 lib 依赖关系,但我的问题是编译器/链接器如何知道应该将什么写入 .dynamic 部分?更加具体:

  1. 如果“libc.so”与“date”静态链接,那么这个函数的代码应该已经编译成“date”,所以在这种情况下“date”不应该依赖“libc.so”,应该没有.dynamic 部分中的“libc.so”。

  2. 如果“libc.so”与“date”动态链接,在这种情况下,我假设一些代码是这样的:

句柄 = dlopen("libc.so", ..);

应该存在于 "date" 中以加载 "libc.so",并且 "dlopen("libc.so")" 应该是 "date" 依赖于 "libc.so" 的唯一线索,在这种情况下,编译器/链接器知道“日期”取决于“libc.so”吗?它是否解析所有“dlopen”行以提取 lib 依赖关系?我认为这不是一个好方法,但真的,这是真的吗?

或者编译器/链接器是否有其他方法来确定动态链接情况下的 lib 依赖性?谢谢。

4

2 回答 2

2

编译器/链接器如何知道应该将什么写入 .dynamic 部分

  • .dynamic编译器对节一无所知
  • 链接器知道您是与libc.a还是与链接libc.so。对于*.so您链接的任何内容 [1],它都会在DT_NEEDED该部分中写入一个条目.dynamic

我假设一些这样的代码:handle = dlopen("libc.so", ..);

这是您的错误假设和误解。dlopen允许您使用不直接依赖的库(可能存在也可能不存在)。您直接依赖的库(例如libc.so):

  • 不需要 dlended(加载程序在您的程序启动之前已经为您映射了它们)和
  • 不是可选的(如果它们丢失,加载器将失败)。

[1] 链接器标志--as-needed使该语句仅部分正确。

于 2013-01-04T19:04:30.987 回答
0

文件中的内容.so不仅仅是.dynamic部分。阅读有关可执行和可链接格式的更多信息(ELF 是.so文件和二进制可执行文件的格式)。

特别是 ELF 文件确实有标题,这些包含信息。使用objdump和/或 readelf实用程序来探索它们。

不要忘记,在构建共享库时,您可以将其与其他库链接。

于 2013-01-04T09:29:02.763 回答