daily update
[deliverable/binutils-gdb.git] / bfd / elf32-cris.c
index 06865dcc2e2251d417294b29aa5d7643b9159a49..199ee1b4bffad10799f35a4d42c6d9c6a52d35fc 100644 (file)
@@ -1,5 +1,5 @@
 /* CRIS-specific support for 32-bit ELF.
-   Copyright 2000, 2001, 2002, 2003, 2004, 2005
+   Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
    Contributed by Axis Communications AB.
    Written by Hans-Peter Nilsson, based on elf32-fr30.c
@@ -51,14 +51,6 @@ static bfd_reloc_status_type cris_final_link_relocate
   PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *,
           Elf_Internal_Rela *, bfd_vma));
 
-static bfd_boolean cris_elf_gc_sweep_hook
-  PARAMS ((bfd *, struct bfd_link_info *, asection *,
-          const Elf_Internal_Rela *));
-
-static asection * cris_elf_gc_mark_hook
-  PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,
-          struct elf_link_hash_entry *, Elf_Internal_Sym *));
-
 static bfd_boolean cris_elf_object_p PARAMS ((bfd *));
 
 static void cris_elf_final_write_processing PARAMS ((bfd *, bfd_boolean));
@@ -849,8 +841,9 @@ elf_cris_link_hash_table_create (abfd)
   if (ret == (struct elf_cris_link_hash_table *) NULL)
     return NULL;
 
-  if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
-                                      elf_cris_link_hash_newfunc))
+  if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
+                                     elf_cris_link_hash_newfunc,
+                                     sizeof (struct elf_cris_link_hash_entry)))
     {
       free (ret);
       return NULL;
@@ -1387,7 +1380,7 @@ cris_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                  if (name == NULL)
                    return FALSE;
 
-                 BFD_ASSERT (strncmp (name, ".rela", 5) == 0
+                 BFD_ASSERT (CONST_STRNEQ (name, ".rela")
                              && strcmp (bfd_get_section_name (input_bfd,
                                                               input_section),
                                         name + 5) == 0);
@@ -1437,11 +1430,12 @@ cris_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                }
              else
                {
+                 outrel.r_addend = relocation + rel->r_addend;
+
                  if (r_type == R_CRIS_32)
                    {
                      relocate = TRUE;
                      outrel.r_info = ELF32_R_INFO (0, R_CRIS_RELATIVE);
-                     outrel.r_addend = relocation + rel->r_addend;
                    }
                  else
                    {
@@ -1458,13 +1452,24 @@ cris_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                        {
                          asection *osec;
 
+                         /* We are turning this relocation into one
+                            against a section symbol.  It would be
+                            proper to subtract the symbol's value,
+                            osec->vma, from the emitted reloc addend,
+                            but ld.so expects buggy relocs.  */
                          osec = sec->output_section;
                          indx = elf_section_data (osec)->dynindx;
-                         BFD_ASSERT (indx > 0);
+                         if (indx == 0)
+                           {
+                             struct elf_cris_link_hash_table *htab;
+                             htab = elf_cris_hash_table (info);
+                             osec = htab->root.text_index_section;
+                             indx = elf_section_data (osec)->dynindx;
+                           }
+                         BFD_ASSERT (indx != 0);
                        }
 
                      outrel.r_info = ELF32_R_INFO (indx, r_type);
-                     outrel.r_addend = relocation + rel->r_addend;
                    }
                }
 
@@ -1769,7 +1774,7 @@ elf_cris_finish_dynamic_symbol (output_bfd, info, h, sym)
 
   /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
   if (strcmp (h->root.root.string, "_DYNAMIC") == 0
-      || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+      || h == elf_hash_table (info)->hgot)
     sym->st_shndx = SHN_ABS;
 
   return TRUE;
@@ -1922,50 +1927,30 @@ elf_cris_finish_dynamic_sections (output_bfd, info)
    relocation.  */
 
 static asection *
-cris_elf_gc_mark_hook (sec, info, rel, h, sym)
-     asection *sec;
-     struct bfd_link_info *info ATTRIBUTE_UNUSED;
-     Elf_Internal_Rela *rel;
-     struct elf_link_hash_entry *h;
-     Elf_Internal_Sym *sym;
+cris_elf_gc_mark_hook (asection *sec,
+                      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_CRIS_GNU_VTINHERIT:
-       case R_CRIS_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);
+    switch (ELF32_R_TYPE (rel->r_info))
+      {
+      case R_CRIS_GNU_VTINHERIT:
+      case R_CRIS_GNU_VTENTRY:
+       return NULL;
+      }
 
-  return NULL;
+  return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
 }
 
 /* Update the got entry reference counts for the section being removed.  */
 
 static bfd_boolean
-cris_elf_gc_sweep_hook (abfd, info, sec, relocs)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     struct bfd_link_info *info ATTRIBUTE_UNUSED;
-     asection *sec ATTRIBUTE_UNUSED;
-     const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;
+cris_elf_gc_sweep_hook (bfd *abfd,
+                       struct bfd_link_info *info,
+                       asection *sec,
+                       const Elf_Internal_Rela *relocs)
 {
   Elf_Internal_Shdr *symtab_hdr;
   struct elf_link_hash_entry **sym_hashes;
@@ -2798,7 +2783,7 @@ cris_elf_check_relocs (abfd, info, sec, relocs)
              if (name == NULL)
                return FALSE;
 
-             BFD_ASSERT (strncmp (name, ".rela", 5) == 0
+             BFD_ASSERT (CONST_STRNEQ (name, ".rela")
                          && strcmp (bfd_get_section_name (abfd, sec),
                                     name + 5) == 0);
 
@@ -2961,7 +2946,7 @@ elf_cris_size_dynamic_sections (output_bfd, info)
          /* Remember whether there is a PLT.  */
          plt = s->size != 0;
        }
-      else if (strncmp (name, ".rela", 5) == 0)
+      else if (CONST_STRNEQ (name, ".rela"))
        {
          if (s->size != 0)
            {
@@ -2975,7 +2960,7 @@ elf_cris_size_dynamic_sections (output_bfd, info)
              s->reloc_count = 0;
            }
        }
-      else if (strncmp (name, ".got", 4) != 0
+      else if (! CONST_STRNEQ (name, ".got")
               && strcmp (name, ".dynbss") != 0)
        {
          /* It's not one of our sections, so don't allocate space.  */
@@ -3417,6 +3402,7 @@ elf_cris_reloc_type_class (rela)
        elf_cris_adjust_dynamic_symbol
 #define elf_backend_size_dynamic_sections \
        elf_cris_size_dynamic_sections
+#define elf_backend_init_index_section         _bfd_elf_init_1_index_section
 #define elf_backend_finish_dynamic_symbol \
        elf_cris_finish_dynamic_symbol
 #define elf_backend_finish_dynamic_sections \
This page took 0.026447 seconds and 4 git commands to generate.