Как переключить разборку iOS Xcode 4.2 с большого пальца на ARM? - PullRequest
3 голосов
/ 09 ноября 2011

Мое приложение для iOS создается с помощью компилятора Apple LLVM 3.0 в режиме большого пальца. Для armv7 я почти уверен, что это на самом деле Thumb-2.

Я переопределяю свои две самые трудоемкие функции в коде сборки ARM. Вызывающими этими функциями являются Thumb, поэтому я использую инструкции взаимодействия между Thumb и ARM, чтобы переключиться на ARM в прологе своих функций, чтобы получить доступ к более богатому набору инструкций ARM и большему количеству регистров. При выходе из функции я использую ARM to Thumb, чтобы вернуться в режим ARM.

Разборка GDB верна для кода Thumb, но когда я нахожусь в режиме ARM, он разбирает инструкции ARM, как если бы каждая из них была парой совершенно бессмысленных команд Thumb. Есть ли какой-нибудь способ, которым я могу сказать GDB перейти на разборку ARM, а затем, вернувшись к коду Thumb, использовать дизассемблер Thumb?

Google не помогает. Очевидно, есть другие вилки GDB, которые могут это делать, но я не нашел способа сделать это с GDB.

LLDB, очевидно, поддерживает отладку ARM, но она еще не работает на устройствах iOS в Xcode 4.2. Когда я выбираю отладчик LLDB в Product -> Edit Scheme, а затем устанавливаю точку останова в моем коде, мое приложение зависает, прежде чем достичь точки останова.

Прошло много времени с тех пор, как я делал какие-либо ассемблеры любого рода, поэтому я разбираюсь с соглашениями о вызовах ARM, реализуя функции, которые принимают различные параметры и возвращают различные типы результатов как в ассемблере C, так и в ARM. Функции в нижнем регистре - это C, а функции CamelCase - это сборка. Я вызываю abiTest первым делом из main () и использую 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 разбирать как, но это, очевидно, не тот случай с GDB Xcode 4.2.

В Gcode XCode есть команда «дизассемблер set arm» и соответствующий ему «дизассемблер show arm», который выглядит так, как будто это поможет, но это не так. Это, очевидно, предназначено для поддержки других видов вариантов ARM, чем те, которые используют устройства iOS.

"set fallback-mode" может быть установлен на arm, thumb или auto в других форках GDB, но не в Xcodes. То же самое для "установить дизассемблер-ароматизатор".

То, что я ДЕЙСТВИТЕЛЬНО ДЕЙСТВИТЕЛЬНО ДЕЙСТВИТЕЛЬНО ДЕЙСТВИТЕЛЬНО бы хотел, - это отладчик машины, который работал так же, как MacsBug в Classic Mac OS. Хотя GDB обычно способен выполнять отладку на ассемблере, для этой цели он полностью отстой. Это не чья-то вина, на самом деле, потому что он предназначен для отладки исходного кода. Хороший сборочный отладчик предназначен для этого с нуля.

1 Ответ

0 голосов
/ 14 июня 2012

Руководство по вызову функции ABI утверждает, что переключение между режимами ARM и Thumb может быть выполнено только на границах функций в iOS. Убедитесь, что вы используете только функции ARM или Thumb, и отладчик будет работать нормально.

...