X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Felflink.c;h=ce6282a9dcfc0691ff05979222adba6e816d1c2f;hb=refs%2Fheads%2Fconcurrent-displaced-stepping-2020-04-01;hp=f87927f0bd8f7b71d41ff23c517d49d8895728ad;hpb=a6dbf402de65fe66f4ec99b56527dfd00d077cb6;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elflink.c b/bfd/elflink.c index f87927f0bd..ce6282a9dc 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -7650,6 +7650,37 @@ _bfd_elf_link_hash_copy_indirect (struct bfd_link_info *info, { struct elf_link_hash_table *htab; + if (ind->dyn_relocs != NULL) + { + if (dir->dyn_relocs != NULL) + { + struct elf_dyn_relocs **pp; + struct elf_dyn_relocs *p; + + /* Add reloc counts against the indirect sym to the direct sym + list. Merge any entries against the same section. */ + for (pp = &ind->dyn_relocs; (p = *pp) != NULL; ) + { + struct elf_dyn_relocs *q; + + for (q = dir->dyn_relocs; q != NULL; q = q->next) + if (q->sec == p->sec) + { + q->pc_count += p->pc_count; + q->count += p->count; + *pp = p->next; + break; + } + if (q == NULL) + pp = &p->next; + } + *pp = dir->dyn_relocs; + } + + dir->dyn_relocs = ind->dyn_relocs; + ind->dyn_relocs = NULL; + } + /* Copy down any references that we may have already seen to the symbol which just became indirect. */ @@ -14793,3 +14824,54 @@ bfd_elf_define_start_stop (struct bfd_link_info *info, } return NULL; } + +/* Find dynamic relocs for H that apply to read-only sections. */ + +asection * +_bfd_elf_readonly_dynrelocs (struct elf_link_hash_entry *h) +{ + struct elf_dyn_relocs *p; + + for (p = 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; +} + +/* Set DF_TEXTREL if we find any dynamic relocs that apply to + read-only sections. */ + +bfd_boolean +_bfd_elf_maybe_set_textrel (struct elf_link_hash_entry *h, void *inf) +{ + asection *sec; + + if (h->root.type == bfd_link_hash_indirect) + return TRUE; + + sec = _bfd_elf_readonly_dynrelocs (h); + if (sec != NULL) + { + struct bfd_link_info *info = (struct bfd_link_info *) inf; + + info->flags |= DF_TEXTREL; + /* xgettext:c-format */ + info->callbacks->minfo (_("%pB: dynamic relocation against `%pT' " + "in read-only section `%pA'\n"), + sec->owner, h->root.root.string, sec); + + if (bfd_link_textrel_check (info)) + /* xgettext:c-format */ + info->callbacks->einfo (_("%P: %pB: warning: relocation against `%s' " + "in read-only section `%pA'\n"), + sec->owner, h->root.root.string, sec); + + /* Not an error, just cut short the traversal. */ + return FALSE; + } + return TRUE; +}