《程序员的自我修养》笔记二:目标文件

目标文件

程序与目标文件

源代码经过编译器编译后生成的文件,是已经编译后的可执行文件格式,只是还没有经过链接,与真正的可执行文件在结构上稍有不同。

目标文件在不同的段中保存代码、数据和辅助信息

ELF 文件结构

ELF 结构

  • 文件头
    包含了描述整个文件的基本属性
    • ELF 文件版本
    • 目标机器型号
    • 程序入口地址
    • 段表的位置、长度和段的数量
  • 各个段
    应用程序可以自定义段,段名以 .作为前缀的是系统保留段
    • .text
      保存代码
    • .code
      保存程序的指令
    • .data
      保存程序中已初始化的全局变量和静态变量
    • .bss
      未初始化的全局变量和静态变量,并没有内容,在文件中不占据空间
    • .rodata
      保存只读数据
    • .debug
      存放调试信息,调试信息在目标文件和可执行文件中占用很大的空间,发布时需去掉
  • 段表(Section Header Table)
    描述了 ELF 文件所包含的所有段的信息,段的结构是由段表决定的
    • 段表内容
      • 段名
      • 段长
      • 文件中的偏移
      • 读写权限
      • 段的其他属性
    • 重定位表
      同时也是 ELF 的一个段
      • 每个在链接时需要重定位的代码段和数据段,都有一个相对应的重定位表
    • 字符串表
      同时也是 ELF 的一个段
    • 符号表 (Symbol Table/.symtab)
      • 符号名
        函数名或变量名就是符号名
      • 符号值
        函数或变量的地址
      • 符号大小
      • 符号所在段
      • 符号类型和绑定信息
        • 符号类型
          • 未知类型
          • 数据对象
            变量或数组等
          • 函数或可执行代码
          • 文件名
            该目标文件所对应的的源文件名
        • 绑定信息
          • 局部符号
          • 全局符号
          • 弱引用

链接的接口——符号

链接过程中,目标文件之间的连接就是对符号(函数和变量)的地址的引用

链接过程值关心全局符号的相互粘合,其他符号对于其他目标文件来说是不可见的,在链接过程中无关紧要。

特殊符号

链接器链接可执行文件时,会定义许多特殊的符号,我们可以在程序中直接声明并引用

部分特殊符号:

__executable_start
__etext/_etext/etext
_edata/edata
_end/end

符号修饰与函数签名

强符号和弱符号

强符号和弱符号是针对定义来说的

  • 强符号
    函数和初始化的全局变量为强符号​
  • 弱符号
    未初始化的全局变量为弱符号
  • 处理规则
    • 不允许强符号被定义多次
    • 一个符号在某个目标文件中是强符号,其他文件中是弱符号,链接器会选择强符号
    • 一个符号在所有目标文件中都是弱符号,链接器选择占用空间最大的一个
  • 强引用和弱引用
    • 强引用
      对外部目标文件的符号引用,如果未找到定义,链接器报错
    • 弱引用
      对于未定义的弱引用,链接器不报错
  • 作用
    弱符号和弱引用对于库来说十分有用,库定义的弱符号可以被用户定义的强符号覆盖,或将扩展功能模块的引用定义为弱引用,扩展模块和程序链接一起时,功能可以使用,去掉功能模块,程序也可以正常链接,只是少了相应的功能,使程序功能组合更方便

可执行文件格式

可执行文件格式 PE(Windows)和 ELF(Linux)都是 COFF 格式的变种,目标文件可以看成是可执行文件的一种

  • 可执行文件
    EXEELF

  • 动态链接库
    .dll.so

  • 静态链接库
    .lib.a​ 静态链接库可以理解为包含很多目标文件的文件包


为什么把程序指令和数据分开存放?

源代码被编译后主要分为两种段:程序指令和程序数据

  • 分权限,数据域可读写,指令域只读,防止程序指令被改写
  • 因为现代 CPU 的缓存被设计为数据和指令缓存分离,提高缓存的命中率
  • (最重要)当运行多个该程序的副本时,只需要保存一份该程序的指令域,只读数据也是可以共享的,节省大量的内存。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值