Skip to content
On this page

ELF文件格式


软件版本硬件版本更新内容
ELF64arm64

1. 概述

ELF文件,也就是Executable and Linking Format.gcc等编译器生成的就是这个类型的文件.存在三种类型的elf文件:

  1. 可重定位文件relocatable file, 可用于生成可执行文件或者共享库文件的二进制代码和数据,例如**.o**文件
  2. 可执行文件executable file, 可直接执行的二进制文件
  3. 共享库文件shared object file, 常见的为**.so**文件,两个作用:
    • 用于链接生成新的二进制文件
    • 用于动态映射到一个可执行文件中创建新的进程

2. ELF文件组织形式

分两种格式,一种可执行文件,另外一种用于链接的包括.o和.so

elf file

一个有效的ELF文件必须满足如下几条:

  1. 必须存在文件头
  2. 用于连接的ELF必须包括Section head Table,对于可执行文件这部分可选
  3. Program Header Table,可执行文件必须包括,用于连接的ELF文件可选
  4. Section由数据,字符串和可重定位的符号
  5. 由头,Section header table, Program header table, Sections组成

提示

这里需要注意在linking view中使用的是section,而在executable view中使用是segment,我们写程序时可以通过链接脚本指定当前代码或者数据存放在那个section中,而且只有控制section,而segment是链接器在生成可执行文件时生成的叫segment.

3. ELF文件中使用的数据类型

名子大小对齐方式功能
Elf64_Addr88表示程序地址
Elf64_Off88g表示文件偏移
Elf64_Half22表示无符号的中整数
Elf64_Word44表示无符号的整数
Elf64_Sword44表示有符号的整数
Elf64_Xword88表示无符号的大整数
Elf64_Sxword88表示有符号的大整数
unsigned char11表示无符号的小整数

在linux中是如下的定义:

c
typedef unsigned long long Elf64_Addr;
typedef unsigned short Elf64_Half;
typedef signed short Elf64_SHalf;
typedef unsigned long long Elf64_Off;
typedef signed int Elf64_Sword;
typedef unsigned int Elf64_Word;
typedef unsigned long long Elf64_Xword;
typedef signed long long Elf64_Sxword;

4. ELF文件头

从linux内核中可以找到头部的数据结构如下:

c
typedef struct elf64_hdr {
	unsigned char e_ident[16];	/* ELF "magic number" */
	Elf64_Half e_type;
	Elf64_Half e_machine;
	Elf64_Word e_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;
	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;


4.1 ELF头中的e_ident

identification魔数将文件标识为 ELF 目标文件,并提供有关目标文件结构的数据表示的信息。 e_ident是一个数组,在linux内核中使用如下index的访问

c

/* 这个用于区分32位还是64位,=1 为32位, =2 为64 */
#define	EI_CLASS	4
/* 这个字段用于表示大小端,=1 为小端, =2 为大端 */
#define	EI_DATA		5
/* 这个字段用于表示版本,目前使用固定的 EV_CURRENT = 1*/
#define	EI_VERSION	6
/* 这个字段用于表示操作系统和ABI, 有三种 =0为System V ABI, =1为HP-UX operating system, =2为Standalone (embedded) */
#define	EI_OSABI	7
/* 起始填充位 */
#define	EI_PAD		8

4.2 ELF头中的e_type

类型如下表:

名子含义
ET_NONE0无文件类型
ET_REL1可重新定位的文件如.o
ET_EXEC2可执行文件
ET_DYN3共享库文件
ET_CORE4核心文件
ET_LOOS0xFE00特定环境使用
ET_HIOS0xFEFF
ET_LOPROC0xFF00特定处理器的使用
ET_HIPROC0xFFFF

4.3 ELF头中的e_machine

表示目标处理器架构,如arm64 x86

4.4 ELF头中的e_version

这个和e_ident中版本是一样的

4.5 ELF头中的e_entry

包含程序入口点的虚拟地址。如果没有入口点,则此字段包含零

4.6 ELF头中的e_phoff

包含程序头表的文件偏移量,以字节为单位

4.7 ELF头中的e_shoff

包含节头表的文件偏移量,以字节为单位

4.8 ELF头中的e_flags

包含特定于处理器的标志

4.9 ELF头中的e_ehsize

包含 ELF 标头的大小(以字节为单位)

4.10 ELF头中的e_phentsize

包含程序头表(Program head table)条目的大小(以字节为单位)

4.11 ELF头中的e_phnum

包含程序头表(Program head table)中的条目数

4.12 ELF头中的e_shentsize

每个节头表(section head table)条目的大小(以字节为单位),也就是每个section head 的大小

4.13 ELF头中的e_shnum

节头表(section head table)中的section header条目数

4.14 ELF头中的e_shstrndx

字符串节section header在section header table中的索引

5. SECTIONS节

节是包括除了ELF头,ELF Section header table , ELF Program header table之外的所有东西。

提示

节的内容中没有节的描述信息,它的描述信息都在section header table中对应该的section header中。

6. Section header

在linux中section header的定义如下:

c
typedef struct elf64_shdr {
  Elf64_Word sh_name;		/* Section name, index in string tbl */
  Elf64_Word sh_type;		/* Type of section */
  Elf64_Xword sh_flags;		/* Miscellaneous section attributes */
  Elf64_Addr sh_addr;		/* Section virtual addr at execution */
  Elf64_Off sh_offset;		/* Section file offset */
  Elf64_Xword sh_size;		/* Size of section in bytes */
  Elf64_Word sh_link;		/* Index of another section */
  Elf64_Word sh_info;		/* Additional section information */
  Elf64_Xword sh_addralign;	/* Section alignment */
  Elf64_Xword sh_entsize;	/* Entry size if section holds table */
} Elf64_Shdr;

7. Section header table

是section header的集合,这个表的地址在ELF头中有,是e_shoff这个字段

8. Program header

在linux中Program header的定义如下:

c
typedef struct elf64_phdr {
	Elf64_Word p_type;
	Elf64_Word p_flags;
	Elf64_Off p_offset;	/* Segment file offset */
	Elf64_Addr p_vaddr;	/* Segment virtual address */
	Elf64_Addr p_paddr;	/* Segment physical address */
	Elf64_Xword p_filesz;	/* Segment size in file */
	Elf64_Xword p_memsz;	/* Segment size in memory */
	Elf64_Xword p_align;	/* Segment alignment, file & memory */
} Elf64_Phdr;

9. Program header table

是Program header的集合,这个表的地址在ELF头中有,是e_phoff这个字段

10. 特殊的一些Section

10.1 string table section

string table这个节保存了所有的了section的name,也就是说我们可以读取这个段的内容知道,都有那些个section.


提示

欢迎评论、探讨,如果发现错误请指正。转载请注明出处! 探索者


Released under the MIT License.