aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2018-10-05 11:41:40 +0900
committerStafford Horne <shorne@gmail.com>2018-10-05 11:41:40 +0900
commit1c4f3780f7d939402cfe555007ebff45c8e38951 (patch)
treee4707fb11ce08c16f01e8dbee9504e2b29b43ddd /bfd
parent4677effd9e320d9f09337ef17bf0dc0377a9e8ce (diff)
downloadgdb-1c4f3780f7d939402cfe555007ebff45c8e38951.zip
gdb-1c4f3780f7d939402cfe555007ebff45c8e38951.tar.gz
gdb-1c4f3780f7d939402cfe555007ebff45c8e38951.tar.bz2
or1k: Add relocations for high-signed and low-stores
This patch adds the following target relocations: - BFD_RELOC_HI16_S High 16-bit relocation, for used with signed asm: ha() lower. - BFD_RELOC_HI16_S_GOTOFF High 16-bit GOT offset relocation for local asm: gotoffha() symbols, for use with signed lower. - BFD_RELOC_OR1K_TLS_IE_AHI16 High 16-bit TLS relocation with initial asm: gottpoffha() executable calculation, for use with signed lower. - BFD_RELOC_OR1K_TLS_LE_AHI16 High 16-bit TLS relocation for local executable asm: tpoffha() variables, for use with signed lower. - BFD_RELOC_OR1K_SLO16 Split lower 16-bit relocation, used with asm: lo() OpenRISC store instructions. - BFD_RELOC_OR1K_GOTOFF_SLO16 Split lower 16-bit GOT offset relocation for asm: gotofflo() local symbols, used with OpenRISC store instructions. - BFD_RELOC_OR1K_TLS_LE_SLO16 Split lower 16-bit relocation for TLS local asm: tpofflo() executable variables, used with OpenRISC store instructions. bfd/ChangeLog: yyyy-mm-dd Richard Henderson <rth@twiddle.net> Stafford Horne <shorne@gmail.com> * bfd-in2.h: Regenerated. * elf32-or1k.c (N_ONES): New macro. (or1k_elf_howto_table): Fix R_OR1K_PLT26 to complain on overflow. Add definitions for R_OR1K_TLS_TPOFF, R_OR1K_TLS_DTPOFF, R_OR1K_TLS_DTPMOD, R_OR1K_AHI16, R_OR1K_GOTOFF_AHI16, R_OR1K_TLS_IE_AHI16, R_OR1K_TLS_LE_AHI16, R_OR1K_SLO16, R_OR1K_GOTOFF_SLO16, R_OR1K_TLS_LE_SLO16. (or1k_reloc_map): Add entries for BFD_RELOC_HI16_S, BFD_RELOC_LO16_GOTOFF, BFD_RELOC_HI16_GOTOFF, BFD_RELOC_HI16_S_GOTOFF, BFD_RELOC_OR1K_TLS_IE_AHI16, BFD_RELOC_OR1K_TLS_LE_AHI16, BFD_RELOC_OR1K_SLO16, BFD_RELOC_OR1K_GOTOFF_SLO16, BFD_RELOC_OR1K_TLS_LE_SLO16. (or1k_reloc_type_lookup): Change search loop to start ad index 0 and also check results before returning. (or1k_reloc_name_lookup): Simplify loop to use R_OR1K_max as index limit. (or1k_final_link_relocate): New function. (or1k_elf_relocate_section): Add support for new AHI and SLO relocations. Use or1k_final_link_relocate instead of generic _bfd_final_link_relocate. (or1k_elf_check_relocs): Add support for new AHI and SLO relocations. * reloc.c: Add new enums for BFD_RELOC_OR1K_SLO16, BFD_RELOC_OR1K_GOTOFF_SLO16, BFD_RELOC_OR1K_TLS_IE_AHI16, BFD_RELOC_OR1K_TLS_IE_AHI16, BFD_RELOC_OR1K_TLS_LE_AHI16, BFD_RELOC_OR1K_TLS_LE_SLO16. Remove unused BFD_RELOC_OR1K_GOTOFF_HI16 and BFD_RELOC_OR1K_GOTOFF_LO16. * libbfd.h: Regenerated. cpu/ChangeLog: yyyy-mm-dd Richard Henderson <rth@twiddle.net> * or1k.opc: Add RTYPE_ enum. (INVALID_STORE_RELOC): New string. (or1k_imm16_relocs): New array array. (parse_reloc): New static function that just does the parsing. (parse_imm16): New static function for generic parsing. (parse_simm16): Change to just call parse_imm16. (parse_simm16_split): New function. (parse_uimm16): Change to call parse_imm16. (parse_uimm16_split): New function. * or1korbis.cpu (simm16-split): Change to use new simm16_split. (uimm16-split): Change to use new uimm16_split. gas/ChangeLog: yyyy-mm-dd Richard Henderson <rth@twiddle.net> * testsuite/gas/or1k/allinsn.d (l_ha): Add result for ha() relocation. * testsuite/gas/or1k/allinsn.s (l_ha): Add test for ha() relocations. * testsuite/gas/or1k/allinsn.exp: Renamed to or1k.exp. * testsuite/gas/or1k/or1k.exp: Add reloc-2 list test. * testsuite/gas/or1k/reloc-1.d: New file. * testsuite/gas/or1k/reloc-1.s: New file. * testsuite/gas/or1k/reloc-2.l: New file. * testsuite/gas/or1k/reloc-2.s: New file. include/ChangeLog: yyyy-mm-dd Richard Henderson <rth@twiddle.net> * elf/or1k.h (elf_or1k_reloc_type): Add R_OR1K_AHI16, R_OR1K_GOTOFF_AHI16, R_OR1K_TLS_IE_AHI16, R_OR1K_TLS_LE_AHI16, R_OR1K_SLO16, R_OR1K_GOTOFF_SLO16, R_OR1K_TLS_LE_SLO16. ld/ChangeLog: yyyy-mm-dd Richard Henderson <rth@twiddle.net> * testsuite/ld-or1k/offsets1.d: New file. * testsuite/ld-or1k/offsets1.s: New file. * testsuite/ld-or1k/or1k.exp: New file. opcodes/ChangeLog: yyyy-mm-dd Richard Henderson <rth@twiddle.net> * or1k-asm.c: Regenerate.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog31
-rw-r--r--bfd/bfd-in2.h7
-rw-r--r--bfd/elf32-or1k.c335
-rw-r--r--bfd/libbfd.h7
-rw-r--r--bfd/reloc.c12
5 files changed, 351 insertions, 41 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index e46604b..e0b26df 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,34 @@
+2018-10-05 Richard Henderson <rth@twiddle.net>
+ Stafford Horne <shorne@gmail.com>
+
+ * bfd-in2.h: Regenerated.
+ * elf32-or1k.c (N_ONES): New macro.
+ (or1k_elf_howto_table): Fix R_OR1K_PLT26 to complain on overflow.
+ Add definitions for R_OR1K_TLS_TPOFF, R_OR1K_TLS_DTPOFF,
+ R_OR1K_TLS_DTPMOD, R_OR1K_AHI16, R_OR1K_GOTOFF_AHI16,
+ R_OR1K_TLS_IE_AHI16, R_OR1K_TLS_LE_AHI16, R_OR1K_SLO16,
+ R_OR1K_GOTOFF_SLO16, R_OR1K_TLS_LE_SLO16.
+ (or1k_reloc_map): Add entries for BFD_RELOC_HI16_S,
+ BFD_RELOC_LO16_GOTOFF, BFD_RELOC_HI16_GOTOFF, BFD_RELOC_HI16_S_GOTOFF,
+ BFD_RELOC_OR1K_TLS_IE_AHI16, BFD_RELOC_OR1K_TLS_LE_AHI16,
+ BFD_RELOC_OR1K_SLO16, BFD_RELOC_OR1K_GOTOFF_SLO16,
+ BFD_RELOC_OR1K_TLS_LE_SLO16.
+ (or1k_reloc_type_lookup): Change search loop to start ad index 0 and
+ also check results before returning.
+ (or1k_reloc_name_lookup): Simplify loop to use R_OR1K_max as index
+ limit.
+ (or1k_final_link_relocate): New function.
+ (or1k_elf_relocate_section): Add support for new AHI and SLO
+ relocations. Use or1k_final_link_relocate instead of generic
+ _bfd_final_link_relocate.
+ (or1k_elf_check_relocs): Add support for new AHI and SLO relocations.
+ * reloc.c: Add new enums for BFD_RELOC_OR1K_SLO16,
+ BFD_RELOC_OR1K_GOTOFF_SLO16, BFD_RELOC_OR1K_TLS_IE_AHI16,
+ BFD_RELOC_OR1K_TLS_IE_AHI16, BFD_RELOC_OR1K_TLS_LE_AHI16,
+ BFD_RELOC_OR1K_TLS_LE_SLO16. Remove unused BFD_RELOC_OR1K_GOTOFF_HI16
+ and BFD_RELOC_OR1K_GOTOFF_LO16.
+ * libbfd.h: Regenerated.
+
2018-10-04 Jim Wilson <jimw@sifive.com>
* elfnn-riscv.c (riscv_elf_size_dynamic_sections): In dynobj->sections
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 5981922..cc112f1 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -5472,12 +5472,12 @@ then it may be truncated to 8 bits. */
/* OpenRISC 1000 Relocations. */
BFD_RELOC_OR1K_REL_26,
+ BFD_RELOC_OR1K_SLO16,
BFD_RELOC_OR1K_GOTPC_HI16,
BFD_RELOC_OR1K_GOTPC_LO16,
BFD_RELOC_OR1K_GOT16,
BFD_RELOC_OR1K_PLT26,
- BFD_RELOC_OR1K_GOTOFF_HI16,
- BFD_RELOC_OR1K_GOTOFF_LO16,
+ BFD_RELOC_OR1K_GOTOFF_SLO16,
BFD_RELOC_OR1K_COPY,
BFD_RELOC_OR1K_GLOB_DAT,
BFD_RELOC_OR1K_JMP_SLOT,
@@ -5489,9 +5489,12 @@ then it may be truncated to 8 bits. */
BFD_RELOC_OR1K_TLS_LDO_HI16,
BFD_RELOC_OR1K_TLS_LDO_LO16,
BFD_RELOC_OR1K_TLS_IE_HI16,
+ BFD_RELOC_OR1K_TLS_IE_AHI16,
BFD_RELOC_OR1K_TLS_IE_LO16,
BFD_RELOC_OR1K_TLS_LE_HI16,
+ BFD_RELOC_OR1K_TLS_LE_AHI16,
BFD_RELOC_OR1K_TLS_LE_LO16,
+ BFD_RELOC_OR1K_TLS_LE_SLO16,
BFD_RELOC_OR1K_TLS_TPOFF,
BFD_RELOC_OR1K_TLS_DTPOFF,
BFD_RELOC_OR1K_TLS_DTPMOD,
diff --git a/bfd/elf32-or1k.c b/bfd/elf32-or1k.c
index 91b780f..d888c9f 100644
--- a/bfd/elf32-or1k.c
+++ b/bfd/elf32-or1k.c
@@ -27,6 +27,8 @@
#include "elf/or1k.h"
#include "libiberty.h"
+#define N_ONES(X) (((bfd_vma)2 << (X)) - 1)
+
#define PLT_ENTRY_SIZE 20
#define PLT0_ENTRY_WORD0 0x19800000 /* l.movhi r12, 0 <- hi(.got+4) */
@@ -278,7 +280,7 @@ static reloc_howto_type or1k_elf_howto_table[] =
26, /* Bitsize. */
TRUE, /* PC_relative. */
0, /* Bitpos. */
- complain_overflow_dont, /* Complain on overflow. */
+ complain_overflow_signed, /* Complain on overflow. */
bfd_elf_generic_reloc,/* Special Function. */
"R_OR1K_PLT26", /* Name. */
FALSE, /* Partial Inplace. */
@@ -510,6 +512,145 @@ static reloc_howto_type or1k_elf_howto_table[] =
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
+ HOWTO (R_OR1K_TLS_TPOFF, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_OR1K_TLS_TPOFF", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_TLS_DTPOFF, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_OR1K_TLS_DTPOFF", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_TLS_DTPMOD, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_OR1K_TLS_DTPMOD", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_AHI16, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_OR1K_AHI16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_GOTOFF_AHI16, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_OR1K_GOTOFF_AHI16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_TLS_IE_AHI16, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_OR1K_TLS_IE_AHI16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_TLS_LE_AHI16, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_OR1K_TLS_LE_AHI16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_SLO16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_OR1K_SLO16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_GOTOFF_SLO16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_OR1K_GOTOFF_SLO16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_TLS_LE_SLO16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_OR1K_TLS_LE_SLO16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
};
/* Map BFD reloc types to Or1k ELF reloc types. */
@@ -528,18 +669,20 @@ static const struct or1k_reloc_map or1k_reloc_map[] =
{ BFD_RELOC_8, R_OR1K_8 },
{ BFD_RELOC_LO16, R_OR1K_LO_16_IN_INSN },
{ BFD_RELOC_HI16, R_OR1K_HI_16_IN_INSN },
+ { BFD_RELOC_HI16_S, R_OR1K_AHI16 },
{ BFD_RELOC_OR1K_REL_26, R_OR1K_INSN_REL_26 },
{ BFD_RELOC_VTABLE_ENTRY, R_OR1K_GNU_VTENTRY },
{ BFD_RELOC_VTABLE_INHERIT, R_OR1K_GNU_VTINHERIT },
{ BFD_RELOC_32_PCREL, R_OR1K_32_PCREL },
{ BFD_RELOC_16_PCREL, R_OR1K_16_PCREL },
{ BFD_RELOC_8_PCREL, R_OR1K_8_PCREL },
+ { BFD_RELOC_LO16_GOTOFF, R_OR1K_GOTOFF_LO16 },
+ { BFD_RELOC_HI16_GOTOFF, R_OR1K_GOTOFF_HI16 },
+ { BFD_RELOC_HI16_S_GOTOFF, R_OR1K_GOTOFF_AHI16 },
{ BFD_RELOC_OR1K_GOTPC_HI16, R_OR1K_GOTPC_HI16 },
{ BFD_RELOC_OR1K_GOTPC_LO16, R_OR1K_GOTPC_LO16 },
{ BFD_RELOC_OR1K_GOT16, R_OR1K_GOT16 },
{ BFD_RELOC_OR1K_PLT26, R_OR1K_PLT26 },
- { BFD_RELOC_OR1K_GOTOFF_HI16, R_OR1K_GOTOFF_HI16 },
- { BFD_RELOC_OR1K_GOTOFF_LO16, R_OR1K_GOTOFF_LO16 },
{ BFD_RELOC_OR1K_GLOB_DAT, R_OR1K_GLOB_DAT },
{ BFD_RELOC_OR1K_COPY, R_OR1K_COPY },
{ BFD_RELOC_OR1K_JMP_SLOT, R_OR1K_JMP_SLOT },
@@ -552,8 +695,13 @@ static const struct or1k_reloc_map or1k_reloc_map[] =
{ BFD_RELOC_OR1K_TLS_LDO_LO16, R_OR1K_TLS_LDO_LO16 },
{ BFD_RELOC_OR1K_TLS_IE_HI16, R_OR1K_TLS_IE_HI16 },
{ BFD_RELOC_OR1K_TLS_IE_LO16, R_OR1K_TLS_IE_LO16 },
+ { BFD_RELOC_OR1K_TLS_IE_AHI16, R_OR1K_TLS_IE_AHI16 },
{ BFD_RELOC_OR1K_TLS_LE_HI16, R_OR1K_TLS_LE_HI16 },
{ BFD_RELOC_OR1K_TLS_LE_LO16, R_OR1K_TLS_LE_LO16 },
+ { BFD_RELOC_OR1K_TLS_LE_AHI16, R_OR1K_TLS_LE_AHI16 },
+ { BFD_RELOC_OR1K_SLO16, R_OR1K_SLO16 },
+ { BFD_RELOC_OR1K_GOTOFF_SLO16, R_OR1K_GOTOFF_SLO16 },
+ { BFD_RELOC_OR1K_TLS_LE_SLO16, R_OR1K_TLS_LE_SLO16 },
};
#define TLS_UNKNOWN 0
@@ -671,13 +819,19 @@ or1k_elf_link_hash_table_create (bfd *abfd)
static reloc_howto_type *
or1k_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
- bfd_reloc_code_real_type code)
+ bfd_reloc_code_real_type bcode)
{
unsigned int i;
- for (i = ARRAY_SIZE (or1k_reloc_map); i--;)
- if (or1k_reloc_map[i].bfd_reloc_val == code)
- return & or1k_elf_howto_table[or1k_reloc_map[i].or1k_reloc_val];
+ for (i = 0; i < ARRAY_SIZE (or1k_reloc_map); i++)
+ if (or1k_reloc_map[i].bfd_reloc_val == bcode)
+ {
+ unsigned int ocode = or1k_reloc_map[i].or1k_reloc_val;
+ if (ocode < (unsigned int) R_OR1K_max)
+ return &or1k_elf_howto_table[ocode];
+ else
+ break;
+ }
return NULL;
}
@@ -688,10 +842,7 @@ or1k_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
{
unsigned int i;
- for (i = 0;
- i < (sizeof (or1k_elf_howto_table)
- / sizeof (or1k_elf_howto_table[0]));
- i++)
+ for (i = 0; i < R_OR1K_max; i++)
if (or1k_elf_howto_table[i].name != NULL
&& strcasecmp (or1k_elf_howto_table[i].name, r_name) == 0)
return &or1k_elf_howto_table[i];
@@ -736,6 +887,109 @@ tpoff (struct bfd_link_info *info, bfd_vma address)
return (address - elf_hash_table (info)->tls_sec->vma);
}
+/* Like _bfd_final_link_relocate, but handles non-contiguous fields. */
+
+static bfd_reloc_status_type
+or1k_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd,
+ asection *input_section, bfd_byte *contents,
+ bfd_vma offset, bfd_vma value)
+{
+ bfd_reloc_status_type status = bfd_reloc_ok;
+ int size = bfd_get_reloc_size (howto);
+ bfd_vma x;
+
+ /* Sanity check the address. */
+ if (offset + size > bfd_get_section_limit_octets (input_bfd, input_section))
+ return bfd_reloc_outofrange;
+
+ if (howto->pc_relative)
+ {
+ value -= (input_section->output_section->vma
+ + input_section->output_offset);
+ if (howto->pcrel_offset)
+ value -= offset;
+ }
+
+ switch (howto->type)
+ {
+ case R_OR1K_AHI16:
+ case R_OR1K_GOTOFF_AHI16:
+ case R_OR1K_TLS_IE_AHI16:
+ case R_OR1K_TLS_LE_AHI16:
+ /* Adjust the operand to match with a signed LO16. */
+ value += 0x8000;
+ break;
+
+ case R_OR1K_INSN_REL_26:
+ /* Diagnose mis-aligned branch targets. */
+ if (value & 3)
+ status = bfd_reloc_dangerous;
+ break;
+ }
+
+ status = bfd_check_overflow (howto->complain_on_overflow,
+ howto->bitsize,
+ howto->rightshift,
+ bfd_arch_bits_per_address (input_bfd),
+ value);
+ value >>= howto->rightshift;
+
+ /* If we're overwriting the entire destination,
+ then no need to read the current contents. */
+ if (size == 0 || howto->dst_mask == N_ONES (size))
+ x = 0;
+ else
+ {
+ BFD_ASSERT (size == 4);
+ x = bfd_get_32 (input_bfd, contents + offset);
+ }
+
+ switch (howto->type)
+ {
+ case R_OR1K_SLO16:
+ case R_OR1K_GOTOFF_SLO16:
+ case R_OR1K_TLS_LE_SLO16:
+ /* The split imm16 field used for stores. */
+ x = (x & ~0x3e007ff) | ((value & 0xf800) << 10) | (value & 0x7ff);
+ break;
+
+ default:
+ {
+ bfd_vma fieldmask = howto->dst_mask;
+ value <<= howto->bitpos;
+ x = (x & ~fieldmask) | (value & fieldmask);
+ }
+ break;
+ }
+
+ /* Put the relocated value back in the object file. */
+ switch (size)
+ {
+ case 0:
+ break;
+ case 1:
+ bfd_put_8 (input_bfd, x, contents + offset);
+ break;
+ case 2:
+ bfd_put_16 (input_bfd, x, contents + offset);
+ break;
+ case 4:
+ bfd_put_32 (input_bfd, x, contents + offset);
+ break;
+#ifdef BFD64
+ case 8:
+ bfd_put_64 (input_bfd, x, contents + offset);
+ break;
+#endif
+ default:
+ _bfd_error_handler
+ (_("%pB: Cannot handle relocation value size of %d"),
+ input_bfd, size);
+ abort ();
+ }
+ return status;
+}
+
/* Relocate an Or1k ELF section.
The RELOCATE_SECTION function is called by the new ELF backend linker
@@ -972,6 +1226,8 @@ or1k_elf_relocate_section (bfd *output_bfd,
case R_OR1K_GOTOFF_LO16:
case R_OR1K_GOTOFF_HI16:
+ case R_OR1K_GOTOFF_AHI16:
+ case R_OR1K_GOTOFF_SLO16:
/* Relocation is offset from GOT. */
BFD_ASSERT (sgot != NULL);
relocation
@@ -983,6 +1239,8 @@ or1k_elf_relocate_section (bfd *output_bfd,
case R_OR1K_INSN_REL_26:
case R_OR1K_HI_16_IN_INSN:
case R_OR1K_LO_16_IN_INSN:
+ case R_OR1K_AHI16:
+ case R_OR1K_SLO16:
case R_OR1K_32:
/* R_OR1K_16? */
{
@@ -1080,11 +1338,11 @@ or1k_elf_relocate_section (bfd *output_bfd,
bfd_set_error (bfd_error_bad_value);
return FALSE;
-
case R_OR1K_TLS_GD_HI16:
case R_OR1K_TLS_GD_LO16:
case R_OR1K_TLS_IE_HI16:
case R_OR1K_TLS_IE_LO16:
+ case R_OR1K_TLS_IE_AHI16:
{
bfd_vma gotoff;
Elf_Internal_Rela rela;
@@ -1196,9 +1454,11 @@ or1k_elf_relocate_section (bfd *output_bfd,
relocation = sgot->output_offset + gotoff;
break;
}
+
case R_OR1K_TLS_LE_HI16:
case R_OR1K_TLS_LE_LO16:
-
+ case R_OR1K_TLS_LE_AHI16:
+ case R_OR1K_TLS_LE_SLO16:
/* Relocation is offset from TP. */
relocation = tpoff (info, relocation);
break;
@@ -1218,8 +1478,9 @@ or1k_elf_relocate_section (bfd *output_bfd,
default:
break;
}
- r = _bfd_final_link_relocate (howto, input_bfd, input_section, contents,
- rel->r_offset, relocation, rel->r_addend);
+
+ r = or1k_final_link_relocate (howto, input_bfd, input_section, contents,
+ rel->r_offset, relocation + rel->r_addend);
if (r != bfd_reloc_ok)
{
@@ -1329,6 +1590,7 @@ or1k_elf_check_relocs (bfd *abfd,
struct elf_link_hash_entry *h;
unsigned long r_symndx;
unsigned char tls_type;
+ int r_type;
r_symndx = ELF32_R_SYM (rel->r_info);
if (r_symndx < symtab_hdr->sh_info)
@@ -1341,7 +1603,8 @@ or1k_elf_check_relocs (bfd *abfd,
h = (struct elf_link_hash_entry *) h->root.u.i.link;
}
- switch (ELF32_R_TYPE (rel->r_info))
+ r_type = ELF32_R_TYPE (rel->r_info);
+ switch (r_type)
{
case R_OR1K_TLS_GD_HI16:
case R_OR1K_TLS_GD_LO16:
@@ -1355,10 +1618,13 @@ or1k_elf_check_relocs (bfd *abfd,
break;
case R_OR1K_TLS_IE_HI16:
case R_OR1K_TLS_IE_LO16:
+ case R_OR1K_TLS_IE_AHI16:
tls_type = TLS_IE;
break;
case R_OR1K_TLS_LE_HI16:
case R_OR1K_TLS_LE_LO16:
+ case R_OR1K_TLS_LE_AHI16:
+ case R_OR1K_TLS_LE_SLO16:
tls_type = TLS_LE;
break;
default:
@@ -1387,7 +1653,7 @@ or1k_elf_check_relocs (bfd *abfd,
local_tls_type[r_symndx] = tls_type;
}
- switch (ELF32_R_TYPE (rel->r_info))
+ switch (r_type)
{
/* This relocation describes the C++ object vtable hierarchy.
Reconstruct it for later use during GC. */
@@ -1415,23 +1681,11 @@ or1k_elf_check_relocs (bfd *abfd,
break;
case R_OR1K_GOT16:
- case R_OR1K_GOTOFF_HI16:
- case R_OR1K_GOTOFF_LO16:
case R_OR1K_TLS_GD_HI16:
case R_OR1K_TLS_GD_LO16:
case R_OR1K_TLS_IE_HI16:
case R_OR1K_TLS_IE_LO16:
- if (htab->root.sgot == NULL)
- {
- if (dynobj == NULL)
- htab->root.dynobj = dynobj = abfd;
- if (!_bfd_elf_create_got_section (dynobj, info))
- return FALSE;
- }
-
- if (ELF32_R_TYPE (rel->r_info) != R_OR1K_GOTOFF_HI16 &&
- ELF32_R_TYPE (rel->r_info) != R_OR1K_GOTOFF_LO16)
- {
+ case R_OR1K_TLS_IE_AHI16:
if (h != NULL)
h->got.refcount += 1;
else
@@ -1453,14 +1707,27 @@ or1k_elf_check_relocs (bfd *abfd,
}
local_got_refcounts[r_symndx] += 1;
}
+ /* FALLTHRU */
+
+ case R_OR1K_GOTOFF_HI16:
+ case R_OR1K_GOTOFF_LO16:
+ case R_OR1K_GOTOFF_AHI16:
+ case R_OR1K_GOTOFF_SLO16:
+ if (htab->root.sgot == NULL)
+ {
+ if (dynobj == NULL)
+ htab->root.dynobj = dynobj = abfd;
+ if (!_bfd_elf_create_got_section (dynobj, info))
+ return FALSE;
}
break;
case R_OR1K_INSN_REL_26:
case R_OR1K_HI_16_IN_INSN:
case R_OR1K_LO_16_IN_INSN:
+ case R_OR1K_AHI16:
+ case R_OR1K_SLO16:
case R_OR1K_32:
- /* R_OR1K_16? */
{
if (h != NULL && !bfd_link_pic (info))
{
@@ -1469,7 +1736,7 @@ or1k_elf_check_relocs (bfd *abfd,
/* We may also need a .plt entry. */
h->plt.refcount += 1;
- if (ELF32_R_TYPE (rel->r_info) != R_OR1K_INSN_REL_26)
+ if (r_type != R_OR1K_INSN_REL_26)
h->pointer_equality_needed = 1;
}
@@ -1497,7 +1764,7 @@ or1k_elf_check_relocs (bfd *abfd,
if ((bfd_link_pic (info)
&& (sec->flags & SEC_ALLOC) != 0
- && (ELF32_R_TYPE (rel->r_info) != R_OR1K_INSN_REL_26
+ && (r_type != R_OR1K_INSN_REL_26
|| (h != NULL
&& (!SYMBOLIC_BIND (info, h)
|| h->root.type == bfd_link_hash_defweak
@@ -1593,7 +1860,7 @@ or1k_elf_check_relocs (bfd *abfd,
}
p->count += 1;
- if (ELF32_R_TYPE (rel->r_info) == R_OR1K_INSN_REL_26)
+ if (r_type == R_OR1K_INSN_REL_26)
p->pc_count += 1;
}
}
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index d37716c..6cb0cae 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -2664,12 +2664,12 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_CRIS_DTPMOD",
"BFD_RELOC_CRIS_32_IE",
"BFD_RELOC_OR1K_REL_26",
+ "BFD_RELOC_OR1K_SLO16",
"BFD_RELOC_OR1K_GOTPC_HI16",
"BFD_RELOC_OR1K_GOTPC_LO16",
"BFD_RELOC_OR1K_GOT16",
"BFD_RELOC_OR1K_PLT26",
- "BFD_RELOC_OR1K_GOTOFF_HI16",
- "BFD_RELOC_OR1K_GOTOFF_LO16",
+ "BFD_RELOC_OR1K_GOTOFF_SLO16",
"BFD_RELOC_OR1K_COPY",
"BFD_RELOC_OR1K_GLOB_DAT",
"BFD_RELOC_OR1K_JMP_SLOT",
@@ -2681,9 +2681,12 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_OR1K_TLS_LDO_HI16",
"BFD_RELOC_OR1K_TLS_LDO_LO16",
"BFD_RELOC_OR1K_TLS_IE_HI16",
+ "BFD_RELOC_OR1K_TLS_IE_AHI16",
"BFD_RELOC_OR1K_TLS_IE_LO16",
"BFD_RELOC_OR1K_TLS_LE_HI16",
+ "BFD_RELOC_OR1K_TLS_LE_AHI16",
"BFD_RELOC_OR1K_TLS_LE_LO16",
+ "BFD_RELOC_OR1K_TLS_LE_SLO16",
"BFD_RELOC_OR1K_TLS_TPOFF",
"BFD_RELOC_OR1K_TLS_DTPOFF",
"BFD_RELOC_OR1K_TLS_DTPMOD",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 07be1a4..353a240 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -6146,6 +6146,8 @@ ENUMDOC
ENUM
BFD_RELOC_OR1K_REL_26
ENUMX
+ BFD_RELOC_OR1K_SLO16
+ENUMX
BFD_RELOC_OR1K_GOTPC_HI16
ENUMX
BFD_RELOC_OR1K_GOTPC_LO16
@@ -6154,9 +6156,7 @@ ENUMX
ENUMX
BFD_RELOC_OR1K_PLT26
ENUMX
- BFD_RELOC_OR1K_GOTOFF_HI16
-ENUMX
- BFD_RELOC_OR1K_GOTOFF_LO16
+ BFD_RELOC_OR1K_GOTOFF_SLO16
ENUMX
BFD_RELOC_OR1K_COPY
ENUMX
@@ -6180,12 +6180,18 @@ ENUMX
ENUMX
BFD_RELOC_OR1K_TLS_IE_HI16
ENUMX
+ BFD_RELOC_OR1K_TLS_IE_AHI16
+ENUMX
BFD_RELOC_OR1K_TLS_IE_LO16
ENUMX
BFD_RELOC_OR1K_TLS_LE_HI16
ENUMX
+ BFD_RELOC_OR1K_TLS_LE_AHI16
+ENUMX
BFD_RELOC_OR1K_TLS_LE_LO16
ENUMX
+ BFD_RELOC_OR1K_TLS_LE_SLO16
+ENUMX
BFD_RELOC_OR1K_TLS_TPOFF
ENUMX
BFD_RELOC_OR1K_TLS_DTPOFF