![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5iNlljZ3QzNwcTZlljMxEDZ3IjZyMGM5MzM3IjZ4ATY48CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
常見的ELF檔案大緻結構如下:
常見的ELF格式如上圖所示,左邊為連結視圖,右邊為執行視圖。
連結視圖:靜态連結器(即編譯後參與生成最終ELF過程的連結器,如ld )會以連結視圖解析ELF。編譯時生成的 .o(目标檔案)以及連結後的 .so (共享庫)均可通過連結視圖解析,連結視圖可以沒有段表(如目标檔案不會有段表)。
執行視圖:動态連結器(即加載器,如x86架構 linux下的 /lib/ld-linux.so.2或者安卓系統下的 /system/linker均為動态連結器)會以執行視圖解析ELF并動态連結,執行視圖可以沒有節表。
檔案頭ELF的結構聲明位于系統頭檔案 elf.h 中,ELF格式分為32位與64位兩種,除了重定位類型稍有差別,其它大緻相同,為了簡化描述,後續說明将省略32/64字樣。
ELF Header的聲明如下 :
#define EI_NIDENT (16)
typedef struct
{
unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
Elf_Half e_type; /* Object file type */
Elf_Half e_machine; /* Architecture */
Elf_Word e_version; /* Object file version */
Elf_Addr e_entry; /* Entry point virtual address */
Elf_Off e_phoff; /* Program header table file offset */
Elf_Off e_shoff; /* Section header table file offset */
Elf_Word e_flags; /* Processor-specific flags */
Elf_Half e_ehsize; /* ELF header size in bytes */
Elf_Half e_phentsize; /* Program header table entry size */
Elf_Half e_phnum; /* Program header table entry count */
Elf_Half e_shentsize; /* Section header table entry size */
Elf_Half e_shnum; /* Section header table entry count */
Elf_Half e_shstrndx; /* Section header string table index */
} Elf_Ehdr;
e_ident 包含了Maigc Number和其它資訊,共16位元組。
0~3:前4位元組為Magic Number,固定為ELFMAG。
4(EI_CLASS):ELFCLASS32代表是32位ELF,ELFCLASS64 代表64位ELF。
5(EI_DATA):ELFDATA2LSB代表小端,ELFDATA2MSB代表大端。
6(EI_VERSION):固定為EV_CURRENT(1)。
7(EI_OSABI):作業系統ABI辨別(實際未使用)。
8(EI_ABIVERSION):ABI版本(實際 未使用)。
9~15:對齊填充,無實際意義。
e_type ELF的檔案類型,定義如下:
ET_REL 可重定位文 件(如目标檔案)
ET_EXEC 可執行檔案(可直接執行的檔案)
DT_DYN 共享目标檔案(如SO庫)
DT_CORE Core檔案(吐核檔案)
注:GCC使用編譯選項 -pie 編譯的可執行檔案實際 也是DT_DYN類型。
e_machine
e_verison
檔案版本,目前常見的ELF 檔案版本均為EV_CURRENT(1)。
e_entry
入口虛拟位址。
e_phoff
段表檔案偏移。
e_shoff
節表檔案偏移。
e_flags
處理器特定的标志,一般為0。
e_ehsize
Elf_Header的大小(位元組)
e_phentsize
段頭(Program Header)的大小(位元組)。
e_phnum
段的數量。
e_shentsize
節頭(Section Header)的大小(位元組)。
e_shnum
字的數量。
e_shstrndx
節字元串表的節索引。
更多技術相關文章:Virbox技術部落格