本文最后更新于:2020年6月27日 晚上
* 总结的速度,追不上看书的速度了。。。 *
第三章 目标文件里面有什么
ELF文件的基本结构是什么样子?
ELF目标文件的最前部是ELF 文件头(ELF Header),其包含描述整个文件的基本属性,如ELF文件版本、目标机器型号、程序入口地址等。接着是各段。之后为段表(Section Header Table),该表描述了ELF文件包含的所有段的信息,如短的段名、段的长度、在文件中的偏移、读写权限及段的其他属性。
ELF文件头中定义了ELF魔数、文件机器字节长度、数据存储方式、版本、运行平台、ABI版本、ELF重定位类型、硬件平台、硬件平台版本、入口地址、程序头入口和长度、段表的位置和长度及段的数量。ELF文件头结构及相关常数被定义在“/usr/include/elf.h”。
//32位文件结构头 typedef struct { unsigned char e_ident[16];//魔数 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;//段表描述符大小,一般为sizeof(Elf32_Shdr) ELF32_Half e_shnum;//段描述符数量,等于文件中拥有段的数量 //Seciton header sting table index ELF32_Half e_shstrndx;//段表字符串表所在的段在段表中的下标 }ELF32_Ehdr;
- ELF文件头最前面的“Magic”的16个字节对应“ELF32_Ehdr“的e_ident成员,用来标识ELF文件的平台属性。
- 前四个字节为ELF文件统一标识码,为0x7F、0x45、0x4c、0x46.分别对应ASCII字符中的DEL控制符、E、L、F。第五个字节用来标识ELF文件类。第六个字节规定ELF文件大小端。第七个字节规定ELF文件主版本号。后九个未定义,填0。
段表(Section Header Table)保存着段的基本属性的结构,它描述了各段的信息,如段的段名、段的长度、在文件中的偏、读写权限及段的其他属性。段结构由段表决定,编译器、连接器依靠段表定位和访问各段的属性。段表的位置由文件头的”e_shoff“决定。
//段描述符结构 typedef struct { //段名是一个字符串,位于.shstrtab字符串表。sh_name是段名字符串在.shstrtab中的偏移 Elf32_Word sh_name; Elf32_Word sh_type;//段的类型 Elf32_Word sh_flags;//段的标志位 //段虚拟地址,若该段可以被加载则sh_addr为该段被加载后在进程地址空间中的虚拟的地址;否则为0 Elf32_Addr sh_addr; //段偏移,如果该段存在于文件中,则表示该段在文件中的偏移,否则无意义如.bss段 Elf32_Off sh_offset; Elf32_Word sh_size;//段的长度 Elf32_Word sh_link;//段链接信息 Elf32_Word sh_info;//段链接信息 //段地址对齐,地址对齐的数量都是2的指数倍,sh_addralign表示地址对齐数量中的指数 Elf32_Word sh_addralign; //项的长度,有些段包含固定大小的项,如符号表所包含的每个符号大小一样;若不包含固定大小的项,则为0 Elf32_Word sh_entsize; }Elf32_Shdr;
- 段表是一个以”Elf32_Shdr“ ——段描述符(Section Description)结构体为元素的数组。数组元素的个数等于段的个数,每个”Elf32_Shdr“结构体对应一个段。ELF段表的数组的第一个元素是无效的段描述符,其类型为NULL。Elf32_Shdr被定义在”/usr/include/elf.h“中
更复杂的ELF文件结构:
重定位表(Relocation Table),类型(sh_type)为”SHT_REL“。链接器在处理目标文件时,须要对目标文件中的某些部位进行重定位,即代码段和数据段中对绝对地址引用的位置。重定位信息都记录在重定位表中,每个须要重定位的段都会有一个相应的重定位表。一个重定位表同时也是ELF的一个段。
因为字符串的长度是不固定的,所以常见的表示方法是把字符串集中起来存放到一个表,然后使用字符串在表中的偏移来引用字符串。在ELF文件中引用字符串只须给出一个数字下标即可,不用考虑字符串长度的问题。
一般字符串表在ELF文件中以段的形式保存,常见段字符串表(String Table)”.strtab“和段表字符串表(Section Header String Table)”.shstrtab“。字符串表保存普通的字符串,如符号的名字;段表字符串表保存段表中用到的字符串,如段名(sh_name)。
分析ELF文件头,得到段表和段表字符串表的位置,继而解析整个ELF文件
* 下次就是静态链接了。。。Link! *
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!