X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=bfd%2Felf32-metag.c;h=f68f9dca6f80098f498c043b89fa940b0d1af4c1;hb=refs%2Fheads%2Fsandbox%2Fvbarinov%2Ftizen_6_base;hp=39d3fffcb66b76d3cafebb03ee9cdbabc075bb2a;hpb=64f52338e924cce3a205527136e145da660a4686;p=external%2Fbinutils.git diff --git a/bfd/elf32-metag.c b/bfd/elf32-metag.c index 39d3fff..f68f9dc 100644 --- a/bfd/elf32-metag.c +++ b/bfd/elf32-metag.c @@ -1,5 +1,5 @@ /* Meta support for 32-bit ELF - Copyright (C) 2013-2016 Free Software Foundation, Inc. + Copyright (C) 2013-2019 Free Software Foundation, Inc. Contributed by Imagination Technologies Ltd. This file is part of BFD, the Binary File Descriptor library. @@ -73,20 +73,18 @@ static const unsigned int plt_pic_entry[] = /* Variable names follow a coding style. Please follow this (Apps Hungarian) style: - Structure/Variable Prefix - elf_link_hash_table "etab" - elf_link_hash_entry "eh" + Structure/Variable Prefix + elf_link_hash_table "etab" + elf_link_hash_entry "eh" - elf_metag_link_hash_table "htab" - elf_metag_link_hash_entry "hh" + elf_metag_link_hash_table "htab" + elf_metag_link_hash_entry "hh" - bfd_link_hash_table "btab" - bfd_link_hash_entry "bh" + bfd_link_hash_table "btab" + bfd_link_hash_entry "bh" bfd_hash_table containing stubs "bstab" - elf_metag_stub_hash_entry "hsh" - - elf_metag_dyn_reloc_entry "hdh" + elf_metag_stub_hash_entry "hsh" Always remember to use GNU Coding Style. */ @@ -701,44 +699,44 @@ struct metag_reloc_map static const struct metag_reloc_map metag_reloc_map [] = { - { BFD_RELOC_NONE, R_METAG_NONE }, - { BFD_RELOC_32, R_METAG_ADDR32 }, - { BFD_RELOC_METAG_HIADDR16, R_METAG_HIADDR16 }, - { BFD_RELOC_METAG_LOADDR16, R_METAG_LOADDR16 }, + { BFD_RELOC_NONE, R_METAG_NONE }, + { BFD_RELOC_32, R_METAG_ADDR32 }, + { BFD_RELOC_METAG_HIADDR16, R_METAG_HIADDR16 }, + { BFD_RELOC_METAG_LOADDR16, R_METAG_LOADDR16 }, { BFD_RELOC_METAG_RELBRANCH, R_METAG_RELBRANCH }, { BFD_RELOC_METAG_GETSETOFF, R_METAG_GETSETOFF }, - { BFD_RELOC_VTABLE_INHERIT, R_METAG_GNU_VTINHERIT }, - { BFD_RELOC_VTABLE_ENTRY, R_METAG_GNU_VTENTRY }, - { BFD_RELOC_METAG_REL8, R_METAG_REL8 }, - { BFD_RELOC_METAG_REL16, R_METAG_REL16 }, + { BFD_RELOC_VTABLE_INHERIT, R_METAG_GNU_VTINHERIT }, + { BFD_RELOC_VTABLE_ENTRY, R_METAG_GNU_VTENTRY }, + { BFD_RELOC_METAG_REL8, R_METAG_REL8 }, + { BFD_RELOC_METAG_REL16, R_METAG_REL16 }, { BFD_RELOC_METAG_HI16_GOTOFF, R_METAG_HI16_GOTOFF }, { BFD_RELOC_METAG_LO16_GOTOFF, R_METAG_LO16_GOTOFF }, { BFD_RELOC_METAG_GETSET_GOTOFF, R_METAG_GETSET_GOTOFF }, { BFD_RELOC_METAG_GETSET_GOT, R_METAG_GETSET_GOT }, { BFD_RELOC_METAG_HI16_GOTPC, R_METAG_HI16_GOTPC }, { BFD_RELOC_METAG_LO16_GOTPC, R_METAG_LO16_GOTPC }, - { BFD_RELOC_METAG_HI16_PLT, R_METAG_HI16_PLT }, - { BFD_RELOC_METAG_LO16_PLT, R_METAG_LO16_PLT }, + { BFD_RELOC_METAG_HI16_PLT, R_METAG_HI16_PLT }, + { BFD_RELOC_METAG_LO16_PLT, R_METAG_LO16_PLT }, { BFD_RELOC_METAG_RELBRANCH_PLT, R_METAG_RELBRANCH_PLT }, - { BFD_RELOC_METAG_GOTOFF, R_METAG_GOTOFF }, - { BFD_RELOC_METAG_PLT, R_METAG_PLT }, - { BFD_RELOC_METAG_COPY, R_METAG_COPY }, - { BFD_RELOC_METAG_JMP_SLOT, R_METAG_JMP_SLOT }, - { BFD_RELOC_METAG_RELATIVE, R_METAG_RELATIVE }, - { BFD_RELOC_METAG_GLOB_DAT, R_METAG_GLOB_DAT }, - { BFD_RELOC_METAG_TLS_GD, R_METAG_TLS_GD }, - { BFD_RELOC_METAG_TLS_LDM, R_METAG_TLS_LDM }, + { BFD_RELOC_METAG_GOTOFF, R_METAG_GOTOFF }, + { BFD_RELOC_METAG_PLT, R_METAG_PLT }, + { BFD_RELOC_METAG_COPY, R_METAG_COPY }, + { BFD_RELOC_METAG_JMP_SLOT, R_METAG_JMP_SLOT }, + { BFD_RELOC_METAG_RELATIVE, R_METAG_RELATIVE }, + { BFD_RELOC_METAG_GLOB_DAT, R_METAG_GLOB_DAT }, + { BFD_RELOC_METAG_TLS_GD, R_METAG_TLS_GD }, + { BFD_RELOC_METAG_TLS_LDM, R_METAG_TLS_LDM }, { BFD_RELOC_METAG_TLS_LDO_HI16, R_METAG_TLS_LDO_HI16 }, { BFD_RELOC_METAG_TLS_LDO_LO16, R_METAG_TLS_LDO_LO16 }, - { BFD_RELOC_METAG_TLS_LDO, R_METAG_TLS_LDO }, - { BFD_RELOC_METAG_TLS_IE, R_METAG_TLS_IE }, + { BFD_RELOC_METAG_TLS_LDO, R_METAG_TLS_LDO }, + { BFD_RELOC_METAG_TLS_IE, R_METAG_TLS_IE }, { BFD_RELOC_METAG_TLS_IENONPIC, R_METAG_TLS_IENONPIC }, { BFD_RELOC_METAG_TLS_IENONPIC_HI16, R_METAG_TLS_IENONPIC_HI16 }, { BFD_RELOC_METAG_TLS_IENONPIC_LO16, R_METAG_TLS_IENONPIC_LO16 }, { BFD_RELOC_METAG_TLS_TPOFF, R_METAG_TLS_TPOFF }, { BFD_RELOC_METAG_TLS_DTPMOD, R_METAG_TLS_DTPMOD }, { BFD_RELOC_METAG_TLS_DTPOFF, R_METAG_TLS_DTPOFF }, - { BFD_RELOC_METAG_TLS_LE, R_METAG_TLS_LE }, + { BFD_RELOC_METAG_TLS_LE, R_METAG_TLS_LE }, { BFD_RELOC_METAG_TLS_LE_HI16, R_METAG_TLS_LE_HI16 }, { BFD_RELOC_METAG_TLS_LE_LO16, R_METAG_TLS_LE_LO16 }, }; @@ -789,20 +787,7 @@ struct elf_metag_link_hash_entry /* Used to count relocations for delayed sizing of relocation sections. */ - struct elf_metag_dyn_reloc_entry { - - /* Next relocation in the chain. */ - struct elf_metag_dyn_reloc_entry *hdh_next; - - /* The input section of the reloc. */ - asection *sec; - - /* Number of relocs copied in this section. */ - bfd_size_type count; - - /* Number of relative relocs copied for the input section. */ - bfd_size_type relative_count; - } *dyn_relocs; + struct elf_dyn_relocs *dyn_relocs; enum { @@ -842,10 +827,6 @@ struct elf_metag_link_hash_table asection **input_list; Elf_Internal_Sym **all_local_syms; - /* Short-cuts to get to dynamic linker sections. */ - asection *sdynbss; - asection *srelbss; - /* Small local sym cache. */ struct sym_cache sym_cache; @@ -883,8 +864,8 @@ tpoff (struct bfd_link_info *info, bfd_vma address) elf_hash_table (info)->tls_sec->alignment_power)); } -static void -metag_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED, +static bfd_boolean +metag_info_to_howto_rela (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst) { @@ -894,10 +875,13 @@ metag_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED, if (r_type >= (unsigned int) R_METAG_MAX) { /* xgettext:c-format */ - _bfd_error_handler (_("%B: invalid METAG reloc number: %d"), abfd, r_type); - r_type = 0; + _bfd_error_handler (_("%pB: unsupported relocation type %#x"), + abfd, r_type); + bfd_set_error (bfd_error_bad_value); + return FALSE; } cache_ptr->howto = & elf_metag_howto_table [r_type]; + return TRUE; } static reloc_howto_type * @@ -1199,7 +1183,7 @@ metag_add_stub (const char *stub_name, if (hsh == NULL) { /* xgettext:c-format */ - _bfd_error_handler (_("%B: cannot create stub entry %s"), + _bfd_error_handler (_("%pB: cannot create stub entry %s"), section->owner, stub_name); return NULL; } @@ -1412,7 +1396,7 @@ metag_final_link_relocate (reloc_howto_type *howto, rel, relend, howto, contents) \ { \ _bfd_clear_contents (howto, input_bfd, input_section, \ - contents + rel->r_offset); \ + contents, rel->r_offset); \ \ if (bfd_link_relocatable (info) \ && (input_section->flags & SEC_DEBUGGING)) \ @@ -1876,10 +1860,10 @@ elf_metag_relocate_section (bfd *output_bfd, /* We don't support changing the TLS model. */ /* PR 20675 */ if (bfd_link_pic (info)) - _bfd_error_handler (_("%B(%A): multiple TLS models are not supported"), - input_bfd, input_section, name); + _bfd_error_handler (_("%pB(%pA): multiple TLS models are not supported"), + input_bfd, input_section); else - _bfd_error_handler (_("%B(%A): shared library symbol %s encountered whilst performing a static link"), + _bfd_error_handler (_("%pB(%pA): shared library symbol %s encountered whilst performing a static link"), input_bfd, input_section, name); return FALSE; } @@ -1932,9 +1916,10 @@ elf_metag_relocate_section (bfd *output_bfd, { _bfd_error_handler /* xgettext:c-format */ - (_("%B(%A+0x%lx): R_METAG_TLS_LE/IENONPIC relocation not permitted in shared object"), - input_bfd, input_section, - (long) rel->r_offset, howto->name); + (_("%pB(%pA+%#" PRIx64 "): " + "%s relocation not permitted in shared object"), + input_bfd, input_section, (uint64_t) rel->r_offset, + howto->name); return FALSE; } else @@ -2069,9 +2054,6 @@ elf_metag_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) htab->etab.hgot = eh; - htab->sdynbss = bfd_get_linker_section (abfd, ".dynbss"); - htab->srelbss = bfd_get_linker_section (abfd, ".rela.bss"); - return TRUE; } @@ -2136,10 +2118,6 @@ elf_metag_check_relocs (bfd *abfd, while (hh->eh.root.type == bfd_link_hash_indirect || hh->eh.root.type == bfd_link_hash_warning) hh = (struct elf_metag_link_hash_entry *) hh->eh.root.u.i.link; - - /* PR15323, ref flags aren't set for references in the same - object. */ - hh->eh.root.non_ir_ref = 1; } /* Some relocs require a global offset table. */ @@ -2276,7 +2254,7 @@ elf_metag_check_relocs (bfd *abfd, name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL); _bfd_error_handler /* xgettext:c-format */ - (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"), + (_("%pB: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"), abfd, elf_metag_howto_table[r_type].name, name); bfd_set_error (bfd_error_bad_value); return FALSE; @@ -2324,8 +2302,8 @@ elf_metag_check_relocs (bfd *abfd, && (hh->eh.root.type == bfd_link_hash_defweak || !hh->eh.def_regular))) { - struct elf_metag_dyn_reloc_entry *hdh_p; - struct elf_metag_dyn_reloc_entry **hdh_head; + struct elf_dyn_relocs *hdh_p; + struct elf_dyn_relocs **hdh_head; if (dynobj == NULL) htab->etab.dynobj = dynobj = abfd; @@ -2362,26 +2340,26 @@ elf_metag_check_relocs (bfd *abfd, sr = sec; vpp = &elf_section_data (sr)->local_dynrel; - hdh_head = (struct elf_metag_dyn_reloc_entry **) vpp; + hdh_head = (struct elf_dyn_relocs **) vpp; } hdh_p = *hdh_head; if (hdh_p == NULL || hdh_p->sec != sec) { - hdh_p = ((struct elf_metag_dyn_reloc_entry *) + hdh_p = ((struct elf_dyn_relocs *) bfd_alloc (dynobj, sizeof *hdh_p)); if (hdh_p == NULL) return FALSE; - hdh_p->hdh_next = *hdh_head; + hdh_p->next = *hdh_head; *hdh_head = hdh_p; hdh_p->sec = sec; hdh_p->count = 0; - hdh_p->relative_count = 0; + hdh_p->pc_count = 0; } hdh_p->count += 1; if (ELF32_R_TYPE (rel->r_info) == R_METAG_RELBRANCH) - hdh_p->relative_count += 1; + hdh_p->pc_count += 1; } break; @@ -2396,9 +2374,7 @@ elf_metag_check_relocs (bfd *abfd, /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_METAG_GNU_VTENTRY: - BFD_ASSERT (hh != NULL); - if (hh != NULL - && !bfd_elf_gc_record_vtentry (abfd, sec, &hh->eh, rel->r_addend)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, &hh->eh, rel->r_addend)) return FALSE; break; } @@ -2423,8 +2399,8 @@ elf_metag_copy_indirect_symbol (struct bfd_link_info *info, { if (hh_dir->dyn_relocs != NULL) { - struct elf_metag_dyn_reloc_entry **hdh_pp; - struct elf_metag_dyn_reloc_entry *hdh_p; + struct elf_dyn_relocs **hdh_pp; + struct elf_dyn_relocs *hdh_p; if (eh_ind->root.type == bfd_link_hash_indirect) abort (); @@ -2433,19 +2409,19 @@ elf_metag_copy_indirect_symbol (struct bfd_link_info *info, list. Merge any entries against the same section. */ for (hdh_pp = &hh_ind->dyn_relocs; (hdh_p = *hdh_pp) != NULL; ) { - struct elf_metag_dyn_reloc_entry *hdh_q; + struct elf_dyn_relocs *hdh_q; for (hdh_q = hh_dir->dyn_relocs; hdh_q != NULL; - hdh_q = hdh_q->hdh_next) + hdh_q = hdh_q->next) if (hdh_q->sec == hdh_p->sec) { - hdh_q->relative_count += hdh_p->relative_count; + hdh_q->pc_count += hdh_p->pc_count; hdh_q->count += hdh_p->count; - *hdh_pp = hdh_p->hdh_next; + *hdh_pp = hdh_p->next; break; } if (hdh_q == NULL) - hdh_pp = &hdh_p->hdh_next; + hdh_pp = &hdh_p->next; } *hdh_pp = hh_dir->dyn_relocs; } @@ -2464,6 +2440,23 @@ elf_metag_copy_indirect_symbol (struct bfd_link_info *info, _bfd_elf_link_hash_copy_indirect (info, eh_dir, eh_ind); } +/* Find dynamic relocs for H that apply to read-only sections. */ + +static asection * +readonly_dynrelocs (struct elf_link_hash_entry *h) +{ + struct elf_dyn_relocs *p; + + for (p = metag_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next) + { + asection *s = p->sec->output_section; + + if (s != NULL && (s->flags & SEC_READONLY) != 0) + return p->sec; + } + return NULL; +} + /* Adjust a symbol defined by a dynamic object and referenced by a regular object. The current definition is in some section of the dynamic object, but we're not including those sections. We have to @@ -2475,9 +2468,7 @@ elf_metag_adjust_dynamic_symbol (struct bfd_link_info *info, struct elf_link_hash_entry *eh) { struct elf_metag_link_hash_table *htab; - struct elf_metag_link_hash_entry *hh; - struct elf_metag_dyn_reloc_entry *hdh_p; - asection *s; + asection *s, *srel; /* If this is a function, put it in the procedure linkage table. We will fill in the contents of the procedure linkage table later, @@ -2507,14 +2498,13 @@ elf_metag_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 (eh->u.weakdef != NULL) + if (eh->is_weakalias) { - if (eh->u.weakdef->root.type != bfd_link_hash_defined - && eh->u.weakdef->root.type != bfd_link_hash_defweak) - abort (); - eh->root.u.def.section = eh->u.weakdef->root.u.def.section; - eh->root.u.def.value = eh->u.weakdef->root.u.def.value; - eh->non_got_ref = eh->u.weakdef->non_got_ref; + struct elf_link_hash_entry *def = weakdef (eh); + BFD_ASSERT (def->root.type == bfd_link_hash_defined); + eh->root.u.def.section = def->root.u.def.section; + eh->root.u.def.value = def->root.u.def.value; + eh->non_got_ref = def->non_got_ref; return TRUE; } @@ -2540,17 +2530,9 @@ elf_metag_adjust_dynamic_symbol (struct bfd_link_info *info, return TRUE; } - hh = (struct elf_metag_link_hash_entry *) eh; - for (hdh_p = hh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->hdh_next) - { - s = hdh_p->sec->output_section; - if (s != NULL && (s->flags & SEC_READONLY) != 0) - break; - } - - /* If we didn't find any dynamic relocs in read-only sections, then + /* If we don't find any dynamic relocs in read-only sections, then we'll be keeping the dynamic relocs and avoiding the copy reloc. */ - if (hdh_p == NULL) + if (!readonly_dynrelocs (eh)) { eh->non_got_ref = 0; return TRUE; @@ -2571,14 +2553,22 @@ elf_metag_adjust_dynamic_symbol (struct bfd_link_info *info, /* We must generate a COPY reloc to tell the dynamic linker to copy the initial value out of the dynamic object and into the runtime process image. */ + if ((eh->root.u.def.section->flags & SEC_READONLY) != 0) + { + s = htab->etab.sdynrelro; + srel = htab->etab.sreldynrelro; + } + else + { + s = htab->etab.sdynbss; + srel = htab->etab.srelbss; + } if ((eh->root.u.def.section->flags & SEC_ALLOC) != 0 && eh->size != 0) { - htab->srelbss->size += sizeof (Elf32_External_Rela); + srel->size += sizeof (Elf32_External_Rela); eh->needs_copy = 1; } - s = htab->sdynbss; - return _bfd_elf_adjust_dynamic_copy (info, eh, s); } @@ -2591,7 +2581,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf) struct bfd_link_info *info; struct elf_metag_link_hash_table *htab; struct elf_metag_link_hash_entry *hh; - struct elf_metag_dyn_reloc_entry *hdh_p; + struct elf_dyn_relocs *hdh_p; if (eh->root.type == bfd_link_hash_indirect) return TRUE; @@ -2710,16 +2700,16 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf) { if (SYMBOL_CALLS_LOCAL (info, eh)) { - struct elf_metag_dyn_reloc_entry **hdh_pp; + struct elf_dyn_relocs **hdh_pp; for (hdh_pp = &hh->dyn_relocs; (hdh_p = *hdh_pp) != NULL; ) { - hdh_p->count -= hdh_p->relative_count; - hdh_p->relative_count = 0; + hdh_p->count -= hdh_p->pc_count; + hdh_p->pc_count = 0; if (hdh_p->count == 0) - *hdh_pp = hdh_p->hdh_next; + *hdh_pp = hdh_p->next; else - hdh_pp = &hdh_p->hdh_next; + hdh_pp = &hdh_p->next; } } @@ -2775,7 +2765,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf) } /* Finally, allocate space. */ - for (hdh_p = hh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->hdh_next) + for (hdh_p = hh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->next) { asection *sreloc = elf_section_data (hdh_p->sec)->sreloc; sreloc->size += hdh_p->count * sizeof (Elf32_External_Rela); @@ -2784,31 +2774,29 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, 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 *eh, void *inf) +maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p) { - struct elf_metag_link_hash_entry *hh; - struct elf_metag_dyn_reloc_entry *hdh_p; + asection *sec; - if (eh->root.type == bfd_link_hash_warning) - eh = (struct elf_link_hash_entry *) eh->root.u.i.link; + if (h->root.type == bfd_link_hash_indirect) + return TRUE; - hh = (struct elf_metag_link_hash_entry *) eh; - for (hdh_p = hh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->hdh_next) + sec = readonly_dynrelocs (h); + if (sec != NULL) { - asection *s = hdh_p->sec->output_section; + struct bfd_link_info *info = (struct bfd_link_info *) info_p; - if (s != NULL && (s->flags & SEC_READONLY) != 0) - { - struct bfd_link_info *info = inf; - - info->flags |= DF_TEXTREL; + info->flags |= DF_TEXTREL; + info->callbacks->minfo + (_("%pB: dynamic relocation against `%pT' in read-only section `%pA'\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; } @@ -2859,12 +2847,12 @@ elf_metag_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, for (s = ibfd->sections; s != NULL; s = s->next) { - struct elf_metag_dyn_reloc_entry *hdh_p; + struct elf_dyn_relocs *hdh_p; - for (hdh_p = ((struct elf_metag_dyn_reloc_entry *) + for (hdh_p = ((struct elf_dyn_relocs *) elf_section_data (s)->local_dynrel); hdh_p != NULL; - hdh_p = hdh_p->hdh_next) + hdh_p = hdh_p->next) { if (!bfd_is_abs_section (hdh_p->sec) && bfd_is_abs_section (hdh_p->sec->output_section)) @@ -2940,7 +2928,8 @@ elf_metag_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, if (s == htab->etab.splt || s == htab->etab.sgot || s == htab->etab.sgotplt - || s == htab->sdynbss) + || s == htab->etab.sdynbss + || s == htab->etab.sdynrelro) { /* Strip this section if we don't need it; see the comment below. */ @@ -3036,7 +3025,7 @@ elf_metag_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->etab, readonly_dynrelocs, info); + elf_link_hash_traverse (&htab->etab, maybe_set_textrel, info); if ((info->flags & DF_TEXTREL) != 0) { @@ -3222,13 +3211,15 @@ elf_metag_finish_dynamic_symbol (bfd *output_bfd, || eh->root.type == bfd_link_hash_defweak))) abort (); - s = htab->srelbss; - rel.r_offset = (eh->root.u.def.value + eh->root.u.def.section->output_offset + eh->root.u.def.section->output_section->vma); rel.r_addend = 0; rel.r_info = ELF32_R_INFO (eh->dynindx, R_METAG_COPY); + if (eh->root.u.def.section == htab->etab.sdynrelro) + s = htab->etab.sreldynrelro; + else + s = htab->etab.srelbss; loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela); bfd_elf32_swap_reloca_out (output_bfd, &rel, loc); } @@ -3414,131 +3405,6 @@ elf_metag_gc_mark_hook (asection *sec, return _bfd_elf_gc_mark_hook (sec, info, rela, hh, sym); } -/* Update the got and plt entry reference counts for the section being - removed. */ - -static bfd_boolean -elf_metag_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED, - struct bfd_link_info *info ATTRIBUTE_UNUSED, - asection *sec ATTRIBUTE_UNUSED, - const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED) -{ - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **eh_syms; - bfd_signed_vma *local_got_refcounts; - bfd_signed_vma *local_plt_refcounts; - const Elf_Internal_Rela *rel, *relend; - - if (bfd_link_relocatable (info)) - return TRUE; - - elf_section_data (sec)->local_dynrel = NULL; - - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - eh_syms = elf_sym_hashes (abfd); - local_got_refcounts = elf_local_got_refcounts (abfd); - local_plt_refcounts = local_got_refcounts; - if (local_plt_refcounts != NULL) - local_plt_refcounts += symtab_hdr->sh_info; - - relend = relocs + sec->reloc_count; - for (rel = relocs; rel < relend; rel++) - { - unsigned long r_symndx; - unsigned int r_type; - struct elf_link_hash_entry *eh = NULL; - - r_symndx = ELF32_R_SYM (rel->r_info); - if (r_symndx >= symtab_hdr->sh_info) - { - struct elf_metag_link_hash_entry *hh; - struct elf_metag_dyn_reloc_entry **hdh_pp; - struct elf_metag_dyn_reloc_entry *hdh_p; - - eh = eh_syms[r_symndx - symtab_hdr->sh_info]; - while (eh->root.type == bfd_link_hash_indirect - || eh->root.type == bfd_link_hash_warning) - eh = (struct elf_link_hash_entry *) eh->root.u.i.link; - hh = (struct elf_metag_link_hash_entry *) eh; - - for (hdh_pp = &hh->dyn_relocs; (hdh_p = *hdh_pp) != NULL; - hdh_pp = &hdh_p->hdh_next) - if (hdh_p->sec == sec) - { - /* Everything must go for SEC. */ - *hdh_pp = hdh_p->hdh_next; - break; - } - } - - r_type = ELF32_R_TYPE (rel->r_info); - switch (r_type) - { - case R_METAG_TLS_LDM: - if (metag_link_hash_table (info)->tls_ldm_got.refcount > 0) - metag_link_hash_table (info)->tls_ldm_got.refcount -= 1; - break; - case R_METAG_TLS_IE: - case R_METAG_TLS_GD: - case R_METAG_GETSET_GOT: - if (eh != NULL) - { - if (eh->got.refcount > 0) - eh->got.refcount -= 1; - } - else if (local_got_refcounts != NULL) - { - if (local_got_refcounts[r_symndx] > 0) - local_got_refcounts[r_symndx] -= 1; - } - break; - - case R_METAG_RELBRANCH_PLT: - if (eh != NULL) - { - if (eh->plt.refcount > 0) - eh->plt.refcount -= 1; - } - break; - - case R_METAG_ADDR32: - case R_METAG_HIADDR16: - case R_METAG_LOADDR16: - case R_METAG_GETSETOFF: - case R_METAG_RELBRANCH: - if (eh != NULL) - { - struct elf_metag_link_hash_entry *hh; - struct elf_metag_dyn_reloc_entry **hdh_pp; - struct elf_metag_dyn_reloc_entry *hdh_p; - - if (!bfd_link_pic (info) && eh->plt.refcount > 0) - eh->plt.refcount -= 1; - - hh = (struct elf_metag_link_hash_entry *) eh; - - for (hdh_pp = &hh->dyn_relocs; (hdh_p = *hdh_pp) != NULL; - hdh_pp = &hdh_p->hdh_next) - if (hdh_p->sec == sec) - { - if (ELF32_R_TYPE (rel->r_info) == R_METAG_RELBRANCH) - hdh_p->relative_count -= 1; - hdh_p->count -= 1; - if (hdh_p->count == 0) - *hdh_pp = hdh_p->hdh_next; - break; - } - } - break; - - default: - break; - } - } - - return TRUE; -} - /* Determine the type of stub needed, if any, for a call. */ static enum elf_metag_stub_type @@ -4271,7 +4137,6 @@ elf_metag_plt_sym_val (bfd_vma i, const asection *plt, elf_metag_link_hash_table_create #define elf_backend_relocate_section elf_metag_relocate_section #define elf_backend_gc_mark_hook elf_metag_gc_mark_hook -#define elf_backend_gc_sweep_hook elf_metag_gc_sweep_hook #define elf_backend_check_relocs elf_metag_check_relocs #define elf_backend_create_dynamic_sections elf_metag_create_dynamic_sections #define elf_backend_adjust_dynamic_symbol elf_metag_adjust_dynamic_symbol @@ -4279,7 +4144,7 @@ elf_metag_plt_sym_val (bfd_vma i, const asection *plt, #define elf_backend_finish_dynamic_sections elf_metag_finish_dynamic_sections #define elf_backend_size_dynamic_sections elf_metag_size_dynamic_sections #define elf_backend_omit_section_dynsym \ - ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true) + _bfd_elf_omit_section_dynsym_all #define elf_backend_post_process_headers elf_metag_post_process_headers #define elf_backend_reloc_type_class elf_metag_reloc_type_class #define elf_backend_copy_indirect_symbol elf_metag_copy_indirect_symbol @@ -4293,6 +4158,7 @@ elf_metag_plt_sym_val (bfd_vma i, const asection *plt, #define elf_backend_want_plt_sym 0 #define elf_backend_plt_readonly 1 #define elf_backend_dtrel_excludes_plt 1 +#define elf_backend_want_dynrelro 1 #define bfd_elf32_bfd_reloc_type_lookup metag_reloc_type_lookup #define bfd_elf32_bfd_reloc_name_lookup metag_reloc_name_lookup