深入理解-位置无关代码
2017-03-05 16:42
176 查看
位置无关代码:
起因:
当程序在多个不空地址空间运行时,操作系统通常会将程序加载到各个地址空间的相同位置,这样可以让链接期在程序加载时不用再重定位,将地址绑定到固定位置。
对于动态库而言,如果如果我们不将动态库编译成PIC的也就是意味着loader一定要把动态库加载到某个特定
的地址(该地址编译的时候就确定了)上它才可以正确的执行。
--
如果有ABCD四个库,,假设程序P1依赖A B两个动态库,P2依赖C D两个动态库,那么A B和C D的动态库的加载地址有重叠也
没有关系,P1和P2可以同时运行。但是如果有一个新的程序P3依赖A B C D四个动态库,那么前面为动态库分配的加载地址就
不能正常工作了。当然,重新为这四个动态库分配load address(让地址不重叠)也是ok的,但是这样一来,P1虽然没有使用
C D这两个动态库,但是P1的地址空间还是要保留C D动态库的那段地址,浪费资源。
PIC
于是出现了可以直接加载而无需重定位的代码(位置无关代码)。主要是因为无论内存在何处加载目标模块,数据段和代码段的距离总是保持不变的。
因此,代码段中的任意指令与数据段中的任意变量之间的距离在运行时都是一个常量,而与代码和数据加载的绝对内存位置无关。
延迟绑定
一个程序只会调用共享库中一部分的程序,将函数地址的绑定推迟到实际调用的时候,能够避免动态链接器在加载的时候进行成百上千不需要的重定位。
--
延时绑定主要是通过两个数据结构来实现GOT和PLT(过程链接表).
如果一个目标模块调用了共享库中的任意函数,那么它就有它自己的GOT和PLT。GOT是.data段的一部分。PLT是.text段的一部分。
GOT[0]中保存的是.dynamic段的地址,其中保存着动态链接器用来绑定过程地址所需要的信息,包括符号表的位置和重定位信息。
GOT[1]中保存着当前模块的一些信息。
GOT[2]是动态链接器延迟绑定代码的入口地址。
GOT[3]开始。比如,定义在libc.so的printf,以及定义在libvector.so的addvec。
GOT[0]:addr of .dynamic ... GOT[4]:0x4005c6 #add() ->(调用过后) GOT[4]:&add
每个PLT占了16个字节,PLT[0]条目是跳转到动态链接器,PLT[1]则是调用系统启动函数。
#PLT[0] 4005a0:pushq *GOT[1] 4005a6:jmpq *GOT[2] ... #PLT[2]: call add() 4005c0: jmpq *GOT[4] 4005c6: pushq $0x1 4005cb: jmpq 4005a0
如果运行过程中遇到一个函数add:
如果add是第一次被调用,初始时GOT条目指向的 其PLT的下一条指令。于是将add()的ID(0x1)压入栈,然后跳转到PLT[0]
PLT[0]通过GOT[1]间接地把动态链接器的一个参数压入栈,然后GOT[2]跳转到动态链接器。
动态链接器通过 两个栈条目来确定 add()的位置,然后写入GOT[4]。
所以仅在第一次调用是会产生额外的时间开销(通过动态链接器找地址),但在后面的调用中仅仅消耗一条额外指令和内存引用。
参考:
位置无关(PIC)代码原理剖析:http://blog.csdn.net/loushuai/article/details/50493603深入理解计算机结构
计算机科学基础知识(四): 动态库和位置无关代码:http://www.wowotech.net/basic_subject/pic.html
位置无关代码:http://www.cnblogs.com/tekkaman/archive/2013/03/04/2943118.html
相关文章推荐
- bootloader与linux中位置无关代码(PIC)的分析理解
- bootloader与linux中位置无关代码(PIC)的分析理解
- ARM 位置无关代码(PIC)的分析理解
- bootloader与linux中位置无关代码的分析理解
- ARM 位置无关代码(PIC)的分析理解
- bootloader与linux中位置无关代码(PIC)的分析理解
- bootloader与linux中位置无关代码(PIC)的分析理解
- bootloader与linux中位置无关代码(PIC)的分析理解
- 对位置无关代码的理解
- bootloader与linux中位置无关代码(PIC)的分析理解
- bootloader与linux中位置无关代码(PIC)的分析理解
- bootloader与linux中位置无关代码的分析理解
- arm蛋疼汇编part 10--与位置有关代码 与位置无关代码
- 深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点
- ARM位置无关代码设计规范
- 深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点
- 深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点javascript
- 深入理解 GNU GRUB - 03 diskboot.S 3.1 diskboot.S执行时的环境 & 3.2 diskboot.S代码结构
- 深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点
- 一个String代码,便于深入理解String