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 из этого места и так далее.