链接器如何将 Program Headers 添加到 Relocatable 文件中?

How linker adds Program Headers to the Relocatable file?

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

然后这些Headers用于将程序加载到内存run-time。

例如一个用汇编写的简单的helloworld有2个程序headers:

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

但是 bash11 个程序 headers:

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 的其他信息。其中每一个都有自己的程序头。