Skip to content

Commit e1eb01f

Browse files
committed
docs: add some tips
1 parent c00dc0d commit e1eb01f

File tree

1 file changed

+16
-1
lines changed

1 file changed

+16
-1
lines changed

README.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,14 @@ Relocation {
369369

370370
接着,处理所有的重定位项。在上面的例子中,`main.fle` 中有一个对 `str` 的引用需要重定位。
371371

372+
> [!TIP]
373+
> 在处理目标文件的符号表时,你会发现单个目标文件的符号表中可能包含未定义符号(即在当前文件中被引用但尚未定义的符号)。这与标准 ELF 格式的行为是一致的。处理这些符号时:
374+
> - 不要立即报告未定义错误
375+
> - 在后续的目标文件中继续查找该符号的定义
376+
> - 只有在处理完所有目标文件后,仍然找不到定义时才报错
377+
>
378+
> 这种机制允许目标文件之间相互引用,不要求符号定义必须出现在引用之前。
379+
372380
在这个阶段,我们只需要处理 `R_X86_64_32` 和 `R_X86_64_32S` 类型的重定位 —— 它们都是将符号的绝对地址填入重定位位置。
373381

374382
> [!TIP]
@@ -459,7 +467,7 @@ int main() {
459467
}
460468
```
461469
462-
> [!TIP]
470+
> [!NOTE]
463471
> 从任务三开始,我们开始包含 [`tests/common/minilibc.h`](./tests/common/minilibc.h) 库,这个库模拟了标准 C 库的一部分功能,提供预定义的 `_start` 函数,会将控制权交给 `main` 函数。
464472
465473
编译器会将这些源文件编译成目标文件。这个函数调用在我们的 FLE 格式中,表示为:
@@ -671,6 +679,13 @@ int debug = 1;
671679
> - 使用完整的符号名(包含前缀)进行重定位查找
672680
> - 在调试输出中显示完整的符号名,便于排查问题
673681
682+
> [!NOTE]
683+
> 对于需要报错的情况,你可以:
684+
> - 通过 `throw std::runtime_error("错误信息")` 抛出异常,实验框架会自动捕获并输出错误信息
685+
> - 或者使用 `std::cerr << "错误信息" << std::endl` 输出后调用 `exit(1)` 中止程序
686+
>
687+
> 我们的测试脚本采用宽松的匹配方式,只要错误信息中包含符合格式的一行即可通过测试。
688+
674689
完成后,你的链接器就能正确处理符号冲突和访问限制了。运行测试来验证:
675690
676691
```bash

0 commit comments

Comments
 (0)