Makefile.in: Move ravenscar-thread.c from SFILES to ALLDEPFILES.
[deliverable/binutils-gdb.git] / bfd / elf32-avr.c
index 40cc0830fb7b28302e7f5c7883ced31525ea9e0b..857a4b7f41cea9f151c00de62d93656956efc6ca 100644 (file)
@@ -1,5 +1,6 @@
 /* AVR-specific support for 32-bit ELF
-   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2006
+   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
+   2010, 2011, 2012
    Free Software Foundation, Inc.
    Contributed by Denis Chertykov <denisc@overta.ru>
 
@@ -7,7 +8,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 +21,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"
@@ -38,7 +39,7 @@ static bfd_boolean debug_stubs = FALSE;
 
 /* We use two hash tables to hold information for linking avr objects.
 
-   The first is the elf32_avr_link_hash_tablse which is derived from the
+   The first is the elf32_avr_link_hash_table which is derived from the
    stanard ELF linker hash table.  We use this as a place to attach the other
    hash table and some static information.
 
@@ -103,7 +104,9 @@ struct elf32_avr_link_hash_table
 
 /* Various hash macros and functions.  */
 #define avr_link_hash_table(p) \
-  ((struct elf32_avr_link_hash_table *) ((p)->hash))
+  /* PR 3874: Check that we have an AVR style hash table before using it.  */\
+  (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+  == AVR_ELF_DATA ? ((struct elf32_avr_link_hash_table *) ((p)->hash)) : NULL)
 
 #define avr_stub_hash_entry(ent) \
   ((struct elf32_avr_stub_hash_entry *)(ent))
@@ -471,7 +474,7 @@ static reloc_howto_type elf_avr_howto_table[] =
         0xffff,                /* dst_mask */
         FALSE),                /* pcrel_offset */
   /* A low 8 bit absolute relocation of 24 bit program memory address.
-     For LDI command.  Will be changed when linker stubs are needed. */
+     For LDI command.  Will be changed when linker stubs are needed.  */
   HOWTO (R_AVR_LO8_LDI_GS,      /* type */
          1,                     /* rightshift */
          1,                     /* size (0 = byte, 1 = short, 2 = long) */
@@ -486,7 +489,7 @@ static reloc_howto_type elf_avr_howto_table[] =
          0xffff,                /* dst_mask */
          FALSE),                /* pcrel_offset */
   /* A low 8 bit absolute relocation of 24 bit program memory address.
-     For LDI command.  Will be changed when linker stubs are needed. */
+     For LDI command.  Will be changed when linker stubs are needed.  */
   HOWTO (R_AVR_HI8_LDI_GS,      /* type */
          9,                     /* rightshift */
          1,                     /* size (0 = byte, 1 = short, 2 = long) */
@@ -499,7 +502,63 @@ static reloc_howto_type elf_avr_howto_table[] =
          FALSE,                 /* partial_inplace */
          0xffff,                /* src_mask */
          0xffff,                /* dst_mask */
-         FALSE)                 /* pcrel_offset */
+         FALSE),                /* pcrel_offset */
+  /* 8 bit offset.  */
+  HOWTO (R_AVR_8,              /* type */
+        0,                     /* rightshift */
+        0,                     /* size (0 = byte, 1 = short, 2 = long) */
+        8,                     /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_AVR_8",             /* name */
+        FALSE,                 /* partial_inplace */
+        0x000000ff,            /* src_mask */
+        0x000000ff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
+  /* lo8-part to use in  .byte lo8(sym).  */
+  HOWTO (R_AVR_8_LO8,          /* type */
+        0,                     /* rightshift */
+        0,                     /* size (0 = byte, 1 = short, 2 = long) */
+        8,                     /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_AVR_8_LO8",         /* name */
+        FALSE,                 /* partial_inplace */
+        0xffffff,              /* src_mask */
+        0xffffff,              /* dst_mask */
+        FALSE),                /* pcrel_offset */
+  /* hi8-part to use in  .byte hi8(sym).  */
+  HOWTO (R_AVR_8_HI8,          /* type */
+        8,                     /* rightshift */
+        0,                     /* size (0 = byte, 1 = short, 2 = long) */
+        8,                     /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_AVR_8_HI8",         /* name */
+        FALSE,                 /* partial_inplace */
+        0xffffff,              /* src_mask */
+        0xffffff,              /* dst_mask */
+        FALSE),                /* pcrel_offset */
+  /* hlo8-part to use in  .byte hlo8(sym).  */
+  HOWTO (R_AVR_8_HLO8,         /* type */
+        16,                    /* rightshift */
+        0,                     /* size (0 = byte, 1 = short, 2 = long) */
+        8,                     /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_AVR_8_HLO8",        /* name */
+        FALSE,                 /* partial_inplace */
+        0xffffff,              /* src_mask */
+        0xffffff,              /* dst_mask */
+        FALSE),                /* pcrel_offset */
 };
 
 /* Map BFD reloc types to AVR ELF reloc types.  */
@@ -537,7 +596,11 @@ static const struct avr_reloc_map avr_reloc_map[] =
   { BFD_RELOC_AVR_CALL,             R_AVR_CALL },
   { BFD_RELOC_AVR_LDI,              R_AVR_LDI  },
   { BFD_RELOC_AVR_6,                R_AVR_6    },
-  { BFD_RELOC_AVR_6_ADIW,           R_AVR_6_ADIW }
+  { BFD_RELOC_AVR_6_ADIW,           R_AVR_6_ADIW },
+  { BFD_RELOC_8,                    R_AVR_8 },
+  { BFD_RELOC_AVR_8_LO,             R_AVR_8_LO8 },
+  { BFD_RELOC_AVR_8_HI,             R_AVR_8_HI8 },
+  { BFD_RELOC_AVR_8_HLO,            R_AVR_8_HLO8 }
 };
 
 /* Meant to be filled one day with the wrap around address for the
@@ -587,6 +650,18 @@ stub_hash_newfunc (struct bfd_hash_entry *entry,
   return entry;
 }
 
+/* This function is just a straight passthrough to the real
+   function in linker.c.  Its prupose is so that its address
+   can be compared inside the avr_link_hash_table macro.  */
+
+static struct bfd_hash_entry *
+elf32_avr_link_hash_newfunc (struct bfd_hash_entry * entry,
+                            struct bfd_hash_table * table,
+                            const char * string)
+{
+  return _bfd_elf_link_hash_newfunc (entry, table, string);
+}
+
 /* Create the derived linker hash table.  The AVR ELF port uses the derived
    hash table to keep information specific to the AVR ELF linker (without
    using static variables).  */
@@ -602,8 +677,9 @@ elf32_avr_link_hash_table_create (bfd *abfd)
     return NULL;
 
   if (!_bfd_elf_link_hash_table_init (&htab->etab, abfd,
-                                      _bfd_elf_link_hash_newfunc,
-                                      sizeof (struct elf_link_hash_entry)))
+                                      elf32_avr_link_hash_newfunc,
+                                      sizeof (struct elf_link_hash_entry),
+                                     AVR_ELF_DATA))
     {
       free (htab);
       return NULL;
@@ -674,6 +750,22 @@ bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
   return NULL;
 }
 
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+                                const char *r_name)
+{
+  unsigned int i;
+
+  for (i = 0;
+       i < sizeof (elf_avr_howto_table) / sizeof (elf_avr_howto_table[0]);
+       i++)
+    if (elf_avr_howto_table[i].name != NULL
+       && strcasecmp (elf_avr_howto_table[i].name, r_name) == 0)
+      return &elf_avr_howto_table[i];
+
+  return NULL;
+}
+
 /* Set the howto pointer for an AVR ELF reloc.  */
 
 static void
@@ -688,51 +780,6 @@ avr_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
   cache_ptr->howto = &elf_avr_howto_table[r_type];
 }
 
-/* Look through the relocs for a section during the first phase.
-   Since we don't do .gots or .plts, we just need to consider the
-   virtual table relocs for gc.  */
-
-static bfd_boolean
-elf32_avr_check_relocs (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, **sym_hashes_end;
-  const Elf_Internal_Rela *rel;
-  const Elf_Internal_Rela *rel_end;
-
-  if (info->relocatable)
-    return TRUE;
-
-  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++)
-    {
-      struct elf_link_hash_entry *h;
-      unsigned long r_symndx;
-
-      r_symndx = ELF32_R_SYM (rel->r_info);
-      if (r_symndx < symtab_hdr->sh_info)
-        h = NULL;
-      else
-       {
-         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
-         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;
-       }
-    }
-
-  return TRUE;
-}
-
 static bfd_boolean
 avr_stub_is_required_for_16_bit_reloc (bfd_vma relocation)
 {
@@ -748,14 +795,14 @@ static bfd_vma
 avr_get_stub_addr (bfd_vma srel,
                    struct elf32_avr_link_hash_table *htab)
 {
-  unsigned int index;
+  unsigned int sindex;
   bfd_vma stub_sec_addr =
               (htab->stub_sec->output_section->vma +
               htab->stub_sec->output_offset);
 
-  for (index = 0; index < htab->amt_max_entry_cnt; index ++)
-    if (htab->amt_destination_addr[index] == srel)
-      return htab->amt_stub_offsets[index] + stub_sec_addr;
+  for (sindex = 0; sindex < htab->amt_max_entry_cnt; sindex ++)
+    if (htab->amt_destination_addr[sindex] == srel)
+      return htab->amt_stub_offsets[sindex] + stub_sec_addr;
 
   /* Return an address that could not be reached by 16 bit relocs.  */
   return 0x020000;
@@ -827,10 +874,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;
 
@@ -1139,8 +1187,8 @@ elf32_avr_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
   Elf_Internal_Rela *           relend;
   struct elf32_avr_link_hash_table * htab = avr_link_hash_table (info);
 
-  if (info->relocatable)
-    return TRUE;
+  if (htab == NULL)
+    return FALSE;
 
   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
@@ -1158,10 +1206,9 @@ elf32_avr_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
       const char *                 name;
       int                          r_type;
 
-      /* This is a final link.  */
       r_type = ELF32_R_TYPE (rel->r_info);
       r_symndx = ELF32_R_SYM (rel->r_info);
-      howto  = elf_avr_howto_table + ELF32_R_TYPE (rel->r_info);
+      howto  = elf_avr_howto_table + r_type;
       h      = NULL;
       sym    = NULL;
       sec    = NULL;
@@ -1188,6 +1235,13 @@ elf32_avr_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
          name = h->root.root.string;
        }
 
+      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, 1, relend, howto, 0, contents);
+
+      if (info->relocatable)
+       continue;
+
       r = avr_final_link_relocate (howto, input_bfd, input_section,
                                   contents, rel, relocation, htab);
 
@@ -1259,10 +1313,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;
@@ -1271,9 +1337,41 @@ 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;
+
+    case bfd_mach_avrxmega1:
+      val = E_AVR_MACH_XMEGA1;
+      break;
+
+    case bfd_mach_avrxmega2:
+      val = E_AVR_MACH_XMEGA2;
+      break;
+
+    case bfd_mach_avrxmega3:
+      val = E_AVR_MACH_XMEGA3;
+      break;
+
+    case bfd_mach_avrxmega4:
+      val = E_AVR_MACH_XMEGA4;
+      break;
+
+    case bfd_mach_avrxmega5:
+      val = E_AVR_MACH_XMEGA5;
+      break;
+
+    case bfd_mach_avrxmega6:
+      val = E_AVR_MACH_XMEGA6;
+      break;
+
+    case bfd_mach_avrxmega7:
+      val = E_AVR_MACH_XMEGA7;
+      break;
     }
 
   elf_elfheader (abfd)->e_machine = EM_AVR;
@@ -1305,10 +1403,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;
@@ -1317,9 +1427,41 @@ 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;
+
+       case E_AVR_MACH_XMEGA1:
+         e_set = bfd_mach_avrxmega1;
+         break;
+
+       case E_AVR_MACH_XMEGA2:
+         e_set = bfd_mach_avrxmega2;
+         break;
+
+       case E_AVR_MACH_XMEGA3:
+         e_set = bfd_mach_avrxmega3;
+         break;
+
+       case E_AVR_MACH_XMEGA4:
+         e_set = bfd_mach_avrxmega4;
+         break;
+
+       case E_AVR_MACH_XMEGA5:
+         e_set = bfd_mach_avrxmega5;
+         break;
+
+       case E_AVR_MACH_XMEGA6:
+         e_set = bfd_mach_avrxmega6;
+         break;
+
+       case E_AVR_MACH_XMEGA7:
+         e_set = bfd_mach_avrxmega7;
+         break;
        }
     }
   return bfd_default_set_arch_mach (abfd, bfd_arch_avr,
@@ -1342,10 +1484,8 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
   unsigned int sec_shndx;
   bfd_byte *contents;
   Elf_Internal_Rela *irel, *irelend;
-  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;
@@ -1355,10 +1495,6 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
   sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
   contents = elf_section_data (sec)->this_hdr.contents;
 
-  /* The deletion must stop at the next ALIGN reloc for an aligment
-     power larger than the number of bytes we are deleting.  */
-
-  irelalign = NULL;
   toaddr = sec->size;
 
   irel = elf_section_data (sec)->relocs;
@@ -1374,12 +1510,9 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
   for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
     {
       bfd_vma old_reloc_address;
-      bfd_vma shrinked_insn_address;
 
       old_reloc_address = (sec->output_section->vma
                            + sec->output_offset + irel->r_offset);
-      shrinked_insn_address = (sec->output_section->vma
-                              + sec->output_offset + addr - count);
 
       /* Get the new reloc address.  */
       if ((irel->r_offset > addr
@@ -1416,11 +1549,18 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
        bfd_vma symval;
        bfd_vma shrinked_insn_address;
 
+       if (isec->reloc_count == 0)
+        continue;
+
        shrinked_insn_address = (sec->output_section->vma
                                 + sec->output_offset + addr - count);
 
-       irelend = elf_section_data (isec)->relocs + isec->reloc_count;
-       for (irel = elf_section_data (isec)->relocs;
+       irel = elf_section_data (isec)->relocs;
+       /* PR 12161: Read in the relocs for this section if necessary.  */
+       if (irel == NULL)
+         irel = _bfd_elf_link_read_relocs (abfd, isec, NULL, NULL, TRUE);
+
+       for (irelend = irel + isec->reloc_count;
             irel < irelend;
             irel++)
          {
@@ -1441,7 +1581,6 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
            if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
              {
                /* A local symbol.  */
-               Elf_Internal_Sym *isym;
                asection *sym_sec;
 
                isym = isymbuf + ELF32_R_SYM (irel->r_info);
@@ -1483,13 +1622,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.  */
@@ -1555,11 +1700,25 @@ elf32_avr_relax_section (bfd *abfd,
   Elf_Internal_Rela *irel, *irelend;
   bfd_byte *contents = NULL;
   Elf_Internal_Sym *isymbuf = NULL;
-  static asection *last_input_section = NULL;
-  static Elf_Internal_Rela *last_reloc = NULL;
   struct elf32_avr_link_hash_table *htab;
 
+  /* If 'shrinkable' is FALSE, do not shrink by deleting bytes while
+     relaxing. Such shrinking can cause issues for the sections such 
+     as .vectors and .jumptables. Instead the unused bytes should be 
+     filled with nop instructions. */
+  bfd_boolean shrinkable = TRUE;
+
+  if (!strcmp (sec->name,".vectors")
+      || !strcmp (sec->name,".jumptables"))
+    shrinkable = FALSE;
+
+  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;
 
   /* Assume nothing changes.  */
   *again = FALSE;
@@ -1610,11 +1769,6 @@ elf32_avr_relax_section (bfd *abfd,
   if (internal_relocs == NULL)
     goto error_return;
 
-  if (sec != last_input_section)
-    last_reloc = NULL;
-
-  last_input_section = sec;
-
   /* Walk through the relocs looking for relaxing opportunities.  */
   irelend = internal_relocs + sec->reloc_count;
   for (irel = internal_relocs; irel < irelend; irel++)
@@ -1622,8 +1776,8 @@ elf32_avr_relax_section (bfd *abfd,
       bfd_vma symval;
 
       if (   ELF32_R_TYPE (irel->r_info) != R_AVR_13_PCREL
-          && ELF32_R_TYPE (irel->r_info) != R_AVR_7_PCREL
-          && ELF32_R_TYPE (irel->r_info) != R_AVR_CALL)
+            && ELF32_R_TYPE (irel->r_info) != R_AVR_7_PCREL
+            && ELF32_R_TYPE (irel->r_info) != R_AVR_CALL)
         continue;
 
       /* Get the section contents if we haven't done so already.  */
@@ -1640,7 +1794,7 @@ elf32_avr_relax_section (bfd *abfd,
             }
         }
 
-     /* Read this BFD's local symbols if we haven't done so already.  */
+      /* Read this BFD's local symbols if we haven't done so already.  */
       if (isymbuf == NULL && symtab_hdr->sh_info != 0)
         {
           isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
@@ -1699,9 +1853,9 @@ elf32_avr_relax_section (bfd *abfd,
          the linker is run.  */
       switch (ELF32_R_TYPE (irel->r_info))
         {
-         /* Try to turn a 22-bit absolute call/jump into an 13-bit
-            pc-relative rcall/rjmp.  */
-         case R_AVR_CALL:
+         /* Try to turn a 22-bit absolute call/jump into an 13-bit
+            pc-relative rcall/rjmp.  */
+       case R_AVR_CALL:
           {
             bfd_vma value = symval + irel->r_addend;
             bfd_vma dot, gap;
@@ -1714,10 +1868,16 @@ elf32_avr_relax_section (bfd *abfd,
             /* Compute the distance from this insn to the branch target.  */
             gap = value - dot;
 
-            /* If the distance is within -4094..+4098 inclusive, then we can
-               relax this jump/call.  +4098 because the call/jump target
-               will be closer after the relaxation.  */
-            if ((int) gap >= -4094 && (int) gap <= 4098)
+            /* Check if the gap falls in the range that can be accommodated
+               in 13bits signed (It is 12bits when encoded, as we deal with
+               word addressing). */
+            if (!shrinkable && ((int) gap >= -4096 && (int) gap <= 4095))
+              distance_short_enough = 1;
+            /* If shrinkable, then we can check for a range of distance which
+               is two bytes farther on both the directions because the call
+               or jump target will be closer by two bytes after the 
+               relaxation. */
+            else if (shrinkable && ((int) gap >= -4094 && (int) gap <= 4097))
               distance_short_enough = 1;
 
             /* Here we handle the wrap-around case.  E.g. for a 16k device
@@ -1726,27 +1886,27 @@ elf32_avr_relax_section (bfd *abfd,
                vaiable avr_pc_wrap_around with the appropriate value.
                I.e. 0x4000 for a 16k device.  */
             {
-               /* Shrinking the code size makes the gaps larger in the
-                  case of wrap-arounds.  So we use a heuristical safety
-                  margin to avoid that during relax the distance gets
-                  again too large for the short jumps.  Let's assume
-                  a typical code-size reduction due to relax for a
-                  16k device of 600 bytes.  So let's use twice the
-                  typical value as safety margin.  */
-               int rgap;
-               int safety_margin;
-
-               int assumed_shrink = 600;
-               if (avr_pc_wrap_around > 0x4000)
-                 assumed_shrink = 900;
-
-               safety_margin = 2 * assumed_shrink;
-
-               rgap = avr_relative_distance_considering_wrap_around (gap);
-
-               if (rgap >= (-4092 + safety_margin)
-                   && rgap <= (4094 - safety_margin))
-                distance_short_enough = 1;
+             /* Shrinking the code size makes the gaps larger in the
+                case of wrap-arounds.  So we use a heuristical safety
+                margin to avoid that during relax the distance gets
+                again too large for the short jumps.  Let's assume
+                a typical code-size reduction due to relax for a
+                16k device of 600 bytes.  So let's use twice the
+                typical value as safety margin.  */
+             int rgap;
+             int safety_margin;
+
+             int assumed_shrink = 600;
+             if (avr_pc_wrap_around > 0x4000)
+               assumed_shrink = 900;
+
+             safety_margin = 2 * assumed_shrink;
+
+             rgap = avr_relative_distance_considering_wrap_around (gap);
+
+             if (rgap >= (-4092 + safety_margin)
+                 && rgap <= (4094 - safety_margin))
+               distance_short_enough = 1;
             }
 
             if (distance_short_enough)
@@ -1791,11 +1951,9 @@ elf32_avr_relax_section (bfd *abfd,
                 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
                                              R_AVR_13_PCREL);
 
-                /* Check for the vector section. There we don't want to
-                   modify the ordering!  */
-
-                if (!strcmp (sec->name,".vectors")
-                    || !strcmp (sec->name,".jumptables"))
+                /* We should not modify the ordering if 'shrinkable' is
+                   FALSE. */ 
+                if (!shrinkable)
                   {
                     /* Let's insert a nop.  */
                     bfd_put_8 (abfd, 0x00, contents + irel->r_offset + 2);
@@ -1840,9 +1998,9 @@ elf32_avr_relax_section (bfd *abfd,
                 if (irel->r_offset + 3 < sec->size)
                   {
                     next_insn_msb =
-                        bfd_get_8 (abfd, contents + irel->r_offset + 3);
+                     bfd_get_8 (abfd, contents + irel->r_offset + 3);
                     next_insn_lsb =
-                        bfd_get_8 (abfd, contents + irel->r_offset + 2);
+                     bfd_get_8 (abfd, contents + irel->r_offset + 2);
                   }
 
                if ((0x95 == next_insn_msb) && (0x08 == next_insn_lsb))
@@ -1870,9 +2028,9 @@ elf32_avr_relax_section (bfd *abfd,
                 if (irel->r_offset + 5 < sec->size)
                   {
                     next_insn_msb =
-                        bfd_get_8 (abfd, contents + irel->r_offset + 5);
+                     bfd_get_8 (abfd, contents + irel->r_offset + 5);
                     next_insn_lsb =
-                        bfd_get_8 (abfd, contents + irel->r_offset + 4);
+                     bfd_get_8 (abfd, contents + irel->r_offset + 4);
                   }
 
                 if ((0x95 == next_insn_msb) && (0x08 == next_insn_lsb))
@@ -1907,20 +2065,20 @@ elf32_avr_relax_section (bfd *abfd,
                 if (irel->r_offset + insn_size + 1 < sec->size)
                   {
                     next_insn_msb =
-                        bfd_get_8 (abfd, contents + irel->r_offset
-                                         + insn_size + 1);
+                     bfd_get_8 (abfd, contents + irel->r_offset
+                                + insn_size + 1);
                     next_insn_lsb =
-                        bfd_get_8 (abfd, contents + irel->r_offset
-                                         + insn_size);
+                     bfd_get_8 (abfd, contents + irel->r_offset
+                                + insn_size);
                   }
 
                 if ((0x95 == next_insn_msb) && (0x08 == next_insn_lsb))
                   {
                     /* The next insn is a ret. We possibly could delete
-                       this ret. First we need to check for preceeding
+                       this ret. First we need to check for preceding
                        sbis/sbic/sbrs or cpse "skip" instructions.  */
 
-                    int there_is_preceeding_non_skip_insn = 1;
+                    int there_is_preceding_non_skip_insn = 1;
                     bfd_vma address_of_ret;
 
                     address_of_ret = dot + insn_size;
@@ -1932,51 +2090,52 @@ elf32_avr_relax_section (bfd *abfd,
                       printf ("found jmp / ret sequence at address 0x%x\n",
                               (int) dot);
 
-                    /* We have to make sure that there is a preceeding insn.  */
+                    /* We have to make sure that there is a preceding insn.  */
                     if (irel->r_offset >= 2)
                       {
-                        unsigned char preceeding_msb;
-                        unsigned char preceeding_lsb;
-                        preceeding_msb =
-                            bfd_get_8 (abfd, contents + irel->r_offset - 1);
-                        preceeding_lsb =
-                            bfd_get_8 (abfd, contents + irel->r_offset - 2);
+                        unsigned char preceding_msb;
+                        unsigned char preceding_lsb;
+
+                        preceding_msb =
+                         bfd_get_8 (abfd, contents + irel->r_offset - 1);
+                        preceding_lsb =
+                         bfd_get_8 (abfd, contents + irel->r_offset - 2);
 
                         /* sbic.  */
-                        if (0x99 == preceeding_msb)
-                          there_is_preceeding_non_skip_insn = 0;
+                        if (0x99 == preceding_msb)
+                          there_is_preceding_non_skip_insn = 0;
 
                         /* sbis.  */
-                        if (0x9b == preceeding_msb)
-                          there_is_preceeding_non_skip_insn = 0;
+                        if (0x9b == preceding_msb)
+                          there_is_preceding_non_skip_insn = 0;
 
                         /* sbrc */
-                        if ((0xfc == (preceeding_msb & 0xfe)
-                            && (0x00 == (preceeding_lsb & 0x08))))
-                          there_is_preceeding_non_skip_insn = 0;
+                        if ((0xfc == (preceding_msb & 0xfe)
+                            && (0x00 == (preceding_lsb & 0x08))))
+                          there_is_preceding_non_skip_insn = 0;
 
                         /* sbrs */
-                        if ((0xfe == (preceeding_msb & 0xfe)
-                            && (0x00 == (preceeding_lsb & 0x08))))
-                          there_is_preceeding_non_skip_insn = 0;
+                        if ((0xfe == (preceding_msb & 0xfe)
+                            && (0x00 == (preceding_lsb & 0x08))))
+                          there_is_preceding_non_skip_insn = 0;
 
                         /* cpse */
-                        if (0x10 == (preceeding_msb & 0xfc))
-                          there_is_preceeding_non_skip_insn = 0;
+                        if (0x10 == (preceding_msb & 0xfc))
+                          there_is_preceding_non_skip_insn = 0;
 
-                        if (there_is_preceeding_non_skip_insn == 0)
+                        if (there_is_preceding_non_skip_insn == 0)
                           if (debug_relax)
-                            printf ("preceeding skip insn prevents deletion of"
-                                    " ret insn at addr 0x%x in section %s\n",
+                            printf ("preceding skip insn prevents deletion of"
+                                    " ret insn at Addy 0x%x in section %s\n",
                                     (int) dot + 2, sec->name);
                       }
                     else
                       {
                         /* There is no previous instruction.  */
-                        there_is_preceeding_non_skip_insn = 0;
+                        there_is_preceding_non_skip_insn = 0;
                       }
 
-                    if (there_is_preceeding_non_skip_insn)
+                    if (there_is_preceding_non_skip_insn)
                       {
                         /* We now only have to make sure that there is no
                            local label defined at the address of the ret
@@ -1985,7 +2144,7 @@ elf32_avr_relax_section (bfd *abfd,
 
                         int deleting_ret_is_safe = 1;
                         unsigned int section_offset_of_ret_insn =
-                                          irel->r_offset + insn_size;
+                         irel->r_offset + insn_size;
                         Elf_Internal_Sym *isym, *isymend;
                         unsigned int sec_shndx;
 
@@ -1995,146 +2154,142 @@ 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++)
-                         {
-                           if (isym->st_value == section_offset_of_ret_insn
-                               && isym->st_shndx == sec_shndx)
-                             {
-                               deleting_ret_is_safe = 0;
-                               if (debug_relax)
-                                 printf ("local label prevents deletion of ret "
-                                         "insn at address 0x%x\n",
-                                         (int) dot + insn_size);
-                             }
-                         }
-
-                         /* Now check for global symbols.  */
-                         {
-                           int symcount;
-                           struct elf_link_hash_entry **sym_hashes;
-                           struct elf_link_hash_entry **end_hashes;
-
-                           symcount = (symtab_hdr->sh_size
-                                       / sizeof (Elf32_External_Sym)
-                                       - symtab_hdr->sh_info);
-                           sym_hashes = elf_sym_hashes (abfd);
-                           end_hashes = sym_hashes + symcount;
-                           for (; sym_hashes < end_hashes; sym_hashes++)
-                            {
-                              struct elf_link_hash_entry *sym_hash =
-                                                                 *sym_hashes;
-                              if ((sym_hash->root.type == bfd_link_hash_defined
-                                  || sym_hash->root.type ==
+                       /* 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)
+                             {
+                               deleting_ret_is_safe = 0;
+                               if (debug_relax)
+                                 printf ("local label prevents deletion of ret "
+                                         "insn at address 0x%x\n",
+                                         (int) dot + insn_size);
+                             }
+                         }
+
+                       /* Now check for global symbols.  */
+                       {
+                         int symcount;
+                         struct elf_link_hash_entry **sym_hashes;
+                         struct elf_link_hash_entry **end_hashes;
+
+                         symcount = (symtab_hdr->sh_size
+                                     / sizeof (Elf32_External_Sym)
+                                     - symtab_hdr->sh_info);
+                         sym_hashes = elf_sym_hashes (abfd);
+                         end_hashes = sym_hashes + symcount;
+                         for (; sym_hashes < end_hashes; sym_hashes++)
+                           {
+                             struct elf_link_hash_entry *sym_hash =
+                               *sym_hashes;
+                             if ((sym_hash->root.type == bfd_link_hash_defined
+                                  || sym_hash->root.type ==
                                   bfd_link_hash_defweak)
-                                  && sym_hash->root.u.def.section == sec
-                                  && sym_hash->root.u.def.value == section_offset_of_ret_insn)
-                                {
-                                  deleting_ret_is_safe = 0;
-                                  if (debug_relax)
-                                    printf ("global label prevents deletion of "
-                                            "ret insn at address 0x%x\n",
-                                            (int) dot + insn_size);
-                                }
-                            }
-                         }
-                         /* Now we check for relocations pointing to ret.  */
-                         {
-                           Elf_Internal_Rela *irel;
-                           Elf_Internal_Rela *relend;
-                           Elf_Internal_Shdr *symtab_hdr;
-
-                           symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
-                           relend = elf_section_data (sec)->relocs
-                                    + sec->reloc_count;
-
-                           for (irel = elf_section_data (sec)->relocs;
-                                irel < relend; irel++)
-                             {
-                               bfd_vma reloc_target = 0;
-                               bfd_vma symval;
-                               Elf_Internal_Sym *isymbuf = NULL;
-
-                               /* Read this BFD's local symbols if we haven't
-                                  done so already.  */
-                               if (isymbuf == NULL && symtab_hdr->sh_info != 0)
-                                 {
-                                   isymbuf = (Elf_Internal_Sym *)
-                                             symtab_hdr->contents;
-                                   if (isymbuf == NULL)
-                                     isymbuf = bfd_elf_get_elf_syms
-                                      (abfd,
-                                       symtab_hdr,
-                                       symtab_hdr->sh_info, 0,
-                                       NULL, NULL, NULL);
-                                   if (isymbuf == NULL)
-                                     break;
-                                  }
-
-                               /* Get the value of the symbol referred to
-                                  by the reloc.  */
-                               if (ELF32_R_SYM (irel->r_info)
-                                   < symtab_hdr->sh_info)
-                                 {
-                                   /* A local symbol.  */
-                                   Elf_Internal_Sym *isym;
-                                   asection *sym_sec;
-
-                                   isym = isymbuf
-                                          + ELF32_R_SYM (irel->r_info);
-                                   sym_sec = bfd_section_from_elf_index
-                                    (abfd, isym->st_shndx);
-                                   symval = isym->st_value;
-
-                                   /* If the reloc is absolute, it will not
-                                      have a symbol or section associated
-                                      with it.  */
-
-                                   if (sym_sec)
-                                     {
-                                       symval +=
-                                           sym_sec->output_section->vma
-                                           + sym_sec->output_offset;
-                                       reloc_target = symval + irel->r_addend;
-                                     }
-                                   else
-                                     {
-                                       reloc_target = symval + irel->r_addend;
-                                       /* Reference symbol is absolute.  */
-                                     }
-                                 }
-                              /* else ... reference symbol is extern.  */
-
-                               if (address_of_ret == reloc_target)
-                                 {
-                                   deleting_ret_is_safe = 0;
-                                   if (debug_relax)
-                                     printf ("ret from "
-                                             "rjmp/jmp ret sequence at address"
-                                             " 0x%x could not be deleted. ret"
-                                             " is target of a relocation.\n",
-                                             (int) address_of_ret);
-                                 }
-                             }
-                         }
-
-                         if (deleting_ret_is_safe)
-                           {
-                             if (debug_relax)
-                               printf ("unreachable ret instruction "
-                                       "at address 0x%x deleted.\n",
-                                       (int) dot + insn_size);
-
-                             /* Delete two bytes of data.  */
-                             if (!elf32_avr_relax_delete_bytes (abfd, sec,
-                                        irel->r_offset + insn_size, 2))
-                               goto error_return;
-
-                             /* That will change things, so, we should relax
-                                again. Note that this is not required, and it
-                                may be slow.  */
-                             *again = TRUE;
-                             break;
-                           }
+                                 && sym_hash->root.u.def.section == sec
+                                 && sym_hash->root.u.def.value == section_offset_of_ret_insn)
+                               {
+                                 deleting_ret_is_safe = 0;
+                                 if (debug_relax)
+                                   printf ("global label prevents deletion of "
+                                           "ret insn at address 0x%x\n",
+                                           (int) dot + insn_size);
+                               }
+                           }
+                       }
+                       /* Now we check for relocations pointing to ret.  */
+                       {
+                         Elf_Internal_Rela *rel;
+                         Elf_Internal_Rela *relend;
+
+                         relend = elf_section_data (sec)->relocs
+                           + sec->reloc_count;
+
+                         for (rel = elf_section_data (sec)->relocs;
+                              rel < relend; rel++)
+                           {
+                             bfd_vma reloc_target = 0;
+
+                             /* Read this BFD's local symbols if we haven't
+                                done so already.  */
+                             if (isymbuf == NULL && symtab_hdr->sh_info != 0)
+                               {
+                                 isymbuf = (Elf_Internal_Sym *)
+                                   symtab_hdr->contents;
+                                 if (isymbuf == NULL)
+                                   isymbuf = bfd_elf_get_elf_syms
+                                     (abfd,
+                                      symtab_hdr,
+                                      symtab_hdr->sh_info, 0,
+                                      NULL, NULL, NULL);
+                                 if (isymbuf == NULL)
+                                   break;
+                               }
+
+                             /* Get the value of the symbol referred to
+                                by the reloc.  */
+                             if (ELF32_R_SYM (rel->r_info)
+                                 < symtab_hdr->sh_info)
+                               {
+                                 /* A local symbol.  */
+                                 asection *sym_sec;
+
+                                 isym = isymbuf
+                                   + ELF32_R_SYM (rel->r_info);
+                                 sym_sec = bfd_section_from_elf_index
+                                   (abfd, isym->st_shndx);
+                                 symval = isym->st_value;
+
+                                 /* If the reloc is absolute, it will not
+                                    have a symbol or section associated
+                                    with it.  */
+
+                                 if (sym_sec)
+                                   {
+                                     symval +=
+                                       sym_sec->output_section->vma
+                                       + sym_sec->output_offset;
+                                     reloc_target = symval + rel->r_addend;
+                                   }
+                                 else
+                                   {
+                                     reloc_target = symval + rel->r_addend;
+                                     /* Reference symbol is absolute.  */
+                                   }
+                               }
+                             /* else ... reference symbol is extern.  */
+
+                             if (address_of_ret == reloc_target)
+                               {
+                                 deleting_ret_is_safe = 0;
+                                 if (debug_relax)
+                                   printf ("ret from "
+                                           "rjmp/jmp ret sequence at address"
+                                           " 0x%x could not be deleted. ret"
+                                           " is target of a relocation.\n",
+                                           (int) address_of_ret);
+                               }
+                           }
+                       }
+
+                       if (deleting_ret_is_safe)
+                         {
+                           if (debug_relax)
+                             printf ("unreachable ret instruction "
+                                     "at address 0x%x deleted.\n",
+                                     (int) dot + insn_size);
+
+                           /* Delete two bytes of data.  */
+                           if (!elf32_avr_relax_delete_bytes (abfd, sec,
+                                                              irel->r_offset + insn_size, 2))
+                             goto error_return;
+
+                           /* That will change things, so, we should relax
+                              again. Note that this is not required, and it
+                              may be slow.  */
+                           *again = TRUE;
+                           break;
+                         }
                       }
 
                   }
@@ -2364,6 +2519,8 @@ avr_build_one_stub (struct bfd_hash_entry *bh, void *in_arg)
   info = (struct bfd_link_info *) in_arg;
 
   htab = avr_link_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
 
   target = hsh->target_value;
 
@@ -2412,12 +2569,10 @@ avr_build_one_stub (struct bfd_hash_entry *bh, void *in_arg)
 
 static bfd_boolean
 avr_mark_stub_not_to_be_necessary (struct bfd_hash_entry *bh,
-                                   void *in_arg)
+                                   void *in_arg ATTRIBUTE_UNUSED)
 {
   struct elf32_avr_stub_hash_entry *hsh;
-  struct elf32_avr_link_hash_table *htab;
 
-  htab = in_arg;
   hsh = avr_stub_hash_entry (bh);
   hsh->is_actually_needed = FALSE;
 
@@ -2454,8 +2609,10 @@ elf32_avr_setup_params (struct bfd_link_info *info,
                         bfd_vma pc_wrap_around,
                         bfd_boolean call_ret_replacement)
 {
-  struct elf32_avr_link_hash_table *htab = avr_link_hash_table(info);
+  struct elf32_avr_link_hash_table *htab = avr_link_hash_table (info);
 
+  if (htab == NULL)
+    return;
   htab->stub_sec = avr_stub_section;
   htab->stub_bfd = avr_stub_bfd;
   htab->no_stubs = no_stubs;
@@ -2483,9 +2640,9 @@ elf32_avr_setup_section_lists (bfd *output_bfd,
   asection *section;
   asection **input_list, **list;
   bfd_size_type amt;
-  struct elf32_avr_link_hash_table *htab = avr_link_hash_table(info);
+  struct elf32_avr_link_hash_table *htab = avr_link_hash_table (info);
 
-  if (htab->no_stubs)
+  if (htab == NULL || htab->no_stubs)
     return 0;
 
   /* Count the number of input BFDs and find the top input section id.  */
@@ -2546,11 +2703,15 @@ 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;
 
   /* 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)
@@ -2596,21 +2757,23 @@ elf32_avr_size_stubs (bfd *output_bfd,
                       struct bfd_link_info *info,
                       bfd_boolean is_prealloc_run)
 {
- struct elf32_avr_link_hash_table *htab;
- int stub_changed = 0;
 struct elf32_avr_link_hash_table *htab;
 int stub_changed = 0;
 
- htab = avr_link_hash_table (info);
+  htab = avr_link_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
 
- /* At this point we initialize htab->vector_base
-    To the start of the text output section.  */
- htab->vector_base = htab->stub_sec->output_section->vma;
 /* At this point we initialize htab->vector_base
+     To the start of the text output section.  */
 htab->vector_base = htab->stub_sec->output_section->vma;
 
- if (get_local_syms (info->input_bfds, info))
-   {
-     if (htab->all_local_syms)
-       goto error_ret_free_local;
-     return FALSE;
-   }
 if (get_local_syms (info->input_bfds, info))
+    {
+      if (htab->all_local_syms)
+       goto error_ret_free_local;
+      return FALSE;
+    }
 
   if (ADD_DUMMY_STUBS_FOR_DEBUGGING)
     {
@@ -2709,15 +2872,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
                     {
@@ -2856,6 +3024,8 @@ elf32_avr_build_stubs (struct bfd_link_info *info)
   bfd_size_type total_size = 0;
 
   htab = avr_link_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
 
   /* In case that there were several stub sections:  */
   for (stub_sec = htab->stub_bfd->sections;
@@ -2896,6 +3066,7 @@ elf32_avr_build_stubs (struct bfd_link_info *info)
 }
 
 #define ELF_ARCH               bfd_arch_avr
+#define ELF_TARGET_ID          AVR_ELF_DATA
 #define ELF_MACHINE_CODE       EM_AVR
 #define ELF_MACHINE_ALT1       EM_AVR_OLD
 #define ELF_MAXPAGESIZE                1
@@ -2909,7 +3080,6 @@ elf32_avr_build_stubs (struct bfd_link_info *info)
 #define elf_info_to_howto                   avr_info_to_howto_rela
 #define elf_info_to_howto_rel               NULL
 #define elf_backend_relocate_section         elf32_avr_relocate_section
-#define elf_backend_check_relocs             elf32_avr_check_relocs
 #define elf_backend_can_gc_sections          1
 #define elf_backend_rela_normal                     1
 #define elf_backend_final_write_processing \
This page took 0.041827 seconds and 4 git commands to generate.