X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Felfxx-tilegx.c;h=19c55417ab24301bb02e7e5faa2ce66de4e7bae3;hb=63c1f59d665542359de4737e3e48033c588f44dc;hp=ec88ab31a66865d9164a27a3b9e800a338ce8a86;hpb=535b785fb0c97220dea23a18f07baad6b5d77ae5;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elfxx-tilegx.c b/bfd/elfxx-tilegx.c index ec88ab31a6..19c55417ab 100644 --- a/bfd/elfxx-tilegx.c +++ b/bfd/elfxx-tilegx.c @@ -1622,7 +1622,7 @@ static int tilegx_elf_tls_transition (struct bfd_link_info *info, int r_type, int is_local, bfd_boolean disable_le_transition) { - if (bfd_link_pic (info)) + if (!bfd_link_executable (info)) return r_type; if (is_local && !disable_le_transition) @@ -1695,7 +1695,7 @@ tilegx_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, for (rel = relocs; rel < rel_end; rel++) { unsigned int r_type; - unsigned long r_symndx; + unsigned int r_symndx; struct elf_link_hash_entry *h; int tls_type; @@ -1718,10 +1718,6 @@ 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_regular = 1; } r_type = tilegx_elf_tls_transition (info, r_type, h == NULL, @@ -1734,7 +1730,7 @@ tilegx_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, case R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE: case R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE: case R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE: - if (bfd_link_pic (info)) + if (!bfd_link_executable (info)) goto r_tilegx_plt32; break; @@ -1755,7 +1751,7 @@ tilegx_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, case R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE: case R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE: tls_type = GOT_TLS_IE; - if (bfd_link_pic (info)) + if (!bfd_link_executable (info)) info->flags |= DF_STATIC_TLS; goto have_got_reference; @@ -1837,7 +1833,7 @@ tilegx_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, break; case R_TILEGX_TLS_GD_CALL: - if (bfd_link_pic (info)) + if (!bfd_link_executable (info)) { /* These are basically R_TILEGX_JUMPOFF_X1_PLT relocs against __tls_get_addr. */ @@ -2103,6 +2099,8 @@ tilegx_elf_gc_mark_hook (asection *sec, dealing with TLS optimization, ought to be !bfd_link_executable (info). */ if (bfd_link_pic (info)) { + struct bfd_link_hash_entry *bh; + switch (TILEGX_ELF_R_TYPE (rel->r_info)) { case R_TILEGX_TLS_GD_CALL: @@ -2111,12 +2109,18 @@ tilegx_elf_gc_mark_hook (asection *sec, 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); + bh = NULL; + if (! _bfd_generic_link_add_one_symbol (info, sec->owner, + "__tls_get_addr", 0, + bfd_und_section_ptr, + 0, NULL, FALSE, + FALSE, &bh)) + return NULL; + h = (struct elf_link_hash_entry *) bh; BFD_ASSERT (h != NULL); h->mark = 1; - if (h->u.weakdef != NULL) - h->u.weakdef->mark = 1; + if (h->is_weakalias) + weakdef (h)->mark = 1; sym = NULL; } } @@ -2124,193 +2128,21 @@ tilegx_elf_gc_mark_hook (asection *sec, return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym); } -/* Update the got entry reference counts for the section being removed. */ -bfd_boolean -tilegx_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info, - asection *sec, const Elf_Internal_Rela *relocs) -{ - struct tilegx_elf_link_hash_table *htab; - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; - bfd_signed_vma *local_got_refcounts; - const Elf_Internal_Rela *rel, *relend; - - if (bfd_link_relocatable (info)) - return TRUE; - - BFD_ASSERT (is_tilegx_elf (abfd) || sec->reloc_count == 0); +/* Find dynamic relocs for H that apply to read-only sections. */ - elf_section_data (sec)->local_dynrel = NULL; - - htab = tilegx_elf_hash_table (info); - BFD_ASSERT (htab != NULL); - symtab_hdr = &elf_symtab_hdr (abfd); - sym_hashes = elf_sym_hashes (abfd); - local_got_refcounts = elf_local_got_refcounts (abfd); +static asection * +readonly_dynrelocs (struct elf_link_hash_entry *h) +{ + struct tilegx_elf_dyn_relocs *p; - relend = relocs + sec->reloc_count; - for (rel = relocs; rel < relend; rel++) + for (p = tilegx_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next) { - unsigned long r_symndx; - unsigned int r_type; - struct elf_link_hash_entry *h = NULL; - - r_symndx = TILEGX_ELF_R_SYMNDX (htab, rel->r_info); - if (r_symndx >= symtab_hdr->sh_info) - { - struct tilegx_elf_link_hash_entry *eh; - struct tilegx_elf_dyn_relocs **pp; - struct tilegx_elf_dyn_relocs *p; - - h = sym_hashes[r_symndx - symtab_hdr->sh_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; - eh = (struct tilegx_elf_link_hash_entry *) h; - for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next) - if (p->sec == sec) - { - /* Everything must go for SEC. */ - *pp = p->next; - break; - } - } - - r_type = TILEGX_ELF_R_TYPE (rel->r_info); - r_type = tilegx_elf_tls_transition (info, r_type, h != NULL, - sec->sec_flg0); - switch (r_type) - { - case R_TILEGX_IMM16_X0_HW0_GOT: - case R_TILEGX_IMM16_X1_HW0_GOT: - case R_TILEGX_IMM16_X0_HW0_LAST_GOT: - case R_TILEGX_IMM16_X1_HW0_LAST_GOT: - case R_TILEGX_IMM16_X0_HW1_LAST_GOT: - case R_TILEGX_IMM16_X1_HW1_LAST_GOT: - case R_TILEGX_IMM16_X0_HW0_TLS_GD: - case R_TILEGX_IMM16_X1_HW0_TLS_GD: - case R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD: - case R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD: - case R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD: - case R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD: - case R_TILEGX_IMM16_X0_HW0_TLS_IE: - case R_TILEGX_IMM16_X1_HW0_TLS_IE: - case R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE: - case R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE: - case R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE: - case R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE: - if (h != NULL) - { - if (h->got.refcount > 0) - h->got.refcount--; - } - else - { - if (local_got_refcounts && - local_got_refcounts[r_symndx] > 0) - local_got_refcounts[r_symndx]--; - } - break; - - case R_TILEGX_64_PCREL: - case R_TILEGX_32_PCREL: - case R_TILEGX_16_PCREL: - case R_TILEGX_8_PCREL: - case R_TILEGX_IMM16_X0_HW0_PCREL: - case R_TILEGX_IMM16_X1_HW0_PCREL: - case R_TILEGX_IMM16_X0_HW1_PCREL: - case R_TILEGX_IMM16_X1_HW1_PCREL: - case R_TILEGX_IMM16_X0_HW2_PCREL: - case R_TILEGX_IMM16_X1_HW2_PCREL: - case R_TILEGX_IMM16_X0_HW3_PCREL: - case R_TILEGX_IMM16_X1_HW3_PCREL: - case R_TILEGX_IMM16_X0_HW0_LAST_PCREL: - case R_TILEGX_IMM16_X1_HW0_LAST_PCREL: - case R_TILEGX_IMM16_X0_HW1_LAST_PCREL: - case R_TILEGX_IMM16_X1_HW1_LAST_PCREL: - case R_TILEGX_IMM16_X0_HW2_LAST_PCREL: - case R_TILEGX_IMM16_X1_HW2_LAST_PCREL: - if (h != NULL - && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0) - break; - /* Fall through. */ - - case R_TILEGX_64: - case R_TILEGX_32: - case R_TILEGX_16: - case R_TILEGX_8: - case R_TILEGX_HW0: - case R_TILEGX_HW1: - case R_TILEGX_HW2: - case R_TILEGX_HW3: - case R_TILEGX_HW0_LAST: - case R_TILEGX_HW1_LAST: - case R_TILEGX_HW2_LAST: - case R_TILEGX_COPY: - case R_TILEGX_GLOB_DAT: - case R_TILEGX_JMP_SLOT: - case R_TILEGX_RELATIVE: - case R_TILEGX_BROFF_X1: - case R_TILEGX_JUMPOFF_X1: - case R_TILEGX_IMM8_X0: - case R_TILEGX_IMM8_Y0: - case R_TILEGX_IMM8_X1: - case R_TILEGX_IMM8_Y1: - case R_TILEGX_DEST_IMM8_X1: - case R_TILEGX_MT_IMM14_X1: - case R_TILEGX_MF_IMM14_X1: - case R_TILEGX_MMSTART_X0: - case R_TILEGX_MMEND_X0: - case R_TILEGX_SHAMT_X0: - case R_TILEGX_SHAMT_X1: - case R_TILEGX_SHAMT_Y0: - case R_TILEGX_SHAMT_Y1: - case R_TILEGX_IMM16_X0_HW0: - case R_TILEGX_IMM16_X1_HW0: - case R_TILEGX_IMM16_X0_HW1: - case R_TILEGX_IMM16_X1_HW1: - case R_TILEGX_IMM16_X0_HW2: - case R_TILEGX_IMM16_X1_HW2: - case R_TILEGX_IMM16_X0_HW3: - case R_TILEGX_IMM16_X1_HW3: - case R_TILEGX_IMM16_X0_HW0_LAST: - case R_TILEGX_IMM16_X1_HW0_LAST: - case R_TILEGX_IMM16_X0_HW1_LAST: - case R_TILEGX_IMM16_X1_HW1_LAST: - case R_TILEGX_IMM16_X0_HW2_LAST: - case R_TILEGX_IMM16_X1_HW2_LAST: - if (bfd_link_pic (info)) - break; - /* 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) - h->plt.refcount--; - } - break; + asection *s = p->sec->output_section; - default: - break; - } + if (s != NULL && (s->flags & SEC_READONLY) != 0) + return p->sec; } - - return TRUE; + return NULL; } /* Adjust a symbol defined by a dynamic object and referenced by a @@ -2337,7 +2169,7 @@ tilegx_elf_adjust_dynamic_symbol (struct bfd_link_info *info, /* Make sure we know what is going on here. */ BFD_ASSERT (dynobj != NULL && (h->needs_plt - || h->u.weakdef != NULL + || h->is_weakalias || (h->def_dynamic && h->ref_regular && !h->def_regular))); @@ -2370,12 +2202,12 @@ tilegx_elf_adjust_dynamic_symbol (struct bfd_link_info *info, /* If this is a weak symbol, and there is a real definition, the processor independent code will have arranged for us to see the real definition first, and we can just use the same value. */ - if (h->u.weakdef != NULL) + if (h->is_weakalias) { - BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined - || h->u.weakdef->root.type == bfd_link_hash_defweak); - h->root.u.def.section = h->u.weakdef->root.u.def.section; - h->root.u.def.value = h->u.weakdef->root.u.def.value; + struct elf_link_hash_entry *def = weakdef (h); + BFD_ASSERT (def->root.type == bfd_link_hash_defined); + h->root.u.def.section = def->root.u.def.section; + h->root.u.def.value = def->root.u.def.value; return TRUE; } @@ -2529,7 +2361,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) requiring no TLS entry. */ if (h->got.refcount > 0 && !htab->disable_le_transition - && !bfd_link_pic (info) + && bfd_link_executable (info) && h->dynindx == -1 && tilegx_elf_hash_entry(h)->tls_type == GOT_TLS_IE) h->got.offset = (bfd_vma) -1; @@ -2599,7 +2431,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) if (eh->dyn_relocs != NULL && h->root.type == bfd_link_hash_undefweak) { - if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) + if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT + || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)) eh->dyn_relocs = NULL; /* Make sure undefined weak symbols are output as a dynamic @@ -2655,28 +2488,29 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) return TRUE; } -/* Find any dynamic relocs that apply to read-only sections. */ +/* Set DF_TEXTREL if we find any dynamic relocs that apply to + read-only sections. */ static bfd_boolean -readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf) +maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p) { - struct tilegx_elf_link_hash_entry *eh; - struct tilegx_elf_dyn_relocs *p; + asection *sec; - eh = (struct tilegx_elf_link_hash_entry *) h; - for (p = eh->dyn_relocs; p != NULL; p = p->next) - { - asection *s = p->sec->output_section; + if (h->root.type == bfd_link_hash_indirect) + return TRUE; - if (s != NULL && (s->flags & SEC_READONLY) != 0) - { - struct bfd_link_info *info = (struct bfd_link_info *) inf; + sec = readonly_dynrelocs (h); + if (sec != NULL) + { + struct bfd_link_info *info = (struct bfd_link_info *) info_p; - info->flags |= DF_TEXTREL; + info->flags |= DF_TEXTREL; + info->callbacks->minfo + (_("%B: dynamic relocation against `%T' in read-only section `%A'\n"), + sec->owner, h->root.root.string, sec); - /* Not an error, just cut short the traversal. */ - return FALSE; - } + /* Not an error, just cut short the traversal. */ + return FALSE; } return TRUE; } @@ -2757,7 +2591,12 @@ tilegx_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, srel = elf_section_data (p->sec)->sreloc; srel->size += p->count * TILEGX_ELF_RELA_BYTES (htab); if ((p->sec->output_section->flags & SEC_READONLY) != 0) - info->flags |= DF_TEXTREL; + { + info->flags |= DF_TEXTREL; + + info->callbacks->minfo (_("%B: dynamic relocation in read-only section `%A'\n"), + p->sec->owner, p->sec); + } } } } @@ -2916,7 +2755,7 @@ tilegx_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, /* If any dynamic relocs apply to a read-only section, then we need a DT_TEXTREL entry. */ if ((info->flags & DF_TEXTREL) == 0) - elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, info); + elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info); if (info->flags & DF_TEXTREL) { @@ -3151,7 +2990,7 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, const char *name; bfd_vma off; bfd_boolean is_plt = FALSE; - + bfd_boolean resolved_to_zero; bfd_boolean unresolved_reloc; r_type = TILEGX_ELF_R_TYPE (rel->r_info); @@ -3160,15 +2999,7 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, continue; if ((unsigned int)r_type >= ARRAY_SIZE (tilegx_elf_howto_table)) - { - /* Not clear if we need to check here, but just be paranoid. */ - _bfd_error_handler - /* xgettext:c-format */ - (_("%B: unrecognized relocation (0x%x) in section `%A'"), - input_bfd, r_type, input_section); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } + return _bfd_unrecognized_reloc (input_bfd, input_section, r_type); howto = tilegx_elf_howto_table + r_type; @@ -3240,9 +3071,9 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, else if (h != NULL) tls_type = tilegx_elf_hash_entry(h)->tls_type; - is_tls_iele = (! bfd_link_pic (info) || tls_type == GOT_TLS_IE); + is_tls_iele = (bfd_link_executable (info) || tls_type == GOT_TLS_IE); is_tls_le = is_tls_iele && (!input_section->sec_flg0 - && !bfd_link_pic (info) + && bfd_link_executable (info) && (h == NULL || h->dynindx == -1)); if (r_type == R_TILEGX_TLS_GD_CALL) @@ -3387,7 +3218,7 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, break; case R_TILEGX_TLS_IE_LOAD: if (!input_section->sec_flg0 - && !bfd_link_pic (info) + && bfd_link_executable (info) && (h == NULL || h->dynindx == -1)) { /* IE -> LE */ @@ -3413,6 +3244,9 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, break; } + resolved_to_zero = (h != NULL + && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)); + switch (r_type) { case R_TILEGX_IMM16_X0_HW0_GOT: @@ -3610,7 +3444,8 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, if ((bfd_link_pic (info) && (h == NULL - || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT + || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT + && !resolved_to_zero) || h->root.type != bfd_link_hash_undefweak) && (! howto->pc_relative || !SYMBOL_CALLS_LOCAL (info, h))) @@ -3750,7 +3585,7 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, case R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE: case R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE: case R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE: - if (bfd_link_pic (info)) + if (!bfd_link_executable (info)) { Elf_Internal_Rela outrel; bfd_boolean skip; @@ -3802,7 +3637,7 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, else if (h != NULL) { tls_type = tilegx_elf_hash_entry(h)->tls_type; - if (!bfd_link_pic (info) + if (bfd_link_executable (info) && h->dynindx == -1 && tls_type == GOT_TLS_IE) r_type = (!input_section->sec_flg0 @@ -3973,10 +3808,10 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, rel->r_offset) != (bfd_vma) -1) _bfd_error_handler /* xgettext:c-format */ - (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"), + (_("%B(%A+%#Lx): unresolvable %s relocation against symbol `%s'"), input_bfd, input_section, - (long) rel->r_offset, + rel->r_offset, howto->name, h->root.root.string); @@ -4313,10 +4148,10 @@ tilegx_elf_finish_dynamic_sections (bfd *output_bfd, 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 - = PLT_ENTRY_SIZE; + elf_section_data (splt->output_section)->this_hdr.sh_entsize + = PLT_ENTRY_SIZE; + } } if (htab->elf.sgotplt) @@ -4337,10 +4172,10 @@ tilegx_elf_finish_dynamic_sections (bfd *output_bfd, TILEGX_ELF_PUT_WORD (htab, output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + GOT_ENTRY_SIZE (htab)); - } - elf_section_data (htab->elf.sgotplt->output_section)->this_hdr.sh_entsize = - GOT_ENTRY_SIZE (htab); + elf_section_data (htab->elf.sgotplt->output_section)->this_hdr.sh_entsize = + GOT_ENTRY_SIZE (htab); + } } if (htab->elf.sgot) @@ -4354,10 +4189,10 @@ tilegx_elf_finish_dynamic_sections (bfd *output_bfd, 0); TILEGX_ELF_PUT_WORD (htab, output_bfd, val, htab->elf.sgot->contents); - } - elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = - GOT_ENTRY_SIZE (htab); + elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = + GOT_ENTRY_SIZE (htab); + } } return TRUE;