链接器的世界/ 实验篇/ 16 篇
3 分钟阅读公开阅读

[链接器的世界-实验篇04] 第一个能运行的 ELF:两张程序头与一个入口

本实验生成一个能由 Linux 内核直接执行的 ELF64 文件。输入只有一个非空代码节,不含重定位;目标是把代码放到确定的位置,并正确描述入口和映射。节与段、程序头字段见原理篇 02,启动过程见原理篇 06。

起点:class4 代码与测试,位于 private 仓库,需要访问权限。复用 class0–3,在 class4 crate 的库接口中实现三个接口;命令行 I/O 和可执行权限处理已提供。

实现任务

任务接口要达到的结果
C4.1layout规划代码的文件偏移、文件大小和入口虚拟地址,不分配缓冲区
C4.2executable按规划写出 ELF 头、两个程序头、零填充和代码
C4.3link_single解析一个对象,检查支持范围,选择入口并生成产物

逐字段取值、错误顺序与边界见 class4 README。头部共 176 字节,代码从满足输入对齐的位置开始;文件偏移零对应 BASE=0x400000,因此入口是 BASE + code_offset + entry_offset。例如 12 字节代码、16 字节对齐、入口偏移零,代码占 [176,188),入口为 0x4000b0。

输出是 ET_EXEC,包含覆盖整个文件的 RX PT_LOAD,以及明确要求 RW、不可执行栈的 PT_GNU_STACK,不输出节头表。整数逐字段以小端序写入,不能把 Rust 结构体的内存布局当作文件格式。输入节标志和输出段权限是两套编码。

支持范围是恰好一个非空的已分配 PROGBITS 代码节、恰好一张符号表、没有非空 REL/RELA。入口必须是该代码节内的全局节定义,不能是 ABS、COMMON 或末尾之后的位置。按类型与标志识别代码,不要求节名为 .text。调用系统链接器或输出脚本不符合任务。

验收及其含义

在克隆后的仓库根目录、原生 x86-64 Linux 上执行:

cargo test --locked -p class4
cargo test --locked -p class4 --release
python3 scripts/grade.py class4

合同测试检查布局边界、诊断顺序、头部字段、零填充与非零入口偏移。原生测试汇编自己的系统调用程序,用 readelf 检查输出并执行,验证不同退出码、CLI、自定义代码节名以及非法输入。

退出码正确证明代码被执行;字段检查另外证明产物表达了要求的映射和栈策略。两者都需要通过。输入文件偏移、输出文件偏移、运行时虚拟地址也必须在实现中保持区别。