elf是什么意思 elf是什么意思英语( 二 )


*.o*.soe_entry 是程序的入口虚拟地址 , 注意不是main函数的地址,而是 .text 段的首地址 _start。当然这也要求程序本身非PIE( -no-pie )编译的且ASLR关闭的情况下,对于非 ET_EXEC 类型通常并不是实际的虚拟地址值 。
其他的字段大多数是指定Section Header( e_sh )和Program Header( e_ph )的信息 。Section/Program Header Table本身可以看做是数组结构,ELF头中的信息指定对应Table数组的位置、长度、元素大小信息 。最后一个 e_shstrndx 表示的是section table中的第 e_shstrndx 项元素,保存了所有section table名称的字符串信息 。
Section Header上节说了section header table是一个数组结构,这个数组的位置在 e_shoff 处,共有 e_shnum 个元素(即section),每个元素的大小为 e_shentsize 字节 。每个元素的结构如下:
typedef struct{Elf32_Word sh_name;/* Section name (string tbl index) */Elf32_Word sh_type;/* Section type */Elf32_Word sh_flags;/* Section flags */Elf32_Addr sh_addr;/* Section virtual addr at execution */Elf32_Off sh_offset;/* Section file offset */Elf32_Word sh_size;/* Section size in bytes */Elf32_Word sh_link;/* Link to another section */Elf32_Word sh_info;/* Additional section information */Elf32_Word sh_addralign;/* Section alignment */Elf32_Word sh_entsize;/* Entry size if section holds table */} Elf32_Shdr;其中 sh_name 是该section的名称,用一个word表示其在字符表中的偏移 , 字符串表(.shstrtab)就是上面说到的第 e_shstrndx 个元素 。ELF文件中经常使用这种偏移表示方式,可以方便组织不同区段之间的引用 。
sh_type 表示本section的类型,SPEC中定义了几十个类型,列举其中一些如下:
SHT_NULL: 表示该section无效,通常第0个section为该类型SHT_PROGBITS: 表示该section包含由程序决定的内容 , 如 .text 、 .data 、 .plt 、 .gotSHT_SYMTAB/SHT_DYNSYM: 表示该section中包含符号表,如 .symtab 、 .dynsymSHT_DYNAMIC: 表示该section中包含动态链接阶段所需要的信息SHT_STRTAB: 表示该section中包含字符串信息 , 如 .strtab 、 .shstrtabSHT_REL/SHT_RELA: 包含重定向项信息虽然每个section header的大小一样(e_shentsize字节),但不同类型的section有不同的内容,内容部分由这几个字段表示:
sh_offset: 内容起始地址相对于文件开头的偏移sh_size: 内容的大小sh_entsize: 有的内容是也是一个数组 , 这个字段就表示数组的元素大小与运行时信息相关的字段为:
sh_addr: 如果该section需要在运行时加载到虚拟内存中,该字段就是对应section内容(第一个字节)的虚拟地址sh_addralign: 内容地址的对齐,如果有的话需要满足 sh_addr % sh_addralign = 0sh_flags: 表示所映射内容的权限,可根据 SHF_WRITE/ALLOC/EXECINSTR 进行组合另外两个字段 sh_link 和 sh_info 的含义根据section类型的不同而不同,如下表所示:

至于不同类型的section,有的是保存符号表,有的是保存字符串,这也是ELF表现出拓展性和复杂性的地方,因此需要在遇到具体问题的时候查看文档去进行具体分析 。
Program Headerprogram header table用来保存程序加载到内存中所需要的信息,使用段(segment)来表示 。与section header table类似,同样是数组结构 。数组的位置在偏移 e_phoff 处 , 每个元素(segment header)的大小为 e_phentsize,共有 e_phnum 个元素 。单个segment header的结构如下:
typedef struct{Elf32_Word p_type;/* Segment type */Elf32_Off p_offset;/* Segment file offset */Elf32_Addr p_vaddr;/* Segment virtual address */Elf32_Addr p_paddr;/* Segment physical address */Elf32_Word p_filesz;/* Segment size in file */Elf32_Word p_memsz;/* Segment size in memory */Elf32_Word p_flags;/* Segment flags */Elf32_Word p_align;/* Segment alignment */} Elf32_Phdr;既然program header的作用是提供用于初始化程序进程的段信息,那么下面这些字段就是很直观的:

推荐阅读