From: Maciej W. Rozycki Date: Thu, 30 Oct 2025 14:24:23 +0000 (+0000) Subject: MIPS: Add o32 RELA relocations for VxWorks targets X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6b218502034c1e2f1efbbb7f2f012be7f221ae85;p=thirdparty%2Fbinutils-gdb.git MIPS: Add o32 RELA relocations for VxWorks targets MIPS/VxWorks targets have an unusual arrangement in that they use RELA relocations with the o32 ABI, unlike any other MIPS target. Due to an inconsistency in BFD however "hybrid" relocations are produced by GAS, where despite the relocations being of the RELA type the field to be relocated also holds an in-place addend to be applied at link time. For example: $ cat vxworks-rela.s .text foo: la $2, bar + 0x12345678 $ mips-vxworks-as -o vxworks-rela.o vxworks-rela.s $ mips-vxworks-objdump -dr vxworks-rela.o vxworks-rela.o: file format elf32-bigmips-vxworks Disassembly of section .text: 00000000 : 0: 3c021234 lui v0,0x1234 0: R_MIPS_HI16 bar+0x12345678 4: 24425678 addiu v0,v0,22136 4: R_MIPS_LO16 bar+0x12345678 $ This is due to the BFD backend being strapped for RELA relocations: #undef elf_backend_may_use_rel_p #define elf_backend_may_use_rel_p 0 #undef elf_backend_may_use_rela_p #define elf_backend_may_use_rela_p 1 #undef elf_backend_default_use_rela_p #define elf_backend_default_use_rela_p 1 but the howtos in use requesting an in-place addend, e.g.: /* High 16 bits of symbol value. */ HOWTO (R_MIPS_HI16, /* type */ 16, /* rightshift */ 4, /* size */ 16, /* bitsize */ false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ _bfd_mips_elf_hi16_reloc, /* special_function */ "R_MIPS_HI16", /* name */ true, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ /* Low 16 bits of symbol value. */ HOWTO (R_MIPS_LO16, /* type */ 0, /* rightshift */ 4, /* size */ 16, /* bitsize */ false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ _bfd_mips_elf_lo16_reloc, /* special_function */ "R_MIPS_LO16", /* name */ true, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ This arrangement nevertheless happens to produce correct ELF executables owing to the ELF linker avoiding the use of howtos and doing relocation calculations using its own knowledge of relocation semantics embedded directly in `mips_elf_calculate_relocation' code. Beyond producing questionable link object files it however breaks badly with the generic linker, such as when output is srec. Fix the problem by providing a set of o32 RELA howtos and making VxWorks targets use it. Complement it with a set of test cases for GAS and LD; we expect link object files to be essentially the same as n32 ones for other MIPS targets sans the ABI2 ELF file header flag, and machine code produced to be the same between SREC and ELF executables. --- diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c index 5871fb75e8a..939debda223 100644 --- a/bfd/elf32-mips.c +++ b/bfd/elf32-mips.c @@ -33,6 +33,7 @@ #include "sysdep.h" #include "bfd.h" #include "libbfd.h" +#include "libiberty.h" #include "bfdlink.h" #include "genlink.h" #include "elf-bfd.h" @@ -55,8 +56,6 @@ static bfd_reloc_status_type mips_elf_gprel32_reloc (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); static bfd_reloc_status_type mips32_64bit_reloc (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); -static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup - (bfd *, bfd_reloc_code_real_type); static bool mips_info_to_howto_rel (bfd *, arelent *, Elf_Internal_Rela *); static bool mips_info_to_howto_rela @@ -811,75 +810,1386 @@ static reloc_howto_type elf_mips_howto_table_rel[] = true), /* pcrel_offset */ }; -/* The reloc used for BFD_RELOC_CTOR when doing a 64 bit link. This - is a hack to make the linker think that we need 64 bit values. */ -static reloc_howto_type elf_mips_ctor64_howto = +/* The relocation table used for SHT_RELA sections. */ + +static reloc_howto_type elf_mips_howto_table_rela[] = +{ + /* No relocation. */ + HOWTO (R_MIPS_NONE, /* type */ + 0, /* rightshift */ + 0, /* size */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_NONE", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* 16 bit relocation. */ + HOWTO (R_MIPS_16, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 32 bit relocation. */ + HOWTO (R_MIPS_32, /* type */ + 0, /* rightshift */ + 4, /* size */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_32", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 32 bit symbol relative relocation. */ + HOWTO (R_MIPS_REL32, /* type */ + 0, /* rightshift */ + 4, /* size */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_REL32", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 26 bit jump address. */ + HOWTO (R_MIPS_26, /* type */ + 2, /* rightshift */ + 4, /* size */ + 26, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + /* This needs complex overflow + detection, because the upper four + bits must match the PC + 4. */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_26", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x03ffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* High 16 bits of symbol value. */ + HOWTO (R_MIPS_HI16, /* type */ + 16, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_HI16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Low 16 bits of symbol value. */ + HOWTO (R_MIPS_LO16, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_LO16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* GP relative reference. */ + HOWTO (R_MIPS_GPREL16, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf32_gprel16_reloc, /* special_function */ + "R_MIPS_GPREL16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Reference to literal section. */ + HOWTO (R_MIPS_LITERAL, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf32_gprel16_reloc, /* special_function */ + "R_MIPS_LITERAL", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Reference to global offset table. */ + HOWTO (R_MIPS_GOT16, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_GOT16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 16 bit PC relative reference. Note that the ABI document has a typo + and claims R_MIPS_PC16 to be not rightshifted, rendering it useless. + We do the right thing here. */ + HOWTO (R_MIPS_PC16, /* type */ + 2, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_PC16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + true), /* pcrel_offset */ + + /* 16 bit call through global offset table. */ + HOWTO (R_MIPS_CALL16, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_CALL16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 32 bit GP relative reference. */ + HOWTO (R_MIPS_GPREL32, /* type */ + 0, /* rightshift */ + 4, /* size */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + mips_elf_gprel32_reloc, /* special_function */ + "R_MIPS_GPREL32", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + EMPTY_HOWTO (13), + EMPTY_HOWTO (14), + EMPTY_HOWTO (15), + + /* A 5 bit shift field. */ + HOWTO (R_MIPS_SHIFT5, /* type */ + 0, /* rightshift */ + 4, /* size */ + 5, /* bitsize */ + false, /* pc_relative */ + 6, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_SHIFT5", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x000007c0, /* dst_mask */ + false), /* pcrel_offset */ + + /* A 6 bit shift field. */ + /* FIXME: This is not handled correctly; a special function is + needed to put the most significant bit in the right place. */ + HOWTO (R_MIPS_SHIFT6, /* type */ + 0, /* rightshift */ + 4, /* size */ + 6, /* bitsize */ + false, /* pc_relative */ + 6, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_SHIFT6", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x000007c4, /* dst_mask */ + false), /* pcrel_offset */ + + /* A 64 bit relocation. */ HOWTO (R_MIPS_64, /* type */ 0, /* rightshift */ - 8, /* size */ - 32, /* bitsize */ + 8, /* size */ + 64, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + mips32_64bit_reloc, /* special_function */ + "R_MIPS_64", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + MINUS_ONE, /* dst_mask */ + false), /* pcrel_offset */ + + /* Displacement in the global offset table. */ + HOWTO (R_MIPS_GOT_DISP, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_GOT_DISP", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Displacement to page pointer in the global offset table. */ + HOWTO (R_MIPS_GOT_PAGE, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_GOT_PAGE", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Offset from page pointer in the global offset table. */ + HOWTO (R_MIPS_GOT_OFST, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_GOT_OFST", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* High 16 bits of displacement in global offset table. */ + HOWTO (R_MIPS_GOT_HI16, /* type */ + 16, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_GOT_HI16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Low 16 bits of displacement in global offset table. */ + HOWTO (R_MIPS_GOT_LO16, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_GOT_LO16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 64 bit subtraction. Used in the N32 ABI. */ + HOWTO (R_MIPS_SUB, /* type */ + 0, /* rightshift */ + 8, /* size */ + 64, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_SUB", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + MINUS_ONE, /* dst_mask */ + false), /* pcrel_offset */ + + /* Used to cause the linker to insert and delete instructions? */ + EMPTY_HOWTO (R_MIPS_INSERT_A), + EMPTY_HOWTO (R_MIPS_INSERT_B), + EMPTY_HOWTO (R_MIPS_DELETE), + + /* Get the higher value of a 64 bit addend. */ + HOWTO (R_MIPS_HIGHER, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_HIGHER", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Get the highest value of a 64 bit addend. */ + HOWTO (R_MIPS_HIGHEST, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_HIGHEST", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* High 16 bits of displacement in global offset table. */ + HOWTO (R_MIPS_CALL_HI16, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_CALL_HI16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Low 16 bits of displacement in global offset table. */ + HOWTO (R_MIPS_CALL_LO16, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_CALL_LO16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Section displacement. */ + HOWTO (R_MIPS_SCN_DISP, /* type */ + 0, /* rightshift */ + 4, /* size */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_SCN_DISP", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + EMPTY_HOWTO (R_MIPS_REL16), + EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE), + EMPTY_HOWTO (R_MIPS_PJUMP), + EMPTY_HOWTO (R_MIPS_RELGOT), + + /* Protected jump conversion. This is an optimization hint. No + relocation is required for correctness. */ + HOWTO (R_MIPS_JALR, /* type */ + 0, /* rightshift */ + 4, /* size */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_JALR", /* name */ + false, /* partial_inplace */ + 0x00000000, /* src_mask */ + 0x00000000, /* dst_mask */ + false), /* pcrel_offset */ + + /* TLS GD/LD dynamic relocations. */ + HOWTO (R_MIPS_TLS_DTPMOD32, /* type */ + 0, /* rightshift */ + 4, /* size */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_DTPMOD32", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO (R_MIPS_TLS_DTPREL32, /* type */ + 0, /* rightshift */ + 4, /* size */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_DTPREL32", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + EMPTY_HOWTO (R_MIPS_TLS_DTPMOD64), + EMPTY_HOWTO (R_MIPS_TLS_DTPREL64), + + /* TLS general dynamic variable reference. */ + HOWTO (R_MIPS_TLS_GD, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_GD", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* TLS local dynamic variable reference. */ + HOWTO (R_MIPS_TLS_LDM, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_LDM", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* TLS local dynamic offset. */ + HOWTO (R_MIPS_TLS_DTPREL_HI16, /* type */ + 16, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_DTPREL_HI16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* TLS local dynamic offset. */ + HOWTO (R_MIPS_TLS_DTPREL_LO16, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_DTPREL_LO16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* TLS thread pointer offset. */ + HOWTO (R_MIPS_TLS_GOTTPREL, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_GOTTPREL", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* TLS IE dynamic relocations. */ + HOWTO (R_MIPS_TLS_TPREL32, /* type */ + 0, /* rightshift */ + 4, /* size */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_TPREL32", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + EMPTY_HOWTO (R_MIPS_TLS_TPREL64), + + /* TLS thread pointer offset. */ + HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */ + 16, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_TPREL_HI16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* TLS thread pointer offset. */ + HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_TPREL_LO16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 32 bit relocation with no addend. */ + HOWTO (R_MIPS_GLOB_DAT, /* type */ + 0, /* rightshift */ + 4, /* size */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_GLOB_DAT", /* name */ + false, /* partial_inplace */ + 0x0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + EMPTY_HOWTO (52), + EMPTY_HOWTO (53), + EMPTY_HOWTO (54), + EMPTY_HOWTO (55), + EMPTY_HOWTO (56), + EMPTY_HOWTO (57), + EMPTY_HOWTO (58), + EMPTY_HOWTO (59), + + HOWTO (R_MIPS_PC21_S2, /* type */ + 2, /* rightshift */ + 4, /* size */ + 21, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_PC21_S2", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x001fffff, /* dst_mask */ + true), /* pcrel_offset */ + + HOWTO (R_MIPS_PC26_S2, /* type */ + 2, /* rightshift */ + 4, /* size */ + 26, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_PC26_S2", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x03ffffff, /* dst_mask */ + true), /* pcrel_offset */ + + HOWTO (R_MIPS_PC18_S3, /* type */ + 3, /* rightshift */ + 4, /* size */ + 18, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_PC18_S3", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0003ffff, /* dst_mask */ + true), /* pcrel_offset */ + + HOWTO (R_MIPS_PC19_S2, /* type */ + 2, /* rightshift */ + 4, /* size */ + 19, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_PC19_S2", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0007ffff, /* dst_mask */ + true), /* pcrel_offset */ + + HOWTO (R_MIPS_PCHI16, /* type */ + 16, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_PCHI16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + true), /* pcrel_offset */ + + HOWTO (R_MIPS_PCLO16, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_PCLO16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + true), /* pcrel_offset */ +}; + +/* The reloc used for BFD_RELOC_CTOR when doing a 64 bit link. This + is a hack to make the linker think that we need 64 bit values. */ +static reloc_howto_type elf_mips_ctor64_howto = + HOWTO (R_MIPS_64, /* type */ + 0, /* rightshift */ + 8, /* size */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + mips32_64bit_reloc, /* special_function */ + "R_MIPS_64", /* name */ + true, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + false); /* pcrel_offset */ + +static reloc_howto_type elf_mips16_howto_table_rel[] = +{ + /* The reloc used for the mips16 jump instruction. */ + HOWTO (R_MIPS16_26, /* type */ + 2, /* rightshift */ + 4, /* size */ + 26, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + /* This needs complex overflow + detection, because the upper four + bits must match the PC. */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_26", /* name */ + true, /* partial_inplace */ + 0x3ffffff, /* src_mask */ + 0x3ffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* The reloc used for the mips16 gprel instruction. */ + HOWTO (R_MIPS16_GPREL, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + mips16_gprel_reloc, /* special_function */ + "R_MIPS16_GPREL", /* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* A MIPS16 reference to the global offset table. */ + HOWTO (R_MIPS16_GOT16, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_got16_reloc, /* special_function */ + "R_MIPS16_GOT16", /* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* A MIPS16 call through the global offset table. */ + HOWTO (R_MIPS16_CALL16, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_CALL16", /* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* MIPS16 high 16 bits of symbol value. */ + HOWTO (R_MIPS16_HI16, /* type */ + 16, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_hi16_reloc, /* special_function */ + "R_MIPS16_HI16", /* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* MIPS16 low 16 bits of symbol value. */ + HOWTO (R_MIPS16_LO16, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_lo16_reloc, /* special_function */ + "R_MIPS16_LO16", /* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* MIPS16 TLS general dynamic variable reference. */ + HOWTO (R_MIPS16_TLS_GD, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_GD", /* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* MIPS16 TLS local dynamic variable reference. */ + HOWTO (R_MIPS16_TLS_LDM, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_LDM", /* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* MIPS16 TLS local dynamic offset. */ + HOWTO (R_MIPS16_TLS_DTPREL_HI16, /* type */ + 16, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_hi16_reloc, /* special_function */ + "R_MIPS16_TLS_DTPREL_HI16", /* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* MIPS16 TLS local dynamic offset. */ + HOWTO (R_MIPS16_TLS_DTPREL_LO16, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_lo16_reloc, /* special_function */ + "R_MIPS16_TLS_DTPREL_LO16", /* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* MIPS16 TLS thread pointer offset. */ + HOWTO (R_MIPS16_TLS_GOTTPREL, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_GOTTPREL", /* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* MIPS16 TLS thread pointer offset. */ + HOWTO (R_MIPS16_TLS_TPREL_HI16, /* type */ + 16, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_hi16_reloc, /* special_function */ + "R_MIPS16_TLS_TPREL_HI16", /* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* MIPS16 TLS thread pointer offset. */ + HOWTO (R_MIPS16_TLS_TPREL_LO16, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_lo16_reloc, /* special_function */ + "R_MIPS16_TLS_TPREL_LO16", /* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* MIPS16 16-bit PC-relative branch offset. */ + HOWTO (R_MIPS16_PC16_S1, /* type */ + 1, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_PC16_S1", /* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + true), /* pcrel_offset */ +}; + +static reloc_howto_type elf_mips16_howto_table_rela[] = +{ + /* The reloc used for the mips16 jump instruction. */ + HOWTO (R_MIPS16_26, /* type */ + 2, /* rightshift */ + 4, /* size */ + 26, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + /* This needs complex overflow + detection, because the upper four + bits must match the PC. */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_26", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x3ffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* The reloc used for the mips16 gprel instruction. */ + HOWTO (R_MIPS16_GPREL, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + mips16_gprel_reloc, /* special_function */ + "R_MIPS16_GPREL", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* A MIPS16 reference to the global offset table. */ + HOWTO (R_MIPS16_GOT16, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_GOT16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* A MIPS16 call through the global offset table. */ + HOWTO (R_MIPS16_CALL16, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_CALL16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* MIPS16 high 16 bits of symbol value. */ + HOWTO (R_MIPS16_HI16, /* type */ + 16, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_HI16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* MIPS16 low 16 bits of symbol value. */ + HOWTO (R_MIPS16_LO16, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_LO16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* MIPS16 TLS general dynamic variable reference. */ + HOWTO (R_MIPS16_TLS_GD, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_GD", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* MIPS16 TLS local dynamic variable reference. */ + HOWTO (R_MIPS16_TLS_LDM, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_LDM", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* MIPS16 TLS local dynamic offset. */ + HOWTO (R_MIPS16_TLS_DTPREL_HI16, /* type */ + 16, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_DTPREL_HI16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* MIPS16 TLS local dynamic offset. */ + HOWTO (R_MIPS16_TLS_DTPREL_LO16, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_DTPREL_LO16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* MIPS16 TLS thread pointer offset. */ + HOWTO (R_MIPS16_TLS_GOTTPREL, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_GOTTPREL", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* MIPS16 TLS thread pointer offset. */ + HOWTO (R_MIPS16_TLS_TPREL_HI16, /* type */ + 16, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_TPREL_HI16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* MIPS16 TLS thread pointer offset. */ + HOWTO (R_MIPS16_TLS_TPREL_LO16, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_TPREL_LO16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* MIPS16 16-bit PC-relative branch offset. */ + HOWTO (R_MIPS16_PC16_S1, /* type */ + 1, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_PC16_S1", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + true), /* pcrel_offset */ +}; + +static reloc_howto_type elf_micromips_howto_table_rel[] = +{ + EMPTY_HOWTO (130), + EMPTY_HOWTO (131), + EMPTY_HOWTO (132), + + /* 26 bit jump address. */ + HOWTO (R_MICROMIPS_26_S1, /* type */ + 1, /* rightshift */ + 4, /* size */ + 26, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + /* This needs complex overflow + detection, because the upper four + bits must match the PC. */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_26_S1", /* name */ + true, /* partial_inplace */ + 0x3ffffff, /* src_mask */ + 0x3ffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* High 16 bits of symbol value. */ + HOWTO (R_MICROMIPS_HI16, /* type */ + 16, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_hi16_reloc, /* special_function */ + "R_MICROMIPS_HI16", /* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Low 16 bits of symbol value. */ + HOWTO (R_MICROMIPS_LO16, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_lo16_reloc, /* special_function */ + "R_MICROMIPS_LO16", /* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* GP relative reference. */ + HOWTO (R_MICROMIPS_GPREL16, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf32_gprel16_reloc, /* special_function */ + "R_MICROMIPS_GPREL16", /* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Reference to literal section. */ + HOWTO (R_MICROMIPS_LITERAL, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf32_gprel16_reloc, /* special_function */ + "R_MICROMIPS_LITERAL", /* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Reference to global offset table. */ + HOWTO (R_MICROMIPS_GOT16, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ false, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips32_64bit_reloc, /* special_function */ - "R_MIPS_64", /* name */ + _bfd_mips_elf_got16_reloc, /* special_function */ + "R_MICROMIPS_GOT16", /* name */ true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false); /* pcrel_offset */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ -static reloc_howto_type elf_mips16_howto_table_rel[] = -{ - /* The reloc used for the mips16 jump instruction. */ - HOWTO (R_MIPS16_26, /* type */ - 2, /* rightshift */ + /* This is for microMIPS branches. */ + HOWTO (R_MICROMIPS_PC7_S1, /* type */ + 1, /* rightshift */ + 2, /* size */ + 7, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_PC7_S1", /* name */ + true, /* partial_inplace */ + 0x0000007f, /* src_mask */ + 0x0000007f, /* dst_mask */ + true), /* pcrel_offset */ + + HOWTO (R_MICROMIPS_PC10_S1, /* type */ + 1, /* rightshift */ + 2, /* size */ + 10, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_PC10_S1", /* name */ + true, /* partial_inplace */ + 0x000003ff, /* src_mask */ + 0x000003ff, /* dst_mask */ + true), /* pcrel_offset */ + + HOWTO (R_MICROMIPS_PC16_S1, /* type */ + 1, /* rightshift */ 4, /* size */ - 26, /* bitsize */ + 16, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_PC16_S1", /* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + true), /* pcrel_offset */ + + /* 16 bit call through global offset table. */ + HOWTO (R_MICROMIPS_CALL16, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ false, /* pc_relative */ 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - /* This needs complex overflow - detection, because the upper four - bits must match the PC. */ + complain_overflow_signed, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ - "R_MIPS16_26", /* name */ + "R_MICROMIPS_CALL16", /* name */ true, /* partial_inplace */ - 0x3ffffff, /* src_mask */ - 0x3ffffff, /* dst_mask */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ - /* The reloc used for the mips16 gprel instruction. */ - HOWTO (R_MIPS16_GPREL, /* type */ + EMPTY_HOWTO (143), + EMPTY_HOWTO (144), + + /* Displacement in the global offset table. */ + HOWTO (R_MICROMIPS_GOT_DISP, /* type */ 0, /* rightshift */ 4, /* size */ 16, /* bitsize */ false, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips16_gprel_reloc, /* special_function */ - "R_MIPS16_GPREL", /* name */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_GOT_DISP",/* name */ true, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ - /* A MIPS16 reference to the global offset table. */ - HOWTO (R_MIPS16_GOT16, /* type */ + /* Displacement to page pointer in the global offset table. */ + HOWTO (R_MICROMIPS_GOT_PAGE, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_GOT_PAGE",/* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Offset from page pointer in the global offset table. */ + HOWTO (R_MICROMIPS_GOT_OFST, /* type */ 0, /* rightshift */ 4, /* size */ 16, /* bitsize */ false, /* pc_relative */ 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_GOT_OFST",/* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* High 16 bits of displacement in global offset table. */ + HOWTO (R_MICROMIPS_GOT_HI16, /* type */ + 16, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - _bfd_mips_elf_got16_reloc, /* special_function */ - "R_MIPS16_GOT16", /* name */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_GOT_HI16",/* name */ true, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ - /* A MIPS16 call through the global offset table. */ - HOWTO (R_MIPS16_CALL16, /* type */ + /* Low 16 bits of displacement in global offset table. */ + HOWTO (R_MICROMIPS_GOT_LO16, /* type */ 0, /* rightshift */ 4, /* size */ 16, /* bitsize */ @@ -887,44 +2197,141 @@ static reloc_howto_type elf_mips16_howto_table_rel[] = 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ - "R_MIPS16_CALL16", /* name */ + "R_MICROMIPS_GOT_LO16",/* name */ true, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ - /* MIPS16 high 16 bits of symbol value. */ - HOWTO (R_MIPS16_HI16, /* type */ + /* 64 bit subtraction. Used in the N32 ABI. */ + HOWTO (R_MICROMIPS_SUB, /* type */ + 0, /* rightshift */ + 8, /* size */ + 64, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_SUB", /* name */ + true, /* partial_inplace */ + MINUS_ONE, /* src_mask */ + MINUS_ONE, /* dst_mask */ + false), /* pcrel_offset */ + + /* Get the higher value of a 64 bit addend. */ + HOWTO (R_MICROMIPS_HIGHER, /* type */ + 32, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_HIGHER", /* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Get the highest value of a 64 bit addend. */ + HOWTO (R_MICROMIPS_HIGHEST, /* type */ + 48, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_HIGHEST", /* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* High 16 bits of displacement in global offset table. */ + HOWTO (R_MICROMIPS_CALL_HI16, /* type */ 16, /* rightshift */ 4, /* size */ 16, /* bitsize */ false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - _bfd_mips_elf_hi16_reloc, /* special_function */ - "R_MIPS16_HI16", /* name */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_CALL_HI16",/* name */ true, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ - /* MIPS16 low 16 bits of symbol value. */ - HOWTO (R_MIPS16_LO16, /* type */ + /* Low 16 bits of displacement in global offset table. */ + HOWTO (R_MICROMIPS_CALL_LO16, /* type */ 0, /* rightshift */ 4, /* size */ 16, /* bitsize */ false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - _bfd_mips_elf_lo16_reloc, /* special_function */ - "R_MIPS16_LO16", /* name */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_CALL_LO16",/* name */ true, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ - /* MIPS16 TLS general dynamic variable reference. */ - HOWTO (R_MIPS16_TLS_GD, /* type */ + /* Section displacement. */ + HOWTO (R_MICROMIPS_SCN_DISP, /* type */ + 0, /* rightshift */ + 4, /* size */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_SCN_DISP",/* name */ + true, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Protected jump conversion. This is an optimization hint. No + relocation is required for correctness. */ + HOWTO (R_MICROMIPS_JALR, /* type */ + 0, /* rightshift */ + 4, /* size */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_JALR", /* name */ + false, /* partial_inplace */ + 0x00000000, /* src_mask */ + 0x00000000, /* dst_mask */ + false), /* pcrel_offset */ + + /* Low 16 bits of symbol value. Note that the high 16 bits of symbol values + must be zero. This is used for relaxation. */ + HOWTO (R_MICROMIPS_HI0_LO16, /* type */ + 0, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_HI0_LO16",/* name */ + true, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + false), /* pcrel_offset */ + + EMPTY_HOWTO (158), + EMPTY_HOWTO (159), + EMPTY_HOWTO (160), + EMPTY_HOWTO (161), + + /* TLS general dynamic variable reference. */ + HOWTO (R_MICROMIPS_TLS_GD, /* type */ 0, /* rightshift */ 4, /* size */ 16, /* bitsize */ @@ -932,14 +2339,14 @@ static reloc_howto_type elf_mips16_howto_table_rel[] = 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ - "R_MIPS16_TLS_GD", /* name */ + "R_MICROMIPS_TLS_GD", /* name */ true, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ - /* MIPS16 TLS local dynamic variable reference. */ - HOWTO (R_MIPS16_TLS_LDM, /* type */ + /* TLS local dynamic variable reference. */ + HOWTO (R_MICROMIPS_TLS_LDM, /* type */ 0, /* rightshift */ 4, /* size */ 16, /* bitsize */ @@ -947,14 +2354,14 @@ static reloc_howto_type elf_mips16_howto_table_rel[] = 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ - "R_MIPS16_TLS_LDM", /* name */ + "R_MICROMIPS_TLS_LDM", /* name */ true, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ - /* MIPS16 TLS local dynamic offset. */ - HOWTO (R_MIPS16_TLS_DTPREL_HI16, /* type */ + /* TLS local dynamic offset. */ + HOWTO (R_MICROMIPS_TLS_DTPREL_HI16, /* type */ 16, /* rightshift */ 4, /* size */ 16, /* bitsize */ @@ -962,14 +2369,14 @@ static reloc_howto_type elf_mips16_howto_table_rel[] = 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ _bfd_mips_elf_hi16_reloc, /* special_function */ - "R_MIPS16_TLS_DTPREL_HI16", /* name */ + "R_MICROMIPS_TLS_DTPREL_HI16", /* name */ true, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ - /* MIPS16 TLS local dynamic offset. */ - HOWTO (R_MIPS16_TLS_DTPREL_LO16, /* type */ + /* TLS local dynamic offset. */ + HOWTO (R_MICROMIPS_TLS_DTPREL_LO16, /* type */ 0, /* rightshift */ 4, /* size */ 16, /* bitsize */ @@ -977,14 +2384,14 @@ static reloc_howto_type elf_mips16_howto_table_rel[] = 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ _bfd_mips_elf_lo16_reloc, /* special_function */ - "R_MIPS16_TLS_DTPREL_LO16", /* name */ + "R_MICROMIPS_TLS_DTPREL_LO16", /* name */ true, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ - /* MIPS16 TLS thread pointer offset. */ - HOWTO (R_MIPS16_TLS_GOTTPREL, /* type */ + /* TLS thread pointer offset. */ + HOWTO (R_MICROMIPS_TLS_GOTTPREL, /* type */ 0, /* rightshift */ 4, /* size */ 16, /* bitsize */ @@ -992,14 +2399,17 @@ static reloc_howto_type elf_mips16_howto_table_rel[] = 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ - "R_MIPS16_TLS_GOTTPREL", /* name */ + "R_MICROMIPS_TLS_GOTTPREL", /* name */ true, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ - /* MIPS16 TLS thread pointer offset. */ - HOWTO (R_MIPS16_TLS_TPREL_HI16, /* type */ + EMPTY_HOWTO (167), + EMPTY_HOWTO (168), + + /* TLS thread pointer offset. */ + HOWTO (R_MICROMIPS_TLS_TPREL_HI16, /* type */ 16, /* rightshift */ 4, /* size */ 16, /* bitsize */ @@ -1007,14 +2417,14 @@ static reloc_howto_type elf_mips16_howto_table_rel[] = 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ _bfd_mips_elf_hi16_reloc, /* special_function */ - "R_MIPS16_TLS_TPREL_HI16", /* name */ + "R_MICROMIPS_TLS_TPREL_HI16", /* name */ true, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ - /* MIPS16 TLS thread pointer offset. */ - HOWTO (R_MIPS16_TLS_TPREL_LO16, /* type */ + /* TLS thread pointer offset. */ + HOWTO (R_MICROMIPS_TLS_TPREL_LO16, /* type */ 0, /* rightshift */ 4, /* size */ 16, /* bitsize */ @@ -1022,29 +2432,45 @@ static reloc_howto_type elf_mips16_howto_table_rel[] = 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ _bfd_mips_elf_lo16_reloc, /* special_function */ - "R_MIPS16_TLS_TPREL_LO16", /* name */ + "R_MICROMIPS_TLS_TPREL_LO16", /* name */ true, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ - /* MIPS16 16-bit PC-relative branch offset. */ - HOWTO (R_MIPS16_PC16_S1, /* type */ - 1, /* rightshift */ + EMPTY_HOWTO (171), + + /* GP- and PC-relative relocations. */ + HOWTO (R_MICROMIPS_GPREL7_S2, /* type */ + 2, /* rightshift */ + 2, /* size */ + 7, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf32_gprel16_reloc, /* special_function */ + "R_MICROMIPS_GPREL7_S2", /* name */ + true, /* partial_inplace */ + 0x0000007f, /* src_mask */ + 0x0000007f, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO (R_MICROMIPS_PC23_S2, /* type */ + 2, /* rightshift */ 4, /* size */ - 16, /* bitsize */ + 23, /* bitsize */ true, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ - "R_MIPS16_PC16_S1", /* name */ + "R_MICROMIPS_PC23_S2", /* name */ true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ + 0x007fffff, /* src_mask */ + 0x007fffff, /* dst_mask */ true), /* pcrel_offset */ }; -static reloc_howto_type elf_micromips_howto_table_rel[] = +static reloc_howto_type elf_micromips_howto_table_rela[] = { EMPTY_HOWTO (130), EMPTY_HOWTO (131), @@ -1063,8 +2489,8 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = bits must match the PC. */ _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_26_S1", /* name */ - true, /* partial_inplace */ - 0x3ffffff, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ 0x3ffffff, /* dst_mask */ false), /* pcrel_offset */ @@ -1076,10 +2502,10 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - _bfd_mips_elf_hi16_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_HI16", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ @@ -1091,10 +2517,10 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - _bfd_mips_elf_lo16_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_LO16", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ @@ -1108,8 +2534,8 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = complain_overflow_signed, /* complain_on_overflow */ _bfd_mips_elf32_gprel16_reloc, /* special_function */ "R_MICROMIPS_GPREL16", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ @@ -1123,8 +2549,8 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = complain_overflow_signed, /* complain_on_overflow */ _bfd_mips_elf32_gprel16_reloc, /* special_function */ "R_MICROMIPS_LITERAL", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ @@ -1136,10 +2562,10 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = false, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - _bfd_mips_elf_got16_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_GOT16", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ @@ -1153,8 +2579,8 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = complain_overflow_signed, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_PC7_S1", /* name */ - true, /* partial_inplace */ - 0x0000007f, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ 0x0000007f, /* dst_mask */ true), /* pcrel_offset */ @@ -1167,8 +2593,8 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = complain_overflow_signed, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_PC10_S1", /* name */ - true, /* partial_inplace */ - 0x000003ff, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ 0x000003ff, /* dst_mask */ true), /* pcrel_offset */ @@ -1181,8 +2607,8 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = complain_overflow_signed, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_PC16_S1", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ 0x0000ffff, /* dst_mask */ true), /* pcrel_offset */ @@ -1196,8 +2622,8 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = complain_overflow_signed, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_CALL16", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ @@ -1214,8 +2640,8 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = complain_overflow_signed, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_GOT_DISP",/* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ @@ -1229,8 +2655,8 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = complain_overflow_signed, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_GOT_PAGE",/* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ @@ -1244,8 +2670,8 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = complain_overflow_signed, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_GOT_OFST",/* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ @@ -1259,8 +2685,8 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = complain_overflow_dont, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_GOT_HI16",/* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ @@ -1274,8 +2700,8 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = complain_overflow_dont, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_GOT_LO16",/* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ @@ -1289,8 +2715,8 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = complain_overflow_dont, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_SUB", /* name */ - true, /* partial_inplace */ - MINUS_ONE, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ MINUS_ONE, /* dst_mask */ false), /* pcrel_offset */ @@ -1304,8 +2730,8 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = complain_overflow_dont, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_HIGHER", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ @@ -1319,8 +2745,8 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = complain_overflow_dont, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_HIGHEST", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ @@ -1334,8 +2760,8 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = complain_overflow_dont, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_CALL_HI16",/* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ @@ -1349,8 +2775,8 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = complain_overflow_dont, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_CALL_LO16",/* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ @@ -1363,9 +2789,9 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ - "R_MICROMIPS_SCN_DISP",/* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ + "R_MICROMIPS_SCN_DISP", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ 0xffffffff, /* dst_mask */ false), /* pcrel_offset */ @@ -1381,7 +2807,7 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_JALR", /* name */ false, /* partial_inplace */ - 0x00000000, /* src_mask */ + 0, /* src_mask */ 0x00000000, /* dst_mask */ false), /* pcrel_offset */ @@ -1396,8 +2822,8 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = complain_overflow_dont, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_HI0_LO16",/* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ @@ -1416,8 +2842,8 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = complain_overflow_signed, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_TLS_GD", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ @@ -1431,8 +2857,8 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = complain_overflow_signed, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_TLS_LDM", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ @@ -1444,10 +2870,10 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = false, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - _bfd_mips_elf_hi16_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_TLS_DTPREL_HI16", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ @@ -1459,10 +2885,10 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - _bfd_mips_elf_lo16_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_TLS_DTPREL_LO16", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ @@ -1476,8 +2902,8 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = complain_overflow_signed, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_TLS_GOTTPREL", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ @@ -1492,10 +2918,10 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = false, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - _bfd_mips_elf_hi16_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_TLS_TPREL_HI16", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ @@ -1507,10 +2933,10 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - _bfd_mips_elf_lo16_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_TLS_TPREL_LO16", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ @@ -1526,8 +2952,8 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = complain_overflow_signed, /* complain_on_overflow */ _bfd_mips_elf32_gprel16_reloc, /* special_function */ "R_MICROMIPS_GPREL7_S2", /* name */ - true, /* partial_inplace */ - 0x0000007f, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ 0x0000007f, /* dst_mask */ false), /* pcrel_offset */ @@ -1540,8 +2966,8 @@ static reloc_howto_type elf_micromips_howto_table_rel[] = complain_overflow_signed, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_PC23_S2", /* name */ - true, /* partial_inplace */ - 0x007fffff, /* src_mask */ + false, /* partial_inplace */ + 0, /* src_mask */ 0x007fffff, /* dst_mask */ true), /* pcrel_offset */ }; @@ -1562,6 +2988,22 @@ static reloc_howto_type elf_mips_gnu_rel16_s2 = 0xffff, /* dst_mask */ true); /* pcrel_offset */ +/* 16 bit offset for pc-relative branches. */ +static reloc_howto_type elf_mips_gnu_rela16_s2 = + HOWTO (R_MIPS_GNU_REL16_S2, /* type */ + 2, /* rightshift */ + 4, /* size */ + 16, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_GNU_REL16_S2", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + true); /* pcrel_offset */ + /* 32 bit pc-relative. This was a GNU extension used by embedded-PIC. It was co-opted by mips-linux for exception-handling data. GCC stopped using it in May, 2004, then started using it again for compact unwind @@ -2097,12 +3539,12 @@ static const struct elf_reloc_map micromips_reloc_map[] = /* Given a BFD reloc type, return a howto structure. */ static reloc_howto_type * -bfd_elf32_bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code) +mips_elf32_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code, + reloc_howto_type *howto_table, + reloc_howto_type *howto16_table, + reloc_howto_type *howto_micromips_table) { unsigned int i; - reloc_howto_type *howto_table = elf_mips_howto_table_rel; - reloc_howto_type *howto16_table = elf_mips16_howto_table_rel; - reloc_howto_type *howto_micromips_table = elf_micromips_howto_table_rel; for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map); i++) @@ -2156,35 +3598,55 @@ bfd_elf32_bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code) } } +/* Given a BFD reloc type, return a howto structure; REL wrapper. */ + +static reloc_howto_type * +mips_elf32_reloc_type_lookup_rel (bfd *abfd, bfd_reloc_code_real_type code) +{ + return mips_elf32_reloc_type_lookup (abfd, code, + elf_mips_howto_table_rel, + elf_mips16_howto_table_rel, + elf_micromips_howto_table_rel); +} + +/* Given a BFD reloc type, return a howto structure; RELA wrapper. */ + +static reloc_howto_type * +mips_elf32_reloc_type_lookup_rela (bfd *abfd, bfd_reloc_code_real_type code) +{ + return mips_elf32_reloc_type_lookup (abfd, code, + elf_mips_howto_table_rela, + elf_mips16_howto_table_rela, + elf_micromips_howto_table_rela); +} + +/* Given an ELF reloc name, return a howto structure. */ + static reloc_howto_type * -bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, - const char *r_name) +mips_elf32_reloc_name_lookup (const char *r_name, + reloc_howto_type *howto_table, + size_t howto_table_size, + reloc_howto_type *howto16_table, + size_t howto16_table_size, + reloc_howto_type *howto_micromips_table, + size_t howto_micromips_table_size) { unsigned int i; - for (i = 0; - i < (sizeof (elf_mips_howto_table_rel) - / sizeof (elf_mips_howto_table_rel[0])); - i++) - if (elf_mips_howto_table_rel[i].name != NULL - && strcasecmp (elf_mips_howto_table_rel[i].name, r_name) == 0) - return &elf_mips_howto_table_rel[i]; + for (i = 0; i < howto_table_size; i++) + if (howto_table[i].name != NULL + && strcasecmp (howto_table[i].name, r_name) == 0) + return &howto_table[i]; - for (i = 0; - i < (sizeof (elf_mips16_howto_table_rel) - / sizeof (elf_mips16_howto_table_rel[0])); - i++) - if (elf_mips16_howto_table_rel[i].name != NULL - && strcasecmp (elf_mips16_howto_table_rel[i].name, r_name) == 0) - return &elf_mips16_howto_table_rel[i]; + for (i = 0; i < howto16_table_size; i++) + if (howto16_table[i].name != NULL + && strcasecmp (howto16_table[i].name, r_name) == 0) + return &howto16_table[i]; - for (i = 0; - i < (sizeof (elf_micromips_howto_table_rel) - / sizeof (elf_micromips_howto_table_rel[0])); - i++) - if (elf_micromips_howto_table_rel[i].name != NULL - && strcasecmp (elf_micromips_howto_table_rel[i].name, r_name) == 0) - return &elf_micromips_howto_table_rel[i]; + for (i = 0; i < howto_micromips_table_size; i++) + if (howto_micromips_table[i].name != NULL + && strcasecmp (howto_micromips_table[i].name, r_name) == 0) + return &howto_micromips_table[i]; if (strcasecmp (elf_mips_gnu_pcrel32.name, r_name) == 0) return &elf_mips_gnu_pcrel32; @@ -2204,12 +3666,42 @@ bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, return NULL; } -/* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */ +/* Given an ELF reloc name, return a howto structure; REL wrapper. */ + +static reloc_howto_type * +mips_elf32_reloc_name_lookup_rel (bfd *abfd ATTRIBUTE_UNUSED, + const char *r_name) +{ + return + mips_elf32_reloc_name_lookup (r_name, + elf_mips_howto_table_rel, + ARRAY_SIZE (elf_mips_howto_table_rel), + elf_mips16_howto_table_rel, + ARRAY_SIZE (elf_mips16_howto_table_rel), + elf_micromips_howto_table_rel, + ARRAY_SIZE (elf_micromips_howto_table_rel)); +} + +/* Given an ELF reloc name, return a howto structure; RELA wrapper. */ + +static reloc_howto_type * +mips_elf32_reloc_name_lookup_rela (bfd *abfd ATTRIBUTE_UNUSED, + const char *r_name) +{ + return + mips_elf32_reloc_name_lookup (r_name, + elf_mips_howto_table_rela, + ARRAY_SIZE (elf_mips_howto_table_rela), + elf_mips16_howto_table_rela, + ARRAY_SIZE (elf_mips16_howto_table_rela), + elf_micromips_howto_table_rela, + ARRAY_SIZE (elf_micromips_howto_table_rela)); +} + +/* Given an ELF reloc type, return a howto structure. */ static reloc_howto_type * -mips_elf32_rtype_to_howto (bfd *abfd, - unsigned int r_type, - bool rela_p ATTRIBUTE_UNUSED) +mips_elf32_rtype_to_howto (bfd *abfd, unsigned int r_type, bool rela_p) { reloc_howto_type *howto = NULL; @@ -2220,7 +3712,7 @@ mips_elf32_rtype_to_howto (bfd *abfd, case R_MIPS_GNU_VTENTRY: return &elf_mips_gnu_vtentry_howto; case R_MIPS_GNU_REL16_S2: - return &elf_mips_gnu_rel16_s2; + return rela_p ? &elf_mips_gnu_rela16_s2 : &elf_mips_gnu_rel16_s2; case R_MIPS_PC32: return &elf_mips_gnu_pcrel32; case R_MIPS_COPY: @@ -2231,11 +3723,17 @@ mips_elf32_rtype_to_howto (bfd *abfd, return &elf_mips_eh_howto; default: if (r_type >= R_MICROMIPS_min && r_type < R_MICROMIPS_max) - howto = &elf_micromips_howto_table_rel[r_type - R_MICROMIPS_min]; + howto = (rela_p + ? &elf_micromips_howto_table_rela[r_type - R_MICROMIPS_min] + : &elf_micromips_howto_table_rel[r_type - R_MICROMIPS_min]); if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max) - howto = &elf_mips16_howto_table_rel[r_type - R_MIPS16_min]; + howto = (rela_p + ? &elf_mips16_howto_table_rela[r_type - R_MIPS16_min] + : &elf_mips16_howto_table_rel[r_type - R_MIPS16_min]); if (r_type < R_MIPS_max) - howto = &elf_mips_howto_table_rel[r_type]; + howto = (rela_p + ? &elf_mips_howto_table_rela[r_type] + : &elf_mips_howto_table_rel[r_type]); if (howto != NULL && howto->name != NULL) return howto; @@ -2246,15 +3744,16 @@ mips_elf32_rtype_to_howto (bfd *abfd, } } -/* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */ +/* Given a MIPS Elf_Internal_Rela, fill in an arelent structure. */ static bool -mips_info_to_howto_rel (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst) +mips_info_to_howto (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst, + bool rela_p) { unsigned int r_type; r_type = ELF32_R_TYPE (dst->r_info); - cache_ptr->howto = mips_elf32_rtype_to_howto (abfd, r_type, false); + cache_ptr->howto = mips_elf32_rtype_to_howto (abfd, r_type, rela_p); if (cache_ptr->howto == NULL) return false; @@ -2270,15 +3769,22 @@ mips_info_to_howto_rel (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst) return true; } -/* Given a MIPS Elf_Internal_Rela, fill in an arelent structure. */ +/* Given a MIPS Elf_Internal_Rela, fill in an arelent structure; + REL wrapper. */ static bool -mips_info_to_howto_rela (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst) +mips_info_to_howto_rel (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst) { - return mips_info_to_howto_rel (abfd, cache_ptr, dst); + return mips_info_to_howto (abfd, cache_ptr, dst, false); +} - /* If we ever need to do any extra processing with dst->r_addend - (the field omitted in an Elf_Internal_Rel) we can do it here. */ +/* Given a MIPS Elf_Internal_Rela, fill in an arelent structure; + RELA wrapper. */ + +static bool +mips_info_to_howto_rela (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst) +{ + return mips_info_to_howto (abfd, cache_ptr, dst, true); } /* Determine whether a symbol is global for the purposes of splitting @@ -2578,6 +4084,8 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = { #define bfd_elf32_bfd_is_local_label_name \ mips_elf_is_local_label_name +#define bfd_elf32_bfd_reloc_type_lookup mips_elf32_reloc_type_lookup_rel +#define bfd_elf32_bfd_reloc_name_lookup mips_elf32_reloc_name_lookup_rel #define bfd_elf32_bfd_is_target_special_symbol \ _bfd_mips_elf_is_target_special_symbol #define bfd_elf32_get_synthetic_symtab _bfd_mips_elf_get_synthetic_symtab @@ -2714,6 +4222,12 @@ mips_vxworks_final_write_processing (bfd *abfd) #undef elf_backend_finish_dynamic_symbol #define elf_backend_finish_dynamic_symbol \ _bfd_mips_vxworks_finish_dynamic_symbol +#undef bfd_elf32_bfd_reloc_type_lookup +#define bfd_elf32_bfd_reloc_type_lookup \ + mips_elf32_reloc_type_lookup_rela +#undef bfd_elf32_bfd_reloc_name_lookup +#define bfd_elf32_bfd_reloc_name_lookup \ + mips_elf32_reloc_name_lookup_rela #undef bfd_elf32_bfd_link_hash_table_create #define bfd_elf32_bfd_link_hash_table_create \ _bfd_mips_vxworks_link_hash_table_create diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index 5fbfbc6c2dd..80e7e08308a 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -10524,9 +10524,8 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, struct elf_link_hash_entry *h; bool rel_reloc; - rel_reloc = (NEWABI_P (input_bfd) - && mips_elf_rel_relocation_p (input_bfd, input_section, - relocs, rel)); + rel_reloc = mips_elf_rel_relocation_p (input_bfd, input_section, + relocs, rel); /* Find the relocation howto for this relocation. */ howto = MIPS_ELF_RTYPE_TO_HOWTO (input_bfd, r_type, !rel_reloc); diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index 5f1099da96c..1f85b81da45 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -492,7 +492,11 @@ static int mips_32bitmode = 0; #define HAVE_64BIT_OBJECTS (mips_abi == N64_ABI) /* True if relocations are stored in-place. */ +#ifdef TE_VXWORKS +#define HAVE_IN_PLACE_ADDENDS 0 +#else #define HAVE_IN_PLACE_ADDENDS (!HAVE_NEWABI) +#endif /* The ABI-derived address size. */ #define HAVE_64BIT_ADDRESSES \ diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp index 85820c27b5a..48b1fe7bf46 100644 --- a/gas/testsuite/gas/mips/mips.exp +++ b/gas/testsuite/gas/mips/mips.exp @@ -573,6 +573,12 @@ if { [istarget mips*-*-vxworks*] } { "MIPS invalid PIC option in VxWorks PIC" run_list_test "option-pic-vxworks-2" "-mvxworks-pic" \ "MIPS invalid switch to SVR4 PIC from VxWorks PIC" + + run_dump_test "vxworks-mips-hilo" + run_dump_test "vxworks-mips16-hilo" + run_dump_test "vxworks-mips16e2-hilo" + run_dump_test "vxworks-micromips-hilo" + run_dump_test "vxworks-pcrel-hilo" } elseif { [istarget mips*-*-*] } { set addr32 [expr [istarget mipstx39*-*-*] || [istarget mips-*-linux*] || [istarget mipsel-*-linux*] \ || [istarget mipsisa32*-*-linux*]] diff --git a/gas/testsuite/gas/mips/vxworks-micromips-hilo.d b/gas/testsuite/gas/mips/vxworks-micromips-hilo.d new file mode 100644 index 00000000000..b62134ba8cf --- /dev/null +++ b/gas/testsuite/gas/mips/vxworks-micromips-hilo.d @@ -0,0 +1,5 @@ +#objdump: -dr +#name: VxWorks microMIPS lui/addiu +#as: -mabi=32 -march=mips32r2 -mmicromips +#source: mips-hilo.s +#dump: micromips-hilo-n32.d diff --git a/gas/testsuite/gas/mips/vxworks-mips-hilo.d b/gas/testsuite/gas/mips/vxworks-mips-hilo.d new file mode 100644 index 00000000000..64f576ac7df --- /dev/null +++ b/gas/testsuite/gas/mips/vxworks-mips-hilo.d @@ -0,0 +1,5 @@ +#objdump: -dr +#name: VxWorks MIPS lui/addiu +#as: -mabi=32 -march=mips32r2 +#source: mips-hilo.s +#dump: mips-hilo-n32.d diff --git a/gas/testsuite/gas/mips/vxworks-mips16-hilo.d b/gas/testsuite/gas/mips/vxworks-mips16-hilo.d new file mode 100644 index 00000000000..6c5f7c19cfb --- /dev/null +++ b/gas/testsuite/gas/mips/vxworks-mips16-hilo.d @@ -0,0 +1,5 @@ +#objdump: -dr +#name: VxWorks MIPS16 lui/addi +#as: -mips16 -mabi=32 -march=mips32 +#source: mips16-hilo.s +#dump: mips16-hilo-n32.d diff --git a/gas/testsuite/gas/mips/vxworks-mips16e2-hilo.d b/gas/testsuite/gas/mips/vxworks-mips16e2-hilo.d new file mode 100644 index 00000000000..9fc371d18bf --- /dev/null +++ b/gas/testsuite/gas/mips/vxworks-mips16e2-hilo.d @@ -0,0 +1,5 @@ +#objdump: -dr +#name: VxWorks MIPS16e2 lui/addi +#as: -mips16 -mabi=32 -march=mips32r2 -mmips16e2 +#source: mips-hilo.s +#dump: mips16e2-hilo-n32.d diff --git a/gas/testsuite/gas/mips/vxworks-pcrel-hilo.d b/gas/testsuite/gas/mips/vxworks-pcrel-hilo.d new file mode 100644 index 00000000000..368e3b7282d --- /dev/null +++ b/gas/testsuite/gas/mips/vxworks-pcrel-hilo.d @@ -0,0 +1,5 @@ +#readelf: -r +#name: VxWorks MIPSr6 PCHI16/PCLO16 relocations +#as: -mabi=32 -march=mips32r6 -mno-pdr +#source: pcrel-hilo.s +#dump: pcrel-hilo-n32.d diff --git a/ld/testsuite/ld-mips-elf/mips-elf.exp b/ld/testsuite/ld-mips-elf/mips-elf.exp index da6bed9b4ce..6350b2432f9 100644 --- a/ld/testsuite/ld-mips-elf/mips-elf.exp +++ b/ld/testsuite/ld-mips-elf/mips-elf.exp @@ -47,10 +47,20 @@ if {[istarget "mips*-*-vxworks"]} { run_dump_test "vxworks-forced-local-1" run_dump_test "mips-hilo" + run_dump_test "mips-hilo-srec" \ + [list [list objdump [expr { [istarget *el-*-*] ? "-EL" : "-EB" }]]] run_dump_test "mips16-hilo" + run_dump_test "mips16-hilo-srec" \ + [list [list objdump [expr { [istarget *el-*-*] ? "-EL" : "-EB" }]]] run_dump_test "mips16e2-hilo" + run_dump_test "mips16e2-hilo-srec" \ + [list [list objdump [expr { [istarget *el-*-*] ? "-EL" : "-EB" }]]] run_dump_test "micromips-hilo" + run_dump_test "micromips-hilo-srec" \ + [list [list objdump [expr { [istarget *el-*-*] ? "-EL" : "-EB" }]]] run_dump_test "pcrel-hilo" + run_dump_test "pcrel-hilo-srec" \ + [list [list objdump [expr { [istarget *el-*-*] ? "-EL" : "-EB" }]]] return }