From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-oi1-f180.google.com (mail-oi1-f180.google.com [209.85.167.180]) by sourceware.org (Postfix) with ESMTPS id 268473858D33 for ; Fri, 2 Feb 2024 06:42:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 268473858D33 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=gcc.gnu.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 268473858D33 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=209.85.167.180 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1706856166; cv=none; b=Xnq/Z7DGD1haLAZXFbf7jUEkhGmOFKCf1fjhOKPOx3VBehRs3qTypDMg+MA/BJJk9xrb9o4Q0O7owQgrnnw1NPup6HfxOHjE9VahBzaLQvlewqtFjaMBHuA+mXFH0pkk12Wp8E1LxlI5iFD+S03/omOYTejOBqB6hFocAiFfgRw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1706856166; c=relaxed/simple; bh=pGAKlBI2juv4j5Wb/OOt7yIr4VtosBIG2E1xIWVomlc=; h=MIME-Version:From:Date:Message-ID:Subject:To; b=s5fESXNejC9grjt42tS49DHbjhldNvdAkzvW9EtppHOe3WJGptME9vD7pfmFRuFX+yUDb7+GlAYXe1pTOVlqtg2W6Vrh3GtTBG1VPDUbiemPH0/r5/TsWXqC1yqCK1a4xYJMi9tYtikJOQUjb1NJLbkok7iKGLfnIsojmt2grw8= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-oi1-f180.google.com with SMTP id 5614622812f47-3bb9d54575cso1149579b6e.2 for ; Thu, 01 Feb 2024 22:42:41 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706856160; x=1707460960; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=LnjjLEG9Kbq8dEIf95SipHGX7U1SOk1/UAGUVrHzO8Y=; b=ay4z2kon4ozyxnnzAAQliScuV5I6rbuhmCAXX33CpwqoPZOkL0LWcJglWfCNgo4F73 RTLOWq0ztN5X4k0ha9ZBwrvBM+3DdGxOyviJGhgcxOe7P0MHgzOhRjFtZ7XYv55vB18h nZo+txFnGNtZhz6ldq9aSrYn47wjIXHQfhXw25kESs/tREM1LcDTrDK562deZ1O+VQc5 ZYmOeRLsRewRvLnTcJon70JrPZRGTphXeieuYJGMVyPAxyUjF9afphkDIvmBzM8+ByZF xNgqeBAxWj03UsoaNVIcbLwO3G992VIGxdURCsAgToRuES6ANvpoRD/G5GthsS2kRf/d OOCw== X-Gm-Message-State: AOJu0YxvhFRrFnKmnILumBsQ2Q8dQaoGcsmfAzH1OGpQSojjb2ApNlXy H18bp773sdGuAFsPoQ+hzKQrNDYenrnR7zubta3tPflSQnSSpUayW38MaP3zeso= X-Google-Smtp-Source: AGHT+IFQx300301gIgASrsMsl0vSoQEQIcQFaYpGP0K5cYCul6hf9p7rYWvCXyaP8t8EWLpjO+BzGQ== X-Received: by 2002:a05:6808:209c:b0:3be:3cb3:8231 with SMTP id s28-20020a056808209c00b003be3cb38231mr1785671oiw.26.1706856159936; Thu, 01 Feb 2024 22:42:39 -0800 (PST) Received: from mail-pf1-f182.google.com (mail-pf1-f182.google.com. [209.85.210.182]) by smtp.gmail.com with ESMTPSA id r18-20020aa78452000000b006ddc77dc4fasm861149pfn.11.2024.02.01.22.42.39 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 01 Feb 2024 22:42:39 -0800 (PST) Received: by mail-pf1-f182.google.com with SMTP id d2e1a72fcca58-6dddf4fc85dso1380685b3a.0 for ; Thu, 01 Feb 2024 22:42:39 -0800 (PST) X-Received: by 2002:a05:6a20:244b:b0:19e:4aae:644b with SMTP id t11-20020a056a20244b00b0019e4aae644bmr1262225pzc.28.1706856159197; Thu, 01 Feb 2024 22:42:39 -0800 (PST) MIME-Version: 1.0 References: <20240202063919.1414368-1-syq@gcc.gnu.org> In-Reply-To: <20240202063919.1414368-1-syq@gcc.gnu.org> From: YunQiang Su Date: Fri, 2 Feb 2024 14:42:27 +0800 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: [PATCH] MIPS: Support PCREL GOT access To: nickc@redhat.com Cc: binutils@sourceware.org, macro@orcam.me.uk, xry111@xry111.site Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-8.0 required=5.0 tests=BAYES_00,BODY_8BITS,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM,GIT_PATCH_0,HEADER_FROM_DIFFERENT_DOMAINS,KAM_DMARC_STATUS,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: YunQiang Su =E4=BA=8E2024=E5=B9=B42=E6=9C=882=E6=97=A5=E5= =91=A8=E4=BA=94 14:39=E5=86=99=E9=81=93=EF=BC=9A > > 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_AHI1= 6 > 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[] = =3D > 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[]= =3D > { 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[] =3D > 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[= ] =3D > 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_re= la[] =3D > 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[] =3D > @@ -3743,7 +3967,15 @@ static const struct elf_reloc_map mips_reloc_map[]= =3D > { 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[] =3D > 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[] = =3D > 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= [] =3D > 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[] =3D > @@ -3577,7 +3801,15 @@ static const struct elf_reloc_map mips_reloc_map[]= =3D > { 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[] =3D > 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 =3D=3D R_MIPS_GOT_LO16 || r_type =3D=3D R_MICROMIPS_GOT_= LO16; > + return r_type =3D=3D R_MIPS_GOT_LO16 > + || r_type =3D=3D R_MIPS_GOTPC_LO16 > + || r_type =3D=3D R_MIPS_GOTPC_ALO16 > + || r_type =3D=3D R_MICROMIPS_GOT_LO16; > } > > static inline bool > call_hi16_reloc_p (unsigned int r_type) > { > - return r_type =3D=3D R_MIPS_CALL_HI16 || r_type =3D=3D R_MICROMIPS_CAL= L_HI16; > + return r_type =3D=3D R_MIPS_CALL_HI16 > + || r_type =3D=3D R_MIPS_GOTPC_CALL_HI16 > + || r_type =3D=3D R_MIPS_GOTPC_CALL_AHI16 > + || r_type =3D=3D R_MICROMIPS_CALL_HI16; > } > > static inline bool > call_lo16_reloc_p (unsigned int r_type) > { > - return r_type =3D=3D R_MIPS_CALL_LO16 || r_type =3D=3D R_MICROMIPS_CAL= L_LO16; > + return r_type =3D=3D R_MIPS_CALL_LO16 > + || r_type =3D=3D R_MIPS_GOTPC_CALL_LO16 > + || r_type =3D=3D R_MIPS_GOTPC_CALL_ALO16 > + || r_type =3D=3D 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 =3D (value & 0xffff) + (p & 0xffff); > + bfd_vma value_hi =3D (value >> 16) & 0xffff; > + value_hi +=3D mips_elf_high (value_lo); > + value_lo &=3D 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 *inp= ut_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 *inpu= t_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 *inp= ut_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 *inp= ut_bfd, > value &=3D 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 +=3D4, and HI should -=3D4. > + > + 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_o= ffet */ > + case R_MIPS_GOTPC_HI16: > + case R_MIPS_GOTPC_CALL_HI16: > + value =3D mips_elf_high (addend + gp - p + g - 4); > + value &=3D howto->dst_mask; > + break; > + > + case R_MIPS_GOTPC_LO16: > + case R_MIPS_GOTPC_CALL_LO16: > + if (howto->partial_inplace) > + addend =3D _bfd_mips_elf_sign_extend (addend, 16); > + value =3D addend + gp - p + g + 4; > + value &=3D howto->dst_mask; > + break; > + > + case R_MIPS_GOTPC_AHI16: > + case R_MIPS_GOTPC_CALL_AHI16: > + value =3D mips_elf_16bit_align (addend + gp - p + g, p, true); > + value &=3D howto->dst_mask; > + break; > + > + case R_MIPS_GOTPC_ALO16: > + case R_MIPS_GOTPC_CALL_ALO16: > + if (howto->partial_inplace) > + addend =3D _bfd_mips_elf_sign_extend (addend, 16); > + value =3D mips_elf_16bit_align (addend + gp - p + g, p, false); > + value &=3D howto->dst_mask; > + break; > + > case R_MIPS_PCHI16: > value =3D mips_elf_high (symbol + addend - p); > value &=3D howto->dst_mask; > @@ -8282,6 +8359,14 @@ mips_elf_add_lo16_rel_addend (bfd *abfd, > lo16_type =3D R_MIPS16_LO16; > else if (micromips_reloc_p (r_type)) > lo16_type =3D R_MICROMIPS_LO16; > + else if (r_type =3D=3D R_MIPS_GOTPC_HI16) > + lo16_type =3D R_MIPS_GOTPC_LO16; > + else if (r_type =3D=3D R_MIPS_GOTPC_CALL_HI16) > + lo16_type =3D R_MIPS_GOTPC_CALL_LO16; > + else if (r_type =3D=3D R_MIPS_GOTPC_AHI16) > + lo16_type =3D R_MIPS_GOTPC_ALO16; > + else if (r_type =3D=3D R_MIPS_GOTPC_CALL_AHI16) > + lo16_type =3D R_MIPS_GOTPC_CALL_ALO16; > else if (r_type =3D=3D R_MIPS_PCHI16) > lo16_type =3D 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_l= ink_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_l= ink_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 !=3D 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= [] =3D { "@@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 =3D 63, > R_MIPS_PCHI16 =3D 64, > R_MIPS_PCLO16 =3D 65, > + R_MIPS_GOTPC_HI16 =3D 66, > + R_MIPS_GOTPC_LO16 =3D 67, > + R_MIPS_GOTPC_CALL_HI16 =3D 68, > + R_MIPS_GOTPC_CALL_LO16 =3D 69, > + R_MIPS_GOTPC_HI16 =3D 70, > + R_MIPS_GOTPC_LO16 =3D 71, > + R_MIPS_GOTPC_CALL_HI16 =3D 72, > + R_MIPS_GOTPC_CALL_LO16 =3D 73, > // These relocs are used for the mips16. > R_MIPS16_26 =3D 100, > R_MIPS16_GPREL =3D 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 re= loc) > 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, of= fsetT 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 =3D ((operand + 0x8000) >> 16) & 0xffff; > @@ -7445,6 +7455,10 @@ calculate_reloc (bfd_reloc_code_real_type reloc, o= ffsetT 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 =3D 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) !=3D 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 =3D=3D NULL) > ip->complete_p =3D 1; > else if (reloc_type[0] <=3D BFD_RELOC_UNUSED > @@ -14583,7 +14613,15 @@ static const struct percent_op_match mips_percen= t_op[] =3D > {"%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[] =3D > @@ -15541,6 +15579,14 @@ mips_force_relocation (fixS *fixp) > || fixp->fx_r_type =3D=3D BFD_RELOC_MIPS_26_PCREL_S2 > || fixp->fx_r_type =3D=3D BFD_RELOC_MIPS_18_PCREL_S3 > || fixp->fx_r_type =3D=3D BFD_RELOC_MIPS_19_PCREL_S2 > + || fixp->fx_r_type =3D=3D BFD_RELOC_HI16_S_GOTOFF > + || fixp->fx_r_type =3D=3D BFD_RELOC_LO16_GOTOFF > + || fixp->fx_r_type =3D=3D BFD_RELOC_MIPS_LO16_GOTOFF_CALL > + || fixp->fx_r_type =3D=3D BFD_RELOC_MIPS_HI16_S_GOTOFF_CALL > + || fixp->fx_r_type =3D=3D BFD_RELOC_MIPS_AHI16_S_GOTOFF > + || fixp->fx_r_type =3D=3D BFD_RELOC_MIPS_ALO16_GOTOFF > + || fixp->fx_r_type =3D=3D BFD_RELOC_MIPS_ALO16_GOTOFF_CALL > + || fixp->fx_r_type =3D=3D BFD_RELOC_MIPS_AHI16_S_GOTOFF_CALL > || fixp->fx_r_type =3D=3D BFD_RELOC_HI16_S_PCREL > || fixp->fx_r_type =3D=3D 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 =3D=3D BFD_RELOC_MIPS_26_PCREL_S2 > || fixp->fx_r_type =3D=3D BFD_RELOC_MIPS_18_PCREL_S3 > || fixp->fx_r_type =3D=3D BFD_RELOC_MIPS_19_PCREL_S2 > + || fixp->fx_r_type =3D=3D BFD_RELOC_HI16_S_GOTOFF > + || fixp->fx_r_type =3D=3D BFD_RELOC_LO16_GOTOFF > + || fixp->fx_r_type =3D=3D BFD_RELOC_MIPS_LO16_GOTOFF_CA= LL > + || fixp->fx_r_type =3D=3D BFD_RELOC_MIPS_HI16_S_GOTOFF_= CALL > + || fixp->fx_r_type =3D=3D BFD_RELOC_MIPS_AHI16_S_GOTOFF > + || fixp->fx_r_type =3D=3D BFD_RELOC_MIPS_ALO16_GOTOFF > + || fixp->fx_r_type =3D=3D BFD_RELOC_MIPS_ALO16_GOTOFF_C= ALL > + || fixp->fx_r_type =3D=3D BFD_RELOC_MIPS_AHI16_S_GOTOFF= _CALL > || fixp->fx_r_type =3D=3D BFD_RELOC_HI16_S_PCREL > || fixp->fx_r_type =3D=3D 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=3Dxx > + .module nooddspreg > + .module arch=3Dmips32r6 > + .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=3D 0, regs=3D 1/0, args=3D= 16, gp=3D 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=3D 0, regs=3D 2/0, args=3D= 0, gp=3D 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/ga= s/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/ga= s/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/ga= s/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/mi= ps/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=3Dxx > + .module nooddspreg > + .module arch=3Dmips32r6 > + .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=3D 0, regs=3D 1/0, args=3D= 16, gp=3D 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/mi= ps/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=3D 0, regs=3D 2/0, args=3D= 0, gp=3D 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/m= ips/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=3Dfrom-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/m= ips/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=3Dfrom-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/m= ips/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=3Dfrom-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/mip= s.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 >