* 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.
This commit is contained in:
Stephen Clarke 2002-10-02 21:53:40 +00:00
parent 10abb1d48f
commit 4989d792c8
2 changed files with 39 additions and 4 deletions

View File

@ -1,3 +1,15 @@
2002-10-02 Stephen Clarke <stephen.clarke@superh.com>
* 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 <jakub@redhat.com>
* elf32-i386.c (elf_i386_relocate_section): Fix

View File

@ -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;