《深入理解计算机系统》第七章 链接(Linking)
本章主要讲解链接器如何将多个目标文件.o .a .so组合成可执行文件或共享库以及链接过程中涉及的符号解析、重定位、动态链接等核心机制。以下是对关键知识点的梳理并关联了Link Lab实验。1. 编译驱动程序与链接的作用链接器在编译器驱动程序的最后阶段工作其作用包括将分散的代码和数据合并成单一可执行文件解析符号引用如函数调用、全局变量引用与符号定义如函数、全局变量之间的对应关系重定位目标文件中的地址使得代码和数据能够加载到正确的内存位置。使用静态链接时链接器会拷贝所有被引用的目标模块使用动态链接共享库时则仅在运行时加载共享库节省磁盘和内存空间。2. 目标文件格式可重定位目标文件.o包含代码、数据、符号表、重定位信息等尚未链接。可执行目标文件a.out已完全链接可直接加载到内存执行。共享目标文件.so/.dll动态链接库可加载时链接或运行时链接。ELFLinux和PEWindows是两种常见的二进制格式书中以ELF为例讲解节区.text, .data, .bss, .symtab, .rel.text等。3. 符号解析与强符号规则符号解析阶段链接器为每个符号引用找到其对应的符号定义。规则如下强符号函数初始化了的全局变量。弱符号未初始化的全局变量。规则多个强符号冲突报错一个强符号多个弱符号选择强符号多个弱符号任意选一个通常为大者。正确理解该规则可避免因同名全局变量导致的意外错误如两个模块定义了同名的全局变量int x其中一个未初始化则可能导致未定义行为。4. 重定位与地址链接经过符号解析后链接器执行重定位合并相同节区如所有.text合并。为每个符号分配运行时地址虚拟地址空间。修改符号引用处的地址将其指向正确的符号定义。书中详细介绍了绝对重定位如R_X86_64_64和相对重定位如R_X86_64_PC32的计算方式。例如在x86-64架构中相对调用指令call func使用偏移量链接器会计算目标地址与当前指令地址之差填入指令中。5. 动态链接与共享库静态库.a链接时整体拷贝生成的可执行文件独立但臃肿。共享库.so运行时加载动态链接器ld-linux.so负责解析符号和重定位实现多个进程共享同一份库代码。动态链接过程包括位置无关代码PIC通过GOT全局偏移表和PLT过程链接表实现地址无关性支持共享库的随机加载。延迟绑定Lazy Binding第一次调用库函数时才解析符号提高启动速度。6. Link Lab 实验对应本书配套的Link Lab实验第七章提供了实际动手操作的机会通过修改链接器行为或分析目标文件深化对链接过程的理解。实验内容包括编写简单的链接器支持符号解析和重定位。观察ELF文件结构使用readelf或objdump工具。实现共享库的动态加载与符号解析。建议在阅读教材第七章后同步完成Link Lab的源文件如GitHub上csapp-link-lab仓库中的linker.c和resolve.c以验证对重定位算法和符号表操作的理解。相关问题链接过程中静态链接与动态链接在性能、内存占用、部署灵活性方面各有何优缺点符号解析的强弱规则在实际工程中如何避免大型项目中的符号冲突如何利用readelf工具分析一个ELF可重定位目标文件的符号表和重定位条目Link Lab实验中实现相对重定位如R_X86_64_PC32时需要注意哪些地址计算细节动态链接中的延迟绑定PLT/GOT机制如何工作为什么能提高启动速度: 参考《深入理解计算机系统》第七章“链接”知识整理强调链接器构造大型程序、避免危险编程错误、理解作用域规则等作用。本仓库提供Link Lab源文件及文档说明对应第七章链接实验包含源文件、文档和参考答案。