快上网专注成都网站设计 成都网站制作 成都网站建设
成都网站建设公司服务热线:028-86922220

网站建设知识

十年网站开发经验 + 多家企业客户 + 靠谱的建站团队

量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决

Mach-O的动态链接(LazyBind机制)-创新互联

原文出自【听云技术博客】:http://blog.tingyun.com/web/article/detail/1347

在丰满等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供成都网站建设、成都做网站 网站设计制作按需定制开发,公司网站建设,企业网站建设,成都品牌网站建设,全网整合营销推广,外贸营销网站建设,丰满网站建设费用合理。

动态链接

要解决空间浪费和更新困难这两个问题最简单的方法就是把程序的模块相互分割开来,形成独立的文件,而不再将它们静态的链接在一起。简单地讲,就是不对那些组成程序的目标文件进行链接,等到程序要运行时才进行链接。也就是说,把链接过程推迟到了运行时再进行,这就是 _动态链接(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 文件的分析与代码的调试简单的分析一下。

 源代码如下:

Mach-O 的动态链接(Lazy Bind 机制)

分别在两个printf函数处下 断点。

第一个调用printf函数

Mach-O 的动态链接(Lazy Bind 机制)

在0x100000f52 \<+34\>行处通过callq 0x100000f76 来调用printf。

执行callq指令 之后代码跳转到这里:

Mach-O 的动态链接(Lazy Bind 机制)

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

Mach-O 的动态链接(Lazy Bind 机制)

通过lldb 的命令 查看 0x100001010处的地址 获取了同样的值。

通过—stub—helper进行lazybind

在Mach-O 中每一个Symbol Stub 可能有以下两种行为其中之一:跳转到函数的指令,执行函数体,通过动态动态库链接器查找函数的Symbol,然后执行函数体

查看 —stubs的Section 数据,发现只有一个函数就是 printf

Mach-O 的动态链接(Lazy Bind 机制)

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

Mach-O 的动态链接(Lazy Bind 机制)

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

Mach-O 的动态链接(Lazy Bind 机制)

第二次调用printf 函数

Mach-O 的动态链接(Lazy Bind 机制)

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

Mach-O 的动态链接(Lazy Bind 机制)

再一次查看 0x100001010 处内存值。已经很第一次不同了,也就是说, —Data, —la-symbol-ptr 中指向printf地址的值已经发生了变化,指向了 printf的指令。

这就证明了,延迟绑定只会在第一次调用的时候发生。整个流程与 linux中的PLT 和GOT 在实现逻辑上基本相同,只是实现代码不同而已。

参考《Mac OS X  and iOS Internals》、《链接,装载与库》

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


名称栏目:Mach-O的动态链接(LazyBind机制)-创新互联
网页地址:http://6mz.cn/article/jdhso.html

其他资讯