GNU ld удаляет раздел

Я пишу сценарий начальной загрузки для основанного на ARM-Cortex M3 устройства. Если я компилирую ассемблерный сценарий начальной загрузки и код приложения C и затем комбинирую объектные файлы и передаю их моему устройству, все работает.

Однако, если я использую ar для создания архива (libboot.a) и объединения, которые архивируют с приложением C, существует проблема:

Я поместил загрузочный код в раздел:

    .section    .boot, "ax"
    .global     _start

_start:
    .word       0x10000800  /* Initial stack pointer (FIXME!) */
    .word       start
    .word       nmi_handler
    .word       hard_fault_handler
    ... etc ...

Я нашел это ld полосы это от заключительного двоичного файла (раздел "начальная загрузка" не доступен). Это довольно естественно, поскольку нет никакой зависимости от него этого ld знает о, но это заставляет устройство не загружаться правильно.

Таким образом, мой вопрос: что лучший способ состоит в том, чтобы вынудить этот код быть включенным?

7
задан Phonon 22 June 2011 в 20:07
поделиться

4 ответа

Попробуйте добавить что-нибудь вроде:

KEEP(*(.boot))

в сценарий компоновщика ld , чтобы он оставил секцию .boot .

Однако я не уверен, достаточно ли этого для того, чтобы ld извлекал любые объекты из архива, которые находятся в разделе .boot - это может не учитывать объект вообще, если какой-либо символ в этом объекте не вызывает его втягивание. Если это проблема, укажите _start в качестве точки входа (используя -e _start в команде ld строка или использование ENTRY (_start) в сценарии компоновщика) может быть решением.

10
ответ дан 6 December 2019 в 10:48
поделиться

Я думаю, вы хотите пройти - no-gc-section вариант компоновщика. Из документации GNU ld :

--gc-sections
--no-gc-sections

Enable garbage collection of unused input sections.

`--gc-sections' decides which input sections are used
by examining symbols and relocations. The section
containing the entry symbol and all sections containing symbols
undefined on the command-line will be kept, as will sections
containing symbols referenced by dynamic objects.
Note that when building shared libraries, the linker must
assume that any visible symbol is referenced. Once this initial
set of sections has been determined, the linker recursively marks
as used any section referenced by their relocations.
See `--entry' and `--undefined'.
3
ответ дан 6 December 2019 в 10:48
поделиться

Вы можете использовать параметр ld --whole-archive для извлечения символов без ссылок. На этой странице параметров ld есть это для всего архива - all-archive

Для каждого архива, указанного в командной строке после --whole-archive { {1}}, включите каждый объектный файл в архив в ссылку вместо поиска в архиве требуемых объектных файлов . Обычно это используется для преобразования файла архива в общую библиотеку, заставляя каждый объект включать в результирующую общую библиотеку. Эту опцию можно использовать несколько раз .
Два примечания при использовании этой опции из gcc: во-первых, gcc не знает об этой опции, поэтому вы должны использовать -Wl, -whole-archive . Во-вторых, не забудьте использовать -Wl, -no-all-archive после списка архивов, потому что gcc добавит свой собственный список архивов к вашей ссылке и вы можете не захотеть, чтобы этот флаг также влиял на них.

Также см. Этот вопрос о переполнении стека, использование опции полного архива

1
ответ дан 6 December 2019 в 10:48
поделиться

Компоновщик извлечет из архива только те объекты, которые необходимы для разрешения явно указанных символов. На ваш код запуска нет явной ссылки, потому что он вызывается через вектор сброса.

Если ваш загрузочный код состоит из нескольких модулей, вы должны создать частично связанный объектный файл, используя ld и параметр -r / --relocatable , это объединит объекты в один объект без необходимости разрешать все символы (например, main ()). Затем его можно использовать в полной ссылке с кодом вашего приложения. Если это только один объектный файл, то в любом случае нет никакого реального преимущества в создании архива (и, как вы обнаружили, это не сработает).

Обратите внимание, что традиционно запуск среды выполнения GNU C предоставляется в файле с именем crt0.o (не архивом), предположительно по той же причине.

2
ответ дан 6 December 2019 в 10:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: