《深入理解计算机系统》Linking

 为什么不把所有的文件都编译到一个可执行文件中:

1. 效果:分成多个模块,有利于开发不同的优秀的模块,开发不同的库。

2. 效率:改代码时,只需要重新编译一个模块,替换即可。

链接器做的2件事:

1. 符号解析。

2. 重定位:在重定位之前,每个模块中的函数和数据只对应了在本模块的偏移。链接器将所有的模块的函数和数据进行合并,并把他们重定位。

目标文件有三种,所有的目标文件都是elf格式的:

1. 可重定位目标文件(.o):

2. 可执行目标文件(.out可执行文件):

3. 共享目标文件(.so):

.p .out .so 都是elf文件

elf文件格式:

int func1()

{

static int x = 0;

xxx

return 0;

}

int func2()

{

static int x = 0;

xxx

return 0;

}

func1和func2中的x只是在函数内有效,存储在.data段中。符号可能时x_func1,x_func2

多重定义的符号:

已初始化的全局变量优先级高于未初始化的全局变量

链接器的规则:

1. 多个强符号的定义,报错。

2. 如果有一个强符号和多个弱符号同名,则选择强符号

3. 如果有多个弱符号同名,则选择弱符号(如果使用gcc的-fno-common选项,则多个弱符号同名则会报错)(或时殷弘-Werror选项,将所有警告变成错误)

强弱符号可能导致的bug:

可执行目标文件和进程虚拟地址空间的对应关系:

所有的代码段都是从0x400000开始的。

所有的栈底端地址都是2的48次方-1(64位机)或3G(32位机)

动态申请内存时,如果申请<128k内存,则申请的内存位于堆区。若申请>128k,则申请内存位于堆和栈之间的某处。

readelf -s xxx.so | grep FUNC

查看so文件的符号表中的函数

当使用dlclose卸载某个so,但是so里头开了线程,必须把线程先退出,否则调用dlclose就会出现问题,会coredump

练习:

1. dlopen模拟上面的coredump

2. 库打桩

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值