Попытка загрузить независимый от позиции код на cortex-m3 - PullRequest
9 голосов
/ 17 февраля 2011

У меня есть встроенное приложение, которое будет иметь загрузчик, который решит запустить 1 из двух приложений непосредственно из внутренней флэш-памяти. Я пытаюсь сделать эти приложения независимыми, чтобы они могли быть скомпилированы для одного базового адреса. Операционная система отсутствует, поэтому динамический компоновщик недоступен. До сих пор я пытался собрать с опцией -fpie (используя gcc) с не слишком большим успехом. Вызовы функций кажутся правильными, но глобальные данные не имеют правильного адреса. Кажется, что локально определенные глобальные данные имеют смещение адреса на величину, на которую приложение смещено от своего исходного базового адреса. Глобальные данные, которые объявлены в других файлах, имеют совершенно неправильный адрес (и если я собираю с помощью -fpic, то и локально объявленные глобальные данные, и глобальные данные в других файлах совершенно неверны). Я подозреваю, что мне нужно сделать некоторые манипуляции с разделом GOT при запуске моего приложения, но я не уверен.

Ответы [ 2 ]

8 голосов
/ 22 февраля 2011

Я наконец-то заработал. Похоже, мне нужно сделать следующее: Весь код должен соответствовать -fpic (ранее я пытался -fpie)

Также у меня был скрипт для моего компоновщика, нуждающийся в модификации. Я заставлял GOT войти в раздел sram, и он был расположен после динамического раздела, который был во вспышке. Похоже, что все работает правильно, если раздел GOT расположен до динамического раздела во флэш-памяти. Не уверен, почему это важно, но казалось, что все исправлено - до этого все выглядело так, как будто код неправильно определил местонахождение GOT, так как в GOT хранятся правильные значения, но адрес всех моих переменных был неправильным.

5 голосов
/ 17 февраля 2011
Для кода

PIE (и PIC) требуется процесс перемещения после загрузки по какому-либо адресу (отличному от значения по умолчанию) и до его запуска. Предлагаю вам ознакомиться с кодом ld.so. Кроме того, вы должны проверить таблицу перемещений в вашем двоичном файле (например, используя readelf -r).

Вот хорошая презентация о PIE (речь идет об OpenBSD, но процесс такой же). http://www.openbsd.org/papers/nycbsdcon08-pie/ или http://www.dcbsdcon.org/speakers/slides/miller_dcbsdcon2009.pdf

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

По сути, обработка двоичного файла PIE с помощью ld.so почти такая же, как обработка динамической библиотеки с помощью PIC с перемещением не библиотеки, а самого исполняемого образа.

«Неправильные адреса», которые вы видите, - это место, где фактическое значение будет записано путем решения о перемещении. Что касается i386 http://books.google.com/books?id=Id9cYsIdjIwC&pg=PA174, то есть перемещения:

  • R_386_GOTPC
  • R_386_GOT32
  • R_386_GOTOFF
  • R_386_RELATIVE

Линкер должен разрешить все из них, прежде чем код сможет получить доступ к глобальным данным.

Readelf -r образец:

Динамически связанный

$ readelf -r fdyn

Relocation section '.rel.dyn' at offset 0x27c contains 1 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
08049ff0  00000106 R_386_GLOB_DAT    00000000   __gmon_start__

Relocation section '.rel.plt' at offset 0x284 contains 2 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
0804a000  00000107 R_386_JUMP_SLOT   00000000   __gmon_start__
0804a004  00000207 R_386_JUMP_SLOT   00000000   __libc_start_main

PIE:

$ readelf -r fPIE

Relocation section '.rel.dyn' at offset 0x388 contains 6 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
00001fe8  00000008 R_386_RELATIVE
00001ff0  00000008 R_386_RELATIVE
00002010  00000008 R_386_RELATIVE
00001fe0  00000106 R_386_GLOB_DAT    00000000   __gmon_start__
00001fe4  00000206 R_386_GLOB_DAT    00000000   _Jv_RegisterClasses
00001fec  00000406 R_386_GLOB_DAT    00000000   __cxa_finalize

Relocation section '.rel.plt' at offset 0x3b8 contains 3 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
00002000  00000107 R_386_JUMP_SLOT   00000000   __gmon_start__
00002004  00000307 R_386_JUMP_SLOT   00000000   __libc_start_main
00002008  00000407 R_386_JUMP_SLOT   00000000   __cxa_finalize
...