链接

链接的基本概念

链接是将各种代码和数据片段收集起来组合成一个单一文件的过程,且这个文件可以被加载到内存中并执行

  • 链接可以执行于编译时,也就是在源代码被翻译成机器代码的过程中
  • 链接可以执行于加载时,也就是在程序被加载器加载到内存中并执行
  • 链接可以执行于运行时,也就是由应用程序来执行

在早期的计算机系统中,链接是手动执行的。在现代系统中,链接是由叫做链接器的长须自动执行的。

链接器

链接器在软件开发中扮演着一个关键的角色,因为它们使得分离编译成为可能。现在我们可以把源文件分成很小的文件,方便更好的管理。
链接器的作用是把多个可重定位目标文件组合起来,创建一个可执行文件。
在这里插入图片描述
链接器的主要任务:

  • 符号解析:比如两个可重定位文件中有两个定义为a的变量,我们将它组合时则需变成只有一个a。
  • 重定位:通过每个符号定义与一个内存位置关联起来。

可重定位目标文件

可重定位文件就是源文件进过编译器和汇编器之后的文件,可重定位文件有固定的格式:
在这里插入图片描述

  • ELF头:ELF头以一个16字节的序列开始,这个序列描述了生成改文件的系统的字的大小和字节顺序。
  • .text:已编译程序的机器代码。
  • .rodata:只读数据。
  • .data:已初始化的全局和静态C变量。
  • .bss:未初始化的全局和静态C变量。
  • .symtab:一个符号表,它存放着程序中定义和引用的函数和全局变量的信息。
  • .rel.text:链接器调用时需要修改的地方。
  • .rel.data:被模块引用或定义的所有全局变量的重定位信息。
  • .debug:一个调用符号表。
  • .line:原始C源程序中的行号和.text节中机器指令之间的映射。
  • .strtab:一个字符串表。

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

链接器的输入是一组可重定位目标模块。每个模块定义一组符号,有些是局部的,有些是全局的。如果多个模块定义同名的全局符号,会发生什么呢?
在编译时,编译器想汇编器输出每个全局符号,或者是或者是,而汇编器把这个信息隐含的编码在可重定位目标文件的符号表里。函数和已初始化的全局变量是强符号,未初始化的全局变量是弱符号。如果出现符号重复的现象则按照以下规则执行:

  • 多个同名强符号则会出现错误。
  • 一个强符号和多个弱符号则选择强符号。
  • 如果有多个弱符号同名,则从弱符号中任选一个。

比如说:

/*fool.c/
int main()
{
	return 0;
}
/*bar1.c/
int main()
{
	return 0;
}
	

我们输入指令gcc fool.c bar1.c看看得到什么结果:
在这里插入图片描述
正如规则1所描述的,两个强符号出现了问题,规则2,3不做展示。

这就是有关链接的部分内容。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值