了解ldd输出

com*_*fan 13 linker ldd

怎么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)
Run Code Online (Sandbox Code Playgroud)

osg*_*sgx 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]
...
Run Code Online (Sandbox Code Playgroud)

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

甚至不了解ELF文件格式:

$ strings /bin/echo |grep libc.so
libc.so.6
Run Code Online (Sandbox Code Playgroud)

要找到,如何找到链接库,使用(它在编译的最后一步完成)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
Run Code Online (Sandbox Code Playgroud)

链接不知道什么.digit后缀,它只是遍历所有库搜索目录试图打开libLIBNAME.solibLIBNAME.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 ) )
Run Code Online (Sandbox Code Playgroud)

因此,脚本/usr/lib/libc.so比实际库更早找到,并且此脚本说,libc.so.6在这种情况下,将链接哪个文件.

更常见的情况,lib___.so是符号链接到一些版本一样lib___.so.3.4.5,有是一个充满SONAME领域lib___.so.3.4.5它说,以ld不连接lib___.so,而是lib___.so.3.4这是另一种符号链接lib___.so.3.4.5.该.3.4名称将记录在二进制的NEEDED字段中.