Apple Clang12 LLVM — неизвестный тип исправления AArch64

Я пытаюсь перенести некоторый код Linux C на Apple M1 Mac и столкнулся с проблемой с некоторой встроенной сборкой. И это ставит меня в тупик.

У меня есть следующий встроенный блок сборки:

#define TEST asm volatile(\    
    "adr x0, label9 \n"\                                                                                                                                                          
    : : : "x0");

И столкнулся со следующей ошибкой:

test.c:73:5: error: unknown AArch64 fixup kind!
    TEST
    ^
./ARM_branch_macros.h:2862:7: note: expanded from macro 'TEST'
      "adr x0, label9 \n"\
      ^
<inline asm>:1:2: note: instantiated into assembly here
        adr x0, label9 
        ^
1 error generated.
make: *** [indirect_branch_latency.o] Error 1

Я использую следующий компилятор:

Apple clang version 12.0.0 (clang-1200.0.32.27)
Target: arm64-apple-darwin20.1.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

С помощью командной строки:

clang -c -o test.o test.c -I. -w -g -lrt -O0 -static -DARM_ASSEMBLY

Любая помощь будет принята с благодарностью!

Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
3
0
1 804
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Инструкция ADR сохраняет смещение от текущего значения PC до метки, на которую вы ссылаетесь.

Когда у вас есть инструкция, которая ссылается на символ в другом объектном файле (или в другом разделе того же объектного файла), ассемблер не может напрямую закодировать точное смещение, поскольку он не знает, как компоновщик их разместит. , но должен оставить перемещение в объектном файле, предписывая компоновщику исправить инструкцию, как только станет известно точное местоположение символа.

Я думаю, что проблема здесь просто в том, что формат объектного файла MachO (который используется на платформах Apple) не имеет типа перемещения для исправления инструкции ADR, указывающей на символ в другом месте. И даже если бы он имел это, конструкция довольно хрупкая - символ, на который он указывает, должен быть в пределах +/- 1 МБ от инструкции, ссылающейся на него - это предел, который довольно легко достичь.

Чтобы получить доступ к большему диапазону, часто используется пара инструкций ADRP+ADD, которая дает вам диапазон +/- 4 ГБ, и формат MachO поддерживает их.

Синтаксис ассемблера для них немного отличается между MachO и ELF (и COFF). Для MachO синтаксис выглядит так:

adrp x0, symbol@PAGE
add x0, x0, symbol@PAGEOFF

Или, если вы хотите загрузиться с него одновременно:

adrp x0, symbol@PAGE
ldr x1, [x0, symbol@PAGEOFF]

На платформах ELF (формат объектного файла, используемый в Linux) и COFF (Windows, при сборке сборки в стиле GNU с LLVM) синтаксис выглядит следующим образом:

adrp x0, symbol
add x0, x0, :lo12:symbol

В качестве дополнения: clang поддерживает «Подсказки по оптимизации компоновщика», которые позволяют, например, включить. adrp+add в просто adr+nop во время компоновки, если это позволяет относительное смещение. Это делается путем присвоения обеим инструкциям метки, а затем включения директивы сборки .loh AdrpAdd L1, L2. Информация об этой функции кажется скудной, но в источнике clang есть несколько полезных комментариев.

Siguza 19.12.2020 12:09

Другие вопросы по теме