动态链接之plt

来源:互联网 发布:日程提醒软件app 编辑:程序博客网 时间:2024/06/05 23:50

因为动态链接的过程需要在运行时完成,这个带来了资源的功用和节省,但同时因为这个过程需要耗费一定的时间(进程将执行权限交给动态连接器执行链接工作,包括共享对象装载以及一系列工作),再加上复制的GOT定位以及之后的间接寻址,所以动态链接相对静态链接一定会有一定效率的耗损。

这种效率耗损实际上因为机制上的问题无法得到完美解决,但是想想,将这一系列的工作都放在应用程序加载开始时进行,必然明显给人以这种效率的迟缓感觉,模块越多,系统越大,这种感觉越明显,因为链接器需要装载的对象会越多,GOT定位也会越多。

仔细想想,程序的执行毕竟相对而言,有一个时序过程,毕竟不大可能一开始就会用到所有的函数符号,所以将这个过程(符号的查找,GOT定位等)广尔散之,分散在整个程序的执行过程中,靠符号的初次使用来驱动这个过程能将这个效率的耗损分散到程序漫长的执行过程中,那么这种效率耗损就不那么明显了,这种类似写时复制(copy on write)的思想就是延迟绑定(Lazy Binding)。

这个思想需要一个结构来寄托,它做了什么呢?

通常来说,外部函数调用的过程是通过GOT表中的函数地址指针跳转,延迟绑定实际上是在这个过程之间又加了一层,写到这里,突然想起来一句话:软件工程中,任何问题都可以通过加一层来解决。。。。

那么这个结构里面装了什么呢,如果该函数符号已经使用过,即已经经过重定位,那么这个表项里就是GOT中函数的对应项。如果没有经过重定位,那么这个PLT表中对应的就是函数在重定位表.rel.plt中的下标,和其所在模块的moduleID,有了这两个参数,链接器就可以完成符号解析和重定位工作了,完成这个工作的是动态链接器中一个叫_dl_runtime_resolve()(.got.plt的第三项保存其地址,由链接器初始化时填充)的函数。


0 0
原创粉丝点击