[PATCH v2 2/6] BFD changes for nanoMIPS support.

"Tsing" <[email protected]> Fri, 24 Jul 2026 18:30:54 +0800
Newsgroups gmane.comp.gnu.binutils
Message-ID <[email protected]>
From: tsing <[email protected]>

bfd/
	* Makefile.am: Add entries for nanomips32-elf and nanomips64-elf.
	* Makefile.in: Regenerate.
	* configure: Regenerate.
	* configure.ac: Likewise.
	* config.bfd: Likewise.
	* archures.c: Add bfd_nanomips_arch.
	* reloc.c: Add nanomips relocs.
	* targets.c: Add naonmips_elf32_vec and nanomips_elf64_vec.
	* bfd-in2.h: Regenerate.
	* libbfd.h: Regenerate.
	* elf-bfd.h: Add NANOMIPS_ELF_DATA to enum elf_target_id.
	* elfnn-nanomips.c: New file.
	* elfxx-nanomips.c: New file.
	* elfxx-nanomips.h: New file.
include/
	* elf/common.h: Add EM_NANOMIPS.
	* elf/nanomips.h: New file.
---
 bfd/Makefile.am        |   17 +
 bfd/Makefile.in        |   20 +
 bfd/archures.c         |    5 +
 bfd/bfd-in2.h          |   72 ++
 bfd/config.bfd         |   11 +
 bfd/configure          |    4 +
 bfd/configure.ac       |    4 +
 bfd/cpu-nanomips.c     |   61 ++
 bfd/elf-bfd.h          |    1 +
 bfd/elfnn-nanomips.c   | 1535 ++++++++++++++++++++++++++++++++++++++++
 bfd/elfxx-nanomips.c   |  449 ++++++++++++
 bfd/elfxx-nanomips.h   |   46 ++
 bfd/libbfd.h           |   67 ++
 bfd/reloc.c            |  138 ++++
 bfd/targets.c          |   11 +
 include/elf/common.h   |    1 +
 include/elf/nanomips.h |  211 ++++++
 17 files changed, 2653 insertions(+)
 create mode 100644 bfd/cpu-nanomips.c
 create mode 100644 bfd/elfnn-nanomips.c
 create mode 100644 bfd/elfxx-nanomips.c
 create mode 100644 bfd/elfxx-nanomips.h
 create mode 100644 include/elf/nanomips.h

diff --git a/bfd/Makefile.am b/bfd/Makefile.am
index e4df05441eb..89de4afc36b 100644
--- a/bfd/Makefile.am
+++ b/bfd/Makefile.am
@@ -142,6 +142,7 @@ ALL_MACHINES = \
 	cpu-moxie.lo \
 	cpu-msp430.lo \
 	cpu-mt.lo \
+	cpu-nanomips.lo \
 	cpu-nds32.lo \
 	cpu-nfp.lo \
 	cpu-ns32k.lo \
@@ -225,6 +226,7 @@ ALL_MACHINES_CFILES = \
 	cpu-moxie.c \
 	cpu-msp430.c \
 	cpu-mt.c \
+	cpu-nanomips.c \
 	cpu-nds32.c \
 	cpu-nfp.c \
 	cpu-ns32k.c \
@@ -331,6 +333,7 @@ BFD32_BACKENDS = \
 	elf32-moxie.lo \
 	elf32-msp430.lo \
 	elf32-mt.lo \
+	elf32-nanomips.lo \
 	elf32-nds32.lo \
 	elf32-or1k.lo \
 	elf32-pj.lo \
@@ -466,6 +469,7 @@ BFD32_BACKENDS_CFILES = \
 	elf32-moxie.c \
 	elf32-msp430.c \
 	elf32-mt.c \
+	elf32-nanomips.c \
 	elf32-nds32.c \
 	elf32-or1k.c \
 	elf32-pj.c \
@@ -562,6 +566,8 @@ BFD64_BACKENDS = \
 	elf64-loongarch.lo \
 	elf64-mips.lo \
 	elf64-mmix.lo \
+	elf64-nanomips.lo \
+	elfxx-nanomips.lo \
 	elf64-nfp.lo \
 	elf64-ppc.lo \
 	elf64-riscv.lo \
@@ -612,6 +618,7 @@ BFD64_BACKENDS_CFILES = \
 	elf64-ia64-vms.c \
 	elf64-mips.c \
 	elf64-mmix.c \
+	elf64-nanomips.c \
 	elf64-nfp.c \
 	elf64-ppc.c \
 	elf64-s390.c \
@@ -625,6 +632,7 @@ BFD64_BACKENDS_CFILES = \
 	elfxx-kvx.c \
 	elfxx-loongarch.c \
 	elfxx-mips.c \
+	elfxx-nanomips.c \
 	elfxx-riscv.c \
 	elfxx-x86.c \
 	mach-o-aarch64.c \
@@ -692,6 +700,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 \
 	pe-riscv64igen.c
 
@@ -883,6 +892,14 @@ elf64-riscv.c : elfnn-riscv.c
 	$(AM_V_at)echo "#line 1 \"$<\"" > $@
 	$(AM_V_GEN)$(SED) -e s/NN/64/g < $< >> $@
 
+elf32-nanomips.c : elfnn-nanomips.c
+	$(AM_V_at)echo "#line 1 \"elfnn-nanomips.c\"" > $@
+	$(AM_V_GEN)$(SED) -e s/NN/32/g < $< >> $@
+
+elf64-nanomips.c : elfnn-nanomips.c
+	$(AM_V_at)echo "#line 1 \"elfnn-nanomips.c\"" > $@
+	$(AM_V_GEN)$(SED) -e s/NN/64/g < $< >> $@
+
 peigen.c : peXXigen.c
 	$(AM_V_at)echo "#line 1 \"$<\"" > $@
 	$(AM_V_GEN)$(SED) -e s/XX/pe/g < $< >> $@
diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index 14512cf61fb..af5c0dd8242 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -610,6 +610,7 @@ ALL_MACHINES = \
 	cpu-moxie.lo \
 	cpu-msp430.lo \
 	cpu-mt.lo \
+	cpu-nanomips.lo \
 	cpu-nds32.lo \
 	cpu-nfp.lo \
 	cpu-ns32k.lo \
@@ -693,6 +694,7 @@ ALL_MACHINES_CFILES = \
 	cpu-moxie.c \
 	cpu-msp430.c \
 	cpu-mt.c \
+	cpu-nanomips.c \
 	cpu-nds32.c \
 	cpu-nfp.c \
 	cpu-ns32k.c \
@@ -800,6 +802,7 @@ BFD32_BACKENDS = \
 	elf32-moxie.lo \
 	elf32-msp430.lo \
 	elf32-mt.lo \
+	elf32-nanomips.lo \
 	elf32-nds32.lo \
 	elf32-or1k.lo \
 	elf32-pj.lo \
@@ -935,6 +938,7 @@ BFD32_BACKENDS_CFILES = \
 	elf32-moxie.c \
 	elf32-msp430.c \
 	elf32-mt.c \
+	elf32-nanomips.c \
 	elf32-nds32.c \
 	elf32-or1k.c \
 	elf32-pj.c \
@@ -1017,6 +1021,7 @@ BFD64_BACKENDS = \
 	elf32-kvx.lo \
 	elf32-loongarch.lo \
 	elf32-mips.lo \
+	elf32-nanomips.lo \
 	elf32-riscv.lo \
 	elf32-score.lo \
 	elf32-score7.lo \
@@ -1032,6 +1037,8 @@ BFD64_BACKENDS = \
 	elf64-loongarch.lo \
 	elf64-mips.lo \
 	elf64-mmix.lo \
+	elf64-nanomips.lo \
+	elfxx-nanomips.lo \
 	elf64-nfp.lo \
 	elf64-ppc.lo \
 	elf64-riscv.lo \
@@ -1095,6 +1102,7 @@ BFD64_BACKENDS_CFILES = \
 	elfxx-kvx.c \
 	elfxx-loongarch.c \
 	elfxx-mips.c \
+	elfxx-nanomips.c \
 	elfxx-riscv.c \
 	elfxx-x86.c \
 	mach-o-aarch64.c \
@@ -1161,6 +1169,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 \
 	pe-riscv64igen.c
 
@@ -1612,6 +1621,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-or1k.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-pj.Plo@am__quote@
@@ -1651,6 +1661,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-loongarch.Plo@am__quote@
 @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-nanomips.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-nfp.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@
@@ -1666,6 +1677,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfxx-kvx.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@
@@ -2394,6 +2406,14 @@ elf64-riscv.c : elfnn-riscv.c
 	$(AM_V_at)echo "#line 1 \"$<\"" > $@
 	$(AM_V_GEN)$(SED) -e s/NN/64/g < $< >> $@
 
+elf32-nanomips.c : elfnn-nanomips.c
+	$(AM_V_at)echo "#line 1 \"elfnn-nanomips.c\"" > $@
+	$(AM_V_GEN)$(SED) -e s/NN/32/g < $< >> $@
+
+elf64-nanomips.c : elfnn-nanomips.c
+	$(AM_V_at)echo "#line 1 \"elfnn-nanomips.c\"" > $@
+	$(AM_V_GEN)$(SED) -e s/NN/64/g < $< >> $@
+
 peigen.c : peXXigen.c
 	$(AM_V_at)echo "#line 1 \"$<\"" > $@
 	$(AM_V_GEN)$(SED) -e s/XX/pe/g < $< >> $@
diff --git a/bfd/archures.c b/bfd/archures.c
index 0e919246673..25dff977eff 100644
--- a/bfd/archures.c
+++ b/bfd/archures.c
@@ -545,6 +545,9 @@ DESCRIPTION
 .  bfd_arch_nfp,       {* Netronome Flow Processor *}
 .#define bfd_mach_nfp3200	0x3200
 .#define bfd_mach_nfp6000	0x6000
+.  bfd_arch_nanomips,      {* nanoMIPSrX *}
+.#define bfd_mach_nanomipsisa32r6       32
+.#define bfd_mach_nanomipsisa64r6       64
 .  bfd_arch_csky,      {* C-SKY.  *}
 .#define bfd_mach_ck_unknown    0
 .#define bfd_mach_ck510		1
@@ -691,6 +694,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_ns32k_arch;
@@ -779,6 +783,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_ns32k_arch,
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index e49d67316f3..91bc8779389 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -1802,6 +1802,9 @@ enum bfd_architecture
   bfd_arch_nfp,       /* Netronome Flow Processor */
 #define bfd_mach_nfp3200       0x3200
 #define bfd_mach_nfp6000       0x6000
+  bfd_arch_nanomips,      /* nanoMIPSrX */
+#define bfd_mach_nanomipsisa32r6       32
+#define bfd_mach_nanomipsisa64r6       64
   bfd_arch_csky,      /* C-SKY.  */
 #define bfd_mach_ck_unknown    0
 #define bfd_mach_ck510         1
@@ -3808,6 +3811,75 @@ enum bfd_reloc_code_real
   BFD_RELOC_MICROMIPS_TLS_TPREL_LO16,
   BFD_RELOC_MIPS_EH,
 
+  /* 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,
+
   /* Moxie ELF relocations.  */
   BFD_RELOC_MOXIE_10_PCREL,
 
diff --git a/bfd/config.bfd b/bfd/config.bfd
index 02a1a68525e..0b61fa8b9e5 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -210,6 +210,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 ;;
 or1k*|or1knd*)	 targ_archs=bfd_or1k_arch ;;
 pdp11*)		 targ_archs=bfd_pdp11_arch ;;
@@ -961,6 +962,16 @@ case "${targ}" in
     targ_underscore=yes
     ;;
 
+  nanomips*-*-elf*)
+    targ_defvec=nanomips_elf32_le_vec
+    targ_selvecs="nanomips_elf32_be_vec nanomips_elf64_be_vec nanomips_elf64_le_vec"
+    ;;
+
+  nanomips*-*-linux*)
+    targ_defvec=nanomips_elf32_le_vec
+    targ_selvecs="nanomips_elf32_be_vec nanomips_elf64_be_vec nanomips_elf64_le_vec"
+    ;;
+
   or1k-*-elf | or1k-*-linux* | or1k-*-rtems*)
     targ_defvec=or1k_elf32_vec
     ;;
diff --git a/bfd/configure b/bfd/configure
index 89c4f92b52e..f99abe76c30 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -16011,6 +16011,10 @@ do
     msp430_elf32_vec)		 tb="$tb elf32-msp430.lo elf32.lo elf-attrs.lo $elf" ;;
     msp430_elf32_ti_vec)	 tb="$tb elf32-msp430.lo elf32.lo elf-attrs.lo $elf" ;;
     mt_elf32_vec)		 tb="$tb elf32-mt.lo elf32.lo $elf" ;;
+    nanomips_elf32_be_vec)	 tb="$tb elf32-nanomips.lo elfxx-nanomips.lo elf32.lo $elf ecofflink.lo" ;;
+    nanomips_elf32_le_vec)	 tb="$tb elf32-nanomips.lo elfxx-nanomips.lo elf32.lo $elf ecofflink.lo" ;;
+    nanomips_elf64_be_vec)	 tb="$tb elf64-nanomips.lo elf64.lo elfxx-nanomips.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
+    nanomips_elf64_le_vec)	 tb="$tb elf64-nanomips.lo elf64.lo elfxx-nanomips.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
     nds32_elf32_be_vec)		 tb="$tb elf32-nds32.lo elf32.lo $elf" ;;
     nds32_elf32_le_vec)		 tb="$tb elf32-nds32.lo elf32.lo $elf" ;;
     nds32_elf32_linux_be_vec)	 tb="$tb elf32-nds32.lo elf32.lo $elf" ;;
diff --git a/bfd/configure.ac b/bfd/configure.ac
index c30a75ba8b7..b15a5840f72 100644
--- a/bfd/configure.ac
+++ b/bfd/configure.ac
@@ -552,6 +552,10 @@ do
     msp430_elf32_vec)		 tb="$tb elf32-msp430.lo elf32.lo elf-attrs.lo $elf" ;;
     msp430_elf32_ti_vec)	 tb="$tb elf32-msp430.lo elf32.lo elf-attrs.lo $elf" ;;
     mt_elf32_vec)		 tb="$tb elf32-mt.lo elf32.lo $elf" ;;
+    nanomips_elf32_be_vec)	 tb="$tb elf32-nanomips.lo elfxx-nanomips.lo elf32.lo $elf ecofflink.lo" ;;
+    nanomips_elf32_le_vec)	 tb="$tb elf32-nanomips.lo elfxx-nanomips.lo elf32.lo $elf ecofflink.lo" ;;
+    nanomips_elf64_be_vec)	 tb="$tb elf64-nanomips.lo elf64.lo elfxx-nanomips.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
+    nanomips_elf64_le_vec)	 tb="$tb elf64-nanomips.lo elf64.lo elfxx-nanomips.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
     nds32_elf32_be_vec)		 tb="$tb elf32-nds32.lo elf32.lo $elf" ;;
     nds32_elf32_le_vec)		 tb="$tb elf32-nds32.lo elf32.lo $elf" ;;
     nds32_elf32_linux_be_vec)	 tb="$tb elf32-nds32.lo elf32.lo $elf" ;;
diff --git a/bfd/cpu-nanomips.c b/bfd/cpu-nanomips.c
new file mode 100644
index 00000000000..d29e52c6094
--- /dev/null
+++ b/bfd/cpu-nanomips.c
@@ -0,0 +1,61 @@
+/* bfd back-end for nanomips support
+   Copyright (C) 2017-2026 Free Software Foundation, CIP United Inc.
+   Contributed by MIPS Tech LLC.
+   Written by Faraz Shahbazker <[email protected]>
+
+   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,
+     NULL),
+};
+
+const bfd_arch_info_type bfd_nanomips_arch =
+  N (32, 32, 0, "nanomips", true, &arch_info_struct[0]);
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 88d35925987..e7e3acea135 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -574,6 +574,7 @@ enum elf_target_id
   MIPS_ELF_DATA,
   MMIX_ELF_DATA,
   MN10300_ELF_DATA,
+  NANOMIPS_ELF_DATA,
   NDS32_ELF_DATA,
   OR1K_ELF_DATA,
   PPC32_ELF_DATA,
diff --git a/bfd/elfnn-nanomips.c b/bfd/elfnn-nanomips.c
new file mode 100644
index 00000000000..bb9b6d93a64
--- /dev/null
+++ b/bfd/elfnn-nanomips.c
@@ -0,0 +1,1535 @@
+/* nanoMIPS-specific support for 32-bit ELF
+   Copyright (C) 2017-2026 Free Software Foundation, CIP United Inc.
+   Contributed by MIPS Tech LLC.
+   Written by Faraz Shahbazker <[email protected]>
+
+   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 "libiberty.h"
+#include "ecoff-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 */
+	 1,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size  */
+	 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 */
+	 1,			/* size  */
+	 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 */
+	 1,			/* size  */
+	 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 */
+	 2,			/* size */
+	 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 */
+	 2,			/* size  */
+	 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 */
+	 4,			/* size  */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 2,			/* size */
+	 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 */
+	 2,			/* size */
+	 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 */
+	 2,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 2,			/* size  */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size  */
+	 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 */
+	 4,			/* size  */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size  */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 2,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 1,			/* size */
+	 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 */
+	 1,			/* size */
+	 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 */
+	 1,			/* size  */
+	 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 */
+	 1,			/* size */
+	 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 */
+	 1,			/* size */
+	 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 */
+	 1,			/* size */
+	 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 */
+	 1,			/* size */
+	 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 */
+	 1,			/* size */
+	 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 */
+	 1,			/* size */
+	 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 */
+	 1,			/* size */
+	 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 */
+	 1,			/* size */
+	 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 */
+
+  EMPTY_HOWTO (75),
+
+  /* Place-holder for relaxing frame-register information.  */
+  HOWTO (R_NANOMIPS_FRAME_REG, /* type */
+	 0,			/* rightshift */
+	 1,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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 */
+	 4,			/* size */
+	 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_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, unsigned int r_type)
+{
+  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:
+      if (r_type >= ARRAY_SIZE (elfNN_nanomips_howto_table_rela))
+        {
+          (*_bfd_error_handler) (_("%pB: unsupported relocation type %#x"),
+                                   abfd, r_type);
+          bfd_set_error (bfd_error_bad_value);
+          return NULL;
+        }
+      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)
+{
+  cache_ptr->howto = nanomips_elfNN_rtype_to_howto (abfd, ELFNN_R_TYPE (dst->r_info));
+  cache_ptr->addend = dst->r_addend;
+  return cache_ptr->howto != NULL;
+}
+
+/* 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;
+}
+
+#if ARCH_SIZE == 32
+# define PRSTATUS_SIZE			256
+# define PRSTATUS_OFFSET_PR_CURSIG	12
+# define PRSTATUS_OFFSET_PR_PID		24
+# define PRSTATUS_OFFSET_PR_REG		72
+# define ELF_GREGSET_T_SIZE		180
+# define PRPSINFO_SIZE			128
+# define PRPSINFO_OFFSET_PR_PID		16
+# define PRPSINFO_OFFSET_PR_FNAME	32
+# define PRPSINFO_OFFSET_PR_PSARGS	48
+#else
+# define PRSTATUS_SIZE			480
+# define PRSTATUS_OFFSET_PR_CURSIG	12
+# define PRSTATUS_OFFSET_PR_PID		32
+# define PRSTATUS_OFFSET_PR_REG		112
+# define ELF_GREGSET_T_SIZE		360
+# define PRPSINFO_SIZE			136
+# define PRPSINFO_OFFSET_PR_PID		24
+# define PRPSINFO_OFFSET_PR_FNAME	40
+# define PRPSINFO_OFFSET_PR_PSARGS	56
+#endif
+
+static bool
+nanomips_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+  size_t size;
+  int offset;
+
+  switch (note->descsz)
+    {
+    default:
+      return false;
+
+    case PRSTATUS_SIZE: /* sizeof(struct elf_prstatus) on Linux/nanoMIPS.  */
+      /* pr_cursig */
+      elf_tdata (abfd)->core->signal
+	= bfd_get_16 (abfd, note->descdata + PRSTATUS_OFFSET_PR_CURSIG);
+
+      /* pr_pid */
+      elf_tdata (abfd)->core->lwpid
+	= bfd_get_32 (abfd, note->descdata + PRSTATUS_OFFSET_PR_PID);
+
+      /* pr_reg */
+      offset = PRSTATUS_OFFSET_PR_REG;
+      size = ELF_GREGSET_T_SIZE;
+      break;
+    }
+  /* Make a ".reg/999" section.  */
+  return _bfd_elfcore_make_pseudosection (abfd, ".reg", size,
+					  note->descpos + offset);
+}
+
+static bool
+nanomips_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+  switch (note->descsz)
+    {
+    default:
+      return false;
+
+    case PRPSINFO_SIZE: /* sizeof(struct elf_prpsinfo) on Linux/nanoMIPS.  */
+      /* pr_pid */
+      elf_tdata (abfd)->core->pid
+	= bfd_get_32 (abfd, note->descdata + PRPSINFO_OFFSET_PR_PID);
+
+      /* pr_fname */
+      elf_tdata (abfd)->core->program = _bfd_elfcore_strndup
+	(abfd, note->descdata + PRPSINFO_OFFSET_PR_FNAME, 16);
+
+      /* pr_psargs */
+      elf_tdata (abfd)->core->command = _bfd_elfcore_strndup
+	(abfd, note->descdata + PRPSINFO_OFFSET_PR_PSARGS, 80);
+      break;
+    }
+  /* Note that for some reason, a spurious space is tacked
+     onto the end of the args in some (at least one anyway)
+     implementations, so strip it off if it exists.  */
+  {
+    char *command = elf_tdata (abfd)->core->command;
+    int n = strlen (command);
+
+    if (0 < n && command[n - 1] == ' ')
+      command[n - 1] = '\0';
+  }
+  return true;
+}
+
+/* Write Linux core PRSTATUS note into core file.  */
+
+static char *
+nanomips_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type,
+			      ...)
+{
+  switch (note_type)
+    {
+    default:
+      return NULL;
+
+    case NT_PRPSINFO:
+      BFD_FAIL ();
+      return NULL;
+
+    case NT_PRSTATUS:
+      {
+        char data[PRSTATUS_SIZE];
+        va_list ap;
+        long pid;
+        int cursig;
+        const void *greg;
+
+        va_start (ap, note_type);
+        memset (data, 0, PRSTATUS_OFFSET_PR_REG);
+        pid = va_arg (ap, long);
+        bfd_put_32 (abfd, pid, data + PRSTATUS_OFFSET_PR_PID);
+        cursig = va_arg (ap, int);
+        bfd_put_16 (abfd, cursig, data + PRSTATUS_OFFSET_PR_CURSIG);
+        greg = va_arg (ap, const void *);
+        memcpy (data + PRSTATUS_OFFSET_PR_REG, greg, ELF_GREGSET_T_SIZE);
+        memset (data + PRSTATUS_OFFSET_PR_REG + ELF_GREGSET_T_SIZE, 0,
+		PRSTATUS_SIZE - (PRSTATUS_OFFSET_PR_REG + ELF_GREGSET_T_SIZE));
+        va_end (ap);
+        return elfcore_write_note (abfd, buf, bufsiz,
+                                   "CORE", note_type, data, sizeof (data));
+      }
+    }
+}
+
+#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_final_write_processing \
+					_bfd_nanomips_elf_final_write_processing
+#define elf_backend_grok_prstatus	nanomips_elf_grok_prstatus
+#define elf_backend_grok_psinfo		nanomips_elf_grok_psinfo
+#define elf_backend_write_core_note	nanomips_elf_write_core_note
+
+#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_print_private_bfd_data \
+					_bfd_nanomips_elf_print_private_bfd_data
+#define bfd_elfNN_mkobject		_bfd_nanomips_elf_mkobject
+#define bfd_elfNN_bfd_is_local_label_name \
+					nanomips_elf_is_local_label_name
+
+#define ELF_MAXPAGESIZE			0x1000
+#define ELF_COMMONPAGESIZE		0x1000
+
+/* Support for nanomipsNN target.  */
+
+#define TARGET_LITTLE_SYM               nanomips_elfNN_le_vec
+#define TARGET_LITTLE_NAME              "elfNN-littlenanomips"
+#define TARGET_BIG_SYM                  nanomips_elfNN_be_vec
+#define TARGET_BIG_NAME                 "elfNN-bignanomips"
+
+#define elfNN_bed			elfNN_nanomips_bed
+
+/* Include the target file for this target.  */
+#include "elfNN-target.h"
diff --git a/bfd/elfxx-nanomips.c b/bfd/elfxx-nanomips.c
new file mode 100644
index 00000000000..7f4a441d789
--- /dev/null
+++ b/bfd/elfxx-nanomips.c
@@ -0,0 +1,449 @@
+/* nanoMIPS-specific support for ELF
+   Copyright (C) 2017-2026 Free Software Foundation, CIP United Inc.
+   Contributed by MIPS Tech LLC.
+   Written by Faraz Shahbazker <[email protected]>
+
+   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 "ecoff-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;
+
+  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)
+
+/* 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));
+}
+
+/* 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 = 0;
+  val += symbol->section->output_section->vma;
+  val += symbol->section->output_offset;
+  val += symbol->value;
+
+  /* Transmit the negated value (-S + A) for composition.  */
+  if (!relocatable && reloc_entry[1].address == reloc_entry->address)
+    reloc_entry[1].addend = - val + reloc_entry->addend;
+
+  if (relocatable)
+    reloc_entry->address += input_section->output_offset;
+
+  return bfd_reloc_ok;
+}
+
+/* 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;
+}
+
+/* Return printable name for ABI.  */
+
+static inline char *
+elf_nanomips_abi_name (bfd *abfd)
+{
+  flagword flags;
+
+  flags = elf_elfheader (abfd)->e_flags;
+  switch (flags & EF_NANOMIPS_ABI)
+    {
+    case 0:
+      return "none";
+    case E_NANOMIPS_ABI_P32:
+      return "P32";
+    case E_NANOMIPS_ABI_P64:
+      return "P64";
+    default:
+      return "unknown abi";
+    }
+}
+
+/* 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, 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;
+
+  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;
+    }
+
+  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;
+
+  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.  */
+
+void
+_bfd_nanomips_final_write_processing (bfd *abfd)
+{
+  nanomips_set_isa_flags (abfd);
+}
+
+bool
+_bfd_nanomips_elf_final_write_processing (bfd *abfd)
+{
+   _bfd_nanomips_final_write_processing (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_MT)
+    fputs ("\n\tMT ASE", file);
+  if (mask & NANOMIPS_ASE_VIRT)
+    fputs ("\n\tVZ 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;
+    }
+}
+
+/* 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_PIC)
+    fprintf (file, " [PIC]");
+
+  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);
+    }
+}
diff --git a/bfd/elfxx-nanomips.h b/bfd/elfxx-nanomips.h
new file mode 100644
index 00000000000..c5ed51c7538
--- /dev/null
+++ b/bfd/elfxx-nanomips.h
@@ -0,0 +1,46 @@
+/* nanoMIPS ELF specific backend routines.
+   Copyright (C) 2017-2026 Free Software Foundation, CIP United Inc.
+   Contributed by MIPS Tech LLC.
+   Written by Faraz Shahbazker <[email protected]>
+
+   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 void _bfd_nanomips_final_write_processing
+  (bfd *);
+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[];
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 27bc0875cf6..2b2789ab381 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -1278,6 +1278,73 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_MICROMIPS_JMP",
   "BFD_RELOC_MIPS16_JMP",
   "BFD_RELOC_MIPS16_GPREL",
+  "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_HI16",
   "BFD_RELOC_HI16_S",
   "BFD_RELOC_LO16",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 6b9e00da5d6..9a9e719b0ac 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -2264,6 +2264,144 @@ ENUMX
 ENUMDOC
   Fujitsu Frv Relocations.
 
+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
+ENUMDOC
+  nanoMIPS relocations
+COMMENT
+
 ENUM
   BFD_RELOC_MN10300_GOTOFF24
 ENUMDOC
diff --git a/bfd/targets.c b/bfd/targets.c
index fcf650410dc..4d029e536e1 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -830,6 +830,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;
@@ -1206,6 +1210,13 @@ static const bfd_target * const _bfd_target_vector[] =
 
 	&mt_elf32_vec,
 
+	&nanomips_elf32_be_vec,
+	&nanomips_elf32_le_vec,
+#ifdef BFD64
+	&nanomips_elf64_be_vec,
+	&nanomips_elf64_le_vec,
+#endif
+
 	&nds32_elf32_be_vec,
 	&nds32_elf32_le_vec,
 	&nds32_elf32_linux_be_vec,
diff --git a/include/elf/common.h b/include/elf/common.h
index f811b8daeb5..eb1c422ec62 100644
--- a/include/elf/common.h
+++ b/include/elf/common.h
@@ -360,6 +360,7 @@
 #define EM_U16_U8CORE	260	/* LAPIS nX-U16/U8 */
 #define EM_TACHYUM	261	/* Tachyum */
 #define EM_56800EF	262	/* NXP 56800EF Digital Signal Controller (DSC) */
+#define EM_NANOMIPS	263	/* MIPS Tech nanoMIPS architecture.  */
 
 /* If it is necessary to assign new unofficial EM_* values, please pick large
    random numbers (0x8523, 0xa7f2, etc.) to minimize the chances of collision
diff --git a/include/elf/nanomips.h b/include/elf/nanomips.h
new file mode 100644
index 00000000000..25ca243e6b7
--- /dev/null
+++ b/include/elf/nanomips.h
@@ -0,0 +1,211 @@
+/* nanoMIPS ELF support for BFD.
+   Copyright (C) 2017-2026 Free Software Foundation, CIP United Inc.
+   Contributed by MIPS Tech LLC.
+   Written by Faraz Shahbazker <[email protected]>
+
+   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"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+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_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
+
+/* 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
+
+/* Object attribute tags.  */
+enum
+{
+  /* 0-3 are generic.  */
+
+  /* Floating-point ABI used by this object file.  */
+  Tag_GNU_NANOMIPS_ABI_FP = 4,
+};
+
+/* 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,
+};
+
+/* 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_UNUSED1      0x00000002 /* was DSP R2 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_RESERVED1    0x00000400 /* was MIPS16 ASE.  */
+#define NANOMIPS_ASE_RESERVED2    0x00000800 /* was MICROMIPS ASE.  */
+#define NANOMIPS_ASE_UNUSED5      0x00004000 /* was MIPS16 E2 Extension.  */
+#define NANOMIPS_ASE_CRYPTO	  0x00010000 /* Cryptography extension.  */
+#define NANOMIPS_ASE_xNMS         0x00040000 /* not nanoMIPS Subset.  */
+#define NANOMIPS_ASE_MASK         0x0007af4d /* All valid ASEs.  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ELF_NANOMIPS_H */
-- 
2.39.5