ELF目标文件格式的最前部是ELF文件头(ELF Header),它包含了描述整个文件
的基本属性,比如ELF文件版本、目标机器类型、程序入口地址等,紧接着是
ELF文件各个段。ELF文件中与段最有关的数据结构就是段表(Section Header Table)
,该表描述了ELF文件包含的所有段的信息,比如每个段的段名、段的长度、
在文件中的偏移、读写权限以及段的其他属性。
3.2.1 ELF文件头
ELF文件头定义了ELF魔数、文件机器字节长度、数据存储方式、版本、运行
平台、ABI版本、ELF重定位类型、硬件平台、硬件平台版本、入口地址、程序
头入口和长度、段表的位置和长度、段的数量等。
ELF文件有32为版本和64位版本,ELF文件头结构也有这两种版本,分别叫做
“Elf32_Ehdr”和“Elf64_Ehdr”。其中Elf32_Ehdr为一个结构体,定义如下:
typedef struct {
unsigned char e_indent[16];
Elf32_Half e_type;
Elf32_Half e_machine; //Elf32_Half为32位版本无符号短整形 长度2字节
Elf32_Word e_version; //Elf32_Word为32位版本有符号整形 长度4字节
Elf32_Addr e_entry;
Elf32_Off e_phoff; //Elf32_Off为32位版本的偏移地址 长度4字节
Elf32_Off e_shoff;
Elf32_Word e_flags;
Elf32_Half e_ehsize;
Elf32_Half e_phentsize;
Elf32_Half e_phnum;
Elf32_Half e_shentsize;
Elf32_Half e_shnum;
Elf32_Half e_shstrndx;
}Elf32_Ehdr;
我们可以用readelf -h *.o来查看可执行文件的文件头。
ELF魔数
ELF文件的文件头为ELF魔数,形如:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
其中最开始的四个字节:0x7f 0x45 0x4c 0x46是所有ELF文件必须相同的标识码,
第一个字节对应ASCII字符里面的DEL控制符,后面三个字节刚好是E L F这三个
字母的ASCII码,这四个字节又成为ELF文件的魔数,几乎所有的可执行文件开始
的几个字节都是魔数。操作系统在加载可执行文件的时候会确认魔数是否正确,
如果不正确会拒绝加载。
Magic第5个字节0x01用来表示ELF文件类,0x01表示是32位,0x02表示是64位。
第6个字节是字节序,0x01表示是小端格式,0x02表示是大端格式。第7个字节
规定ELF文件的主版本号,一般是1。后面的9个字节ELF没有定义。
文件类型
e_type成员表示ELF文件类型,系统通过这个常量来判断ELF文件的真正类型,
而不是文件的扩展名。ELF文件类型有如下三种:
ET_REL 1 可重定位文件,一般为.o文件
ET_EXEC 2 可执行文件
ET_DYN 3 共享目标文件,一般为.so文件
机器类型
ELF文件格式被设计成可以在多个平台下使用,这并不表示同一个ELF文件可以
在不同的平台下使用,而是表示不同平台下的ELF文件遵循同一套ELF标准。
e_machine成员就表示ELF文件的平台属性,比如3表示该ELF文件只能在Intel X86
平台下使用。