本文介绍了Apple Clang12 LLVM - 未知的 AArch64 修复类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将一些 Linux C 代码移植到 Apple M1 Mac,并且遇到了一些内联汇编的问题.这让我很难过.

I'm trying to port some Linux C code to an Apple M1 Mac and have been encountering an issue with some inline assembly. And it has me stumped.

我有以下内联汇编块:

#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

我正在使用以下编译器:

I am using the following compiler:

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

任何帮助将不胜感激!

推荐答案

ADR 指令存储从当前 PC 值到您引用的标签的偏移量.

The ADR instruction stores the offset from the current PC value to the label you reference.

当您有一条指令引用不同目标文件(或同一目标文件的不同部分)中的符号时,汇编器无法直接编码确切的偏移量,因为它不知道链接器将如何布置它们,但必须在目标文件中留下重定位,一旦知道符号的确切位置,就会指示链接器修复指令.

When you have an instruction that references a symbol in a different object file (or in a different section in the same object file), the assembler can't encode the exact offset directly as it doesn't know how the linker will lay them out, but has to leave a relocation in the object file, instructing the linker to fix up the instruction once the exact location of the symbol is known.

我认为这里的问题只是 MachO 目标文件(在苹果平台上使用)格式没有用于修复指向其他地方符号的 ADR 指令的重定位类型.即使它有这样的构造,它也非常脆弱——它指向的符号必须与引用它的指令相差 +/- 1 MB 之内——这是一个很容易达到的限制.

I think the issue here is simply that the MachO object file (which is used on apple platforms) format doesn't have a relocation type for fixing up an ADR instruction pointing at a symbol elsewhere. And even if it had that, the construct is pretty brittle - the symbol that it points at has to be within +/- 1 MB from the instruction referencing it - that's a limit that is pretty easy to hit.

为了访问更大的范围,经常使用 ADRP+ADD 指令对,它为您提供 +/- 4 GB 的范围,而 MachO 格式确实支持这些.

To get access to a bigger range, an ADRP+ADD instruction pair is often used, which gives you a +/- 4 GB range, and the MachO format does support those.

它们的汇编语法在 MachO 和 ELF(和 COFF)之间略有不同.对于 MachO,语法如下所示:

The assembler syntax for them differs a bit between MachO and ELF (and COFF). For MachO, the syntax looks like this:

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

或者如果您想同时从中加载:

Or if you want to load from it at the same time:

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

在 ELF(Linux 上使用的目标文件格式)和 COFF(windows,当使用 LLVM 组装 GNU 样式程序集时)平台上,语法如下所示:

On ELF (the object file format used on Linux) and COFF (windows, when assembling GNU style assembly with LLVM) platforms, the syntax looks like this:

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

这篇关于Apple Clang12 LLVM - 未知的 AArch64 修复类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 18:52