From be228e0db6047054b1ebfe6ac440186eeaba8f16 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 14 Jul 1998 15:45:55 +0000 Subject: [PATCH] Tue Jul 14 11:22:21 1998 Andreas Schwab * 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 * elflink.h (elf_gc_sections): Return true rather than falling off the bottom. --- bfd/ChangeLog | 41 ++++++++++++++++++++ bfd/elflink.h | 103 +++++++++++++++++++++++++++++++++----------------- 2 files changed, 110 insertions(+), 34 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 7b6c6615f94..f40488e2c92 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,46 @@ +Tue Jul 14 11:22:21 1998 Andreas Schwab + + * 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 + * 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. diff --git a/bfd/elflink.h b/bfd/elflink.h index 97087396482..4b56211dcd2 100644 --- a/bfd/elflink.h +++ b/bfd/elflink.h @@ -1456,9 +1456,9 @@ elf_link_add_object_symbols (abfd, info) & (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; @@ -1466,6 +1466,13 @@ elf_link_add_object_symbols (abfd, info) } 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; @@ -1557,9 +1564,9 @@ elf_link_add_object_symbols (abfd, info) & (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; @@ -1567,6 +1574,13 @@ elf_link_add_object_symbols (abfd, info) } 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; @@ -2839,7 +2853,10 @@ elf_fix_symbol_flags (h, eif) && 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; } @@ -2877,7 +2894,10 @@ elf_adjust_dynamic_symbol (h, data) || (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. */ @@ -3162,6 +3182,7 @@ elf_link_assign_sym_version (h, data) 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. */ @@ -3276,6 +3297,7 @@ elf_link_assign_sym_version (h, data) 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. */ @@ -3300,6 +3322,7 @@ elf_link_assign_sym_version (h, data) 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. */ } @@ -5518,6 +5541,8 @@ elf_gc_sweep (info, gc_sweep_hook) elf_hash_table (info)->dynsymcount = i; } + + return true; } /* Sweep symbols in swept sections. Called via elf_link_hash_traverse. */ @@ -5777,39 +5802,43 @@ elf_gc_common_finalize_got_offsets (abfd, info) 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; } @@ -5823,7 +5852,13 @@ elf_gc_allocate_got_offsets (h, offarg) { 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; } -- 2.30.2