* elf32-sh.c (sh_elf_relocate_section): Don't complain about
[deliverable/binutils-gdb.git] / bfd / elf32-vax.c
index ad04283b3352016853bfc7c90d00a5f13bc5b7f3..0d42b728f4093ed6d55bd3c1e3a7e11343d1039b 100644 (file)
@@ -38,7 +38,7 @@ static boolean elf_vax_check_relocs
   PARAMS ((bfd *, struct bfd_link_info *, asection *,
           const Elf_Internal_Rela *));
 static asection *elf_vax_gc_mark_hook
-  PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *,
+  PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,
           struct elf_link_hash_entry *, Elf_Internal_Sym *));
 static boolean elf_vax_gc_sweep_hook
   PARAMS ((bfd *, struct bfd_link_info *, asection *,
@@ -341,8 +341,6 @@ reloc_type_lookup (abfd, code)
 #define bfd_elf32_bfd_reloc_type_lookup reloc_type_lookup
 #define ELF_ARCH bfd_arch_vax
 /* end code generated by elf.el */
-
-#define USE_RELA
 \f
 /* Functions for the VAX ELF linker.  */
 
@@ -419,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)                  \
@@ -542,13 +545,13 @@ elf32_vax_print_private_bfd_data (abfd, ptr)
   /* xgettext:c-format */
   fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
 
-  if (elf_elfheader (abfd)->e_flags & EF_NONPIC)
+  if (elf_elfheader (abfd)->e_flags & EF_VAX_NONPIC)
     fprintf (file, _(" [nonpic]"));
 
-  if (elf_elfheader (abfd)->e_flags & EF_DFLOAT)
+  if (elf_elfheader (abfd)->e_flags & EF_VAX_DFLOAT)
     fprintf (file, _(" [d-float]"));
 
-  if (elf_elfheader (abfd)->e_flags & EF_GFLOAT)
+  if (elf_elfheader (abfd)->e_flags & EF_VAX_GFLOAT)
     fprintf (file, _(" [g-float]"));
 
   fputc ('\n', file);
@@ -569,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;
@@ -582,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;
@@ -653,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
                {
@@ -675,7 +664,7 @@ elf_vax_check_relocs (abfd, info, sec, relocs)
                              bfd_get_filename (abfd), rel->r_addend,
                              h->root.root.string,
                              eh->got_addend);
-               
+
                }
            }
          break;
@@ -855,8 +844,8 @@ elf_vax_check_relocs (abfd, info, sec, relocs)
    relocation.  */
 
 static asection *
-elf_vax_gc_mark_hook (abfd, info, rel, h, sym)
-     bfd *abfd;
+elf_vax_gc_mark_hook (sec, info, rel, h, sym)
+     asection *sec;
      struct bfd_link_info *info ATTRIBUTE_UNUSED;
      Elf_Internal_Rela *rel;
      struct elf_link_hash_entry *h;
@@ -886,15 +875,7 @@ elf_vax_gc_mark_hook (abfd, info, rel, h, sym)
        }
     }
   else
-    {
-      if (!(elf_bad_symtab (abfd)
-           && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
-         && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
-               && sym->st_shndx != SHN_COMMON))
-       {
-         return bfd_section_from_elf_index (abfd, sym->st_shndx);
-       }
-    }
+    return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
 
   return NULL;
 }
@@ -910,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++)
     {
@@ -940,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;
 
@@ -1229,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
@@ -1400,6 +1359,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
@@ -1427,6 +1440,9 @@ elf_vax_relocate_section (output_bfd, info, input_bfd, input_section,
   Elf_Internal_Rela *rel;
   Elf_Internal_Rela *relend;
 
+  if (info->relocateable)
+    return true;
+
   dynobj = elf_hash_table (info)->dynobj;
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
@@ -1458,28 +1474,8 @@ elf_vax_relocate_section (output_bfd, info, input_bfd, input_section,
        }
       howto = howto_table + r_type;
 
-      r_symndx = ELF32_R_SYM (rel->r_info);
-
-      if (info->relocateable)
-       {
-         /* This is a relocateable link.  We don't have to change
-            anything, unless the reloc is against a section symbol,
-            in which case we have to adjust according to where the
-            section symbol winds up in the output section.  */
-         if (r_symndx < symtab_hdr->sh_info)
-           {
-             sym = local_syms + r_symndx;
-             if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
-               {
-                 sec = local_sections[r_symndx];
-                 rel->r_addend += sec->output_offset + sym->st_value;
-               }
-           }
-
-         continue;
-       }
-
       /* This is a final link.  */
+      r_symndx = ELF32_R_SYM (rel->r_info);
       h = NULL;
       sym = NULL;
       sec = NULL;
@@ -1564,8 +1560,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
@@ -1574,18 +1569,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");
@@ -1595,6 +1578,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
@@ -1623,15 +1607,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;
 
@@ -1673,7 +1654,7 @@ elf_vax_relocate_section (output_bfd, info, input_bfd, input_section,
          got_offset = (plt_index + 3) * 4;
 
          /* We want the relocate to point into the .got.plt instead
-            of the plt itself. */
+            of the plt itself.  */
          relocation = (sgotplt->output_section->vma
                        + sgotplt->output_offset
                        + got_offset);
@@ -1809,7 +1790,7 @@ elf_vax_relocate_section (output_bfd, info, input_bfd, input_section,
                }
 
              if (!strcmp (bfd_get_section_name (input_bfd, input_section),
-                          ".text") != 0 || 
+                          ".text") != 0 ||
                  (info->shared
                   && ELF32_R_TYPE(outrel.r_info) != R_VAX_32
                   && ELF32_R_TYPE(outrel.r_info) != R_VAX_RELATIVE
@@ -1855,11 +1836,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,
@@ -2158,7 +2139,7 @@ elf_vax_finish_dynamic_sections (output_bfd, info)
                           + sgot->output_offset + 8
                           - (splt->output_section->vma + 12)),
                          splt->contents + 8);
-          elf_section_data (splt->output_section)->this_hdr.sh_entsize 
+          elf_section_data (splt->output_section)->this_hdr.sh_entsize
            = PLT_ENTRY_SIZE;
        }
     }
@@ -2216,5 +2197,6 @@ elf_vax_finish_dynamic_sections (output_bfd, info)
 #define elf_backend_plt_readonly       1
 #define elf_backend_want_plt_sym       0
 #define elf_backend_got_header_size    16
+#define elf_backend_rela_normal                1
 
 #include "elf32-target.h"
This page took 0.028151 seconds and 4 git commands to generate.