链接

静态链接

Unix ld程序这样的静态链接器,输入的可重定位的目标文件由各种不同的代码和数据节组成。指令在一个节中,初始化的全局变量在一个节中,而未初始化的变量在另外一个节中。
为了构造可执行文件,链接器必须完成连个主要任务
符号解析:
重定位:

目标文件

可重定位目标文件:
可执行目标文件:
共享目标文件:一种特殊类型的目标文件,可以在加载或者运行时被动态地加载到存储器并链接。
现代Unix系统使用的是Unix可执行可链接格式,ELF。

可重定位目标文件

.bss:未初始化的全局C变量,在目标文件中这个节不占据实际的空间,它仅仅是一个占位符。目标文件区分初始化和为初始化变量只是为了空间效率,在目标文件中,未初始化的变量不需要占据任何实际的磁盘空间。
.debug:一张调试符号表,其条目是程序中定义的局部变量和类型定义,程序中定义和引用的全局变量,以及原始的c源文件,只有以-g选项调用编译驱动程序才会得到这张表。

符号解析

解析多重定义的全局符号

在编译时,编译器向汇编器输出每个全局符号,或者强,或者弱。函数和已初始化的全局变量是强的,未初始化的全局变量是弱的。
Unix 链接器使用下面的规则来使用多重定义的符号:
规则1:不允许多个强符号
规则2:如果有一个强符号和多个弱符号,那么选择强符号的。
规则3:如果有多个弱符号,那么任选一个弱符号。

如果两个定义的全局变量的类型不同,可能会发生意想不到的情况。

与静态库链接

在Unix系统中,静态库以一种以存档(archive)的特殊文件格式存放在磁盘中。在链接时,编译器维持一个可重定位目标文件的集合E(这个集合中的文件会被合并起来形成可执行文件),一个未解析的符号(即引用了但是尚未定义的符号)集合U,以及前面输入文件中已经定义的符号集合D。初始时,这三者都是空的。
在命令行中,如果定义一个符号的库出现在引用这个符号的目标文件之前, 那么引用就不能被解析。
关于库的一般规则是将他们放在命令行的末尾,如果需要满足依赖需求,可以在命令行上重复库。

可执行目标文件

loader是驻留在存储器中的操作系统代码来运行它。任何Unix程序都可以通过调用execve函数来调用加载器。
每个Unix程序都有一个运行时存储器映像,在32位的系统中,代码段总是从地址0x08048000处开始的。数据段在接下来一个4KB对齐处。运行时堆在读写段之后接下来第一个4KB对齐地址处。用户栈总是从最大合法用户地址开始,向下增长的。

动态链接共享库

在动态链接过程中,链接器拷贝了一些重定位和符号表信息,他们使得运行时可以解析对libvector.so中的代码和数据。
加载部分链接

与位置无关的代码

在一个ia-32系统中,对同一个目标模块中过程的调用是不用特殊处理的,因为引用是pc相对的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值