[AArch64] Question about far call

Hi,

For the following code:

void foo ();

int main () {foo();}

llvm emits “bl foo”

Then I set foo at a far address in linking:

aarch64-linux-gnu-gcc -Wl,–defsym=foo=0x80000000 a.o -o a.exe

I got an error from ld:

a.c:(.text+0x8): relocation truncated to fit: R_AARCH64_CALL26 against symbol `foo’ define in ABS section in a.exe

The question is: do I miss some options or pragmas during compilation ?

Should I expect llvm to emit the following code?

movz x8, #:abs_g3:foo

movk x8, #:abs_g2_nc:foo

movk x8, #:abs_g1_nc:foo

movk x8, #:abs_g0_nc:foo

ldr x8, [x8]

blr x8

or I miss some flag during linking?

PS. The above test works fine with arm v7 targart. (clang emits “bl foo” and ld generates veneer)

Thanks,

Weiming

Hi Weiming,

PS. The above test works fine with arm v7 targart. (clang emits “bl foo” and
ld generates veneer)

This is what I'd expect ld to do in the AArch64 case too. Most of the
time the destination (or its stub) is in range, so general codegen
shouldn't be penalised by having to emit movz/movk sequences &
indirect branches for each call.

Unfortunately, the AArch64 (& ARM) ELF ABI appears to make it a QoI
issue by using vague wording in section 4.6.7 ("a linker *may* use a
veneer..."). I'm still surprised they haven't done that yet though; I
wonder if there's a bug lying around.

Cheers.

Tim.

Hi Tim,

Thanks for answering.
I also tried armlink 6 for aarch64. It inserts veneer too. So gnu ld is
not doing the job very well.
My current workaround is declaring those functions as function pointers
and compile with -mcmodel=large to force compiler to generate 4 movs and
"blr".

Thanks,
Weiming