daily update
[deliverable/binutils-gdb.git] / bfd / elf32-avr.c
index 0f070b47756671904c7428250822dbc7773cb9f5..1b6612374564550f9af3956c51d6eda2313d4bd8 100644 (file)
@@ -1,5 +1,5 @@
 /* AVR-specific support for 32-bit ELF
-   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007
+   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008
    Free Software Foundation, Inc.
    Contributed by Denis Chertykov <denisc@overta.ru>
 
@@ -7,7 +7,7 @@
 
    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,
@@ -20,8 +20,8 @@
    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/avr.h"
@@ -729,7 +729,7 @@ elf32_avr_check_relocs (bfd *abfd,
                        const Elf_Internal_Rela *relocs)
 {
   Elf_Internal_Shdr *symtab_hdr;
-  struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
+  struct elf_link_hash_entry **sym_hashes;
   const Elf_Internal_Rela *rel;
   const Elf_Internal_Rela *rel_end;
 
@@ -738,9 +738,6 @@ elf32_avr_check_relocs (bfd *abfd,
 
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (abfd);
-  sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
-  if (!elf_bad_symtab (abfd))
-    sym_hashes_end -= symtab_hdr->sh_info;
 
   rel_end = relocs + sec->reloc_count;
   for (rel = relocs; rel < rel_end; rel++)
@@ -857,10 +854,11 @@ avr_final_link_relocate (reloc_howto_type *                 howto,
        {
           /* Relative distance is too large.  */
 
-         /* Always apply WRAPAROUND for avr2 and avr4.  */
+         /* Always apply WRAPAROUND for avr2, avr25, and avr4.  */
          switch (bfd_get_mach (input_bfd))
            {
            case bfd_mach_avr2:
+           case bfd_mach_avr25:
            case bfd_mach_avr4:
              break;
 
@@ -1299,10 +1297,22 @@ bfd_elf_avr_final_write_processing (bfd *abfd,
       val = E_AVR_MACH_AVR1;
       break;
 
+    case bfd_mach_avr25:
+      val = E_AVR_MACH_AVR25;
+      break;
+
     case bfd_mach_avr3:
       val = E_AVR_MACH_AVR3;
       break;
 
+    case bfd_mach_avr31:
+      val = E_AVR_MACH_AVR31;
+      break;
+
+    case bfd_mach_avr35:
+      val = E_AVR_MACH_AVR35;
+      break;
+
     case bfd_mach_avr4:
       val = E_AVR_MACH_AVR4;
       break;
@@ -1311,6 +1321,10 @@ bfd_elf_avr_final_write_processing (bfd *abfd,
       val = E_AVR_MACH_AVR5;
       break;
 
+    case bfd_mach_avr51:
+      val = E_AVR_MACH_AVR51;
+      break;
+
     case bfd_mach_avr6:
       val = E_AVR_MACH_AVR6;
       break;
@@ -1345,10 +1359,22 @@ elf32_avr_object_p (bfd *abfd)
          e_set = bfd_mach_avr1;
          break;
 
+       case E_AVR_MACH_AVR25:
+         e_set = bfd_mach_avr25;
+         break;
+
        case E_AVR_MACH_AVR3:
          e_set = bfd_mach_avr3;
          break;
 
+       case E_AVR_MACH_AVR31:
+         e_set = bfd_mach_avr31;
+         break;
+
+       case E_AVR_MACH_AVR35:
+         e_set = bfd_mach_avr35;
+         break;
+
        case E_AVR_MACH_AVR4:
          e_set = bfd_mach_avr4;
          break;
@@ -1357,6 +1383,10 @@ elf32_avr_object_p (bfd *abfd)
          e_set = bfd_mach_avr5;
          break;
 
+       case E_AVR_MACH_AVR51:
+         e_set = bfd_mach_avr51;
+         break;
+
        case E_AVR_MACH_AVR6:
          e_set = bfd_mach_avr6;
          break;
@@ -1385,7 +1415,6 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
   Elf_Internal_Rela *irelalign;
   Elf_Internal_Sym *isym;
   Elf_Internal_Sym *isymbuf = NULL;
-  Elf_Internal_Sym *isymend;
   bfd_vma toaddr;
   struct elf_link_hash_entry **sym_hashes;
   struct elf_link_hash_entry **end_hashes;
@@ -1523,13 +1552,19 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
 
   /* Adjust the local symbols defined in this section.  */
   isym = (Elf_Internal_Sym *) symtab_hdr->contents;
-  isymend = isym + symtab_hdr->sh_info;
-  for (; isym < isymend; isym++)
+  /* Fix PR 9841, there may be no local symbols.  */
+  if (isym != NULL)
     {
-      if (isym->st_shndx == sec_shndx
-          && isym->st_value > addr
-          && isym->st_value < toaddr)
-        isym->st_value -= count;
+      Elf_Internal_Sym *isymend;
+
+      isymend = isym + symtab_hdr->sh_info;
+      for (; isym < isymend; isym++)
+       {
+         if (isym->st_shndx == sec_shndx
+             && isym->st_value > addr
+             && isym->st_value < toaddr)
+           isym->st_value -= count;
+       }
     }
 
   /* Now adjust the global symbols defined in this section.  */
@@ -1599,6 +1634,10 @@ elf32_avr_relax_section (bfd *abfd,
   static Elf_Internal_Rela *last_reloc = NULL;
   struct elf32_avr_link_hash_table *htab;
 
+  if (link_info->relocatable)
+    (*link_info->callbacks->einfo)
+      (_("%P%F: --relax and -r may not be used together\n"));
+
   htab = avr_link_hash_table (link_info);
   if (htab == NULL)
     return FALSE;
@@ -2037,7 +2076,8 @@ elf32_avr_relax_section (bfd *abfd,
                         /* Check for local symbols.  */
                         isym = (Elf_Internal_Sym *) symtab_hdr->contents;
                         isymend = isym + symtab_hdr->sh_info;
-                        for (; isym < isymend; isym++)
+                       /* PR 6019: There may not be any local symbols.  */
+                        for (; isym != NULL && isym < isymend; isym++)
                          {
                            if (isym->st_value == section_offset_of_ret_insn
                                && isym->st_shndx == sec_shndx)
@@ -2592,6 +2632,7 @@ get_local_syms (bfd *input_bfd, struct bfd_link_info *info)
   unsigned int bfd_indx;
   Elf_Internal_Sym *local_syms, **all_local_syms;
   struct elf32_avr_link_hash_table *htab = avr_link_hash_table (info);
+  bfd_size_type amt;
 
   if (htab == NULL)
     return -1;
@@ -2599,7 +2640,7 @@ get_local_syms (bfd *input_bfd, struct bfd_link_info *info)
   /* We want to read in symbol extension records only once.  To do this
      we need to read in the local symbols in parallel and save them for
      later use; so hold pointers to the local symbols in an array.  */
-  bfd_size_type amt = sizeof (Elf_Internal_Sym *) * htab->bfd_count;
+  amt = sizeof (Elf_Internal_Sym *) * htab->bfd_count;
   all_local_syms = bfd_zmalloc (amt);
   htab->all_local_syms = all_local_syms;
   if (all_local_syms == NULL)
@@ -2760,15 +2801,20 @@ elf32_avr_size_stubs (bfd *output_bfd,
                       /* It's a local symbol.  */
                       Elf_Internal_Sym *sym;
                       Elf_Internal_Shdr *hdr;
+                     unsigned int shndx;
 
                       sym = local_syms + r_indx;
-                      hdr = elf_elfsections (input_bfd)[sym->st_shndx];
-                      sym_sec = hdr->bfd_section;
                       if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
                         sym_value = sym->st_value;
-                      destination = (sym_value + irela->r_addend
-                                     + sym_sec->output_offset
-                                     + sym_sec->output_section->vma);
+                     shndx = sym->st_shndx;
+                     if (shndx < elf_numsections (input_bfd))
+                       {
+                         hdr = elf_elfsections (input_bfd)[shndx];
+                         sym_sec = hdr->bfd_section;
+                         destination = (sym_value + irela->r_addend
+                                        + sym_sec->output_offset
+                                        + sym_sec->output_section->vma);
+                       }
                     }
                   else
                     {
This page took 0.026555 seconds and 4 git commands to generate.