From patchwork Fri Feb 2 12:51:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: YunQiang Su X-Patchwork-Id: 195850 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:9bc1:b0:106:209c:c626 with SMTP id op1csp402946dyc; Fri, 2 Feb 2024 04:51:40 -0800 (PST) X-Google-Smtp-Source: AGHT+IGpVdZHqqmCTO/ergk9Y9Hx1gtayXmx/uoClnGoqNdpZjgOvUQh3FJ69EfwpGdDNnRX2Vc6 X-Received: by 2002:a81:b613:0:b0:604:978:e779 with SMTP id u19-20020a81b613000000b006040978e779mr2368990ywh.16.1706878299775; Fri, 02 Feb 2024 04:51:39 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706878299; cv=pass; d=google.com; s=arc-20160816; b=Dldu0ZqzAJNOZH8hCKPeVjG9tMuHywXzcvRQ2NKRSmvkopyghnTR0QXcMM+c1awlmU AXadZfz1MZFglKu9sPby1Nehi3/099eZDLG5tvX5EwprpEy3zNr8OTw+h7XdtcI+Jjwa TwLgf3bsrRsk7SWqrVMsiXgF8LyFYT6q9juk97GvPFrNIl+psAPZsUkp6GrMm6tqZ4Ur qB/ecYrTdt4nhEZFlqbFAak6/ryX4LqB7jc3L5yff2+vxILQlqBiOE5TXZlqDrwlN0hp gst6hBLAjNStP0zyBkg3LCSuygo1S2ChS05IlC638PX0nAZYpJuoFRTLndOB0ALkfQze Ub7Q== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:message-id:date:subject:cc:to:from:arc-filter :dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=P3XhoFip1A3zN7XPsDxUlEeaj0NxJMEwvagZ9T3gYNA=; fh=Y7EdKOI4Fo/35QDk1s6Z4yodyPkcRbWSPaufbCiBEZY=; b=wxz6XIWbzVOQ4bQD9I/mmUaCgHuQURpc7Db3EGMcVeKChU19n7rXYdPCem37D+Iyzq HFnIds8zu++IIsCWYIA4hyTEfcULG6HeVlfEu46wp0zCSsXv53otYh7pkyzFYyBm3aZS 4OEgHBbwrwx8j1L6YcnwnOTzng3OHSkxNPCzkeoGOZcBPEHrIwLLgNPM7vecYWwe05HM pcOWLtOmwvWT8ls5/OfpRESj1CLLaClI7BE8lpBDMX/CUiRIk5ba0YmGTdjqZLwEWtqZ 7txqA4DicKM66btroGAFm4UdG8CUJRQrDDPFDjK2syPcRYqmtA+GR+P3Uz+XS+aB1WnK olyg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=jqrQafaz; arc=pass (i=1); spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="binutils-bounces+ouuuleilei=gmail.com@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org X-Forwarded-Encrypted: i=1; AJvYcCXys11M+0ErwB42v6MabOo82As6qzDzrx27Hj7+rNE7Nn1GG62XgEXERDQDlKpc6Yn95jhYJE9VnG5jp8B32YvYHRBUGQ== Received: from server2.sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id p16-20020a05622a00d000b0042bff035730si1934451qtw.162.2024.02.02.04.51.39 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 Feb 2024 04:51:39 -0800 (PST) Received-SPF: pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=jqrQafaz; arc=pass (i=1); spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="binutils-bounces+ouuuleilei=gmail.com@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3B9F9385803D for ; Fri, 2 Feb 2024 12:51:39 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3B9F9385803D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1706878299; bh=P3XhoFip1A3zN7XPsDxUlEeaj0NxJMEwvagZ9T3gYNA=; h=From:To:Cc:Subject:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From; b=jqrQafaz46BWZ3+ddhleQHtwdMAuK2Ba+ZtKsIUAiy+/4SPZ7BJg7zyBVxQjz0Hxy I81k7Z6MOLFBQpgejZLwvkjEZ+1A37km1QPKKAS/RshBppvABIsTPr0y9ymiQg500F uoa2Gz3UTNUfkcrN/bESjCmdZrPLFW0akczf2PkE= X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-pg1-f179.google.com (mail-pg1-f179.google.com [209.85.215.179]) by sourceware.org (Postfix) with ESMTPS id 791CD3858403 for ; Fri, 2 Feb 2024 12:51:18 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 791CD3858403 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 791CD3858403 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=209.85.215.179 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1706878285; cv=none; b=EXCR1IsTYVniEzGyy1eplkreKnwT/e4ru0dGoUbDLWn5hjKdv7sRV2JF5AW8jngZKn/NPwOn/QIZKxY0ETSiQUk/OsdfGWK30/UBmqGK0GrSz9Mzf0zS+HD6bMMwNGfea0kTxYfNJuuXgBHB5n0fVQbMzpx2jFan3q7+BXJPZNw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1706878285; c=relaxed/simple; bh=DQEz1gqfmjFVJwZJDbx9dYpy0Xirm7Ucnl4JyeQmmQ0=; h=From:To:Subject:Date:Message-Id:MIME-Version; b=xg21bX7OQGWMiQN+nxeGNQXvNrH8ZY+eoCYHp5yEJkiqzauVa407uGaIjo3cCKntbiNAbZtftVqEGFQU/SHBBfeCkM7vdkX7INEJFC16G4qziUMs7RuOfdQBO2tC9mkVxAwV2+vggqOvGrotzGgUuRNNMvqzA4mIS8XhQBfLLt0= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pg1-f179.google.com with SMTP id 41be03b00d2f7-5ca29c131ebso1771215a12.0 for ; Fri, 02 Feb 2024 04:51:18 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706878277; x=1707483077; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=P3XhoFip1A3zN7XPsDxUlEeaj0NxJMEwvagZ9T3gYNA=; b=HJYDkrviNf7+tBlNMhZdgqQw1e57awQxJtAC/N19KATMHOxX0aHVM3KCtpA2cny9Td hggfbACYdVK5t/8Fj5y7d89GBquvWz1PiELTLpvN3F0jOeBPfylsNohuH3zKGVKyNNKo xMH9FSFm1o2Q0Vg2wzLiHrgAy28usBFOxozH5PdYP2qS1SSRAch6MRJFLm8O+DVSvs+2 KOKJnywh9CEYEdARTv+WioTLoHVIQkUGpkBGGDzdYmWc2Am6Qr39HfsRiO2HNjZCwzdR 8LYoUTCDaab/vsDh8GQJYOG4hGH5+hxFixZ3wtoOTU5qeesW0As4+M2Fn0v1pk2cfQHN 3JHg== X-Gm-Message-State: AOJu0Yw7nKJpqNrxToNmrWmiik7cnZt7R6nJKuYzSQywQFzVZG2hZSjU Ul8r09e+HwrmX3juRdTz22nNTkPGJhTVwmlubr2Sij3lUFtMGmGwHkyKZICjK8A= X-Received: by 2002:a05:6a20:ba7:b0:19c:9abb:8a64 with SMTP id i39-20020a056a200ba700b0019c9abb8a64mr1731430pzh.24.1706878277013; Fri, 02 Feb 2024 04:51:17 -0800 (PST) X-Forwarded-Encrypted: i=0; AJvYcCUa8Jwb8PwqLVRNz1oEKO/jv91Mp8Dzj2Yb5qf9PIw2dciPZYEhY8u3JMwDFT3GtwYcaCMwTZfipnkTOOz8vPVQ+2RNkKSddK3LObf1m6AExa/A3JN+ Received: from localhost.localdomain ([149.248.38.156]) by smtp.gmail.com with ESMTPSA id a18-20020aa78652000000b006dfbe51de49sm1572225pfo.143.2024.02.02.04.51.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 Feb 2024 04:51:16 -0800 (PST) From: YunQiang Su To: nickc@redhat.com Cc: binutils@sourceware.org, macro@orcam.me.uk, xry111@xry111.site Subject: [PATCH v4] MIPS: Support PCREL GOT access Date: Fri, 2 Feb 2024 20:51:05 +0800 Message-Id: <20240202125105.1504614-1-syq@gcc.gnu.org> X-Mailer: git-send-email 2.39.2 MIME-Version: 1.0 X-Spam-Status: No, score=-10.8 required=5.0 tests=BAYES_00, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, 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 X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: binutils-bounces+ouuuleilei=gmail.com@sourceware.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789768443245178562 X-GMAIL-MSGID: 1789791620427766440 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..79884bd651b 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_AHI16 = 70, + R_MIPS_GOTPC_ALO16 = 71, + R_MIPS_GOTPC_CALL_AHI16 = 72, + R_MIPS_GOTPC_CALL_ALO16 = 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..1832061a34e --- /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 (OldABI, ALUIPC, O32) +#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..57cb891042a --- /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 (OldABI, 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)