13

怎么ldd知道它取决于libc.so.6,不是libc.so.5libc.so.7

libc.so.6 => /lib64/libc.so.6 (0x00000034f4000000)
/lib64/ld-linux-x86-64.so.2 (0x00000034f3c00000)
4

2 回答 2

17

它记录在应用程序二进制文件本身中(在编译时指定,更准确地说是在链接步骤,用 完成ld):

$ readelf -d /bin/echo

Dynamic section at offset 0x5f1c contains 21 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libc.so.6]
...

(还有一些关于 elf 如何在动态部分中存储信息的附加列。但您可以看到 libc.so.6.6由于SONAME而被硬编码为后缀)

甚至不了解 ELF 文件格式:

$ strings /bin/echo |grep libc.so
libc.so.6

要查找,链接器如何查找库(在编译的最后一步完成),使用gcc选项-Wl,--verbose(这要求 gcc 将选项传递--verboseld):

$ gcc a.c -Wl,--verbose

...
attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/libc.so failed
attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/libc.a failed
attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/libc.so failed
attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/libc.a failed
attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/../../../libc.so succeeded
opened script file /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/../../../libc.so
opened script file /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/../../../libc.so
attempt to open /lib/libc.so.6 succeeded
/lib/libc.so.6

链接器对后缀一无所知.digit,它只是遍历所有试图打开libLIBNAME.soand的库搜索目录libLIBNAME.a,其中 LIBNAME 是-l选项后的字符串。(-lc默认添加选项)。

第一个成功是/usr/lib/libc.so它本身不是一个库,而是一个链接器脚本(文本文件)。以下是典型libc.so脚本的内容:

$ cat /usr/lib/libc.so
/* GNU ld script
   Use the shared library, but some functions are only in
   the static library, so try that secondarily.  */
OUTPUT_FORMAT(elf32-i386)
GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a  AS_NEEDED ( /lib/ld-linux.so.2 ) )

因此,在实际库之前找到脚本,并且该脚本说明在这种情况下/usr/lib/libc.so将链接什么文件。libc.so.6

在更常见的情况下,lib___.so是指向某个版本的符号链接,例如lib___.so.3.4.5,并且填写了 SONAME 字段lib___.so.3.4.5,表示不ld链接到,lib___.solib___.so.3.4另一个符号链接到lib___.so.3.4.5. 该.3.4名称将记录在二进制的 NEEDED 字段中。

于 2011-04-05T15:34:25.453 回答
4

http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#dynamic_section

具有每个动态标签的含义。1 表示它是一个 DT_NEEDED 标签,在这种情况下意味着

typedef struct {
    Elf32_Sword d_tag;
    union {
        Elf32_Word  d_val;
        Elf32_Addr  d_ptr;
    } d_un;
} Elf32_Dyn;

结构的 d_val 联合有效,并在 DT_STRTAB 表中查找由 thi 联合成员指定的偏移量,以查找此二进制/SO 所依赖的库的名称。

于 2012-04-05T22:40:44.883 回答