【问题标题】:Loading the dynamic linker加载动态链接器
【发布时间】:2017-05-28 06:02:50
【问题描述】:

如果动态链接器/加载器本身是一个共享目标文件,如果它还没有加载到动态链接程序的进程映像空间中,如何正确加载它?这是某种捕捉 22 的东西吗?

【问题讨论】:

  • 从您的链接中,发帖人说“库由 ld.so 加载”,但是,我的问题是,如果 ld.so 本身是“库”(共享对象),那么首先如何加载 ld.so文件)...
  • 以及讨论的部分'它被声明为所有动态链接ELF二进制文件的“解释器”(INTERP;.interp部分)。因此,当您启动程序时,Linux 会启动一个 ld.so(加载到内存并跳转到其入口点),然后 ld.so 会将您的程序加载到内存中,准备好然后运行它。您也可以使用/lib/ld-linux.so.2 ./your_program your_prog_params' 启动动态程序,说明内核加载并运行它,然后解释二进制文件,从而避免了 Catch-22,因为内核确实处理了动态加载程序的加载。注意我没有使用 Mjölnir!
  • "Linux 将启动一个 ld.so (加载到内存并跳转到它的入口点)", "说明内核加载并运行它" 所以如果我理解正确的话,内核有执行 ld.so 提供的所有功能(例如重定位等)的能力?
  • @John41_,不,内核不支持在用户空间程序中进行 ELF 重定位。它可能只启动静态链接的 ELF 或启动一些特殊编写的二进制文件,如 ld-linux.so,它们是特殊的(不需要过早重定位,自己进行重定位处理)。解释的二进制文件由内核加载,但由 ld-linux.so 处理。

标签: unix linker shared-libraries elf


【解决方案1】:

This answer 提供了一些细节(尽管其中存在技术错误)。

这是某种第 22 条规则吗?

是的:ld.so 特殊的——它是一个自重定位二进制文件。

首先要仔细执行不需要任何重定位的代码。该代码会重新定位 ld.so 本身。在这个自重定位/引导过程完成后,ld.so 将继续作为常规共享库。

【讨论】:

  • 已就业,您能否通过编辑链接的答案或回答技术上正确的答案来纠正一些错误?
【解决方案2】:

参考 Oracle Solaris 11.1 Linkers and Libraries Guide 这是我遇到的最好的链接器参考,简洁明了,解释得很好。

在第 89 页:

作为动态可执行文件初始化和执行的一部分, 调用解释器来完成应用程序的绑定 它的依赖关系。在 Oracle Solaris OS 中,此解释器是 称为运行时链接器。

在动态可执行文件的链接编辑期间,一个特殊的 .interp 部分以及一个 相关的程序头,被创建。本节包含一个路径 指定程序解释器的名称。提供的默认名称 链接编辑器的名称是运行时链接器的名称:/usr/lib/ld.so.1 对于 32 位可执行文件和 /usr/lib/64/ld.so.1 对于 64 位可执行文件 可执行文件。

注意 – ld.so.1 是共享对象的一种特殊情况。这里, 使用版本号 1。但是,后来的 Oracle Solaris OS 版本可能会提供更高的版本号。

过程中 执行动态对象,内核加载文件并读取 程序头信息。请参见第 371 页上的“程序标题”。从 这个信息,内核定位所需的名称 口译员。内核加载,并将控制权转移到这个 解释器,传递足够的信息以启用解释器 继续执行应用程序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-16
    • 2013-07-07
    • 2012-04-20
    • 1970-01-01
    • 1970-01-01
    • 2014-05-31
    相关资源
    最近更新 更多