From: YunQiang Su <syq@gcc.gnu.org>
To: nickc@redhat.com
Cc: binutils@sourceware.org, macro@orcam.me.uk, xry111@xry111.site
Subject: Re: [PATCH] MIPS: Support PCREL GOT access
Date: Fri, 2 Feb 2024 14:42:27 +0800 [thread overview]
Message-ID: <CAKcpw6XMKuyn4SaFpd+t79meV0Cz8=1oUeEFEq5RaycbUTYTcA@mail.gmail.com> (raw)
In-Reply-To: <20240202063919.1414368-1-syq@gcc.gnu.org>
YunQiang Su <syq@gcc.gnu.org> 于2024年2月2日周五 14:39写道:
>
> 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,
> so we have no need to use got_base now.
> For pre-R6, we can use BAL to get the the value of PC.
>
> In this patch, we add 8 new relocs:
> R_MIPS_GOTPC_HI16, R_MIPS_GOTPC_LO16,
> R_MIPS_GOTPC_CALL_HI16, R_MIPS_GOTPC_CALL_LO16,
> R_MIPS_GOTPC_AHI16, R_MIPS_GOTPC_ALO16,
> R_MIPS_GOTPC_CALL_AHI16, R_MIPS_GOTPC_CALL_ALO16.
> These asm notes can be used for them:
> %gotpc_hi(sym), %gotpc_lo(sym),
> %gotpc_call_hi(sym), %gotpc_call_lo(sym),
> %gotpc_ahi(sym), %gotpc_alo(sym),
> %gotpc_call_ahi(sym), %gotpc_call_alo(sym).
>
> 3 new BFD_RELOCS are added for ALUIPC style relocs:
> BFD_RELOC_MIPS_ALO16_GOTOFF,
> BFD_RELOC_MIPS_AHI16_GOTOFF,
> BFD_RELOC_MIPS_AHI16_S_GOTOFF.
>
> 6 new BFD_RELOCS are added for function calling:
> BFD_RELOC_MIPS_LO16_GOTOFF_CALL,
> BFD_RELOC_MIPS_HI16_GOTOFF_CALL,
> BFD_RELOC_MIPS_HI16_S_GOTOFF_CALL,
> BFD_RELOC_MIPS_ALO16_GOTOFF_CALL,
> BFD_RELOC_MIPS_AHI16_GOTOFF_CALL,
> BFD_RELOC_MIPS_AHI16_S_GOTOFF_CALL,
>
> The mapping between BFD_RELOC_ and R_MIPS_GOTPC are:
> BFD_RELOC_HI16_S_GOTOFF -> R_MIPS_GOTPC_HI16
> BFD_RELOC_LO16_GOTOFF -> R_MIPS_GOTPC_LO16
> BFD_RELOC_MIPS_HI16_S_GOTOFF_CALL -> R_MIPS_GOTPC_CALL_HI16
> BFD_RELOC_MIPS_LO16_GOTOFF_CALL -> R_MIPS_GOTPC_CALL_LO16.
> BFD_RELOC_MIPS_AHI16_S_GOTOFF -> R_MIPS_GOTPC_AHI16
> BFD_RELOC_MIPS_ALO16_GOTOFF -> R_MIPS_GOTPC_ALO16
> BFD_RELOC_MIPS_MIPS_AHI16_S_GOTOFF_CALL -> R_MIPS_GOTPC_CALL_AHI16
> BFD_RELOC_MIPS_MIPS_ALO16_GOTOFF_CALL -> R_MIPS_GOTPC_CALL_ALO16.
>
> The difference of BAL and ALUIPC is that ALUIPC will unset the lower 16
> bits of result.
>
> For r6, both styles are supported, and of course ALUIPC style is
> recommended. For pre-R6, only BAL style is supported.
>
> Here are the ASM examples:
> ALUIPC:
> aluipc $2,%gotpc_ahi(sym)
> lw $2,%gotpc_alo(sym)($2)
>
> BAL:
> bal . + 8 # Note: $31 is clobbered here.
> lui $2,%gotpc_hi(sym)
> addiu $2,$2,$31
> lw $2,%gotpc_lo(sym)($2)
>
> gas/ChangeLog:
> * config/tc-mips.c: Add GOTPC relocs support.
> * testsuite/gas/mips/mips.exp: Add GOTPC testcases.
> * testsuite/gas/mips/gotpc-aluipc-32.s: Ditto.
> * testsuite/gas/mips/gotpc-aluipc-64.s: Ditto.
> * testsuite/gas/mips/gotpc-aluipc-n64.d: Ditto.
> * testsuite/gas/mips/gotpc-aluipc-n32.d: Ditto.
> * testsuite/gas/mips/gotpc-aluipc-o32.d: Ditto.
> * testsuite/gas/mips/gotpc-bal-32.s: Ditto.
> * testsuite/gas/mips/gotpc-bal-64.s: Ditto.
> * testsuite/gas/mips/gotpc-bal-n64.d: Ditto.
> * testsuite/gas/mips/gotpc-bal-n32.d: Ditto.
> * testsuite/gas/mips/gotpc-bal-o32.d: Ditto.
>
> bfd/ChangeLog:
> * elfxx-mips.c: Add GOTPC relocs support.
> * elf32-mips.c: Ditto.
> * elf64-mips.c: Ditto.
> * elfn32-mips.c: Ditto.
> * bfd-in2.h: Add new MIPS GOTPC BFD_RELOC defination.
> * reclos.c: Ditto.
> * libbfd.h: Ditto.
>
> elfcpp/ChangeLog:
> * mips.h: Add new MIPS GOTPC relocs.
>
> include/ChangeLog:
> * elf/mips.h (elf_mips_reloc_type): Add new MIPS GOTPC relocs.
> ---
> bfd/bfd-in2.h | 12 ++
> bfd/elf32-mips.c | 123 +++++++++++-
> bfd/elf64-mips.c | 234 +++++++++++++++++++++-
> bfd/elfn32-mips.c | 234 +++++++++++++++++++++-
> bfd/elfxx-mips.c | 107 +++++++++-
> bfd/libbfd.h | 9 +
> bfd/reloc.c | 18 ++
> elfcpp/mips.h | 8 +
> gas/config/tc-mips.c | 72 ++++++-
> gas/testsuite/gas/mips/gotpc-aluipc-32.s | 51 +++++
> gas/testsuite/gas/mips/gotpc-aluipc-64.s | 50 +++++
> gas/testsuite/gas/mips/gotpc-aluipc-n32.d | 17 ++
> gas/testsuite/gas/mips/gotpc-aluipc-n64.d | 25 +++
> gas/testsuite/gas/mips/gotpc-aluipc-o32.d | 17 ++
> gas/testsuite/gas/mips/gotpc-bal-32.s | 55 +++++
> gas/testsuite/gas/mips/gotpc-bal-64.s | 54 +++++
> gas/testsuite/gas/mips/gotpc-bal-n32.d | 17 ++
> gas/testsuite/gas/mips/gotpc-bal-n64.d | 25 +++
> gas/testsuite/gas/mips/gotpc-bal-o32.d | 17 ++
> gas/testsuite/gas/mips/mips.exp | 8 +
> include/elf/mips.h | 10 +-
> 21 files changed, 1155 insertions(+), 8 deletions(-)
> create mode 100644 gas/testsuite/gas/mips/gotpc-aluipc-32.s
> create mode 100644 gas/testsuite/gas/mips/gotpc-aluipc-64.s
> create mode 100644 gas/testsuite/gas/mips/gotpc-aluipc-n32.d
> create mode 100644 gas/testsuite/gas/mips/gotpc-aluipc-n64.d
> create mode 100644 gas/testsuite/gas/mips/gotpc-aluipc-o32.d
> create mode 100644 gas/testsuite/gas/mips/gotpc-bal-32.s
> create mode 100644 gas/testsuite/gas/mips/gotpc-bal-64.s
> create mode 100644 gas/testsuite/gas/mips/gotpc-bal-n32.d
> create mode 100644 gas/testsuite/gas/mips/gotpc-bal-n64.d
> create mode 100644 gas/testsuite/gas/mips/gotpc-bal-o32.d
>
> diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
> index 581d8fe0b3e..bce2030f9c5 100644
> --- a/bfd/bfd-in2.h
> +++ b/bfd/bfd-in2.h
> @@ -3654,6 +3654,18 @@ enum bfd_reloc_code_real
> BFD_RELOC_MIPS_18_PCREL_S3,
> BFD_RELOC_MIPS_19_PCREL_S2,
>
> + BFD_RELOC_MIPS_LO16_GOTOFF_CALL,
> + BFD_RELOC_MIPS_HI16_GOTOFF_CALL,
> + BFD_RELOC_MIPS_HI16_S_GOTOFF_CALL,
> +
> + BFD_RELOC_MIPS_ALO16_GOTOFF,
> + BFD_RELOC_MIPS_AHI16_GOTOFF,
> + BFD_RELOC_MIPS_AHI16_S_GOTOFF,
> +
> + BFD_RELOC_MIPS_ALO16_GOTOFF_CALL,
> + BFD_RELOC_MIPS_AHI16_GOTOFF_CALL,
> + BFD_RELOC_MIPS_AHI16_S_GOTOFF_CALL,
> +
> /* microMIPS versions of generic BFD relocs. */
> BFD_RELOC_MICROMIPS_GPREL16,
> BFD_RELOC_MICROMIPS_HI16,
> diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c
> index 63d7334dd52..7edcc30d331 100644
> --- a/bfd/elf32-mips.c
> +++ b/bfd/elf32-mips.c
> @@ -809,6 +809,119 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
> 0x0000ffff, /* src_mask */
> 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 */
> +
> + HOWTO (R_MIPS_GOTPC_LO16, /* type */
> + 0, /* rightshift */
> + 4, /* size */
> + 16, /* bitsize */
> + true, /* pc_relative */
> + 0, /* bitpos */
> + complain_overflow_dont, /* complain_on_overflow */
> + _bfd_mips_elf_generic_reloc, /* special_function */
> + "R_MIPS_GOTPC_LO16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_CALL_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_CALL_HI16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_CALL_LO16, /* type */
> + 0, /* rightshift */
> + 4, /* size */
> + 16, /* bitsize */
> + true, /* pc_relative */
> + 0, /* bitpos */
> + complain_overflow_dont, /* complain_on_overflow */
> + _bfd_mips_elf_generic_reloc, /* special_function */
> + "R_MIPS_GOTPC_CALL_LO16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_AHI16, /* 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_AHI16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_ALO16, /* type */
> + 0, /* rightshift */
> + 4, /* size */
> + 16, /* bitsize */
> + true, /* pc_relative */
> + 0, /* bitpos */
> + complain_overflow_dont, /* complain_on_overflow */
> + _bfd_mips_elf_generic_reloc, /* special_function */
> + "R_MIPS_GOTPC_ALO16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_CALL_AHI16, /* 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_CALL_AHI16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_CALL_ALO16, /* type */
> + 0, /* rightshift */
> + 4, /* size */
> + 16, /* bitsize */
> + true, /* pc_relative */
> + 0, /* bitpos */
> + complain_overflow_dont, /* complain_on_overflow */
> + _bfd_mips_elf_generic_reloc, /* special_function */
> + "R_MIPS_GOTPC_CALL_ALO16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> };
>
> /* The reloc used for BFD_RELOC_CTOR when doing a 64 bit link. This
> @@ -2030,7 +2143,15 @@ static const struct elf_reloc_map mips_reloc_map[] =
> { BFD_RELOC_MIPS_18_PCREL_S3, R_MIPS_PC18_S3 },
> { BFD_RELOC_MIPS_19_PCREL_S2, R_MIPS_PC19_S2 },
> { BFD_RELOC_HI16_S_PCREL, R_MIPS_PCHI16 },
> - { BFD_RELOC_LO16_PCREL, R_MIPS_PCLO16 }
> + { BFD_RELOC_LO16_PCREL, R_MIPS_PCLO16 },
> + { BFD_RELOC_HI16_S_GOTOFF, R_MIPS_GOTPC_HI16 },
> + { BFD_RELOC_LO16_GOTOFF, R_MIPS_GOTPC_LO16 },
> + { BFD_RELOC_MIPS_HI16_S_GOTOFF_CALL, R_MIPS_GOTPC_CALL_HI16 },
> + { BFD_RELOC_MIPS_LO16_GOTOFF_CALL, R_MIPS_GOTPC_CALL_LO16 },
> + { BFD_RELOC_MIPS_AHI16_S_GOTOFF, R_MIPS_GOTPC_AHI16 },
> + { BFD_RELOC_MIPS_ALO16_GOTOFF, R_MIPS_GOTPC_ALO16 },
> + { BFD_RELOC_MIPS_AHI16_S_GOTOFF_CALL, R_MIPS_GOTPC_CALL_AHI16 },
> + { BFD_RELOC_MIPS_ALO16_GOTOFF_CALL, R_MIPS_GOTPC_CALL_ALO16 }
> };
>
> static const struct elf_reloc_map mips16_reloc_map[] =
> 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
> @@ -889,6 +889,118 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
> 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 */
> +
> + HOWTO (R_MIPS_GOTPC_LO16, /* type */
> + 0, /* rightshift */
> + 4, /* size */
> + 16, /* bitsize */
> + true, /* pc_relative */
> + 0, /* bitpos */
> + complain_overflow_dont, /* complain_on_overflow */
> + _bfd_mips_elf_generic_reloc, /* special_function */
> + "R_MIPS_GOTPC_LO16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_CALL_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_CALL_HI16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_CALL_LO16, /* type */
> + 0, /* rightshift */
> + 4, /* size */
> + 16, /* bitsize */
> + true, /* pc_relative */
> + 0, /* bitpos */
> + complain_overflow_dont, /* complain_on_overflow */
> + _bfd_mips_elf_generic_reloc, /* special_function */
> + "R_MIPS_GOTPC_CALL_LO16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_AHI16, /* 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_AHI16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_ALO16, /* type */
> + 0, /* rightshift */
> + 4, /* size */
> + 16, /* bitsize */
> + true, /* pc_relative */
> + 0, /* bitpos */
> + complain_overflow_dont, /* complain_on_overflow */
> + _bfd_mips_elf_generic_reloc, /* special_function */
> + "R_MIPS_GOTPC_ALO16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_CALL_AHI16, /* 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_CALL_AHI16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_CALL_ALO16, /* type */
> + 0, /* rightshift */
> + 4, /* size */
> + 16, /* bitsize */
> + true, /* pc_relative */
> + 0, /* bitpos */
> + complain_overflow_dont, /* complain_on_overflow */
> + _bfd_mips_elf_generic_reloc, /* special_function */
> + "R_MIPS_GOTPC_CALL_ALO16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> };
>
> /* The relocation table used for SHT_RELA sections. */
> @@ -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 */
> +
> + HOWTO (R_MIPS_GOTPC_LO16, /* type */
> + 0, /* rightshift */
> + 4, /* size */
> + 16, /* bitsize */
> + true, /* pc_relative */
> + 0, /* bitpos */
> + complain_overflow_dont, /* complain_on_overflow */
> + _bfd_mips_elf_generic_reloc, /* special_function */
> + "R_MIPS_GOTPC_LO16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_CALL_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_CALL_HI16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_CALL_LO16, /* type */
> + 0, /* rightshift */
> + 4, /* size */
> + 16, /* bitsize */
> + true, /* pc_relative */
> + 0, /* bitpos */
> + complain_overflow_dont, /* complain_on_overflow */
> + _bfd_mips_elf_generic_reloc, /* special_function */
> + "R_MIPS_GOTPC_CALL_LO16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_AHI16, /* 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_AHI16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_ALO16, /* type */
> + 0, /* rightshift */
> + 4, /* size */
> + 16, /* bitsize */
> + true, /* pc_relative */
> + 0, /* bitpos */
> + complain_overflow_dont, /* complain_on_overflow */
> + _bfd_mips_elf_generic_reloc, /* special_function */
> + "R_MIPS_GOTPC_ALO16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_CALL_AHI16, /* 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_CALL_AHI16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_CALL_ALO16, /* type */
> + 0, /* rightshift */
> + 4, /* size */
> + 16, /* bitsize */
> + true, /* pc_relative */
> + 0, /* bitpos */
> + complain_overflow_dont, /* complain_on_overflow */
> + _bfd_mips_elf_generic_reloc, /* special_function */
> + "R_MIPS_GOTPC_CALL_ALO16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> };
>
> static reloc_howto_type mips16_elf64_howto_table_rel[] =
> @@ -3743,7 +3967,15 @@ static const struct elf_reloc_map mips_reloc_map[] =
> { BFD_RELOC_MIPS_18_PCREL_S3, R_MIPS_PC18_S3 },
> { BFD_RELOC_MIPS_19_PCREL_S2, R_MIPS_PC19_S2 },
> { BFD_RELOC_HI16_S_PCREL, R_MIPS_PCHI16 },
> - { BFD_RELOC_LO16_PCREL, R_MIPS_PCLO16 }
> + { BFD_RELOC_LO16_PCREL, R_MIPS_PCLO16 },
> + { BFD_RELOC_HI16_S_GOTOFF, R_MIPS_GOTPC_HI16 },
> + { BFD_RELOC_LO16_GOTOFF, R_MIPS_GOTPC_LO16 },
> + { BFD_RELOC_MIPS_HI16_S_GOTOFF_CALL, R_MIPS_GOTPC_CALL_HI16 },
> + { BFD_RELOC_MIPS_LO16_GOTOFF_CALL, R_MIPS_GOTPC_CALL_LO16 },
> + { BFD_RELOC_MIPS_AHI16_S_GOTOFF, R_MIPS_GOTPC_AHI16 },
> + { BFD_RELOC_MIPS_ALO16_GOTOFF, R_MIPS_GOTPC_ALO16 },
> + { BFD_RELOC_MIPS_AHI16_S_GOTOFF_CALL, R_MIPS_GOTPC_CALL_AHI16 },
> + { BFD_RELOC_MIPS_ALO16_GOTOFF_CALL, R_MIPS_GOTPC_CALL_ALO16 }
> };
>
> static const struct elf_reloc_map mips16_reloc_map[] =
> diff --git a/bfd/elfn32-mips.c b/bfd/elfn32-mips.c
> index 7e672200006..03e17dfda64 100644
> --- a/bfd/elfn32-mips.c
> +++ b/bfd/elfn32-mips.c
> @@ -868,6 +868,118 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
> 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 */
> +
> + HOWTO (R_MIPS_GOTPC_LO16, /* type */
> + 0, /* rightshift */
> + 4, /* size */
> + 16, /* bitsize */
> + true, /* pc_relative */
> + 0, /* bitpos */
> + complain_overflow_dont, /* complain_on_overflow */
> + _bfd_mips_elf_generic_reloc, /* special_function */
> + "R_MIPS_GOTPC_LO16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_CALL_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_CALL_HI16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_CALL_LO16, /* type */
> + 0, /* rightshift */
> + 4, /* size */
> + 16, /* bitsize */
> + true, /* pc_relative */
> + 0, /* bitpos */
> + complain_overflow_dont, /* complain_on_overflow */
> + _bfd_mips_elf_generic_reloc, /* special_function */
> + "R_MIPS_GOTPC_CALL_LO16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_AHI16, /* 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_AHI16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_ALO16, /* type */
> + 0, /* rightshift */
> + 4, /* size */
> + 16, /* bitsize */
> + true, /* pc_relative */
> + 0, /* bitpos */
> + complain_overflow_dont, /* complain_on_overflow */
> + _bfd_mips_elf_generic_reloc, /* special_function */
> + "R_MIPS_GOTPC_ALO16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_CALL_AHI16, /* 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_CALL_AHI16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_CALL_ALO16, /* type */
> + 0, /* rightshift */
> + 4, /* size */
> + 16, /* bitsize */
> + true, /* pc_relative */
> + 0, /* bitpos */
> + complain_overflow_dont, /* complain_on_overflow */
> + _bfd_mips_elf_generic_reloc, /* special_function */
> + "R_MIPS_GOTPC_CALL_ALO16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> };
>
> /* The relocation table used for SHT_RELA sections. */
> @@ -1650,6 +1762,118 @@ static reloc_howto_type elf_mips_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 */
> +
> + HOWTO (R_MIPS_GOTPC_LO16, /* type */
> + 0, /* rightshift */
> + 4, /* size */
> + 16, /* bitsize */
> + true, /* pc_relative */
> + 0, /* bitpos */
> + complain_overflow_dont, /* complain_on_overflow */
> + _bfd_mips_elf_generic_reloc, /* special_function */
> + "R_MIPS_GOTPC_LO16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_CALL_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_CALL_HI16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_CALL_LO16, /* type */
> + 0, /* rightshift */
> + 4, /* size */
> + 16, /* bitsize */
> + true, /* pc_relative */
> + 0, /* bitpos */
> + complain_overflow_dont, /* complain_on_overflow */
> + _bfd_mips_elf_generic_reloc, /* special_function */
> + "R_MIPS_GOTPC_CALL_LO16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_AHI16, /* 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_AHI16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_ALO16, /* type */
> + 0, /* rightshift */
> + 4, /* size */
> + 16, /* bitsize */
> + true, /* pc_relative */
> + 0, /* bitpos */
> + complain_overflow_dont, /* complain_on_overflow */
> + _bfd_mips_elf_generic_reloc, /* special_function */
> + "R_MIPS_GOTPC_ALO16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_CALL_AHI16, /* 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_CALL_AHI16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> + HOWTO (R_MIPS_GOTPC_CALL_ALO16, /* type */
> + 0, /* rightshift */
> + 4, /* size */
> + 16, /* bitsize */
> + true, /* pc_relative */
> + 0, /* bitpos */
> + complain_overflow_dont, /* complain_on_overflow */
> + _bfd_mips_elf_generic_reloc, /* special_function */
> + "R_MIPS_GOTPC_CALL_ALO16", /* name */
> + true, /* partial_inplace */
> + 0x0000ffff, /* src_mask */
> + 0x0000ffff, /* dst_mask */
> + true), /* pcrel_offset */
> +
> };
>
> static reloc_howto_type elf_mips16_howto_table_rel[] =
> @@ -3577,7 +3801,15 @@ static const struct elf_reloc_map mips_reloc_map[] =
> { BFD_RELOC_MIPS_18_PCREL_S3, R_MIPS_PC18_S3 },
> { BFD_RELOC_MIPS_19_PCREL_S2, R_MIPS_PC19_S2 },
> { BFD_RELOC_HI16_S_PCREL, R_MIPS_PCHI16 },
> - { BFD_RELOC_LO16_PCREL, R_MIPS_PCLO16 }
> + { BFD_RELOC_LO16_PCREL, R_MIPS_PCLO16 },
> + { BFD_RELOC_HI16_S_GOTOFF, R_MIPS_GOTPC_HI16 },
> + { BFD_RELOC_LO16_GOTOFF, R_MIPS_GOTPC_LO16 },
> + { BFD_RELOC_MIPS_HI16_S_GOTOFF_CALL, R_MIPS_GOTPC_CALL_HI16 },
> + { BFD_RELOC_MIPS_LO16_GOTOFF_CALL, R_MIPS_GOTPC_CALL_LO16 },
> + { BFD_RELOC_MIPS_AHI16_S_GOTOFF, R_MIPS_GOTPC_AHI16 },
> + { BFD_RELOC_MIPS_ALO16_GOTOFF, R_MIPS_GOTPC_ALO16 },
> + { BFD_RELOC_MIPS_AHI16_S_GOTOFF_CALL, R_MIPS_GOTPC_CALL_AHI16 },
> + { BFD_RELOC_MIPS_ALO16_GOTOFF_CALL, R_MIPS_GOTPC_CALL_ALO16 }
> };
>
> static const struct elf_reloc_map mips16_reloc_map[] =
> 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;
> }
>
> static inline bool
> call_hi16_reloc_p (unsigned int r_type)
> {
> - return r_type == R_MIPS_CALL_HI16 || r_type == R_MICROMIPS_CALL_HI16;
> + return r_type == R_MIPS_CALL_HI16
> + || r_type == R_MIPS_GOTPC_CALL_HI16
> + || r_type == R_MIPS_GOTPC_CALL_AHI16
> + || r_type == R_MICROMIPS_CALL_HI16;
> }
>
> static inline bool
> call_lo16_reloc_p (unsigned int r_type)
> {
> - return r_type == R_MIPS_CALL_LO16 || r_type == R_MICROMIPS_CALL_LO16;
> + return r_type == R_MIPS_CALL_LO16
> + || r_type == R_MIPS_GOTPC_CALL_LO16
> + || r_type == R_MIPS_GOTPC_CALL_ALO16
> + || r_type == R_MICROMIPS_CALL_LO16;
> }
>
> static inline bool
> @@ -5241,6 +5250,21 @@ mips_elf_highest (bfd_vma value ATTRIBUTE_UNUSED)
> return MINUS_ONE;
> #endif
> }
> +
> +/**/
> +static bfd_vma
> +mips_elf_16bit_align (bfd_vma value, bfd_vma p, bool hi)
> +{
> + bfd_vma value_lo = (value & 0xffff) + (p & 0xffff);
> + bfd_vma value_hi = (value >> 16) & 0xffff;
> + value_hi += mips_elf_high (value_lo);
> + value_lo &= 0xffff;
> + if (hi)
> + return value_hi;
> + else
> + return value_lo;
> +}
> +
>
> /* Create the .compact_rel section. */
>
> @@ -5888,6 +5912,10 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
> case R_MIPS_GOT_DISP:
> case R_MIPS_GOT_LO16:
> case R_MIPS_CALL_LO16:
> + case R_MIPS_GOTPC_LO16:
> + case R_MIPS_GOTPC_CALL_LO16:
> + case R_MIPS_GOTPC_ALO16:
> + case R_MIPS_GOTPC_CALL_ALO16:
> case R_MICROMIPS_CALL16:
> case R_MICROMIPS_GOT16:
> case R_MICROMIPS_GOT_PAGE:
> @@ -5905,6 +5933,8 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
> /* Fall through. */
> case R_MIPS_GOT_HI16:
> case R_MIPS_CALL_HI16:
> + case R_MIPS_GOTPC_HI16:
> + case R_MIPS_GOTPC_CALL_HI16:
> case R_MICROMIPS_GOT_HI16:
> case R_MICROMIPS_CALL_HI16:
> if (resolved_to_zero
> @@ -5952,6 +5982,14 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
> case R_MIPS_CALL_HI16:
> case R_MIPS_GOT_LO16:
> case R_MIPS_CALL_LO16:
> + case R_MIPS_GOTPC_HI16:
> + case R_MIPS_GOTPC_LO16:
> + case R_MIPS_GOTPC_CALL_HI16:
> + case R_MIPS_GOTPC_CALL_LO16:
> + case R_MIPS_GOTPC_AHI16:
> + case R_MIPS_GOTPC_ALO16:
> + case R_MIPS_GOTPC_CALL_AHI16:
> + case R_MIPS_GOTPC_CALL_ALO16:
> case R_MICROMIPS_CALL16:
> case R_MICROMIPS_GOT16:
> case R_MICROMIPS_GOT_DISP:
> @@ -6413,6 +6451,45 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
> value &= howto->dst_mask;
> break;
>
> + /* For r6 and pre-r6, we can use:
> + bal . + 8
> + lui $2,%gotpc_hi(sym) # or %gotpc_call_hi
> + addu $2,$2,$ra
> + lw $2,%gotpc_lo(sym) # or %gotpc_call_lo
> + In this case, the LO should +=4, and HI should -=4.
> +
> + For R6+, we can use
> + aluipc $2,%gotpc_ahi(sym) # or %gotpc_call_ahi
> + lw $2,%gotpc_alo(sym)($2) or %gotpc_call_alo
> + In this case, the HI is OK, while LO should +4 and add the page_offet */
> + case R_MIPS_GOTPC_HI16:
> + case R_MIPS_GOTPC_CALL_HI16:
> + value = mips_elf_high (addend + gp - p + g - 4);
> + value &= howto->dst_mask;
> + break;
> +
> + case R_MIPS_GOTPC_LO16:
> + case R_MIPS_GOTPC_CALL_LO16:
> + if (howto->partial_inplace)
> + addend = _bfd_mips_elf_sign_extend (addend, 16);
> + value = addend + gp - p + g + 4;
> + value &= howto->dst_mask;
> + break;
> +
> + case R_MIPS_GOTPC_AHI16:
> + case R_MIPS_GOTPC_CALL_AHI16:
> + value = mips_elf_16bit_align (addend + gp - p + g, p, true);
> + value &= howto->dst_mask;
> + break;
> +
> + case R_MIPS_GOTPC_ALO16:
> + case R_MIPS_GOTPC_CALL_ALO16:
> + if (howto->partial_inplace)
> + addend = _bfd_mips_elf_sign_extend (addend, 16);
> + value = mips_elf_16bit_align (addend + gp - p + g, p, false);
> + value &= howto->dst_mask;
> + break;
> +
> case R_MIPS_PCHI16:
> value = mips_elf_high (symbol + addend - p);
> value &= howto->dst_mask;
> @@ -8282,6 +8359,14 @@ mips_elf_add_lo16_rel_addend (bfd *abfd,
> lo16_type = R_MIPS16_LO16;
> else if (micromips_reloc_p (r_type))
> lo16_type = R_MICROMIPS_LO16;
> + else if (r_type == R_MIPS_GOTPC_HI16)
> + lo16_type = R_MIPS_GOTPC_LO16;
> + else if (r_type == R_MIPS_GOTPC_CALL_HI16)
> + lo16_type = R_MIPS_GOTPC_CALL_LO16;
> + else if (r_type == R_MIPS_GOTPC_AHI16)
> + lo16_type = R_MIPS_GOTPC_ALO16;
> + else if (r_type == R_MIPS_GOTPC_CALL_AHI16)
> + lo16_type = R_MIPS_GOTPC_CALL_ALO16;
> else if (r_type == R_MIPS_PCHI16)
> lo16_type = R_MIPS_PCLO16;
> else
> @@ -8742,6 +8827,10 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
> case R_MIPS_CALL16:
> case R_MIPS_CALL_HI16:
> case R_MIPS_CALL_LO16:
> + case R_MIPS_GOTPC_CALL_HI16:
> + case R_MIPS_GOTPC_CALL_LO16:
> + case R_MIPS_GOTPC_CALL_AHI16:
> + case R_MIPS_GOTPC_CALL_ALO16:
> case R_MIPS16_CALL16:
> case R_MICROMIPS_CALL16:
> case R_MICROMIPS_CALL_HI16:
> @@ -8751,6 +8840,8 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
>
> case R_MIPS_GOT16:
> case R_MIPS_GOT_LO16:
> + case R_MIPS_GOTPC_LO16:
> + case R_MIPS_GOTPC_ALO16:
> case R_MIPS_GOT_PAGE:
> case R_MIPS_GOT_DISP:
> case R_MIPS16_GOT16:
> @@ -8788,6 +8879,8 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
>
> /* Fall through. */
> case R_MIPS_GOT_HI16:
> + case R_MIPS_GOTPC_HI16:
> + case R_MIPS_GOTPC_AHI16:
> case R_MIPS_GOT_OFST:
> case R_MIPS_TLS_GOTTPREL:
> case R_MIPS_TLS_GD:
> @@ -8958,6 +9051,10 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
>
> case R_MIPS_CALL_HI16:
> case R_MIPS_CALL_LO16:
> + case R_MIPS_GOTPC_CALL_HI16:
> + case R_MIPS_GOTPC_CALL_LO16:
> + case R_MIPS_GOTPC_CALL_AHI16:
> + case R_MIPS_GOTPC_CALL_ALO16:
> case R_MICROMIPS_CALL_HI16:
> case R_MICROMIPS_CALL_LO16:
> if (h != NULL)
> @@ -8983,6 +9080,10 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
> case R_MIPS_GOT16:
> case R_MIPS_GOT_HI16:
> case R_MIPS_GOT_LO16:
> + case R_MIPS_GOTPC_HI16:
> + case R_MIPS_GOTPC_LO16:
> + case R_MIPS_GOTPC_AHI16:
> + case R_MIPS_GOTPC_ALO16:
> case R_MICROMIPS_GOT16:
> case R_MICROMIPS_GOT_HI16:
> case R_MICROMIPS_GOT_LO16:
> diff --git a/bfd/libbfd.h b/bfd/libbfd.h
> index ebd4f24149b..53604a094f6 100644
> --- a/bfd/libbfd.h
> +++ b/bfd/libbfd.h
> @@ -1272,6 +1272,15 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
> "BFD_RELOC_MIPS_26_PCREL_S2",
> "BFD_RELOC_MIPS_18_PCREL_S3",
> "BFD_RELOC_MIPS_19_PCREL_S2",
> + "BFD_RELOC_MIPS_LO16_GOTOFF_CALL",
> + "BFD_RELOC_MIPS_HI16_GOTOFF_CALL",
> + "BFD_RELOC_MIPS_HI16_S_GOTOFF_CALL",
> + "BFD_RELOC_MIPS_ALO16_GOTOFF",
> + "BFD_RELOC_MIPS_AHI16_GOTOFF",
> + "BFD_RELOC_MIPS_AHI16_S_GOTOFF",
> + "BFD_RELOC_MIPS_ALO16_GOTOFF_CALL",
> + "BFD_RELOC_MIPS_AHI16_GOTOFF_CALL",
> + "BFD_RELOC_MIPS_AHI16_S_GOTOFF_CALL",
> "BFD_RELOC_MICROMIPS_GPREL16",
> "BFD_RELOC_MICROMIPS_HI16",
> "BFD_RELOC_MICROMIPS_HI16_S",
> diff --git a/bfd/reloc.c b/bfd/reloc.c
> index e74cbd75e96..85e4081ccd6 100644
> --- a/bfd/reloc.c
> +++ b/bfd/reloc.c
> @@ -2040,6 +2040,24 @@ ENUMX
> BFD_RELOC_MIPS_18_PCREL_S3
> ENUMX
> BFD_RELOC_MIPS_19_PCREL_S2
> +ENUMX
> + BFD_RELOC_LO16_GOTOFF_CALL
> +ENUMX
> + BFD_RELOC_HI16_GOTOFF_CALL
> +ENUMX
> + BFD_RELOC_HI16_S_GOTOFF_CALL
> +ENUMX
> + BFD_RELOC_ALO16_GOTOFF
> +ENUMX
> + BFD_RELOC_AHI16_GOTOFF
> +ENUMX
> + BFD_RELOC_AHI16_S_GOTOFF
> +ENUMX
> + BFD_RELOC_ALO16_GOTOFF_CALL
> +ENUMX
> + BFD_RELOC_AHI16_GOTOFF_CALL
> +ENUMX
> + BFD_RELOC_AHI16_S_GOTOFF_CALL
> ENUMDOC
> MIPS PC-relative relocations.
>
> diff --git a/elfcpp/mips.h b/elfcpp/mips.h
> index e8a8e2458e9..33adb67107b 100644
> --- a/elfcpp/mips.h
> +++ b/elfcpp/mips.h
> @@ -104,6 +104,14 @@ enum
> R_MIPS_PC19_S2 = 63,
> R_MIPS_PCHI16 = 64,
> R_MIPS_PCLO16 = 65,
> + R_MIPS_GOTPC_HI16 = 66,
> + R_MIPS_GOTPC_LO16 = 67,
> + R_MIPS_GOTPC_CALL_HI16 = 68,
> + R_MIPS_GOTPC_CALL_LO16 = 69,
> + R_MIPS_GOTPC_HI16 = 70,
> + R_MIPS_GOTPC_LO16 = 71,
> + R_MIPS_GOTPC_CALL_HI16 = 72,
> + R_MIPS_GOTPC_CALL_LO16 = 73,
> // These relocs are used for the mips16.
> R_MIPS16_26 = 100,
> R_MIPS16_GPREL = 101,
> diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
> index 43c12de2c8a..1ec2feac072 100644
> --- a/gas/config/tc-mips.c
> +++ b/gas/config/tc-mips.c
> @@ -4372,6 +4372,14 @@ limited_pcrel_reloc_p (bfd_reloc_code_real_type reloc)
> case BFD_RELOC_32_PCREL:
> case BFD_RELOC_HI16_S_PCREL:
> case BFD_RELOC_LO16_PCREL:
> + case BFD_RELOC_HI16_S_GOTOFF:
> + case BFD_RELOC_LO16_GOTOFF:
> + case BFD_RELOC_MIPS_LO16_GOTOFF_CALL:
> + case BFD_RELOC_MIPS_HI16_S_GOTOFF_CALL:
> + case BFD_RELOC_MIPS_AHI16_S_GOTOFF:
> + case BFD_RELOC_MIPS_ALO16_GOTOFF:
> + case BFD_RELOC_MIPS_ALO16_GOTOFF_CALL:
> + case BFD_RELOC_MIPS_AHI16_S_GOTOFF_CALL:
> return HAVE_64BIT_ADDRESSES;
>
> default:
> @@ -7432,6 +7440,8 @@ calculate_reloc (bfd_reloc_code_real_type reloc, offsetT operand,
>
> case BFD_RELOC_HI16_S:
> case BFD_RELOC_HI16_S_PCREL:
> + case BFD_RELOC_HI16_S_GOTOFF:
> + case BFD_RELOC_MIPS_AHI16_S_GOTOFF:
> case BFD_RELOC_MICROMIPS_HI16_S:
> case BFD_RELOC_MIPS16_HI16_S:
> *result = ((operand + 0x8000) >> 16) & 0xffff;
> @@ -7445,6 +7455,10 @@ calculate_reloc (bfd_reloc_code_real_type reloc, offsetT operand,
>
> case BFD_RELOC_LO16:
> case BFD_RELOC_LO16_PCREL:
> + case BFD_RELOC_LO16_GOTOFF:
> + case BFD_RELOC_MIPS_LO16_GOTOFF_CALL:
> + case BFD_RELOC_MIPS_ALO16_GOTOFF:
> + case BFD_RELOC_MIPS_ALO16_GOTOFF_CALL:
> case BFD_RELOC_MICROMIPS_LO16:
> case BFD_RELOC_MIPS16_LO16:
> *result = operand & 0xffff;
> @@ -7507,6 +7521,22 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
> as_warn (_("wrong size instruction in a %u-bit branch delay slot"),
> (prev_pinfo2 & INSN2_BRANCH_DELAY_16BIT) != 0 ? 16 : 32);
>
> + if (!ISA_IS_R6 (mips_opts.isa))
> + switch (*reloc_type)
> + {
> + default:
> + break;
> +
> + case BFD_RELOC_MIPS_ALO16_GOTOFF:
> + case BFD_RELOC_MIPS_AHI16_GOTOFF:
> + case BFD_RELOC_MIPS_AHI16_S_GOTOFF:
> + case BFD_RELOC_MIPS_ALO16_GOTOFF_CALL:
> + case BFD_RELOC_MIPS_AHI16_GOTOFF_CALL:
> + case BFD_RELOC_MIPS_AHI16_S_GOTOFF_CALL:
> + as_fatal (_("ALUIPC style GOTPC cannot work with pre-R6."));
> + break;
> + }
> +
> if (address_expr == NULL)
> ip->complete_p = 1;
> else if (reloc_type[0] <= BFD_RELOC_UNUSED
> @@ -14583,7 +14613,15 @@ static const struct percent_op_match mips_percent_op[] =
> {"%gottprel", BFD_RELOC_MIPS_TLS_GOTTPREL},
> {"%hi", BFD_RELOC_HI16_S},
> {"%pcrel_hi", BFD_RELOC_HI16_S_PCREL},
> - {"%pcrel_lo", BFD_RELOC_LO16_PCREL}
> + {"%pcrel_lo", BFD_RELOC_LO16_PCREL},
> + {"%gotpc_hi", BFD_RELOC_HI16_S_GOTOFF},
> + {"%gotpc_lo", BFD_RELOC_LO16_GOTOFF},
> + {"%gotpc_call_hi", BFD_RELOC_MIPS_HI16_S_GOTOFF_CALL},
> + {"%gotpc_call_lo", BFD_RELOC_MIPS_LO16_GOTOFF_CALL},
> + {"%gotpc_ahi", BFD_RELOC_MIPS_AHI16_S_GOTOFF},
> + {"%gotpc_alo", BFD_RELOC_MIPS_ALO16_GOTOFF},
> + {"%gotpc_call_ahi", BFD_RELOC_MIPS_AHI16_S_GOTOFF_CALL},
> + {"%gotpc_call_alo", BFD_RELOC_MIPS_ALO16_GOTOFF_CALL}
> };
>
> static const struct percent_op_match mips16_percent_op[] =
> @@ -15541,6 +15579,14 @@ mips_force_relocation (fixS *fixp)
> || fixp->fx_r_type == BFD_RELOC_MIPS_26_PCREL_S2
> || fixp->fx_r_type == BFD_RELOC_MIPS_18_PCREL_S3
> || fixp->fx_r_type == BFD_RELOC_MIPS_19_PCREL_S2
> + || fixp->fx_r_type == BFD_RELOC_HI16_S_GOTOFF
> + || fixp->fx_r_type == BFD_RELOC_LO16_GOTOFF
> + || fixp->fx_r_type == BFD_RELOC_MIPS_LO16_GOTOFF_CALL
> + || fixp->fx_r_type == BFD_RELOC_MIPS_HI16_S_GOTOFF_CALL
> + || fixp->fx_r_type == BFD_RELOC_MIPS_AHI16_S_GOTOFF
> + || fixp->fx_r_type == BFD_RELOC_MIPS_ALO16_GOTOFF
> + || fixp->fx_r_type == BFD_RELOC_MIPS_ALO16_GOTOFF_CALL
> + || fixp->fx_r_type == BFD_RELOC_MIPS_AHI16_S_GOTOFF_CALL
> || fixp->fx_r_type == BFD_RELOC_HI16_S_PCREL
> || fixp->fx_r_type == BFD_RELOC_LO16_PCREL))
> return 1;
> @@ -15822,6 +15868,14 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
> case BFD_RELOC_MIPS_19_PCREL_S2:
> case BFD_RELOC_HI16_S_PCREL:
> case BFD_RELOC_LO16_PCREL:
> + case BFD_RELOC_HI16_S_GOTOFF:
> + case BFD_RELOC_LO16_GOTOFF:
> + case BFD_RELOC_MIPS_HI16_S_GOTOFF_CALL:
> + case BFD_RELOC_MIPS_LO16_GOTOFF_CALL:
> + case BFD_RELOC_MIPS_AHI16_S_GOTOFF:
> + case BFD_RELOC_MIPS_ALO16_GOTOFF:
> + case BFD_RELOC_MIPS_AHI16_S_GOTOFF_CALL:
> + case BFD_RELOC_MIPS_ALO16_GOTOFF_CALL:
> break;
>
> case BFD_RELOC_32:
> @@ -15965,6 +16019,14 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
> case BFD_RELOC_MIPS_GOT_LO16:
> case BFD_RELOC_MIPS_CALL_HI16:
> case BFD_RELOC_MIPS_CALL_LO16:
> + case BFD_RELOC_HI16_S_GOTOFF:
> + case BFD_RELOC_LO16_GOTOFF:
> + case BFD_RELOC_MIPS_HI16_S_GOTOFF_CALL:
> + case BFD_RELOC_MIPS_LO16_GOTOFF_CALL:
> + case BFD_RELOC_MIPS_AHI16_S_GOTOFF:
> + case BFD_RELOC_MIPS_ALO16_GOTOFF:
> + case BFD_RELOC_MIPS_AHI16_S_GOTOFF_CALL:
> + case BFD_RELOC_MIPS_ALO16_GOTOFF_CALL:
> case BFD_RELOC_HI16_S_PCREL:
> case BFD_RELOC_LO16_PCREL:
> case BFD_RELOC_MIPS16_GPREL:
> @@ -18386,6 +18448,14 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
> || fixp->fx_r_type == BFD_RELOC_MIPS_26_PCREL_S2
> || fixp->fx_r_type == BFD_RELOC_MIPS_18_PCREL_S3
> || fixp->fx_r_type == BFD_RELOC_MIPS_19_PCREL_S2
> + || fixp->fx_r_type == BFD_RELOC_HI16_S_GOTOFF
> + || fixp->fx_r_type == BFD_RELOC_LO16_GOTOFF
> + || fixp->fx_r_type == BFD_RELOC_MIPS_LO16_GOTOFF_CALL
> + || fixp->fx_r_type == BFD_RELOC_MIPS_HI16_S_GOTOFF_CALL
> + || fixp->fx_r_type == BFD_RELOC_MIPS_AHI16_S_GOTOFF
> + || fixp->fx_r_type == BFD_RELOC_MIPS_ALO16_GOTOFF
> + || fixp->fx_r_type == BFD_RELOC_MIPS_ALO16_GOTOFF_CALL
> + || fixp->fx_r_type == BFD_RELOC_MIPS_AHI16_S_GOTOFF_CALL
> || fixp->fx_r_type == BFD_RELOC_HI16_S_PCREL
> || fixp->fx_r_type == BFD_RELOC_LO16_PCREL);
>
> diff --git a/gas/testsuite/gas/mips/gotpc-aluipc-32.s b/gas/testsuite/gas/mips/gotpc-aluipc-32.s
> new file mode 100644
> index 00000000000..877193313a1
> --- /dev/null
> +++ b/gas/testsuite/gas/mips/gotpc-aluipc-32.s
> @@ -0,0 +1,51 @@
> + .file 1 "nn.c"
> + .section .mdebug.abi32
> + .previous
> + .nan 2008
> + .module fp=xx
> + .module nooddspreg
> + .module arch=mips32r6
> + .abicalls
> + .text
> + .section .rodata.str1.4,"aMS",@progbits,1
> + .align 2
> +$LC0:
> + .ascii "XXXX\000"
> + .section .text.startup,"ax",@progbits
> + .align 2
> + .globl main
> + .set nomips16
> + .ent main
> + .type main, @function
> +main:
> + .frame $sp,32,$31 # vars= 0, regs= 1/0, args= 16, gp= 8
> + .mask 0x80000000,-4
> + .fmask 0x00000000,0
> + .set noreorder
> + .cpload $25
> + .set nomacro
> + addiu $sp,$sp,-32
> + sw $31,28($sp)
> +
> + aluipc $4,%gotpc_ahi($LC0)
> + lw $4,%gotpc_alo($LC0)($4)
> +
> + aluipc $25,%gotpc_call_ahi(puts)
> + lw $25,%gotpc_call_alo(puts)($25)
> +
> + .cprestore 16
> + .reloc 1f,R_MIPS_JALR,puts
> +1: jalr $25
> + nop
> +
> + lw $31,28($sp)
> + move $2,$0
> + jr $31
> + addiu $sp,$sp,32
> +
> + .set macro
> + .set reorder
> + .end main
> + .size main, .-main
> + .ident "GCC: (Debian 12.2.0-14) 12.2.0"
> + .section .note.GNU-stack,"",@progbits
> diff --git a/gas/testsuite/gas/mips/gotpc-aluipc-64.s b/gas/testsuite/gas/mips/gotpc-aluipc-64.s
> new file mode 100644
> index 00000000000..234be37b6fe
> --- /dev/null
> +++ b/gas/testsuite/gas/mips/gotpc-aluipc-64.s
> @@ -0,0 +1,50 @@
> + .file 1 "nn.c"
> + .section .mdebug.abi64
> + .previous
> + .abicalls
> + .text
> + .section .rodata.str1.8,"aMS",@progbits,1
> + .align 3
> +.LC0:
> + .ascii "XXXX\000"
> + .section .text.startup,"ax",@progbits
> + .align 2
> + .align 3
> + .globl main
> + .set nomips16
> + .ent main
> + .type main, @function
> +main:
> + .frame $sp,16,$31 # vars= 0, regs= 2/0, args= 0, gp= 0
> + .mask 0x90000000,-8
> + .fmask 0x00000000,0
> + .set noreorder
> + .set nomacro
> + daddiu $sp,$sp,-16
> + sd $28,0($sp)
> + lui $28,%hi(%neg(%gp_rel(main)))
> + daddu $28,$28,$25
> + sd $31,8($sp)
> + daddiu $28,$28,%lo(%neg(%gp_rel(main)))
> +
> + aluipc $4,%gotpc_ahi(.LC0)
> + ld $4,%gotpc_alo(.LC0)($4)
> +
> + aluipc $25,%gotpc_call_ahi(puts)
> + ld $25,%gotpc_call_alo(puts)($25)
> +
> + .reloc 1f,R_MIPS_JALR,puts
> +1: jalr $25
> + nop
> +
> + ld $31,8($sp)
> + ld $28,0($sp)
> + move $2,$0
> + jr $31
> + daddiu $sp,$sp,16
> +
> + .set macro
> + .set reorder
> + .end main
> + .size main, .-main
> + .section .note.GNU-stack,"",@progbits
> diff --git a/gas/testsuite/gas/mips/gotpc-aluipc-n32.d b/gas/testsuite/gas/mips/gotpc-aluipc-n32.d
> new file mode 100644
> index 00000000000..41bc6d474d7
> --- /dev/null
> +++ b/gas/testsuite/gas/mips/gotpc-aluipc-n32.d
> @@ -0,0 +1,17 @@
> +#objdump: -dr --prefix-addresses --show-raw-insn
> +#name: R_MIPS_GOTPC support (NewABI, ALUIPC, N32)
> +#source: gotpc-aluipc-64.s
> +#as: -n32 -mips64r6
> +
> +.*: +file format .*mips.*
> +
> +Disassembly of section \.text\.startup:
> +#...
> +.*R_MIPS_GOTPC_AHI16 \.rodata\.str1\.8
> +#...
> +.*R_MIPS_GOTPC_ALO16 \.rodata\.str1\.8
> +#...
> +.*R_MIPS_GOTPC_CALL_AHI16 puts
> +#...
> +.*R_MIPS_GOTPC_CALL_ALO16 puts
> +#pass
> diff --git a/gas/testsuite/gas/mips/gotpc-aluipc-n64.d b/gas/testsuite/gas/mips/gotpc-aluipc-n64.d
> new file mode 100644
> index 00000000000..0561040ef09
> --- /dev/null
> +++ b/gas/testsuite/gas/mips/gotpc-aluipc-n64.d
> @@ -0,0 +1,25 @@
> +#objdump: -dr --prefix-addresses --show-raw-insn
> +#name: R_MIPS_GOTPC support (NewABI, ALUIPC, N64)
> +#source: gotpc-aluipc-64.s
> +#as: -64 -mips64r6
> +
> +.*: +file format .*mips.*
> +
> +Disassembly of section \.text\.startup:
> +#...
> +.*R_MIPS_GOTPC_AHI16 \.LC0
> +.*R_MIPS_NONE.*
> +.*R_MIPS_NONE.*
> +#...
> +.*R_MIPS_GOTPC_ALO16 \.LC0
> +.*R_MIPS_NONE.*
> +.*R_MIPS_NONE.*
> +#...
> +.*R_MIPS_GOTPC_CALL_AHI16 puts
> +.*R_MIPS_NONE.*
> +.*R_MIPS_NONE.*
> +#...
> +.*R_MIPS_GOTPC_CALL_ALO16 puts
> +.*R_MIPS_NONE.*
> +.*R_MIPS_NONE.*
> +#pass
> diff --git a/gas/testsuite/gas/mips/gotpc-aluipc-o32.d b/gas/testsuite/gas/mips/gotpc-aluipc-o32.d
> new file mode 100644
> index 00000000000..4079c8de661
> --- /dev/null
> +++ b/gas/testsuite/gas/mips/gotpc-aluipc-o32.d
> @@ -0,0 +1,17 @@
> +#objdump: -dr --prefix-addresses --show-raw-insn
> +#name: R_MIPS_GOTPC support (NewABI, ALUIPC, O32)
Sorry a typo, here. V3 will be sent.
> +#source: gotpc-aluipc-32.s
> +#as: -32 -mips32r6
> +
> +.*: +file format .*mips.*
> +
> +Disassembly of section \.text\.startup:
> +#...
> +.*R_MIPS_GOTPC_AHI16 \.rodata\.str1\.4
> +#...
> +.*R_MIPS_GOTPC_ALO16 \.rodata\.str1\.4
> +#...
> +.*R_MIPS_GOTPC_CALL_AHI16 puts
> +#...
> +.*R_MIPS_GOTPC_CALL_ALO16 puts
> +#pass
> diff --git a/gas/testsuite/gas/mips/gotpc-bal-32.s b/gas/testsuite/gas/mips/gotpc-bal-32.s
> new file mode 100644
> index 00000000000..841a13dbf87
> --- /dev/null
> +++ b/gas/testsuite/gas/mips/gotpc-bal-32.s
> @@ -0,0 +1,55 @@
> + .file 1 "nn.c"
> + .section .mdebug.abi32
> + .previous
> + .nan 2008
> + .module fp=xx
> + .module nooddspreg
> + .module arch=mips32r6
> + .abicalls
> + .text
> + .section .rodata.str1.4,"aMS",@progbits,1
> + .align 2
> +$LC0:
> + .ascii "XXXX\000"
> + .section .text.startup,"ax",@progbits
> + .align 2
> + .globl main
> + .set nomips16
> + .ent main
> + .type main, @function
> +main:
> + .frame $sp,32,$31 # vars= 0, regs= 1/0, args= 16, gp= 8
> + .mask 0x80000000,-4
> + .fmask 0x00000000,0
> + .set noreorder
> + .cpload $25
> + .set nomacro
> + addiu $sp,$sp,-32
> + sw $31,28($sp)
> +
> + bal . + 8
> + lui $4,%gotpc_hi($LC0)
> + addu $4,$4,$31
> + lw $4,%gotpc_lo($LC0)($4)
> +
> + bal . + 8
> + lui $25,%gotpc_call_hi(puts)
> + addu $25,$25,$31
> + lw $25,%gotpc_call_lo(puts)($25)
> +
> + .cprestore 16
> + .reloc 1f,R_MIPS_JALR,puts
> +1: jalr $25
> + nop
> +
> + lw $31,28($sp)
> + move $2,$0
> + jr $31
> + addiu $sp,$sp,32
> +
> + .set macro
> + .set reorder
> + .end main
> + .size main, .-main
> + .ident "GCC: (Debian 12.2.0-14) 12.2.0"
> + .section .note.GNU-stack,"",@progbits
> diff --git a/gas/testsuite/gas/mips/gotpc-bal-64.s b/gas/testsuite/gas/mips/gotpc-bal-64.s
> new file mode 100644
> index 00000000000..c97e6b87af9
> --- /dev/null
> +++ b/gas/testsuite/gas/mips/gotpc-bal-64.s
> @@ -0,0 +1,54 @@
> + .file 1 "nn.c"
> + .section .mdebug.abi64
> + .previous
> + .abicalls
> + .text
> + .section .rodata.str1.8,"aMS",@progbits,1
> + .align 3
> +.LC0:
> + .ascii "XXXX\000"
> + .section .text.startup,"ax",@progbits
> + .align 2
> + .align 3
> + .globl main
> + .set nomips16
> + .ent main
> + .type main, @function
> +main:
> + .frame $sp,16,$31 # vars= 0, regs= 2/0, args= 0, gp= 0
> + .mask 0x90000000,-8
> + .fmask 0x00000000,0
> + .set noreorder
> + .set nomacro
> + daddiu $sp,$sp,-16
> + sd $28,0($sp)
> + lui $28,%hi(%neg(%gp_rel(main)))
> + daddu $28,$28,$25
> + sd $31,8($sp)
> + daddiu $28,$28,%lo(%neg(%gp_rel(main)))
> +
> + bal . + 8
> + lui $4,%gotpc_hi(.LC0)
> + daddu $4,$4,$31
> + ld $4,%gotpc_lo(.LC0)($4)
> +
> + bal . + 8
> + lui $25,%gotpc_call_hi(puts)
> + daddu $25,$25,$31
> + ld $25,%gotpc_call_lo(puts)($25)
> +
> + .reloc 1f,R_MIPS_JALR,puts
> +1: jalr $25
> + nop
> +
> + ld $31,8($sp)
> + ld $28,0($sp)
> + move $2,$0
> + jr $31
> + daddiu $sp,$sp,16
> +
> + .set macro
> + .set reorder
> + .end main
> + .size main, .-main
> + .section .note.GNU-stack,"",@progbits
> diff --git a/gas/testsuite/gas/mips/gotpc-bal-n32.d b/gas/testsuite/gas/mips/gotpc-bal-n32.d
> new file mode 100644
> index 00000000000..ec412020dc7
> --- /dev/null
> +++ b/gas/testsuite/gas/mips/gotpc-bal-n32.d
> @@ -0,0 +1,17 @@
> +#objdump: -dr --prefix-addresses --show-raw-insn
> +#name: R_MIPS_GOTPC support (NewABI, BAL, N32)
> +#source: gotpc-bal-64.s
> +#as: -n32 -march=from-abi
> +
> +.*: +file format .*mips.*
> +
> +Disassembly of section \.text\.startup:
> +#...
> +.*R_MIPS_GOTPC_HI16 \.rodata\.str1\.8
> +#...
> +.*R_MIPS_GOTPC_LO16 \.rodata\.str1\.8
> +#...
> +.*R_MIPS_GOTPC_CALL_HI16 puts
> +#...
> +.*R_MIPS_GOTPC_CALL_LO16 puts
> +#pass
> diff --git a/gas/testsuite/gas/mips/gotpc-bal-n64.d b/gas/testsuite/gas/mips/gotpc-bal-n64.d
> new file mode 100644
> index 00000000000..60b9f020f50
> --- /dev/null
> +++ b/gas/testsuite/gas/mips/gotpc-bal-n64.d
> @@ -0,0 +1,25 @@
> +#objdump: -dr --prefix-addresses --show-raw-insn
> +#name: R_MIPS_GOTPC support (NewABI, BAL, N64)
> +#source: gotpc-bal-64.s
> +#as: -64 -march=from-abi
> +
> +.*: +file format .*mips.*
> +
> +Disassembly of section \.text\.startup:
> +#...
> +.*R_MIPS_GOTPC_HI16 \.rodata\.str1\.8
> +.*R_MIPS_NONE.*
> +.*R_MIPS_NONE.*
> +#...
> +.*R_MIPS_GOTPC_LO16 \.rodata\.str1\.8
> +.*R_MIPS_NONE.*
> +.*R_MIPS_NONE.*
> +#...
> +.*R_MIPS_GOTPC_CALL_HI16 puts
> +.*R_MIPS_NONE.*
> +.*R_MIPS_NONE.*
> +#...
> +.*R_MIPS_GOTPC_CALL_LO16 puts
> +.*R_MIPS_NONE.*
> +.*R_MIPS_NONE.*
> +#pass
> diff --git a/gas/testsuite/gas/mips/gotpc-bal-o32.d b/gas/testsuite/gas/mips/gotpc-bal-o32.d
> new file mode 100644
> index 00000000000..b4caff9bbe9
> --- /dev/null
> +++ b/gas/testsuite/gas/mips/gotpc-bal-o32.d
> @@ -0,0 +1,17 @@
> +#objdump: -dr --prefix-addresses --show-raw-insn
> +#name: R_MIPS_GOTPC support (BAL, O32)
> +#source: gotpc-bal-32.s
> +#as: -32 -march=from-abi
> +
> +.*: +file format .*mips.*
> +
> +Disassembly of section \.text\.startup:
> +#...
> +.*R_MIPS_GOTPC_HI16 \.rodata\.str1\.4
> +#...
> +.*R_MIPS_GOTPC_LO16 \.rodata\.str1\.4
> +#...
> +.*R_MIPS_GOTPC_CALL_HI16 puts
> +#...
> +.*R_MIPS_GOTPC_CALL_LO16 puts
> +#pass
> diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp
> index 2ddbf0c768d..619d04b3bd5 100644
> --- a/gas/testsuite/gas/mips/mips.exp
> +++ b/gas/testsuite/gas/mips/mips.exp
> @@ -1210,7 +1210,15 @@ if { [istarget mips*-*-vxworks*] } {
> run_dump_test "elf-rel-xgot-n32"
> run_dump_test "elf-rel-got-n64"
> run_dump_test "elf-rel-xgot-n64"
> +
> + run_dump_test "gotpc-bal-n64"
> + run_dump_test "gotpc-bal-n32"
> + run_dump_test "gotpc-aluipc-n64"
> + run_dump_test "gotpc-aluipc-n32"
> }
> + run_dump_test "gotpc-bal-o32"
> + run_dump_test "gotpc-aluipc-o32"
> +
> run_dump_test "elf-rel17"
> if $has_newabi {
> run_dump_test "elf-rel18"
> diff --git a/include/elf/mips.h b/include/elf/mips.h
> index 686d5500e02..23e95fe0c45 100644
> --- a/include/elf/mips.h
> +++ b/include/elf/mips.h
> @@ -98,7 +98,15 @@ START_RELOC_NUMBERS (elf_mips_reloc_type)
> RELOC_NUMBER (R_MIPS_PC19_S2, 63)
> RELOC_NUMBER (R_MIPS_PCHI16, 64)
> RELOC_NUMBER (R_MIPS_PCLO16, 65)
> - FAKE_RELOC (R_MIPS_max, 66)
> + RELOC_NUMBER (R_MIPS_GOTPC_HI16, 66)
> + RELOC_NUMBER (R_MIPS_GOTPC_LO16, 67)
> + RELOC_NUMBER (R_MIPS_GOTPC_CALL_HI16, 68)
> + RELOC_NUMBER (R_MIPS_GOTPC_CALL_LO16, 69)
> + RELOC_NUMBER (R_MIPS_GOTPC_AHI16, 70)
> + RELOC_NUMBER (R_MIPS_GOTPC_ALO16, 71)
> + RELOC_NUMBER (R_MIPS_GOTPC_CALL_AHI16, 72)
> + RELOC_NUMBER (R_MIPS_GOTPC_CALL_ALO16, 73)
> + FAKE_RELOC (R_MIPS_max, 74)
> /* These relocs are used for the mips16. */
> FAKE_RELOC (R_MIPS16_min, 100)
> RELOC_NUMBER (R_MIPS16_26, 100)
> --
> 2.39.2
>
next prev parent reply other threads:[~2024-02-02 6:42 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-02 6:39 YunQiang Su
2024-02-02 6:42 ` YunQiang Su [this message]
-- strict thread matches above, loose matches on Subject: below --
2024-01-31 8:32 [PATCH] MIPS: support " YunQiang Su
2024-01-31 9:24 ` Xi Ruoyao
2024-02-02 1:25 ` YunQiang Su
2024-02-05 11:48 ` Nick Clifton
2024-02-05 12:59 ` Maciej W. Rozycki
2024-02-06 16:52 ` YunQiang Su
2024-02-06 19:47 ` Maciej W. Rozycki
2024-02-25 16:00 ` YunQiang Su
2024-03-01 17:38 ` Maciej W. Rozycki
2024-03-15 13:44 ` YunQiang Su
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAKcpw6XMKuyn4SaFpd+t79meV0Cz8=1oUeEFEq5RaycbUTYTcA@mail.gmail.com' \
--to=syq@gcc.gnu.org \
--cc=binutils@sourceware.org \
--cc=macro@orcam.me.uk \
--cc=nickc@redhat.com \
--cc=xry111@xry111.site \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).