daily update
[deliverable/binutils-gdb.git] / bfd / elfxx-sparc.c
index 7f1bc7f00d0543fbace7c3ddefe660f01d6ae8da..e587a675d80c09ae8c92468fa2868ebd8cfcf2f6 100644 (file)
@@ -15,7 +15,7 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
 
 /* This file handles functionality common to the different SPARC ABI's.  */
 
@@ -397,7 +397,12 @@ _bfd_sparc_elf_info_to_howto_ptr (unsigned int r_type)
       return &sparc_rev32_howto;
 
     default:
-      BFD_ASSERT (r_type < (unsigned int) R_SPARC_max_std);
+      if (r_type >= (unsigned int) R_SPARC_max_std)
+       {
+         (*_bfd_error_handler) (_("invalid relocation type %d"),
+                                (int) r_type);
+         r_type = R_SPARC_NONE;
+       }
       return &_bfd_sparc_elf_howto_table[r_type];
     }
 }
@@ -500,13 +505,17 @@ sparc_put_word_64 (bfd *bfd, bfd_vma val, void *ptr)
 }
 
 static void
-sparc_elf_append_rela_64 (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
+sparc_elf_append_rela_64 (bfd *abfd ATTRIBUTE_UNUSED,
+                         asection *s ATTRIBUTE_UNUSED,
+                         Elf_Internal_Rela *rel ATTRIBUTE_UNUSED)
 {
+#ifdef BFD64
   Elf64_External_Rela *loc64;
 
   loc64 = (Elf64_External_Rela *) s->contents;
   loc64 += s->reloc_count++;
   bfd_elf64_swap_reloca_out (abfd, rel, (bfd_byte *) loc64);
+#endif
 }
 
 static void
@@ -520,7 +529,9 @@ sparc_elf_append_rela_32 (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
 }
 
 static bfd_vma
-sparc_elf_r_info_64 (Elf_Internal_Rela *in_rel, bfd_vma index, bfd_vma type)
+sparc_elf_r_info_64 (Elf_Internal_Rela *in_rel ATTRIBUTE_UNUSED,
+                    bfd_vma index ATTRIBUTE_UNUSED,
+                    bfd_vma type ATTRIBUTE_UNUSED)
 {
   return ELF64_R_INFO (index,
                       (in_rel ?
@@ -538,7 +549,8 @@ sparc_elf_r_info_32 (Elf_Internal_Rela *in_rel ATTRIBUTE_UNUSED,
 static bfd_vma
 sparc_elf_r_symndx_64 (bfd_vma r_info)
 {
-  return ELF64_R_SYM (r_info);
+  bfd_vma r_symndx = ELF32_R_SYM (r_info);
+  return (r_symndx >> 24);
 }
 
 static bfd_vma
@@ -822,14 +834,14 @@ create_got_section (bfd *dynobj, struct bfd_link_info *info)
   htab->sgot = bfd_get_section_by_name (dynobj, ".got");
   BFD_ASSERT (htab->sgot != NULL);
 
-  htab->srelgot = bfd_make_section (dynobj, ".rela.got");
+  htab->srelgot = bfd_make_section_with_flags (dynobj, ".rela.got",
+                                              SEC_ALLOC
+                                              | SEC_LOAD
+                                              | SEC_HAS_CONTENTS
+                                              | SEC_IN_MEMORY
+                                              | SEC_LINKER_CREATED
+                                              | SEC_READONLY);
   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_alignment (dynobj, htab->srelgot,
                                      htab->word_align_power))
     return FALSE;
@@ -869,7 +881,7 @@ _bfd_sparc_elf_create_dynamic_sections (bfd *dynobj,
 /* Copy the extra info we tack onto an elf_link_hash_entry.  */
 
 void
-_bfd_sparc_elf_copy_indirect_symbol (const struct elf_backend_data *bed,
+_bfd_sparc_elf_copy_indirect_symbol (struct bfd_link_info *info,
                                     struct elf_link_hash_entry *dir,
                                     struct elf_link_hash_entry *ind)
 {
@@ -885,10 +897,7 @@ _bfd_sparc_elf_copy_indirect_symbol (const struct elf_backend_data *bed,
          struct _bfd_sparc_elf_dyn_relocs **pp;
          struct _bfd_sparc_elf_dyn_relocs *p;
 
-         if (ind->root.type == bfd_link_hash_indirect)
-           abort ();
-
-         /* Add reloc counts against the weak sym to the strong sym
+         /* Add reloc counts against the indirect sym to the direct sym
             list.  Merge any entries against the same section.  */
          for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
            {
@@ -918,7 +927,7 @@ _bfd_sparc_elf_copy_indirect_symbol (const struct elf_backend_data *bed,
       edir->tls_type = eind->tls_type;
       eind->tls_type = GOT_UNKNOWN;
     }
-  _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
+  _bfd_elf_link_hash_copy_indirect (info, dir, ind);
 }
 
 static int
@@ -1012,7 +1021,12 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
       if (r_symndx < symtab_hdr->sh_info)
        h = NULL;
       else
-       h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+       {
+         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;
+       }
 
       /* Compatibility with old R_SPARC_REV32 reloc conflicting
         with R_SPARC_TLS_GD_HI22.  */
@@ -1338,13 +1352,14 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
                    {
                      flagword flags;
 
-                     sreloc = bfd_make_section (dynobj, name);
                      flags = (SEC_HAS_CONTENTS | SEC_READONLY
                               | SEC_IN_MEMORY | SEC_LINKER_CREATED);
                      if ((sec->flags & SEC_ALLOC) != 0)
                        flags |= SEC_ALLOC | SEC_LOAD;
+                     sreloc = bfd_make_section_with_flags (dynobj,
+                                                           name,
+                                                           flags);
                      if (sreloc == NULL
-                         || ! bfd_set_section_flags (dynobj, sreloc, flags)
                          || ! bfd_set_section_alignment (dynobj, sreloc,
                                                          htab->word_align_power))
                        return FALSE;
@@ -1363,13 +1378,15 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
                     easily.  Oh well.  */
 
                  asection *s;
+                 void *vpp;
+
                  s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
                                                 sec, r_symndx);
                  if (s == NULL)
                    return FALSE;
 
-                 head = ((struct _bfd_sparc_elf_dyn_relocs **)
-                         &elf_section_data (s)->local_dynrel);
+                 vpp = &elf_section_data (s)->local_dynrel;
+                 head = (struct _bfd_sparc_elf_dyn_relocs **) vpp;
                }
 
              p = *head;
@@ -1698,6 +1715,13 @@ _bfd_sparc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
       return TRUE;
     }
 
+  if (h->size == 0)
+    {
+      (*_bfd_error_handler) (_("dynamic variable `%s' is zero size"),
+                            h->root.root.string);
+      return TRUE;
+    }
+
   /* We must allocate the symbol in our .dynbss section, which will
      become part of the .bss section of the executable.  There will be
      an entry for this symbol in the .dynsym section.  The dynamic
@@ -1790,7 +1814,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, PTR inf)
          /* The procedure linkage table size is bounded by the magnitude
             of the offset we can describe in the entry.  */
          if (s->size >= (SPARC_ELF_WORD_BYTES(htab) == 8 ?
-                         (bfd_vma)1 << 32 : 0x400000))
+                         (((bfd_vma)1 << 31) << 1) : 0x400000))
            {
              bfd_set_error (bfd_error_bad_value);
              return FALSE;
@@ -2046,10 +2070,7 @@ _bfd_sparc_elf_size_dynamic_sections (bfd *output_bfd,
        {
          struct _bfd_sparc_elf_dyn_relocs *p;
 
-         for (p = *((struct _bfd_sparc_elf_dyn_relocs **)
-                    &elf_section_data (s)->local_dynrel);
-              p != NULL;
-              p = p->next)
+         for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
            {
              if (!bfd_is_abs_section (p->sec)
                  && bfd_is_abs_section (p->sec->output_section))
@@ -2134,55 +2155,54 @@ _bfd_sparc_elf_size_dynamic_sections (bfd *output_bfd,
      memory for them.  */
   for (s = dynobj->sections; s != NULL; s = s->next)
     {
-      const char *name;
-      bfd_boolean strip = FALSE;
-
       if ((s->flags & SEC_LINKER_CREATED) == 0)
        continue;
 
-      /* It's OK to base decisions on the section name, because none
-        of the dynobj section names depend upon the input files.  */
-      name = bfd_get_section_name (dynobj, s);
-
-      if (strncmp (name, ".rela", 5) == 0)
+      if (s == htab->splt
+         || s == htab->sgot
+         || s == htab->sdynbss)
        {
-         if (s->size == 0)
-           {
-             /* If we don't need this section, strip it from the
-                output file.  This is to handle .rela.bss and
-                .rel.plt.  We must create it in
-                create_dynamic_sections, because it must be created
-                before the linker maps input sections to output
-                sections.  The linker does that before
-                adjust_dynamic_symbol is called, and it is that
-                function which decides whether anything needs to go
-                into these sections.  */
-             strip = TRUE;
-           }
-         else
+         /* Strip this section if we don't need it; see the
+            comment below.  */
+       }
+      else if (strncmp (s->name, ".rela", 5) == 0)
+       {
+         if (s->size != 0)
            {
              /* We use the reloc_count field as a counter if we need
                 to copy relocs into the output file.  */
              s->reloc_count = 0;
            }
        }
-      else if (s != htab->splt && s != htab->sgot)
+      else
        {
-         /* It's not one of our sections, so don't allocate space.  */
+         /* It's not one of our sections.  */
          continue;
        }
 
-      if (strip)
+      if (s->size == 0)
        {
-         _bfd_strip_section_from_output (info, s);
+         /* If we don't need this section, strip it from the
+            output file.  This is mostly to handle .rela.bss and
+            .rela.plt.  We must create both sections in
+            create_dynamic_sections, because they must be created
+            before the linker maps input sections to output
+            sections.  The linker does that before
+            adjust_dynamic_symbol is called, and it is that
+            function which decides whether anything needs to go
+            into these sections.  */
+         s->flags |= SEC_EXCLUDE;
          continue;
        }
 
+      if ((s->flags & SEC_HAS_CONTENTS) == 0)
+       continue;
+
       /* Allocate memory for the section contents.  Zero the memory
         for the benefit of .rela.plt, which has 4 unused entries
         at the beginning, and we don't want garbage.  */
       s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
-      if (s->contents == NULL && s->size != 0)
+      if (s->contents == NULL)
        return FALSE;
     }
 
@@ -3114,10 +3134,11 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
          && !((input_section->flags & SEC_DEBUGGING) != 0
               && h->def_dynamic))
        (*_bfd_error_handler)
-         (_("%B(%A+0x%lx): unresolvable relocation against symbol `%s'"),
+         (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
           input_bfd,
           input_section,
           (long) rel->r_offset,
+          howto->name,
           h->root.root.string);
 
       r = bfd_reloc_continue;
@@ -3420,12 +3441,14 @@ _bfd_sparc_elf_finish_dynamic_symbol (bfd *output_bfd,
         thus .plt[4] has corresponding .rela.plt[0] and so on.  */
 
       loc = srela->contents;
+#ifdef BFD64
       if (ABI_64_P (output_bfd))
        {
          loc += rela_index * sizeof (Elf64_External_Rela);
          bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
        }
       else
+#endif
        {
          loc += rela_index * sizeof (Elf32_External_Rela);
          bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
@@ -3520,6 +3543,7 @@ _bfd_sparc_elf_finish_dynamic_symbol (bfd *output_bfd,
 
 /* Finish up the dynamic sections.  */
 
+#ifdef BFD64
 static bfd_boolean
 sparc64_finish_dyn (bfd *output_bfd, struct bfd_link_info *info,
                    bfd *dynobj, asection *sdyn,
@@ -3576,6 +3600,7 @@ sparc64_finish_dyn (bfd *output_bfd, struct bfd_link_info *info,
     }
   return TRUE;
 }
+#endif
 
 static bfd_boolean
 sparc32_finish_dyn (bfd *output_bfd,
@@ -3643,9 +3668,11 @@ _bfd_sparc_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *i
       splt = bfd_get_section_by_name (dynobj, ".plt");
       BFD_ASSERT (splt != NULL && sdyn != NULL);
 
+#ifdef BFD64
       if (ABI_64_P (output_bfd))
        ret = sparc64_finish_dyn (output_bfd, info, dynobj, sdyn, splt);
       else
+#endif
        ret = sparc32_finish_dyn (output_bfd, info, dynobj, sdyn, splt);
 
       if (ret != TRUE)
This page took 0.028049 seconds and 4 git commands to generate.