了解动态链接(四)—— 延迟绑定
2015-06-21 19:05
218 查看
ilocker:关注 Android 安全(新入行,0基础) QQ: 2597294287
基本思想是当函数第一次被调用时才进行绑定,所谓绑定就是符号查找和地址重定位。对于一些错误处理函数或不常用的功能函数,可能就避免了“绑定浪费”。采用延迟绑定,能加快程序的启动速度,特别有利于一些大型程序。
当函数第一次被调用时,由动态链接器完成地址绑定工作。他必须知道地址绑定发生在哪个模块的哪个函数,并且要有一个完成绑定工作的函数。
具体实现时,调用某个外部函数要先跳转到 PLT,再跳转到 GOT 得到外部函数地址。每个外部函数都在 PLT 表中有一个相应的项。比如:
第一条指令跳转 bar@GOT,此时 bar@GOT 中保存的是上面代码中的第二条指令“push n”的地址,所以又跳转回来。两条 push 指令分别将符号在重定位表中的下标和模块 ID 入栈,然后调用动态链接器的 _dl_runtime_resolve 函数来完成符号查找和地址重定位,最后将 bar 函数的真正地址填入 bar@GOT。当再次调用 bar@plt 时,第一条 jmp 指令就可以经由 bar@GOT 直接跳转到 bar 函数,而无需再做重定位了。
在具体实现时,ELF 将保存外部函数地址的 GOT 剥离出来,放到 .got.plt 中。.got.plt 的前三项特殊:
第一项保存“.dynamic”的地址;
第二项保存本模块的 ID;
第三项保存 _dl_runtime_resolve 的地址
所以上面的 bar@plt 可以这样:
因为最后两条指令对于每个 plt 项都一样,为了避免代码重复,将这两条指令提出来,放到 PLT0。所以 bar@plt 实际上是这样:
学习资料: 《程序员的自我修养——链接、装载和库》
基本思想是当函数第一次被调用时才进行绑定,所谓绑定就是符号查找和地址重定位。对于一些错误处理函数或不常用的功能函数,可能就避免了“绑定浪费”。采用延迟绑定,能加快程序的启动速度,特别有利于一些大型程序。
当函数第一次被调用时,由动态链接器完成地址绑定工作。他必须知道地址绑定发生在哪个模块的哪个函数,并且要有一个完成绑定工作的函数。
具体实现时,调用某个外部函数要先跳转到 PLT,再跳转到 GOT 得到外部函数地址。每个外部函数都在 PLT 表中有一个相应的项。比如:
bar@plt: jmp *(bar@GOT) push n push moduleID jump _dl_runtime_resolve
第一条指令跳转 bar@GOT,此时 bar@GOT 中保存的是上面代码中的第二条指令“push n”的地址,所以又跳转回来。两条 push 指令分别将符号在重定位表中的下标和模块 ID 入栈,然后调用动态链接器的 _dl_runtime_resolve 函数来完成符号查找和地址重定位,最后将 bar 函数的真正地址填入 bar@GOT。当再次调用 bar@plt 时,第一条 jmp 指令就可以经由 bar@GOT 直接跳转到 bar 函数,而无需再做重定位了。
在具体实现时,ELF 将保存外部函数地址的 GOT 剥离出来,放到 .got.plt 中。.got.plt 的前三项特殊:
第一项保存“.dynamic”的地址;
第二项保存本模块的 ID;
第三项保存 _dl_runtime_resolve 的地址
所以上面的 bar@plt 可以这样:
bar@plt: jmp *(bar@GOT) push n push *(GOT + 4) jump *(GOT + 8)
因为最后两条指令对于每个 plt 项都一样,为了避免代码重复,将这两条指令提出来,放到 PLT0。所以 bar@plt 实际上是这样:
PLT0: push *(GOT + 4) jump *(GOT + 8) … bar@plt: jmp *(bar@GOT) push n jmp PLT0
学习资料: 《程序员的自我修养——链接、装载和库》
相关文章推荐
- 验证码
- Java内部类(二)局部内部类
- 系统调用 5--write
- 系统调用 6--lseek
- javax.servlet.jsp.PageContext cannot be resolved to a type
- 无监督学习和强化学习机器学习
- vb.net controls集合
- 系统调用 4--read
- android fragment的使用
- React Diff 算法
- spring4.0新特性综述
- POJ 1326 Mileage Bank(水~)
- 我看我自己系列1
- 系统调用3--close
- Scanner 调试时程序会结束,而运行时不会结束。
- raspberry 2b 启动信息
- 系统调用2 --creat
- 使用 HTML5 File API 实现client log
- http协议
- java.util.Queue用法