读书笔记-程序员的自我修养(四)

链接的接口:符号

  • 普及 : 链接的过程 实际上 就是 相互拼合 的过程,即目标文件中的(函数和变量) 地址引用符号 是拼合剂

  • 普及 : 我们将函数和变量统称为 符号(Symbol),函数名货变量名就是 符号名(Symbol Name)

  • 普及:符号统一存放在目标文件的 符号表(Symbol Table) 中,每个定义的符号有一个对应的 符号值(Symbol Value)

  • 主要关注的 链接对象 有:1. 定义在本目标文件的 全局符号,可以被其他目标文件引用 2. 在本目标文件中引用的 全局符号,却没有定义在本目标文件中,这一般叫做外部符号

  • ELF符号表 [.symtab] 结构详解

    • 逻辑结构Elf32_Sym 结构体 对应一个符号,符号表是一个 数组,其中

      • 符号类型和绑定信息(st_info):类型:局部,全局,弱引用,绑定信息:位置,对象,函数,段,文件

      • 符号所在段(st_shndx):符号定义在本目标文件中,即对应段的下表,如不在,则跟 深入静态链接COMMON块 有关

      • 符号值(st_value):依据符号所在段不同,值也会有不同的类型

    • 特殊符号:有些符号并没有在你的程序中定义,但是你可以直接声明并且引用它,称之为特殊符号,比如:__executable_start__etext__edata__end 这些符号当且仅在 链接过程中控制

    • 符号的管理

      • 修饰与函数签名:为了防止程序中的符号冲突,先后发明了 名称空间(namespace)符号修饰(Name Decoration) 等机制,以 函数签名(Function Signature) 作为符号的唯一标识,避免多个符号冲突,链接器无法识别

      • exten “C”:C++中用来声明或定义一个 C 符号的语法,配合 __cplusplus 来定义变量,这样就可以在 C 或 C++ 中正确的定义符号,使得链接器能够找到目标符号进行链接

      • 弱符号和强符号: 都是针对定义而言的,编译器默认函数和初始化了的全局变量为 强符号(Strong Symbol),未初始化的全局变量为 弱符号(Weak Symbol),链接器会在链接的时候,遵循3种选择规则,来选择强符号还是弱符号:1. 相同变量强弱都定义,选择强,2. 不允许强符号被多次定义,3. 都是弱,选择占用空间最大的

      • 弱引用和强引用:当链接器在引用决议时未发现符号就报错时,就是强引用,相反,不报错的就是弱引用。之所以有弱引用的存在,是为了使得程序可以在未发现符号的时候,使用原来库的定义,即便去掉了某个模块,也不会报错,方便解耦

  • 调式信息 DWARF(Debug With Arbitrary Record Format)

    • 使用命令 strip 来去掉 ELF 文件中的调试信息, 大幅度减少文件大小
如需转载,请注明出处