* elf-bfd.h (_bfd_elf_section_from_bfd_section): Update prototype.
[deliverable/binutils-gdb.git] / bfd / elf32-xtensa.c
index a1c608872fe4676e6c00cd343a6777b9069ef675..0d744c220e1035e3618ff619bed936cad9eb64b7 100644 (file)
@@ -1,5 +1,5 @@
 /* Xtensa-specific support for 32-bit ELF.
-   Copyright 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+   Copyright 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -1012,6 +1012,9 @@ elf_xtensa_gc_sweep_hook (bfd *abfd,
   bfd_signed_vma *local_got_refcounts;
   const Elf_Internal_Rela *rel, *relend;
 
+  if (info->relocatable)
+    return TRUE;
+
   if ((sec->flags & SEC_ALLOC) == 0)
     return TRUE;
 
@@ -1755,12 +1758,15 @@ vsprint_msg (const char *origmsg, const char *fmt, int arglen, ...)
   len = orig_len + strlen (fmt) + arglen + 20;
   if (len > alloc_size)
     {
-      message = (char *) bfd_realloc (message, len);
+      message = (char *) bfd_realloc_or_free (message, len);
       alloc_size = len;
     }
-  if (!is_append)
-    memcpy (message, origmsg, orig_len);
-  vsprintf (message + orig_len, fmt, ap);
+  if (message != NULL)
+    {
+      if (!is_append)
+       memcpy (message, origmsg, orig_len);
+      vsprintf (message + orig_len, fmt, ap);
+    }
   VA_CLOSE (ap);
   return message;
 }
@@ -2161,6 +2167,7 @@ elf_xtensa_relocate_section (bfd *output_bfd,
                    (info, error_message, input_bfd, input_section,
                     rel->r_offset)))
                return FALSE;
+             continue;
            }
          else if ((r_type == R_XTENSA_32 || r_type == R_XTENSA_PLT)
                   && (input_section->flags & SEC_ALLOC) != 0
@@ -2241,6 +2248,13 @@ elf_xtensa_relocate_section (bfd *output_bfd,
              BFD_ASSERT (sizeof (Elf32_External_Rela) * srel->reloc_count
                          <= srel->size);
            }
+         else if (r_type == R_XTENSA_ASM_EXPAND && dynamic_symbol)
+           {
+             /* This should only happen for non-PIC code, which is not
+                supposed to be used on systems with dynamic linking.
+                Just ignore these relocations.  */
+             continue;
+           }
        }
 
       /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
@@ -2464,7 +2478,7 @@ elf_xtensa_finish_dynamic_sections (bfd *output_bfd,
   bfd *dynobj;
   asection *sdyn, *srelplt, *sgot, *sxtlit, *sgotloc;
   Elf32_External_Dyn *dyncon, *dynconend;
-  int num_xtlit_entries;
+  int num_xtlit_entries = 0;
 
   if (! elf_hash_table (info)->dynamic_sections_created)
     return TRUE;
@@ -2589,11 +2603,14 @@ elf_xtensa_finish_dynamic_sections (bfd *output_bfd,
   BFD_ASSERT (! info->relocatable);
   sxtlit = bfd_get_section_by_name (output_bfd, ".xt.lit");
   sgotloc = htab->sgotloc;
-  BFD_ASSERT (sxtlit && sgotloc);
-  num_xtlit_entries =
-    elf_xtensa_combine_prop_entries (output_bfd, sxtlit, sgotloc);
-  if (num_xtlit_entries < 0)
-    return FALSE;
+  BFD_ASSERT (sgotloc);
+  if (sxtlit)
+    {
+      num_xtlit_entries =
+       elf_xtensa_combine_prop_entries (output_bfd, sxtlit, sgotloc);
+      if (num_xtlit_entries < 0)
+       return FALSE;
+    }
 
   dyncon = (Elf32_External_Dyn *) sdyn->contents;
   dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
@@ -8240,30 +8257,28 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info)
 
                  pin_contents (sec, contents);
                }
+
+             /* If the relocation still references a section in the same
+                input file, modify the relocation directly instead of
+                adding a "fix" record.  */
+             if (target_sec->owner == abfd)
+               {
+                 unsigned r_symndx = ELF32_R_SYM (new_reloc.rela.r_info);
+                 irel->r_info = ELF32_R_INFO (r_symndx, r_type);
+                 irel->r_addend = new_reloc.rela.r_addend;
+                 pin_internal_relocs (sec, internal_relocs);
+               }
              else
                {
-                 /* If the relocation still references a section in the same
-                    input file, modify the relocation directly instead of
-                    adding a "fix" record.  */
-                 if (target_sec->owner == abfd)
-                   {
-                     unsigned r_symndx = ELF32_R_SYM (new_reloc.rela.r_info);
-                     irel->r_info = ELF32_R_INFO (r_symndx, r_type);
-                     irel->r_addend = new_reloc.rela.r_addend;
-                     pin_internal_relocs (sec, internal_relocs);
-                   }
-                 else
-                   {
-                     bfd_vma addend_displacement;
-                     reloc_bfd_fix *fix;
-
-                     addend_displacement =
-                       new_reloc.target_offset + new_reloc.virtual_offset;
-                     fix = reloc_bfd_fix_init (sec, source_offset, r_type,
-                                               target_sec,
-                                               addend_displacement, TRUE);
-                     add_fix (sec, fix);
-                   }
+                 bfd_vma addend_displacement;
+                 reloc_bfd_fix *fix;
+
+                 addend_displacement =
+                   new_reloc.target_offset + new_reloc.virtual_offset;
+                 fix = reloc_bfd_fix_init (sec, source_offset, r_type,
+                                           target_sec,
+                                           addend_displacement, TRUE);
+                 add_fix (sec, fix);
                }
            }
        }
@@ -9488,15 +9503,12 @@ get_elf_r_symndx_section (bfd *abfd, unsigned long r_symndx)
 
       if (section_index == SHN_UNDEF)
        target_sec = bfd_und_section_ptr;
-      else if (section_index > 0 && section_index < SHN_LORESERVE)
-       target_sec = bfd_section_from_elf_index (abfd, section_index);
       else if (section_index == SHN_ABS)
        target_sec = bfd_abs_section_ptr;
       else if (section_index == SHN_COMMON)
        target_sec = bfd_com_section_ptr;
       else
-       /* Who knows?  */
-       target_sec = NULL;
+       target_sec = bfd_section_from_elf_index (abfd, section_index);
     }
   else
     {
This page took 0.025222 seconds and 4 git commands to generate.