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

问题描述 投票:0回答:2

可执行文件的ELF文件有一个程序(段)头和一个节头,可以通过

readelf -a
看到,这里是一个例子:

enter image description here

enter image description here

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

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

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

c linux memory elf
2个回答
28
投票

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

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

malloc
可能能够将其恢复以用作堆的一部分)。

最后,虽然根本不会使用节标题,但您的程序在运行时可能会使用许多不同节的内容。请注意,

.ctors
.dtors
的地址范围位于第二个加载映射的开头,因此它们在运行时被程序映射和访问(运行时启动/退出代码将使用它们来运行全局构造函数和析构函数) ,如果使用带有 ctor/dtor 属性的 C++ 或“GNU C”代码)。另请注意,
.data
从第二个映射页面中的地址 0x0804a00c 开始。这允许在应用重定位(程序头中的 RELRO 指令)后将第一页保护为只读。


© www.soinside.com 2019 - 2024. All rights reserved.