LLVM ARM64 assembly: Getting a symbol/label address?

我的梦境 提交于 2021-02-17 02:28:07

问题


I am porting some 32-bit ARM code to 64-bit and am having trouble determining the 64-bit version of this instruction:

ldr  r1, =_fns

Where _fns is a symbol defined in some C source file elsewhere in the project.

I've tried the below but both give errors:

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

The assembler is LLVM in the iOS SDK (XCode 7.1).

I've noticed that if _fns is locally defined (i.e. in the same .S file) then "adr x1,_fns" works fine. However that's not a fix as _fns has to be in C code (i.e. in a different translation unit).

What is the right way to do this with LLVM ARM assembler?


回答1:


If I feed

extern char ar[];

char *f()
{
  return ar;
}

into the ELLCC (clang based) demo, I get:

Output from the compiler targeting 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

The adrp instruction gets the "page" address of ar into x0. The symbol argument to adrp translates into a 21 bit PC relative offset to the 4K page in which the symbol resides. That offset is added to the PC to get the actual start of the page. The add instruction adds the low 12 bits of the symbol address to get the actual symbol address.

This instruction sequence allows the address of a symbol within +/-4GB of the PC to be loaded.

As far as I can tell, there doesn't seem to be a way of getting functionality similar to 32 bit ARM's "=ar" in C. I assembly language, it looks like this will work:

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

This is very similar to what the 32 bit ARM does under the hood.

The only reason I started out with the C version was to show how I usually attack a problem like this, especially if I'm not that familiar with the target assembly language.




回答2:


this work well for me, xcode7.1 LLVM7.0 IOS9.1

In 32bit arm
ldr r9,=JumpTab

Change to 64bit arm

adrp x9,JumpTab@PAGE
add x9,x9,JumpTab@PAGEOFF

By the way,you need care registers' number, some registers have specific useful in arm64



来源:https://stackoverflow.com/questions/34003338/llvm-arm64-assembly-getting-a-symbol-label-address

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!