GDB неправильно разбирает программу, работающую в оперативной памяти
У меня есть приложение, скомпилированное с использованием GCC для процессора ARM STM32F407. Компоновщик хранит его во Flash, но выполняется в RAM. Небольшая программа начальной загрузки копирует приложение из Flash в оперативную память и затем переходит в ResetHandler приложения.
memcpy(appRamStart, appFlashStart, appRamSize);
// run the application
__asm volatile (
"ldr r1, =_app_ram_start\n\t" // load a pointer to the application's vectors
"add r1, #4\n\t" // increment vector pointer to the second entry (ResetHandler pointer)
"ldr r2, [r1, #0x0]\n\t" // load the ResetHandler address via the vector pointer
// bit[0] must be 1 for THUMB instructions otherwise a bus error will occur.
"bx r2" // jump to the ResetHandler - does not return from here
);
Все это работает нормально, кроме случаев, когда я пытаюсь отладить приложение из ОЗУ (используя GDB из Eclipse), дизассемблирование некорректно. Любопытно, что отладчик получает правильный исходный код, а также принимает и останавливает установленные мной точки останова. Я могу один шаг строки исходного кода. Однако когда я выполняю пошаговые инструкции по сборке, они не имеют никакого смысла. Он также содержит множество неопределенных инструкций. Я предполагаю, что это какая-то проблема с выравниванием, но для меня все выглядит правильно. Какие-либо предложения?
1 ответ
Возможно, что GDB полагается на таблицу символов для проверки режима набора команд, который может быть Thumb(2)/ARM. Когда вы перемещаете код в ОЗУ, он, вероятно, не может найти эту информацию и переключается обратно в режим ARM.
Ты можешь использовать set arm force-mode thumb
в GDB, чтобы заставить инструкцию режима Thumb.
В качестве дополнительного примечания: если вы получаете недопустимую инструкцию при отладке двоичного файла ARM, это, как правило, является проблемой, если это не полная чепуха, как, например, попытка разборки частей данных.
Мне лично кажется странным, что инструменты не используют эвристический подход при разборке двоичных файлов ARM. В случае с авто не должно быть сложно попробовать оба режима и подсчитать количество ошибок, чтобы решить, какой режим использовать в качестве крайней меры.