При игре с созданием исполняемых файлов из неметалла я сталкиваюсь с этой ошибкой:
main.o:(.eh_frame+0x1c): relocation truncated to fit: R_AARCH64_PREL32 against `.text'
collect2: error: ld returned 1 exit status
Затем мне удалось создать пример минимального воспроизведения:
main. c
void _start(void) {}
notmain.S
.skip 32
link.ld
ENTRY(_start)
SECTIONS
{
.text : {
*/bootloader.o(.text)
*(.text)
*(.rodata)
*(.data)
*(COMMON)
}
.bss : { *(.bss) }
heap_low = .;
. = . + 0x1000000;
heap_top = .;
. = . + 0x1000000;
stack_top = .;
}
Команда компиляции:
aarch64-linux-gnu-gcc \
-save-temps \
-T link.ld \
-Wall \
-Werror \
-Wextra \
-Wl,--section-start=.text=0x80000000 \
-Xassembler -march=all \
-fno-pie \
-ggdb3 \
-no-pie \
-nostartfiles \
-nostdlib \
-static \
-o 'main.out' \
-pedantic \
notmain.S \
'main.c'
, где aarch64-linux-gnu-gcc
- версия G CC 9.2.1 из пакета gcc-9-aarch64-linux-gnu
в Ubuntu 19.10.
Позже я также попробовал Ubuntu 18.04 G CC 7.5.0, и там это сработало, поэтому было бы хорошо понять, что изменилось между .
.skip 16
работает, а .skip 32
- нет.
Я знаю, что не идеальным является использование кросс-компилятора не-baremetal для baremetal-материалов, но кто-нибудь может указать, есть ли какая-либо опция командной строки или модификация кода, которую я мог бы сделать, чтобы заставить ссылку работать?
И если это невозможно с этим набором инструментов, кто-нибудь может объяснить, почему? Какой вариант конфигурации сборки G CC, в частности, делает это невозможным?
На самом деле у меня был aarch64
crosstool-NG toolchain, лежащий около , описанного здесь , и он работает с этим, так что на самом деле может быть проблема с набором инструментов.
Я знаю, что R_AARCH64_PREL32
задокументировано по адресу: https://static.docs.arm.com/ihi0044/g/aaelf32.pdf, и у меня есть общее понимание перемещения: Что означает этот G CC ошибка "... перемещение усечено, чтобы соответствовать ..." означает? но это немного больше, чем я хотел бы вырыть прямо сейчас.
Кроме того, если я переместите точку входа в сборку в более реалистичной c настройке:
notmain.S
.global _start
_start:
bl entry
main. c
void entry(void) {}
проблема устранена не происходит.