讲讲 Linux 平台的 ELF 文件结构

ELF 文件的两种视图

理解 ELF 文件的关键在于,它有两个不同的、但相互关联的视图:

  1. 链接视图(Linking View): 供编译器和链接器使用。它由节(Sections)组成,主要用于编译、链接和重定位
  2. 执行视图(Execution View): 供操作系统加载器使用。它由段(Segments)组成,用于将程序加载到内存中并执行

这两种视图由 ELF 头部中的两个表来描述:节头部表和程序头部表

ELF 头部

每个 ELF 文件的开头都是一个 ELF 头部,它提供了文件的基本信息,就像 PE 文件的 DOS 头部一样。它定义了文件的类型、机器架构、入口点地址等

ELF 头部最重要的一些字段是:

  • e_ident[EI_MAG0-3]:4 字节的魔数,固定为 0x7f, 'E', 'L', 'F'。这是识别 ELF 文件的唯一标志
  • e_ident[EI_CLASS]:指定文件架构,1 代表 32 位,2 代表 64 位
  • e_ident[EI_DATA]:指定字节序,1 代表小端序,2 代表大端序
  • e_type:文件类型,如 ET_EXEC(可执行文件)、ET_DYN(共享库)、ET_REL(可重定位文件)
  • e_entry:程序的入口点地址(虚拟地址)
  • e_phoff:程序头部表(Program Header Table)的文件偏移量
  • e_shoff:节头部表(Section Header Table)的文件偏移量
  • e_phentsize:程序头部表中每个条目的大小
  • e_phnum:程序头部表的条目数量
  • e_shentsize:节头部表中每个条目的大小
  • e_shnum:节头部表的条目数量

链接视图:节

节是 ELF 文件的基本单元,用于组织文件中的各种数据和代码。每个节都有特定的目的

常见的节有:

  • .text:包含可执行代码
  • .data:包含已初始化的全局变量和静态变量
  • .rodata:包含只读数据,如字符串常量
  • .bss:包含未初始化的全局变量和静态变量,在文件中不占用空间,加载时由加载器分配和清零
  • .symtab:符号表,包含了程序中所有符号(函数名、变量名)的信息
  • .strtab:字符串表,存储符号表中的字符串
  • .debug:调试信息,用于 GDB 等调试器
  • .got(Global Offset Table):全局偏移表,用于在运行时解析外部函数地址
  • .plt(Procedure Linkage Table):过程链接表,用于动态链接

节头部表

节头部表是一个描述所有节的数组。每个条目都是一个 Elf64_Shdr(对于 64 位)结构体,它包含了每个节的名称、类型、权限、文件偏移、内存地址和大小等信息。链接器和反汇编工具(如 objdump)主要依赖这个表来分析文件结构

执行视图:段

当程序需要被加载到内存中执行时,节会被组合成更大的逻辑单元——。每个段都具有相同的内存权限(可读、可写、可执行)。这是加载器关心的内容

典型的段有两个:

  • 代码段(Code Segment): 通常包含 .text.rodata 节。这个段被映射到内存中,并具有可读和可执行权限
  • 数据段(Data Segment): 通常包含 .data.bss 节。这个段被映射到内存中,并具有可读和可写权限

程序头部表

程序头部表是一个描述所有段的数组。每个条目都是一个 Elf64_Phdr 结构体,它包含了每个段的类型、文件偏移、内存地址、大小和权限等信息。加载器通过遍历这个表,将 ELF 文件中的内容映射到内存中

  • p_type:段的类型,如 PT_LOAD(可加载到内存)
  • p_offset:段在文件中的偏移量
  • p_vaddr:段在内存中的虚拟地址
  • p_memsz:段在内存中的大小
  • p_flags:段的权限,如 PF_R(可读)、PF_W(可写)、PF_X(可执行)

ELF 文件加载过程

  1. 操作系统内核的加载器读取 ELF 头部,找到程序头部表
  2. 加载器遍历程序头部表中的所有条目
  3. 对于每个类型为 PT_LOAD 的段,加载器将文件中的相应部分,从 p_offset 偏移处开始,映射到内存中的 p_vaddr 虚拟地址上
  4. 加载器根据 p_flags 设置内存页的权限(读、写、执行)
  5. 所有段加载完毕后,加载器将程序控制权交给 e_entry 字段指定的入口点地址,程序开始执行
Copyright © 版权信息 all right reserved,powered by Gitbook该文件修订时间: 2025-09-25 03:13:09

results matching ""

    No results matching ""