p_align
字段的
目的到底是什么?每个在线来源都只说了一些模糊的话,说段的“必需对齐”,或者只是说它是一个值,所以
p_vaddr = p_offset mod p_allign
。使用 readelf
,我可以看到 LOAD 段的 p_align
为 4KB。 p_align
为 4KB 的模语句在数学上保证了将 mmap
文件页面存储到内存页面以正确加载段的可能性。这是我看到的 p_align
的唯一实用程序。但 LOAD 段的 p_align
无论如何都需要页面大小,所以没有目的吗?
字段的具体用途是什么?p_align
可以使用
mmap
将 LOAD
段带入内存。
我可以看到
段的LOAD
为 4KB。p_align
为 4KB 的模语句在数学上保证了将p_align
文件页面存储到内存页面以正确加载段的可能性。mmap
某些架构具有不同的页面大小。例如,
powerpc64
页面大小为 64KB,为其链接的二进制文件将具有 p_align == 0x10000
。
此外,
x86_64
支持多种页面大小,如果您希望能够使用例如二进制文件有 2MiB 页,那么您需要适当设置对齐方式:
echo "int main() { return 0; }" | gcc -xc - -Wl,-z,max-page-size=0x200000
readelf -Wl ./a.out
Elf file type is EXEC (Executable file)
Entry point 0x600020
There are 13 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000040 0x0000000000400040 0x0000000000400040 0x0002d8 0x0002d8 R 0x8
INTERP 0x000318 0x0000000000400318 0x0000000000400318 0x00001c 0x00001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x000000 0x0000000000400000 0x0000000000400000 0x0004b8 0x0004b8 R 0x200000
LOAD 0x200000 0x0000000000600000 0x0000000000600000 0x000121 0x000121 R E 0x200000
LOAD 0x400000 0x0000000000800000 0x0000000000800000 0x00009c 0x00009c R 0x200000
LOAD 0x5ffe38 0x0000000000bffe38 0x0000000000bffe38 0x0001cc 0x0001d0 RW 0x200000
DYNAMIC 0x5ffe48 0x0000000000bffe48 0x0000000000bffe48 0x000190 0x000190 RW 0x8
...
事实上,2MB 页面曾经是
x86_64
上的默认页面,正是因为有人可能决定使用 2MB(又名巨大)页面,直到默认值在 this commit 中更改为 4KB。