一个 C++ 程序从磁盘到内存要经历多少次变形?——从 ELF section 到 segment,拆解 execve 加载器的 6 步地址空间构建

📅 2026/7/10 4:17:43 👁️ 阅读次数 📝 编程学习
一个 C++ 程序从磁盘到内存要经历多少次变形?——从 ELF section 到 segment,拆解 execve 加载器的 6 步地址空间构建

在你的终端里敲下readelf -S a.out,屏幕会吐出将近 30 行——.text.rodata.data.bss.symtab.strtab.rela.dyn.rela.plt.init_array.fini_array……一个看似简单的 C++ 程序,编译器和链接器在它体内塞了三十个形状各异的"隔间",每个隔间有自己的名字、大小、对齐要求和访问权限。但如果你紧接着敲下readelf -l a.out,画风突变:整个程序被压缩成了 4 个 Segment,其中真正需要映射到内存的PT_LOAD类型只有 2 个——一个承载只读的代码和常量数据(.text+.rodata+.eh_frame),另一个承载可读写的全局变量和未初始化数据(.data+.bss+.got+.got.plt)。

这就是第一个让人困惑的事实:内核在执行execve系统调用时,完全不看 Section Header Table——它只读 Program Header Table 里的 Segment 描述。链接器辛辛苦苦维护的 30 个 Section,在程