Mach-O符号懒加载

iOS 的非懒加载符号会在dyld加载时就绑定真实的值。而懒加载符号不会。只在第一次调用它是才会绑定真实的地址。

通过一个例子 根据 Mach-O文件去了解。
lazy symbol pre .png

第一次调用这个printf函数


lazy symbol 1.jpeg

会找到在Section64(Text,__stub)上的地址。找到对应的符号,printf。


lazy symbol 2 stubs.jpeg

然后通过 si 命令继续执行。看到跳转到 0x10003eb2的地址,就是 上述 stub中的偏移地址加上基地址。然后跳转到0x100003efa的地址。根据stub 从 la_symbol_ptr 中找到对应的指针。


lazy symbol 3 printf.jpeg

lazy symbol 4 la_symbol_ptr.jpeg

带上偏移地址,跳转到 stub_helper 的头部


lazy symbol 4 stub jump .png

进入执行,会跳转到 0x3eb8 。在 Section64(Text, __stub_helper) 对应的方法执行。
lazy_symbol 5 stub_helper run.png

然后继续执行,会跳转到 libdyld.dylib`dyld_stub_binder: 的方法。去进行方法绑定


lazy symbol 6 dyld stub binder.png

在dyld_stub_binder 中会找到并跳转执行 libsystem_c.dylib`printf


lazy symbol 7 jupq printf .png

当第二次执行 printf 方法时。就会直接找到 printf的地址


lazy symbol 8. printf .png
总结

第一次调用

  1. 通过 __stubs 找到 __la_symbol_prt 中的指针
  2. 带上偏移地址执行 _stub_helper 头部
  3. 调用 dyld_stub_binder 然后再调用 _dyld_fast_stub_entry 执行绑定。(通过 debug -> debug workflow -> allways show disassemblys 断点查看)
  4. 从lazy Bindding info 定位真实符号模块并写会 _la_symbol_ptr

第二次调用

  1. 直接根据 _la_symbol_ptr 已绑定的符号跳转

你可能感兴趣的:(Mach-O符号懒加载)