This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

ARM64 Linaro toochain Link error ( R_AARCH64_LD_PREL_LO19 )

Hi Experts,

I am getting following linker error from Linaro aarch64 tool chain( aarch64-linux-gnu-gcc, gcc-linaro-aarch64-linux-gnu-4.8-2014.03_linux),  for our code which uses  pBitReverseIndex, pSignTable  global pointers which is declared out side the assembly file.

Linking CXX executable decoder-app

(.text+0x14): relocation truncated to fit: R_AARCH64_LD_PREL_LO19 against symbol `pBitReverseIndex' defined in .data.rel section in ../../../../*****.a(dct.c.o)

../../../..**********r.a(dct_opt.s.o): In function `dct':

(.text+0x20): relocation truncated to fit: R_AARCH64_LD_PREL_LO19 against symbol `pRevTable' defined in .data.rel section in ../../../../l*****r.a(dct.c.o)

../../../../lib-decoder/libhd-decoder.a(dct_opt.s.o): In function `dct':

(.text+0x28): relocation truncated to fit: R_AARCH64_LD_PREL_LO19 against symbol `pSignTable' defined in .data.rel section in ../../../..*******.a(dct.c.o)

../../../../****r.a(dct_opt.s.o): In function `L_PreRotateLoop':

collect2: error: ld returned 1 exit status

The DCT assembly function uses BitReverseIndex, SignTable, CosineTable etc. declared inside DCT.c

We are using LDR instruction inside assembly to load the address of these tables :

LDR                 x17, pSignTable

LDR                 x15, pRevTable

These tables and pointers are declared DCT.c

const Int32 SignTable[4]= {1, 1, 1, -1};

const Int8 RevTable[16]= {0,1,2,3,4,5,6,7,0xc,0xd,0xe,0xf,8,9,0xa,0xb};

const Int8* const pRevTable = RevTable;

const Int32* const pSignTable = SignTable;

We also tried with ADR instruction which satisfies position independent coding. But we couldn't fix this issue.

  • Hi,

    While linking the arm64 assembly we are getting "relocation truncated to fit: R_AARCH64_LD_PREL_LO19 against symbol" error for this table. For C code, we could build successfully. 

    So i tried to investigate on dis-assembly. The dis-assembly uses ADRP instruction to find the address of page. And got offset to calculate address of table from page address.

      adrp x2, :got:Block_Divisor
      ldr x2, [x2, #:got_lo12:Block_Divisor]

    I am not sure, How can we implement this method in our assembly.

  • LDR x17,=SignTable


    will load the address of SignTable. I guess you actually didn't really want pSignTable

    The = is needed with LDR to put the address into a literal pool beside the code.

    See about literal pools and LTORG, and also ADRL and MOVL which are also useful for this sort of thing in the ARM compiler armasm User Guide or Reference Guide

    ADR and LDR with a label like you had are limited to using a label which is not too far away relative to the PC.

  • ARM 64 does not support these instruction format( = ). It was used in older arm compilers. Now we have 2 dedicated instructions for PIC address calculations.( ADR, ADRP )

    Thanks.

  • The = format should be supported, the problem probably is that you want position independent code and it can't have addresses in the code area, and literal pools are in the code area. For PIC the ADRL pseudo instruction is probably what you want if the range of ADR is too short as the writable areas of the library will linked at a constant displacement, it'll generate an ADR and ADRP. What exactly goes wrong if you say

    ADR x17, SignTable

    (or ADRL if you have a large program or data)?

    And of course writing a small C program that accesses the area, compiling it for pic and generating the assembly should also show how to do the job, it'll be a little more complicated because it has to cater for the possibility of the address not being in the same library. In effect what they have to do is have a literal pool which is outside the code area.