+Tue Jul 14 11:22:21 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * elf32-m68k.c (elf_m68k_check_relocs): Also reference count
+ R_68K_PCxx and R_68K_xx relocations. Make sure that
+ ELF_LINK_HASH_NEEDS_PLT is always set for a PLT reloc reference.
+ (elf_m68k_gc_sweep_hook): Also reference count R_68K_PCxx and
+ R_68K_xx relocations.
+ (elf_m68k_adjust_dynamic_symbol): Reset the plt offset of a symbol
+ that has no plt entry.
+ (elf_m68k_relocate_section): Ignore the plt offset in a static
+ link.
+ * elflink.h (elf_adjust_dynamic_symbol): Reset the plt offset for
+ an ignored symbol.
+ (elf_gc_common_finalize_got_offsets): Set the got offsets also in
+ a static link.
+
+ * elf32-m68k.c (R_68K_GNU_VTINHERIT, R_68K_GNU_VTENTRY): New reloc
+ types.
+ (howto_table, reloc_map): Add entries for them.
+ (elf_m68k_check_relocs): Handle them. Implement reference
+ counting for got and plt entries.
+ (elf_m68k_gc_mark_hook, elf_m68k_gc_sweep_hook): New functions.
+ (elf_m68k_adjust_dynamic_symbol): Handle unreferenced plt
+ symbols.
+ (rtype_to_howto_rel, elf_info_to_howto_rel): Delete.
+ (elf_m68k_relocate_section): Handle the new reloc types.
+ (bfd_elf32_bfd_final_link, elf_backend_gc_mark_hook,
+ elf_backend_gc_sweep_hook, elf_backend_can_gc_sections): Define.
+ * elflink.h (elf_link_add_object_symbols): When creating an
+ indirect reference for symbol versioning also copy the plt
+ offset.
+ (elf_fix_symbol_flags): When clearing the ELF_LINK_HASH_NEEDS_PLT
+ flag also reset the plt offset.
+ (elf_link_assign_sym_version): Likewise.
+ (elf_gc_common_finalize_got_offsets): Increment the got offset by
+ the size of the entry in bytes.
+ (elf_gc_allocate_got_offsets): Likewise.
+
Tue Jul 14 11:18:14 1998 Ian Lance Taylor <ian@cygnus.com>
+ * elflink.h (elf_gc_sections): Return true rather than falling off
+ the bottom.
+
* coffgen.c (bfd_coff_set_symbol_class): Call bfd_alloc, not
xmalloc.
& (ELF_LINK_HASH_REF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR));
- /* Copy over the global table offset entry.
- This may have been already set up by a
- check_relocs routine. */
+ /* Copy over the global and procedure linkage table
+ offset entries. These may have been already set
+ up by a check_relocs routine. */
if (ht->got.offset == (bfd_vma) -1)
{
ht->got.offset = hi->got.offset;
}
BFD_ASSERT (hi->got.offset == (bfd_vma) -1);
+ if (ht->plt.offset == (bfd_vma) -1)
+ {
+ ht->plt.offset = hi->plt.offset;
+ hi->plt.offset = (bfd_vma) -1;
+ }
+ BFD_ASSERT (hi->plt.offset == (bfd_vma) -1);
+
if (ht->dynindx == -1)
{
ht->dynindx = hi->dynindx;
& (ELF_LINK_HASH_REF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR));
- /* Copy over the global table offset entry.
- This may have been already set up by a
- check_relocs routine. */
+ /* Copy over the global and procedure linkage
+ table offset entries. These may have been
+ already set up by a check_relocs routine. */
if (h->got.offset == (bfd_vma) -1)
{
h->got.offset = hi->got.offset;
}
BFD_ASSERT (hi->got.offset == (bfd_vma) -1);
+ if (h->plt.offset == (bfd_vma) -1)
+ {
+ h->plt.offset = hi->plt.offset;
+ hi->plt.offset = (bfd_vma) -1;
+ }
+ BFD_ASSERT (hi->got.offset == (bfd_vma) -1);
+
if (h->dynindx == -1)
{
h->dynindx = hi->dynindx;
&& eif->info->shared
&& eif->info->symbolic
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0)
- h->elf_link_hash_flags &=~ ELF_LINK_HASH_NEEDS_PLT;
+ {
+ h->elf_link_hash_flags &=~ ELF_LINK_HASH_NEEDS_PLT;
+ h->plt.offset = (bfd_vma) -1;
+ }
return true;
}
|| (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0
|| ((h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0
&& (h->weakdef == NULL || h->weakdef->dynindx == -1))))
- return true;
+ {
+ h->plt.offset = (bfd_vma) -1;
+ return true;
+ }
/* If we've already adjusted this symbol, don't do it again. This
can happen via a recursive call. */
h->elf_link_hash_flags &=~
ELF_LINK_HASH_NEEDS_PLT;
h->dynindx = -1;
+ h->plt.offset = (bfd_vma) -1;
/* FIXME: The name of the symbol has
already been recorded in the dynamic
string table section. */
h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
h->elf_link_hash_flags &=~ ELF_LINK_HASH_NEEDS_PLT;
h->dynindx = -1;
+ h->plt.offset = (bfd_vma) -1;
/* FIXME: The name of the symbol has already
been recorded in the dynamic string table
section. */
h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
h->elf_link_hash_flags &=~ ELF_LINK_HASH_NEEDS_PLT;
h->dynindx = -1;
+ h->plt.offset = (bfd_vma) -1;
/* FIXME: The name of the symbol has already been
recorded in the dynamic string table section. */
}
elf_hash_table (info)->dynsymcount = i;
}
+
+ return true;
}
/* Sweep symbols in swept sections. Called via elf_link_hash_traverse. */
bfd *abfd;
struct bfd_link_info *info;
{
- if (elf_hash_table (info)->dynamic_sections_created)
+ bfd *i;
+ bfd_vma off[2], gotoff = 0;
+
+ /* Do the local .got entries first. */
+ for (i = info->input_bfds; i; i = i->link_next)
{
- bfd *i;
- bfd_vma off[2], gotoff = 0;
+ bfd_signed_vma *local_got = elf_local_got_refcounts (i);
+ bfd_size_type j, locsymcount;
+ Elf_Internal_Shdr *symtab_hdr;
- /* Do the local .got entries first. */
- for (i = info->input_bfds; i; i = i->link_next)
- {
- bfd_signed_vma *local_got = elf_local_got_refcounts (i);
- bfd_size_type j, locsymcount;
- Elf_Internal_Shdr *symtab_hdr;
+ if (!local_got)
+ continue;
- if (!local_got)
- continue;
+ symtab_hdr = &elf_tdata (i)->symtab_hdr;
+ if (elf_bad_symtab (i))
+ locsymcount = symtab_hdr->sh_size / sizeof (Elf_External_Sym);
+ else
+ locsymcount = symtab_hdr->sh_info;
- symtab_hdr = &elf_tdata (i)->symtab_hdr;
- if (elf_bad_symtab (i))
- locsymcount = symtab_hdr->sh_size / sizeof (Elf_External_Sym);
+ for (j = 0; j < locsymcount; ++j)
+ {
+ if (local_got[j] > 0)
+ {
+ local_got[j] = gotoff;
+ gotoff += ARCH_SIZE / 8;
+ }
else
- locsymcount = symtab_hdr->sh_info;
-
- for (j = 0; j < locsymcount; ++j)
- local_got[j] = (local_got[j] > 0 ? gotoff++ : (bfd_vma) - 1);
+ local_got[j] = (bfd_vma) -1;
}
-
- /* Then the global .got and .plt entries. */
- off[0] = gotoff;
- off[1] = 0;
- elf_link_hash_traverse (elf_hash_table (info),
- elf_gc_allocate_got_offsets,
- (PTR) off);
}
+ /* Then the global .got and .plt entries. */
+ off[0] = gotoff;
+ off[1] = 0;
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_gc_allocate_got_offsets,
+ (PTR) off);
return true;
}
{
bfd_vma *off = (bfd_vma *) offarg;
- h->got.offset = (h->got.refcount > 0 ? off[0]++ : (bfd_vma) - 1);
+ if (h->got.refcount > 0)
+ {
+ h->got.offset = off[0];
+ off[0] += ARCH_SIZE / 8;
+ }
+ else
+ h->got.offset = (bfd_vma) -1;
return true;
}