[to-be-committed][PATCH 2/2] MIPS: Add o32 RELA relocations for VxWorks targets
Maciej W. Rozycki
macro@orcam.me.uk
Mon Oct 13 15:57:17 GMT 2025
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 <foo>:
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.
---
bfd/elf32-mips.c | 1604 +++++++++++++++++++++++-
bfd/elfxx-mips.c | 5
gas/config/tc-mips.c | 4
gas/testsuite/gas/mips/mips.exp | 6
gas/testsuite/gas/mips/vxworks-micromips-hilo.d | 5
gas/testsuite/gas/mips/vxworks-mips-hilo.d | 5
gas/testsuite/gas/mips/vxworks-mips16-hilo.d | 5
gas/testsuite/gas/mips/vxworks-mips16e2-hilo.d | 5
gas/testsuite/gas/mips/vxworks-pcrel-hilo.d | 5
ld/testsuite/ld-mips-elf/mips-elf.exp | 10
10 files changed, 1606 insertions(+), 48 deletions(-)
binutils-mips-vxworks-rela.diff
Index: binutils-gdb/bfd/elf32-mips.c
===================================================================
--- binutils-gdb.orig/bfd/elf32-mips.c
+++ binutils-gdb/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_gp
(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,6 +810,715 @@ static reloc_howto_type elf_mips_howto_t
true), /* pcrel_offset */
};
+/* 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 */
+ 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 =
@@ -1044,6 +1752,222 @@ static reloc_howto_type elf_mips16_howto
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),
@@ -1546,6 +2470,508 @@ static reloc_howto_type elf_micromips_ho
true), /* pcrel_offset */
};
+static reloc_howto_type elf_micromips_howto_table_rela[] =
+{
+ 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 */
+ false, /* partial_inplace */
+ 0, /* 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_generic_reloc, /* special_function */
+ "R_MICROMIPS_HI16", /* name */
+ false, /* partial_inplace */
+ 0, /* 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_generic_reloc, /* special_function */
+ "R_MICROMIPS_LO16", /* name */
+ false, /* partial_inplace */
+ 0, /* 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 */
+ false, /* partial_inplace */
+ 0, /* 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 */
+ false, /* partial_inplace */
+ 0, /* 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 */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_GOT16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 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 */
+ false, /* partial_inplace */
+ 0, /* 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 */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x000003ff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ HOWTO (R_MICROMIPS_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_MICROMIPS_PC16_S1", /* name */
+ false, /* partial_inplace */
+ 0, /* 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_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_CALL16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ 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 */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_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_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 */
+ false, /* partial_inplace */
+ 0, /* 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 */
+ false, /* partial_inplace */
+ 0, /* 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_generic_reloc, /* special_function */
+ "R_MICROMIPS_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_MICROMIPS_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_MICROMIPS_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_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 */
+ false, /* partial_inplace */
+ 0, /* 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 */
+ false, /* partial_inplace */
+ 0, /* 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 */
+ false, /* partial_inplace */
+ 0, /* 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_generic_reloc, /* special_function */
+ "R_MICROMIPS_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_MICROMIPS_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_MICROMIPS_CALL_LO16",/* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 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 */
+ false, /* partial_inplace */
+ 0, /* 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 */
+ 0, /* 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 */
+ false, /* partial_inplace */
+ 0, /* 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 */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_TLS_GD", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* TLS local dynamic variable reference. */
+ HOWTO (R_MICROMIPS_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_MICROMIPS_TLS_LDM", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* TLS local dynamic offset. */
+ HOWTO (R_MICROMIPS_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_MICROMIPS_TLS_DTPREL_HI16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* TLS local dynamic offset. */
+ HOWTO (R_MICROMIPS_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_MICROMIPS_TLS_DTPREL_LO16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* TLS thread pointer offset. */
+ HOWTO (R_MICROMIPS_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_MICROMIPS_TLS_GOTTPREL", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ EMPTY_HOWTO (167),
+ EMPTY_HOWTO (168),
+
+ /* TLS thread pointer offset. */
+ HOWTO (R_MICROMIPS_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_MICROMIPS_TLS_TPREL_HI16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* TLS thread pointer offset. */
+ HOWTO (R_MICROMIPS_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_MICROMIPS_TLS_TPREL_LO16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ 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 */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000007f, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_MICROMIPS_PC23_S2, /* type */
+ 2, /* rightshift */
+ 4, /* size */
+ 23, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_PC23_S2", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x007fffff, /* dst_mask */
+ true), /* pcrel_offset */
+};
+
/* 16 bit offset for pc-relative branches. */
static reloc_howto_type elf_mips_gnu_rel16_s2 =
HOWTO (R_MIPS_GNU_REL16_S2, /* type */
@@ -1562,6 +2988,22 @@ static reloc_howto_type elf_mips_gnu_rel
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 microm
/* 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 *ab
}
}
+/* Given a BFD reloc type, return a howto structure; REL wrapper. */
+
static reloc_howto_type *
-bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
- const char *r_name)
+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 *
+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 *ab
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_rtype_to_howto (bfd *abfd,
- unsigned int r_type,
- bool rela_p ATTRIBUTE_UNUSED)
+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)
{
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, arele
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 mip
#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
#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
Index: binutils-gdb/bfd/elfxx-mips.c
===================================================================
--- binutils-gdb.orig/bfd/elfxx-mips.c
+++ binutils-gdb/bfd/elfxx-mips.c
@@ -10527,9 +10527,8 @@ _bfd_mips_elf_relocate_section (bfd *out
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);
Index: binutils-gdb/gas/config/tc-mips.c
===================================================================
--- binutils-gdb.orig/gas/config/tc-mips.c
+++ binutils-gdb/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 \
Index: binutils-gdb/gas/testsuite/gas/mips/mips.exp
===================================================================
--- binutils-gdb.orig/gas/testsuite/gas/mips/mips.exp
+++ binutils-gdb/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*]]
Index: binutils-gdb/gas/testsuite/gas/mips/vxworks-micromips-hilo.d
===================================================================
--- /dev/null
+++ binutils-gdb/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
Index: binutils-gdb/gas/testsuite/gas/mips/vxworks-mips-hilo.d
===================================================================
--- /dev/null
+++ binutils-gdb/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
Index: binutils-gdb/gas/testsuite/gas/mips/vxworks-mips16-hilo.d
===================================================================
--- /dev/null
+++ binutils-gdb/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
Index: binutils-gdb/gas/testsuite/gas/mips/vxworks-mips16e2-hilo.d
===================================================================
--- /dev/null
+++ binutils-gdb/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
Index: binutils-gdb/gas/testsuite/gas/mips/vxworks-pcrel-hilo.d
===================================================================
--- /dev/null
+++ binutils-gdb/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
Index: binutils-gdb/ld/testsuite/ld-mips-elf/mips-elf.exp
===================================================================
--- binutils-gdb.orig/ld/testsuite/ld-mips-elf/mips-elf.exp
+++ binutils-gdb/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
}
More information about the Binutils
mailing list