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)需要清零以保证程序运行的正确性。
这种分离设计既满足了链接器对详细内部信息的需求,又保证了加载器只加载真正需要运行的部分,优化了内存使用和启动速度。
```