ELF文件格式的最前部是 ELF文件头(ELF Header) ,包含整个文件的基本属性。然后是各个节,ELF文件中与节有关的结构是 “节表(Section Header Table)”,节表描述ELF文件包含的所有节的信息。
文件头
elf.h
中的自定义类型
自定义类型 | 描述 | 原始类型 | 长度(字节) |
---|---|---|---|
Elf32_Addr | 32位版本程序地址 | uint32_t | 4 |
Elf32_Half | 32位版本的 | uint16_t | 2 |
Elf32_Off | 32位版本的偏移地址 | uint32_t | 4 |
Elf32_Sword | 32位版本有符号整型 | int32_t | 4 |
Elf32_Word | 32位版本无符号整型 | uint32_t | 4 |
Elf64_Addr | 64位版本程序地址 | uint64_t | 8 |
Elf64_Half | 64位版本无符号整型 | uint16_t | 2 |
Elf64_Off | 64位版本的偏移地址 | uint64 | 8 |
Elf64_Sword | 64位版本有符号整型 | int32_t | 4 |
Elf64_Word | 64位版本无符号整型 | uint32_t | 4 |
32位版本的文件头结构定义如下
#define EI_NIDENT 16struct Elf32_Ehdr //共52个字节 //Ehdr表示ELF header
{unsigned char e_ident[EI_NIDENT];Elf32_Half e_type; //类型包括:可执行文件、可重定向文件、共享目标文件等Elf32_Half e_machine; //有X86、arm之类Elf32_Word e_version;Elf32_Addr e_entry; //可执行程序的入口地址Elf32_Off e_phoff; //Program头表的偏移地址Elf32_Off e_shoff; //Section头表的偏移地址Elf32_Word e_flags;Elf32_Half e_ehsize; //本结构体的sizeElf32_Half e_phentsize; //单个Program头的sizeElf32_Half e_phnum; //Segment头表中Segment头的个数Elf32_Half e_shentsize; //单个Section头的szieElf32_Half e_shnum; //Section头表中Section头的个数Elf32_Half e_shstrndx; //储存Section名字集合的Section的下标,指".shstrtab"的下标
};
节表
节表是保存节的基本属性的结构。
struct Elf32_Shdr //共40个字节 //Shdl表示Section header
{Elf32_Word sh_name; //所指向Section的名字,如".text"、".data"、".bss"等Elf32_Word sh_type; //所指向Section的类型,如:符号表、字符串表等Elf32_Word sh_flags; Elf32_Addr sh_addr;Elf32_Off sh_offset; //所指向Section在ELF文件中的偏移量Elf32_Word sh_size; //所指向Section的sizeElf32_Word sh_link; //和其关联的Section头的下标索引Elf32_Word sh_info;Elf32_Word sh_addralign; //字节对齐Elf32_Word sh_entsize;
};
节的类型(sh_type)
节的类型相关常量以SHT_
开头
常量 | 值 | 含义 |
---|---|---|
SHT_NULL | 0 | 无效段 |
SHT_PROGBITS | 1 | 程序段。代码段、数据段都是这种类型的 |
SHT_SYMTAB | 2 | 表示该段的内容为符号表 |
SHT_STRTAB | 3 | 表示该段内容为字符串表 |
SHT_RELA | 4 | 重定位表。包含重定位信息 |
SHT_HASH | 5 | 符号表的哈希表 |
SHT_DYNAMIC | 6 | 动态链接信息 |
SHT_NOTE | 7 | 提示性信息 |
SHT_NOBITS | 8 | 表示该段在文本中没内容 |
SHT_REL | 9 | 包含重定位信息 |
SHT_SHLIB | 10 | 保留 |
SHT_DNYSYM | 11 | 动态链接 |
节的标志位(sh_flag)
标志位表示段在进程虚拟地址空间中的属性。
常量 | 值 | 含义 |
---|---|---|
SHF_WRITE | 1 | 可写 |
SHF_ALLOC | 2 | 该节在进程空间需要分配空间 |
SHF_EXECINSTR | 4 | 该节在进程空间中可以执行 |
重定位表
链接器在处理目标文件时,需要对目标文件中某些部位进行重定位,即代码段和数据段哪些对绝对地址的引用的位置。
一个重定位表同时也是ELF的一个段,这个段的类型就是“SHT_REL”。
字符串表
字符串长度往往是不定的,将字符串集中起来存放到一个表,然后使用字符串在表中的偏移来引用字符串。
这种方式,在ELF文件中引用字符串只需要给出一个数字下标最为偏移即可。
一般字符串表在ELF文件中也以段的形式保存,常见的段名为“.strtab”或“.shstrtab”。这两个字符串表分别为字符串表(String Table)和段表字符串表(Section Header String Table)。
在ELF文件头中有一个字段e_shstrndx
,它是 “Section header string table index” 的缩写,是段表字符串表在段表中的索引下标。