LLVM ARM64程序集:获取符号/标签地址?

时间:2015-11-30 16:30:58

标签: ios llvm arm64

我正在将一些32位ARM代码移植到64位,并且无法确定此指令的64位版本:

ldr  r1, =_fns

其中_fns是项目中其他地方的某个C源文件中定义的符号。

我已尝试过以下但两者都有错误:

adr  x1, _fns     <== "error: unknown AArch64 fixup kind!"
adrl  x1, _fns    <== "error: unrecognized instruction mnemonic"

汇编程序是iOS SDK(XCode 7.1)中的LLVM。

我注意到如果_fns是本地定义的(即在同一个.S文件中),那么“adr x1,_fns”工作正常。然而,这不是一个修复,因为_fns必须在C代码中(即在不同的翻译单元中)。

使用LLVM ARM汇编程序执行此操作的正确方法是什么?

2 个答案:

答案 0 :(得分:2)

如果我喂

extern char ar[];

char *f()
{
  return ar;
}

进入ELLCC (clang based) demo,我得到:

针对ARM AArch64的编译器输出

    .text
    .file   "/tmp/webcompile/_3793_0.c"
    .globl  f
    .align  2
    .type   f,@function
f:                                      // @f
// BB#0:                                // %entry
    adrp    x0, ar
    add x0, x0, :lo12:ar
    ret
.Lfunc_end0:
    .size   f, .Lfunc_end0-f


    .ident  "ecc 0.1.13 based on clang version 3.7.0 (trunk) (based on LLVM 3.7.0svn)"
    .section    ".note.GNU-stack","",@progbits

adrp 指令获取&#34;页面&#34; ar 的地址为 x0 adrp 的符号参数转换为符号所在的4K页面的21位PC相对偏移量。该偏移量被添加到PC以获得页面的实际开始。 add 指令添加符号地址的低12位以获取实际符号地址。

该指令序列允许加载PC的+/- 4GB范围内的符号地址。

据我所知,似乎没有一种方法可以获得类似于32位ARM的功能&#34; = ar&#34;在C.汇编语言中,它看起来会起作用:

        .text
        .file   "atest.s"
        .globl  f
        .align  2
f:
        ldr     x0, p
        ret
        .align  3
p:
        .xword  _fns

这与32位ARM的内幕非常相似。

我开始使用C版本的唯一原因是为了展示我通常如何解决这样的问题,特别是如果我不熟悉目标汇编语言的话。

答案 1 :(得分:0)

这对我来说很有用,xcode7.1 LLVM7.0 IOS9.1

在32bit臂中  ldr r9,= JumpTab

更改为64位手臂

adrp x9,JumpTab @ PAGE
 添加x9,x9,JumpTab @ PAGEOFF

顺便说一句,你需要护理登记册&#39;数字,一些寄存器在arm64中具有特殊用途