Index: bfd/elfxx-tilegx.c |
diff --git a/bfd/elfxx-tilegx.c b/bfd/elfxx-tilegx.c |
index 6f748ece7f09a477f23315f3757782f25b984090..594ee7998493ae2fc904285ef67fb648928eec0d 100644 |
--- a/bfd/elfxx-tilegx.c |
+++ b/bfd/elfxx-tilegx.c |
@@ -1,5 +1,5 @@ |
/* TILE-Gx-specific support for ELF. |
- Copyright 2011, 2012 Free Software Foundation, Inc. |
+ Copyright 2011, 2012, 2013 Free Software Foundation, Inc. |
This file is part of BFD, the Binary File Descriptor library. |
@@ -490,21 +490,21 @@ static reloc_howto_type tilegx_elf_howto_table [] = |
TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X0_HW0_GOT, 0), |
TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X1_HW0_GOT, 0), |
- /* These relocs are currently not defined. */ |
- EMPTY_HOWTO (66), |
- EMPTY_HOWTO (67), |
- EMPTY_HOWTO (68), |
- EMPTY_HOWTO (69), |
- EMPTY_HOWTO (70), |
- EMPTY_HOWTO (71), |
+ |
+ TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X0_HW0_PLT_PCREL, 0), |
+ TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X1_HW0_PLT_PCREL, 0), |
+ TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X0_HW1_PLT_PCREL, 16), |
+ TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X1_HW1_PLT_PCREL, 16), |
+ TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X0_HW2_PLT_PCREL, 32), |
+ TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X1_HW2_PLT_PCREL, 32), |
TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X0_HW0_LAST_GOT, 0), |
TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X1_HW0_LAST_GOT, 0), |
TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X0_HW1_LAST_GOT, 16), |
TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X1_HW1_LAST_GOT, 16), |
- /* These relocs are currently not defined. */ |
- EMPTY_HOWTO (76), |
- EMPTY_HOWTO (77), |
+ |
+ TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X0_HW3_PLT_PCREL, 48), |
+ TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X1_HW3_PLT_PCREL, 48), |
TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X0_HW0_TLS_GD, 0), |
TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X1_HW0_TLS_GD, 0), |
@@ -530,12 +530,13 @@ static reloc_howto_type tilegx_elf_howto_table [] = |
TILEGX_IMM16_HOWTO_TLS_IE (R_TILEGX_IMM16_X0_HW0_TLS_IE, 0), |
TILEGX_IMM16_HOWTO_TLS_IE (R_TILEGX_IMM16_X1_HW0_TLS_IE, 0), |
- EMPTY_HOWTO (94), |
- EMPTY_HOWTO (95), |
- EMPTY_HOWTO (96), |
- EMPTY_HOWTO (97), |
- EMPTY_HOWTO (98), |
- EMPTY_HOWTO (99), |
+ |
+ TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL, 0), |
+ TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL, 0), |
+ TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL, 16), |
+ TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL, 16), |
+ TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL, 32), |
+ TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL, 32), |
#define TILEGX_IMM16_HOWTO_LAST_TLS_IE(name, rshift) \ |
HOWTO (name, rshift, 1, 16, FALSE, 0, \ |
@@ -713,10 +714,18 @@ static const reloc_map tilegx_reloc_map [] = |
SIMPLE_REMAP (TILEGX_IMM16_X1_HW2_LAST_PCREL) |
SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_GOT) |
SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_GOT) |
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_PLT_PCREL) |
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_PLT_PCREL) |
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW1_PLT_PCREL) |
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW1_PLT_PCREL) |
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW2_PLT_PCREL) |
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW2_PLT_PCREL) |
SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_LAST_GOT) |
SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_LAST_GOT) |
SIMPLE_REMAP (TILEGX_IMM16_X0_HW1_LAST_GOT) |
SIMPLE_REMAP (TILEGX_IMM16_X1_HW1_LAST_GOT) |
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW3_PLT_PCREL) |
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW3_PLT_PCREL) |
SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_TLS_GD) |
SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_TLS_GD) |
SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_TLS_LE) |
@@ -731,6 +740,12 @@ static const reloc_map tilegx_reloc_map [] = |
SIMPLE_REMAP (TILEGX_IMM16_X1_HW1_LAST_TLS_GD) |
SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_TLS_IE) |
SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_TLS_IE) |
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL) |
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL) |
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL) |
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL) |
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL) |
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL) |
SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_LAST_TLS_IE) |
SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_LAST_TLS_IE) |
SIMPLE_REMAP (TILEGX_IMM16_X0_HW1_LAST_TLS_IE) |
@@ -1027,18 +1042,10 @@ static const tilegx_create_func reloc_to_create_func[] = |
create_Imm16_X1, |
create_Imm16_X0, |
create_Imm16_X1, |
- NULL, |
- NULL, |
- NULL, |
- NULL, |
- NULL, |
- NULL, |
create_Imm16_X0, |
create_Imm16_X1, |
create_Imm16_X0, |
create_Imm16_X1, |
- NULL, |
- NULL, |
create_Imm16_X0, |
create_Imm16_X1, |
create_Imm16_X0, |
@@ -1051,20 +1058,28 @@ static const tilegx_create_func reloc_to_create_func[] = |
create_Imm16_X1, |
create_Imm16_X0, |
create_Imm16_X1, |
- NULL, |
- NULL, |
create_Imm16_X0, |
create_Imm16_X1, |
- NULL, |
- NULL, |
- NULL, |
- NULL, |
+ create_Imm16_X0, |
+ create_Imm16_X1, |
+ create_Imm16_X0, |
+ create_Imm16_X1, |
+ create_Imm16_X0, |
+ create_Imm16_X1, |
NULL, |
NULL, |
create_Imm16_X0, |
create_Imm16_X1, |
create_Imm16_X0, |
create_Imm16_X1, |
+ create_Imm16_X0, |
+ create_Imm16_X1, |
+ create_Imm16_X0, |
+ create_Imm16_X1, |
+ create_Imm16_X0, |
+ create_Imm16_X1, |
+ create_Imm16_X0, |
+ create_Imm16_X1, |
}; |
static void |
@@ -1205,7 +1220,7 @@ tilegx64_short_plt_entry[PLT_ENTRY_SIZE] = |
}; |
/* Reuse an existing info 10 bundle. */ |
-static const bfd_byte const *tilegx64_plt_tail_entry = |
+static const bfd_byte *const tilegx64_plt_tail_entry = |
&tilegx64_short_plt_entry[4 * TILEGX_BUNDLE_SIZE_IN_BYTES]; |
static const bfd_byte |
@@ -1250,7 +1265,7 @@ tilegx32_short_plt_entry[PLT_ENTRY_SIZE] = |
}; |
/* Reuse an existing info 10 bundle. */ |
-static const bfd_byte const *tilegx32_plt_tail_entry = |
+static const bfd_byte *const tilegx32_plt_tail_entry = |
&tilegx64_short_plt_entry[4 * TILEGX_BUNDLE_SIZE_IN_BYTES]; |
static int |
@@ -1723,6 +1738,10 @@ tilegx_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, |
while (h->root.type == bfd_link_hash_indirect |
|| h->root.type == bfd_link_hash_warning) |
h = (struct elf_link_hash_entry *) h->root.u.i.link; |
+ |
+ /* PR15323, ref flags aren't set for references in the same |
+ object. */ |
+ h->root.non_ir_ref = 1; |
} |
r_type = tilegx_elf_tls_transition (info, r_type, h == NULL, |
@@ -1855,6 +1874,20 @@ tilegx_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, |
/* Fall through */ |
case R_TILEGX_JUMPOFF_X1_PLT: |
+ case R_TILEGX_IMM16_X0_HW0_PLT_PCREL: |
+ case R_TILEGX_IMM16_X1_HW0_PLT_PCREL: |
+ case R_TILEGX_IMM16_X0_HW1_PLT_PCREL: |
+ case R_TILEGX_IMM16_X1_HW1_PLT_PCREL: |
+ case R_TILEGX_IMM16_X0_HW2_PLT_PCREL: |
+ case R_TILEGX_IMM16_X1_HW2_PLT_PCREL: |
+ case R_TILEGX_IMM16_X0_HW3_PLT_PCREL: |
+ case R_TILEGX_IMM16_X1_HW3_PLT_PCREL: |
+ case R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL: |
+ case R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL: |
+ case R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL: |
+ case R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL: |
+ case R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL: |
+ case R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL: |
/* This symbol requires a procedure linkage table entry. We |
actually build the entry in adjust_dynamic_symbol, |
because this might be a case of linking PIC code without |
@@ -2078,11 +2111,33 @@ tilegx_elf_gc_mark_hook (asection *sec, |
if (h != NULL) |
{ |
switch (TILEGX_ELF_R_TYPE (rel->r_info)) |
- { |
- case R_TILEGX_GNU_VTINHERIT: |
- case R_TILEGX_GNU_VTENTRY: |
- break; |
- } |
+ { |
+ case R_TILEGX_GNU_VTINHERIT: |
+ case R_TILEGX_GNU_VTENTRY: |
+ return NULL; |
+ } |
+ } |
+ |
+ /* FIXME: The test here, in check_relocs and in relocate_section |
+ dealing with TLS optimization, ought to be !info->executable. */ |
+ if (info->shared) |
+ { |
+ switch (TILEGX_ELF_R_TYPE (rel->r_info)) |
+ { |
+ case R_TILEGX_TLS_GD_CALL: |
+ /* This reloc implicitly references __tls_get_addr. We know |
+ another reloc will reference the same symbol as the one |
+ on this reloc, so the real symbol and section will be |
+ gc marked when processing the other reloc. That lets |
+ us handle __tls_get_addr here. */ |
+ h = elf_link_hash_lookup (elf_hash_table (info), "__tls_get_addr", |
+ FALSE, FALSE, TRUE); |
+ BFD_ASSERT (h != NULL); |
+ h->mark = 1; |
+ if (h->u.weakdef != NULL) |
+ h->u.weakdef->mark = 1; |
+ sym = NULL; |
+ } |
} |
return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym); |
@@ -2248,6 +2303,20 @@ tilegx_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info, |
/* Fall through. */ |
case R_TILEGX_JUMPOFF_X1_PLT: |
+ case R_TILEGX_IMM16_X0_HW0_PLT_PCREL: |
+ case R_TILEGX_IMM16_X1_HW0_PLT_PCREL: |
+ case R_TILEGX_IMM16_X0_HW1_PLT_PCREL: |
+ case R_TILEGX_IMM16_X1_HW1_PLT_PCREL: |
+ case R_TILEGX_IMM16_X0_HW2_PLT_PCREL: |
+ case R_TILEGX_IMM16_X1_HW2_PLT_PCREL: |
+ case R_TILEGX_IMM16_X0_HW3_PLT_PCREL: |
+ case R_TILEGX_IMM16_X1_HW3_PLT_PCREL: |
+ case R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL: |
+ case R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL: |
+ case R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL: |
+ case R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL: |
+ case R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL: |
+ case R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL: |
if (h != NULL) |
{ |
if (h->plt.refcount > 0) |
@@ -2427,10 +2496,10 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) |
/* Allocate room for the header and tail. */ |
if (s->size == 0) |
{ |
- s->size = PLT_HEADER_SIZE + PLT_TAIL_SIZE; |
+ s->size = PLT_ENTRY_SIZE; |
} |
- h->plt.offset = s->size - PLT_TAIL_SIZE; |
+ h->plt.offset = s->size - PLT_ENTRY_SIZE + PLT_HEADER_SIZE; |
/* If this symbol is not defined in a regular file, and we are |
not generating a shared library, then set the symbol to this |
@@ -2934,7 +3003,7 @@ static const bfd_byte insn_mask_X1[] = { |
/* Mask to extract the bits corresponding to an instruction in a |
specific pipe of a bundle, minus the destination operand and the |
first source operand. */ |
-static const bfd_byte insn_mask_X0_no_dest_no_srca[] = { |
+static const bfd_byte insn_mask_X0_no_dest_no_srca[] = { |
0x00, 0xf0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00 |
}; |
@@ -3122,12 +3191,13 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, |
} |
else |
{ |
- bfd_boolean warned; |
+ bfd_boolean warned ATTRIBUTE_UNUSED; |
+ bfd_boolean ignored ATTRIBUTE_UNUSED; |
RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, |
r_symndx, symtab_hdr, sym_hashes, |
h, sec, relocation, |
- unresolved_reloc, warned); |
+ unresolved_reloc, warned, ignored); |
if (warned) |
{ |
/* To avoid generating warning messages about truncated |
@@ -3436,10 +3506,24 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, |
local_got_offsets[r_symndx] |= 1; |
} |
} |
- relocation = htab->elf.sgot->output_offset + off - got_base; |
+ relocation = off - got_base; |
break; |
case R_TILEGX_JUMPOFF_X1_PLT: |
+ case R_TILEGX_IMM16_X0_HW0_PLT_PCREL: |
+ case R_TILEGX_IMM16_X1_HW0_PLT_PCREL: |
+ case R_TILEGX_IMM16_X0_HW1_PLT_PCREL: |
+ case R_TILEGX_IMM16_X1_HW1_PLT_PCREL: |
+ case R_TILEGX_IMM16_X0_HW2_PLT_PCREL: |
+ case R_TILEGX_IMM16_X1_HW2_PLT_PCREL: |
+ case R_TILEGX_IMM16_X0_HW3_PLT_PCREL: |
+ case R_TILEGX_IMM16_X1_HW3_PLT_PCREL: |
+ case R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL: |
+ case R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL: |
+ case R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL: |
+ case R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL: |
+ case R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL: |
+ case R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL: |
/* Relocation is to the entry for this symbol in the |
procedure linkage table. */ |
BFD_ASSERT (h != NULL); |
@@ -3869,7 +3953,7 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, |
if (off >= (bfd_vma) -2) |
abort (); |
- relocation = htab->elf.sgot->output_offset + off - got_base; |
+ relocation = off - got_base; |
unresolved_reloc = FALSE; |
howto = tilegx_elf_howto_table + r_type; |
break; |
@@ -4128,7 +4212,7 @@ tilegx_elf_finish_dynamic_symbol (bfd *output_bfd, |
} |
/* Mark some specially defined symbols as absolute. */ |
- if (strcmp (h->root.root.string, "_DYNAMIC") == 0 |
+ if (h == htab->elf.hdynamic |
|| (h == htab->elf.hgot || h == htab->elf.hplt)) |
sym->st_shndx = SHN_ABS; |
@@ -4190,6 +4274,7 @@ tilegx_elf_finish_dynamic_sections (bfd *output_bfd, |
bfd *dynobj; |
asection *sdyn; |
struct tilegx_elf_link_hash_table *htab; |
+ size_t pad_size; |
htab = tilegx_elf_hash_table (info); |
BFD_ASSERT (htab != NULL); |
@@ -4218,10 +4303,15 @@ tilegx_elf_finish_dynamic_sections (bfd *output_bfd, |
tilegx64_plt0_entry : tilegx32_plt0_entry, |
PLT_HEADER_SIZE); |
- memcpy (splt->contents + splt->size - PLT_TAIL_SIZE, |
+ memcpy (splt->contents + splt->size |
+ - PLT_ENTRY_SIZE + PLT_HEADER_SIZE, |
ABI_64_P (output_bfd) ? |
tilegx64_plt_tail_entry : tilegx32_plt_tail_entry, |
PLT_TAIL_SIZE); |
+ /* Add padding so that the plt section is a multiple of its |
+ entry size. */ |
+ pad_size = PLT_ENTRY_SIZE - PLT_HEADER_SIZE - PLT_TAIL_SIZE; |
+ memset (splt->contents + splt->size - pad_size, 0, pad_size); |
} |
elf_section_data (splt->output_section)->this_hdr.sh_entsize |
@@ -4285,7 +4375,9 @@ tilegx_elf_plt_sym_val (bfd_vma i, const asection *plt, |
} |
enum elf_reloc_type_class |
-tilegx_reloc_type_class (const Elf_Internal_Rela *rela) |
+tilegx_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED, |
+ const asection *rel_sec ATTRIBUTE_UNUSED, |
+ const Elf_Internal_Rela *rela) |
{ |
switch ((int) TILEGX_ELF_R_TYPE (rela->r_info)) |
{ |