ELF文件详解
參考1:ELF文件格式解析
參考2:elf文檔
1 介紹
1.1 分類
ELF全稱是Executable and Linking Format。它是對象文件格式(object file format)。對象文件分為以下三類:
- 可重定位文件(relocatable file):包含與其他對象文件鏈接生成可執行文件或共享的對象文件的代碼和數據。
- 可執行文件(executable file):是一個可執行程序。
- 共享對象文件(shared object file):共享對象文件包含適合在兩個上下文中鏈接的代碼和數據。首先,鏈接編輯器(link editor)可以將其與其他可重定位和共享的對象文件一起處理,以創建另一個對象文件。其次,動態鏈接器將其與可執行文件和其他共享對象結合起來,以創建進程映像。
1.2 視圖
我們可以從鏈接視圖和執行視圖這兩個視圖來看ELF。
從上圖可以看出,大致可分為四部分,分別是ELF Header、Program Header Table、Section/Segment、Section Header Table。其中鏈接視圖以Section為單位,執行視圖以Segment為單位。
- ELF Header位于文件的開頭,它描述文件組織的“路線圖”
- Program Header Table 描述了系統如何創建進程映像
- Section Header Table 包含描述文件section的信息
- Section 或 Program :segments是從運行的角度來描述elf文件,sections是從鏈接的角度來描述elf文件
注:Program Header Table 與 Section Header Table 在文件中并無固定順序。
1.3 數據表示
對象文件格式支持8位字節和32位字節的處理器體系結構。下面是32位的數據類型。
2 ELF Header
ELF Header的結構體如下所示:
#define EI_NIDENT 16 typedef struct {unsigned char e_ident[EI_NIDENT];ELF32_Half e_type;ELF32_Half e_machine;ELF32_Word e_version;ELF32__Addr e_entry;ELF32_Off e_phoff;ELF32_Off e_shoff;ELF32_Word e_flags;ELF32_Half e_ehsize;ELF32_Half e_phentsize;ELF32_Half e_phnum;ELF32_Half e_shentsize;ELF32_Half e_shnum;ELF32_Half e_shstrndx; }Elf32_Ehdr;| e_ident | ELF的標識信息。將文件標記為對象文件,并提供獨立于機器的數據,用于解碼和解釋文件內容。 |
| e_type | 標識對象文件類型,0表示可重定位文件,1表示可執行文件,2表示共享對象文件 |
| e_machine | 文件所需的體系結構 |
| e_version | 對象文件的版本,0表示不合法版本,1表示當前版本 |
| e_entry | 程序入口的虛擬地址,若無則置0 |
| e_phoff | 以字節為單位保存Program Header Table的文件偏移量 |
| e_shoff | 以字節為單位保存Section Header Table的文件偏移量 |
| e_flags | 與文件相關但不同于處理器的標志 |
| e_ehsize | 以字節為單位保存ELF Header的大小 |
| e_phentsize | 以字節為單位保存每個Program Header Table的大小 |
| e_phnum | 以字節為單位保存Program Header Table的數量 |
| e_shentsize | 以字節為單位保存Section Header Table的大小 |
| e_shnum | 以字節為單位保存Section Header Table的數量 |
| e_shstrndx | Section Header Table的位置 |
(1)e_ident
- EI_MAG0 到 EI_MAG3表示魔數(magic number):用來標記文件是一個ELF對象文件。
- EI_CLASS:標識文件類。取值0、1、2分別表示Invalid class、32-bit objects、64-bit objects.
- EI_DATA:處理器特定數據的數據編碼方式。ELFDATANONE(0)指非法數據編碼;ELFDATA2LSB(1)指高位在前;ELFDATA2MSB(2)指低位在前。
- EI_VERSION:ELF的版本號。
- EI_PAD:e_ident 中未使用字節的起始。
(2)e_type
(3)e_machine
3 Section Header Table
Section Header Table 的結構體如下所示。
typedef struct{Elf32_Word sh_name; Elf32_Word sh_type; Elf32_Word sh_flags; Elf32_Addr sh_addr; Elf32_Off sh_offset; Elf32_Word sh_size; Elf32_Word sh_link; Elf32_Word sh_info; Elf32_Word sh_addralign; Elf32_Word sh_entsize; }Elf32_Shdr;| sh_name | Section名 |
| sh_type | Section類型 |
| sh_flags | Section標志 |
| sh_addr | Section的第一個字節應處的位置。否則,此字段為0。 |
| sh_offset | Section 第一個字節與文件頭之間的偏移 |
| sh_size | 以字節為單位表示Section的長度 |
| sh_link | Section Header Table的索引鏈接。 |
| sh_info | 附加信息,其解釋依賴于節區類型 |
| sh_addralign | 地址對齊約束 |
| sh_entsize | 某些Section 中包含固定大小的項目,如符號表。對于這類節區,此成員給出每個表項的長度字節數 |
(1)sh_type
- SHT_NULL:Section頭部是不活躍的,缺乏相關Section,該Section的其他成員限值無意義。
- SHT_PROGBITS:該Section的形式和含義僅由程序決定。
- SHT_SYMTAB 和SHT_DYNSYM:含有符號表
- SHT_STRTAB:含有字符串表
- SHT_RELA:含有重定位表項,含補齊
- SHT_HASH:含有符號哈希表
- SHT_DYNAMIC:含有動態鏈接信息
- SHT_NOTE:含有標記文件信息
- SHT_NOBITS:不占空間但類似于SHT_PROGBITS
- SHT_REL:含有重定位表項,不含補齊
- SHT_SHLIB:語義未規定
- SHT_LOPROC 到SHT_HIPROC:此范圍中的值是為處理器專用語義保留的。
- SHT_LOUSER:應用程序的索引下界
- SHT_HIUSER:應用程序的索引上界
(2)sh_flags
Program Header Table
Program Header Table結構體如下所示。
typedef struct { Elf32_Word p_type; Elf32_Off p_offset; Elf32_Addr p_vaddr; Elf32_Addr p_paddr; Elf32_Word p_filesz; Elf32_Word p_memsz; Elf32_Word p_flags; Elf32_Word p_align; } Elf32_phdr;| p_type | Segment類型 |
| p_offset | 從文件頭到該Segment第一個字節的偏移 |
| p_vaddr | Segment第一個字節將被放到內存中的虛擬地址 |
| p_paddr | Segment的物理地址 |
| p_filesz | Segment中文件映像的字節數 |
| p_memsz | Segment中內存映像的字節數 |
| p_flags | Segment標記 |
| p_align | 與內存和文件中Segment對齊的值 |
(1)p_type
- PT_NULL:此數組元整未使用
- PT_LOAD:此數組元素給出一個可加載的段,段的大小由 p_filesz 和 p_memsz描述。
- PT_DYNAMIC:數組元素給出動態鏈接信息
- PT_INTERP:數組元素給出一個 NULL 結尾的字符串的位置和長度,該字符串將被當作解釋器調用
- PT_NOTE:此數組元素給出附加信息的位置和大小
- PT_SHLIB:Segment類型被保留,不過語義未指定
- PT_PHDR:此類型的數組元素如果存在,則給出了程序頭部表自身的大小和位置,既包括在文件中也包括在內存中的信息
- PT_LOPROC 到PT_HIPROC:此范圍的類型保留給處理器專用語義
總結
- 上一篇: ARM中各始终之间的关系,FCLK HC
- 下一篇: 网络:TCP通讯之 time_wait