Skip to content

ELF 文件

1. Section 视角(面向链接过程)

  • 用途:
  • 主要用于链接器(linker)在链接多个目标文件时进行重定位、符号解析等操作。
  • 包含信息:
  • 包括符号表、重定位表、调试信息、各类型的代码段和数据段等。
  • 特点:
  • Section 信息对运行时执行不是必需的,很多内容(如调试信息)不会加载到内存中。

2. Segment 视角(面向执行:程序加载)

  • 用途:
  • 操作系统加载器(loader)使用该视角将程序映射到内存中执行。
  • 描述内容:
  • 描述程序在内存中的布局,例如代码段、数据段以及其他需要加载的区域。
  • 指定 segment 的虚拟地址、文件内偏移、加载大小和访问权限等。
  • 特点:
  • 仅包含程序运行时必需的信息。
  • 不会加载那些仅用于调试或链接的 Section。

3. Section 与 Segment 的映射关系

  • 一个 segment 可以包含零个或多个 section。
  • 部分 section 可能完全不属于任何 segment(如调试符号表)。
  • 工具(例如 readelf)可以显示这两者之间的映射关系,帮助理解编译与加载过程中的数据组织。

4. Program Header Table

  • 用途:
  • 用于管理所有 segments,指导加载器将程序正确映射到内存。
  • 主要属性:
  • Type(类型):PT_LOAD 表示该 segment 需要加载到内存中。
  • Virtual Address: segment 在内存中的起始地址。
  • Flags(标志): 规定了 segment 的读/写/执行权限。
  • Offset & Size: 描述 segment 在 ELF 文件中的偏移量及大小。
  • Alignment: 指定 segment 在内存中所需的对齐要求。

5. 程序加载过程

  • 加载步骤:
  • 加载器读取 Program Header Table,判断哪些 segment 的 Type 为 PT_LOAD
  • 仅加载必要的 segment 至内存中,而非整个 ELF 文件。
  • 对于 segment 中 FileSiz 小于 MemSiz 的部分(通常对应于 .bss 段),加载器为其分配内存并将该区域清零。
  • 目的:
  • 确保程序运行时具有正确的内存映射和权限设置,提高加载效率,同时减少加载无关调试信息或符号表的开销。

6. PT_LOAD 类型的 Segment

  • 定义:
  • 表示需要加载到内存中的程序段。
  • 加载器操作:
  • 根据该 segment 的 Offset、FileSiz、MemSiz、Virtual Address 和 Flags,读取文件中的数据,复制到相应内存位置。
  • 对于 (VirtAddr + FileSiz, VirtAddr + MemSiz) 区间,加载器会进行清零操作,确保未初始化的数据(.bss)段被初始化为零。

总结

  • Section 视角服务于链接过程,包含大量调试和符号信息,而 Segment 视角 则专注于程序加载和运行时的内存映射。
  • Program Header Table 指导加载器仅加载 PT_LOAD 类型的 segment,从而构建出程序在内存中的正确布局。
  • 内存中多余的部分(如 .bss)需要清零以保证程序运行的正确性。

这种分离设计既满足了链接器对详细内部信息的需求,又保证了加载器只加载真正需要运行的部分,优化了内存使用和启动速度。

```