ARM: генерация стека вызовов без указателя кадра

Я пытаюсь создать стек вызовов на процессоре Cortex-M3 (архитектура ARMv7-M), а не на ОС (голое железо). Однако для этого ABI нет регистра указателя кадра. Поэтому я изо всех сил пытаюсь сгенерировать стек вызовов, когда у меня нет указателя кадра.

Независимо от использования -mapcs-frame, -fno-omit-frame-pointer а также -O0 параметры с GCC, указатель кадра не сохраняется. Мне интересно, есть ли другой ABI, который я могу заставить GCC использовать, чтобы у меня был указатель кадра / кадр стека? Если нет, есть ли другой надежный метод генерации стека вызовов?

Заранее спасибо.

1 ответ

Кстати, в связи с приведенным выше комментарием стандарт вызова ARM такой же, как и у Thumb, см. ( Стандарт вызова ARPCS) Наборы команд отличаются, НО набор регистров ЦП не является.

Я бы предпочел задавать вопросы в комментариях, но пока мне не хватает очков. С этим в мыслях....

У вас есть бинарный файл, успешно собранный и исполняемый, но вы пытаетесь сбросить какую-то трассировку вызовов? Моя путаница заключается в выражении "регистр указателя без фрейма" - r13 - указатель фрейма стека. Я думаю, что вы имеете в виду сохранение указателя кадра, хотя.

Это было какое-то время, но я думаю, что это те варианты, которые я использовал

arm-none-eabi-gcc - -nostdlib -ggdb -mthumb -mcpu=cortex-m3 -mtpcs-frame -mtpcs-leaf-frame myfile.c

Это было на gcc-arm-none, загруженном с linaro. GDB смог сделать обратный след с этими опциями на Atmel SAM3X. Thumb ABI был таким же, как ARM EABI, или, по крайней мере, кажется, что смотрит на ассемблер через objdump -D.

Указатель предыдущего кадра сохраняется в r7, когда указывается (или подразумевается) -fno-omit-frame-pointer

void test2(int i) {}
void main() { test(0); 

Скомпилировано с -fomit-frame-pointer

00008000 <test2>:
    8000:   b082        sub   sp, #8
    8002:   9001        str   r0, [sp, #4]
    8004:   b002        add   sp, #8
    8006:   4770        bx lr

00008008 <main>:
    8008:   b508        push  {r3, lr}
    800a:   f04f 0000   mov.w r0, #0
    800e:   f7ff fff7   bl 8000 <test2>
    8012:   bd08        pop   {r3, pc}

Скомпилировано с -fno-omit-frame-pointer

00008000 <test2>:
    8000:   b480        push  {r7}
    8002:   b083        sub   sp, #12
    8004:   af00        add   r7, sp, #0
    8006:   6078        str   r0, [r7, #4]
    8008:   f107 070c   add.w r7, r7, #12
    800c:   46bd        mov   sp, r7
    800e:   bc80        pop   {r7}
    8010:   4770        bx lr
    8012:   bf00        nop

00008014 <main>:
    8014:   b580        push  {r7, lr}
    8016:   af00        add   r7, sp, #0
    8018:   f04f 0000   mov.w r0, #0
    801c:   f7ff fff0   bl 8000 <test2>
    8020:   bd80        pop   {r7, pc}
    8022:   bf00        nop

Поэтому используйте r7 для перехода к предыдущему кадру стека, затем получите следующий r7 из этого места и так далее.

Другие вопросы по тегам