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.