Как предотвратить "main.o :(. Eh_frame + 0x1 c): перемещение усечено до соответствия: R_AARCH64_PREL32 против" .text "" при создании голой металлической программы aarch64? - PullRequest
1 голос
/ 23 марта 2020

При игре с созданием исполняемых файлов из неметалла я сталкиваюсь с этой ошибкой:

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) {}

проблема устранена не происходит.

1 Ответ

0 голосов
/ 23 марта 2020

В качестве обходного пути, позволяющего его компилировать без полного понимания ситуации, вы можете добавить:

-fno-unwind-tables -fno-asynchronous-unwind-tables

, который удаляет кадр .eh_frame, из которого происходило неудачное перемещение: Почему G CC скомпилированная C программа нуждается в секции .eh_frame?

Затем я заметил, что двоичный файл не работает, потому что _start имеет пролог функции C и в первую очередь касается стека, и я не могу найти изумительное решение для этого: Создание функции C без пролога / эпилога и инструкции RET, сгенерированной компилятором? (-O3? :-) Нам нужно изобрести -fno-stack опция).

...