动态链接器/加载器本身如何像`file`所报告的那样动态链接?


12

考虑的共享对象相关性/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,每个人都已经使用了多年。


内核并不关心这些细微的分类学细微之处(您也不应该;-)。内核仅使需要解释器的 ELF与不需要解释器的 ELF有所不同。而AFAIK,您不能使用本身需要的解释器
mosvy

@StephenKitt我的还没有(/lib/x86_64-linux-gnu/ld-2.28.so,debian 10 buster)
mos19

@mosvy是的,很抱歉,我file对有关如何定义静态二进制文件的错误评论与ld-2.28.so... 的现实是混为一谈PT_DYNAMIC
斯蒂芬·基特

Answers:


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

    详细信息rtld.cdl_main函数中的中。

    但是请注意,ld.so它没有外部依赖性。您可以看到与其中有关的符号nm -D;没有一个是未定义的。

  2. 手册页仅是指直接在条目/lib /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符号(没有未定义的符号),则被静态链接。对于file,如果ELF二进制文件中没有PT_DYNAMIC节,则将其静态链接(这将在file以下5.37 版本中更改;现在,它使用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)。


为什么在动态链接的上下文中使用“解释”一词?该词通常在编程语言的上下文中使用。
Shuzheng

“ GNU C库动态链接器”是什么意思?您是指/lib*/ld-linux*.so*还是第三个动态链接器?
Shuzheng

您在哪里可以看到ldd动态链接器报告为静态链接?因为它的共享对象依赖关系列表为空?
Shuzheng

动态链接的程序需要执行一些工作才能执行。该工作由动态链接器完成,该链接器最终扮演着与解释器类似的角色-它解释重定位表等,以生成计算机可以运行的东西。
史蒂芬·基特

当我说“ GNU C库动态链接器”时,我指的是GNU C库中包含的实现,通常以形式提供/lib*/ld-linux*.so*。我指定了动态链接器的来源,因为还有其他可用于Linux的实现。
斯蒂芬·基特

0
  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格式。


您在接受的答案中添加了哪些信息?
miracle173

2
@ miracle173此答案早于接受的答案;-)。
斯蒂芬·基特

你是对的。我错过了 我认为该问题和已接受的答案非常古老,并且此答案已发布在最后几个小时。在有人修改帖子之前,我无法撤消我的拒绝投票。
miracle173
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.