深入理解计算机系统第七章 链接知识整理

文章目录

  • 前言
  • 一、学习链接的目的是什么?
  • 二、正文
    • 1.编译器驱动程序
    • 2.静态链接
    • 3.目标文件
    • 4.可重定位目标文件
    • 5.符号和符号表
    • 6.符号解析
    • 7.重定位
  • 总结


前言

深入理解计算机系统第7章 链接知识梳理
深入理解计算机系统第七章 链接知识整理_第1张图片


一、学习链接的目的是什么?

  1. 构造大型程序
  2. 避免一些危险的编程错误
  3. 理解语言的作用域规则是如何实现的
  4. 理解其他重要的系统概念(加载和运行程序、虚拟内存、分页等)
  5. 效率
  6. 利用共享库

二、正文

1.编译器驱动程序

示例
深入理解计算机系统第七章 链接知识整理_第2张图片

以前的方法,

linux>gcc -Og -o prog main.c sum.c
linux>./prog

如果分开进行编译和链接
深入理解计算机系统第七章 链接知识整理_第3张图片

cpp:c预处理器

cpp main.c sum.c

ccl:c编译器,翻译成汇编

ccl main.i -Og -o main.s

as:汇编器,翻译成可重定位目标文件

as -o main.o main.s

ld:链接器程序,将两个文件以及必要的系统目标文件组合起来创建一个可执行目标文件prog

ld -o prog main.o sum.o

2.静态链接

静态链接:以一组可重定位目标文件和命令行参数作为输入,生成一个完全链接的、可以加载和运行的可执行目标文件作为输出

链接器的两个主要任务:
(1)符号解析
深入理解计算机系统第七章 链接知识整理_第4张图片

	将每个符号引用正好和一个符号定义关联起来

(2)重定位
·编译器和汇编器生成从地址0开始的代码和数据节
·链接器把每个符号与一个内存位置关联起来,重定位这些节
·修改所有对这些符号的引用,使其指向这个内存位置
·链接器使用汇编器产生的重定位条目的详细指令,执行重定位

3.目标文件

1.可重定位目标文件(.o文件)
2.可执行目标文件(a.out文件)
3.共享目标文件(.so文件)
以上三种皆有目标文件的标准二进制格式:ELF二进制文件

4.可重定位目标文件

Elf头 :字大小、字节顺序、文件类型、机器类型
.text节(代码):已编译程序的机器代码
.rodata节(只读数据):跳转表
.data节(数据、可读写):已初始化全局变量和静态C变量
.bss节(未初始化变量):未初始化全局变量、所有被初始化为0的全局或静态变量、有节头,但不占用空间
.symtab节(符号表):函数和全局变量的名字、节名称位置
.rel.text节(可重定位代码):.text节的可重定位信息、在可执行文件中需要修改的指令地址、需要修改的指令
.rel.data节(可重定位时间):.data节的可重定位信息,在合并后的可执行文件中需要修改的指针数据的地址
.debug节(调试)
.line节
.strtab节:一个字符串表,程序中用到的符号和名字
.节头表:每个节的偏移量和大小
使用GNU READELF程序查看main.o目标文件的内容
深入理解计算机系统第七章 链接知识整理_第5张图片
使用GNU READELF程序查看main.o目标文件内容:

指令
readelf -a main.o

深入理解计算机系统第七章 链接知识整理_第6张图片

展开main.o文件
hexdump -C main.o
注意C要大写

深入理解计算机系统第七章 链接知识整理_第7张图片

反汇编
objdump -d main.o

深入理解计算机系统第七章 链接知识整理_第8张图片

深入理解计算机系统第七章 链接知识整理_第9张图片

.symtab符号表:Ndx列是每个符号所在的Section编号,例如array在第3个Section里(也就是.data)。Value列是每个符号所代表的地址。符号地址都是相对于符号所在的section…
.strtab中保存着程序中用到的符号的名字。每个名字都是以’\0’结尾的字符串。
.shstrtab中保存着各Section的名字,每个名字都是以’\0’结尾的字符串。
.rel.text告诉链接器指令中的哪些地方需要重定位。
图片
节头部表起始地址:648(0x288)
深入理解计算机系统第七章 链接知识整理_第10张图片

深入理解计算机系统第七章 链接知识整理_第11张图片

5.符号和符号表

  • 全局符号
    • 由模块m定义的,可以被其他模块引用的符号
    • 如非静态 non-static C函数与非静态全局变量
  • 外部符号
    • 由模块m引用的全局符号,但由其他模块定义
  • 本地/局部符号
    • 由模块m引用的全局符号,但由其他模块定义
    • 如使用静态属性static定义的C函数和全局变量
    • 程序中的局部变量是由编译器管理的,链接器并不知道。因此,本地链接符号不是局部程序变量

深入理解计算机系统第七章 链接知识整理_第12张图片
深入理解计算机系统第七章 链接知识整理_第13张图片

ELF中.symtab节包含ELF符号表,这张符号表包含一个条目的数组。

  • name

    • 字符串表中的字节偏移,指向符号的以null为结尾的字符串名字
  • value:符号地址

    • 对于可重定位模块:value是距定义目标节的起始位置的偏移对于可执行目标文件:value是绝对运行时地址
  • size:目标的大小(以字节为单位)

  • type:数据或函数

  • binding:表示符号是本地的还是全局的
    深入理解计算机系统第七章 链接知识整理_第14张图片

  • section
    标识每个符号被分配到目标文件的哪个节中,该字段是一个到节头部表的索引

深入理解计算机系统第七章 链接知识整理_第15张图片深入理解计算机系统第七章 链接知识整理_第16张图片
例子

6.符号解析

  • 局部符号的引用
    编译器只允许每个模块中每个局部符号有一个定义
  • 全局符号的引用
    编译器找不到符号的定义时,会在其他模块找,实在找不到就报错
    示例
    深入理解计算机系统第七章 链接知识整理_第17张图片

符号的强弱

  • 强: 函数和初始化全局变量
  • 弱: 未初始化的全局变量

链接器如何解析多重定义的全局符号

规则1:不允许多个同名的强符号
规则2:若有一个强符号和多个弱符号同名,选择强符号
规则3:多个弱符号同名,任意选一个(编译器不同排列规则不同)
深入理解计算机系统第七章 链接知识整理_第18张图片
深入理解计算机系统第七章 链接知识整理_第19张图片
深入理解计算机系统第七章 链接知识整理_第20张图片
深入理解计算机系统第七章 链接知识整理_第21张图片

避免上述规则带来预期之外的后果,尽量不使用全局变量

  • 使用static标识

  • 定义了一个全局变量就初始化,让它变成一个强符号


  • 与静态库链接
    深入理解计算机系统第七章 链接知识整理_第22张图片

    • 静态库提出,为解决上述方法的缺点
    • 将所有相关的目标模块打包成一个单独的文件
  1. 串联一个静态库
    深入理解计算机系统第七章 链接知识整理_第23张图片

老方法

gcc -Og main.c addvec.c .....  -o prog2a
./prog2a

深入理解计算机系统第七章 链接知识整理_第24张图片

使用静态库
深入理解计算机系统第七章 链接知识整理_第25张图片

gcc -c addvec.c multvec.c
加入静态库,使用归档器ar
ar rcs libvector.a addvec.o multvec.o
gcc -c main2.c
链接
gcc -static -o prog2c main.o libvector.a
./prog2c
结果如下图

深入理解计算机系统第七章 链接知识整理_第26张图片

  • 链接器在解析外部引用的算法:
    • 按照在命令行的顺序扫描.o与.a文件
    • 在扫描期间,保持一个当前未解析的引用列表
    • 扫到每一个新的.o或.a文件,遇到目标obj,尝试解析列表之后的内容
    • 若后面没有,就会报错

深入理解计算机系统第七章 链接知识整理_第27张图片

  • 问题:
    • 命令行中的顺序很重要
    • 准则:将库放在命令行的末尾(重要)

深入理解计算机系统第七章 链接知识整理_第28张图片

静态库的缺点:大量重复代码(每个函数都要libc),系统库的小错误修复要每个应用程式显式的重新链接

7.重定位

合并输入模块,为每个符号分配运行地址,两步

  • 第一步

    • 重定位节和符号定义:将所有相同类型的节合并为同一类型的新的聚合节
      深入理解计算机系统第七章 链接知识整理_第29张图片
  • 第二步

    • 重定位节中的符号引用:修改符号引用,使他们指向正确的运行时的地址。该过程依赖可重定位模块中的重定位条目之一数据结构。
    • 重定位条目
      • offset
      • symbol
      • type
        • 使用32位pc相对地址的引用
        • 使用32位绝对地址的引用
      • addend:是一个有符号常数,某些类型的重定位利用它对被修改引用的值做偏移调整
        深入理解计算机系统第七章 链接知识整理_第30张图片

相对引用与绝对引用

相对地址的计算
深入理解计算机系统第七章 链接知识整理_第31张图片

作用
深入理解计算机系统第七章 链接知识整理_第32张图片

绝对引用的计算

深入理解计算机系统第七章 链接知识整理_第33张图片

总结

以上就是今天要讲的内容,下午四节课太困了,老师讲的慢,不敲点东西真的要睡觉了,顺便就把这些整理出来当复习资料

你可能感兴趣的:(linux,开发语言,c语言,硬件工程,学习方法)