* elf32-bfin.c (bfd_const_reloc, bfd_oper_reloc, bfin_push_reloc,
[deliverable/binutils-gdb.git] / bfd / elfxx-sparc.c
index b8b87c91284ecd4852643d9d8018fb6d85b19edf..cb5f7cbba9bf64a82144dd0b2f40482618b8fdca 100644 (file)
@@ -1,5 +1,5 @@
 /* SPARC-specific support for ELF
-   Copyright 2005 Free Software Foundation, Inc.
+   Copyright 2005, 2006 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -810,7 +810,8 @@ _bfd_sparc_elf_link_hash_table_create (bfd *abfd)
       ret->dynamic_interpreter_size = sizeof ELF32_DYNAMIC_INTERPRETER;
     }
 
-  if (! _bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc))
+  if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc,
+                                     sizeof (struct _bfd_sparc_elf_link_hash_entry)))
     {
       free (ret);
       return NULL;
@@ -881,7 +882,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)
 {
@@ -897,10 +898,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; )
            {
@@ -930,7 +928,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
@@ -1381,13 +1379,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;
@@ -1716,6 +1716,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
@@ -1929,6 +1936,24 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, PTR inf)
                pp = &p->next;
            }
        }
+
+      /* Also discard relocs on undefined weak syms with non-default
+        visibility.  */
+      if (eh->dyn_relocs != NULL
+         && h->root.type == bfd_link_hash_undefweak)
+       {
+         if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+           eh->dyn_relocs = NULL;
+
+         /* Make sure undefined weak symbols are output as a dynamic
+            symbol in PIEs.  */
+         else if (h->dynindx == -1
+                  && !h->forced_local)
+           {
+             if (! bfd_elf_link_record_dynamic_symbol (info, h))
+               return FALSE;
+           }
+       }
     }
   else
     {
@@ -2064,10 +2089,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))
@@ -3131,10 +3153,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;
@@ -3353,8 +3376,34 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
              {
                const char *name;
 
+               /* The Solaris native linker silently disregards overflows. 
+                  We don't, but this breaks stabs debugging info, whose
+                  relocations are only 32-bits wide.  Ignore overflows in
+                  this case and also for discarded entries.  */
+               if ((r_type == R_SPARC_32 || r_type == R_SPARC_DISP32)
+                   && (((input_section->flags & SEC_DEBUGGING) != 0
+                        && strcmp (bfd_section_name (input_bfd,
+                                                     input_section),
+                                   ".stab") == 0)
+                       || _bfd_elf_section_offset (output_bfd, info,
+                                                   input_section,
+                                                   rel->r_offset)
+                            == (bfd_vma)-1))
+                 break;
+
                if (h != NULL)
-                 name = NULL;
+                 {
+                   /* Assume this is a call protected by other code that
+                      detect the symbol is undefined.  If this is the case,
+                      we can safely ignore the overflow.  If not, the
+                      program is hosed anyway, and a little warning isn't
+                      going to help.  */
+                   if (h->root.type == bfd_link_hash_undefweak
+                       && howto->pc_relative)
+                     break;
+
+                   name = NULL;
+                 }
                else
                  {
                    name = bfd_elf_string_from_elf_section (input_bfd,
@@ -3530,8 +3579,8 @@ _bfd_sparc_elf_finish_dynamic_symbol (bfd *output_bfd,
 
   /* Mark some specially defined symbols as absolute.  */
   if (strcmp (h->root.root.string, "_DYNAMIC") == 0
-      || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
-      || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
+      || h == htab->elf.hgot
+      || h == htab->elf.hplt)
     sym->st_shndx = SHN_ABS;
 
   return TRUE;
This page took 0.025677 seconds and 4 git commands to generate.