[AARCH64] question about RELA relocations

Jiong Wang jiong.wang@foss.arm.com
Tue Jan 12 12:02:00 GMT 2016


weixiangyu writes:

> 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?

Yes, if the offset is encoded in the relocation.

For you question when "volatile" prefixed, that's because the generated
assembly itself contains relocation against symbol *without* addend.

If a target use Rela, and if the offset exist in the relocation, then it
should always be put into addend field in the relocation entry.

FWIK, assembler, especially hooks like tc_gen_reloc, is reponsible to
make sure this happen.

For the example attached, AArch64 assembler is working correctly. When
volatile is used, somehow gcc will split the offset into two parts, then
turn "sym + addend" relocation into "sym" only.

gcc combine should have combined:

 add  x0, x0, :lo12:.LANCHOR0
 ldr  x0, [x0,8] 

into:

 ldr     x0, [x0,#:lo12:.LANCHOR0+8]

It's not happen because combine pass invoked "init_recog_no_volatile" to
prevent volatile memory to be combined. I guess combine is too
conservative on this, purely combine contant offsets inside volatile
memory should be safe. (CCed Segher).

>
> 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
> ************************************************************************************

-- 
Regards,
Jiong



More information about the Gcc-help mailing list