如何解析dyld导入的符号?

时间:2012-04-16 18:35:22

标签: linker objective-c-runtime mach-o dyld otool

我正在尝试实现dyld所做的一些部分,而且我有点陷入残余蹦床。

考虑以下ARM指令:

BL  0x2fec

它以链接(子过程调用)分支到0x2fec。我知道这个事实,__TEXT段中有一个__symbolstub1从0x2fd8开始,所以它跳转到__symbolstub1内的20个字节。

现在,有一个符号

(undefined) external _objc_autoreleasePoolPush (from libobjc)

我通过LC_SYMTAB加载命令解决了这个问题。没有提供已知地址。我知道,事实上,0x2fec地址是_objc_autoreleasePoolPush的蹦床,但我不能通过任何方式证明它。

我已经检查了LC_DYLD_INFO_ONLY命令,我在那里找到了一个轻微的提示,在我发现的lazy_bind符号中:

{:offset=>20, :segment=>2, :library=>6, :flags=>[], :name=>"_objc_autoreleasePoolPush"}

其中名称和偏移量与我的确切匹配,而库#6是“/usr/lib/libobjc.A.dylib”,这也是完美的。现在问题是段#2是__TEXT,但是__TEXT从0x1000开始,而__symbolstub1在那里是0x2fd8。所以我错过了一些参考文章。

关于如何将0x2fec虚拟地址映射到_objc_autoreleasePoolPush的任何想法?

1 个答案:

答案 0 :(得分:1)

嘿,再挖一点,我就在LC_DYSYMTAB的间接符号中找到了它。

现在答案很长。

  1. 查找给定地址的部分;
  2. 该部分应为 type S_NON_LAZY_SYMBOL_POINTERS,S_LAZY_SYMBOL_POINTERS,S_LAZY_DYLIB_SYMBOL_POINTERS,S_THREAD_LOCAL_VARIABLE_POINTERS或S_SYMBOL_STUBS;
  3. 如果节类型为S_SYMBOL_STUBS,则字节大小存储在 reserved2 中,否则视为等于4;
  4. 间接符号表的偏移量存储在 reserved1 ;
  5. 间接符号表的索引计算为

    index = sect.reserved1 +(vmaddr - sect.addr)/ bytesize;

  6. 符号表中的符号位于符号[indirect_symbols [index]]。