链接器那些事

src如何成为exe

一般来说,编译器不是一个单一的庞大的程序,通常由多大6,7个稍小的程序所组成,这些程序由编译器驱动器来调用,主要有:预处理器,语法和语义检查器,代码生成器,汇编程序,优化器,链接器。如下图所示,目标文件不能直接执行,需要载入到链接器中,链接器确认main函数为初始进入点,把符号引用绑定到内存地址,把所有目标文件集中在一起,再加上库文件,从而产生可执行程序。
这里写图片描述

  • 静态链接:如果函数库的一份拷贝是可执行文件的一部分,称之为静态链接
  • 动态链接:如果可执行文件只是包含了文件名,让载入器在运行时能够寻找到程序所需要使用的函数库,称之为动态链接
  • 注意的是,静态链接的程序也只是链接了需要的函数

动态链接的特点

  • 可执行文件体积小,节省磁盘空间和虚拟内存
  • 运行速度稍慢
  • ABI应用程序二进制接口,可以把程序与它们所使用的特定的函数库版本中分离开,取而代之,约定一个接口,保持接口的稳定,甚至可以在运行时换一个库
  • 使得函数库版本升级更容易,新版本可以随时发布,已经有的应用程序不需要重新链接
  • 任何人都可以创建静态库或者动态库,只需要写没有main的代码,静态库用ar,动态库用ld

函数库链接的5个秘密

  • 动态库扩展名是.so,静态库是.a
  • 例如,如果通过-lthread选项,告诉编译器链接到libthread.so
  • 编译器期望在确定的目录找到库(可以使用-Lpathname告诉编译器其他目录,也有环境变量LD_LIBRARY_PATH和LD_RUN_PATH来告诉编译器这类信息,处于安全考虑,一般不在环境变量中直接设置,而是在链接时使用-Lpathname和-Rpathname)
  • 观察头文件,确认所使用的函数库
  • 与提取动态库的符号相比,静态库的符号提取方法限制更严

Interpositioning(重名函数)

通过编写与库函数名字相同的函数,可以取代库函数的行为,使用这个特性尤其要小心,不仅你自己所进行的所有对函数库的调用将被自己的函数所替代,而且调用该库函数的系统调用也会被你的函数取而代之。
多年来,这个特性一直没有被发现有不可替代的作用,反倒是引起了不少bug,因为大家也并不是都知道库函数到底提供了哪些名字

ld命令产生连接器报告文件

  • 可以在ld程序中使用-m命令,让连接器生成一个报告,包括被Interpositioning的符号的说明
  • 使用ldd命令,可以查询可执行文件所依赖的动态链接库

Reference

C专家编程

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值