接上文,为了描述清楚文件格式的本质,咱们先从最基本的“段”说起。
程序中最重要的部分就是段(segment)和节(section),它们是真正的程序体,是真真切切的程序资源,所以下面的说明咱们以它们为例。程序中有很多段,如代码段和数据段等,同样也有很多节,段是由节来组成的,多个节经过链接之后就被合并成一个段了,之前咱们有通过实例解释过segment和section之间的关系。
段和节的信息也是用header来描述的,程序头是program header,节头是section header。
程序中段的大小和数量是不固定的,节的大小和数量也不固定,因此需要为它们专门找个数据结构来描述它们,这个描述结构就是程序头表(program header table)和节头表(section header table)。既然程序头表和节头表都称为表,这说明里面存储的是多个程序头program header和多个节头section header的信息,故这两个表相当于数组,数组元素分别是程序头program header和节头section header。再次强调,这两个表是用来将汇总程序头和节头的表,表中元素是头信息。也就是说程序头表(program header table)中的元素全是程序头(program header),而节头表(section header table)中的元素全是节头(section header)。虽然上面是将两个表一块说明的,但表中的元素全是单一的,不会在程序头表中存在节头信息。
在表中,每个成员(数组元素)都统称为条目,即entry,一个条目代表一个段或一个节的头描述信息。对于程序头表,它本质上就是用来描述段(segment)的,所以您也可以称它为段头表。从名字上就能够看出,段等同于程序,所以将描述段信息的表说成program header table,可见“段”才是程序本身的组成部分。
由于程序中段和节的数量不固定,程序头表和节头表的大小自然也就不固定了,而且各表在程序文件中的存储顺序自然也要有个先后,故这两个表在文件中的位置也不会固定。因此,必须要在一个固定的位置,用一个固定大小的数据结构来描述程序头表和节头表的大小及位置信息,这个数据结构便是ELF header,它位于文件最开始的部分,并具有固定大小,一会咱们看elf header的数据结构就知道了。
ELF header是个用来描述各种“头”的“头”,程序头表和节头表中的元素也是程序头和节头,可见,elf文件格式的核心思想就是头中嵌头,是种层次化结构的格式。