关于ELF
  可执行与可链接格式(Executable and Linkable Format,ELF),常被称为 ELF格式,是一种用于可执行文件、目标代码、共享库和核心转储(core dump)的标准文件格式。  
  ELF文件格式在链接和程序的运行阶段的格式不同。链接阶段每个.o文件都是一个独立的ELF文件,为了效率和便利性将他们的节合并为段才能生成对应的可执行文件。
一个ELF文件包含的内容有:ELF文件头,程序头表,节头表和节。

数据类型和大小
32bit的ELF文件
| 类型 | 
大小 | 
| unsigned char | 
1 | 
| Elf32_Addr | 
4 | 
| Elf32_Half | 
2 | 
| Elf32_Off | 
4 | 
| Elf32_SWord | 
4 | 
| Elf32_Word | 
4 | 
64位的ELF文件
| 类型 | 
大小 | 
| unsigned char | 
1 | 
| Elf32_Addr | 
8 | 
| Elf32_Half | 
2 | 
| Elf32_Off | 
8 | 
| Elf32_Xword | 
8 | 
| Elf32_Word | 
4 | 
ELF 文件头
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
   | #define EI_NIDENT	16
  typedef struct {   unsigned char e_ident[EI_NIDENT];       Elf64_Half e_type;               Elf64_Half e_machine;           Elf64_Word e_version;           Elf64_Addr e_entry;           Elf64_Off e_phoff;           Elf64_Off e_shoff;           Elf64_Word e_flags;           Elf64_Half e_ehsize;           Elf64_Half e_phentsize;           Elf64_Half e_phnum;           Elf64_Half e_shentsize;           Elf64_Half e_shnum;           Elf64_Half e_shstrndx;         } Elf64_Ehdr;
   | 
 
需要注意的几个字段:  
- e_entry: 可执行程序入口点地址
 
- e_phoff: 程序头表偏移地址
 
- e_shoff: 节头表偏移地址
 
- e_ehsize: ELF头部的大小
 
- e_phentsize: 程序头表中每个条目的大小
 
- e_phnum: 程序头表中的条目数量。
 
- e_shentsize: 节头表中每个条目的大小
 
- e_shnum: 节头表中的条目数量
 
- e_shstrndx: 节头字符串表索引
 
程序头表
1 2 3 4 5 6 7 8 9 10 11
   | typedef struct {   Elf64_Word    p_type;                 Elf64_Word    p_flags;           Elf64_Off    p_offset;           Elf64_Addr    p_vaddr;           Elf64_Addr    p_paddr;           Elf64_Xword    p_filesz;           Elf64_Xword    p_memsz;           Elf64_Xword    p_align;         } Elf64_Phdr;
   | 
 
- p_offset: 段相对于文件的偏移地址
 
- p_vaddr: 段在内存中的虚拟地址
 
- p_paddr: 段的物理地址
 
- p_filesz: 段在文件中所占的大小
 
- p_memsz: 段在内存中所占的大小
 
- p_align: 对齐长度
 
节头表
1 2 3 4 5 6 7 8 9 10 11 12
   | typedef struct {     Elf64_Word    sh_name;     Elf64_Word    sh_type;     Elf64_Xword    sh_flags;     Elf64_Addr    sh_addr;     Elf64_Off    sh_offset;     Elf64_Xword    sh_size;     Elf64_Word    sh_link;     Elf64_Word    sh_info;     Elf64_Xword    sh_addralign;     Elf64_Xword    sh_entsize; } Elf64_Shdr;
  | 
 
- sh_name: 节名称,是节区头字符串表节区中(Section Header String Table Section)的索引,因此该字段实际是一个数值。在字符串表中的具体内容是以 NULL 结尾的字符串。
 
- sh_type: 节类型
 
- sh_addr: 节在内存中的地址
 
- sh_offset: 节在文件中的偏移
 
- sh_size: 节的大小
 
- sh_addralign: 节的地址对齐长度