2

我正在尝试实现 dyld 所做的某些部分,但我有点卡在 stub trampolines 上。

考虑以下 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 的任何想法?

4

1 回答 1

1

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

现在长答案。

  1. 查找给定地址的部分;
  2. 该部分的类型应为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. 间接符号表的索引计算为

    索引 = sect.reserved1 + (vmaddr - sect.addr) / 字节大小;

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

于 2012-04-16T19:16:10.197 回答