From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05on2101.outbound.protection.outlook.com [40.107.21.101]) by sourceware.org (Postfix) with ESMTPS id 90E8038555B4 for ; Wed, 10 May 2023 14:18:55 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 90E8038555B4 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=syrmia.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=syrmia.com ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=czVRz1yUWPP9oh256pWDot2cXTV2UnL0VIs/FNIZeZAnu3Yo8vdByUMCZyTlfq6TFChFDLcbUh/pF2A2oagM/yyjYbO7ByEbre+71g+H0kIDbWR9Il5RP9cMjVpC00BP7rZG8oieliqdonQUZbW4WBohhI3BZVeJR7z/Lj5RewYNuYqGmqS3fqaYc7/nAoRq3LkxHPexQe7ZVbO+aA4w0Vzbn+rr0+7WMcgvcjcpM98VW55Afnaj1nLj+iaLQHeCuEAbLBmmMTopuECEHBaFXyTAroVMLArM88qDoTXasbfchRjmFI3+xah1wN4/J1d63hUMDVJ4jtrwOaIY3/yk3Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=yfzXWU5kBNNLq7InWF9lEerTFqqCjNj3BLRgh8OD/Gk=; b=G12rOy7Tc62qmkarNn0/VwJcorUSKfSrzM2lsQPF6XRF20tSXDAinkFyZeSU1B64rlyvX3eREJHecxIKqQOUfdZa1aXbbT99k4suhBQJEXIo5nBl6jx50RAKZ7DUXy4rs8TudWLcfM/V5xq1XHnp6uvi1SW9jtqAKDuJ2MUbX/KKLQ4cJw7wKWKdwVUkQvmzaPOQQpA/TauRpIN5W2PbVgRGQTxyMXL52OyeJpp2N5uKTALObiaFLruwQiDTYfiRdVfFnB9/dCDH3PLcwaKK7VdGnTS32v9OKimy7WJnZGGmR331tZKbf1EO3FNuvwkctovOo+Sa5CyEAWssaS33Lg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=syrmia.com; dmarc=pass action=none header.from=syrmia.com; dkim=pass header.d=syrmia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=syrmia.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=yfzXWU5kBNNLq7InWF9lEerTFqqCjNj3BLRgh8OD/Gk=; b=y11m78y7qrQIJtY2UfVZBbeBE1+JD9tLWEC8/KN2R+tBjO9oLimRLlOyZq8yXLUY/FdBnp0VlP27IKOfk6dxYLYkO6Xj0Jjw/pmG2m91lc9SsEATJAglohiFvPph6Rh29UK6diJql4wzUf7kf8QGMVuCnRtwh7rHF49kUqVsbaA= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=syrmia.com; Received: from VI1PR0302MB3486.eurprd03.prod.outlook.com (2603:10a6:803:1e::32) by DB9PR03MB9784.eurprd03.prod.outlook.com (2603:10a6:10:456::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6363.31; Wed, 10 May 2023 14:18:46 +0000 Received: from VI1PR0302MB3486.eurprd03.prod.outlook.com ([fe80::82b5:25de:e5b:9914]) by VI1PR0302MB3486.eurprd03.prod.outlook.com ([fe80::82b5:25de:e5b:9914%4]) with mapi id 15.20.6387.018; Wed, 10 May 2023 14:18:46 +0000 From: Aleksandar Rikalo To: binutils@sourceware.org Cc: nickc@redhat.com, macro@orcam.me.uk, dragan.mladjenovic@syrmia.com, lei.wang@oss.cipunited.com Subject: [PATCH v6 1/3] BFD changes for nanoMIPS support Date: Wed, 10 May 2023 16:18:27 +0200 Message-Id: <20230510141829.2748105-2-aleksandar.rikalo@syrmia.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230510141829.2748105-1-aleksandar.rikalo@syrmia.com> References: <20230510141829.2748105-1-aleksandar.rikalo@syrmia.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-ClientProxiedBy: VI1PR0501CA0030.eurprd05.prod.outlook.com (2603:10a6:800:60::16) To VI1PR0302MB3486.eurprd03.prod.outlook.com (2603:10a6:803:1e::32) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: VI1PR0302MB3486:EE_|DB9PR03MB9784:EE_ X-MS-Office365-Filtering-Correlation-Id: 7ca83841-4bf9-46b0-7e70-08db516177ae X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: kPFeZAb3fTJuuB32OGo6qVMmaKAkKFD7sI/SvUo6yPPqcxofE/lwPz2n0cXkCz208TSy/WPKwAEjeYsnaC3+ppBRaOB2bPBGA5Bugz/nWmEHKEh+U0nmVxlQpiiZgaLVKCkqFKSJTay/APGrB+H1DvUWfXZBwV13SbGa17hHF0sQ+UrF/4KgQH7Q/AG4AMoNpxFK07mo+qzbdzzywPqZpS7Dt/wEOJfVhp7aPo1GWL72bvbGytg1aqjq719L8Xm5Qs6hpZyR2SmVrEMC7JAiavawnEVUpdenY7yApjfQm7KcdhczqVVIvImt6U72eArqCgWCiHDyib7wvf9C/F4Nq3ZSEZrK4N/zRsodvbGv5f2ODZiJPDwcQvB2QX5UPNQcxa/3nBy6RHZBpxVpcfKhEgE1b2CSXk8lX8HcYzm63V3hCihDABR7uYOTLL8tABSeBz385/vXEugPU2QmQ/MioD7Bd5+0LlOYaGwwWk2FU7w8FGv/u8IIueJrGQzb/KNzkJBZnn5PCyaseKgvVaJ3uoTQYTPWNZYsqY4eLAF3I49JWP7r3/NqDAdOF2O31sBykryyrVjj2SqswhbQSgwDl2tCo85iVfPaPkp8yUkZgU66RbE5cqCn1IenrI29XxwS0AA2ycSRS++NldPUwvg0GM/RbE4+FuDOPiXvamP0kbk= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:VI1PR0302MB3486.eurprd03.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230028)(39840400004)(396003)(366004)(346002)(376002)(136003)(451199021)(8676002)(36756003)(66556008)(83380400001)(38350700002)(44832011)(2906002)(38100700002)(30864003)(316002)(86362001)(66946007)(6916009)(66476007)(41300700001)(4326008)(5660300002)(8936002)(52116002)(6506007)(26005)(186003)(6512007)(1076003)(2616005)(6666004)(478600001)(19627235002)(6486002)(2004002)(21314003)(579004)(559001);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?WUJIZTNtcVE5d0FGeDRPRzJ4YUhla21namEzQ08wOXZqOEhJayttekJTTW5K?= =?utf-8?B?SlpIRjRFayt2RjBLZStFOWc0eW4yei8ydTMybXk4VTFsZUdMU2ZqVk5kUCs2?= =?utf-8?B?MWh5b0tSLy82VENqZ0R3THAxOVdmNUtkSlh4c044MG53cldnK2IwN3JFU0p2?= =?utf-8?B?am1nR3BGZmt5eUZtV3FXVEdpNTVlV3lCRTFOcERkNTBEWUZGRVBkV29UYTRS?= =?utf-8?B?OTlnU1NUdCtXaHhhdkovSzVtWlNJUHhZNDNCbGlUeTIzdHE4RXcxajFwbmc1?= =?utf-8?B?VHJnRS9VeDRhZHl2TnZPVUg2TTc4bTA1bkcrK1BrTnl0SmJYOEFJVFZkRkZR?= =?utf-8?B?SVRXcXBIb3cwR0QxNFhKbnVKWUd2L3krYnFzUjNxYnVSYVg3WU9VdXBQMXMy?= =?utf-8?B?enQ0TXhnZkFVZUQrN2JITjZFb3FhODhqcktVQlYzK09wb3djdWUrbXJ6YWx4?= =?utf-8?B?MDVueER5eW5GNUJQSDdaN0phOEd4RlZvRjY3SlBkYlRKa2Y0NmF6UWxpYnZz?= =?utf-8?B?dW1idThJUmpFVnhDUW03ME9manJQYVJPbGVrMEp0ZHhRc21wOHJ5c1BrQmxC?= =?utf-8?B?M0ZvdW1XMzNJSFk0d0tYTk9BaTlESC9kRGRXejJCT3h4SkVoZ2Vvb3lmWmVi?= =?utf-8?B?QnZuV1grTm1MSHc0VHFGQjg2VkpkQk5jbUFOWjVzbUdnajlRYm1FVUpnR1Iw?= =?utf-8?B?UTVmY0cyZm55eTJpbjY2QnJsNkNucmtvWEhXT0FLa3I1ZDFhMThRSXBHcVlW?= =?utf-8?B?d3FSQ0hvUmwxbzVSTkZYWk56UThkR3dIR0xnUTdKYndzUW1EcXVmZ05Dd3Bu?= =?utf-8?B?L3BXUElaLzY2OGM5NS90aWdYcTV1ZlJDS3p4UzdoVWxUK3ZVcVJFYWo2QjhV?= =?utf-8?B?V3ZKbDNCYTBENzdBd0wxN1dVa3I0OFhqSDhkc3RzTVZUZGJNdXBrUlQ3Vm5I?= =?utf-8?B?eHR6NitFSWx0SG44MXIwRGJERDJqcDcrTVUxeFN6L3pkeExnZHR3WkpSTGd5?= =?utf-8?B?Zkk3NER6NjZ4WHAvVDk2UG5Tem9aNkErMzYxdkJpSTBtd3BkM0g5ZXVsUTU3?= =?utf-8?B?bGRHMG1OYjhOd3kzN25hV2J4QlhtV05MbURhelpUMGdKQjNvcGU1NkdjM1VE?= =?utf-8?B?WDNCb1BVbTdHMTdhUVl3SGg2REl5bmVhS3ppY2J5RTFsZm5aUmJ4dlZwZUZx?= =?utf-8?B?d1pTMGEzMEdTc1VaNmx2STB2UTlySGRHVElFb0ROaXFHc1gvaEJzVUM5RzRE?= =?utf-8?B?QzJGdW12QmJaK2cwRHdoK0owSHhyT0toRUxPZ1kwTDNCV3IrdzA2TkhYd09G?= =?utf-8?B?Sm1JV09tYm85cEVZSFF6QjRvWVZSWnk3MDh6dTdPMVVBQ0JzVitoZkFXOFlO?= =?utf-8?B?dXR2NVdvcnJ2azc3cG4reEhYZDhyL0w2bFpJbStEc0d0TUNoWG1SWHQ2c3lk?= =?utf-8?B?VDhsc3NLR1J5UEhaK2c3cTNTZUdBYlNTcHpNdnJHbSttYmphcTMzdzNSOEZ4?= =?utf-8?B?ekwwemNHNEhJM1M2UExmcXNMRTM2TEtrMllZRm5UdzBXMjJYOE1oc0lMUVp2?= =?utf-8?B?UEVqU2ZLSXZySmsySlRPWi9SZ2pTWndoNnZXc3J2ODhMUlFSNUNXWUc4emUx?= =?utf-8?B?elJUYjJUTkROS1lSUENsdlIrNkhYRjJpOExRaDIzTFB4dnlBcXROSWx1N3ZG?= =?utf-8?B?Ty9Eek5hR3IrTWRaN25lVDZHTDVXWEFFeWxnaFVxVjZGSkhDY2s5VmJ1V0t4?= =?utf-8?B?dklGaHlobTYyR3oreEY1a01PRzlPSUVEV3gyU3pKeXQwVjJWUXJjSTRSZm4v?= =?utf-8?B?MjZEZThiUjR5SkpCYUI3a0xJdjhPdmFFQzhhNloxUTd1aXdQK04ybFMxTmI1?= =?utf-8?B?SVcvdEpWeVk0R1ViL2dYM25CaUhUbWRtdWg0Q2lpWnhCSmxEQWdyS1d0OFl0?= =?utf-8?B?L2hWaXN2cnNnOHNDb1I3RUpyZjJyMVJzdWRMZW5xT1lxQUxzdXlZbFpGSW9C?= =?utf-8?B?WnNCeWR3OE5FeGJQL0lDMTZxL21FZUZSQXhhRVNDR3RQYmVNTlYyTk92WHhm?= =?utf-8?B?bktYOEN1ODhXWUJ2d2tCa2RxbCtFamx2ZlVhVkM4MlZQR0hsTWxOSFVTUk5o?= =?utf-8?B?amc0LzEvT3FmWDhQQ1J4dDJwMDkyZElSa1pEZU1RUjlDWVFQb25icHg2UEpZ?= =?utf-8?B?V1E9PQ==?= X-OriginatorOrg: syrmia.com X-MS-Exchange-CrossTenant-Network-Message-Id: 7ca83841-4bf9-46b0-7e70-08db516177ae X-MS-Exchange-CrossTenant-AuthSource: VI1PR0302MB3486.eurprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 10 May 2023 14:18:46.7761 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 19214a73-c1ab-4e19-8f59-14bdcb09a66e X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: t8lTBkDH8lCruqyIevwtKTQzwItrzz/HVBZFvDon6C6C1yrDvffIugHvofp/O/tE49Fc4deV2ITM6L5amI9OMo62zZ7Y6MsAqN8ccAzrxmU= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB9PR03MB9784 X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_PASS,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: Add a subset of the functionality required for GDB. Co-Authored-By: Jaydeep Patil Co-Authored-By: Matthew Fortune Co-Authored-By: Maciej W. Rozycki Co-Authored-By: Stefan Markovic Co-Authored-By: Sara Graovac Co-Authored-By: Dragan Mladjenovic --- bfd/Makefile.am | 19 + bfd/Makefile.in | 22 + bfd/archures.c | 5 + bfd/bfd-in2.h | 74 +++ bfd/config.bfd | 6 + bfd/configure | 4 + bfd/configure.ac | 4 + bfd/cpu-nanomips.c | 61 ++ bfd/elf-bfd.h | 1 + bfd/elfnn-nanomips.c | 1423 ++++++++++++++++++++++++++++++++++++++++ bfd/elfxx-mips.h | 5 + bfd/elfxx-nanomips.c | 794 ++++++++++++++++++++++ bfd/elfxx-nanomips.h | 54 ++ bfd/libbfd.h | 69 ++ bfd/reloc.c | 140 ++++ bfd/targets.c | 11 + binutils/readelf.c | 2 +- include/elf/common.h | 2 +- include/elf/nanomips.h | 262 ++++++++ 19 files changed, 2956 insertions(+), 2 deletions(-) create mode 100644 bfd/cpu-nanomips.c create mode 100644 bfd/elfnn-nanomips.c create mode 100644 bfd/elfxx-nanomips.c create mode 100644 bfd/elfxx-nanomips.h create mode 100644 include/elf/nanomips.h diff --git a/bfd/Makefile.am b/bfd/Makefile.am index 5c5fdefd3b8..8f452f856f7 100644 --- a/bfd/Makefile.am +++ b/bfd/Makefile.am @@ -142,6 +142,7 @@ ALL_MACHINES = \ cpu-moxie.lo \ cpu-msp430.lo \ cpu-mt.lo \ + cpu-nanomips.lo \ cpu-nds32.lo \ cpu-nfp.lo \ cpu-nios2.lo \ @@ -547,6 +548,7 @@ BFD64_BACKENDS = \ coff64-rs6000.lo \ elf32-ia64.lo \ elf32-mips.lo \ + elf32-nanomips.lo \ elf32-score.lo \ elf32-score7.lo \ elf64-alpha.lo \ @@ -564,6 +566,8 @@ BFD64_BACKENDS = \ elfxx-mips.lo \ elf64-mmix.lo \ elf64-nfp.lo \ + elf64-nanomips.lo \ + elfxx-nanomips.lo \ elf64-ppc.lo \ elf32-riscv.lo \ elf64-riscv.lo \ @@ -607,6 +611,7 @@ BFD64_BACKENDS_CFILES = \ elf64-mips.c \ elf64-mmix.c \ elf64-nfp.c \ + elf64-nanomips.c \ elf64-ppc.c \ elf64-s390.c \ elf64-sparc.c \ @@ -620,6 +625,7 @@ BFD64_BACKENDS_CFILES = \ elfxx-ia64.c \ elfxx-loongarch.c \ elfxx-mips.c \ + elfxx-nanomips.c \ elfxx-riscv.c \ mach-o-aarch64.c \ mach-o-x86-64.c \ @@ -684,6 +690,7 @@ BUILD_CFILES = \ elf32-ia64.c elf64-ia64.c \ elf32-loongarch.c elf64-loongarch.c \ elf32-riscv.c elf64-riscv.c \ + elf32-nanomips.c elf64-nanomips.c \ peigen.c pepigen.c pex64igen.c pe-aarch64igen.c pe-loongarch64igen.c CFILES = $(SOURCE_CFILES) $(BUILD_CFILES) @@ -886,6 +893,18 @@ pe-loongarch64igen.c: peXXigen.c $(AM_V_at)echo "#line 1 \"peXXigen.c\"" > $@ $(AM_V_GEN)$(SED) -e s/XX/peLoongArch64/g < $< >> $@ +elf32-nanomips.c : elfnn-nanomips.c + rm -f elf32-nanomips.c + echo "#line 1 \"$(srcdir)/elfnn-nanomips.c\"" > elf32-nanomips.new + sed -e s/NN/32/g < $(srcdir)/elfnn-nanomips.c >> elf32-nanomips.new + mv -f elf32-nanomips.new elf32-nanomips.c + +elf64-nanomips.c : elfnn-nanomips.c + rm -f elf64-nanomips.c + echo "#line 1 \"$(srcdir)/elfnn-nanomips.c\"" > elf64-nanomips.new + sed -e s/NN/64/g < $(srcdir)/elfnn-nanomips.c >> elf64-nanomips.new + mv -f elf64-nanomips.new elf64-nanomips.c + host-aout.lo: Makefile # The following program can be used to generate a simple config file diff --git a/bfd/Makefile.in b/bfd/Makefile.in index 4edfedee924..64ff01733fd 100644 --- a/bfd/Makefile.in +++ b/bfd/Makefile.in @@ -597,6 +597,7 @@ ALL_MACHINES = \ cpu-moxie.lo \ cpu-msp430.lo \ cpu-mt.lo \ + cpu-nanomips.lo \ cpu-nds32.lo \ cpu-nfp.lo \ cpu-nios2.lo \ @@ -1004,6 +1005,7 @@ BFD64_BACKENDS = \ coff64-rs6000.lo \ elf32-ia64.lo \ elf32-mips.lo \ + elf32-nanomips.lo \ elf32-score.lo \ elf32-score7.lo \ elf64-alpha.lo \ @@ -1021,6 +1023,8 @@ BFD64_BACKENDS = \ elfxx-mips.lo \ elf64-mmix.lo \ elf64-nfp.lo \ + elf64-nanomips.lo \ + elfxx-nanomips.lo \ elf64-ppc.lo \ elf32-riscv.lo \ elf64-riscv.lo \ @@ -1064,6 +1068,7 @@ BFD64_BACKENDS_CFILES = \ elf64-mips.c \ elf64-mmix.c \ elf64-nfp.c \ + elf64-nanomips.c \ elf64-ppc.c \ elf64-s390.c \ elf64-sparc.c \ @@ -1077,6 +1082,7 @@ BFD64_BACKENDS_CFILES = \ elfxx-ia64.c \ elfxx-loongarch.c \ elfxx-mips.c \ + elfxx-nanomips.c \ elfxx-riscv.c \ mach-o-aarch64.c \ mach-o-x86-64.c \ @@ -1140,6 +1146,7 @@ BUILD_CFILES = \ elf32-ia64.c elf64-ia64.c \ elf32-loongarch.c elf64-loongarch.c \ elf32-riscv.c elf64-riscv.c \ + elf32-nanomips.c elf64-nanomips.c \ peigen.c pepigen.c pex64igen.c pe-aarch64igen.c pe-loongarch64igen.c CFILES = $(SOURCE_CFILES) $(BUILD_CFILES) @@ -1593,6 +1600,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-moxie.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-msp430.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-mt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-nanomips.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-nds32.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-nios2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-or1k.Plo@am__quote@ @@ -1633,6 +1641,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-mips.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-mmix.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-nfp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-nanomips.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-ppc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-riscv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-s390.Plo@am__quote@ @@ -1646,6 +1655,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfxx-ia64.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfxx-loongarch.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfxx-mips.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfxx-nanomips.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfxx-riscv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfxx-sparc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfxx-tilegx.Plo@am__quote@ @@ -2384,6 +2394,18 @@ pe-loongarch64igen.c: peXXigen.c $(AM_V_at)echo "#line 1 \"peXXigen.c\"" > $@ $(AM_V_GEN)$(SED) -e s/XX/peLoongArch64/g < $< >> $@ +elf32-nanomips.c : elfnn-nanomips.c + rm -f elf32-nanomips.c + echo "#line 1 \"$(srcdir)/elfnn-nanomips.c\"" > elf32-nanomips.new + sed -e s/NN/32/g < $(srcdir)/elfnn-nanomips.c >> elf32-nanomips.new + mv -f elf32-nanomips.new elf32-nanomips.c + +elf64-nanomips.c : elfnn-nanomips.c + rm -f elf64-nanomips.c + echo "#line 1 \"$(srcdir)/elfnn-nanomips.c\"" > elf64-nanomips.new + sed -e s/NN/64/g < $(srcdir)/elfnn-nanomips.c >> elf64-nanomips.new + mv -f elf64-nanomips.new elf64-nanomips.c + host-aout.lo: Makefile # The following program can be used to generate a simple config file diff --git a/bfd/archures.c b/bfd/archures.c index 6fe8701b412..5e5fd28e71d 100644 --- a/bfd/archures.c +++ b/bfd/archures.c @@ -563,6 +563,9 @@ DESCRIPTION .#define bfd_mach_amdgcn_gfx1030 0x036 .#define bfd_mach_amdgcn_gfx1031 0x037 .#define bfd_mach_amdgcn_gfx1032 0x038 +. bfd_arch_nanomips, {* nanoMIPS. *} +.#define bfd_mach_nanomipsisa32r6 32 +.#define bfd_mach_nanomipsisa64r6 64 . bfd_arch_last . }; */ @@ -663,6 +666,7 @@ extern const bfd_arch_info_type bfd_moxie_arch; extern const bfd_arch_info_type bfd_ft32_arch; extern const bfd_arch_info_type bfd_msp430_arch; extern const bfd_arch_info_type bfd_mt_arch; +extern const bfd_arch_info_type bfd_nanomips_arch; extern const bfd_arch_info_type bfd_nds32_arch; extern const bfd_arch_info_type bfd_nfp_arch; extern const bfd_arch_info_type bfd_nios2_arch; @@ -751,6 +755,7 @@ static const bfd_arch_info_type * const bfd_archures_list[] = &bfd_ft32_arch, &bfd_msp430_arch, &bfd_mt_arch, + &bfd_nanomips_arch, &bfd_nds32_arch, &bfd_nfp_arch, &bfd_nios2_arch, diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 7be18db20a8..98fd0bf2d8f 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -1816,6 +1816,9 @@ enum bfd_architecture #define bfd_mach_amdgcn_gfx1030 0x036 #define bfd_mach_amdgcn_gfx1031 0x037 #define bfd_mach_amdgcn_gfx1032 0x038 + bfd_arch_nanomips, /* nanoMIPS. */ +#define bfd_mach_nanomipsisa32r6 32 +#define bfd_mach_nanomipsisa64r6 64 bfd_arch_last }; @@ -3663,6 +3666,77 @@ to compensate for the borrow when the low bits are added. */ BFD_RELOC_MIPS_JUMP_SLOT, +/* nanoMIPS relocations */ + BFD_RELOC_NANOMIPS_HI20, + BFD_RELOC_NANOMIPS_LO12, + BFD_RELOC_NANOMIPS_LO4_S2, + BFD_RELOC_NANOMIPS_IMM16, + BFD_RELOC_NANOMIPS_NEG12, + BFD_RELOC_NANOMIPS_GPREL7_S2, + BFD_RELOC_NANOMIPS_GPREL18, + BFD_RELOC_NANOMIPS_GPREL19_S2, + BFD_RELOC_NANOMIPS_GPREL16_S2, + BFD_RELOC_NANOMIPS_GPREL18_S3, + BFD_RELOC_NANOMIPS_4_PCREL_S1, + BFD_RELOC_NANOMIPS_7_PCREL_S1, + BFD_RELOC_NANOMIPS_10_PCREL_S1, + BFD_RELOC_NANOMIPS_11_PCREL_S1, + BFD_RELOC_NANOMIPS_14_PCREL_S1, + BFD_RELOC_NANOMIPS_21_PCREL_S1, + BFD_RELOC_NANOMIPS_25_PCREL_S1, + BFD_RELOC_NANOMIPS_PCREL_HI20, + BFD_RELOC_NANOMIPS_GOT_CALL, + BFD_RELOC_NANOMIPS_GOTPC_HI20, + BFD_RELOC_NANOMIPS_GOTPC_I32, + BFD_RELOC_NANOMIPS_GOT_LO12, + BFD_RELOC_NANOMIPS_GOT_DISP, + BFD_RELOC_NANOMIPS_GOT_PAGE, + BFD_RELOC_NANOMIPS_GOT_OFST, + BFD_RELOC_NANOMIPS_I32, + BFD_RELOC_NANOMIPS_GPREL_HI20, + BFD_RELOC_NANOMIPS_GPREL_LO12, + BFD_RELOC_NANOMIPS_TLS_GD, + BFD_RELOC_NANOMIPS_TLS_GD_I32, + BFD_RELOC_NANOMIPS_TLS_LD, + BFD_RELOC_NANOMIPS_TLS_LD_I32, + BFD_RELOC_NANOMIPS_TLS_DTPREL12, + BFD_RELOC_NANOMIPS_TLS_DTPREL16, + BFD_RELOC_NANOMIPS_TLS_DTPREL_I32, + BFD_RELOC_NANOMIPS_TLS_GOTTPREL, + BFD_RELOC_NANOMIPS_TLS_GOTTPREL_PC_I32, + BFD_RELOC_NANOMIPS_TLS_TPREL12, + BFD_RELOC_NANOMIPS_TLS_TPREL16, + BFD_RELOC_NANOMIPS_TLS_TPREL_I32, + BFD_RELOC_NANOMIPS_TLS_DTPMOD, + BFD_RELOC_NANOMIPS_TLS_DTPREL, + BFD_RELOC_NANOMIPS_TLS_TPREL, + BFD_RELOC_NANOMIPS_PC_I32, + BFD_RELOC_NANOMIPS_GPREL_I32, + BFD_RELOC_NANOMIPS_GPREL17_S1, + BFD_RELOC_NANOMIPS_NEG, + BFD_RELOC_NANOMIPS_ASHIFTR_1, + BFD_RELOC_NANOMIPS_UNSIGNED_8, + BFD_RELOC_NANOMIPS_UNSIGNED_16, + BFD_RELOC_NANOMIPS_SIGNED_8, + BFD_RELOC_NANOMIPS_SIGNED_16, + BFD_RELOC_NANOMIPS_EH, + BFD_RELOC_NANOMIPS_JUMP_SLOT, + BFD_RELOC_NANOMIPS_ALIGN, + BFD_RELOC_NANOMIPS_FILL, + BFD_RELOC_NANOMIPS_MAX, + BFD_RELOC_NANOMIPS_INSN32, + BFD_RELOC_NANOMIPS_INSN16, + BFD_RELOC_NANOMIPS_FIXED, + BFD_RELOC_NANOMIPS_RELAX, + BFD_RELOC_NANOMIPS_NORELAX, + BFD_RELOC_NANOMIPS_SAVERESTORE, + BFD_RELOC_NANOMIPS_JALR16, + BFD_RELOC_NANOMIPS_JALR32, + BFD_RELOC_NANOMIPS_COPY, + BFD_RELOC_NANOMIPS_SIGNED_9, + BFD_RELOC_NANOMIPS_JUMPTABLE_LOAD, + + /* Moxie ELF relocations. */ BFD_RELOC_MOXIE_10_PCREL, diff --git a/bfd/config.bfd b/bfd/config.bfd index 954837033c8..6f9324f89a8 100644 --- a/bfd/config.bfd +++ b/bfd/config.bfd @@ -202,6 +202,7 @@ m6812*|m68hc12*) targ_archs="bfd_m68hc12_arch bfd_m68hc11_arch bfd_m9s12x_arch b m68*) targ_archs=bfd_m68k_arch ;; microblaze*) targ_archs=bfd_microblaze_arch ;; mips*) targ_archs=bfd_mips_arch ;; +nanomips*) targ_archs=bfd_nanomips_arch ;; nds32*) targ_archs=bfd_nds32_arch ;; nios2*) targ_archs=bfd_nios2_arch ;; or1k*|or1knd*) targ_archs=bfd_or1k_arch ;; @@ -1020,6 +1021,11 @@ case "${targ}" in targ_selvecs=msp430_elf32_ti_vec ;; + nanomips*-*-elf*) + targ_defvec=nanomips_elf32_le_vec + targ_selvecs="nanomips_elf32_be_vec nanomips_elf64_be_vec nanomips_elf64_le_vec" + ;; + nds32*le-*-linux*) targ_defvec=nds32_elf32_linux_le_vec targ_selvecs=nds32_elf32_linux_be_vec diff --git a/bfd/configure b/bfd/configure index 41d280ef461..81cb3cfec49 100755 --- a/bfd/configure +++ b/bfd/configure @@ -13988,6 +13988,10 @@ do msp430_elf32_vec) tb="$tb elf32-msp430.lo elf32.lo $elf" ;; msp430_elf32_ti_vec) tb="$tb elf32-msp430.lo elf32.lo $elf" ;; mt_elf32_vec) tb="$tb elf32-mt.lo elf32.lo $elf" ;; + nanomips_elf32_be_vec) tb="$tb elf32-nanomips.lo elfxx-nanomips.lo elf32.lo $elf ecofflink.lo" ;; + nanomips_elf32_le_vec) tb="$tb elf32-nanomips.lo elfxx-nanomips.lo elf32.lo $elf ecofflink.lo" ;; + nanomips_elf64_be_vec) tb="$tb elf64-nanomips.lo elf64.lo elfxx-nanomips.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;; + nanomips_elf64_le_vec) tb="$tb elf64-nanomips.lo elf64.lo elfxx-nanomips.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;; nds32_elf32_be_vec) tb="$tb elf32-nds32.lo elf32.lo $elf" ;; nds32_elf32_le_vec) tb="$tb elf32-nds32.lo elf32.lo $elf" ;; nds32_elf32_linux_be_vec) tb="$tb elf32-nds32.lo elf32.lo $elf" ;; diff --git a/bfd/configure.ac b/bfd/configure.ac index f044616f4d9..b2c54704d48 100644 --- a/bfd/configure.ac +++ b/bfd/configure.ac @@ -555,6 +555,10 @@ do msp430_elf32_vec) tb="$tb elf32-msp430.lo elf32.lo $elf" ;; msp430_elf32_ti_vec) tb="$tb elf32-msp430.lo elf32.lo $elf" ;; mt_elf32_vec) tb="$tb elf32-mt.lo elf32.lo $elf" ;; + nanomips_elf32_be_vec) tb="$tb elf32-nanomips.lo elfxx-nanomips.lo elf32.lo $elf ecofflink.lo" ;; + nanomips_elf32_le_vec) tb="$tb elf32-nanomips.lo elfxx-nanomips.lo elf32.lo $elf ecofflink.lo" ;; + nanomips_elf64_be_vec) tb="$tb elf64-nanomips.lo elf64.lo elfxx-nanomips.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;; + nanomips_elf64_le_vec) tb="$tb elf64-nanomips.lo elf64.lo elfxx-nanomips.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;; nds32_elf32_be_vec) tb="$tb elf32-nds32.lo elf32.lo $elf" ;; nds32_elf32_le_vec) tb="$tb elf32-nds32.lo elf32.lo $elf" ;; nds32_elf32_linux_be_vec) tb="$tb elf32-nds32.lo elf32.lo $elf" ;; diff --git a/bfd/cpu-nanomips.c b/bfd/cpu-nanomips.c new file mode 100644 index 00000000000..2cd66786cfe --- /dev/null +++ b/bfd/cpu-nanomips.c @@ -0,0 +1,61 @@ +/* bfd back-end for nanomips support + Copyright (C) 2018-2022 Free Software Foundation, Inc. + + Written by Faraz Shahbazker + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#include "sysdep.h" +#include "bfd.h" +#include "libbfd.h" + +#define N(BITS_WORD, BITS_ADDR, NUMBER, PRINT, DEFAULT, NEXT) \ + { \ + BITS_WORD, /* bits in a word */ \ + BITS_ADDR, /* bits in an address */ \ + 8, /* 8 bits in a byte */ \ + bfd_arch_nanomips, \ + NUMBER, \ + "nanomips", \ + PRINT, \ + 3, \ + DEFAULT, \ + bfd_default_compatible, \ + bfd_default_scan, \ + bfd_arch_default_fill, \ + NEXT, \ + 0 /* Maximum offset of a reloc from the start of an insn. */ \ + } + +enum +{ + I_nanomipsisa32r6, + I_nanomipsisa64r6, +}; + +#define NN(index) (&arch_info_struct[(index) + 1]) + +static const bfd_arch_info_type arch_info_struct[] = { + N (32, 32, bfd_mach_nanomipsisa32r6, "nanomips:isa32r6", false, + NN (I_nanomipsisa32r6)), + N (64, 64, bfd_mach_nanomipsisa64r6, "nanomips:isa64r6", false, + 0), +}; + +const bfd_arch_info_type bfd_nanomips_arch = +N (32, 32, 0, "nanomips", true, &arch_info_struct[0]); diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 2a64a1e6a03..cbdc0d61758 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -554,6 +554,7 @@ enum elf_target_id MICROBLAZE_ELF_DATA, MIPS_ELF_DATA, MN10300_ELF_DATA, + NANOMIPS_ELF_DATA, NDS32_ELF_DATA, NIOS2_ELF_DATA, OR1K_ELF_DATA, diff --git a/bfd/elfnn-nanomips.c b/bfd/elfnn-nanomips.c new file mode 100644 index 00000000000..e134a51c5ee --- /dev/null +++ b/bfd/elfnn-nanomips.c @@ -0,0 +1,1423 @@ +/* nanoMIPS-specific support for 32-bit ELF + Copyright (C) 2018-2022 Free Software Foundation, Inc. + + Written by Faraz Shahbazker + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + + +/* This file handles nanoMIPS ELF targets. */ + +#include "sysdep.h" +#include "bfd.h" +#include "libbfd.h" +#include "elf-bfd.h" +#include "elfxx-nanomips.h" +#include "elf/nanomips.h" + +#define ARCH_SIZE NN + +#if ARCH_SIZE == 32 +/* Nonzero if ABFD is using the P32 ABI. */ +#define ABI_P32_P(abfd) \ + ((elf_elfheader (abfd)->e_flags & EF_NANOMIPS_ABI) != E_NANOMIPS_ABI_P64) +#else /* ARCH_SIZE != 32 */ +/* Nonzero if ABFD is using the P64 ABI. */ +#define ABI_P64_P(abfd) \ + ((elf_elfheader (abfd)->e_flags & EF_NANOMIPS_ABI) != E_NANOMIPS_ABI_P32) +#endif /* ARCH_SIZE == 32 */ + +/* In case we're on a 32-bit machine, construct a 64-bit "-1" value + from smaller values. Start with zero, widen, *then* decrement. */ +#define MINUS_ONE (((bfd_vma)0) - 1) + +/* The relocation table used for SHT_RELA sections. */ + +static reloc_howto_type elfNN_nanomips_howto_table_rela[] = { + /* No relocation. */ + HOWTO (R_NANOMIPS_NONE, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_NONE", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* 32 bit relocation. */ + HOWTO (R_NANOMIPS_32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_32", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 64 bit relocation. */ + HOWTO (R_NANOMIPS_64, /* type */ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_64", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + MINUS_ONE, /* dst_mask */ + false), /* pcrel_offset */ + + /* Symbol address negation, can be composed for label differences. */ + HOWTO (R_NANOMIPS_NEG, /* type */ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_nanomips_elf_negative_reloc, /* special_function */ + "R_NANOMIPS_NEG", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* A 5 bit shift field. */ + HOWTO (R_NANOMIPS_ASHIFTR_1, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_ASHIFTR_1", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO (R_NANOMIPS_UNSIGNED_8, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 8, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_UNSIGNED_8", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xff, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO (R_NANOMIPS_SIGNED_8, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 8, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_SIGNED_8", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xff, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO (R_NANOMIPS_UNSIGNED_16, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_UNSIGNED_16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO (R_NANOMIPS_SIGNED_16, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_SIGNED_16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + EMPTY_HOWTO (R_NANOMIPS_RELATIVE), + EMPTY_HOWTO (R_NANOMIPS_GLOBAL), + + /* Lazy resolver jump slot. */ + HOWTO (R_NANOMIPS_JUMP_SLOT, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_JUMP_SLOT", /* name */ + false, /* partial_inplace */ + 0x0, /* src_mask */ + 0x0, /* dst_mask */ + false), /* pcrel_offset */ + + /* Reserved for IFUNC support. */ + EMPTY_HOWTO (R_NANOMIPS_IRELATIVE), + + HOWTO (R_NANOMIPS_PC25_S1, /* type */ + 1, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 25, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_PC25_S1", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x01ffffff, /* dst_mask */ + true), /* pcrel_offset */ + + HOWTO (R_NANOMIPS_PC21_S1, /* type */ + 1, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 21, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_PC21_S1", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0001ffff, /* dst_mask */ + true), /* pcrel_offset */ + + HOWTO (R_NANOMIPS_PC14_S1, /* type */ + 1, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 14, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_PC14_S1", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x00003fff, /* dst_mask */ + true), /* pcrel_offset */ + + HOWTO (R_NANOMIPS_PC11_S1, /* type */ + 1, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 11, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_PC11_S1", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x000007ff, /* dst_mask */ + true), /* pcrel_offset */ + + HOWTO (R_NANOMIPS_PC10_S1, /* type */ + 1, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 10, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_PC10_S1", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x000003ff, /* dst_mask */ + true), /* pcrel_offset */ + + /* This is for nanoMIPS branches. */ + HOWTO (R_NANOMIPS_PC7_S1, /* type */ + 1, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 7, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_PC7_S1", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000007f, /* dst_mask */ + true), /* pcrel_offset */ + + HOWTO (R_NANOMIPS_PC4_S1, /* type */ + 1, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 4, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_PC4_S1", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000000f, /* dst_mask */ + true), /* pcrel_offset */ + + /* GP relative reference. */ + HOWTO (R_NANOMIPS_GPREL19_S2, /* type */ + 2, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 19, /* bitsize */ + false, /* pc_relative */ + 2, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_GPREL19_S2", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x001ffffc, /* dst_mask */ + false), /* pcrel_offset */ + + /* GP relative reference. */ + HOWTO (R_NANOMIPS_GPREL18_S3, /* type */ + 3, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 18, /* bitsize */ + false, /* pc_relative */ + 3, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_GPREL18_S3", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x001ffff8, /* dst_mask */ + false), /* pcrel_offset */ + + /* GP relative reference. */ + HOWTO (R_NANOMIPS_GPREL18, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 18, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_GPREL18", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0003ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* GP relative reference. */ + HOWTO (R_NANOMIPS_GPREL17_S1, /* type */ + 1, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 17, /* bitsize */ + false, /* pc_relative */ + 1, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_GPREL17_S1", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0001fffe, /* dst_mask */ + false), /* pcrel_offset */ + + /* GP relative reference. */ + HOWTO (R_NANOMIPS_GPREL16_S2, /* type */ + 2, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 2, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_GPREL16_S2", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0003fffc, /* dst_mask */ + false), /* pcrel_offset */ + + /* GP- and PC-relative relocations. */ + HOWTO (R_NANOMIPS_GPREL7_S2, /* type */ + 2, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 7, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_GPREL7_S2", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000007f, /* dst_mask */ + false), /* pcrel_offset */ + + /* High 20 bits of GP relative reference. */ + HOWTO (R_NANOMIPS_GPREL_HI20, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 20, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_GPREL_HI20", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x001ffffd, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO (R_NANOMIPS_PCHI20, /* type */ + 12, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 20, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_PCHI20", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x001ffffd, /* dst_mask */ + true), /* pcrel_offset */ + + /* High 20 bits of symbol value. */ + HOWTO (R_NANOMIPS_HI20, /* type */ + 12, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 20, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_HI20", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x001ffffd, /* dst_mask */ + false), /* pcrel_offset */ + + /* Low 12 bits of symbol value. */ + HOWTO (R_NANOMIPS_LO12, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 12, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_LO12", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x00000fff, /* dst_mask */ + false), /* pcrel_offset */ + + /* High 32 bits of 64-bit address. */ + HOWTO (R_NANOMIPS_GPREL_I32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_GPREL_I32", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* High 32 bits of 64-bit address. */ + HOWTO (R_NANOMIPS_PC_I32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_PC_I32", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Refers to low 32-bits of 48-bit instruction. The 32-bit value + is encoded as nanoMIPS instruction stream - so it will be + half-word swapped on little endian targets. */ + HOWTO (R_NANOMIPS_I32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_I32", /* name */ + false, /* partial_inplace */ + 0x0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Displacement in the global offset table. */ + HOWTO (R_NANOMIPS_GOT_DISP, /* type */ + 2, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 19, /* bitsize */ + false, /* pc_relative */ + 2, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_GOT_DISP", /* name */ + false, /* partial_inplace */ + 0x0, /* src_mask */ + 0x001ffffc, /* dst_mask */ + false), /* pcrel_offset */ + /* High 32 bits of 64-bit address. */ + HOWTO (R_NANOMIPS_GOTPC_I32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_GOTPC_I32", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* High 20 bits of PC-relative GOT offset. */ + HOWTO (R_NANOMIPS_GOTPC_HI20, /* type */ + 12, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 20, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_GOTPC_HI20", /* name */ + false, /* partial_inplace */ + 0x0, /* src_mask */ + 0x001ffffd, /* dst_mask */ + true), /* pcrel_offset */ + + /* Low 12 bits of displacement in global offset table. */ + HOWTO (R_NANOMIPS_GOT_LO12, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 12, /* bitsize */ + false, /* pc_relative */ + 2, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_GOT_LO12", /* name */ + false, /* partial_inplace */ + 0x0, /* src_mask */ + 0x00000fff, /* dst_mask */ + true), /* pcrel_offset */ + + /* 19 bit call through global offset table. */ + HOWTO (R_NANOMIPS_GOT_CALL, /* type */ + 2, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 19, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_GOT_CALL", /* name */ + false, /* partial_inplace */ + 0x0, /* src_mask */ + 0x001ffffc, /* dst_mask */ + false), /* pcrel_offset */ + + /* Displacement to page pointer in the global offset table. */ + HOWTO (R_NANOMIPS_GOT_PAGE, /* type */ + 2, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 19, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_GOT_PAGE", /* name */ + false, /* partial_inplace */ + 0x0, /* src_mask */ + 0x001ffffc, /* dst_mask */ + false), /* pcrel_offset */ + + /* Offset from page pointer in the global offset table. */ + HOWTO (R_NANOMIPS_GOT_OFST, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 12, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_GOT_OFST", /* name */ + false, /* partial_inplace */ + 0x0, /* src_mask */ + 0x00000fff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Low 4 bits of symbol value. */ + HOWTO (R_NANOMIPS_LO4_S2, /* type */ + 2, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 4, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_LO4_S2", /* name */ + false, /* partial_inplace */ + 0x0000000f, /* src_mask */ + 0x0000000f, /* dst_mask */ + false), /* pcrel_offset */ + + /* Reserved for 64-bit ABI, HI32 relocation. */ + EMPTY_HOWTO (R_NANOMIPS_RESERVED1), + + /* Low 12 bits of GP-relative displacement. */ + HOWTO (R_NANOMIPS_GPREL_LO12, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 12, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_GPREL_LO12", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x00000fff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Section displacement. */ + HOWTO (R_NANOMIPS_SCN_DISP, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_SCN_DISP", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Copy relocation. */ + HOWTO (R_NANOMIPS_COPY, /* type */ + 0, /* rightshift */ + 0, /* this one is variable size */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_COPY", /* name */ + false, /* partial_inplace */ + 0x0, /* src_mask */ + 0x0, /* dst_mask */ + false), /* pcrel_offset */ + + EMPTY_HOWTO (45), + EMPTY_HOWTO (46), + EMPTY_HOWTO (47), + EMPTY_HOWTO (48), + EMPTY_HOWTO (49), + EMPTY_HOWTO (50), + EMPTY_HOWTO (51), + EMPTY_HOWTO (52), + EMPTY_HOWTO (53), + EMPTY_HOWTO (54), + EMPTY_HOWTO (55), + EMPTY_HOWTO (56), + EMPTY_HOWTO (57), + EMPTY_HOWTO (58), + EMPTY_HOWTO (59), + EMPTY_HOWTO (60), + EMPTY_HOWTO (61), + EMPTY_HOWTO (62), + EMPTY_HOWTO (63), + + /* Place-holder for code alignment. */ + HOWTO (R_NANOMIPS_ALIGN, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special handler. */ + "R_NANOMIPS_ALIGN", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* Fill value for code alignment. */ + HOWTO (R_NANOMIPS_FILL, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special handler. */ + "R_NANOMIPS_FILL", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* Maximum padding bytes for code alignment. */ + HOWTO (R_NANOMIPS_MAX, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special handler. */ + "R_NANOMIPS_MAX", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* Place-holder to enforce 32-bit instruction encoding. */ + HOWTO (R_NANOMIPS_INSN32, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special handler. */ + "R_NANOMIPS_INSN32", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* Place-holder to inhibit relaxation on one instruction. */ + HOWTO (R_NANOMIPS_FIXED, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special handler. */ + "R_NANOMIPS_FIXED", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* Marker to inhibit linker relaxation. */ + HOWTO (R_NANOMIPS_NORELAX, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special handler. */ + "R_NANOMIPS_NORELAX", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* Marker to enable linker relaxation. */ + HOWTO (R_NANOMIPS_RELAX, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special handler. */ + "R_NANOMIPS_RELAX", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* Place-holder for relaxation of save/restore instructions. */ + HOWTO (R_NANOMIPS_SAVERESTORE, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special handler. */ + "R_NANOMIPS_SAVERESTORE", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* Place-holder to enforce 16-bit instruction encoding. */ + HOWTO (R_NANOMIPS_INSN16, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special handler. */ + "R_NANOMIPS_INSN16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* Place-holder to enforce 32-bit JALR encoding. */ + HOWTO (R_NANOMIPS_JALR32, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special handler. */ + "R_NANOMIPS_JALR32", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* Place-holder to enforce 16-bit JALR encoding. */ + HOWTO (R_NANOMIPS_JALR16, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special handler. */ + "R_NANOMIPS_JALR16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* Place-holder for compressed jump-table load instructions. */ + HOWTO (R_NANOMIPS_JUMPTABLE_LOAD, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special handler */ + "R_NANOMIPS_JUMPTABLE_LOAD", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* Place-holder for relaxing frame-register information. */ + HOWTO (R_NANOMIPS_FRAME_REG, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special handler */ + "R_NANOMIPS_FRAME_REG", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + + EMPTY_HOWTO (77), + EMPTY_HOWTO (78), + EMPTY_HOWTO (79), + + /* TLS GD/LD dynamic relocations. */ + HOWTO (R_NANOMIPS_TLS_DTPMOD, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_TLS_DTPMOD", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO (R_NANOMIPS_TLS_DTPREL, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_TLS_DTPREL", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* TLS IE dynamic relocations. */ + HOWTO (R_NANOMIPS_TLS_TPREL, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_TLS_TPREL", /* name */ + false, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* TLS general dynamic variable reference. */ + HOWTO (R_NANOMIPS_TLS_GD, /* type */ + 2, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 19, /* bitsize */ + false, /* pc_relative */ + 2, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_TLS_GD", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x001ffffc, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO (R_NANOMIPS_TLS_GD_I32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_TLS_GD_I32", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* TLS local dynamic variable reference. */ + HOWTO (R_NANOMIPS_TLS_LD, /* type */ + 2, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 19, /* bitsize */ + false, /* pc_relative */ + 2, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_TLS_LD", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x001ffffc, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO (R_NANOMIPS_TLS_LD_I32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_TLS_LD_I32", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* TLS local dynamic 12-bit offset. */ + HOWTO (R_NANOMIPS_TLS_DTPREL12, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 12, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_TLS_DTPREL12", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x00000fff, /* dst_mask */ + false), /* pcrel_offset */ + + /* TLS local dynamic 16-bit offset. */ + HOWTO (R_NANOMIPS_TLS_DTPREL16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_TLS_DTPREL16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* TLS local dynamic 32-bit offset. */ + HOWTO (R_NANOMIPS_TLS_DTPREL_I32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_TLS_DTPREL_I32", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* TLS thread pointer 21-bit GOT offset. */ + HOWTO (R_NANOMIPS_TLS_GOTTPREL, /* type */ + 2, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 19, /* bitsize */ + false, /* pc_relative */ + 2, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_TLS_GOTTPREL", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x001ffffc, /* dst_mask */ + false), /* pcrel_offset */ + + /* TLS thread pointer 32-bit GOT offset. */ + HOWTO (R_NANOMIPS_TLS_GOTTPREL_PC_I32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_TLS_GOTTPREL_PC_I32", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + true), /* pcrel_offset */ + + /* TLS thread pointer 12-bit offset. */ + HOWTO (R_NANOMIPS_TLS_TPREL12, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 12, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_TLS_TPREL12", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x00000fff, /* dst_mask */ + false), /* pcrel_offset */ + + /* TLS thread pointer 16-bit offset. */ + HOWTO (R_NANOMIPS_TLS_TPREL16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_TLS_TPREL16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* TLS thread pointer 32-bit offset. */ + HOWTO (R_NANOMIPS_TLS_TPREL_I32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_TLS_TPREL_I32", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ +}; + +/* GNU extension to record C++ vtable hierarchy */ +static reloc_howto_type elf_nanomips_gnu_vtinherit_howto = + HOWTO (R_NANOMIPS_GNU_VTINHERIT, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + NULL, /* special_function */ + "R_NANOMIPS_GNU_VTINHERIT", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false); /* pcrel_offset */ + +/* GNU extension to record C++ vtable member usage */ +static reloc_howto_type elf_nanomips_gnu_vtentry_howto = + HOWTO (R_NANOMIPS_GNU_VTENTRY, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_elf_rel_vtable_reloc_fn, /* special_function */ + "R_NANOMIPS_GNU_VTENTRY", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false); /* pcrel_offset */ + +/* 32 bit pc-relative. */ +static reloc_howto_type elf_nanomips_gnu_pcrel32 = + HOWTO (R_NANOMIPS_PC32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_PC32", /* name */ + true, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + true); /* pcrel_offset */ + +/* Used in EH tables. */ +static reloc_howto_type elf_nanomips_eh_howto = + HOWTO (R_NANOMIPS_EH, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_nanomips_elf_generic_reloc, /* special_function */ + "R_NANOMIPS_EH", /* name */ + true, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + false); /* pcrel_offset */ + +/* A mapping from BFD reloc types to nanoMIPS ELF reloc types. */ + +struct elf_reloc_map +{ + bfd_reloc_code_real_type bfd_val; + enum elf_nanomips_reloc_type elf_val; +}; + +static const struct elf_reloc_map nanomips_reloc_map[] = { + { BFD_RELOC_NONE, R_NANOMIPS_NONE }, + { BFD_RELOC_32, R_NANOMIPS_32 }, + { BFD_RELOC_64, R_NANOMIPS_64 }, + { BFD_RELOC_NANOMIPS_NEG, R_NANOMIPS_NEG }, + { BFD_RELOC_NANOMIPS_ASHIFTR_1, R_NANOMIPS_ASHIFTR_1 }, + { BFD_RELOC_NANOMIPS_UNSIGNED_8, R_NANOMIPS_UNSIGNED_8 }, + { BFD_RELOC_NANOMIPS_SIGNED_8, R_NANOMIPS_SIGNED_8 }, + { BFD_RELOC_NANOMIPS_UNSIGNED_16, R_NANOMIPS_UNSIGNED_16 }, + { BFD_RELOC_16, R_NANOMIPS_UNSIGNED_16 }, + { BFD_RELOC_NANOMIPS_SIGNED_16, R_NANOMIPS_SIGNED_16 }, + { BFD_RELOC_NANOMIPS_HI20, R_NANOMIPS_HI20 }, + { BFD_RELOC_NANOMIPS_LO12, R_NANOMIPS_LO12 }, + { BFD_RELOC_NANOMIPS_IMM16, R_NANOMIPS_LO12 }, + { BFD_RELOC_NANOMIPS_25_PCREL_S1, R_NANOMIPS_PC25_S1 }, + { BFD_RELOC_NANOMIPS_21_PCREL_S1, R_NANOMIPS_PC21_S1 }, + { BFD_RELOC_NANOMIPS_14_PCREL_S1, R_NANOMIPS_PC14_S1 }, + { BFD_RELOC_NANOMIPS_11_PCREL_S1, R_NANOMIPS_PC11_S1 }, + { BFD_RELOC_NANOMIPS_10_PCREL_S1, R_NANOMIPS_PC10_S1 }, + { BFD_RELOC_NANOMIPS_7_PCREL_S1, R_NANOMIPS_PC7_S1 }, + { BFD_RELOC_NANOMIPS_GPREL7_S2, R_NANOMIPS_GPREL7_S2 }, + { BFD_RELOC_NANOMIPS_GPREL18, R_NANOMIPS_GPREL18 }, + { BFD_RELOC_NANOMIPS_GPREL19_S2, R_NANOMIPS_GPREL19_S2 }, + { BFD_RELOC_NANOMIPS_4_PCREL_S1,R_NANOMIPS_PC4_S1 }, + { BFD_RELOC_NANOMIPS_PCREL_HI20, R_NANOMIPS_PCHI20 }, + { BFD_RELOC_NANOMIPS_GPREL16_S2, R_NANOMIPS_GPREL16_S2 }, + { BFD_RELOC_NANOMIPS_GPREL18_S3, R_NANOMIPS_GPREL18_S3 }, + { BFD_RELOC_NANOMIPS_GOT_CALL, R_NANOMIPS_GOT_CALL }, + { BFD_RELOC_NANOMIPS_GOT_DISP, R_NANOMIPS_GOT_DISP }, + { BFD_RELOC_NANOMIPS_GOT_PAGE, R_NANOMIPS_GOT_PAGE }, + { BFD_RELOC_NANOMIPS_GOT_OFST, R_NANOMIPS_GOT_OFST }, + { BFD_RELOC_NANOMIPS_GOTPC_HI20, R_NANOMIPS_GOTPC_HI20 }, + { BFD_RELOC_NANOMIPS_GOT_LO12, R_NANOMIPS_GOT_LO12 }, + { BFD_RELOC_NANOMIPS_GOTPC_I32, R_NANOMIPS_GOTPC_I32 }, + { BFD_RELOC_NANOMIPS_I32, R_NANOMIPS_I32 }, + { BFD_RELOC_NANOMIPS_GPREL_HI20, R_NANOMIPS_GPREL_HI20 }, + { BFD_RELOC_NANOMIPS_PC_I32, R_NANOMIPS_PC_I32 }, + { BFD_RELOC_NANOMIPS_GPREL_I32, R_NANOMIPS_GPREL_I32 }, + { BFD_RELOC_NANOMIPS_GPREL17_S1, R_NANOMIPS_GPREL17_S1 }, + { BFD_RELOC_NANOMIPS_GPREL_LO12, R_NANOMIPS_GPREL_LO12 }, + { BFD_RELOC_NANOMIPS_LO4_S2, R_NANOMIPS_LO4_S2 }, + { BFD_RELOC_NANOMIPS_COPY, R_NANOMIPS_COPY }, + + { BFD_RELOC_NANOMIPS_ALIGN, R_NANOMIPS_ALIGN }, + { BFD_RELOC_NANOMIPS_FILL, R_NANOMIPS_FILL }, + { BFD_RELOC_NANOMIPS_MAX, R_NANOMIPS_MAX }, + { BFD_RELOC_NANOMIPS_INSN32, R_NANOMIPS_INSN32 }, + { BFD_RELOC_NANOMIPS_INSN16, R_NANOMIPS_INSN16 }, + { BFD_RELOC_NANOMIPS_FIXED, R_NANOMIPS_FIXED }, + { BFD_RELOC_NANOMIPS_RELAX, R_NANOMIPS_RELAX }, + { BFD_RELOC_NANOMIPS_NORELAX, R_NANOMIPS_NORELAX }, + { BFD_RELOC_NANOMIPS_SAVERESTORE, R_NANOMIPS_SAVERESTORE }, + { BFD_RELOC_NANOMIPS_JALR32, R_NANOMIPS_JALR32 }, + { BFD_RELOC_NANOMIPS_JALR16, R_NANOMIPS_JALR16 }, + { BFD_RELOC_NANOMIPS_JUMPTABLE_LOAD, R_NANOMIPS_JUMPTABLE_LOAD }, + + { BFD_RELOC_NANOMIPS_TLS_GD, R_NANOMIPS_TLS_GD }, + { BFD_RELOC_NANOMIPS_TLS_GD_I32, R_NANOMIPS_TLS_GD_I32 }, + { BFD_RELOC_NANOMIPS_TLS_LD, R_NANOMIPS_TLS_LD }, + { BFD_RELOC_NANOMIPS_TLS_LD_I32, R_NANOMIPS_TLS_LD_I32 }, + { BFD_RELOC_NANOMIPS_TLS_DTPREL12, R_NANOMIPS_TLS_DTPREL12 }, + { BFD_RELOC_NANOMIPS_TLS_DTPREL16, R_NANOMIPS_TLS_DTPREL16 }, + { BFD_RELOC_NANOMIPS_TLS_DTPREL_I32, R_NANOMIPS_TLS_DTPREL_I32 }, + { BFD_RELOC_NANOMIPS_TLS_GOTTPREL, R_NANOMIPS_TLS_GOTTPREL }, + { BFD_RELOC_NANOMIPS_TLS_GOTTPREL_PC_I32, R_NANOMIPS_TLS_GOTTPREL_PC_I32 }, + { BFD_RELOC_NANOMIPS_TLS_TPREL12, R_NANOMIPS_TLS_TPREL12 }, + { BFD_RELOC_NANOMIPS_TLS_TPREL16, R_NANOMIPS_TLS_TPREL16 }, + { BFD_RELOC_NANOMIPS_TLS_TPREL_I32, R_NANOMIPS_TLS_TPREL_I32 }, + { BFD_RELOC_NANOMIPS_TLS_DTPMOD, R_NANOMIPS_TLS_DTPMOD }, + { BFD_RELOC_NANOMIPS_TLS_DTPREL, R_NANOMIPS_TLS_DTPREL }, + { BFD_RELOC_NANOMIPS_TLS_TPREL, R_NANOMIPS_TLS_TPREL }, +}; + +/* Given a BFD reloc type, return a howto structure. */ + +static reloc_howto_type * +bfd_elfNN_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) +{ + unsigned int i; + reloc_howto_type *howto_nanomips_table; + + howto_nanomips_table = elfNN_nanomips_howto_table_rela; + + for (i = 0; i < sizeof (nanomips_reloc_map) / sizeof (struct elf_reloc_map); + i++) + { + if (nanomips_reloc_map[i].bfd_val == code) + return &howto_nanomips_table[(int) nanomips_reloc_map[i].elf_val]; + } + + switch (code) + { + default: + bfd_set_error (bfd_error_bad_value); + return NULL; + + case BFD_RELOC_CTOR: + return &howto_nanomips_table[(int) R_NANOMIPS_32]; + + case BFD_RELOC_VTABLE_INHERIT: + return &elf_nanomips_gnu_vtinherit_howto; + case BFD_RELOC_VTABLE_ENTRY: + return &elf_nanomips_gnu_vtentry_howto; + case BFD_RELOC_NANOMIPS_EH: + return &elf_nanomips_eh_howto; + case BFD_RELOC_32_PCREL: + return &elf_nanomips_gnu_pcrel32; + } +} + +/* Map a BFD relocation to its display name. */ + +static reloc_howto_type * +bfd_elfNN_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, + const char *r_name) +{ + unsigned int i; + + for (i = 0; + i < (sizeof (elfNN_nanomips_howto_table_rela) + / sizeof (elfNN_nanomips_howto_table_rela[0])); i++) + if (elfNN_nanomips_howto_table_rela[i].name != NULL + && strcasecmp (elfNN_nanomips_howto_table_rela[i].name, r_name) == 0) + return &elfNN_nanomips_howto_table_rela[i]; + + if (strcasecmp (elf_nanomips_gnu_vtinherit_howto.name, r_name) == 0) + return &elf_nanomips_gnu_vtinherit_howto; + if (strcasecmp (elf_nanomips_gnu_vtentry_howto.name, r_name) == 0) + return &elf_nanomips_gnu_vtentry_howto; + if (strcasecmp (elf_nanomips_eh_howto.name, r_name) == 0) + return &elf_nanomips_eh_howto; + + return NULL; +} + +/* Given a nanoMIPS Elf_Internal_Rel, fill in an arelent structure. */ + +static reloc_howto_type * +nanomips_elfNN_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED, + unsigned int r_type, + bool rela_p ATTRIBUTE_UNUSED) +{ + switch (r_type) + { + case R_NANOMIPS_GNU_VTINHERIT: + return &elf_nanomips_gnu_vtinherit_howto; + case R_NANOMIPS_GNU_VTENTRY: + return &elf_nanomips_gnu_vtentry_howto; + case R_NANOMIPS_EH: + return &elf_nanomips_eh_howto; + case R_NANOMIPS_PC32: + return &elf_nanomips_gnu_pcrel32; + default: + return &elfNN_nanomips_howto_table_rela[r_type]; + } +} + +/* Given a nanoMIPS Elf_Internal_Rela, fill in an arelent structure. */ + +static bool +nanomips_info_to_howto_rela (bfd *abfd, arelent *cache_ptr, + Elf_Internal_Rela *dst) +{ + const struct elf_backend_data *bed; + unsigned int r_type; + + r_type = ELFNN_R_TYPE (dst->r_info); + bed = get_elf_backend_data (abfd); + cache_ptr->howto = bed->elf_backend_mips_rtype_to_howto (abfd, r_type, true); + cache_ptr->addend = dst->r_addend; + return true; +} + +/* nanoMIPS ELF local labels start with '$'. */ + +static bool +nanomips_elf_is_local_label_name (bfd *abfd, const char *name) +{ + if (name[0] == '$') + return true; + + /* Fall back to the generic ELF local label syntax. */ + return _bfd_elf_is_local_label_name (abfd, name); +} + +/* Set the right machine number for a nanoMIPS ELF file. */ + +static bool +nanomips_elfNN_object_p (bfd *abfd) +{ + unsigned long mach; + + if (!ABI_PNN_P (abfd)) + return false; + + mach = _bfd_elf_nanomips_mach (elf_elfheader (abfd)->e_flags); + bfd_default_set_arch_mach (abfd, bfd_arch_nanomips, mach); + return true; +} + +#define ELF_ARCH bfd_arch_nanomips +#define ELF_TARGET_ID NANOMIPS_ELF_DATA +#define ELF_MACHINE_CODE EM_NANOMIPS + +#define elf_backend_collect true +#define elf_backend_type_change_ok true +#define elf_info_to_howto nanomips_info_to_howto_rela +#define elf_backend_object_p nanomips_elfNN_object_p +#define elf_backend_section_processing _bfd_nanomips_elf_section_processing +#define elf_backend_section_from_shdr _bfd_nanomips_elf_section_from_shdr +#define elf_backend_fake_sections _bfd_nanomips_elf_fake_sections +#define elf_backend_final_write_processing \ + _bfd_nanomips_elf_final_write_processing + +#define elf_backend_may_use_rela_p 1 +#define elf_backend_default_use_rela_p 1 +#define elf_backend_sign_extend_vma true +#define elf_backend_plt_readonly 1 + +#define bfd_elfNN_bfd_get_relocated_section_contents \ + _bfd_elf_nanomips_get_relocated_section_contents +#define elf_backend_mips_rtype_to_howto nanomips_elfNN_rtype_to_howto +#define bfd_elfNN_bfd_print_private_bfd_data \ + _bfd_nanomips_elf_print_private_bfd_data +#define bfd_elfNN_mkobject _bfd_nanomips_elf_mkobject +#define bfd_elfNN_bfd_is_local_label_name \ + nanomips_elf_is_local_label_name + +#define ELF_MAXPAGESIZE 0x1000 +#define ELF_COMMONPAGESIZE 0x1000 + +/* Support for nanomipsNN target. */ + +#define TARGET_LITTLE_SYM nanomips_elfNN_le_vec +#define TARGET_LITTLE_NAME "elfNN-littlenanomips" +#define TARGET_BIG_SYM nanomips_elfNN_be_vec +#define TARGET_BIG_NAME "elfNN-bignanomips" + +#define elfNN_bed elfNN_nanomips_bed + +/* Include the target file for this target. */ +#include "elfNN-target.h" diff --git a/bfd/elfxx-mips.h b/bfd/elfxx-mips.h index 2c790ed5ed6..a24c30f5d55 100644 --- a/bfd/elfxx-mips.h +++ b/bfd/elfxx-mips.h @@ -65,6 +65,8 @@ extern bool _bfd_mips_elf_create_dynamic_sections (bfd *, struct bfd_link_info *); extern bool _bfd_mips_elf_check_relocs (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *); +extern bool _bfd_mips_relax_section + (bfd *, asection *, struct bfd_link_info *, bool *again); extern bool _bfd_mips_elf_adjust_dynamic_symbol (struct bfd_link_info *, struct elf_link_hash_entry *); extern bool _bfd_mips_elf_always_size_sections @@ -133,6 +135,8 @@ extern const char * _bfd_mips_fp_abi_string (int); extern bool _bfd_mips_elf_print_private_bfd_data (bfd *, void *); +extern bool _bfd_nanomips_elf_print_private_bfd_data + (bfd *, void *); extern bool _bfd_mips_elf_discard_info (bfd *, struct elf_reloc_cookie *, struct bfd_link_info *); extern bool _bfd_mips_elf_write_section @@ -165,6 +169,7 @@ extern bfd_vma _bfd_mips_elf_sign_extend extern void _bfd_mips_elf_merge_symbol_attribute (struct elf_link_hash_entry *, unsigned int, bool, bool); extern char *_bfd_mips_elf_get_target_dtag (bfd_vma); +extern char *_bfd_nanomips_elf_get_target_dtag (bfd_vma); extern bool _bfd_mips_elf_ignore_undef_symbol (struct elf_link_hash_entry *); extern void _bfd_mips_elf_use_plts_and_copy_relocs diff --git a/bfd/elfxx-nanomips.c b/bfd/elfxx-nanomips.c new file mode 100644 index 00000000000..8405fe09c34 --- /dev/null +++ b/bfd/elfxx-nanomips.c @@ -0,0 +1,794 @@ +/* nanoMIPS-specific support for ELF + Copyright (C) 2018-2022 Free Software Foundation, Inc. + + Written by Faraz Shahbazker + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + + +/* This file handles functionality common to nanoMIPS ABIs. */ + +#include "sysdep.h" +#include "bfd.h" +#include "libbfd.h" +#include "elf-bfd.h" +#include "elfxx-nanomips.h" +#include "elf/nanomips.h" + +/* nanoMIPS ELF private object data. */ + +struct nanomips_elf_obj_tdata +{ + /* Generic ELF private object data. */ + struct elf_obj_tdata root; + + /* Input BFD providing Tag_GNU_NANOMIPS_ABI_FP attribute for output. */ + bfd *abi_fp_bfd; + + /* Input BFD providing Tag_GNU_NANOMIPS_ABI_MSA attribute for output. */ + bfd *abi_msa_bfd; + + /* The abiflags for this object. */ + Elf_Internal_ABIFlags_v0 abiflags; + bool abiflags_valid; + + bfd_signed_vma sdata_section[1000]; +}; + +/* Get nanoMIPS ELF private object data from BFD's tdata. */ + +#define nanomips_elf_tdata(bfd) \ + ((struct nanomips_elf_obj_tdata *) (bfd)->tdata.any) + +/* True if NAME is the recognized name of any SHT_NANOMIPS_ABIFLAGS section. */ + +#define NANOMIPS_ELF_ABIFLAGS_SECTION_NAME_P(NAME) \ + (strcmp (NAME, ".nanoMIPS.abiflags") == 0) + +/* Allocate nanoMIPS ELF private object data. */ + +bool +_bfd_nanomips_elf_mkobject (bfd *abfd) +{ + return bfd_elf_allocate_object (abfd, + sizeof (struct nanomips_elf_obj_tdata), + NANOMIPS_ELF_DATA); +} + +/* A generic howto special_function. This calculates and installs the + relocation itself, thus avoiding the oft-discussed problems in + bfd_perform_relocation and bfd_install_relocation. */ + +bfd_reloc_status_type +_bfd_nanomips_elf_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED, + arelent *reloc_entry, asymbol *symbol, + void *data ATTRIBUTE_UNUSED, + asection *input_section, bfd *output_bfd, + char **error_message ATTRIBUTE_UNUSED) +{ + bfd_signed_vma val; + bfd_reloc_status_type status; + bool relocatable; + + relocatable = (output_bfd != NULL); + + if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) + return bfd_reloc_outofrange; + + /* Build up the field adjustment in VAL. */ + val = 0; + if (!relocatable || (symbol->flags & BSF_SECTION_SYM) != 0) + { + /* Either we're calculating the final field value or we have a + relocation against a section symbol. Add in the section's + offset or address. */ + val += symbol->section->output_section->vma; + val += symbol->section->output_offset; + } + + if (!relocatable) + { + /* We're calculating the final field value. Add in the symbol's value + and, if pc-relative, subtract the address of the field itself. */ + val += symbol->value; + if (reloc_entry->howto->pc_relative) + { + val -= input_section->output_section->vma; + val -= input_section->output_offset; + val -= reloc_entry->address; + } + } + + /* VAL is now the final adjustment. If we're keeping this relocation + in the output file, and if the relocation uses a separate addend, + we just need to add VAL to that addend. Otherwise we need to add + VAL to the relocation field itself. */ + if (relocatable && !reloc_entry->howto->partial_inplace) + reloc_entry->addend += val; + else + { + bfd_byte *location = (bfd_byte *) data + reloc_entry->address; + + /* Add in the separate addend, if any. */ + val += reloc_entry->addend; + + /* Add VAL to the relocation field. */ + status = _bfd_relocate_contents (reloc_entry->howto, abfd, val, + location); + if (status != bfd_reloc_ok) + return status; + } + + if (relocatable) + reloc_entry->address += input_section->output_offset; + + return bfd_reloc_ok; +} + +/* A negation howto special_function. */ + +bfd_reloc_status_type +_bfd_nanomips_elf_negative_reloc (bfd *abfd ATTRIBUTE_UNUSED, + arelent *reloc_entry, asymbol *symbol, + void *data ATTRIBUTE_UNUSED, + asection *input_section, bfd *output_bfd, + char **error_message ATTRIBUTE_UNUSED) +{ + bfd_signed_vma val; + bool relocatable; + + relocatable = (output_bfd != NULL); + + if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) + return bfd_reloc_outofrange; + + /* Calculate the value of the symbol S. */ + val = symbol->section->output_section->vma; + val += symbol->section->output_offset; + val += symbol->value; + + /* Add negated value to addend: (-S + A). */ + if (! relocatable ) + reloc_entry->addend = -val + reloc_entry->addend; + + if (relocatable) + reloc_entry->address += input_section->output_offset; + + return bfd_reloc_ok; +} + +/* Swap in an abiflags structure. */ + +void +bfd_nanomips_elf_swap_abiflags_v0_in (bfd *abfd, + const Elf_External_ABIFlags_v0 *ex, + Elf_Internal_ABIFlags_v0 *in) +{ + in->version = H_GET_16 (abfd, ex->version); + in->isa_level = H_GET_8 (abfd, ex->isa_level); + in->isa_rev = H_GET_8 (abfd, ex->isa_rev); + in->gpr_size = H_GET_8 (abfd, ex->gpr_size); + in->cpr1_size = H_GET_8 (abfd, ex->cpr1_size); + in->cpr2_size = H_GET_8 (abfd, ex->cpr2_size); + in->fp_abi = H_GET_8 (abfd, ex->fp_abi); + in->isa_ext = H_GET_32 (abfd, ex->isa_ext); + in->ases = H_GET_32 (abfd, ex->ases); + in->flags1 = H_GET_32 (abfd, ex->flags1); + in->flags2 = H_GET_32 (abfd, ex->flags2); +} + +/* Swap out an abiflags structure. */ + +void +bfd_nanomips_elf_swap_abiflags_v0_out (bfd *abfd, + const Elf_Internal_ABIFlags_v0 *in, + Elf_External_ABIFlags_v0 *ex) +{ + H_PUT_16 (abfd, in->version, ex->version); + H_PUT_8 (abfd, in->isa_level, ex->isa_level); + H_PUT_8 (abfd, in->isa_rev, ex->isa_rev); + H_PUT_8 (abfd, in->gpr_size, ex->gpr_size); + H_PUT_8 (abfd, in->cpr1_size, ex->cpr1_size); + H_PUT_8 (abfd, in->cpr2_size, ex->cpr2_size); + H_PUT_8 (abfd, in->fp_abi, ex->fp_abi); + H_PUT_32 (abfd, in->isa_ext, ex->isa_ext); + H_PUT_32 (abfd, in->ases, ex->ases); + H_PUT_32 (abfd, in->flags1, ex->flags1); + H_PUT_32 (abfd, in->flags2, ex->flags2); +} + +/* Map flag bits to BFD architecture. */ + +unsigned long +_bfd_elf_nanomips_mach (flagword flags) +{ + switch (flags & EF_NANOMIPS_ARCH) + { + default: + case E_NANOMIPS_ARCH_32R6: + return bfd_mach_nanomipsisa32r6; + + case E_NANOMIPS_ARCH_64R6: + return bfd_mach_nanomipsisa64r6; + } + + return 0; +} + +/* Work over a section just before writing it out. This routine is + used by both the 32-bit and the 64-bit ABI. */ + +bool +_bfd_nanomips_elf_section_processing (bfd *abfd ATTRIBUTE_UNUSED, + Elf_Internal_Shdr *hdr) +{ + if (hdr->bfd_section != NULL) + { + const char *name = bfd_section_name (hdr->bfd_section); + + /* .sbss is not handled specially here because the GNU/Linux + prelinker can convert .sbss from NOBITS to PROGBITS and + changing it back to NOBITS breaks the binary. The entry in + _bfd_nanomips_elf_special_sections will ensure the correct flags + are set on .sbss if BFD creates it without reading it from an + input file, and without special handling here the flags set + on it in an input file will be followed. */ + if (strcmp (name, ".sdata") == 0 + || strcmp (name, ".lit8") == 0 + || strcmp (name, ".lit4") == 0 + || strncmp (name, ".sdata_", 7) == 0) + { + hdr->sh_flags |= SHF_ALLOC | SHF_WRITE; + hdr->sh_type = SHT_PROGBITS; + } + else if (strcmp (name, ".srdata") == 0) + { + hdr->sh_flags |= SHF_ALLOC; + hdr->sh_type = SHT_PROGBITS; + } + else if (strcmp (name, ".compact_rel") == 0) + { + hdr->sh_flags = 0; + hdr->sh_type = SHT_PROGBITS; + } + else if (strcmp (name, ".rtproc") == 0) + { + if (hdr->sh_addralign != 0 && hdr->sh_entsize == 0) + { + unsigned int adjust; + + adjust = hdr->sh_size % hdr->sh_addralign; + if (adjust != 0) + hdr->sh_size += hdr->sh_addralign - adjust; + } + } + } + + return true; +} + +/* Handle a nanoMIPS specific section when reading an object file. + This is called when elfcode.h finds a section with an unknown type. + This routine supports both the 32-bit and 64-bit ELF ABI. */ + +bool +_bfd_nanomips_elf_section_from_shdr (bfd *abfd, Elf_Internal_Shdr *hdr, + const char *name, int shindex) +{ + flagword flags = 0; + + /* There ought to be a place to keep ELF backend specific flags, but + at the moment there isn't one. We just keep track of the + sections by their name, instead. */ + switch (hdr->sh_type) + { + case SHT_NANOMIPS_ABIFLAGS: + if (!NANOMIPS_ELF_ABIFLAGS_SECTION_NAME_P (name)) + return false; + flags = (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_SAME_SIZE); + break; + default: + break; + } + + if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex)) + return false; + + if (flags) + { + if (!bfd_set_section_flags (hdr->bfd_section, + (bfd_section_flags (hdr->bfd_section) + | flags))) + return false; + } + + if (hdr->sh_type == SHT_NANOMIPS_ABIFLAGS) + { + Elf_External_ABIFlags_v0 ext; + + if (! bfd_get_section_contents (abfd, hdr->bfd_section, &ext, + 0, sizeof ext)) + return false; + bfd_nanomips_elf_swap_abiflags_v0_in + (abfd, &ext, &nanomips_elf_tdata (abfd)->abiflags); + if (nanomips_elf_tdata (abfd)->abiflags.version != 0) + return false; + nanomips_elf_tdata (abfd)->abiflags_valid = true; + } + + return true; +} + +/* Set the correct type for a nanoMIPS ELF section. We do this by the + section name, which is a hack, but ought to work. This routine is + used by both the 32-bit and the 64-bit ABI. */ + +bool +_bfd_nanomips_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED, + Elf_Internal_Shdr *hdr, + asection *sec) +{ + const char *name = bfd_section_name (sec); + + if (startswith (name, ".nanoMIPS.abiflags")) + { + hdr->sh_type = SHT_NANOMIPS_ABIFLAGS; + hdr->sh_entsize = sizeof (Elf_External_ABIFlags_v0); + } + + /* The generic elf_fake_sections will set up REL_HDR using the default + kind of relocations. */ + return true; +} + +/* Functions for the dynamic linker. */ + +/* Set ABFD's EF_NANOMIPS_ARCH and EF_NANOMIPS_MACH flags. */ + +static void +nanomips_set_isa_flags (bfd *abfd) +{ + flagword val = 0; + + switch (bfd_get_mach (abfd)) + { + case bfd_mach_nanomipsisa32r6: + val = E_NANOMIPS_ARCH_32R6; + break; + + case bfd_mach_nanomipsisa64r6: + val = E_NANOMIPS_ARCH_64R6; + break; + default: + break; + } + + elf_elfheader (abfd)->e_flags &= ~(EF_NANOMIPS_ARCH | EF_NANOMIPS_MACH); + elf_elfheader (abfd)->e_flags |= val; +} + +/* The final processing done just before writing out a nanoMIPS ELF + object file. This gets the nanoMIPS architecture right based on the + machine number. This is used by both the 32-bit and the 64-bit ABI. */ + +bool +_bfd_nanomips_elf_final_write_processing (bfd *abfd) +{ + nanomips_set_isa_flags (abfd); + return _bfd_elf_final_write_processing (abfd); +} + +/* Return the meaning of Tag_GNU_NANOMIPS_ABI_FP value FP, or null if + not known. */ + +const char * +_bfd_nanomips_fp_abi_string (int fp) +{ + switch (fp) + { + /* These strings aren't translated because they're simply + option lists. */ + case Val_GNU_NANOMIPS_ABI_FP_DOUBLE: + return "-mdouble-float"; + + case Val_GNU_NANOMIPS_ABI_FP_SINGLE: + return "-msingle-float"; + + case Val_GNU_NANOMIPS_ABI_FP_SOFT: + return "-msoft-float"; + + default: + return 0; + } +} + +/* Print the name of an ASE. */ + +static void +print_nanomips_ases (FILE *file, unsigned int mask) +{ + if (mask & NANOMIPS_ASE_DSPR3) + fputs ("\n\tDSP R3 ASE", file); + if (mask & NANOMIPS_ASE_EVA) + fputs ("\n\tEnhanced VA Scheme", file); + if (mask & NANOMIPS_ASE_MCU) + fputs ("\n\tMCU (MicroController) ASE", file); + if (mask & NANOMIPS_ASE_MT) + fputs ("\n\tMT ASE", file); + if (mask & NANOMIPS_ASE_VIRT) + fputs ("\n\tVZ ASE", file); + if (mask & NANOMIPS_ASE_MSA) + fputs ("\n\tMSA ASE", file); + if (mask & NANOMIPS_ASE_TLB) + fputs ("\n\tTLB ASE", file); + if (mask & NANOMIPS_ASE_CRC) + fputs ("\n\tCRC ASE", file); + if ((mask & NANOMIPS_ASE_xNMS) == 0) + fputs ("\n\tnanoMIPS subset", file); + else if (mask == 0) + fprintf (file, "\n\t%s", _("None")); + else if ((mask & ~NANOMIPS_ASE_MASK) != 0) + fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~NANOMIPS_ASE_MASK); +} + +/* Print the name of an ISA extension. None yet for nanoMIPS. */ + +static void +print_nanomips_isa_ext (FILE *file, unsigned int isa_ext) +{ + switch (isa_ext) + { + case 0: + fputs (_("None"), file); + break; + default: + fprintf (file, "%s (%d)", _("Unknown"), isa_ext); + break; + } +} + +/* Decode and print the FP ABI mode. */ + +static void +print_nanomips_fp_abi_value (FILE *file, int val) +{ + switch (val) + { + case Val_GNU_NANOMIPS_ABI_FP_ANY: + fprintf (file, _("Hard or soft float\n")); + break; + case Val_GNU_NANOMIPS_ABI_FP_DOUBLE: + fprintf (file, _("Hard float (double precision)\n")); + break; + case Val_GNU_NANOMIPS_ABI_FP_SINGLE: + fprintf (file, _("Hard float (single precision)\n")); + break; + case Val_GNU_NANOMIPS_ABI_FP_SOFT: + fprintf (file, _("Soft float\n")); + break; + default: + fprintf (file, "??? (%d)\n", val); + break; + } +} + +/* Map register type to size. */ + +static int +get_nanomips_reg_size (int reg_size) +{ + return ((reg_size == AFL_REG_NONE) ? 0 + : (reg_size == AFL_REG_32) ? 32 + : (reg_size == AFL_REG_64) ? 64 + : (reg_size == AFL_REG_128) ? 128 + : -1); +} + +/* Print nanoMIPS-specific ELF data. */ + +bool +_bfd_nanomips_elf_print_private_bfd_data (bfd *abfd, void *ptr) +{ + FILE *file = ptr; + + BFD_ASSERT (abfd != NULL && ptr != NULL); + + /* Print normal ELF private data. */ + _bfd_elf_print_private_bfd_data (abfd, ptr); + + /* xgettext:c-format */ + fprintf (file, _("private flags = %08lx:"), elf_elfheader (abfd)->e_flags); + + if ((elf_elfheader (abfd)->e_flags & EF_NANOMIPS_ABI) == E_NANOMIPS_ABI_P32) + fprintf (file, _(" [abi=P32]")); + else if ((elf_elfheader (abfd)->e_flags & EF_NANOMIPS_ABI) == + E_NANOMIPS_ABI_P64) + fprintf (file, _(" [abi=P64]")); + else + fprintf (file, _(" [no abi set]")); + + if ((elf_elfheader (abfd)->e_flags & EF_NANOMIPS_ARCH) + == E_NANOMIPS_ARCH_32R6) + fprintf (file, " [nanomips32r6]"); + else if ((elf_elfheader (abfd)->e_flags & EF_NANOMIPS_ARCH) + == E_NANOMIPS_ARCH_64R6) + fprintf (file, " [nanomips64r6]"); + else + fprintf (file, _(" [unknown ISA]")); + + if (elf_elfheader (abfd)->e_flags & EF_NANOMIPS_32BITMODE) + fprintf (file, " [32bitmode]"); + else + fprintf (file, _(" [not 32bitmode]")); + + if (elf_elfheader (abfd)->e_flags & EF_NANOMIPS_LINKRELAX) + fprintf (file, " [RELAXABLE]"); + + if (elf_elfheader (abfd)->e_flags & EF_NANOMIPS_PIC) + fprintf (file, " [PIC]"); + + if (elf_elfheader (abfd)->e_flags & EF_NANOMIPS_PID) + fprintf (file, " [PID]"); + + if (elf_elfheader (abfd)->e_flags & EF_NANOMIPS_PCREL) + fprintf (file, " [PCREL]"); + + fputc ('\n', file); + + if (nanomips_elf_tdata (abfd)->abiflags_valid) + { + Elf_Internal_ABIFlags_v0 *abiflags = + &nanomips_elf_tdata (abfd)->abiflags; + fprintf (file, "\nnanoMIPS ABI Flags Version: %d\n", abiflags->version); + fprintf (file, "\nISA: nanoMIPS%d", abiflags->isa_level); + if (abiflags->isa_rev > 1) + fprintf (file, "r%d", abiflags->isa_rev); + fprintf (file, "\nGPR size: %d", + get_nanomips_reg_size (abiflags->gpr_size)); + fprintf (file, "\nCPR1 size: %d", + get_nanomips_reg_size (abiflags->cpr1_size)); + fprintf (file, "\nCPR2 size: %d", + get_nanomips_reg_size (abiflags->cpr2_size)); + fputs ("\nFP ABI: ", file); + print_nanomips_fp_abi_value (file, abiflags->fp_abi); + fputs ("ISA Extension: ", file); + print_nanomips_isa_ext (file, abiflags->isa_ext); + fputs ("\nASEs:", file); + print_nanomips_ases (file, abiflags->ases); + fprintf (file, "\nFLAGS 1: %8.8lx", abiflags->flags1); + fprintf (file, "\nFLAGS 2: %8.8lx", abiflags->flags2); + fputc ('\n', file); + } + + return true; +} + +const struct bfd_elf_special_section _bfd_nanomips_elf_special_sections[] = { + { STRING_COMMA_LEN (".lit4"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE}, + { STRING_COMMA_LEN (".lit8"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE}, + { STRING_COMMA_LEN (".sbss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE}, + { STRING_COMMA_LEN (".sdata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE}, + { NULL, 0, 0, 0, 0 } +}; + +/* Merge non visibility st_other attributes. Ensure that the + STO_OPTIONAL flag is copied into h->other, even if this is not a + definiton of the symbol. */ + +void +_bfd_nanomips_elf_merge_symbol_attribute (struct elf_link_hash_entry *h, + unsigned int st_other, + bool definition, + bool dynamic + ATTRIBUTE_UNUSED) +{ + if ((st_other & ~ELF_ST_VISIBILITY (-1)) != 0) + { + unsigned char other; + + other = (definition ? st_other : h->other); + other &= ~ELF_ST_VISIBILITY (-1); + h->other = other | ELF_ST_VISIBILITY (h->other); + } +} + +/* Get ABI flags for a nanoMIPS BFD arch. */ + +Elf_Internal_ABIFlags_v0 * +bfd_nanomips_elf_get_abiflags (bfd *abfd) +{ + struct nanomips_elf_obj_tdata *tdata = nanomips_elf_tdata (abfd); + + return tdata->abiflags_valid ? &tdata->abiflags : NULL; +} + +/* Relocate a section. Tools like readelf/binutils needed to perform a static + relocation on objects to make sense debug information that contains label + difference relocations. The only difference between this and the generic + ELF version is that correct handling of composite relocations according to + gABI spec. */ + +bfd_byte * +_bfd_elf_nanomips_get_relocated_section_contents (bfd *abfd, + struct bfd_link_info *link_info, + struct bfd_link_order *link_order, + bfd_byte *data, + bool relocatable, + asymbol **symbols) +{ + bfd *input_bfd = link_order->u.indirect.section->owner; + asection *input_section = link_order->u.indirect.section; + long reloc_size; + arelent **reloc_vector; + long reloc_count; + + reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section); + if (reloc_size < 0) + return NULL; + + /* Read in the section. */ + if (!bfd_get_full_section_contents (input_bfd, input_section, &data)) + return NULL; + + if (data == NULL) + return NULL; + + if (reloc_size == 0) + return data; + + reloc_vector = (arelent **) bfd_malloc (reloc_size); + if (reloc_vector == NULL) + return NULL; + + reloc_count = bfd_canonicalize_reloc (input_bfd, input_section, + reloc_vector, symbols); + + if (reloc_count < 0) + goto error_return; + + if (reloc_count > 0) + { + arelent **parent; + /* offset in section of previous relocation */ + bfd_size_type last_address = 0; + /* saved result of previous relocation. */ + bfd_vma saved_addend = 0; + + for (parent = reloc_vector; *parent != NULL; parent++) + { + char *error_message = NULL; + asymbol *symbol; + bfd_reloc_status_type r; + + symbol = *(*parent)->sym_ptr_ptr; + /* PR ld/19628: A specially crafted input file + can result in a NULL symbol pointer here. */ + if (symbol == NULL) + { + link_info->callbacks->einfo + /* xgettext:c-format */ + (_("%X%P: %B(%A): error: relocation for offset %V has no value\n"), + abfd, input_section, (* parent)->address); + goto error_return; + } + + if (symbol->section && discarded_section (symbol->section)) + { + bfd_vma off; + static reloc_howto_type none_howto + = HOWTO (0, 0, 0, 0, false, 0, complain_overflow_dont, NULL, + "unused", false, 0, 0, false); + + off = (*parent)->address * bfd_octets_per_byte (input_bfd, input_section); + _bfd_clear_contents ((*parent)->howto, input_bfd, input_section, + data, off); + (*parent)->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; + (*parent)->addend = 0; + (*parent)->howto = &none_howto; + r = bfd_reloc_ok; + } + else + { + if (last_address != 0 && (*parent)->address == last_address) + (*parent)->addend = saved_addend; + else + saved_addend = 0; + + r = bfd_perform_relocation (input_bfd, + *parent, + data, + input_section, + relocatable ? abfd : NULL, + &error_message); + saved_addend = (*parent)->addend; + } + + if (relocatable) + { + asection *os = input_section->output_section; + + /* A partial link, so keep the relocs. */ + os->orelocation[os->reloc_count] = *parent; + os->reloc_count++; + } + + if (r != bfd_reloc_ok) + { + switch (r) + { + case bfd_reloc_undefined: + (*link_info->callbacks->undefined_symbol) + (link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr), + input_bfd, input_section, (*parent)->address, true); + break; + case bfd_reloc_dangerous: + BFD_ASSERT (error_message != NULL); + (*link_info->callbacks->reloc_dangerous) + (link_info, error_message, + input_bfd, input_section, (*parent)->address); + break; + case bfd_reloc_overflow: + (*link_info->callbacks->reloc_overflow) + (link_info, NULL, + bfd_asymbol_name (*(*parent)->sym_ptr_ptr), + (*parent)->howto->name, (*parent)->addend, + input_bfd, input_section, (*parent)->address); + break; + case bfd_reloc_outofrange: + /* PR ld/13730: + This error can result when processing some partially + complete binaries. Do not abort, but issue an error + message instead. */ + link_info->callbacks->einfo + /* xgettext:c-format */ + (_("%X%P: %B(%A): relocation \"%R\" goes out of range\n"), + abfd, input_section, *parent); + goto error_return; + + case bfd_reloc_notsupported: + /* PR ld/17512 + This error can result when processing a corrupt binary. + Do not abort. Issue an error message instead. */ + link_info->callbacks->einfo + /* xgettext:c-format */ + (_("%X%P: %B(%A): relocation \"%R\" is not supported\n"), + abfd, input_section, *parent); + goto error_return; + + default: + /* PR 17512; file: 90c2a92e. + Report unexpected results, without aborting. */ + link_info->callbacks->einfo + /* xgettext:c-format */ + (_("%X%P: %B(%A): relocation \"%R\" returns an unrecognized value %x\n"), + abfd, input_section, *parent, r); + break; + } + + } + last_address = (*parent)->address; + } + } + + free (reloc_vector); + return data; + +error_return: + free (reloc_vector); + return NULL; +} diff --git a/bfd/elfxx-nanomips.h b/bfd/elfxx-nanomips.h new file mode 100644 index 00000000000..6566db550cb --- /dev/null +++ b/bfd/elfxx-nanomips.h @@ -0,0 +1,54 @@ +/* nanoMIPS ELF specific backend routines. + Copyright (C) 2018-2022 Free Software Foundation, Inc. + + Written by Faraz Shahbazker + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#include "elf/nanomips.h" + +extern bool _bfd_nanomips_elf_mkobject (bfd *); +extern bool _bfd_nanomips_elf_section_processing + (bfd *, Elf_Internal_Shdr *); +extern bool _bfd_nanomips_elf_section_from_shdr + (bfd *, Elf_Internal_Shdr *, const char *, int); +extern bool _bfd_nanomips_elf_fake_sections + (bfd *, Elf_Internal_Shdr *, asection *); +extern bool _bfd_nanomips_elf_final_write_processing (bfd *); +extern const char *_bfd_nanomips_fp_abi_string (int); +extern bool _bfd_nanomips_elf_print_private_bfd_data (bfd *, void *); + +extern bfd_reloc_status_type _bfd_nanomips_elf_generic_reloc + (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); +extern bfd_reloc_status_type _bfd_nanomips_elf_negative_reloc + (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); + +extern unsigned long _bfd_elf_nanomips_mach (flagword); +extern void _bfd_nanomips_elf_merge_symbol_attribute + (struct elf_link_hash_entry *, unsigned int, bool, bool); + +extern const struct bfd_elf_special_section + _bfd_nanomips_elf_special_sections[]; + +extern bfd_byte *_bfd_elf_nanomips_get_relocated_section_contents + (bfd *, struct bfd_link_info *, struct bfd_link_order *, + bfd_byte *, bool, asymbol **); + +#define elf_backend_special_sections _bfd_nanomips_elf_special_sections +#define elf_backend_merge_symbol_attribute \ + _bfd_nanomips_elf_merge_symbol_attribute diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 05508c986ad..c48f85ea582 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -1330,6 +1330,75 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_MIPS_COPY", "BFD_RELOC_MIPS_JUMP_SLOT", + "BFD_RELOC_NANOMIPS_HI20", + "BFD_RELOC_NANOMIPS_LO12", + "BFD_RELOC_NANOMIPS_LO4_S2", + "BFD_RELOC_NANOMIPS_IMM16", + "BFD_RELOC_NANOMIPS_NEG12", + "BFD_RELOC_NANOMIPS_GPREL7_S2", + "BFD_RELOC_NANOMIPS_GPREL18", + "BFD_RELOC_NANOMIPS_GPREL19_S2", + "BFD_RELOC_NANOMIPS_GPREL16_S2", + "BFD_RELOC_NANOMIPS_GPREL18_S3", + "BFD_RELOC_NANOMIPS_4_PCREL_S1", + "BFD_RELOC_NANOMIPS_7_PCREL_S1", + "BFD_RELOC_NANOMIPS_10_PCREL_S1", + "BFD_RELOC_NANOMIPS_11_PCREL_S1", + "BFD_RELOC_NANOMIPS_14_PCREL_S1", + "BFD_RELOC_NANOMIPS_21_PCREL_S1", + "BFD_RELOC_NANOMIPS_25_PCREL_S1", + "BFD_RELOC_NANOMIPS_PCREL_HI20", + "BFD_RELOC_NANOMIPS_GOT_CALL", + "BFD_RELOC_NANOMIPS_GOTPC_HI20", + "BFD_RELOC_NANOMIPS_GOTPC_I32", + "BFD_RELOC_NANOMIPS_GOT_LO12", + "BFD_RELOC_NANOMIPS_GOT_DISP", + "BFD_RELOC_NANOMIPS_GOT_PAGE", + "BFD_RELOC_NANOMIPS_GOT_OFST", + "BFD_RELOC_NANOMIPS_I32", + "BFD_RELOC_NANOMIPS_GPREL_HI20", + "BFD_RELOC_NANOMIPS_GPREL_LO12", + "BFD_RELOC_NANOMIPS_TLS_GD", + "BFD_RELOC_NANOMIPS_TLS_GD_I32", + "BFD_RELOC_NANOMIPS_TLS_LD", + "BFD_RELOC_NANOMIPS_TLS_LD_I32", + "BFD_RELOC_NANOMIPS_TLS_DTPREL12", + "BFD_RELOC_NANOMIPS_TLS_DTPREL16", + "BFD_RELOC_NANOMIPS_TLS_DTPREL_I32", + "BFD_RELOC_NANOMIPS_TLS_GOTTPREL", + "BFD_RELOC_NANOMIPS_TLS_GOTTPREL_PC_I32", + "BFD_RELOC_NANOMIPS_TLS_TPREL12", + "BFD_RELOC_NANOMIPS_TLS_TPREL16", + "BFD_RELOC_NANOMIPS_TLS_TPREL_I32", + "BFD_RELOC_NANOMIPS_TLS_DTPMOD", + "BFD_RELOC_NANOMIPS_TLS_DTPREL", + "BFD_RELOC_NANOMIPS_TLS_TPREL", + "BFD_RELOC_NANOMIPS_PC_I32", + "BFD_RELOC_NANOMIPS_GPREL_I32", + "BFD_RELOC_NANOMIPS_GPREL17_S1", + "BFD_RELOC_NANOMIPS_NEG", + "BFD_RELOC_NANOMIPS_ASHIFTR_1", + "BFD_RELOC_NANOMIPS_UNSIGNED_8", + "BFD_RELOC_NANOMIPS_UNSIGNED_16", + "BFD_RELOC_NANOMIPS_SIGNED_8", + "BFD_RELOC_NANOMIPS_SIGNED_16", + "BFD_RELOC_NANOMIPS_EH", + "BFD_RELOC_NANOMIPS_JUMP_SLOT", + "BFD_RELOC_NANOMIPS_ALIGN", + "BFD_RELOC_NANOMIPS_FILL", + "BFD_RELOC_NANOMIPS_MAX", + "BFD_RELOC_NANOMIPS_INSN32", + "BFD_RELOC_NANOMIPS_INSN16", + "BFD_RELOC_NANOMIPS_FIXED", + "BFD_RELOC_NANOMIPS_RELAX", + "BFD_RELOC_NANOMIPS_NORELAX", + "BFD_RELOC_NANOMIPS_SAVERESTORE", + "BFD_RELOC_NANOMIPS_JALR16", + "BFD_RELOC_NANOMIPS_JALR32", + "BFD_RELOC_NANOMIPS_COPY", + "BFD_RELOC_NANOMIPS_SIGNED_9", + "BFD_RELOC_NANOMIPS_JUMPTABLE_LOAD", + "BFD_RELOC_MOXIE_10_PCREL", "BFD_RELOC_FT32_10", diff --git a/bfd/reloc.c b/bfd/reloc.c index aab5d49bdb3..bc422fef840 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -2177,6 +2177,146 @@ ENUMDOC MIPS ELF relocations (VxWorks and PLT extensions). COMMENT +ENUM + BFD_RELOC_NANOMIPS_HI20 +ENUMX + BFD_RELOC_NANOMIPS_LO12 +ENUMX + BFD_RELOC_NANOMIPS_LO4_S2 +ENUMX + BFD_RELOC_NANOMIPS_IMM16 +ENUMX + BFD_RELOC_NANOMIPS_NEG12 +ENUMX + BFD_RELOC_NANOMIPS_GPREL7_S2 +ENUMX + BFD_RELOC_NANOMIPS_GPREL18 +ENUMX + BFD_RELOC_NANOMIPS_GPREL19_S2 +ENUMX + BFD_RELOC_NANOMIPS_GPREL16_S2 +ENUMX + BFD_RELOC_NANOMIPS_GPREL18_S3 +ENUMX + BFD_RELOC_NANOMIPS_4_PCREL_S1 +ENUMX + BFD_RELOC_NANOMIPS_7_PCREL_S1 +ENUMX + BFD_RELOC_NANOMIPS_10_PCREL_S1 +ENUMX + BFD_RELOC_NANOMIPS_11_PCREL_S1 +ENUMX + BFD_RELOC_NANOMIPS_14_PCREL_S1 +ENUMX + BFD_RELOC_NANOMIPS_21_PCREL_S1 +ENUMX + BFD_RELOC_NANOMIPS_25_PCREL_S1 +ENUMX + BFD_RELOC_NANOMIPS_PCREL_HI20 +ENUMX + BFD_RELOC_NANOMIPS_GOT_CALL +ENUMX + BFD_RELOC_NANOMIPS_GOTPC_HI20 +ENUMX + BFD_RELOC_NANOMIPS_GOTPC_I32 +ENUMX + BFD_RELOC_NANOMIPS_GOT_LO12 +ENUMX + BFD_RELOC_NANOMIPS_GOT_DISP +ENUMX + BFD_RELOC_NANOMIPS_GOT_PAGE +ENUMX + BFD_RELOC_NANOMIPS_GOT_OFST +ENUMX + BFD_RELOC_NANOMIPS_I32 +ENUMX + BFD_RELOC_NANOMIPS_GPREL_HI20 +ENUMX + BFD_RELOC_NANOMIPS_GPREL_LO12 +ENUMX + BFD_RELOC_NANOMIPS_TLS_GD +ENUMX + BFD_RELOC_NANOMIPS_TLS_GD_I32 +ENUMX + BFD_RELOC_NANOMIPS_TLS_LD +ENUMX + BFD_RELOC_NANOMIPS_TLS_LD_I32 +ENUMX + BFD_RELOC_NANOMIPS_TLS_DTPREL12 +ENUMX + BFD_RELOC_NANOMIPS_TLS_DTPREL16 +ENUMX + BFD_RELOC_NANOMIPS_TLS_DTPREL_I32 +ENUMX + BFD_RELOC_NANOMIPS_TLS_GOTTPREL +ENUMX + BFD_RELOC_NANOMIPS_TLS_GOTTPREL_PC_I32 +ENUMX + BFD_RELOC_NANOMIPS_TLS_TPREL12 +ENUMX + BFD_RELOC_NANOMIPS_TLS_TPREL16 +ENUMX + BFD_RELOC_NANOMIPS_TLS_TPREL_I32 +ENUMX + BFD_RELOC_NANOMIPS_TLS_DTPMOD +ENUMX + BFD_RELOC_NANOMIPS_TLS_DTPREL +ENUMX + BFD_RELOC_NANOMIPS_TLS_TPREL +ENUMX + BFD_RELOC_NANOMIPS_PC_I32 +ENUMX + BFD_RELOC_NANOMIPS_GPREL_I32 +ENUMX + BFD_RELOC_NANOMIPS_GPREL17_S1 +ENUMX + BFD_RELOC_NANOMIPS_NEG +ENUMX + BFD_RELOC_NANOMIPS_ASHIFTR_1 +ENUMX + BFD_RELOC_NANOMIPS_UNSIGNED_8 +ENUMX + BFD_RELOC_NANOMIPS_UNSIGNED_16 +ENUMX + BFD_RELOC_NANOMIPS_SIGNED_8 +ENUMX + BFD_RELOC_NANOMIPS_SIGNED_16 +ENUMX + BFD_RELOC_NANOMIPS_EH +ENUMX + BFD_RELOC_NANOMIPS_JUMP_SLOT +ENUMX + BFD_RELOC_NANOMIPS_ALIGN +ENUMX + BFD_RELOC_NANOMIPS_FILL +ENUMX + BFD_RELOC_NANOMIPS_MAX +ENUMX + BFD_RELOC_NANOMIPS_INSN32 +ENUMX + BFD_RELOC_NANOMIPS_INSN16 +ENUMX + BFD_RELOC_NANOMIPS_FIXED +ENUMX + BFD_RELOC_NANOMIPS_RELAX +ENUMX + BFD_RELOC_NANOMIPS_NORELAX +ENUMX + BFD_RELOC_NANOMIPS_SAVERESTORE +ENUMX + BFD_RELOC_NANOMIPS_JALR16 +ENUMX + BFD_RELOC_NANOMIPS_JALR32 +ENUMX + BFD_RELOC_NANOMIPS_COPY +ENUMX + BFD_RELOC_NANOMIPS_SIGNED_9 +ENUMX + BFD_RELOC_NANOMIPS_JUMPTABLE_LOAD +ENUMDOC + nanoMIPS relocations +COMMENT + ENUM BFD_RELOC_MOXIE_10_PCREL ENUMDOC diff --git a/bfd/targets.c b/bfd/targets.c index 3dbcd088966..264933a83eb 100644 --- a/bfd/targets.c +++ b/bfd/targets.c @@ -829,6 +829,10 @@ extern const bfd_target moxie_elf32_le_vec; extern const bfd_target msp430_elf32_vec; extern const bfd_target msp430_elf32_ti_vec; extern const bfd_target mt_elf32_vec; +extern const bfd_target nanomips_elf32_be_vec; +extern const bfd_target nanomips_elf32_le_vec; +extern const bfd_target nanomips_elf64_le_vec; +extern const bfd_target nanomips_elf64_be_vec; extern const bfd_target nds32_elf32_be_vec; extern const bfd_target nds32_elf32_le_vec; extern const bfd_target nds32_elf32_linux_be_vec; @@ -1203,6 +1207,13 @@ static const bfd_target * const _bfd_target_vector[] = &mt_elf32_vec, + &nanomips_elf32_be_vec, + &nanomips_elf32_le_vec, +#ifdef BFD64 + &nanomips_elf64_be_vec, + &nanomips_elf64_le_vec, +#endif + &nds32_elf32_be_vec, &nds32_elf32_le_vec, &nds32_elf32_linux_be_vec, diff --git a/binutils/readelf.c b/binutils/readelf.c index b872876a8b6..140337d7bec 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -2963,7 +2963,7 @@ get_machine_name (unsigned e_machine) case EM_CEVA_X2: return "CEVA X2 Processor Family"; case EM_BPF: return "Linux BPF"; case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit"; - case EM_IMG1: return "Imagination Technologies"; + case EM_NANOMIPS: return "nanoMIPS"; /* 250 */ case EM_NFP: return "Netronome Flow Processor"; case EM_VE: return "NEC Vector Engine"; diff --git a/include/elf/common.h b/include/elf/common.h index 6f64f05890c..253200fa652 100644 --- a/include/elf/common.h +++ b/include/elf/common.h @@ -346,7 +346,7 @@ #define EM_CEVA_X2 246 /* CEVA X2 Processor Family */ #define EM_BPF 247 /* Linux BPF – in-kernel virtual machine. */ #define EM_GRAPHCORE_IPU 248 /* Graphcore Intelligent Processing Unit */ -#define EM_IMG1 249 /* Imagination Technologies */ +#define EM_NANOMIPS 249 /* nanoMIPS */ #define EM_NFP 250 /* Netronome Flow Processor. */ #define EM_VE 251 /* NEC Vector Engine */ #define EM_CSKY 252 /* C-SKY processor family. */ diff --git a/include/elf/nanomips.h b/include/elf/nanomips.h new file mode 100644 index 00000000000..b04c7343af2 --- /dev/null +++ b/include/elf/nanomips.h @@ -0,0 +1,262 @@ +/* nanoMIPS ELF support for BFD. + Copyright (C) 2018-2022 Free Software Foundation, Inc. + + Written by Faraz Shahbazker + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* This file holds definitions specific to the nanoMIPS ELF ABI. */ + +#ifndef _ELF_NANOMIPS_H +#define _ELF_NANOMIPS_H + +#include "elf/reloc-macros.h" +#include "elf/mips.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Values for the xxx_size bytes of an ABI flags structure. */ + +#define AFL_REG_NONE 0x00 /* No registers. */ +#define AFL_REG_32 0x01 /* 32-bit registers. */ +#define AFL_REG_64 0x02 /* 64-bit registers. */ +#define AFL_REG_128 0x03 /* 128-bit registers. */ + +START_RELOC_NUMBERS (elf_nanomips_reloc_type) + RELOC_NUMBER (R_NANOMIPS_NONE, 0) + RELOC_NUMBER (R_NANOMIPS_32, 1) + RELOC_NUMBER (R_NANOMIPS_64, 2) + RELOC_NUMBER (R_NANOMIPS_NEG, 3) + RELOC_NUMBER (R_NANOMIPS_ASHIFTR_1, 4) + RELOC_NUMBER (R_NANOMIPS_UNSIGNED_8, 5) + RELOC_NUMBER (R_NANOMIPS_SIGNED_8, 6) + RELOC_NUMBER (R_NANOMIPS_UNSIGNED_16, 7) + RELOC_NUMBER (R_NANOMIPS_SIGNED_16, 8) + RELOC_NUMBER (R_NANOMIPS_RELATIVE, 9) + RELOC_NUMBER (R_NANOMIPS_GLOBAL, 10) + RELOC_NUMBER (R_NANOMIPS_JUMP_SLOT, 11) + RELOC_NUMBER (R_NANOMIPS_IRELATIVE, 12) + + RELOC_NUMBER (R_NANOMIPS_PC25_S1, 13) + RELOC_NUMBER (R_NANOMIPS_PC21_S1, 14) + RELOC_NUMBER (R_NANOMIPS_PC14_S1, 15) + RELOC_NUMBER (R_NANOMIPS_PC11_S1, 16) + RELOC_NUMBER (R_NANOMIPS_PC10_S1, 17) + RELOC_NUMBER (R_NANOMIPS_PC7_S1, 18) + RELOC_NUMBER (R_NANOMIPS_PC4_S1, 19) + + RELOC_NUMBER (R_NANOMIPS_GPREL19_S2, 20) + RELOC_NUMBER (R_NANOMIPS_GPREL18_S3, 21) + RELOC_NUMBER (R_NANOMIPS_GPREL18, 22) + RELOC_NUMBER (R_NANOMIPS_GPREL17_S1, 23) + RELOC_NUMBER (R_NANOMIPS_GPREL16_S2, 24) + RELOC_NUMBER (R_NANOMIPS_GPREL7_S2, 25) + RELOC_NUMBER (R_NANOMIPS_GPREL_HI20, 26) + RELOC_NUMBER (R_NANOMIPS_PCHI20, 27) + + RELOC_NUMBER (R_NANOMIPS_HI20, 28) + RELOC_NUMBER (R_NANOMIPS_LO12, 29) + RELOC_NUMBER (R_NANOMIPS_GPREL_I32, 30) + RELOC_NUMBER (R_NANOMIPS_PC_I32, 31) + RELOC_NUMBER (R_NANOMIPS_I32, 32) + RELOC_NUMBER (R_NANOMIPS_GOT_DISP, 33) + RELOC_NUMBER (R_NANOMIPS_GOTPC_I32, 34) + RELOC_NUMBER (R_NANOMIPS_GOTPC_HI20, 35) + RELOC_NUMBER (R_NANOMIPS_GOT_LO12, 36) + RELOC_NUMBER (R_NANOMIPS_GOT_CALL, 37) + RELOC_NUMBER (R_NANOMIPS_GOT_PAGE, 38) + RELOC_NUMBER (R_NANOMIPS_GOT_OFST, 39) + RELOC_NUMBER (R_NANOMIPS_LO4_S2, 40) + /* Reserved for 64-bit ABI. */ + RELOC_NUMBER (R_NANOMIPS_RESERVED1, 41) + RELOC_NUMBER (R_NANOMIPS_GPREL_LO12, 42) + RELOC_NUMBER (R_NANOMIPS_SCN_DISP, 43) + RELOC_NUMBER (R_NANOMIPS_COPY, 44) + + RELOC_NUMBER (R_NANOMIPS_ALIGN, 64) + RELOC_NUMBER (R_NANOMIPS_FILL, 65) + RELOC_NUMBER (R_NANOMIPS_MAX, 66) + RELOC_NUMBER (R_NANOMIPS_INSN32, 67) + RELOC_NUMBER (R_NANOMIPS_FIXED, 68) + RELOC_NUMBER (R_NANOMIPS_NORELAX, 69) + RELOC_NUMBER (R_NANOMIPS_RELAX, 70) + RELOC_NUMBER (R_NANOMIPS_SAVERESTORE, 71) + RELOC_NUMBER (R_NANOMIPS_INSN16, 72) + RELOC_NUMBER (R_NANOMIPS_JALR32, 73) + RELOC_NUMBER (R_NANOMIPS_JALR16, 74) + RELOC_NUMBER (R_NANOMIPS_JUMPTABLE_LOAD, 75) + RELOC_NUMBER (R_NANOMIPS_FRAME_REG, 76) + + /* TLS relocations. */ + RELOC_NUMBER (R_NANOMIPS_TLS_DTPMOD, 80) + RELOC_NUMBER (R_NANOMIPS_TLS_DTPREL, 81) + RELOC_NUMBER (R_NANOMIPS_TLS_TPREL, 82) + RELOC_NUMBER (R_NANOMIPS_TLS_GD, 83) + RELOC_NUMBER (R_NANOMIPS_TLS_GD_I32, 84) + RELOC_NUMBER (R_NANOMIPS_TLS_LD, 85) + RELOC_NUMBER (R_NANOMIPS_TLS_LD_I32, 86) + RELOC_NUMBER (R_NANOMIPS_TLS_DTPREL12, 87) + RELOC_NUMBER (R_NANOMIPS_TLS_DTPREL16, 88) + RELOC_NUMBER (R_NANOMIPS_TLS_DTPREL_I32, 89) + RELOC_NUMBER (R_NANOMIPS_TLS_GOTTPREL, 90) + RELOC_NUMBER (R_NANOMIPS_TLS_GOTTPREL_PC_I32, 91) + RELOC_NUMBER (R_NANOMIPS_TLS_TPREL12, 92) + RELOC_NUMBER (R_NANOMIPS_TLS_TPREL16, 93) + RELOC_NUMBER (R_NANOMIPS_TLS_TPREL_I32, 94) + + FAKE_RELOC (R_NANOMIPS_max, 94) + /* May be used for compact unwind tables in the future. */ + RELOC_NUMBER (R_NANOMIPS_PC32, 248) + RELOC_NUMBER (R_NANOMIPS_EH, 249) + /* These are GNU extensions to enable C++ vtable garbage collection. */ + RELOC_NUMBER (R_NANOMIPS_GNU_VTINHERIT, 253) + RELOC_NUMBER (R_NANOMIPS_GNU_VTENTRY, 254) +END_RELOC_NUMBERS (R_NANOMIPS_maxext) + +/* Processor specific flags for the ELF header e_flags field. */ + +/* File may be relaxed by the linker. */ +#define EF_NANOMIPS_LINKRELAX 0x00000001 + +/* File contains position independent code. */ +#define EF_NANOMIPS_PIC 0x00000002 + +/* Indicates code compiled for a 64-bit machine in 32-bit mode + (regs are 32-bits wide). */ +#define EF_NANOMIPS_32BITMODE 0x00000004 + +/* File contains position independent code. */ +#define EF_NANOMIPS_PID 0x00000008 + +/* File contains pure PC-relative code. */ +#define EF_NANOMIPS_PCREL 0x00000010 + +/* Four bit nanoMIPS architecture field. */ +#define EF_NANOMIPS_ARCH 0xf0000000 + +/* -march=32r6[s] code. */ +#define E_NANOMIPS_ARCH_32R6 0x00000000 + +/* -march=64r6 code. */ +#define E_NANOMIPS_ARCH_64R6 0x10000000 + +/* The ABI of the file. */ +#define EF_NANOMIPS_ABI 0x0000F000 + +/* nanoMIPS ABI in 32 bit mode. */ +#define E_NANOMIPS_ABI_P32 0x00001000 + +/* nanoMIPS ABI in 64 bit mode. */ +#define E_NANOMIPS_ABI_P64 0x00002000 + +/* Machine variant if we know it. This field was invented at Cygnus + for MIPS. It may be used similarly for nanoMIPS. */ + +#define EF_NANOMIPS_MACH 0x00FF0000 + +/* Processor specific section types. */ + +/* ABI related flags section. */ +#define SHT_NANOMIPS_ABIFLAGS 0x70000000 + +/* Processor specific program header types. */ + +/* Records ABI related flags. */ +#define PT_NANOMIPS_ABIFLAGS 0x70000000 + +/* Object attribute tags. */ +enum +{ + /* 0-3 are generic. */ + + /* Floating-point ABI used by this object file. */ + Tag_GNU_NANOMIPS_ABI_FP = 4, + + /* MSA ABI used by this object file. */ + Tag_GNU_NANOMIPS_ABI_MSA = 8, +}; + +/* Object attribute values. */ +enum +{ + /* Values defined for Tag_GNU_NANOMIPS_ABI_FP. */ + + /* Not tagged or not using any ABIs affected by the differences. */ + Val_GNU_NANOMIPS_ABI_FP_ANY = 0, + + /* Using hard-float -mdouble-float. */ + Val_GNU_NANOMIPS_ABI_FP_DOUBLE = 1, + + /* Using hard-float -msingle-float. */ + Val_GNU_NANOMIPS_ABI_FP_SINGLE = 2, + + /* Using soft-float. */ + Val_GNU_NANOMIPS_ABI_FP_SOFT = 3, + + /* Not tagged or not using any ABIs affected by the differences. */ + Val_GNU_NANOMIPS_ABI_MSA_ANY = 0, + + /* Using 128-bit MSA. */ + Val_GNU_NANOMIPS_ABI_MSA_128 = 1, +}; + +/* Masks for the ases word of an ABI flags structure. + + Unfortunate decisions in early development transitioning from MIPS + to nanoMIPS, left this horifically fragmented. Bits marked as + UNUSED may be cannibalized for future ASEs; bits marked as RESERVED + are intended to remain blocked. If MIPS history is anything to go + by, nanoMIPS will eventually spawn enough ASEs to fill up the gaps! +*/ + +#define NANOMIPS_ASE_TLB 0x00000001 /* TLB control ASE. */ +#define NANOMIPS_ASE_UNUSED1 0x00000002 /* was DSP R2 ASE. */ +#define NANOMIPS_ASE_EVA 0x00000004 /* Enhanced VA Scheme. */ +#define NANOMIPS_ASE_MCU 0x00000008 /* MCU (MicroController) ASE. */ +#define NANOMIPS_ASE_UNUSED2 0x00000010 /* was MDMX ASE. */ +#define NANOMIPS_ASE_UNUSED3 0x00000020 /* was MIPS-3D ASE. */ +#define NANOMIPS_ASE_MT 0x00000040 /* MT ASE. */ +#define NANOMIPS_ASE_UNUSED4 0x00000080 /* was SmartMIPS ASE. */ +#define NANOMIPS_ASE_VIRT 0x00000100 /* VZ ASE. */ +#define NANOMIPS_ASE_MSA 0x00000200 /* MSA ASE. */ +#define NANOMIPS_ASE_RESERVED1 0x00000400 /* was MIPS16 ASE. */ +#define NANOMIPS_ASE_RESERVED2 0x00000800 /* was MICROMIPS ASE. */ +#define NANOMIPS_ASE_UNUSED6 0x00001000 /* was XPA. */ +#define NANOMIPS_ASE_DSPR3 0x00002000 /* DSP R3 ASE. */ +#define NANOMIPS_ASE_UNUSED5 0x00004000 /* was MIPS16 E2 Extension. */ +#define NANOMIPS_ASE_CRC 0x00008000 /* CRC extension. */ +#define NANOMIPS_ASE_CRYPTO 0x00010000 /* Cryptography extension. */ +#define NANOMIPS_ASE_GINV 0x00020000 /* GINV ASE. */ +#define NANOMIPS_ASE_xNMS 0x00040000 /* not nanoMIPS Subset. */ +#define NANOMIPS_ASE_MASK 0x0007af4d /* All valid ASEs. */ + +/* nanoMIPS ELF flags routines. */ +extern Elf_Internal_ABIFlags_v0 * bfd_nanomips_elf_get_abiflags (bfd *); + +extern void bfd_nanomips_elf_swap_abiflags_v0_in + (bfd *, const Elf_External_ABIFlags_v0 *, Elf_Internal_ABIFlags_v0 *); +extern void bfd_nanomips_elf_swap_abiflags_v0_out + (bfd *, const Elf_Internal_ABIFlags_v0 *, Elf_External_ABIFlags_v0 *); + +#ifdef __cplusplus +} +#endif + +#endif /* _ELF_NANOMIPS_H */ -- 2.25.1