ELF文件格式有32位及64位的两种,本质上差别不是很大,主要关注ELF 32位的文件处理方式。
整体文件格式
ELF为Executable and Linking Format的缩写,为编译生成的目标文件,编译生成的目标文件有几种格式 relocatable file、executable file 和 shared Object file三种,linking file 及 Execution file的格式如下:
在图示的各个元素中,只有ELF header要求严格固定的位置,其他模块的位置可以变化。在ELF header中可以配置 Program header table及 Section header table的偏移位置,以及相应的个数和占用字节大小等等,目前主要关心Linking file的组成格式。
元素类型定义
由于不同的机器环境对数据表达的空间格式存在差异,ELF文件的数据格式大小做了如下规定:
ELF Header结构
其中包含了program header的信息: phoff 偏移,phnum个数,phentsize大小,section header的信息: shoff 偏移、shnum section的个数及 section的大小 shentsize等。
Section Header的结构
section header结构体重包含了相应名字,地址、文件中的偏移、大小等等。一些特殊的section命名如下,包含了我们常用的.bss 堆栈段、.data数据段、.text代码段等等:
program header格式
Program header结构中包含偏移 offset、虚拟地址、物理地址等,program header的内容仅仅对excutable 和 shared object的文件有效。
Linking file的工作方式理解
在编译link的时候可以生成elf文件,而编译过程中可以设置相应内容存放位置,对应在elf文件中的不同section,在处理elf文件时,通过ELF header获取相应信息,得到section header table的位置,而section header table 的信息将相应的编译结果分段存放elf文件中。通过elf文件的信息,可以生成相应的二进制文件,在GNU编译系统中,通过工具objcopy转换得到。
如下所示 编译处理的过程,个人理解 c 源文件需要转换为.s 再编译为.o,抑或至少先编译成.o文件才相对更为合理。
简述ELF 64位格式
ELF 64位的数据定义如下,可以看到其和32位的数据格式定义存在一些变化
在数据类型的定义中 unsigned char的大小没有发生变化,所以在elf header的定义中e_ident的结构不会发生变化,在e_ident中定义了一个元素用来指示文件格式为ELF32或ELF64。