动态链接器/加载器本身如何按照“文件”报告进行动态链接?

动态链接器/加载器本身如何按照“文件”报告进行动态链接?

考虑 的共享对象依赖性/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

我想知道:

  1. 动态链接器/加载器()本身如何/lib64/ld-linux-x86-64.so.2动态链接?它在运行时链接自己吗?
  2. /lib/x86_64-linux-gnu/ld-2.28.so被记录为处理 a.out 二进制文件 ( man ld.so),但/bin/bashELF 是可执行文件吗?

程序 ld.so 处理 a.out 二进制文件,这是很久以前使用的格式; ld-linux.so*(对于 libc5 来说是 /lib/ld-linux.so.1,对于 glibc2 来说是 /lib/ld-linux.so.2)处理 ELF,每个人都已经使用它很多年了。

答案1

  1. 是的,它在初始化时会自行链接。从技术上讲,动态链接器本身不需要对象解析和重定位,因为它按原样完全解析,但它确实定义了符号,并且在解析它“解释”的二进制文件时必须处理这些符号,并且这些符号被更新指向它们在加载的库中的实现。特别是,这会影响malloc- 链接器有一个内置的最小版本,带有相应的符号,但一旦加载和重定位,它就会被 C 库的版本替换(或者甚至被插入的版本,如果有的话),需要小心采取措施确保这种情况不会发生在可能破坏链接器的地方。

    血淋淋的细节在rtld.c,在dl_main函数中。

    但请注意,它ld.so没有外部依赖项。您可以看到涉及的符号nm -D;它们都不是未定义的。

  2. 联机帮助页仅引用直接位于/lib,IE /lib/ld.so(libc 5 动态链接器,支持a.out) 和/lib*/ld-linux*.so*(libc 6 动态链接器,支持 ELF)。联机帮助页是非常具体的,ld.so并不是ld-2.28.so

    当前绝大多数系统上的动态链接器不包含a.out支持。

fileldd为动态链接器报告不同的内容,因为它们对静态链接二进制文件的构成有不同的定义。对于ldd,如果二进制文件没有DT_NEEDED符号,则它是静态链接的,IE没有未定义的符号。对于file,如果 ELF 二进制文件没有PT_DYNAMIC节,则它是静态链接的(这将在以下 5.37 版本中更改file;现在PT_INTERP使用节的存在作为动态链接二进制文件的指示符,与代码中的注释匹配)。

GNU C 库动态链接器没有任何DT_NEEDED符号,但它有一个PT_DYNAMIC部分(因为它在技术上是一个共享库)。结果,ldd(即动态链接器)指示它是静态链接的,但file指示它是动态链接的。它没有PT_INTERP节,因此下一个版本file也将表明它是静态链接的。

$ ldd /lib64/ld-linux-x86-64.so.2
        statically linked

$ file $(readlink /lib64/ld-linux-x86-64.so.2)
/lib/x86_64-linux-gnu/ld-2.28.so: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=f25dfd7b95be4ba386fd71080accae8c0732b711, stripped

file5.35)

$ file $(readlink /lib64/ld-linux-x86-64.so.2)
/lib/x86_64-linux-gnu/ld-2.28.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=f25dfd7b95be4ba386fd71080accae8c0732b711, stripped

(当前正在开发的版本file)。

答案2

  1. 我怀疑file程序对于动态链接器/加载器本身的动态链接是错误的。程序ldd不同意。至少在我的系统上没有(Debian Stretch):

    ldd /lib/x86_64-linux-gnu/ld-2.24.so
        statically linked
    
  2. man ld.so还读到:“ld-linux.so* 处理 ELF”。在你的系统上(顺便说一下,我的系统上也是如此),两者都是指向同一个二进制文件的符号链接,我推断它能够处理 ELF 和(旧的过时的)a.out 格式。

相关内容