* elf-hppa.h (elf_hppa_final_link): Use elf_hppa_final_link.
[deliverable/binutils-gdb.git] / bfd / elf32-v850.c
index 26f479c9c0638f85bb520692cb89828f563f8091..8f9eda409319e8eed13fd6f47dea97dfbdb7fe4b 100644 (file)
@@ -1,12 +1,12 @@
 /* V850-specific support for 32-bit ELF
 /* V850-specific support for 32-bit ELF
-   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-   Free Software Foundation, Inc.
+   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+   2006, 2007, 2008  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
 
    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,
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
    MA 02110-1301, USA.  */
 
    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
    MA 02110-1301, USA.  */
 
+
 /* XXX FIXME: This code is littered with 32bit int, 16bit short, 8bit char
    dependencies.  As is the gas & simulator code for the v850.  */
 
 /* XXX FIXME: This code is littered with 32bit int, 16bit short, 8bit char
    dependencies.  As is the gas & simulator code for the v850.  */
 
-#include "bfd.h"
 #include "sysdep.h"
 #include "sysdep.h"
+#include "bfd.h"
 #include "bfdlink.h"
 #include "libbfd.h"
 #include "elf-bfd.h"
 #include "bfdlink.h"
 #include "libbfd.h"
 #include "elf-bfd.h"
@@ -33,6 +34,8 @@
 /* Sign-extend a 24-bit number.  */
 #define SEXT24(x)      ((((x) & 0xffffff) ^ 0x800000) - 0x800000)
 
 /* Sign-extend a 24-bit number.  */
 #define SEXT24(x)      ((((x) & 0xffffff) ^ 0x800000) - 0x800000)
 
+static reloc_howto_type v850_elf_howto_table[];
+
 /* Look through the relocs for a section during the first phase, and
    allocate space in the global offset table or procedure linkage
    table.  */
 /* Look through the relocs for a section during the first phase, and
    allocate space in the global offset table or procedure linkage
    table.  */
@@ -49,7 +52,6 @@ v850_elf_check_relocs (bfd *abfd,
   struct elf_link_hash_entry **sym_hashes;
   const Elf_Internal_Rela *rel;
   const Elf_Internal_Rela *rel_end;
   struct elf_link_hash_entry **sym_hashes;
   const Elf_Internal_Rela *rel;
   const Elf_Internal_Rela *rel_end;
-  asection *sreloc;
   enum v850_reloc_type r_type;
   int other = 0;
   const char *common = NULL;
   enum v850_reloc_type r_type;
   int other = 0;
   const char *common = NULL;
@@ -65,7 +67,6 @@ v850_elf_check_relocs (bfd *abfd,
   dynobj = elf_hash_table (info)->dynobj;
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (abfd);
   dynobj = elf_hash_table (info)->dynobj;
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (abfd);
-  sreloc = NULL;
 
   rel_end = relocs + sec->reloc_count;
   for (rel = relocs; rel < rel_end; rel++)
 
   rel_end = relocs + sec->reloc_count;
   for (rel = relocs; rel < rel_end; rel++)
@@ -113,7 +114,9 @@ v850_elf_check_relocs (bfd *abfd,
         /* This relocation describes which C++ vtable entries
           are actually used.  Record for later use during GC.  */
         case R_V850_GNU_VTENTRY:
         /* This relocation describes which C++ vtable entries
           are actually used.  Record for later use during GC.  */
         case R_V850_GNU_VTENTRY:
-          if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+          BFD_ASSERT (h != NULL);
+          if (h != NULL
+              && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
             return FALSE;
           break;
 
             return FALSE;
           break;
 
@@ -1337,6 +1340,22 @@ v850_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
 
   return NULL;
 }
 
   return NULL;
 }
+
+static reloc_howto_type *
+v850_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+                           const char *r_name)
+{
+  unsigned int i;
+
+  for (i = 0;
+       i < sizeof (v850_elf_howto_table) / sizeof (v850_elf_howto_table[0]);
+       i++)
+    if (v850_elf_howto_table[i].name != NULL
+       && strcasecmp (v850_elf_howto_table[i].name, r_name) == 0)
+      return &v850_elf_howto_table[i];
+
+  return NULL;
+}
 \f
 /* Set the howto pointer for an V850 ELF reloc.  */
 
 \f
 /* Set the howto pointer for an V850 ELF reloc.  */
 
@@ -1565,9 +1584,6 @@ v850_elf_relocate_section (bfd *output_bfd,
   Elf_Internal_Rela *rel;
   Elf_Internal_Rela *relend;
 
   Elf_Internal_Rela *rel;
   Elf_Internal_Rela *relend;
 
-  if (info->relocatable)
-    return TRUE;
-
   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
 
   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
 
@@ -1596,7 +1612,6 @@ v850_elf_relocate_section (bfd *output_bfd,
           || r_type == R_V850_GNU_VTINHERIT)
         continue;
 
           || r_type == R_V850_GNU_VTINHERIT)
         continue;
 
-      /* This is a final link.  */
       howto = v850_elf_howto_table + r_type;
       h = NULL;
       sym = NULL;
       howto = v850_elf_howto_table + r_type;
       h = NULL;
       sym = NULL;
@@ -1629,6 +1644,20 @@ v850_elf_relocate_section (bfd *output_bfd,
                                   unresolved_reloc, warned);
        }
 
                                   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;
+
       /* FIXME: We should use the addend, but the COFF relocations don't.  */
       r = v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
                                        input_section,
       /* FIXME: We should use the addend, but the COFF relocations don't.  */
       r = v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
                                        input_section,
@@ -1709,50 +1738,22 @@ v850_elf_relocate_section (bfd *output_bfd,
   return TRUE;
 }
 
   return TRUE;
 }
 
-static bfd_boolean
-v850_elf_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)
-{
-  /* No got and plt entries for v850-elf.  */
-  return TRUE;
-}
-
 static asection *
 v850_elf_gc_mark_hook (asection *sec,
 static asection *
 v850_elf_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)
                       Elf_Internal_Rela *rel,
                       struct elf_link_hash_entry *h,
                       Elf_Internal_Sym *sym)
 {
   if (h != NULL)
-    {
-      switch (ELF32_R_TYPE (rel->r_info))
+    switch (ELF32_R_TYPE (rel->r_info))
       {
       case R_V850_GNU_VTINHERIT:
       case R_V850_GNU_VTENTRY:
       {
       case R_V850_GNU_VTINHERIT:
       case R_V850_GNU_VTENTRY:
-        break;
-
-      default:
-        switch (h->root.type)
-          {
-          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;
-
-         default:
-           break;
-          }
-       }
-     }
-   else
-     return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
+       return NULL;
+      }
 
 
-  return NULL;
+  return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
 }
 
 /* Set the right machine number.  */
 }
 
 /* Set the right machine number.  */
@@ -2115,6 +2116,12 @@ v850_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
        sym->st_shndx = SHN_V850_ZCOMMON;
     }
 
        sym->st_shndx = SHN_V850_ZCOMMON;
     }
 
+  /* The price we pay for using h->other unused bits as flags in the
+     linker is cleaning up after ourselves.  */
+
+  sym->st_other &= ~(V850_OTHER_SDA | V850_OTHER_ZDA | V850_OTHER_TDA
+                    | V850_OTHER_ERROR);
+
   return TRUE;
 }
 
   return TRUE;
 }
 
@@ -3024,54 +3031,35 @@ v850_elf_relax_section (bfd *abfd,
   goto finish;
 }
 
   goto finish;
 }
 
-static struct bfd_elf_special_section const v850_elf_special_sections[] =
+static const struct bfd_elf_special_section v850_elf_special_sections[] =
 {
 {
-  { ".call_table_data", 16,  0, SHT_PROGBITS,     (SHF_ALLOC
-                                                   + SHF_WRITE) },
-  { ".call_table_text", 16,  0, SHT_PROGBITS,     (SHF_ALLOC + SHF_WRITE
-                                                   + SHF_EXECINSTR) },
-  { ".rosdata",          8, -2, SHT_PROGBITS,     (SHF_ALLOC
-                                                   + SHF_V850_GPREL) },
-  { ".rozdata",          8, -2, SHT_PROGBITS,     (SHF_ALLOC
-                                                   + SHF_V850_R0REL) },
-  { ".sbss",             5, -2, SHT_NOBITS,       (SHF_ALLOC + SHF_WRITE
-                                                   + SHF_V850_GPREL) },
-  { ".scommon",          8, -2, SHT_V850_SCOMMON, (SHF_ALLOC + SHF_WRITE
-                                                   + SHF_V850_GPREL) },
-  { ".sdata",            6, -2, SHT_PROGBITS,     (SHF_ALLOC + SHF_WRITE
-                                                   + SHF_V850_GPREL) },
-  { ".tbss",             5, -2, SHT_NOBITS,       (SHF_ALLOC + SHF_WRITE
-                                                   + SHF_V850_EPREL) },
-  { ".tcommon",          8, -2, SHT_V850_TCOMMON, (SHF_ALLOC + SHF_WRITE
-                                                   + SHF_V850_R0REL) },
-  { ".tdata",            6, -2, SHT_PROGBITS,     (SHF_ALLOC + SHF_WRITE
-                                                   + SHF_V850_EPREL) },
-  { ".zbss",             5, -2, SHT_NOBITS,       (SHF_ALLOC + SHF_WRITE
-                                                   + SHF_V850_R0REL) },
-  { ".zcommon",          8, -2, SHT_V850_ZCOMMON, (SHF_ALLOC + SHF_WRITE
-                                                   + SHF_V850_R0REL) },
-  { ".zdata",            6, -2, SHT_PROGBITS,     (SHF_ALLOC + SHF_WRITE
-                                                   + SHF_V850_R0REL) },
-  { NULL,        0, 0, 0,            0 }
+  { STRING_COMMA_LEN (".call_table_data"), 0, SHT_PROGBITS,     (SHF_ALLOC + SHF_WRITE) },
+  { STRING_COMMA_LEN (".call_table_text"), 0, SHT_PROGBITS,     (SHF_ALLOC + SHF_WRITE
+                                                                + SHF_EXECINSTR) },
+  { STRING_COMMA_LEN (".rosdata"),        -2, SHT_PROGBITS,     (SHF_ALLOC
+                                                                + SHF_V850_GPREL) },
+  { STRING_COMMA_LEN (".rozdata"),        -2, SHT_PROGBITS,     (SHF_ALLOC
+                                                                + SHF_V850_R0REL) },
+  { STRING_COMMA_LEN (".sbss"),           -2, SHT_NOBITS,       (SHF_ALLOC + SHF_WRITE
+                                                                + SHF_V850_GPREL) },
+  { STRING_COMMA_LEN (".scommon"),        -2, SHT_V850_SCOMMON, (SHF_ALLOC + SHF_WRITE
+                                                                + SHF_V850_GPREL) },
+  { STRING_COMMA_LEN (".sdata"),          -2, SHT_PROGBITS,     (SHF_ALLOC + SHF_WRITE
+                                                                + SHF_V850_GPREL) },
+  { STRING_COMMA_LEN (".tbss"),           -2, SHT_NOBITS,       (SHF_ALLOC + SHF_WRITE
+                                                                + SHF_V850_EPREL) },
+  { STRING_COMMA_LEN (".tcommon"),        -2, SHT_V850_TCOMMON, (SHF_ALLOC + SHF_WRITE
+                                                                + SHF_V850_R0REL) },
+  { STRING_COMMA_LEN (".tdata"),          -2, SHT_PROGBITS,     (SHF_ALLOC + SHF_WRITE
+                                                                + SHF_V850_EPREL) },
+  { STRING_COMMA_LEN (".zbss"),           -2, SHT_NOBITS,       (SHF_ALLOC + SHF_WRITE
+                                                                + SHF_V850_R0REL) },
+  { STRING_COMMA_LEN (".zcommon"),        -2, SHT_V850_ZCOMMON, (SHF_ALLOC + SHF_WRITE
+                                                                + SHF_V850_R0REL) },
+  { STRING_COMMA_LEN (".zdata"),          -2, SHT_PROGBITS,     (SHF_ALLOC + SHF_WRITE
+                                                                + SHF_V850_R0REL) },
+  { NULL,                     0,           0, 0,                0 }
 };
 };
-
-static const struct bfd_elf_special_section *
-v850_elf_get_sec_type_attr (bfd *abfd, asection *sec)
-{
-  const struct bfd_elf_special_section const *ssect;
-
-  /* See if this is one of the special sections.  */
-  if (sec->name == NULL)
-    return NULL;
-
-  ssect = _bfd_elf_get_special_section (sec->name,
-                                       v850_elf_special_sections,
-                                       sec->use_rela_p);
-  if (ssect != NULL)
-    return ssect;
-
-  return _bfd_elf_get_sec_type_attr (abfd, sec);
-}
 \f
 #define TARGET_LITTLE_SYM                      bfd_elf32_v850_vec
 #define TARGET_LITTLE_NAME                     "elf32-v850"
 \f
 #define TARGET_LITTLE_SYM                      bfd_elf32_v850_vec
 #define TARGET_LITTLE_NAME                     "elf32-v850"
@@ -3095,14 +3083,14 @@ v850_elf_get_sec_type_attr (bfd *abfd, asection *sec)
 #define elf_backend_section_from_shdr          v850_elf_section_from_shdr
 #define elf_backend_fake_sections              v850_elf_fake_sections
 #define elf_backend_gc_mark_hook                v850_elf_gc_mark_hook
 #define elf_backend_section_from_shdr          v850_elf_section_from_shdr
 #define elf_backend_fake_sections              v850_elf_fake_sections
 #define elf_backend_gc_mark_hook                v850_elf_gc_mark_hook
-#define elf_backend_gc_sweep_hook               v850_elf_gc_sweep_hook
-#define elf_backend_get_sec_type_attr          v850_elf_get_sec_type_attr
+#define elf_backend_special_sections           v850_elf_special_sections
 
 #define elf_backend_can_gc_sections 1
 #define elf_backend_rela_normal 1
 
 #define bfd_elf32_bfd_is_local_label_name      v850_elf_is_local_label_name
 #define bfd_elf32_bfd_reloc_type_lookup                v850_elf_reloc_type_lookup
 
 #define elf_backend_can_gc_sections 1
 #define elf_backend_rela_normal 1
 
 #define bfd_elf32_bfd_is_local_label_name      v850_elf_is_local_label_name
 #define bfd_elf32_bfd_reloc_type_lookup                v850_elf_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup        v850_elf_reloc_name_lookup
 #define bfd_elf32_bfd_merge_private_bfd_data   v850_elf_merge_private_bfd_data
 #define bfd_elf32_bfd_set_private_flags                v850_elf_set_private_flags
 #define bfd_elf32_bfd_print_private_bfd_data   v850_elf_print_private_bfd_data
 #define bfd_elf32_bfd_merge_private_bfd_data   v850_elf_merge_private_bfd_data
 #define bfd_elf32_bfd_set_private_flags                v850_elf_set_private_flags
 #define bfd_elf32_bfd_print_private_bfd_data   v850_elf_print_private_bfd_data
This page took 0.027142 seconds and 4 git commands to generate.