了解ldd输出 [英] Understanding ldd output

查看:322
本文介绍了了解ldd输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

ldd如何知道它取决于libc.so.6,而不是libc.so.5libc.so.7?

How does ldd knows it's depending on libc.so.6 ,not libc.so.5 or libc.so.7?

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

推荐答案

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

It is recorded inside application binary itself (specified at compile time, more exactly at link step, done with 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如何在动态部分中存储信息的列.但是您可以看到,由于

(there are some additional columns for how elf does store information in dynamic section. but you can see that libc.so.6 is hardcoded with .6 suffix because of SONAME)

,甚至不了解ELF文件格式:

or even without any knowledge of ELF file format:

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

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

To find, how does linker find a library (it is done at final step of compilation), use gcc option -Wl,--verbose (this asks gcc to pass option --verbose to ld):

$ 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.solibLIBNAME.a,其中LIBNAME是-l选项后的字符串. (默认添加-lc选项.)

Linker doesn't know anything about .digit suffix, it just iterate over all library search directories trying to open libLIBNAME.so and libLIBNAME.a, where LIBNAME is a string after -l option. ( -lc option is added by default).

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

First success is /usr/lib/libc.so which itself is not a library, but a linker script (text file). Here is content from typical libc.so script:

$ 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.

So, script /usr/lib/libc.so is found earlier than actual library, and this script says, what file will be linked, libc.so.6 in this case.

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

In more common case, lib___.so is symlink to some version like lib___.so.3.4.5 and there is SONAME field filled in lib___.so.3.4.5 which says to ld link not to lib___.so but to lib___.so.3.4 which is another symlink to lib___.so.3.4.5. The .3.4 name will be recorded in NEEDED field of binary.

这篇关于了解ldd输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆