静态连接总结
2012-06-03 16:26
127 查看
目前的链接器都采用2步链接法,链接过程可采用脚本来控制
1,空间与地址分配,
2,符号解析与重定位
一空间与地址分配
有2种方式,按序叠加如图1,相似段合并如图2。目前一般采用第二种方法。
事实上,我们在这里谈到的空间分配只关注于虚拟地址空间分配。
图1
图2
在Linux下,ELF可执行文件默认从地址0x08048000开始分配。
$ld a.o b.o -e nomain -o ab
-e nomain表示将nomain函数作为程序入口,ld链接器默认的程序入口为_start(并非程序一定从main函数入口,也可以没有main函数)
二 符号解析与重定位
$objdump -d a.o
使用objdump -d参数可以看到代码段反汇编的结果。
在未进行空间分配之前,目标文件代码段中的起始地址以0x00000000开始,等到空间分配完成以后,各个函数才会确定自己在虚拟地址空间的位置。
$readelf -s a.o
查看 a.o 的符号表。
三,common块机制
概念:当不同的目标文件需要的common 块空间大小不一致时,以最大的那个块为准。
编译器将未初始化的全局变量定义作为弱符号处理。
当编译器将一个编译单元编译成目标文件的时候,如果该编译单元包括了弱符号(未初始化的全局变量)那么该弱符号最终所占空间的大小是未知的,
因为有可能其他编译单元中该符号所占的空间比本编译单元该符号所占的空间要大。所以编译器此时无法为该弱符号在BSS段分配空间,因为所需空间大小未知。
但在链接过程中可以确定弱符号的大小,所以它可以在最终输出文件的BSS段为其分配空间。
四,重复代码消除,
产生的可能:模板\ 外部内联函数\虚函数表
针对模板的方法是:将每个模板的实例代码都单独地存放在一个段中。
其他也是用同样的方法来消除。
五\
.init ,若一个函数放在.init段,在 main函数执行前系统就会执行它。
. fini,若一个函数放在. fini段,在 main函数执行后该函数就会被执行。
C++中构造与析构函数就是由此而实现。
六\BFD库
目标:通过一种统一的接口来处理不同的目标文件格式。
现在GCC\ 链接器LD \调度器GDB及binutils 的其他工具都通过BFD库来处理目标文件
ubuntu下包含BFD开发库的软件包为binutils-dev
1,空间与地址分配,
2,符号解析与重定位
一空间与地址分配
有2种方式,按序叠加如图1,相似段合并如图2。目前一般采用第二种方法。
事实上,我们在这里谈到的空间分配只关注于虚拟地址空间分配。
图1
图2
在Linux下,ELF可执行文件默认从地址0x08048000开始分配。
$ld a.o b.o -e nomain -o ab
-e nomain表示将nomain函数作为程序入口,ld链接器默认的程序入口为_start(并非程序一定从main函数入口,也可以没有main函数)
二 符号解析与重定位
$objdump -d a.o
使用objdump -d参数可以看到代码段反汇编的结果。
在未进行空间分配之前,目标文件代码段中的起始地址以0x00000000开始,等到空间分配完成以后,各个函数才会确定自己在虚拟地址空间的位置。
$readelf -s a.o
查看 a.o 的符号表。
三,common块机制
概念:当不同的目标文件需要的common 块空间大小不一致时,以最大的那个块为准。
编译器将未初始化的全局变量定义作为弱符号处理。
当编译器将一个编译单元编译成目标文件的时候,如果该编译单元包括了弱符号(未初始化的全局变量)那么该弱符号最终所占空间的大小是未知的,
因为有可能其他编译单元中该符号所占的空间比本编译单元该符号所占的空间要大。所以编译器此时无法为该弱符号在BSS段分配空间,因为所需空间大小未知。
但在链接过程中可以确定弱符号的大小,所以它可以在最终输出文件的BSS段为其分配空间。
四,重复代码消除,
产生的可能:模板\ 外部内联函数\虚函数表
针对模板的方法是:将每个模板的实例代码都单独地存放在一个段中。
其他也是用同样的方法来消除。
五\
.init ,若一个函数放在.init段,在 main函数执行前系统就会执行它。
. fini,若一个函数放在. fini段,在 main函数执行后该函数就会被执行。
C++中构造与析构函数就是由此而实现。
六\BFD库
目标:通过一种统一的接口来处理不同的目标文件格式。
现在GCC\ 链接器LD \调度器GDB及binutils 的其他工具都通过BFD库来处理目标文件
ubuntu下包含BFD开发库的软件包为binutils-dev
相关文章推荐
- C++编译连接总结(二)--自己的静态库动态库的编译与引用
- oracle连接总结(内连接、外连接、自然连接,交叉连接,自连接)
- 静态库部分代码未被连接解决方案
- java基础 变量和静态的总结
- 学习总结:java面试方法重写详解,静态代码块和构造方法执行顺序问题
- 【总结:数据库连接字符串的使用方法】
- Java中JDBC连接数据库代码和步骤详解总结
- Django关于访问静态文件总结
- 静态连接库、动态连接库、和com组件 (ZZ)
- tomcat问题总结之-连接超时-maximum-active-time
- SSH服务突然连接不了案例总结
- android 静态连接库引用方法
- Java反射学习总结三(静态代理)
- 数据库连接池、静态连接,普通连接的比较1(单线程)
- 关于静态变量,静态代码块,实例变量,实例代码块,构造函数的执行顺序的总结
- Oracle内连接、外连接、右外连接、全外连接小总结
- Java中解锁数组正确姿势以及赋值,foreach遍历?,Java自带的对数组排序,比较等等的静态方法总结
- URLConnection的连接、超时、关闭用法总结
- java中利用JDBC连接MySQL方法总结
- 静态连接和动态链接有什么区别?