Linux动态链接过程延迟绑定的实现(2)

上面描述的是PLT的基本原理,PLT的真正实现要比它的结构复杂一些,ELF将GOT拆分成两个表".got"和"".got.plt"。其中"".got"用来保存全局变量的引用地址。".got.plt"用来保存函数引用的地址,也就是说,所有对于外部函数的引用全部被分离出来放到了 ".got.plt"中。另外 ".got.plt"还有一个特殊的地方就是它的前三项是有特殊意义的,分别含义如下:

第一项保存的是 ".dynamic" 段的地址,这个段描述了本模块动态链接的相关信息,我们在后面还会介绍 ".dynamic"段

第二项保存的是本模块的ID

第三项保存的是_dl_runtime_resolve()的地址

其中第二项和第三项由动态链接器在转载共享模块的时候负责将它们初始化。".got.plt"的其余项分别对应每一个外部函数的引用。PLT的结构也与我们示例中的PLT稍有不同,为了减少代码的重复,ELF把上面的例子中的最后两条指令放在PLT中的第一项,并且规定每一项是16个字节,刚好用来存放3条指令,实际上的PLT的基本结构如图所示:

Linux动态链接过程延迟绑定的实现

实际上的PLT结构如下:

PLT0: push *(GOT + 4) jump *(GOT + 8) .... bar@plt: jmp *(bar@GOT) push n jump PLT0

PLT在ELF文件中以独立代码的段存放,段名通常称为 ".plt",因为它本身就是一些地址无关的代码,所以可以跟代码段一起合并成同一个可读可执行的""Segment"被装载到内存中

Linux公社的RSS地址https://www.linuxidc.com/rssFeed.aspx

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/df828922658238d21f79d8e66a16f3ed.html