* elf32-vax.c (elf_vax_check_relocs): Remove unused
authorJason Thorpe <thorpej@netbsd.org>
Fri, 27 Sep 2002 22:28:17 +0000 (22:28 +0000)
committerJason Thorpe <thorpej@netbsd.org>
Fri, 27 Sep 2002 22:28:17 +0000 (22:28 +0000)
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.

bfd/ChangeLog
bfd/elf32-vax.c

index 27bff18c33909b3a401ab3b5b1d61097b07127cd..a78f22406b7fe1a23c3f261e3ff463460e60f00d 100644 (file)
@@ -1,3 +1,18 @@
+2002-09-27  Matt Thomas  <matt@3am-software.com>
+
+       * 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  <jakub@redhat.com>
 
        * reloc.c: Add x86-64 TLS relocs.
index 068578bb24575bed2f9d1020b7c2f3858463e194..64b2c40694d43a5320a942ac2eb57c5871d78cc1 100644 (file)
@@ -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,