Fix SH2A machine variants in order to correctly select instruction inheritance
[deliverable/binutils-gdb.git] / bfd / elf32-sparc.c
index 5b8053341922b81af8bf6038da631840971410aa..1669aaa874efe7d0399b20881deae3ab4eae584c 100644 (file)
@@ -1,6 +1,6 @@
 /* SPARC-specific support for 32-bit ELF
    Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-   2003, 2004 Free Software Foundation, Inc.
+   2003, 2004, 2005 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -39,6 +39,8 @@ static bfd_boolean allocate_dynrelocs
   PARAMS ((struct elf_link_hash_entry *, PTR));
 static bfd_boolean readonly_dynrelocs
   PARAMS ((struct elf_link_hash_entry *, PTR));
+static bfd_boolean elf32_sparc_omit_section_dynsym
+  PARAMS ((bfd *, struct bfd_link_info *, asection *));
 static bfd_boolean elf32_sparc_size_dynamic_sections
   PARAMS ((bfd *, struct bfd_link_info *));
 static bfd_boolean elf32_sparc_new_section_hook
@@ -693,7 +695,7 @@ elf32_sparc_link_hash_table_create (abfd)
   struct elf32_sparc_link_hash_table *ret;
   bfd_size_type amt = sizeof (struct elf32_sparc_link_hash_table);
 
-  ret = (struct elf32_sparc_link_hash_table *) bfd_malloc (amt);
+  ret = (struct elf32_sparc_link_hash_table *) bfd_zmalloc (amt);
   if (ret == NULL)
     return NULL;
 
@@ -703,15 +705,6 @@ elf32_sparc_link_hash_table_create (abfd)
       return NULL;
     }
 
-  ret->sgot = NULL;
-  ret->srelgot = NULL;
-  ret->splt = NULL;
-  ret->srelplt = NULL;
-  ret->sdynbss = NULL;
-  ret->srelbss = NULL;
-  ret->tls_ldm_got.refcount = 0;
-  ret->sym_sec.abfd = NULL;
-
   return &ret->elf.root;
 }
 
@@ -730,15 +723,16 @@ create_got_section (dynobj, info)
 
   htab = elf32_sparc_hash_table (info);
   htab->sgot = bfd_get_section_by_name (dynobj, ".got");
-  if (!htab->sgot)
-    abort ();
+  BFD_ASSERT (htab->sgot != NULL);
 
   htab->srelgot = bfd_make_section (dynobj, ".rela.got");
   if (htab->srelgot == NULL
-      || ! bfd_set_section_flags (dynobj, htab->srelgot,
-                                 (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
-                                  | SEC_IN_MEMORY | SEC_LINKER_CREATED
-                                  | SEC_READONLY))
+      || ! bfd_set_section_flags (dynobj, htab->srelgot, SEC_ALLOC
+                                                        | SEC_LOAD
+                                                        | SEC_HAS_CONTENTS
+                                                        | SEC_IN_MEMORY
+                                                        | SEC_LINKER_CREATED
+                                                        | SEC_READONLY)
       || ! bfd_set_section_alignment (dynobj, htab->srelgot, 2))
     return FALSE;
   return TRUE;
@@ -1098,7 +1092,7 @@ elf32_sparc_check_relocs (abfd, info, sec, relocs)
              break;
            }
 
-         h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+         h->needs_plt = 1;
 
          if (ELF32_R_TYPE (rel->r_info) == R_SPARC_PLT32)
            goto r_sparc_plt32;
@@ -1108,7 +1102,7 @@ elf32_sparc_check_relocs (abfd, info, sec, relocs)
        case R_SPARC_PC10:
        case R_SPARC_PC22:
          if (h != NULL)
-           h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;
+           h->non_got_ref = 1;
 
          if (h != NULL
              && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
@@ -1132,7 +1126,7 @@ elf32_sparc_check_relocs (abfd, info, sec, relocs)
        case R_SPARC_UA16:
        case R_SPARC_UA32:
          if (h != NULL)
-           h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;
+           h->non_got_ref = 1;
 
        r_sparc_plt32:
          if (h != NULL && !info->shared)
@@ -1169,14 +1163,12 @@ elf32_sparc_check_relocs (abfd, info, sec, relocs)
                   || (h != NULL
                       && (! info->symbolic
                           || h->root.type == bfd_link_hash_defweak
-                          || (h->elf_link_hash_flags
-                              & ELF_LINK_HASH_DEF_REGULAR) == 0))))
+                          || !h->def_regular))))
              || (!info->shared
                  && (sec->flags & SEC_ALLOC) != 0
                  && h != NULL
                  && (h->root.type == bfd_link_hash_defweak
-                     || (h->elf_link_hash_flags
-                         & ELF_LINK_HASH_DEF_REGULAR) == 0)))
+                     || !h->def_regular)))
            {
              struct elf32_sparc_dyn_relocs *p;
              struct elf32_sparc_dyn_relocs **head;
@@ -1353,6 +1345,9 @@ elf32_sparc_gc_sweep_hook (abfd, info, sec, relocs)
          struct elf32_sparc_dyn_relocs *p;
 
          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+         while (h->root.type == bfd_link_hash_indirect
+                || h->root.type == bfd_link_hash_warning)
+           h = (struct elf_link_hash_entry *) h->root.u.i.link;
          eh = (struct elf32_sparc_link_hash_entry *) h;
          for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
            if (p->sec == sec)
@@ -1457,14 +1452,11 @@ elf32_sparc_adjust_dynamic_symbol (info, h)
 
   /* Make sure we know what is going on here.  */
   BFD_ASSERT (htab->elf.dynobj != NULL
-             && ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT)
-                 || h->weakdef != NULL
-                 || ((h->elf_link_hash_flags
-                      & ELF_LINK_HASH_DEF_DYNAMIC) != 0
-                     && (h->elf_link_hash_flags
-                         & ELF_LINK_HASH_REF_REGULAR) != 0
-                     && (h->elf_link_hash_flags
-                         & ELF_LINK_HASH_DEF_REGULAR) == 0)));
+             && (h->needs_plt
+                 || h->u.weakdef != NULL
+                 || (h->def_dynamic
+                     && h->ref_regular
+                     && !h->def_regular)));
 
   /* If this is a function, put it in the procedure linkage table.  We
      will fill in the contents of the procedure linkage table later
@@ -1474,7 +1466,7 @@ elf32_sparc_adjust_dynamic_symbol (info, h)
      some of their functions as STT_NOTYPE when they really should be
      STT_FUNC.  */
   if (h->type == STT_FUNC
-      || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0
+      || h->needs_plt
       || (h->type == STT_NOTYPE
          && (h->root.type == bfd_link_hash_defined
              || h->root.type == bfd_link_hash_defweak)
@@ -1482,8 +1474,8 @@ elf32_sparc_adjust_dynamic_symbol (info, h)
     {
       if (h->plt.refcount <= 0
          || (! info->shared
-             && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0
-             && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0
+             && !h->def_dynamic
+             && !h->ref_dynamic
              && h->root.type != bfd_link_hash_undefweak
              && h->root.type != bfd_link_hash_undefined))
        {
@@ -1493,7 +1485,7 @@ elf32_sparc_adjust_dynamic_symbol (info, h)
             such a case, we don't actually need to build a procedure
             linkage table, and we can just do a WDISP30 reloc instead.  */
          h->plt.offset = (bfd_vma) -1;
-         h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
+         h->needs_plt = 0;
        }
 
       return TRUE;
@@ -1504,12 +1496,12 @@ elf32_sparc_adjust_dynamic_symbol (info, h)
   /* If this is a weak symbol, and there is a real definition, the
      processor independent code will have arranged for us to see the
      real definition first, and we can just use the same value.  */
-  if (h->weakdef != NULL)
+  if (h->u.weakdef != NULL)
     {
-      BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
-                 || h->weakdef->root.type == bfd_link_hash_defweak);
-      h->root.u.def.section = h->weakdef->root.u.def.section;
-      h->root.u.def.value = h->weakdef->root.u.def.value;
+      BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+                 || h->u.weakdef->root.type == bfd_link_hash_defweak);
+      h->root.u.def.section = h->u.weakdef->root.u.def.section;
+      h->root.u.def.value = h->u.weakdef->root.u.def.value;
       return TRUE;
     }
 
@@ -1525,7 +1517,7 @@ elf32_sparc_adjust_dynamic_symbol (info, h)
 
   /* If there are no references to this symbol that do not use the
      GOT, we don't need to generate a copy reloc.  */
-  if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0)
+  if (!h->non_got_ref)
     return TRUE;
 
   eh = (struct elf32_sparc_link_hash_entry *) h;
@@ -1540,7 +1532,7 @@ elf32_sparc_adjust_dynamic_symbol (info, h)
      we'll be keeping the dynamic relocs and avoiding the copy reloc.  */
   if (p == NULL)
     {
-      h->elf_link_hash_flags &= ~ELF_LINK_NON_GOT_REF;
+      h->non_got_ref = 0;
       return TRUE;
     }
 
@@ -1561,7 +1553,7 @@ elf32_sparc_adjust_dynamic_symbol (info, h)
   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
     {
       htab->srelbss->size += sizeof (Elf32_External_Rela);
-      h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY;
+      h->needs_copy = 1;
     }
 
   /* We need to figure out the alignment required for this symbol.  I
@@ -1620,7 +1612,7 @@ allocate_dynrelocs (h, inf)
       /* Make sure this symbol is output as a dynamic symbol.
         Undefined weak syms won't yet be marked as dynamic.  */
       if (h->dynindx == -1
-         && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
+         && !h->forced_local)
        {
          if (! bfd_elf_link_record_dynamic_symbol (info, h))
            return FALSE;
@@ -1649,7 +1641,7 @@ allocate_dynrelocs (h, inf)
             pointers compare as equal between the normal executable and
             the shared library.  */
          if (! info->shared
-             && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+             && !h->def_regular)
            {
              h->root.u.def.section = s;
              h->root.u.def.value = h->plt.offset;
@@ -1664,13 +1656,13 @@ allocate_dynrelocs (h, inf)
       else
        {
          h->plt.offset = (bfd_vma) -1;
-         h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
+         h->needs_plt = 0;
        }
     }
   else
     {
       h->plt.offset = (bfd_vma) -1;
-      h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
+      h->needs_plt = 0;
     }
 
   /* If R_SPARC_TLS_IE_{HI22,LO10} symbol is now local to the binary,
@@ -1689,7 +1681,7 @@ allocate_dynrelocs (h, inf)
       /* Make sure this symbol is output as a dynamic symbol.
         Undefined weak syms won't yet be marked as dynamic.  */
       if (h->dynindx == -1
-         && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
+         && !h->forced_local)
        {
          if (! bfd_elf_link_record_dynamic_symbol (info, h))
            return FALSE;
@@ -1728,8 +1720,8 @@ allocate_dynrelocs (h, inf)
 
   if (info->shared)
     {
-      if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0
-         && ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0
+      if (h->def_regular
+         && (h->forced_local
              || info->symbolic))
        {
          struct elf32_sparc_dyn_relocs **pp;
@@ -1751,9 +1743,9 @@ allocate_dynrelocs (h, inf)
         symbols which turn out to need copy relocs or are not
         dynamic.  */
 
-      if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0
-         && (((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
-              && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+      if (!h->non_got_ref
+         && ((h->def_dynamic
+              && !h->def_regular)
              || (htab->elf.dynamic_sections_created
                  && (h->root.type == bfd_link_hash_undefweak
                      || h->root.type == bfd_link_hash_undefined))))
@@ -1761,7 +1753,7 @@ allocate_dynrelocs (h, inf)
          /* Make sure this symbol is output as a dynamic symbol.
             Undefined weak syms won't yet be marked as dynamic.  */
          if (h->dynindx == -1
-             && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
+             && !h->forced_local)
            {
              if (! bfd_elf_link_record_dynamic_symbol (info, h))
                return FALSE;
@@ -1819,6 +1811,23 @@ readonly_dynrelocs (h, inf)
   return TRUE;
 }
 
+/* Return true if the dynamic symbol for a given section should be
+   omitted when creating a shared library.  */
+
+static bfd_boolean
+elf32_sparc_omit_section_dynsym (bfd *output_bfd,
+                                struct bfd_link_info *info,
+                                asection *p)
+{
+  /* We keep the .got section symbol so that explicit relocations
+     against the _GLOBAL_OFFSET_TABLE_ symbol emitted in PIC mode
+     can be turned into relocations against the .got symbol.  */
+  if (strcmp (p->name, ".got") == 0)
+    return FALSE;
+
+  return _bfd_elf_link_omit_section_dynsym (output_bfd, info, p);
+}
+
 /* Set the sizes of the dynamic sections.  */
 
 static bfd_boolean
@@ -2229,8 +2238,8 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
                  || (info->shared
                      && (info->symbolic
                          || h->dynindx == -1
-                         || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL))
-                     && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
+                         || h->forced_local)
+                     && h->def_regular))
                {
                  /* This is actually a static link, or it is a
                     -Bsymbolic link and the symbol is defined
@@ -2378,16 +2387,13 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
                   || (h != NULL
                       && h->dynindx != -1
                       && (! info->symbolic
-                          || (h->elf_link_hash_flags
-                              & ELF_LINK_HASH_DEF_REGULAR) == 0))))
+                          || !h->def_regular))))
              || (!info->shared
                  && h != NULL
                  && h->dynindx != -1
-                 && (h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0
-                 && (((h->elf_link_hash_flags
-                       & ELF_LINK_HASH_DEF_DYNAMIC) != 0
-                      && (h->elf_link_hash_flags
-                          & ELF_LINK_HASH_DEF_REGULAR) == 0)
+                 && !h->non_got_ref
+                 && ((h->def_dynamic
+                      && !h->def_regular)
                      || h->root.type == bfd_link_hash_undefweak
                      || h->root.type == bfd_link_hash_undefined)))
            {
@@ -2452,8 +2458,7 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
                 become local.  */
              else if (h != NULL && ! is_plt
                       && ((! info->symbolic && h->dynindx != -1)
-                          || (h->elf_link_hash_flags
-                              & ELF_LINK_HASH_DEF_REGULAR) == 0))
+                          || !h->def_regular))
                {
                  BFD_ASSERT (h->dynindx != -1);
                  outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
@@ -2849,7 +2854,7 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
         not process them.  */
       if (unresolved_reloc
          && !((input_section->flags & SEC_DEBUGGING) != 0
-              && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0))
+              && h->def_dynamic))
        (*_bfd_error_handler)
          (_("%B(%A+0x%lx): unresolvable relocation against symbol `%s'"),
           input_bfd,
@@ -3023,7 +3028,7 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
                const char *name;
 
                if (h != NULL)
-                 name = h->root.root.string;
+                 name = NULL;
                else
                  {
                    name = bfd_elf_string_from_elf_section (input_bfd,
@@ -3035,8 +3040,9 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
                      name = bfd_section_name (input_bfd, sec);
                  }
                if (! ((*info->callbacks->reloc_overflow)
-                      (info, name, howto->name, (bfd_vma) 0,
-                       input_bfd, input_section, rel->r_offset)))
+                      (info, (h ? &h->root : NULL), name, howto->name,
+                       (bfd_vma) 0, input_bfd, input_section,
+                       rel->r_offset)))
                  return FALSE;
              }
              break;
@@ -3100,7 +3106,7 @@ elf32_sparc_finish_dynamic_symbol (output_bfd, info, h, sym)
       loc += (h->plt.offset / PLT_ENTRY_SIZE - 4) * sizeof (Elf32_External_Rela);
       bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
 
-      if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+      if (!h->def_regular)
        {
          /* Mark the symbol as undefined, rather than as defined in
             the .plt section.  Leave the value alone.  */
@@ -3109,8 +3115,7 @@ elf32_sparc_finish_dynamic_symbol (output_bfd, info, h, sym)
             Otherwise, the PLT entry would provide a definition for
             the symbol even if the symbol wasn't defined anywhere,
             and so the symbol would never be NULL.  */
-         if ((h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR_NONWEAK)
-             == 0)
+         if (!h->ref_regular_nonweak)
            sym->st_value = 0;
        }
     }
@@ -3142,7 +3147,7 @@ elf32_sparc_finish_dynamic_symbol (output_bfd, info, h, sym)
         initialized in the relocate_section function.  */
       if (info->shared
          && (info->symbolic || h->dynindx == -1)
-         && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
+         && h->def_regular)
        {
          asection *sec = h->root.u.def.section;
          rela.r_info = ELF32_R_INFO (0, R_SPARC_RELATIVE);
@@ -3163,7 +3168,7 @@ elf32_sparc_finish_dynamic_symbol (output_bfd, info, h, sym)
       bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
     }
 
-  if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0)
+  if (h->needs_copy)
     {
       asection *s;
       Elf_Internal_Rela rela;
@@ -3381,6 +3386,8 @@ elf32_sparc_final_write_processing (abfd, linker)
   switch (bfd_get_mach (abfd))
     {
     case bfd_mach_sparc :
+    case bfd_mach_sparc_sparclet :
+    case bfd_mach_sparc_sparclite :
       break; /* nothing to do */
     case bfd_mach_sparc_v8plus :
       elf_elfheader (abfd)->e_machine = EM_SPARC32PLUS;
@@ -3399,7 +3406,6 @@ elf32_sparc_final_write_processing (abfd, linker)
                                       | EF_SPARC_SUN_US3;
       break;
     case bfd_mach_sparc_sparclite_le :
-      elf_elfheader (abfd)->e_machine = EM_SPARC;
       elf_elfheader (abfd)->e_flags |= EF_SPARC_LEDATA;
       break;
     default :
@@ -3456,6 +3462,7 @@ elf32_sparc_plt_sym_val (bfd_vma i ATTRIBUTE_UNUSED,
 #define elf_backend_check_relocs       elf32_sparc_check_relocs
 #define elf_backend_adjust_dynamic_symbol \
                                        elf32_sparc_adjust_dynamic_symbol
+#define elf_backend_omit_section_dynsym        elf32_sparc_omit_section_dynsym
 #define elf_backend_size_dynamic_sections \
                                        elf32_sparc_size_dynamic_sections
 #define elf_backend_relocate_section   elf32_sparc_relocate_section
This page took 0.032295 seconds and 4 git commands to generate.