Skip to content

第四章:成为Elf领主

这篇文章是关于ELF(可执行和链接格式)文件如何在Linux系统中被执行的详细解析。

1. ELF文件格式:

  • ELF是最常用的Linux程序文件格式。
  • ELF文件由四个部分组成:ELF头部、程序头部表(PHT)、节头部表(SHT)和数据部分。

2. ELF头部:

  • 包含关于二进制文件的基本信息,如目标处理器架构、是否为可执行文件、程序入口点等。
  • 指定PHT和SHT的位置。

3. 程序头部表(PHT):

  • 描述如何以及在何处将ELF文件的数据加载到内存中。
  • 常见的PHT类型包括PT_LOAD(要加载到内存的数据)、PT_NOTE(版权声明等自由格式文本)、PT_DYNAMIC(动态链接信息)和PT_INTERP(ELF解释器的路径)。

4. 节头部表(SHT):

  • 可选的“地图”,帮助调试器理解ELF文件中数据的预期用途。
  • 包含节的名称、类型和标志。

5. 数据:

  • PHT和SHT指向的数据块,包含程序的机器代码、初始化数据、BSS段、只读数据等。

6. 动态链接:

  • 与静态链接相比,动态链接只包含对库函数的引用,而不是库代码本身。
  • 运行时,操作系统需要确定所需的库,加载它们,替换所有命名指针为实际的跳转指令,然后启动程序代码。

7. ELF解释器:

  • 动态链接的程序需要通过ELF解释器来运行,它负责加载所需的库并初始化程序。

8. 执行过程:

  • 内核读取ELF头部和PHT,设置新程序的内存结构。
  • 加载所有PT_LOAD段到内存,填充程序的静态数据、BSS空间和机器代码。
  • 如果程序是动态链接的,内核还需要执行ELF解释器。
  • 设置CPU的指令指针,如果是动态链接,指向ELF解释器的代码;否则指向可执行文件的开始。
  • 内核将argcargv和环境变量推送到栈上,供程序开始时读取。
  • 清空寄存器,准备返回用户空间。
  • 系统调用结束,内核返回用户空间,恢复寄存器,并跳转到存储的指令指针,这将是新程序(或ELF解释器)的起始点。

文章深入探讨了ELF文件的结构和执行过程,解释了静态链接和动态链接的区别,以及Linux内核如何处理和执行ELF文件。这些信息对于理解Linux系统上的程序执行机制非常有用。

基于 知识共享 CC BY-NC-SA 许可发布