为什么动态链接二进制显示硬编码的SO名称?

时间:2017-04-28 03:07:53

标签: c++ c linker elf

对不起,这可能是一个愚蠢的问题。 我没有直接链接libaudit,但为什么它的名字显示在我的二进制文件中?

字符串显示:

strings dataserver|grep libaudit
libaudit.so.0

readelf显示:

readelf -a dataserver|grep "Shared lib"
0x0000000000000001 (NEEDED)             Shared library: [libsapcrypto.so]
0x0000000000000001 (NEEDED)             Shared library: [libaio.so.1]
0x0000000000000001 (NEEDED)             Shared library: [libnsl.so.1]
0x0000000000000001 (NEEDED)             Shared library: [libdl.so.2]
0x0000000000000001 (NEEDED)             Shared library: [libpam.so.0]
0x0000000000000001 (NEEDED)             Shared library: [libpthread.so.0]
0x0000000000000001 (NEEDED)             Shared library: [librt.so.1]
0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
0x0000000000000001 (NEEDED)             Shared library: [libaudit.so.0]

这是什么意思,无论如何我可以检查为什么它被添加到我的二进制文件中?

由于

更新

感谢。我正在阅读下面的链接,并添加更多的发现。 我发现libpam是链接的,它需要libaudit.so.0

检查libpam.so.0

ldd /lib64/libpam.so.0
linux-vdso.so.1 =>  (0x00007ffff7fdf000)
libaudit.so.0 => /lib64/libaudit.so.0 (0x00007ffff7b80000)   <-- libaudit
libdl.so.2 => /lib64/libdl.so.2 (0x00007ffff797c000)
libc.so.6 => /lib64/libc.so.6 (0x00007ffff7616000)
/lib64/ld-linux-x86-64.so.2 (0x00007ffff7fe0000)

但是,我有2个二进制文件,都链接了libpam.so。对于binary1,它将libaudit.so.0列为NEEDED,但对于binary2,它不会。

binary1(使用libpam但不依赖于libaudit.so.0):

readelf -d binary1|grep "Shared lib"
0x0000000000000001 (NEEDED)             Shared library: [libsybcsi_core210.so]
0x0000000000000001 (NEEDED)             Shared library: [libsybcsi_profiler210.so]
0x0000000000000001 (NEEDED)             Shared library: [libsybcsi_propertiesconfig210.so]
0x0000000000000001 (NEEDED)             Shared library: [libsybcsi_openssl210.so]
0x0000000000000001 (NEEDED)             Shared library: [libaio.so.1]
0x0000000000000001 (NEEDED)             Shared library: [libnsl.so.1]
0x0000000000000001 (NEEDED)             Shared library: [libdl.so.2]
0x0000000000000001 (NEEDED)             Shared library: [libpam.so.0]       <--- libpam
0x0000000000000001 (NEEDED)             Shared library: [libpthread.so.0]
0x0000000000000001 (NEEDED)             Shared library: [librt.so.1]
0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

binary2(使用libpam,但依赖于libaudit.so.0):

readelf -d binary2|grep "Shared lib"
0x0000000000000001 (NEEDED)             Shared library: [libsapcrypto.so]
0x0000000000000001 (NEEDED)             Shared library: [libaio.so.1]
0x0000000000000001 (NEEDED)             Shared library: [libnsl.so.1]
0x0000000000000001 (NEEDED)             Shared library: [libdl.so.2]
0x0000000000000001 (NEEDED)             Shared library: [libpam.so.0]       <--- libpam
0x0000000000000001 (NEEDED)             Shared library: [libpthread.so.0]
0x0000000000000001 (NEEDED)             Shared library: [librt.so.1]
0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
0x0000000000000001 (NEEDED)             Shared library: [libaudit.so.0] <--- libaudit

关键词“需要”让我很困惑,如果不是直接,那么lib何时会被“需要”?

2 个答案:

答案 0 :(得分:1)

  

是什么意思

这意味着你的二进制文件取决于它。

  

并且无论如何我可以检查它为什么被添加到我的二进制文件中?

您使用的链接器很可能发现链接行上的某些其他库取决于libaudit,并且自动将其添加到其中。

GNU-ld这样做,而Gold并没有(产生一个稳定的程序流,这些程序的Makefile不正确且无法与Gold链接)。

如果你链接-v标志,你应该看到实际的链接命令,虽然它可能被collect2或某些这样的包装器隐藏。

strace -fvs 1024 -e execve下运行链接将显示实际的链接命令。

答案 1 :(得分:0)

好的,我找到了原因。

由于某些参考&#34; _edata&#34;和&#34; _end&#34;在我的代码中。 在libpam.so中,找不到libdam.so所需的libaudit.so,找到它并链接器解析它,然后将libaudit添加为&#34; NEEDED&#34;。

_end从链接描述文件中公开如下 -

_end =。; PROVIDE(end =。);

这意味着,除非我们使用自己的链接描述文件提供“_end”,否则我们应该使用“end”而不是“_end”。 因此,修复是将_end(以及所有此类相关符号,如_etext和_edata)更改为end(和etext,edata),以便从标准libc正确解析它们,从而避免对libaudit.so等其他共享对象的任何依赖。

相关问题