[PATCH] LoongArch: Adapt R_LARCH_{PCALA, GOT, TLS_IE, TLS_DESC}64_* handling per psABI v2.30

mengqinggang mengqinggang@loongson.cn
Tue Jan 16 06:38:32 GMT 2024


在 2024/1/15 下午8:44, Xi Ruoyao 写道:
> In LoongArch psABI v2.30, an offset (-8 for LO20 and -12 for HI12)
> should be applied on PC for these reloc types to avoid wrong relocation
> when the instruction sequence crosses a page boundary.
>
> The lld linker has already adapted the change.  Make it for the bfd
> linker too.
>
> Link: https://github.com/loongson/la-abi-specs/releases/v2.30
> Link: https://github.com/loongson-community/discussions/issues/17
> Link: https://github.com/llvm/llvm-project/pull/73387
> Signed-off-by: Xi Ruoyao <xry111@xry111.site>
> ---
>   bfd/elfnn-loongarch.c                         | 29 +++++++++++--------
>   .../ld-loongarch-elf/ld-loongarch-elf.exp     |  1 +
>   ld/testsuite/ld-loongarch-elf/pcala64.d       | 15 ++++++++++
>   ld/testsuite/ld-loongarch-elf/pcala64.s       |  8 +++++
>   4 files changed, 41 insertions(+), 12 deletions(-)
>   create mode 100644 ld/testsuite/ld-loongarch-elf/pcala64.d
>   create mode 100644 ld/testsuite/ld-loongarch-elf/pcala64.s
>
> diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
> index 3858a3179fd..e4f4da7a0dc 100644
> --- a/bfd/elfnn-loongarch.c
> +++ b/bfd/elfnn-loongarch.c
> @@ -3544,14 +3544,16 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
>   	    }
>   	  break;
>   
> -	case R_LARCH_PCALA64_LO20:
>   	case R_LARCH_PCALA64_HI12:
> +	  pc -= 4;
> +	  /* Fall through.  */
> +	case R_LARCH_PCALA64_LO20:
>   	  if (h && h->plt.offset != MINUS_ONE)
>   	    relocation = sec_addr (plt) + h->plt.offset;
>   	  else
>   	    relocation += rel->r_addend;
>   
> -	  RELOCATE_CALC_PC64_HI32 (relocation, pc);
> +	  RELOCATE_CALC_PC64_HI32 (relocation, pc - 8);


The 'pc - 8' triggered an error because the pc parameter is not enclosed 
in parentheses in macro definition.

/home/mengqinggang/toolchains/src/binutils-gdb/bfd/elfnn-loongarch.c:3546:51: 
error: suggest parentheses around '-' in operand of '&' 
[-Werror=parentheses]
  3546 |           RELOCATE_CALC_PC64_HI32 (relocation, pc - 8);
       |                                                ~~~^~~
/home/mengqinggang/toolchains/src/binutils-gdb/bfd/elfnn-loongarch.c:2532:22: 
note: in definition of macro 'RELOCATE_CALC_PC64_HI32'
  2532 |                   - (pc & ~(bfd_vma)0xfff);             \
       |                      ^~

>   
>   	  break;
>   
> @@ -3678,9 +3680,10 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
>   	      relocation = got_off + sec_addr (got);
>   	    }
>   
> -	  if (r_type == R_LARCH_GOT64_PC_HI12
> -	      || r_type == R_LARCH_GOT64_PC_LO20)
> -	    RELOCATE_CALC_PC64_HI32 (relocation, pc);
> +	  if (r_type == R_LARCH_GOT64_PC_HI12)
> +	    RELOCATE_CALC_PC64_HI32 (relocation, pc - 12);
> +	  else if (r_type == R_LARCH_GOT64_PC_LO20)
> +	    RELOCATE_CALC_PC64_HI32 (relocation, pc - 8);
>   
>   	  break;
>   
> @@ -3881,13 +3884,14 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
>   	    /* Use both TLS_GD and TLS_DESC.  */
>   	    if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_GDESC))
>   	      relocation += 2 * GOT_ENTRY_SIZE;
> -	  }
>   
> -	    if (r_type == R_LARCH_TLS_DESC64_PC_LO20
> -		|| r_type == R_LARCH_TLS_DESC64_PC_HI12)
> -	      RELOCATE_CALC_PC64_HI32 (relocation, pc);
> +	    if (r_type == R_LARCH_TLS_DESC64_PC_LO20)
> +	      RELOCATE_CALC_PC64_HI32 (relocation, pc - 8);
> +	    else if (r_type == R_LARCH_TLS_DESC64_PC_HI12)
> +	      RELOCATE_CALC_PC64_HI32 (relocation, pc - 12);
>   
>   	    break;
> +	  }
>   
>   	case R_LARCH_TLS_DESC_LD:
>   	case R_LARCH_TLS_DESC_CALL:
> @@ -3916,9 +3920,10 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
>   	  else if (GOT_TLS_GD_ANY_P (tls_type) && (tls_type & GOT_TLS_IE))
>   	    relocation += 2 * GOT_ENTRY_SIZE;
>   
> -	  if (r_type == R_LARCH_TLS_IE64_PC_LO20
> -	      || r_type == R_LARCH_TLS_IE64_PC_HI12)
> -	    RELOCATE_CALC_PC64_HI32 (relocation, pc);
> +	  if (r_type == R_LARCH_TLS_IE64_PC_LO20)
> +	    RELOCATE_CALC_PC64_HI32 (relocation, pc - 8);
> +	  else if (r_type == R_LARCH_TLS_IE64_PC_HI12)
> +	    RELOCATE_CALC_PC64_HI32 (relocation, pc - 12);
>   
>   	  break;
>   
> diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
> index 6ab87163039..2ff06d62236 100644
> --- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
> +++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
> @@ -26,6 +26,7 @@ if [istarget "loongarch64-*-*"] {
>       run_dump_test "disas-jirl"
>       run_dump_test "local-ifunc-reloc"
>       run_dump_test "anno-sym"
> +    run_dump_test "pcala64"
>   }
>   
>   if [istarget "loongarch32-*-*"] {
> diff --git a/ld/testsuite/ld-loongarch-elf/pcala64.d b/ld/testsuite/ld-loongarch-elf/pcala64.d
> new file mode 100644
> index 00000000000..6b1411577db
> --- /dev/null
> +++ b/ld/testsuite/ld-loongarch-elf/pcala64.d
> @@ -0,0 +1,15 @@
> +#ld: -Ttext=0x180000ff8 -Tdata=0x1000000000 -shared


The test need to be disabled on loongarch*-elf target because -shared 
option is not supported on loongarch*-elf target.

It can be disabled by  adding a line "#skip: loongarch*-elf" after 
"#objdump -d".


> +#objdump: -d
> +
> +.*:[    ]+file format .*
> +
> +
> +Disassembly of section .text:
> +
> +0000000180000ff8 <_start>:
> +[ 	]+180000ff8:[ 	]+1b000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+-524288
> +[ 	]+180000ffc:[ 	]+02c0000c[ 	]+li.d[ 	]+\$t0,[ 	]+0
> +[ 	]+180001000:[ 	]+160001ec[ 	]+lu32i.d[ 	]+\$t0,[ 	]+15
> +[ 	]+180001004:[ 	]+0300018c[ 	]+lu52i.d[ 	]+\$t0,[ 	]+\$t0,[ 	]+0
> +[ 	]+180001008:[ 	]+0010b084[ 	]+add.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+\$t0
> +[ 	]+18000100c:[ 	]+4c000020[ 	]+ret
> diff --git a/ld/testsuite/ld-loongarch-elf/pcala64.s b/ld/testsuite/ld-loongarch-elf/pcala64.s
> new file mode 100644
> index 00000000000..dfef0e2b7b7
> --- /dev/null
> +++ b/ld/testsuite/ld-loongarch-elf/pcala64.s
> @@ -0,0 +1,8 @@
> +.text
> +.globl _start
> +_start:
> +	la.pcrel $a0, $t0, sym
> +	jr $ra
> +.data
> +sym:
> +	.dword 0



More information about the Binutils mailing list