考虑 的共享对象依赖关系/bin/bash
,其中包括/lib64/ld-linux-x86-64.so.2
(动态链接器/加载器):
ldd /bin/bash
linux-vdso.so.1 (0x00007fffd0887000)
libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007f57a04e3000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f57a04de000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f57a031d000)
/lib64/ld-linux-x86-64.so.2 (0x00007f57a0652000)
检查/lib64/ld-linux-x86-64.so.2
表明它是一个符号链接/lib/x86_64-linux-gnu/ld-2.28.so
:
ls -la /lib64/ld-linux-x86-64.so.2
lrwxrwxrwx 1 root root 32 May 1 19:24 /lib64/ld-linux-x86-64.so.2 -> /lib/x86_64-linux-gnu/ld-2.28.so
此外,file
报告/lib/x86_64-linux-gnu/ld-2.28.so
自身是动态链接的:
file -L /lib64/ld-linux-x86-64.so.2
/lib64/ld-linux-x86-64.so.2: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=f25dfd7b95be4ba386fd71080accae8c0732b711, stripped
我想知道:
- 动态链接器/加载器 (
/lib64/ld-linux-x86-64.so.2
) 本身如何动态链接?它是否在运行时链接自身? /lib/x86_64-linux-gnu/ld-2.28.so
记录处理 a.out 二进制文件(man ld.so
),但是/bin/bash
ELF 可执行文件吗?
程序 ld.so 处理 a.out 二进制文件,这是一种很久以前使用的格式;ld-linux.so*(/lib/ld-linux.so.1 用于 libc5,/lib/ld-linux.so.2 用于 glibc2)处理 ELF,每个人都已经使用多年了。
是的,它在初始化时会自行链接。从技术上讲,动态链接器本身不需要对象解析和重定位,因为它完全按原样解析,但它确实定义了符号,并且在解析它“解释”的二进制文件时必须处理这些符号,并且这些符号被更新指向它们在加载的库中的实现。特别是,这会影响
malloc
- 链接器有一个内置的最小版本,带有相应的符号,但是一旦加载和重定位它就会被 C 库的版本替换(如果有的话,甚至被插入的版本替换),需要小心采取以确保这不会发生在可能会破坏链接器的地方。血淋淋的细节在
rtld.c
函数中dl_main
。但是请注意,
ld.so
它没有外部依赖项。您可以看到与nm -D
;相关的符号。它们都不是未定义的。手册页仅引用直接在 下的条目
/lib
,即/lib/ld.so
(支持 的 libc 5 动态链接器a.out
)和/lib*/ld-linux*.so*
(支持 ELF 的 libc 6 动态链接器)。手册页非常具体,而ld.so
不是ld-2.28.so
.在绝大多数当前系统上发现的动态链接器不包括
a.out
支持。file
并ldd
为动态链接器报告不同的内容,因为它们对构成静态链接二进制文件的定义不同。对于ldd
,如果二进制文件没有DT_NEEDED
符号,即没有未定义的符号,则它是静态链接的。对于file
,如果 ELF 二进制文件没有PT_DYNAMIC
节,则它是静态链接的(这将在file
5.37 之后的版本中更改;它现在使用PT_INTERP
节的存在作为动态链接二进制文件的指示符,这与中的注释相匹配编码)。GNU C 库动态链接器没有任何
DT_NEEDED
符号,但它确实有一个PT_DYNAMIC
部分(因为它在技术上是一个共享库)。结果,ldd
(即动态链接器)表明它是静态链接的,但file
表明它是动态链接的。它没有PT_INTERP
部分,因此下一个版本file
也将表明它是静态链接的。(与
file
5.35)(使用当前正在开发的版本
file
)。我怀疑
file
程序在动态链接器/加载器本身被动态链接方面是错误的。ldd
程序不同意。至少不在我的系统上(Debian Stretch):man ld.so
还写着:“ld-linux.so* 处理 ELF”。在您的系统上(顺便说一下我的系统),它们都是指向同一个二进制文件的符号链接,我推断它能够处理 ELF 和(旧的过时的)a.out 格式。