32 位 ELF header 定义:
typedef struct
{
unsigned char e_ident[EI_NIDENT]; /* Magic number和其它信息 */
Elf32_Half e_type; /* Object file type */
Elf32_Half e_machine; /* Architecture */
Elf32_Word e_version; /* Object file version */
Elf32_Addr e_entry; /* Entry point virtual address */
Elf32_Off e_phoff; /* Program header table file offset */
Elf32_Off e_shoff; /* Section header table file offset */
Elf32_Word e_flags; /* Processor-specific flags */
Elf32_Half e_ehsize; /* ELF header size in bytes */
Elf32_Half e_phentsize; /* Program header table entry size */
Elf32_Half e_phnum; /* Program header table entry count */
Elf32_Half e_shentsize; /* Section header table entry size */
Elf32_Half e_shnum; /* Section header table entry count */
Elf32_Half e_shstrndx; /* Section header string table index */
} Elf32_Ehdr;
64 位 ELF header 定义:
typedef struct
{
unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
Elf64_Half e_type; /* Object file type */
Elf64_Half e_machine; /* Architecture */
Elf64_Word e_version; /* Object file version */
Elf64_Addr e_entry; /* Entry point virtual address */
Elf64_Off e_phoff; /* Program header table file offset */
Elf64_Off e_shoff; /* Section header table file offset */
Elf64_Word e_flags; /* Processor-specific flags */
Elf64_Half e_ehsize; /* ELF header size in bytes */
Elf64_Half e_phentsize; /* Program header table entry size */
Elf64_Half e_phnum; /* Program header table entry count */
Elf64_Half e_shentsize; /* Section header table entry size */
Elf64_Half e_shnum; /* Section header table entry count */
Elf64_Half e_shstrndx; /* Section header string table index */
} Elf64_Ehdr;
64 位和 32 位个别字段长度不同,比如 Elf64_Addr 和 Elf64_Off 都是64 位无符号整数。而 Elf32_Addr 和 Elf32_Off 是 32 位无符号整数。这导致 ELF header 的所占的字节数不同。32 位的 ELF header 占 52 个字节,64 位的 ELF header 占 64 个字节。
-
e_ident 占 16 个字节。前四个字节被称作 ELF 的 Magic Number。后面的字节描述了 ELF 文件内容如何解码等信息。等一下详细讲。 -
e_type ,2 字节,描述了 ELF 文件的类型。以下取值有意义: ET_NONE, 0, No file type
ET_REL, 1, Relocatable file(可重定位文件,通常是文件名以 .o 结尾,目标文件)
ET_EXEC, 2, Executable file (可执行文件)
ET_DYN, 3, Shared object file (动态库文件,你用 gcc 编译出的二进制往往也属于这种类型,惊讶吗?)
ET_CORE, 4, Core file (core 文件,是 core dump 生成的吧?)
ET_NUM, 5,表示已经定义了 5 种文件类型
ET_LOPROC, 0xff00, Processor-specific
ET_HIPROC, 0xffff, Processor-specific
从 ET_LOPROC 到 ET_HIPROC 的值,包含特定于处理器的语义。 -
e_machine ,2 字节。描述了文件面向的架构,可取值如下(因为文档较老,现在有更多取值,参见 /usr/include/elf.h 中的 EM_ 开头的宏定义): EM_NONE, 0, No machine
EM_M32, 1, AT&T WE 32100
EM_SPARC, 2, SPARC
EM_386, 3, Intel 80386
EM_68K, 4, Motorola 68000
EM_88K, 5, Motorola 88000
EM_860, 7, Intel 80860
EM_MIPS, 8, MIPS RS3000
... ...
-
e_version ,2 字节,描述了 ELF 文件的版本号,合法取值如下: EV_NONE, 0, Invalid version
EV_CURRENT, 1, Current version,通常都是这个取值。
EV_NUM, 2, 表示已经定义了 2 种版本号
-
e_entry ,( 32 位 4 字节,64 位 8 字节),执行入口点,如果文件没有入口点,这个域保持 0。 -
e_phoff , (32 位 4 字节,64 位 8 字节),program header table 的 offset,如果文件没有 PH,这个值是 0。 -
e_shoff , (32 位 4 字节,64 位 8 字节), section header table 的 offset,如果文件没有 SH,这个值是 0。 -
e_flags , 4 字节,特定于处理器的标志,32 位和 64 位 Intel 架构都没有定义标志,因此 eflags 的值是 0。 -
e_ehsize, 2 字节,ELF header 的大小,32 位 ELF 是 52 字节,64 位是 64 字节。 -
e_phentsize ,2 字节。program header table 中每个入口的大小。 -
e_phnum , 2 字节。如果文件没有 program header table, e_phnum 的值为0。e_phentsize 乘以 e_phnum 就得到了整个 program header table 的大小。 -
e_shentsize , 2 字节,section header table 中 entry 的大小,即每个section header 占多少字节。 -
e_shnum , 2 字节,section header table 中 header 的数目。如果文件没有 section header table, e_shnum的值为0。e_shentsize 乘以 e_shnum ,就得到了整个 section header table 的大小。 -
e_shstrndx , 2 字节。section header string table index. 包含了 section header table 中 section name string table。如果没有 section name string table, e_shstrndx 的值是 SHN_UNDEF 。
示例:
$ readelf -h test.axf
ELF 头:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
类别: ELF32
数据: 2 补码,小端序 (little endian)
Version: 1 (current)
OS/ABI: UNIX - System V
ABI 版本: 0
类型: EXEC (可执行文件)
系统架构: ARM
版本: 0x1
入口点地址: 0x80000ed
程序头起点: 521888 (bytes into file)
Start of section headers: 521920 (bytes into file)
标志: 0x5000202, Version5 EABI, soft-float ABI, <unknown>
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 1
Size of section headers: 40 (bytes)
Number of section headers: 16
Section header string table index: 15
$ readelf -h ~/tmp/a.out
ELF 头:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
类别: ELF64
数据: 2 补码,小端序 (little endian)
Version: 1 (current)
OS/ABI: UNIX - System V
ABI 版本: 0
类型: EXEC (可执行文件)
系统架构: Advanced Micro Devices X86-64
版本: 0x1
入口点地址: 0x400078
程序头起点: 64 (bytes into file)
Start of section headers: 0 (bytes into file)
标志: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 1
Size of section headers: 0 (bytes)
Number of section headers: 0
Section header string table index: 0
参考: ELF文件解析(二):ELF header详解
|