linux - 链接器如何将程序头添加到可重定位文件?

标签 linux linker ld elf readelf

所以我们知道 linker(在我的例子中是 ld)将 Program Headers 添加到 Relocatable file在创建实际的 Executable 时。

然后这些 header 用于在运行时将程序加载到内存中。

  • 首先,ld 是如何计算这些 header 并将其添加到文件中的?

  • 如果 Program Headers 仅用于将程序加载到内存中(如果我错了请纠正我),为什么不同的可执行文件具有不同数量的 Program header ?

例如,一个用汇编语言编写的简单 helloworld 有2 个程序头:

readelf -h helloworld
...
  Number of program headers:         2
...

但是 bash11 个程序头:

readelf -h /bin/bash
...
  Number of program headers:         11
...

最佳答案

First of all how ld calculates and adds these headers to the file?

这个问题太笼统了,不好回答。您不妨阅读this series解释链接器工作原理的博文。

And then if the Program Headers are used only to load the program into memory (correct me if I'm wrong), how come different executables have different number of Program Headers?

可执行文件有不同数量的程序头,因为它们有不同的需求。

例如,一个完全静态的可执行文件不需要与动态链接器进行任何交互,因此不需要 PT_DYNAMIC 段(以及描述该段的程序头)。

常见的动态链接可执行文件将至少有两个 PT_LOAD 段(数据和代码),PT_INTERP(告诉使用哪个运行时加载器),PT_DYNAMIC(告知要使用哪些共享库,以及 ld.so 的其他信息)、PT_NOTE(用于链接器构建 ID)和 PT_PHDR。其中每一个都有自己的程序头。

关于linux - 链接器如何将程序头添加到可重定位文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51966583/

相关文章:

linux - 如何使用 awk 显示所有行,但在第二个字段中有条件?

linux - 我可以在 Windows 中运行 Linux shell 脚本吗?

linux - 如何将此命令的结果存储为 bash 脚本中的变量?

c - "multiple definition of ` memcmp“链接Rust staticlib与嵌入式C程序时出错

c# - P/Invoke ioctl 系统调用

c++ - 如何在 Visual C++ 中同时创建 .lib 文件和 .exe 文件?

android-ndk - 在 Android Studio 中将没有 header 的共享对象库与 NDK 链接

GCC 链接器 - 指定存档文件中包含的代码的输出部分

c - 让 Scons 意识到我的链接描述文件已经改变

linux - ld链接失败