This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [AARCH64] question about RELA relocations


On Mon, Jan 11, 2016 at 7:26 PM, weixiangyu <weixiangyu@huawei.com> wrote:
> Hello,sorry to bother you, but I have some confusion about the RELA relocation.
> As we know, RELA means relocation entries with addends.Then my question is:
> If we use RELA,can we say that the offset will be 100 percent put into addend?

No.  Your example shows that.  What are you trying to do really?  It
is more complex than the below code.
Take an example of:

unsigned long test3(void)
{
  return test[flags+flags1];
}

You will get the following code:
test3:
        adrp    x0, .LANCHOR0
        add     x1, x0, :lo12:.LANCHOR0
        ldr     x2, [x1,16]
        ldr     x1, [x1,8]
        ldr     x0, [x0,#:lo12:.LANCHOR0]
        add     x1, x2, x1
        ldrsw   x0, [x0,x1,lsl 2]
        ret

Where you have three different variables at .LANCHOR0, LANCHOR0+8 and
LANCHOR0+16.

Are you trying to patch the code afterwards?  Also you might not want
section anchors you can disable that -fno-section-anchors and you get
more relocations (three R_AARCH64_ADR_PRE) :
test3:
        adrp    x0, flags1
        ldr     x2, [x0,#:lo12:flags1]
        adrp    x0, flags
        ldr     x1, [x0,#:lo12:flags]
        adrp    x0, test
        ldr     x0, [x0,#:lo12:test]
        add     x1, x2, x1
        ldrsw   x0, [x0,x1,lsl 2]
        ret

Thanks,
Andrew


>
> Considering the following testcase:
>
> **************************************************************
> #include <stdlib.h>
> #define __test_section __attribute__((__section__(".data.test_section")))
>
> static unsigned long flags __test_section;
> static int *test __test_section;
>
> unsigned long test1(void)
> {
> test = NULL;
> return 0;
> }
>
> unsigned long test2(void)
> {
> //const volatile unsigned long *addr = &flags;
> const unsigned long *addr = &flags;
> return *addr;
> }
>
> **************************************************************
> My toolchain is aarch64_be-linux-gnu cross compiler based on gcc-4.9.3 and binutils-2.24.
>
> Execute the following command:
> aarch64_be-linux-gnu-gcc -c test.c -O2 -dp
> aarch64_be-linux-gnu-readelf -r test.o > readelf_r
>
> The relocation information is as follows:
> We can see that the offset of the global variable "flags" is put into Addend,and as my understanding,this is the right way of RELA relocations
>
> *********************************************************************************
> Relocation section '.rela.text' at offset 0x538 contains 4 entries:
>   Offset          Info           Type           Sym. Value    Sym. Name + Addend
> 000000000000  000600000113 R_AARCH64_ADR_PRE 0000000000000000 .data.test_section + 0
> 000000000008  00060000011e R_AARCH64_LDST64_ 0000000000000000 .data.test_section + 0
> 000000000010  000600000113 R_AARCH64_ADR_PRE 0000000000000000 .data.test_section + 8
> 000000000014  00060000011e R_AARCH64_LDST64_ 0000000000000000 .data.test_section + 8
> *********************************************************************************
>
> But when "addr" is prefixed with the keyword "volatile" ,then the relocation would look like this:
> *********************************************************************************
> Relocation section '.rela.text' at offset 0x538 contains 4 entries:
>   Offset          Info           Type           Sym. Value    Sym. Name + Addend
> 000000000000  000600000113 R_AARCH64_ADR_PRE 0000000000000000 .data.test_section + 0
> 000000000008  00060000011e R_AARCH64_LDST64_ 0000000000000000 .data.test_section + 0
> 000000000010  000600000113 R_AARCH64_ADR_PRE 0000000000000000 .data.test_section + 0
> 000000000014  000600000115 R_AARCH64_ADD_ABS 0000000000000000 .data.test_section + 0
> *********************************************************************************
> The addend is zero.
>
> Get the assemble output of the two situations with the following command:
> aarch64_be-linux-gnu-gcc -S test.c -O2 -dp -o test.s
>
> the assemble output without "volatile":
> ************************************************************************************
> test2:
>         adrp    x0, .LANCHOR0+8 // 6    *movdi_aarch64/10       [length = 4]
>         ldr     x0, [x0,#:lo12:.LANCHOR0+8]     // 12   *movdi_aarch64/5        [length = 4]
>         ret     // 20   *do_return      [length = 4]
>         .size   test2, .-test2
>         .section        .data.test_section,"aw",%progbits
>         .align  3
> .LANCHOR0 = . + 0
>         .type   test, %object
>         .size   test, 8
> ************************************************************************************
>
>
> the assemble output with "volatile":
> ************************************************************************************
> test2:
>         adrp    x0, .LANCHOR0   // 5    *movdi_aarch64/10       [length = 4]
>         add     x0, x0, :lo12:.LANCHOR0 // 6    add_losym_di    [length = 4]
>         ldr     x0, [x0,8]      // 7    *movdi_aarch64/5        [length = 4]
>         ret     // 20   *do_return      [length = 4]
>         .size   test2, .-test2
>         .section        .data.test_section,"aw",%progbits
>         .align  3
> .LANCHOR0 = . + 0
>         .type   test, %object
>         .size   test, 8
> ************************************************************************************
>
>
>
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]