链接器那些事

来源:互联网 发布:淘宝白底图拍摄技巧 编辑:程序博客网 时间:2024/05/22 14:23

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
原创粉丝点击