如何切换Xcode 4.2';从拇指到手臂的iOS拆卸?

如何切换Xcode 4.2';从拇指到手臂的iOS拆卸?,ios,xcode,debugging,gdb,assembly,Ios,Xcode,Debugging,Gdb,Assembly,我的iOS应用程序是在Thumb模式下使用Apple LLVM 3.0编译器构建的。对于armv7,我很确定这实际上是Thumb-2 我正在重新实现ARM汇编代码中最耗时的两个函数。这些函数的调用者是Thumb,因此我在函数的序言中使用Thumb-to-ARM交互指令切换到ARM,这样我就可以访问ARM更丰富的指令集和更多的寄存器。在功能退出时,我使用ARM-to-Thumb交互来返回ARM模式 GDB的反汇编对于Thumb代码是正确的,但是当我处于ARM模式时,它反汇编ARM指令,就好像每一条

我的iOS应用程序是在Thumb模式下使用Apple LLVM 3.0编译器构建的。对于armv7,我很确定这实际上是Thumb-2

我正在重新实现ARM汇编代码中最耗时的两个函数。这些函数的调用者是Thumb,因此我在函数的序言中使用Thumb-to-ARM交互指令切换到ARM,这样我就可以访问ARM更丰富的指令集和更多的寄存器。在功能退出时,我使用ARM-to-Thumb交互来返回ARM模式

GDB的反汇编对于Thumb代码是正确的,但是当我处于ARM模式时,它反汇编ARM指令,就好像每一条指令都是一对完全没有意义的Thumb指令一样。有没有什么方法可以让GDB切换到ARM反汇编,然后在返回到Thumb代码时,使用Thumb反汇编程序

谷歌帮不了什么忙。显然,GDB的其他分支也可以做到这一点,但我还没有找到一种使用GDB实现这一点的方法

LLDB显然支持ARM调试,但它还不能在Xcode 4.2的iOS设备上工作。当我在Product->Edit Scheme中选择LLDB调试器,然后在代码中设置断点时,我的应用程序在到达断点之前挂起

我已经有很长一段时间没有完成任何类型的汇编了,所以我正在通过实现在C和ARM汇编中获取各种参数并返回各种类型结果的函数来复习ARM调用约定。小写函数为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}
0x000172c8添加r0,pc,#0(adr r0,0x172c)
0x00017CA bx r0
0x00017CC lsls r0,r0
0x00017CE stmdb sp!,{r1,r3,r5}
0x00017D2 b.n 0x17a16
0x00017D4 lsls r0,r0
0x00017D6 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
0x000172d8 vrhadd.u16 d14、d14、d31
si指令总是做正确的事情,无论是在Thumb模式还是ARM模式下,它只推进一条指令。所以GDB必须知道当前的指令集架构,只是反汇编程序没有得到这些信息

ARM寄存器中有一位指示当前模式。GDB的一些分支在确定要反汇编为哪个ISA时能够使用该位的值,但Xcode 4.2的GDB显然不是这样

Xcode的GDB有一个命令“设置arm反汇编程序”和相应的“显示arm反汇编程序”,看起来会有所帮助,但实际上没有。这显然是为了支持iOS设备使用之外的其他ARM变体

“设置回退模式”可以在GDB的其他分支中设置为arm、thumb或auto,但不能设置为Xcode。“设置反汇编程序风格”同上


我真正想要的是一个机器调试器,它的工作原理和MacsBug在经典MacOS上的工作原理一样。虽然GDB通常能够进行汇编程序调试,但它在这方面却非常糟糕。这真的不是任何人的错,因为它是为源代码调试而设计的。一个好的汇编调试器就是这样设计的。

ABI函数调用指南指出,在ARM和Thumb模式之间的切换只能在iOS中的函数边界上完成。确保您的函数是ARM或Thumb,调试器将正常工作。

为什么从迁移到这里?我不是在抱怨,但在我看来,程序员委员会更适合这个问题。这听起来像是调试器中的一个bug,你应该向苹果报告。格雷厄姆,好主意,有点。我刚刚尝试过,但未能提交Bug#10420051。不幸的是,我的表格提交失败了。虽然雷达给了我一个虫子编号,但据我所知,虫子实际上并没有进入。有人建议我把雷达问题报告给他devbugs@apple.com,我就是这么做的。我将等待,看看是否有任何回应,以及给苹果的系统管理员一个机会来修复任何错误,然后重新提交错误。