链接、装载与库[4]静态链接

1.链接器空间分配策略:两步链接法

  • 1)空间与地址分配:扫描所有的输入目标文件,获得它们各个段的长度、属性、位置,且将输入目标文件中的符号表中所有的符号定义和符号引用收集起来,统一放到一个全局符号表。链接器获得所有输入目标文件的段长度,并合并它们,计算出输出文件中各个段合并后的长度与位置,并建立映射关系。
  • 2)符号解析与重定位。读取输入目标文件中段的数据、重定位信息,并且进行符号解析与重定位等。

举例子:

$ld a.o b.o -e main -o ab
  • -e mian 表示将main函数作为程序入口,ld链接器默认程序入口为_start;
  • -o ab 表示链接输出文件名为ab, 默认为a.out

2.Common块

  • 现代的链接机制在处理弱符号的时候,采用的就是与COMMON块一样的机制。比如符号global_uninit_var,它们在符号表中的各个值为;

st_name = “global_uninit_var”
st_value = 4
st_size = 4
st_info = 0x11 STB_GLOBAL STT_OBJECT
st_other = 0
st_shndx = 0xfff2 SHN_COMMON

  • 按照COMMON类型的弱符号的链接规则,如果多个文件都含有global_uninit_var,输出文件中global_uninit_var所占空间以输入文件中的最大为基准。若其中有一个文件中将其定义为强符号,则最终以强符号为基准,且弱符号大小不能大于强符号。

3.C++的二进制兼容性

  • C++的二进制兼容性差。若库A是用Compiler A 编译的,库B是用Compiler B编译的,程序C想同时使用库A和库B会比较棘手。因为库厂商不希望用户看到库的源代码,一般提高库的二进制形式给用户。这样,若用户的编译器型号与版本与编译库所用的编译器型号和版本不同时,就可能产生不兼容。

4.静态库

  • 静态库(如“libc.a”)是一组目标文件的集合,即多个目标文件经过压缩打包("ar"压缩程序)后形成的一个文件;
  • Linux最常用的C语言静态库libc位于/usr/lib/libc.a,它属于glibc项目的一部分,glibc由成百上千个C语言源代码文件组成;
  • 静态运行库里面一个目标文件只包含一个函数,如libc.a里面printf.o只有printf()函数。
  • 注释:静态链接器符号为ld

猜你喜欢

转载自blog.csdn.net/qq_43118572/article/details/113848772