ELF文件格式依然是分为文件头和文件体两部分,只是该文件头相对稍显复杂,类似层次化结构,先用个ELF header从“全局上”给出程序文件的组织结构,概要出程序中其它头表的位置大小等信息,如程序头表的大小及位置、节头表的大小及位置。然后,各个段和节的位置、大小等信息再分别从“具体的”程序头表和节头表中予以说明。
ELF格式的作用体现在两方面,一是链接阶段,另一方面是运行阶段,故它们在文件中组织布局咱们也从这两方面展示,如图:
无论是在待重定位文件,还是可执行文件中,文件最开头的部分必须是elf header,这就是前面咱们所说的固定的位置。在ELF header之后紧挨着的是程序头表,这对于可执行文件是必须存在的,而对于待重定位文件是可选的。其它成员的位置要取决于各头表中的说明。坦白说,刚接触elf之初并不容易理解它,所以,之后咱们会以一个实际例子来细说,这里咱们先有个笼统的认识。
咱们马上要步入正题啦,在此之前必须要提前跟大伙儿交待一下,以下咱们书中有关elf的任何定义,包括变量、常量及取值范围,都可以在linux系统的/usr/include/elf.h中找到,这里面的定义才是最全最权威的。为了方便大家学习,本书中从elf.h中搬了必要的部分,有的并不全面,只是起到帮助大家阅读本书的作用。
一切就绪,咱们开始正式介绍elf结构。
一些重要的数据结构中用到了自定义的数据类型,所以先给大家介绍一下它们,免得造成学习的困扰,请大伙见表
好啦,现在咱们从上至下,依次揭开各层header的庐山真面目。咱们这里先介绍ELF header的结构。
c语言中的结构体能够很直观地表示物理内存结构,所以用结构体的形式展现一个数据结构是最合适不过的啦,所以咱们结合图5-35,依次介绍下各结构体成员的意义。
e_ident[16]是16字节大小的数组,用来表示elf字符等信息,开头的4个字节是固定不变的,是elf文件的魔数,它们分别是0x7f,以及字符串ELF的asc码:0x45,0x4c,0x46。对于此数组说明如下表