* elf32-bfin.c (bfd_const_reloc, bfd_oper_reloc, bfin_push_reloc,
[deliverable/binutils-gdb.git] / bfd / elfxx-sparc.c
index eff34eadf04dcb7b3757f8595aabd5beabbf89f6..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
@@ -1938,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
     {
@@ -3360,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,
@@ -3537,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.024527 seconds and 4 git commands to generate.