daily update
[deliverable/binutils-gdb.git] / bfd / elf32-bfin.c
index 6ceaeb0e089b2d0c48fcae50bdc4a03e2b07f71f..f3d94804ea90363e000ff6cfca413f8696c35c2b 100644 (file)
@@ -1,11 +1,11 @@
 /* ADI Blackfin BFD support for 32-bit ELF.
-   Copyright 2005, 2006 Free Software Foundation, Inc.
+   Copyright 2005, 2006, 2007 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
 
    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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
-   USA.  */
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
 
-#include "bfd.h"
 #include "sysdep.h"
+#include "bfd.h"
 #include "libbfd.h"
 #include "elf-bfd.h"
 #include "elf/bfin.h"
@@ -1057,8 +1057,8 @@ bfin_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
 
   else
     cache_ptr->howto = (reloc_howto_type *) NULL;
-
 }
+
 /* Given a BFD reloc type, return the howto.  */
 static reloc_howto_type *
 bfin_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
@@ -1078,8 +1078,33 @@ bfin_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
    return &bfin_gnuext_howto_table [r_type - BFIN_GNUEXT_RELOC_MIN];
 
   return (reloc_howto_type *) NULL;
+}
 
+static reloc_howto_type *
+bfin_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+                           const char *r_name)
+{
+  unsigned int i;
+
+  for (i = 0;
+       i < (sizeof (bfin_howto_table)
+           / sizeof (bfin_howto_table[0]));
+       i++)
+    if (bfin_howto_table[i].name != NULL
+       && strcasecmp (bfin_howto_table[i].name, r_name) == 0)
+      return &bfin_howto_table[i];
+
+  for (i = 0;
+       i < (sizeof (bfin_gnuext_howto_table)
+           / sizeof (bfin_gnuext_howto_table[0]));
+       i++)
+    if (bfin_gnuext_howto_table[i].name != NULL
+       && strcasecmp (bfin_gnuext_howto_table[i].name, r_name) == 0)
+      return &bfin_gnuext_howto_table[i];
+
+  return NULL;
 }
+
 /* Given a bfin relocation type, return the howto.  */
 static reloc_howto_type *
 bfin_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
@@ -1092,7 +1117,6 @@ bfin_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
    return &bfin_gnuext_howto_table [r_type - BFIN_GNUEXT_RELOC_MIN];
 
   return (reloc_howto_type *) NULL;
-
 }
 
 /* Return TRUE if the name is a local label.
@@ -2109,9 +2133,6 @@ bfinfdpic_relocate_section (bfd * output_bfd,
     check_segment[2];
   int silence_segment_error = !(info->shared || info->pie);
 
-  if (info->relocatable)
-    return TRUE;
-
   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
   relend     = relocs + input_section->reloc_count;
@@ -2152,7 +2173,6 @@ bfinfdpic_relocate_section (bfd * output_bfd,
          || r_type == R_BFIN_GNU_VTENTRY)
        continue;
 
-      /* This is a final link.  */
       r_symndx = ELF32_R_SYM (rel->r_info);
       howto = bfin_reloc_type_lookup (input_bfd, r_type);
       if (howto == NULL)
@@ -2177,48 +2197,37 @@ bfinfdpic_relocate_section (bfd * output_bfd,
        }
       else
        {
-         h = sym_hashes [r_symndx - symtab_hdr->sh_info];
+         bfd_boolean warned;
+         bfd_boolean unresolved_reloc;
 
-         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;
+         RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+                                  r_symndx, symtab_hdr, sym_hashes,
+                                  h, sec, relocation,
+                                  unresolved_reloc, warned);
+         osec = sec;
+       }
 
-         name = h->root.root.string;
+      if (sec != NULL && elf_discarded_section (sec))
+       {
+         /* For relocs against symbols from removed linkonce sections,
+            or sections discarded by a linker script, we just want the
+            section contents zeroed.  Avoid any special processing.  */
+         _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+         rel->r_info = 0;
+         rel->r_addend = 0;
+         continue;
+       }
 
-         if ((h->root.type == bfd_link_hash_defined
-              || h->root.type == bfd_link_hash_defweak)
-             && ! BFINFDPIC_SYM_LOCAL (info, h))
-           {
-             sec = NULL;
-             relocation = 0;
-           }
-         else
-           if (h->root.type == bfd_link_hash_defined
-               || h->root.type == bfd_link_hash_defweak)
-             {
-               sec = h->root.u.def.section;
-               relocation = (h->root.u.def.value
-                             + sec->output_section->vma
-                             + sec->output_offset);
-             }
-           else if (h->root.type == bfd_link_hash_undefweak)
-             {
-               relocation = 0;
-             }
-           else if (info->unresolved_syms_in_objects == RM_IGNORE
-                    && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
-             relocation = 0;
-           else
-             {
-               if (! ((*info->callbacks->undefined_symbol)
-                      (info, h->root.root.string, input_bfd,
-                       input_section, rel->r_offset,
-                       (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
-                        || ELF_ST_VISIBILITY (h->other)))))
-                 return FALSE;
-               relocation = 0;
-             }
-         osec = sec;
+      if (info->relocatable)
+       continue;
+
+      if (h != NULL
+         && (h->root.type == bfd_link_hash_defined
+             || h->root.type == bfd_link_hash_defweak)
+         && !BFINFDPIC_SYM_LOCAL (info, h))
+       {
+         osec = sec = NULL;
+         relocation = 0;
        }
 
       switch (r_type)
@@ -2831,9 +2840,6 @@ bfin_relocate_section (bfd * output_bfd,
   Elf_Internal_Rela *relend;
   int i = 0;
 
-  if (info->relocatable)
-    return TRUE;
-
   dynobj = elf_hash_table (info)->dynobj;
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
@@ -2890,13 +2896,27 @@ bfin_relocate_section (bfd * output_bfd,
       else
        {
          bfd_boolean warned;
-         h = NULL;
+
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
                                   r_symndx, symtab_hdr, sym_hashes,
                                   h, sec, relocation,
                                   unresolved_reloc, warned);
        }
 
+      if (sec != NULL && elf_discarded_section (sec))
+       {
+         /* For relocs against symbols from removed linkonce sections,
+            or sections discarded by a linker script, we just want the
+            section contents zeroed.  Avoid any special processing.  */
+         _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+         rel->r_info = 0;
+         rel->r_addend = 0;
+         continue;
+       }
+
+      if (info->relocatable)
+       continue;
+
       address = rel->r_offset;
 
       /* Then, process normally.  */
@@ -3106,51 +3126,20 @@ bfin_relocate_section (bfd * output_bfd,
 
 static asection *
 bfin_gc_mark_hook (asection * sec,
-                  struct bfd_link_info *info ATTRIBUTE_UNUSED,
+                  struct bfd_link_info *info,
                   Elf_Internal_Rela * rel,
                   struct elf_link_hash_entry *h,
                    Elf_Internal_Sym * sym)
 {
   if (h != NULL)
-    {
-      switch (ELF32_R_TYPE (rel->r_info))
-       {
-
-       case R_BFIN_GNU_VTINHERIT:
-       case R_BFIN_GNU_VTENTRY:
-         break;
-
-       default:
-         switch (h->root.type)
-           {
-           default:
-             break;
-
-           case bfd_link_hash_defined:
-           case bfd_link_hash_defweak:
-             return h->root.u.def.section;
-
-           case bfd_link_hash_common:
-             return h->root.u.c.p->section;
-           }
-       }
-    }
-  else
-    return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
-
-  return NULL;
-}
-
-
-/* Update the got entry reference counts for the section being removed.  */
+    switch (ELF32_R_TYPE (rel->r_info))
+      {
+      case R_BFIN_GNU_VTINHERIT:
+      case R_BFIN_GNU_VTENTRY:
+       return NULL;
+      }
 
-static bfd_boolean
-bfinfdpic_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED,
-                        struct bfd_link_info *info ATTRIBUTE_UNUSED,
-                        asection *sec ATTRIBUTE_UNUSED,
-                        const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED)
-{
-  return TRUE;
+  return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
 }
 
 /* Update the got entry reference counts for the section being removed.  */
@@ -4736,6 +4725,10 @@ bfin_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
 
   elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
   elf_flags_init (obfd) = TRUE;
+
+  /* Copy object attributes.  */
+  _bfd_elf_copy_obj_attributes (ibfd, obfd);
+
   return TRUE;
 }
 
@@ -5510,6 +5503,8 @@ error_return:
 #define elf_symbol_leading_char                '_'
 
 #define bfd_elf32_bfd_reloc_type_lookup        bfin_bfd_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup \
+                                       bfin_bfd_reloc_name_lookup
 #define elf_info_to_howto              bfin_info_to_howto
 #define elf_info_to_howto_rel          0
 #define elf_backend_object_p           elf32_bfin_object_p
@@ -5564,7 +5559,6 @@ error_return:
 #define        elf32_bed               elf32_bfinfdpic_bed
 
 #undef elf_backend_gc_sweep_hook
-#define elf_backend_gc_sweep_hook       bfinfdpic_gc_sweep_hook
 
 #undef elf_backend_got_header_size
 #define elf_backend_got_header_size     0
This page took 0.026428 seconds and 4 git commands to generate.