为什么 ELF 头和文本段一起加载到内存中?

Why is the ELF header loaded into memory along with the text segment?

我用 -m32 -nostdlib 将这个程序编译成一个 ELF 可执行文件:

void _start() {}

当我这样做时 readelf -l 我惊讶地发现 LOAD 段上的偏移量是 0x000000,因为这意味着可执行文件头将与文本段同时加载到内存中.于是去GDB查了一下,确实是这样:

(gdb) b _start
Breakpoint 1 at 0x8048083
(gdb) r
Starting program: /home/tbodt/ish/build/a.out 

Breakpoint 1, 0x08048083 in _start ()
(gdb) x/4c 0x08048000
0x8048000:      127 '7'      69 'E'  76 'L'  70 'F'

为什么这有用?

I was surprised to see that the offset on the LOAD segment was 0x000000

你为什么感到惊讶?

since that would mean that the executable header would get loaded into memory at the same time as the text segment.

正确。为什么这是个问题?

正如 this answer 解释的那样,可执行文件是 mmaped 并且 mmap 整个 页面上工作;您不能映射从偏移 0x34.

开始的页面部分

可以构建一个可执行文件,其中 .text 从偏移量 4096 开始(在 ELF header 和程序之间留下一个大洞headers 和文本),然后这样的可执行文件可以具有偏移量为 4096 的第一个 PT_LOAD 段。这并不常见:文件中浪费的 space 通常不值得节省 52 字节的内存。