如何将Xcode 4.2的iOS反汇编从Thumb模式切换到ARM模式?

4
我的iOS应用程序使用Apple LLVM 3.0编译器以Thumb模式构建。对于armv7,我非常确定实际上是Thumb-2。
我正在用ARM汇编代码重新实现我最耗时的两个函数。这些函数的调用方是Thumb,因此我在函数序言中使用Thumb到ARM互操作指令切换到ARM,以便可以访问ARM更丰富的指令集和更多的寄存器。在函数退出时,我使用ARM到Thumb的互操作返回到ARM模式。
GDB的反汇编对于Thumb代码是正确的,但是当我处于ARM模式时,它会将ARM指令解析为一对完全无意义的Thumb指令。有没有办法告诉GDB切换到ARM反汇编,然后返回到Thumb代码时使用Thumb反汇编器?
Google没有帮助。显然还有其他的GDB分支可以做到这一点,但是我还没有找到在GDB中执行此操作的方法。
LLDB显然支持ARM调试,但是在Xcode 4.2中尚不能在iOS设备上运行。当我选择LLDB调试器并在我的代码中设置断点时,我的应用程序在达到断点之前就挂起了。
我很久没有做过任何类型的汇编语言了,所以我正在通过在C和ARM汇编中实现具有不同参数和返回不同类型结果的函数来学习ARM调用约定。lower_case函数是C,CamelCase函数是汇编。我从main()非常第一件事就调用了abiTest,并使用assert()确保它返回YES。
BOOL abiTest( void )
{
    void_no_args();
    VoidNoArgs();

    if ( 42 != int_no_args() )
        return NO;

    if ( 42 != IntNoArgs() )
        return NO;

    return YES;
}

这里是IntNoArgs的源代码。.thumb_func是链接器的指令。我的研究表明,即使在混合两种类型的代码时,如果一个人同时使用ARM函数,也需要它。

.globl _IntNoArgs
.align 1
.code 16
.thumb_func _IntNoArgs

_IntNoArgs:
    @ int IntNoArgs( void );
    .loc 1 __LINE__ 0

    adr r0, Larm1     @ Larm1 is a PC-relative address.  r0's low bit will be cleared
    bx r0                   @ Switch to ARM mode then branch to Larm1.  That's the next instruction

    .align 2
    .code 32
Larm1:
    stmfd sp!, { r7, lr }

    mov r0, #42

    ldmfd sp!, { r7, lr }
    bx lr

以下是 GDB 如何反汇编 _IntNoArgs。前两行是正确的,其余完全错误。

0x000172c8  <+0000>  add    r0, pc, #0  (adr r0, 0x172cc <VoidNoArgs+4>)
0x000172ca  <+0002>  bx r0
0x000172cc  <+0004>  lsls   r0, r0
0x000172ce  <+0006>  stmdb  sp!, {r1, r3, r5}
0x000172d2  <+0010>  b.n    0x17a16
0x000172d4  <+0012>  lsls   r0, r0
0x000172d6  <+0014>  ldmia.w    sp!, {r1, r2, r3, r4, r8, r9, r10, r11, r12, sp, lr, pc}

因为ldmia.w指令从堆栈中取出一个新值并将其放入程序计数器中,从而返回子例程,所以反汇编在此处停止。使用"si"单步执行该指令后,反汇编面板显示如下:

0x000172d8  <+0016>  vrhadd.u16 d14, d14, d31

si指令始终做正确的事情,无论我们处于Thumb模式还是ARM模式,它只会推进一条指令。因此,GDB必须知道当前的指令集架构,只是反汇编程序没有获取到这些信息。在ARM寄存器中有一个位指示当前模式。一些GDB分支可以使用该位的值确定要反汇编的ISA,但Xcode 4.2的GDB显然不支持此功能。 Xcode的GDB具有“set arm disassembler”命令及其相应的“show arm disassembler”,看起来似乎有所帮助,但实际并非如此。这项功能显然是为支持iOS设备未使用的其他类型的ARM变体而设计的。在其他GDB分支中,“set fallback-mode”可以设置为arm、thumb或auto,但在Xcodes中不能,同样的情况也适用于“set disassembler-flavor”。我真正想要的是一款机器调试器,它像Classic Mac OS上的MacsBug一样工作。虽然GDB通常能够进行汇编程序调试,但对于这个目的来说,它完全不太好用。这并不是任何人的过错,因为它是为源代码调试而设计的。一个好的汇编程序调试器从底层就是这样设计的。

为什么这个问题从http://programmers.stackexchange.com/迁移到了这里?我不是在抱怨,但对我来说,程序员的讨论版更适合这个问题。 - Mike Crawford
听起来像是调试器中的一个错误,你应该在http://bugreport.apple.com上向苹果报告它。 - user23743
Graham,好主意,有点。我刚试图提交Bug#10420051,但失败了。不幸的是,我的表单提交失败了。虽然Radar给了我一个bug号码,但据我所知,该bug实际上并没有被输入。建议我向devbugs@apple.com报告Radar问题,我已经这样做了。我会等待看看是否会得到任何回应,以及给Apple的系统管理员修复任何错误的机会,然后重新提交该bug。 - Mike Crawford
1个回答

0
ABI函数调用指南指出,在iOS中,ARM和Thumb模式之间的切换只能在函数边界处进行。确保您的函数仅为ARM或Thumb模式,并且调试器将正常工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接