@@ -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
@@ -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
@@ -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,
@@ -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,
@@ -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
@@ -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" ;;
@@ -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" ;;
new file mode 100644
@@ -0,0 +1,61 @@
+/* bfd back-end for nanomips support
+ Copyright (C) 2018-2022 Free Software Foundation, Inc.
+
+ Written by Faraz Shahbazker <faraz.shahbazker@mips.com>
+
+ 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]);
@@ -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,
new file mode 100644
@@ -0,0 +1,1423 @@
+/* nanoMIPS-specific support for 32-bit ELF
+ Copyright (C) 2018-2022 Free Software Foundation, Inc.
+
+ Written by Faraz Shahbazker <faraz.shahbazker@mips.com>
+
+ 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"
@@ -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
new file mode 100644
@@ -0,0 +1,794 @@
+/* nanoMIPS-specific support for ELF
+ Copyright (C) 2018-2022 Free Software Foundation, Inc.
+
+ Written by Faraz Shahbazker <faraz.shahbazker@mips.com>
+
+ 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;
+}
new file mode 100644
@@ -0,0 +1,54 @@
+/* nanoMIPS ELF specific backend routines.
+ Copyright (C) 2018-2022 Free Software Foundation, Inc.
+
+ Written by Faraz Shahbazker <faraz.shahbazker@mips.com>
+
+ 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
@@ -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",
@@ -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
@@ -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,
@@ -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";
@@ -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. */
new file mode 100644
@@ -0,0 +1,262 @@
+/* nanoMIPS ELF support for BFD.
+ Copyright (C) 2018-2022 Free Software Foundation, Inc.
+
+ Written by Faraz Shahbazker <faraz.shahbazker@mips.com>
+
+ 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 */