From 4989d792c87e7f545ad83e6f24dc2396db4c31e9 Mon Sep 17 00:00:00 2001 From: Stephen Clarke Date: Wed, 2 Oct 2002 21:53:40 +0000 Subject: [PATCH] * elf32-sh.c (elf_sh_link_hash_entry): Add gotplt_refcount. (sh_elf_link_hash_newfunc): Initialize it. (allocate_dynrelocs): Transfer gotplt refs from plt.refcount to got.refcount for symbols that are forced local or when we have direct got refs. (sh_elf_gc_sweep_hook): Adjust gotplt_refcount. Use it to correctly adjust got.refcount and plt.refcount. (sh_elf_copy_indirect_symbol): Copy gotplt_refcount across. (sh_elf_check_relocs): Increment gotplt_refcount. --- bfd/ChangeLog | 12 ++++++++++++ bfd/elf32-sh.c | 31 +++++++++++++++++++++++++++---- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 90d90d2..f2c7a38 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,15 @@ +2002-10-02 Stephen Clarke + + * elf32-sh.c (elf_sh_link_hash_entry): Add gotplt_refcount. + (sh_elf_link_hash_newfunc): Initialize it. + (allocate_dynrelocs): Transfer gotplt refs from plt.refcount + to got.refcount for symbols that are forced local or when + we have direct got refs. + (sh_elf_gc_sweep_hook): Adjust gotplt_refcount. Use it + to correctly adjust got.refcount and plt.refcount. + (sh_elf_copy_indirect_symbol): Copy gotplt_refcount across. + (sh_elf_check_relocs): Increment gotplt_refcount. + 2002-10-01 Jakub Jelinek * elf32-i386.c (elf_i386_relocate_section): Fix diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c index c8bbe71..703ac40 100644 --- a/bfd/elf32-sh.c +++ b/bfd/elf32-sh.c @@ -3388,6 +3388,8 @@ struct elf_sh_link_hash_entry /* Track dynamic relocs copied for this symbol. */ struct elf_sh_dyn_relocs *dyn_relocs; + + bfd_signed_vma gotplt_refcount; }; /* sh ELF linker hash table. */ @@ -3452,6 +3454,7 @@ sh_elf_link_hash_newfunc (entry, table, string) eh = (struct elf_sh_link_hash_entry *) ret; eh->dyn_relocs = NULL; + eh->gotplt_refcount = 0; #ifdef INCLUDE_SHMEDIA ret->datalabel_got_offset = (bfd_vma) -1; #endif @@ -3867,6 +3870,18 @@ allocate_dynrelocs (h, inf) info = (struct bfd_link_info *) inf; htab = sh_elf_hash_table (info); + eh = (struct elf_sh_link_hash_entry *) h; + if ((h->got.refcount > 0 + || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL)) + && eh->gotplt_refcount > 0) + { + /* The symbol has been forced local, or we have some direct got refs, + so treat all the gotplt refs as got refs. */ + h->got.refcount += eh->gotplt_refcount; + if (h->plt.refcount >= eh->gotplt_refcount) + h->plt.refcount -= eh->gotplt_refcount; + } + if (htab->root.dynamic_sections_created && h->plt.refcount > 0) { @@ -3961,7 +3976,6 @@ allocate_dynrelocs (h, inf) else h->got.offset = (bfd_vma) -1; - eh = (struct elf_sh_link_hash_entry *) h; if (eh->dyn_relocs == NULL) return true; @@ -5200,6 +5214,7 @@ sh_elf_gc_sweep_hook (abfd, info, sec, relocs) const Elf_Internal_Rela *rel, *relend; unsigned long r_symndx; struct elf_link_hash_entry *h; + struct elf_sh_link_hash_entry *eh; elf_section_data (sec)->local_dynrel = NULL; @@ -5302,10 +5317,15 @@ sh_elf_gc_sweep_hook (abfd, info, sec, relocs) if (r_symndx >= symtab_hdr->sh_info) { h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - if (h->got.refcount > 0) + eh = (struct elf_sh_link_hash_entry *) h; + if (eh->gotplt_refcount > 0) + { + eh->gotplt_refcount -= 1; + if (h->plt.refcount > 0) + h->plt.refcount -= 1; + } + else if (h->got.refcount > 0) h->got.refcount -= 1; - if (h->plt.refcount > 0) - h->plt.refcount -= 1; } else if (local_got_refcounts != NULL) { @@ -5365,6 +5385,8 @@ sh_elf_copy_indirect_symbol (bed, dir, ind) edir->dyn_relocs = eind->dyn_relocs; eind->dyn_relocs = NULL; } + edir->gotplt_refcount = eind->gotplt_refcount; + eind->gotplt_refcount = 0; _bfd_elf_link_hash_copy_indirect (bed, dir, ind); } @@ -5539,6 +5561,7 @@ sh_elf_check_relocs (abfd, info, sec, relocs) h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; h->plt.refcount += 1; + ((struct elf_sh_link_hash_entry *) h)->gotplt_refcount += 1; break; -- 2.7.4