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

[链接器的世界-实验篇08] 只留下被用到的:可达性回收与链接映射

本实验以节为单位回收不可达存储,并生成解释 KEEP/DROP 的链接映射。归档成员的抽取只决定哪些对象参与链接,GC 再决定这些对象中的哪些节进入输出。可达性与布局的通用关系见原理篇 05。

起点:class8 代码与测试,位于 private 仓库,需要访问权限。复用归档选择、符号选择、class6 布局与 class5 重定位。CLI、默认分类策略、ET_EXEC lowering 和 link 流程已提供;学生构建后续后端共用的 Prepared。

实现任务

任务接口要达到的结果
C8.1trace迭代遍历 Graph,返回存活节与 COMMON,报告可达的延迟错误
C8.2render_map按稳定身份排序并转义任意名称字节,输出规定的 map
C8.3prepare_with校验选中对象、分类节、解析引用和根,生成尚未布局的存活计划

接口、容器与全部规则见 class8 README。SectionId 是“选中对象序号、该对象的 ELF 节下标”,不是输出地址。边引用被选中的定义;Common 保留分配,Absolute 不保留存储,Undefined/Invalid 在可达时报告错误。

先按调用顺序检查所有根存在,再按规定的 DFS 边顺序遍历;使用显式栈,不能依赖递归线程栈。README 的 图与结果演算 给出存活集合,并解释死引用、根校验与 DFS 错误顺序为何产生不同结果。入口和 keep 是课程的根,不因导出或可见性自动保留构造函数、GNU_RETAIN 或脚本指定内容。

必须区分结构校验与应用校验:所有选中对象的节、符号和 RELA 结构都要合法,死节不能掩盖损坏的表;只有活节的引用才进入绑定错误报告和补丁应用。Prepared 保留稳定输入身份并只暴露不可变访问,不通过解析 map 恢复计划。

验收及其含义

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

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

合同测试检查根优先校验、DFS 错误顺序、环和长链、COMMON 存活以及 map 排序和转义。原生测试检查代码到数据/BSS 的依赖、死环、显式根、归档抽取、选中定义和死活引用的错误边界,并运行产物;另有 GNU ld 的有效样本对照。

判断 GC 是否正确要同时看 map 成员与运行行为,不能只看文件变小:页对齐可能让删除小节后的文件大小不变。map 不嵌入 ELF,也不能参与决定后端布局。