程序员的自我修养-动态链接(2)

7.4延迟绑定(PLT)
 延迟绑定的原因主要是为了将动态链接的效率损失降低到最小。毕竟,大部分函数其实在装载之后是暂时不会被用到的,既然如此不如我们在需要的时候再装载他们吧~这就是延迟绑定。
 延迟绑定的基本原理貌似还是有点复杂(至少我对书上的讲解还有些不懂),既然如此我只能按书上的意思来说了。延迟绑定其实还是通过GOT来实现的。但此时GOT分为.got和.got.plt。前者保存的是全局变量的引用地址,后者用来保存函数引用地址。
对于.GOT.plt来说其前三项是有意义的。
 第一项:保存的是.dynamic段的地址
 第二项:保存的是本模块ID(?)
 第三项:保存的是_dl_RUNTIME_RESOLVE()函数的地址。发散的有点远。。。。
动态绑定的实现是通过利用上面说的两种表进行间接跳转实现的。
code:
 jmp *(bar@GOT)
 push n
 push moduleID
 jump _dl_runtime_resolve
 bar@GOT保存的是要重定位的函数的项(这里是bar),在重定位前这里保存的是下一条指令push n的地址。(n是bar这个函数的符号引用在重定位表.rel.plt中的下标)在push n执行后,会压入模块ID然后调用_dl_runtime_resolve来完成符号解析和重定位。最后将bar的真正地址压入bar@got中。
7.5动态链接相关结构
(这段抄书)
 在动态链接的情况下,操作系统还不能在装载完后,把控制权交给可执行文件,因为我们知道可执行文件依赖于很多共享对象,而此时很多外部符号的引用还处于未知无效状态,即还没有跟相应的共享对象中的实际未知链接起来。所以在操作系统映射完可执行文件后,会先启动一个动态链接器。
 在linux中,动态链接器ld.so实际上是一个共享对象,操作系统同样通过映射的方式将他加载到进程的地址空间中。加载完后,操作系统将控制权交给了动态链接器的入口地址,动态链接器在得到控制权之后,会执行一系列的初始化工作,然后根据环境参数对可执行文件进行动态链接工作。当动态链接完成后,动态链接器将控制权交给可执行文件的入口地址,程序开始执行。
 .interp段
这个段保存的是动态链接器的软连接
 .dynamic段
这个段保存了动态链接所需要的基本信息,比如依赖于那些共享对象,动态链接符号表的位置,动态链接重定位表的位置,共享对象初始化代码的地址。
  7.5.3动态符号表
为了在动态链接的情况下表示符号间的导入导出关系,ELF专门有一个叫做动态符号表的段用来保存这些信息。这个段名叫做“.dynsym”。不过这个段只保存了与动态链接相关的符号。对于模块内部的符号,比如模块私有变量,则不博爱村。
 7.5.4动态链接重定位表
 动态链接的文件中,有“.rel.dyn”和“.rel.plt”。前者是对数据引用的修正,它所引用的位置位于.got以及数据段:后者是对函数引用的修正,它所修正的位置位于.GOT.PLT。

 

 

(不过我到现在还是满脑子的浆糊啊啊啊啊啊啊啊,做实验去了!!!!!)

posted @ 2013-01-05 21:13  I_O_S  阅读(258)  评论(0编辑  收藏  举报