目标文件格式支持各种8位字节、32位架构的处理器,而且打算支持更大或更小的架构。所以目标文件使用与机器无关的格式重新表示(represent)了一些控制数据。
32位数据类型
Name | Size | Alignment | Purpose |
Elf32_Addr | 4 | 4 | Unsigned program address |
Elf32_Half | 2 | 2 | Unsigned medium integer |
Elf32_Off | 4 | 4 | Unsigned file offset |
Elf32_Sword | 4 | 4 | Signed large integer |
Elf32_Word | 4 | 4 | Unsigned large integer |
unsigned char | 1 | 1 | Unsigned small integer |
所有的目标文件数据结构遵循通常的(natural)的大小和对齐指南。基于可移植原因,ELF不使用位域。
单字节字符使用7位ASCII字符。字符不在ASCII里面的可以占用1个或多个字节,根据其对应的字符编码。程序可以控制他们自己的字符集,TIS-conformance不限制字符集,但他们通常应当遵循一些简单的规则。
字符值在0到127的应当对应7位ASCII码,也就是说ASCII应该是这些字符集的子集。
字符值超出127的多字节字符编码应当只包含不在0到127范围的字节。
多字节字符应该是自我定义的。意味着,任何多字节字符可以插入到任何多字节字符对中,而无需改变字符的翻译。
通过ELF头,可以确定文件类型,处理器架构,索引program header table和section header table等。ELF头可以使用一个结构体表示,定义如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #define EI_NIDENT 16 typedef struct { unsigned char e_ident[EI_NIDENT]; 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; Elf32_Half e_shnum; Elf32_Half e_shstrndx; } Elf32_Ehdr; |
e_ident,用于标识文件为ELF格式,提供机器独立的数据,来解析ELF内容。
e_type,定义目标文件的格式。
Name | Value | Meaning |
ET_NONE | 0 | No file type |
ET_REL | 1 | Relocatable file |
ET_EXEC | 2 | Executable file |
ET_DYN | 3 | Shared object file |
ET_CORE | 4 | Core file |
ET_LOPROC | 0xff00 | Processor-specific |
ET_HIPROC | 0xffff | Processor-specific |
e_machine,定义处理器架构。下表并不全,不同的架构在不同的规范中添加他们的定义。
Name | Value | Meaning |
ET_NONE | 0 | No machine |
EM_M32 | 1 | AT&T WE 32100 |
EM_SPARC | 2 | SPARC |
EM_386 | 3 | Intel Architecture |
EM_MIPS | 8 | MIPS RS3000 Big-Endian |
Reserved | 11-16 | Processor-specific |
e_version,当以ELF版本,当前值为1。
Name | Value | Meaning |
EV_NONE | 0 | Invalid version |
EV_CURRENT | 1 | Current version |
e_entry,定义系统转移控制的虚拟地址,从此启动进程。如果没有相关的entry point,设为0。
e_phoff,存储program header table距文件开始处的字节偏移值。如果没有,则设为0。
e_shoff,存储section header table距文件开始处的字节偏移值。如果没有,则设为0。
e_flags,存储处理器相关的flags。
e_ehsize,存储ELF头的字节大小。
e_phentsize,存储program header table一个条目的大小,每个条目大小一样。
e_phnum,存储program header table条目数。
e_shentsize,存储section header table一个条目的大小,每个条目大小一样。
e_shnum,存储section header table的条目数。
e_shstrndx,存储section header string table section的索引。这个section存储所有section的名字。如果没有这个section,值为SHN_UNDEF(0)。
e_ident有16个字节的内容,其分为几个部分,如下:
Name | Value | Purpose |
EI_MAG0 | 0 | File identification |
EI_MAG1 | 1 | File identification |
EI_MAG2 | 2 | File identification |
EI_MAG3 | 3 | File identification |
EI_CLASS | 4 | File class |
EI_DATA | 5 | Data encoding |
EI_VERSION | 6 | File version |
EI_PAD | 7 | Start of padding bytes |
第一个字符为0x7f,紧接着3个字符为"ELF",前4个字符为magic number,标识一个ELF文件。
EI_CLASS,定义了文件的类型或者能力。
Name | Value | Meaning |
ELFCLASSNONE | 0 | Invalid class |
ELFCLASS32 | 1 | 32-bit目标 |
ELFCLASS64 | 2 | 64-bit目标 |
EI_DATA,定义目标文件中,处理器相关的字节编码。
Name | Value | Meaning |
ELFDATANONE | 0 | Invalid data encoding |
ELFDATA2LSB | 1 | 小端在前 |
ELFDATA2MSB | 2 | 大端在前 |
EI_VERSION,指定ELF头的版本号,必须为EV_CURRENT。
EI_PAD,未用的字节开头,这些未用字节是保留的,被设为0。
在Symtem V ABI 4.1 update中,添加了2个内容。EI_OSABI和EI_ABIVERSION。EI_OSABI的值为7,EI_ABIVERSION的值为8。EI_PAD变成了9。ELFOSABI_LINUX的值被定义为3。