c - 必须将 ELF 文件的哪一部分加载到内存中?

标签 c linux memory elf

可执行文件的ELF文件有一个程序(段)头和一个节头,通过readelf -a可以看到,下面是一个例子:

enter image description here

enter image description here

上面两张图分别是section header和program(segment) header。可以看出,一个段头是由几个段头组成的,用于将程序加载到内存中。

是否只需要将 .text、.rodata、.data、.bss 段加载到内存中?

段中的所有其他部分(例如,第 3 段中的 .ctors、.dtors .jcr)是否都用于对齐?

最佳答案

节和段是完全不同的两个概念。部分与存储在那里的数据的语义有关(即它将用于什么),并且一旦链接程序或共享库,除了调试目的之外实际上是无关紧要的。您甚至可以完全删除节标题(或用随机垃圾覆盖它们)并且程序仍然可以工作。

段(即程序头加载指令)是内核和/或动态链接器在加载程序时实际查看的内容。例如,在您的情况下,您有两个加载指令。第一个导致文件的前 4k(1 页)映射到地址 0x08048000,并表示实际上只使用此映射的前 0x4b8 个字节(其余为对齐)。第二个导致文件的前 8k(2 页)映射到地址 0x08049000。其中绝大多数是对齐。前 0xf14 字节不是加载指令的一部分(只是对齐),将被浪费。从 0x08049f14 开始,实际使用从文件映射的 0x108 字节,另外 0x10 字节(以达到 0x118 的 MemSize)由加载器(内核或动态链接器)填充零。这最多跨越 0x0804a02c(在第二个映射页面中)。第二个映射页面的其余部分未使用/浪费(但 malloc 可能能够恢复它以用作堆的一部分)。

最后,虽然根本不会使用节标题,但您的程序在运行时可能会使用许多不同节的内容。注意 .ctors.dtors 的地址范围位于第二个加载映射的开头,因此它们在运行时被程序映射和访问(运行时启动/exit 代码将使用它们来运行全局构造函数和析构函数,如果使用了具有 ctor/dtor 属性的 C++ 或“GNU C”代码)。另请注意,.data 从地址 0x0804a00c 开始,在第二个映射页面中。这允许在应用重定位后以只读方式保护第一页(程序头中的 RELRO 指令)。

关于c - 必须将 ELF 文件的哪一部分加载到内存中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10417312/

相关文章:

linux - 将 wget 输出覆盖到文本文件

windows - 报告 Direct3D 内存使用情况

c++ - 检查算术运算中的溢出条件

c - 如何调试使用 GDB 执行 bash shell 脚本的 C 程序?

我可以在 Google App Engine 上使用 CGo 吗?

linux - ps2pdf 从 paps-created-ps 文件创建一个非常大的 pdf 文件

c++ - 代码信息

php - Linux Centos MySQL PHP InnoDB 上的内存管理

c# - UWP - 框架导航似乎会导致非托管内存泄漏

database - 为什么我无法创建大于 1.8GB 的​​固定长度 tokyo Cabinet 数据库?