卓一笔记---ELF文件结构介绍

卓一笔记---ELF文件结构介绍_第1张图片

        上图是ELF文件大致的结构。在计算机科学中,ELF是一种用于二进制文件、可执行文件、目标代码、共享库和核心转储格式的文件。是UNIX系统实验室(USL)作为应用程序二进制接口(Application Binary Interface,ABI)开发和发布的,也是Linux的主要可执行文件格式。1999年,被86open项目选为x86架构上的类Unix操作系统的二进制文件标准格式,用来取代COFF。因其可扩展性与灵活性,也可应用在其它处理器、计算机系统架构的操作系统上。

       如下图,ELF文件由4部分组成,分别是ELF头(ELF header)、程序头表(Program header table)、节(Section)和节头表(Section header table)。实际上,一个文件中不一定包含全部内容,而且它们的位置也未必如同所示这样安排,只有ELF头的位置是固定的,其余各部分的位置、大小等信息由ELF头中的各项值来决定。

卓一笔记---ELF文件结构介绍_第2张图片

卓一笔记---ELF文件结构介绍_第3张图片

      ELF文件格式提供了两种不同的视角,在汇编器和链接器看来,ELF文件是由Section Header Table描述的一系列Section的集合,而执行一个ELF文件时,在加载器(Loader)看来它是由Program Header Table描述的一系列Segment的集合。

卓一笔记---ELF文件结构介绍_第4张图片

          如上图,左边是从汇编器和链接器的视角来看这个文件,开头的ELF Header描述了体系结构和操作系统等基本信息,并指出Section Header Table和Program Header Table在文件中的位置,Section Header Table中保存了所有Section的描述信息。右边是从加载器的视角来看这个文件,开头是ELF Header,Program Header Table中保存了所有Segment的描述信息。注意Section Header Table和Program Header Table并不是一定要位于文件开头和结尾的,其位置由ELF Header指出,上图这么画只是为了清晰。

      在汇编程序中用.section声明的Section会成为目标文件中的Section,此外汇编器还会自动添加一些Section(比如符号表)。Segment是指在程序运行时加载到内存的具有相同属性的区域,由一个或多个Section组成,比如有两个Section都要求加载到内存后可读可写,就属于同一个Segment。有些Section只对汇编器和链接器有意义,在运行时用不到,也不需要加载到内存,那么就不属于任何Segment。

       目标文件需要链接器做进一步处理时,一定要有Section Header Table;可执行文件需要加载运行,所以一定要有Program Header Table;而共享库既要加载运行,又要在加载时做动态链接,所以既要有Section Header Table又要有Program Header Table。

1)ELF Header

格式如下:

卓一笔记---ELF文件结构介绍_第5张图片

#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;

数据类型说明

名称 大小 对齐 用途
Elf32_Addr 4 4 无符号程序地址
Elf32_Half 2 2 无符号中等大小整数
Elf32_Off 4 4 无符号文件偏移
Elf32_Sword 4 4 有符号大整数
Elf32_Word 4 4 无符号大整数
unsigned char 1 1 无符号小整数

各项含义

最开头是16个字节的e_ident, 其中包含用以表示ELF文件的字符,以及其他一些与机器无关的信息。开头的4个字节值固定不变,为0x7f和ELF三个字符。

e_type 它标识的是该文件的类型。

e_machine 表明运行该程序需要的体系结构。

e_version 表示文件的版本。

e_entry 程序的入口地址。

e_phoff 表示Program header table 在文件中的偏移量(以字节计数)。

e_shoff 表示Section header table 在文件中的偏移量(以字节计数)。

e_flags 对IA32而言,此项为0。

e_ehsize 表示ELF header大小(以字节计数)。

e_phentsize 表示Program header table中每一个条目的大小。

e_phnum 表示Program header table中有多少个条目。

e_shentsize 表示Section header table中的每一个条目的大小。

e_shnum 表示Section header table中有多少个条目。

e_shstrndx 包含节名称的字符串是第几个节(从零开始计数)。

2)Program header

Program header描述的是一个段在文件中的位置、大小以及它被放进内存后所在的位置和大小。

格式如下

typedef struct {

Elf32_Wordp_type;

Elf32_Offp_offset;

Elf32_Addr p_vaddr;

Elf32_Addr p_paddr;

Elf32_Wordp_filesz;

Elf32_Word p_memsz;

Elf32_Word p_flags;

Elf32_Word p_align;

}Elf32_Phdr;

各项含义

p_type 当前Program header所描述的段的类型。

p_offset 段的第一个字节在文件中的偏移。

p_vaddr 段的一个字节在内存中的虚拟地址

p_paddr 在物理内存定位相关的系统中,此项是为物理地址保留。

p_filesz 段在文件中的长度。

p_memsz 段在内存中的长度。

p_flags 与段相关的标志。

p_align 根据此项值来确定段在文件及内存中如何对齐。

3)Section Header

数据定义 数据格式 个数 说明
section header name Elf32_Word 1 数据段名称
section header type Elf32_Word 1 数据段的类型
section header flags Elf32_Word 1 此数据段的标志位
section header address Elf32_Address 1 数据段的关于代码执行的地址
section header offset Elf32_Offset 1 数据段在文件中的偏移量
section header size Elf32_Word 1 数据段的长度
section header link Elf32_Word 1 索引位数量
section header info Elf32_Word 1 其他类的信息
section header address align Elf32_Word 1 数据排列定义
section header entry size Elf32_Word 1 数据段的入口长度,用于索引(如果有的话)
BFD Compatible 下文强调 1 用于兼容BFD文件的兼容定义,是一个定义完善的数据结构
section header content Address Elf32_Address(容器为Elf32_Char) 1 数据的真实数据指针

 

卓一笔记---ELF文件结构介绍_第6张图片

你可能感兴趣的:(卓一笔记,操作系统,os)