[PATCH v2] Not append rela for absolute symbol

Lulu Cai cailulu@loongson.cn
Sat Sep 7 02:14:49 GMT 2024


Thank you. The patch has been applied.

On 8/16/24 11:28 AM, Xin Wang wrote:
> LoongArch: Not append rela for absolute symbol
>
> Use la.global to get absolute symbol like la.abs.
> la.global put address of a global symbol into a got
> entry and append a rela for it, which will be used
> to relocate by dynamic linker. Dynamic linker should
> not relocate for got entry of absolute symbol as it
> stores symval not symbol's address.
>
> diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
> index f58ced30ac3..a69c41bc699 100644
> --- a/bfd/elfnn-loongarch.c
> +++ b/bfd/elfnn-loongarch.c
> @@ -4138,6 +4138,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
>   		      if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn,
>   							    bfd_link_pic (info),
>   							    h)
> +			  && !bfd_is_abs_section(h->root.u.def.section)
>   			  && bfd_link_pic (info)
>   			  && LARCH_REF_LOCAL (info, h)
>   			  && !info->enable_dt_relr)
> @@ -4160,7 +4161,8 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
>   			      && local_got_offsets[r_symndx] != MINUS_ONE);
>   
>   		  got_off = local_got_offsets[r_symndx] & (~(bfd_vma)1);
> -		  if ((local_got_offsets[r_symndx] & 1) == 0)
> +		  if (sym->st_shndx != SHN_ABS
> +		      && (local_got_offsets[r_symndx] & 1) == 0)
>   		    {
>   		      if (bfd_link_pic (info) && !info->enable_dt_relr)
>   			{
> @@ -5321,6 +5323,7 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
>         bfd_vma symval;
>         asection *sym_sec;
>         bool local_got = false;
> +      bool is_abs_symbol = false;
>         Elf_Internal_Rela *rel = relocs + i;
>         struct elf_link_hash_entry *h = NULL;
>         unsigned long r_type = ELFNN_R_TYPE (rel->r_info);
> @@ -5502,7 +5505,21 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
>   	  break;
>   
>   	case R_LARCH_GOT_PC_HI20:
> +	  if (h)
> +	    is_abs_symbol = bfd_is_abs_section(h->root.u.def.section);
> +	  else
> +	    {
> +	      Elf_Internal_Sym *sym = (Elf_Internal_Sym *)symtab_hdr->contents
> +				    + ELFNN_R_SYM (rel->r_info);
> +	      is_abs_symbol = sym->st_shndx == SHN_ABS;
> +	    }
> +	 /* If symval is in the range [-2^31, 2^31), we can relax the
> +	    pair of instructions from pcalau12i/ld.d to lu12i.w/ori for
> +	    abosulte symbol. This is not implemented yet, so we just
> +	    remain the r_type which will be needed when relocate for
> +	    absolute symbol. */
>   	  if (local_got && 0 == info->relax_pass
> +	      && !is_abs_symbol
>   	      && (i + 4) <= sec->reloc_count)
>   	    {
>   	      if (loongarch_relax_pcala_ld (abfd, sec, rel))
> diff --git a/ld/testsuite/ld-loongarch-elf/abs-global.out b/ld/testsuite/ld-loongarch-elf/abs-global.out
> new file mode 100644
> index 00000000000..3656652b938
> --- /dev/null
> +++ b/ld/testsuite/ld-loongarch-elf/abs-global.out
> @@ -0,0 +1 @@
> +abba
> diff --git a/ld/testsuite/ld-loongarch-elf/abs-global.s b/ld/testsuite/ld-loongarch-elf/abs-global.s
> new file mode 100644
> index 00000000000..93a5da6dd22
> --- /dev/null
> +++ b/ld/testsuite/ld-loongarch-elf/abs-global.s
> @@ -0,0 +1,5 @@
> +.text
> +.globl get_sym
> +get_sym:
> + la.global $a0, sym
> + ret
> diff --git a/ld/testsuite/ld-loongarch-elf/get_abs_global_sym.c b/ld/testsuite/ld-loongarch-elf/get_abs_global_sym.c
> new file mode 100644
> index 00000000000..29781ad7703
> --- /dev/null
> +++ b/ld/testsuite/ld-loongarch-elf/get_abs_global_sym.c
> @@ -0,0 +1,7 @@
> +#include <stdio.h>
> +
> +extern int get_sym();
> +int main() {
> +	printf("%x\n", get_sym());
> +	return 0;
> +}
> diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
> index d80014d9563..270bff03874 100644
> --- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
> +++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
> @@ -130,6 +130,18 @@ if [istarget "loongarch64-*-*"] {
>   		"a.binary" \
>   	   ] \
>         ]
> +
> +
> +  run_ld_link_exec_tests [list \
> +	[list \
> +	    "get global abs symbol test" \
> +	    "-Wl,-z norelro -Wl,--defsym sym=0xabba" \
> +	    "" \
> +	    { abs-global.s get_abs_global_sym.c} \
> +	    "abs-global" \
> +	    "abs-global.out" \
> +	] \
> +    ]
>   }
>   
>   if [istarget "loongarch64-*-*"] {




More information about the Binutils mailing list