Program header (Phdr)
program header 是一个 array of structures,每一个描述了 a segment 或者是系统需要的程序执行的信息。
一个 object 文件的 segment 包含一个或几个 sections。program header 只有在 executable 和 shared
object file 中才有意义。ELF header 中的 e_phentsize 和 e_phnum 说明了一个文件它自己的 program
header 的大小。ELF program header 的结构体是 Elf32_Phdr 或者是 Elf64_Phdr,用哪个看结构:
typedef struct {
uint32_t p_type;
Elf32_Off p_offset;
Elf32_Addr p_vaddr;
Elf32_Addr p_paddr;
uint32_t p_filesz;
uint32_t p_memsz;
uint32_t p_flags;
uint32_t p_align;
} Elf32_Phdr;
typedef struct {
uint32_t p_type;
uint32_t p_flags;
Elf64_Off p_offset;
Elf64_Addr p_vaddr;
Elf64_Addr p_paddr;
uint64_t p_filesz;
uint64_t p_memsz;
uint64_t p_align;
} Elf64_Phdr;
两种结构最大不同就是lies in the location of the p_flags member in the total struct.
p_type
这个成员表面了:这个 array element 描述了这个 segment 是什么类型,或者如何去
说明 这个 array element 的信息。
PT_NULL 没有被使用,而且其他的成员的值没有被定义。这个让这个 program header
忽略 entries。
PT_LOAD 这是一个 loadable segment,p_filesz 和 p_memsz 描述它。文件的大小
are mapped to the memory segment 的开始。(实在是不好翻译)如果此
segment 的 memory size——p_memsz 比文件大小 p_filesz 大,the "extra"
bytes are defined to hold the value 0 and to follow the segment's
initialized area. file size 也许不会比 memory size 大。 program header
中出现的 loadable segment 是按升序排序的,sorted on p_vaddr。
PT_DYNAMIC
这种格式代表的是 dynamic linking 信息。
PT_INTERP
The array element specifies the location and size of a null-terminated
pathname to invoke as an interpreter. (我实在是不知道怎么翻译这句话)
这种格式只有对可执行文件才有意义(没准对 share object 也有用)。然而,
在一个文件种此种格式的段最多出现一次。If it is present, 它一定要在
所有 loadable segment 之前出现。
PT_NOTE location of notes(ElfN_Nhdr)
PT_SHLIB 保留字段但是在语义上还没有被定义。只要有这种格式段的程序就不会符合 ABI。
PT_PHDR 如果存在,表示的是 location 和 program header 的大小,也就是自己的大小,
在内存种和在镜像中都是这样。此段类型在文件中不能出现超过一次。此外,也许只有
在 program header table 是程序在 memory image 一部分的时候才会出现。如果它
存在,它必须先于任何可加载的部分条目。
PT_LOPROC, PT_HIPROC
[PT_LOPROC, PT_HIPROC]are reserved for processor-specific semantics.
PT_GNU_STACK
linux内核使用的GNU扩展,通过p_flags中的标志去控制的 the state of the stack。
p_offset
保存的是从文件中的段的开始偏移量。
p_vaddr
和p_offset一样,不过是在虚拟地址中。
p_paddr
和物理地址相关,是为了段的物理地址所保留的。在BSD系统中没有被使用并且必须是0.
p_filesz
段在 file image 中的大小,也许是0.
p_memsz
段在 memory image 中的大小,也许是0.
p_flags
为段使用的按位操作的标志:
PF_X 可执行的段。
PF_W 可写段。
PF_R 可读段。
text segment 一般有 PF_X 和 PX_R 权限。 data segment 一般3种都有。
p_align
段在内存和文件中对齐的值。loadable process segment 为了 p_vaddr 和
p_offset 一定要有合适的值,modulo 页大小。0和1代表没有对齐要求。否则,
一定是一个正的integral power of two(2的积分幂),p_vaddr should equal
p_offset, modulo p_align.