diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 27bff18c33..a78f22406b 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,18 @@ +2002-09-27 Matt Thomas + + * elf32-vax.c (elf_vax_check_relocs): Remove unused + local_got_refcounts usage. Remove allocation of got slot. + (elf_vax_gc_sweep_hook): Remove unused local_got_refcounts usage. + Remove de-allocation of got slot. + (elf_vax_size_dynamic_section): Fix some indentation. Add hash + traversal for elf_vax_instantiate_got_entries. Allow empty .got + sections to be GC'ed. + (elf_vax_instantiate_got_entries): New function. + (elf_vax_relocate_section): Simplify R_VAX_GOT32 handling. Remove + tests that are now handled by elf_vax_instantiate_got_entries. + Assert GOT entry falls within .got section size. Remove redundant + comparisions. Fix comments. + 2002-09-27 Jakub Jelinek * reloc.c: Add x86-64 TLS relocs. diff --git a/bfd/elf32-vax.c b/bfd/elf32-vax.c index 068578bb24..64b2c40694 100644 --- a/bfd/elf32-vax.c +++ b/bfd/elf32-vax.c @@ -417,6 +417,11 @@ struct elf_vax_link_hash_table static boolean elf_vax_discard_copies PARAMS ((struct elf_vax_link_hash_entry *, PTR)); +/* Declare this now that the above structures are defined. */ + +static boolean elf_vax_instantiate_got_entries + PARAMS ((struct elf_link_hash_entry *, PTR)); + /* Traverse an VAX ELF linker hash table. */ #define elf_vax_link_hash_traverse(table, func, info) \ @@ -567,7 +572,6 @@ elf_vax_check_relocs (abfd, info, sec, relocs) bfd *dynobj; Elf_Internal_Shdr *symtab_hdr; struct elf_link_hash_entry **sym_hashes; - bfd_signed_vma *local_got_refcounts; const Elf_Internal_Rela *rel; const Elf_Internal_Rela *rel_end; asection *sgot; @@ -580,7 +584,6 @@ elf_vax_check_relocs (abfd, info, sec, relocs) dynobj = elf_hash_table (info)->dynobj; symtab_hdr = &elf_tdata (abfd)->symtab_hdr; sym_hashes = elf_sym_hashes (abfd); - local_got_refcounts = elf_local_got_refcounts (abfd); sgot = NULL; srelgot = NULL; @@ -651,18 +654,6 @@ elf_vax_check_relocs (abfd, info, sec, relocs) { h->got.refcount = 1; eh->got_addend = rel->r_addend; - - /* Make sure this symbol is output as a dynamic symbol. */ - if (h->dynindx == -1) - { - if (!bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; - } - - /* Allocate space in the .got section. */ - sgot->_raw_size += 4; - /* Allocate relocation space. */ - srelgot->_raw_size += sizeof (Elf32_External_Rela); } else { @@ -900,25 +891,18 @@ elf_vax_gc_sweep_hook (abfd, info, sec, relocs) { Elf_Internal_Shdr *symtab_hdr; struct elf_link_hash_entry **sym_hashes; - bfd_signed_vma *local_got_refcounts; const Elf_Internal_Rela *rel, *relend; unsigned long r_symndx; struct elf_link_hash_entry *h; bfd *dynobj; - asection *sgot; - asection *srelgot; symtab_hdr = &elf_tdata (abfd)->symtab_hdr; sym_hashes = elf_sym_hashes (abfd); - local_got_refcounts = elf_local_got_refcounts (abfd); dynobj = elf_hash_table (info)->dynobj; if (dynobj == NULL) return true; - sgot = bfd_get_section_by_name (dynobj, ".got"); - srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); - relend = relocs + sec->reloc_count; for (rel = relocs; rel < relend; rel++) { @@ -930,29 +914,7 @@ elf_vax_gc_sweep_hook (abfd, info, sec, relocs) { h = sym_hashes[r_symndx - symtab_hdr->sh_info]; if (h->got.refcount > 0) - { - --h->got.refcount; - if (h->got.refcount == 0) - { - /* We don't need the .got entry any more. */ - sgot->_raw_size -= 4; - srelgot->_raw_size -= sizeof (Elf32_External_Rela); - } - } - } - else if (local_got_refcounts != NULL) - { - if (local_got_refcounts[r_symndx] > 0) - { - --local_got_refcounts[r_symndx]; - if (local_got_refcounts[r_symndx] == 0) - { - /* We don't need the .got entry any more. */ - sgot->_raw_size -= 4; - if (info->shared) - srelgot->_raw_size -= sizeof (Elf32_External_Rela); - } - } + --h->got.refcount; } break; @@ -1219,8 +1181,15 @@ elf_vax_size_dynamic_sections (output_bfd, info) fill them in in the relocate_section routine. */ if (info->shared && info->symbolic) elf_vax_link_hash_traverse (elf_vax_hash_table (info), - elf_vax_discard_copies, - (PTR) NULL); + elf_vax_discard_copies, + (PTR) NULL); + + /* If this is a -Bsymbolic shared link or a static link, we need to + discard all the got entries we've recorded. Otherwise, we need to + instantiate (allocate space for them). */ + elf_link_hash_traverse (elf_hash_table (info), + elf_vax_instantiate_got_entries, + (PTR) info); /* The check_relocs and adjust_dynamic_symbol entry points have determined the sizes of the various dynamic sections. Allocate @@ -1301,7 +1270,16 @@ elf_vax_size_dynamic_sections (output_bfd, info) s->reloc_count = 0; } } - else if (strncmp (name, ".got", 4) != 0) + else if (strncmp (name, ".got", 4) == 0) + { + if (s->_raw_size == 0) + { + /* Strip this section if we don't need it; see the + comment below. */ + strip = true; + } + } + else { /* It's not one of our sections, so don't allocate space. */ continue; @@ -1390,6 +1368,60 @@ elf_vax_discard_copies (h, ignore) return true; } +/* This function is called via elf_link_hash_traverse. It looks for entries + that have GOT or PLT (.GOT) references. If creating a static object or a + shared object with -Bsymbolic, it resets the reference count back to 0 + and sets the offset to -1 so normal PC32 relocation will be done. If + creating a shared object or executable, space in the .got and .rela.got + will be reserved for the symbol. */ + +/*ARGSUSED*/ +static boolean +elf_vax_instantiate_got_entries (h, infoptr) + struct elf_link_hash_entry *h; + PTR infoptr; +{ + struct bfd_link_info *info = (struct bfd_link_info *) infoptr; + bfd *dynobj; + asection *sgot; + asection *srelgot; + + /* We don't care about non-GOT (and non-PLT) entries. */ + if (h->got.refcount <= 0 && h->plt.refcount <= 0) + return true; + + dynobj = elf_hash_table (info)->dynobj; + if (dynobj == NULL) + return true; + + sgot = bfd_get_section_by_name (dynobj, ".got"); + srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); + + if (!elf_hash_table (info)->dynamic_sections_created + || (info->shared && info->symbolic)) + { + h->got.refcount = 0; + h->got.offset = (bfd_vma) -1; + h->plt.refcount = 0; + h->plt.offset = (bfd_vma) -1; + } + else if (h->got.refcount > 0) + { + /* Make sure this symbol is output as a dynamic symbol. */ + if (h->dynindx == -1) + { + if (!bfd_elf32_link_record_dynamic_symbol (info, h)) + return false; + } + + /* Allocate space in the .got and .rela.got sections. */ + sgot->_raw_size += 4; + srelgot->_raw_size += sizeof (Elf32_External_Rela); + } + + return true; +} + /* Relocate an VAX ELF section. */ static boolean @@ -1537,8 +1569,7 @@ elf_vax_relocate_section (output_bfd, info, input_bfd, input_section, case R_VAX_GOT32: /* Relocation is to the address of the entry for this symbol in the global offset table. */ - if (h != NULL - && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0) + if (h == NULL || h->got.offset == (bfd_vma) -1) break; /* Relocation is the offset of the entry for this symbol in @@ -1547,18 +1578,6 @@ elf_vax_relocate_section (output_bfd, info, input_bfd, input_section, { bfd_vma off; - if (!elf_hash_table (info)->dynamic_sections_created - || (h == NULL) - || (info->shared - && info->symbolic - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))) - { - /* This is actually a static link, or it is a -Bsymbolic link - and the symbol is defined locally or there is no symbol. - Change the GOT32 entry to a PC32 entry. */ - break; - } - if (sgot == NULL) { sgot = bfd_get_section_by_name (dynobj, ".got"); @@ -1568,6 +1587,7 @@ elf_vax_relocate_section (output_bfd, info, input_bfd, input_section, BFD_ASSERT (h != NULL); off = h->got.offset; BFD_ASSERT (off != (bfd_vma) -1); + BFD_ASSERT (off < sgot->_raw_size); if (info->shared && h->dynindx == -1 @@ -1596,15 +1616,12 @@ elf_vax_relocate_section (output_bfd, info, input_bfd, input_section, } relocation = sgot->output_offset + off; - /* Neither GOT relocation uses the addend. */ + /* The GOT relocation uses the addend. */ rel->r_addend = 0; - if (r_type == R_VAX_GOT32) - { - /* Change the reference to be indirect */ - contents[rel->r_offset - 1] |= 0x10; - relocation += sgot->output_section->vma; - } + /* Change the reference to be indirect. */ + contents[rel->r_offset - 1] |= 0x10; + relocation += sgot->output_section->vma; } break; @@ -1828,11 +1845,11 @@ elf_vax_relocate_section (output_bfd, info, input_bfd, input_section, break; } - /* VAX PCREL relocations are from the end of relocation, not the start */ + /* VAX PCREL relocations are from the end of relocation, not the start. + So subtract the difference from the relocation amount since we can't + add it to the offset. */ if (howto->pc_relative && howto->pcrel_offset) - { - relocation -= bfd_get_reloc_size(howto); - } + relocation -= bfd_get_reloc_size(howto); r = _bfd_final_link_relocate (howto, input_bfd, input_section, contents, rel->r_offset,