目标文件中的一些控制结构可以增大,因为 ELF 头包含这些控制结构的实际大小。如果目标文件格式发生变化,则程序可能会遇到大于或小于所需大小的控制结构。因此,程序可能会忽略额外信息。这些忽略的信息的处理方式取决于上下文,如果定义了扩展内容,则会指定处理方式。
ELF 头具有以下结构。 请参见 sys/elf.h。
#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; typedef struct { unsigned char e_ident[EI_NIDENT]; Elf64_Half e_type; Elf64_Half e_machine; Elf64_Word e_version; Elf64_Addr e_entry; Elf64_Off e_phoff; Elf64_Off e_shoff; Elf64_Word e_flags; Elf64_Half e_ehsize; Elf64_Half e_phentsize; Elf64_Half e_phnum; Elf64_Half e_shentsize; Elf64_Half e_shnum; Elf64_Half e_shstrndx; } Elf64_Ehdr;
将文件标记为目标文件的初始字节。这些字节可提供与计算机无关的数据,用于解码和解释文件的内容。ELF 标识中提供了完整说明。
标识目标文件类型,如下表中所列。
名称 |
值 |
含义 |
---|---|---|
ET_NONE |
0 |
无文件类型 |
ET_REL |
1 |
可重定位文件 |
ET_EXEC |
2 |
可执行文件 |
ET_DYN |
3 |
共享库文件 |
ET_CORE |
4 |
核心转储文件 |
ET_LOPROC |
0xff00 |
特定于处理器 |
ET_HIPROC |
0xffff |
特定于处理器 |
虽然未指定核心转储文件内容,但类型 ET_CORE 保留用于标记文件。从 ET_LOPROC 到 ET_HIPROC 之间的值(包括这两个值)保留用于特定于处理器的语义。其他值保留供将来使用。
指定独立文件所需的体系结构。下表中列出了相关体系结构。
名称 |
值 |
含义 |
---|---|---|
EM_NONE |
0 |
无计算机 |
EM_SPARC |
2 |
SPARC |
EM_386 |
3 |
Intel 80386 |
EM_SPARC32PLUS |
18 |
Sun SPARC 32+ |
EM_SPARCV9 |
43 |
SPARC V9 |
EM_AMD64 |
62 |
AMD 64 |
其他值保留供将来使用。特定于处理器的 ELF 名称通过使用计算机名来进行区分。例如,为 e_flags 定义的标志会使用前缀 EF_。EM_XYZ 计算机的名为 WIDGET 的标志可称为 EF_XYZ_WIDGET。
标识目标文件版本,如下表中所列。
名称 |
值 |
含义 |
---|---|---|
EV_NONE |
0 |
无效版本 |
EV_CURRENT |
>=1 |
当前版本 |
值 1 表示原始文件格式。EV_CURRENT 的值可根据需要进行更改,以反映当前版本号。
系统首先将控制权转移到的虚拟地址,从而启动进程。如果文件没有关联的入口点,则此成员值为零。
程序头表的文件偏移(以字节为单位)。如果文件没有程序头表,则此成员值为零。
节头表的文件偏移(以字节为单位)。如果文件没有节头表,则此成员值为零。
与文件关联的特定于处理器的标志。标志名称采用 EF_machine_flag 形式。对于 x86,此成员目前为零。下表中列出了 SPARC 标志。
名称 |
值 |
含义 |
---|---|---|
EF_SPARC_EXT_MASK |
0xffff00 |
供应商扩展掩码 |
EF_SPARC_32PLUS |
0x000100 |
通用 V8+ 功能 |
EF_SPARC_SUN_US1 |
0x000200 |
Sun UltraSPARC™ 1 扩展 |
EF_SPARC_HAL_R1 |
0x000400 |
HAL R1 扩展 |
EF_SPARC_SUN_US3 |
0x000800 |
Sun UltraSPARC 3 扩展 |
EF_SPARCV9_MM |
0x3 |
内存型号掩码 |
EF_SPARCV9_TSO |
0x0 |
总体存储排序 |
EF_SPARCV9_PSO |
0x1 |
部分存储排序 |
EF_SPARCV9_RMO |
0x2 |
非严格存储排序 |
ELF 头的大小(以字节为单位)。
文件的程序头表中某一项的大小(以字节为单位)。所有项的大小都相同。
程序头表中的项数。生成的 e_phentsize 和 e_phnum 指定了表的大小(以字节为单位)。如果文件没有程序头表,则 e_phnum 值为零。
节头的大小(以字节为单位)。节头是节头表中的一项。所有项的大小都相同。
节头表中的项数。生成的 e_shentsize 和 e_shnum 指定了节头表的大小(以字节为单位)。如果文件没有节头表,则 e_shnum 值为零。
如果节数大于或等于 SHN_LORESERVE (0xff00),则 e_shnum 值为零。节头表的实际项数包含在节头表中索引为 0 的 sh_size 字段中。否则,初始节头项的 sh_size 成员值为零。请参见表 7–6 和表 7–7。
与节名字符串表关联的项的节头表索引。如果文件没有节名字符串表,则此成员值为 SHN_UNDEF。
如果节名字符串表的节索引大于或等于 SHN_LORESERVE (0xff00),则此成员值为 SHN_XINDEX (0xffff),节名字符串表的实际节索引包含在节头中索引为 0 的 sh_link 字段中。否则,初始节头项的 sh_link 成员值为零。请参见表 7–6 和表 7–7。