GDB пропускает заполнение при загрузке ELF в цель - PullRequest
0 голосов
/ 20 мая 2018

У меня есть плата STM32F4 Discovery, сервер отладки OpenOCD и armv7m-unknown-eabi-gdb, и я хочу, чтобы на моей плате был запущенный ELF с "голым железом", который я построил.Я запускаю gdb, даю ему команды target remote :3333, load, monitor reset halt, а затем пытаюсь пройтись по коду, но ничего не получается.После некоторого расследования я обнаружил, что код был загружен по неправильному адресу.

readelf -S дает:

[ 1] vectors           PROGBITS        00000000 000114 000040 00   A  0   0  1
[ 2] .interp           PROGBITS        00000040 000154 000011 00   A  0   0  1
[ 3] .dynsym           DYNSYM          00000054 000168 000030 10   A  4   3  4
[ 4] .dynstr           STRTAB          00000084 000198 000001 00   A  0   0  1
[ 5] .hash             HASH            00000088 00019c 000018 04   A  3   0  4
[ 6] .text             PROGBITS        000000a0 0001b4 000134 00 WAX  0   0  4

И вы можете видеть, что компоновщик поставил два 3-байтовых дополнения: первый между .interp и .dynsym и второй между .dynstr и .hash разделами.

Но когда gdb загружает изображение на плату, он, кажется, игнорирует эти пробелы и помещает разделы сразу последругой (неважно адреса 0x2xxxxxxx, ЦП настроен для сопоставления их с областью 0x0xxxxxxx):

(gdb) load
Loading section vectors, size 0x40 lma 0x20000000
Loading section .interp, size 0x11 lma 0x20000040
Loading section .dynsym, size 0x30 lma 0x20000051
Loading section .dynstr, size 0x1 lma 0x20000081
Loading section .hash, size 0x18 lma 0x20000082
Loading section .text, size 0x134 lma 0x2000009a

В результате код находит себя за 6 байтов до того, как адрес GDB ожидает его нахождения, и, следовательно, всеинформация отладки применяется к памяти неправильно.Я буквально получаю сумасшедшие результаты, потому что следующая инструкция, которую я собираюсь выполнить (это та, на которую указывает GDB), на самом деле это какая-то другая (точнее, текущая инструкция + 3 полуслова).

* 1015Итак, что может быть не так?Я неправильно использую GDB?Или это ELF был построен неправильно?Может быть, виновен OpenOCD?Или что-то еще?

Редактировать

Похоже, GDB выполняет свою работу в соответствии с тем, что написано в ELF.LMA-адреса секций .dynsym и .hash действительно не выровнены.

objdump -h дает:

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 vectors       00000040  00000000  20000000  00000114  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .interp       00000011  00000040  20000040  00000154  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .dynsym       00000030  00000054  20000051  00000168  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .dynstr       00000001  00000084  20000081  00000198  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .hash         00000018  00000088  20000082  0000019c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .text         00000134  000000a0  2000009a  000001b4  2**2
                  CONTENTS, ALLOC, LOAD, CODE

Также оказывается, что .interp, .dynsym, .dynstr и.секции хеша были сгенерированы компоновщиком, потому что GCC дал ему флаг -pic.Я не упомянул эти разделы в своем скрипте компоновщика.Поэтому мне нужно понять, почему я выровнял адреса VMA, а не адреса LMA.

...