Mach-O 的动态链接(Lazy Bind 机制)
动态链接
要解决空间浪费和更新困难这两个问题最简单的方法就是把程序的模块相互分割开来,形成独立的文件,而不再将它们静态的链接在一起。简单地讲,就是不对那些组成程序的目标文件进行链接,等到程序要运行时才进行链接。也就是说,把链接过程推迟到了运行时再进行,这就是 _动态链接(Dynamic Linking)_的思想。
延迟绑定(PLT)
动态链接比静态链接性能低,主要原因是动态链接下对于全局和静态的数据访问都要进行复杂的GOT定位,间接寻址;对于模块间的调用也要先定位GOT,间接跳转, 程序的运行速度一定会减慢。 另外因为动态链接是在运行时完成链接的工作:在程序开始执行时,动态链接器都要进行一次链接工作,动态链接器会 search 并 load 所需要的 共享对象,然后进行符号查询 地址重定位,这一系列动作会减慢程序的启动速度。
PLT 就是为了优化动态链接性能而存在,基本思想就是 当函数第一次被调用到时才进行绑定(符号查找,重定位),如果没有用到则不进行 bind。 这样在程序执行时,模块间的函数调用都没有进行 bind , 而是需要调用时才由 动态链接器来负责 bind 。这样可以加速程序的启动速度。
Mach-O Lazy Bind
Mach-O 文件通过dyld 加载的时候并没有确定每一个函数的具体地址在哪里,而是在真正调用该函数的时候通过 过程链接表(procedure linkage table),简称 PLT,来进行一次lazybind。
结合Mach-O 文件的分析与代码的调试简单的分析一下。
源代码如下:

分别在两个printf函数处下 断点。
第一个调用printf函数

在0x100000f52 \<+34\>行处通过callq 0x100000f76 来调用printf。
执行callq指令 之后代码跳转到这里:

这里的jmpq 要跳转到 0x0000000100000F8C ,这个地址是从 —Data , —la-symbol-ptr 中的Lazy Symbol Pointers 中获取到的。

通过lldb 的命令 查看 0x100001010处的地址 获取了同样的值。
通过—stub—helper进行lazybind
在Mach-O 中每一个Symbol Stub 可能有以下两种行为其中之一:跳转到函数的指令,执行函数体,通过动态动态库链接器查找函数的Symbol,然后执行函数体
查看 —stubs的Section 数据,发现只有一个函数就是 printf

这里的Data 其实就是上面看到的 jmpq 的代码。执行之后代码跳转到了这样的代码片段。

这里就是通过 —stub-helper来调用 dyld-stubbinder函数来计算printf 函数的真是地址。 通过下面的 信息可以看出来,jmpq 0x100000f7c ,就是在压如入参数0x0 (函数的link 的时候给的编号) 之后跳转到Section的起始处,调用 binder(一段汇编代码, 作用就是计算具体的函数地址,并调用printf 函数)

第二次调用printf 函数

执行指令之后发现和第一次调用printf 已经不一样了。

再一次查看 0x100001010 处内存值。已经很第一次不同了,也就是说, —Data, —la-symbol-ptr 中指向printf地址的值已经发生了变化,指向了 printf的指令。
这就证明了,延迟绑定只会在第一次调用的时候发生。整个流程与 linux中的PLT 和GOT 在实现逻辑上基本相同,只是实现代码不同而已。
参考《Mac OS X and iOS Internals》、《链接,装载与库》
原文链接:http://blog.tingyun.com/web/article/detail/1347
Mach-O 的动态链接(Lazy Bind 机制)的更多相关文章
- [CSAPP-II] 链接[符号解析和重定位] 静态链接 动态链接 动态链接接口
1 平台 转http://blog.csdn.net/misskissc/article/details/43063419 1.1 硬件 Table 1. 硬件(lscpu) Architecture ...
- 程序员的自我修养九Windows下的动态链接
9.1 DLL简介 DLL即动态链接库的缩写,它相对于Linux下的共享对象. Windows下的DLL文件和EXE文件实际上是一个概念,它们都是有PE格式的二进制文件. 微软希望通过DLL机制加强软 ...
- Android so 文件进阶<二> 从dlsym()源码看android 动态链接过程
0x00 前言 这篇文章其实是我之前学习elf文件关于符号表的学习笔记,网上也有很多关于符号表的文章,怎么说呢,感觉像是在翻译elf文件格式的文档一样,千篇一律,因此把自己的学习笔记分享出来.dls ...
- 聊聊动态链接和dl_runtime_resolve
写在前面 linux下的动态链接相关结构,重新回顾_dl_runtime_resolve的流程以及利用方法 动态链接相关结构 为了高效率的利用内存,多个进程可以共享代码段.程序模块化方便更新维护等,动 ...
- 实例分析ELF文件动态链接
参考文献: <ELF V1.2> <程序员的自我修养---链接.装载与库>第6章 可执行文件的装载与进程 第7章 动态链接 <Linux GOT与PLT> 开发平台 ...
- Linux下实现C++类的动态链接
1. 背景 在java中,jvm支持类的动态链接(Class.forName(String className)),用起来也很方便.动态链接是实现IOC(Inversion of Control,控制 ...
- 再探Linux动态链接 -- 关于动态库的基础知识
在近一段时间里,由于多次参与相关专业软件Linux运行环境建设,深感有必要将这些知识理一理,供往后参考. 编译时和运行时 纵观程序编译整个过程,细分可分为编译(Compiling,指的是语言到平台 ...
- linux 下动态链接实现原理
符号重定位 讲动态链接之前,得先说说符号重定位. c/c++ 程序的编译是以文件为单位进行的,因此每个 c/cpp 文件也叫作一个编译单元(translation unit), 源文件先是被编译成一个 ...
- Python 调度算法 死锁 静动态链接 分页分段
1 select poll epoll的区别基本上select有3个缺点: 连接数受限查找配对速度慢数据由内核拷贝到用户态poll改善了第一个缺点 epoll改了三个缺点. (1)select,pol ...
随机推荐
- 你必须知道的EF知识和经验
注意:以下内容如果没有特别申明,默认使用的EF6.0版本,code first模式. 推荐MiniProfiler插件 工欲善其事,必先利其器. 我们使用EF和在很大程度提高了开发速度,不过随之带来的 ...
- 如何一步一步用DDD设计一个电商网站(十)—— 一个完整的购物车
阅读目录 前言 回顾 梳理 实现 结语 一.前言 之前的文章中已经涉及到了购买商品加入购物车,购物车内购物项的金额计算等功能.本篇准备把剩下的购物车的基本概念一次处理完. 二.回顾 在动手之前我对之 ...
- Kali对wifi的破解记录
好记性不如烂笔头,记录一下. 我是在淘宝买的拓实N87,Kali可以识别,还行. 操作系统:Kali 开始吧. 查看一下网卡的接口.命令如下 airmon-ng 可以看出接口名称是wlan0mon. ...
- 通俗易懂的来讲讲DOM
DOM是所有前端开发每天打交道的东西,但是随着jQuery等库的出现,大大简化了DOM操作,导致大家慢慢的“遗忘”了它的本来面貌.不过,要想深入学习前端知识,对DOM的了解是不可或缺的,所以本文力图系 ...
- 菜鸟学Struts2——零配置(Convention )
又是周末,继续Struts2的学习,之前学习了,Struts的原理,Actions以及Results,今天对对Struts的Convention Plugin进行学习,如下图: Struts Conv ...
- 第一个shell脚本
打开文本编辑器,新建一个文件,扩展名为sh(sh代表shell),扩展名并不影响脚本执行,见名知意就好. #!/bin/bash echo "Hello World !" &quo ...
- 协议森林16 小美的桌号(DHCP协议)
作者:Vamei 出处:http://www.cnblogs.com/vamei 转载请先与我联系. DHCP协议用于动态的配置电脑的网络相关参数,如主机的IP地址,路由器出口地址.DNS域名服务器地 ...
- 解读发布:.NET Core RC2 and .NET Core SDK Preview 1
先看一下 .NET Core(包含 ASP.NET Core)的路线图: Beta6: 2015年7月27日 Beta7: 2015年9月2日 Beta8: 2015年10月15日 RC1: 2015 ...
- .NET中AOP方便之神SheepAspect
SheepAspect 简介以及代码示列: SheepAspect是一个AOP框架为.NET平台,深受AspectJ.它静织目标组件作为一个编译后的任务(编译时把AOP代码植入). 多有特性时,可根据 ...
- JavaScript事件代理和委托(Delegation)
JavaScript事件代理 首先介绍一下JavaScript的事件代理.事件代理在JS世界中一个非常有用也很有趣的功能.当我们需要对很多元素添加事件的时候,可以通过将事件添加到它们的父节点而将事件委 ...