[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