[PATCH v4] MIPS: Support PCREL GOT access

Maciej W. Rozycki macro@orcam.me.uk
Fri Feb 2 13:30:04 GMT 2024


On Fri, 2 Feb 2024, YunQiang Su wrote:

> Current if we need to access a GOT entry, we use the
> got_base + offset. Thus we have GOT and XGOT.
> >From MIPSr6, we have PCREL instructions like ALUIPC,

 I'm assuming ">" above is a typo; overall the change description may need 
a little bit polishing, but let's leave it until all the issues with code 
itself have been sorted.

> so we have no need to use got_base now.
> For pre-R6, we can use BAL to get the the value of PC.

 I've skimmed over your change and spotted a couple of issues right away, 
as noted below.  I'll go through your change more thoroughly again.

 Have the new relocations been formally documented anywhere?

> diff --git a/bfd/elf64-mips.c b/bfd/elf64-mips.c
> index 489a461bb0b..dc4e56d1f55 100644
> --- a/bfd/elf64-mips.c
> +++ b/bfd/elf64-mips.c
> @@ -1670,6 +1782,118 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
>  	 0x0000ffff,		/* dst_mask */
>  	 true),			/* pcrel_offset */
>  
> +  HOWTO (R_MIPS_GOTPC_HI16,	/* type */
> +	 16,			/* rightshift */
> +	 4,			/* size */
> +	 16,			/* bitsize */
> +	 true,			/* pc_relative */
> +	 0,			/* bitpos */
> +	 complain_overflow_signed, /* complain_on_overflow */
> +	 _bfd_mips_elf_generic_reloc,   /* special_function */
> +	 "R_MIPS_GOTPC_HI16",	/* name */
> +	 true,			/* partial_inplace */
> +	 0x0000ffff,		/* src_mask */
> +	 0x0000ffff,		/* dst_mask */
> +	 true),			/* pcrel_offset */

 For RELA relocations you need to set `partial_inplace' to `false' and 
`src_mask' to 0, because they do not store the addend in the field 
relocated.  Likewise throughout and with n32.

> diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
> index 69dd71419ff..c8a9ceb7524 100644
> --- a/bfd/elfxx-mips.c
> +++ b/bfd/elfxx-mips.c
> @@ -2267,19 +2267,28 @@ got_page_reloc_p (unsigned int r_type)
>  static inline bool
>  got_lo16_reloc_p (unsigned int r_type)
>  {
> -  return r_type == R_MIPS_GOT_LO16 || r_type == R_MICROMIPS_GOT_LO16;
> +  return r_type == R_MIPS_GOT_LO16
> +	 || r_type == R_MIPS_GOTPC_LO16
> +	 || r_type == R_MIPS_GOTPC_ALO16
> +	 || r_type == R_MICROMIPS_GOT_LO16;
>  }

 Please follow the GNU coding style, i.e.:

  return (r_type == R_MIPS_GOT_LO16
	  || r_type == R_MIPS_GOTPC_LO16
	  || r_type == R_MIPS_GOTPC_ALO16
	  || r_type == R_MICROMIPS_GOT_LO16);

Likewise throughout.

  Maciej


More information about the Binutils mailing list