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

tbo*_*odt 5 c linux elf

我将此程序编译-m32 -nostdlib为 ELF 可执行文件:

void _start() {}
Run Code Online (Sandbox Code Playgroud)

当我这样做时,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 '\177'      69 'E'  76 'L'  70 'F'
Run Code Online (Sandbox Code Playgroud)

为什么这有用?

Emp*_*ian 3

我很惊讶地发现 LOAD 段上的偏移量是 0x000000

你为什么感到惊讶?

因为这意味着可执行标头将与文本段同时加载到内存中。

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

正如这个答案所解释的,可执行文件是mmaped 的并且可以在整个mmap页面上运行;您无法映射从 offset 开始的页面部分。0x34

可以构建一个从.textoffset 开始的可执行文件4096(在 ELF 标头和程序标头和文本之间留下一个大洞),然后这样的可执行文件可以具有带有PT_LOADoffset 的第一个段4096。这种做法并不常见:文件中浪费的空间通常不值得节省 52 字节的内存。

  • 哦,我以为 mmap 可以让你在文件中的任何位置指定偏移量 (2认同)