gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / bfd / elf32-avr.c
index b95e251e1e05f06cb5d23eabfa95cdf4cfb5ab4b..d4ad18c82579f704cda765d65cf4277f3ff07f10 100644 (file)
@@ -1,5 +1,5 @@
 /* AVR-specific support for 32-bit ELF
-   Copyright (C) 1999-2016 Free Software Foundation, Inc.
+   Copyright (C) 1999-2020 Free Software Foundation, Inc.
    Contributed by Denis Chertykov <denisc@overta.ru>
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -25,7 +25,6 @@
 #include "elf-bfd.h"
 #include "elf/avr.h"
 #include "elf32-avr.h"
-#include "bfd_stdint.h"
 
 /* Enable debugging printout at stdout with this variable.  */
 static bfd_boolean debug_relax = FALSE;
@@ -88,9 +87,9 @@ struct elf32_avr_link_hash_table
   bfd_vma vector_base;
 
   /* Assorted information used by elf32_avr_size_stubs.  */
-  unsigned int        bfd_count;
-  unsigned int        top_index;
-  asection **         input_list;
+  unsigned int       bfd_count;
+  unsigned int       top_index;
+  asection **        input_list;
   Elf_Internal_Sym ** all_local_syms;
 
   /* Tables for mapping vma beyond the 128k boundary to the address of the
@@ -475,37 +474,37 @@ static reloc_howto_type elf_avr_howto_table[] =
         FALSE,                 /* partial_inplace */
         0xffff,                /* src_mask */
         0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        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.  */
-  HOWTO (R_AVR_LO8_LDI_GS,      /* type */
-         1,                     /* rightshift */
-         1,                     /* 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_LO8_LDI_GS",    /* name */
-         FALSE,                 /* partial_inplace */
-         0xffff,                /* src_mask */
-         0xffff,                /* dst_mask */
-         FALSE),                /* pcrel_offset */
+  HOWTO (R_AVR_LO8_LDI_GS,     /* type */
+        1,                     /* rightshift */
+        1,                     /* 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_LO8_LDI_GS",    /* name */
+        FALSE,                 /* partial_inplace */
+        0xffff,                /* src_mask */
+        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.  */
-  HOWTO (R_AVR_HI8_LDI_GS,      /* type */
-         9,                     /* rightshift */
-         1,                     /* 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_HI8_LDI_GS",    /* name */
-         FALSE,                 /* partial_inplace */
-         0xffff,                /* src_mask */
-         0xffff,                /* dst_mask */
-         FALSE),                /* pcrel_offset */
+  HOWTO (R_AVR_HI8_LDI_GS,     /* type */
+        9,                     /* rightshift */
+        1,                     /* 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_HI8_LDI_GS",    /* name */
+        FALSE,                 /* partial_inplace */
+        0xffff,                /* src_mask */
+        0xffff,                /* dst_mask */
+        FALSE),                /* pcrel_offset */
   /* 8 bit offset.  */
   HOWTO (R_AVR_8,              /* type */
         0,                     /* rightshift */
@@ -563,57 +562,57 @@ static reloc_howto_type elf_avr_howto_table[] =
         0xffffff,              /* dst_mask */
         FALSE),                /* pcrel_offset */
   HOWTO (R_AVR_DIFF8,          /* type */
-        0,                     /* rightshift */
-        0,                     /* size (0 = byte, 1 = short, 2 = long) */
-        8,                     /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
+        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_avr_diff_reloc, /* special_function */
-        "R_AVR_DIFF8",         /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xff,                  /* dst_mask */
-        FALSE),                /* pcrel_offset */
-  HOWTO (R_AVR_DIFF16,         /* type */
-        0,                     /* rightshift */
+        "R_AVR_DIFF8",         /* name */
+        FALSE,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xff,                  /* dst_mask */
+        FALSE),                /* pcrel_offset */
+  HOWTO (R_AVR_DIFF16,         /* type */
+        0,                     /* rightshift */
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
         bfd_elf_avr_diff_reloc,/* special_function */
-        "R_AVR_DIFF16",        /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
-  HOWTO (R_AVR_DIFF32,         /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
+        "R_AVR_DIFF16",        /* name */
+        FALSE,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffff,                /* dst_mask */
+        FALSE),                /* pcrel_offset */
+  HOWTO (R_AVR_DIFF32,         /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
         bfd_elf_avr_diff_reloc,/* special_function */
-        "R_AVR_DIFF32",        /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        "R_AVR_DIFF32",        /* name */
+        FALSE,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffffffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
   /* 7 bit immediate for LDS/STS in Tiny core.  */
   HOWTO (R_AVR_LDS_STS_16,  /* type */
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        7,                     /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
+        0,                     /* rightshift */
+        1,                     /* size (0 = byte, 1 = short, 2 = long) */
+        7,                     /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_AVR_LDS_STS_16",    /* name */
-        FALSE,                 /* partial_inplace */
-        0xffff,                /* src_mask */
-        0xffff,                /* dst_mask */
+        "R_AVR_LDS_STS_16",    /* name */
+        FALSE,                 /* partial_inplace */
+        0xffff,                /* src_mask */
+        0xffff,                /* dst_mask */
         FALSE),                /* pcrel_offset */
 
   HOWTO (R_AVR_PORT6,          /* type */
@@ -641,21 +640,21 @@ static reloc_howto_type elf_avr_howto_table[] =
         FALSE,                 /* partial_inplace */
         0xffffff,              /* src_mask */
         0xffffff,              /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* A 32 bit PC relative relocation.  */
   HOWTO (R_AVR_32_PCREL,       /* type */
-        0,                             /* rightshift */
-        2,                             /* size (0 = byte, 1 = short, 2 = long) */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
         TRUE,                  /* pc_relative */
-        0,                             /* bitpos */
+        0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_AVR_32_PCREL",      /* name */
         FALSE,                 /* partial_inplace */
-        0xffffffff,    /* src_mask */
-        0xffffffff,    /* dst_mask */
+        0xffffffff,            /* src_mask */
+        0xffffffff,            /* dst_mask */
         TRUE),                 /* pcrel_offset */
 };
 
@@ -669,43 +668,49 @@ struct avr_reloc_map
 
 static const struct avr_reloc_map avr_reloc_map[] =
 {
-  { BFD_RELOC_NONE,                 R_AVR_NONE },
-  { BFD_RELOC_32,                   R_AVR_32 },
-  { BFD_RELOC_AVR_7_PCREL,          R_AVR_7_PCREL },
-  { BFD_RELOC_AVR_13_PCREL,         R_AVR_13_PCREL },
-  { BFD_RELOC_16,                   R_AVR_16 },
-  { BFD_RELOC_AVR_16_PM,            R_AVR_16_PM },
-  { BFD_RELOC_AVR_LO8_LDI,          R_AVR_LO8_LDI},
-  { BFD_RELOC_AVR_HI8_LDI,          R_AVR_HI8_LDI },
-  { BFD_RELOC_AVR_HH8_LDI,          R_AVR_HH8_LDI },
-  { BFD_RELOC_AVR_MS8_LDI,          R_AVR_MS8_LDI },
-  { BFD_RELOC_AVR_LO8_LDI_NEG,      R_AVR_LO8_LDI_NEG },
-  { BFD_RELOC_AVR_HI8_LDI_NEG,      R_AVR_HI8_LDI_NEG },
-  { BFD_RELOC_AVR_HH8_LDI_NEG,      R_AVR_HH8_LDI_NEG },
-  { BFD_RELOC_AVR_MS8_LDI_NEG,      R_AVR_MS8_LDI_NEG },
-  { BFD_RELOC_AVR_LO8_LDI_PM,       R_AVR_LO8_LDI_PM },
-  { BFD_RELOC_AVR_LO8_LDI_GS,       R_AVR_LO8_LDI_GS },
-  { BFD_RELOC_AVR_HI8_LDI_PM,       R_AVR_HI8_LDI_PM },
-  { BFD_RELOC_AVR_HI8_LDI_GS,       R_AVR_HI8_LDI_GS },
-  { BFD_RELOC_AVR_HH8_LDI_PM,       R_AVR_HH8_LDI_PM },
+  { BFD_RELOC_NONE,                R_AVR_NONE },
+  { BFD_RELOC_32,                  R_AVR_32 },
+  { BFD_RELOC_AVR_7_PCREL,         R_AVR_7_PCREL },
+  { BFD_RELOC_AVR_13_PCREL,        R_AVR_13_PCREL },
+  { BFD_RELOC_16,                  R_AVR_16 },
+  { BFD_RELOC_AVR_16_PM,           R_AVR_16_PM },
+  { BFD_RELOC_AVR_LO8_LDI,         R_AVR_LO8_LDI},
+  { BFD_RELOC_AVR_HI8_LDI,         R_AVR_HI8_LDI },
+  { BFD_RELOC_AVR_HH8_LDI,         R_AVR_HH8_LDI },
+  { BFD_RELOC_AVR_MS8_LDI,         R_AVR_MS8_LDI },
+  { BFD_RELOC_AVR_LO8_LDI_NEG,     R_AVR_LO8_LDI_NEG },
+  { BFD_RELOC_AVR_HI8_LDI_NEG,     R_AVR_HI8_LDI_NEG },
+  { BFD_RELOC_AVR_HH8_LDI_NEG,     R_AVR_HH8_LDI_NEG },
+  { BFD_RELOC_AVR_MS8_LDI_NEG,     R_AVR_MS8_LDI_NEG },
+  { BFD_RELOC_AVR_LO8_LDI_PM,      R_AVR_LO8_LDI_PM },
+  { BFD_RELOC_AVR_LO8_LDI_GS,      R_AVR_LO8_LDI_GS },
+  { BFD_RELOC_AVR_HI8_LDI_PM,      R_AVR_HI8_LDI_PM },
+  { BFD_RELOC_AVR_HI8_LDI_GS,      R_AVR_HI8_LDI_GS },
+  { BFD_RELOC_AVR_HH8_LDI_PM,      R_AVR_HH8_LDI_PM },
   { BFD_RELOC_AVR_LO8_LDI_PM_NEG,   R_AVR_LO8_LDI_PM_NEG },
   { BFD_RELOC_AVR_HI8_LDI_PM_NEG,   R_AVR_HI8_LDI_PM_NEG },
   { BFD_RELOC_AVR_HH8_LDI_PM_NEG,   R_AVR_HH8_LDI_PM_NEG },
-  { 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_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 },
-  { BFD_RELOC_AVR_DIFF8,            R_AVR_DIFF8 },
-  { BFD_RELOC_AVR_DIFF16,           R_AVR_DIFF16 },
-  { BFD_RELOC_AVR_DIFF32,           R_AVR_DIFF32 },
-  { BFD_RELOC_AVR_LDS_STS_16,       R_AVR_LDS_STS_16},
-  { BFD_RELOC_AVR_PORT6,            R_AVR_PORT6},
-  { BFD_RELOC_AVR_PORT5,            R_AVR_PORT5},
-  { BFD_RELOC_32_PCREL,             R_AVR_32_PCREL}
+  { 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_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 },
+  { BFD_RELOC_AVR_DIFF8,           R_AVR_DIFF8 },
+  { BFD_RELOC_AVR_DIFF16,          R_AVR_DIFF16 },
+  { BFD_RELOC_AVR_DIFF32,          R_AVR_DIFF32 },
+  { BFD_RELOC_AVR_LDS_STS_16,      R_AVR_LDS_STS_16},
+  { BFD_RELOC_AVR_PORT6,           R_AVR_PORT6},
+  { BFD_RELOC_AVR_PORT5,           R_AVR_PORT5},
+  { BFD_RELOC_32_PCREL,                    R_AVR_32_PCREL}
+};
+
+static const struct bfd_elf_special_section elf_avr_special_sections[] =
+{
+  { STRING_COMMA_LEN (".noinit"), 0, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE },
+  { NULL, 0,                     0, 0,            0 }
 };
 
 /* Meant to be filled one day with the wrap around address for the
@@ -762,7 +767,7 @@ elf_avr_new_section_hook (bfd *abfd, asection *sec)
   if (!sec->used_by_bfd)
     {
       struct elf_avr_section_data *sdata;
-      bfd_size_type amt = sizeof (*sdata);
+      size_t amt = sizeof (*sdata);
 
       sdata = bfd_zalloc (abfd, amt);
       if (sdata == NULL)
@@ -804,17 +809,17 @@ init_avr_relax_info (asection *sec)
 
 static struct bfd_hash_entry *
 stub_hash_newfunc (struct bfd_hash_entry *entry,
-                   struct bfd_hash_table *table,
-                   const char *string)
+                  struct bfd_hash_table *table,
+                  const char *string)
 {
   /* Allocate the structure if it has not already been allocated by a
      subclass.  */
   if (entry == NULL)
     {
       entry = bfd_hash_allocate (table,
-                                 sizeof (struct elf32_avr_stub_hash_entry));
+                                sizeof (struct elf32_avr_stub_hash_entry));
       if (entry == NULL)
-        return entry;
+       return entry;
     }
 
   /* Call the allocation method of the superclass.  */
@@ -853,10 +858,8 @@ elf32_avr_link_hash_table_free (bfd *obfd)
     = (struct elf32_avr_link_hash_table *) obfd->link.hash;
 
   /* Free the address mapping table.  */
-  if (htab->amt_stub_offsets != NULL)
-    free (htab->amt_stub_offsets);
-  if (htab->amt_destination_addr != NULL)
-    free (htab->amt_destination_addr);
+  free (htab->amt_stub_offsets);
+  free (htab->amt_destination_addr);
 
   bfd_hash_table_free (&htab->bstab);
   _bfd_elf_link_hash_table_free (obfd);
@@ -870,15 +873,15 @@ static struct bfd_link_hash_table *
 elf32_avr_link_hash_table_create (bfd *abfd)
 {
   struct elf32_avr_link_hash_table *htab;
-  bfd_size_type amt = sizeof (*htab);
+  size_t amt = sizeof (*htab);
 
   htab = bfd_zmalloc (amt);
   if (htab == NULL)
     return NULL;
 
   if (!_bfd_elf_link_hash_table_init (&htab->etab, abfd,
-                                      elf32_avr_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);
@@ -887,7 +890,7 @@ elf32_avr_link_hash_table_create (bfd *abfd)
 
   /* Init the stub hash table too.  */
   if (!bfd_hash_table_init (&htab->bstab, stub_hash_newfunc,
-                            sizeof (struct elf32_avr_stub_hash_entry)))
+                           sizeof (struct elf32_avr_stub_hash_entry)))
     {
       _bfd_elf_link_hash_table_free (abfd);
       return NULL;
@@ -905,7 +908,7 @@ avr_relative_distance_considering_wrap_around (unsigned int distance)
   unsigned int wrap_around_mask = avr_pc_wrap_around - 1;
   int dist_with_wrap_around = distance & wrap_around_mask;
 
-  if (dist_with_wrap_around > ((int) (avr_pc_wrap_around >> 1)))
+  if (dist_with_wrap_around >= ((int) (avr_pc_wrap_around >> 1)))
     dist_with_wrap_around -= avr_pc_wrap_around;
 
   return dist_with_wrap_around;
@@ -945,8 +948,8 @@ bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
 
 /* Set the howto pointer for an AVR ELF reloc.  */
 
-static void
-avr_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
+static bfd_boolean
+avr_info_to_howto_rela (bfd *abfd,
                        arelent *cache_ptr,
                        Elf_Internal_Rela *dst)
 {
@@ -955,10 +958,14 @@ avr_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
   r_type = ELF32_R_TYPE (dst->r_info);
   if (r_type >= (unsigned int) R_AVR_max)
     {
-      _bfd_error_handler (_("%B: invalid AVR reloc number: %d"), abfd, r_type);
-      r_type = 0;
+      /* xgettext:c-format */
+      _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
+                         abfd, r_type);
+      bfd_set_error (bfd_error_bad_value);
+      return FALSE;
     }
   cache_ptr->howto = &elf_avr_howto_table[r_type];
+  return TRUE;
 }
 
 static bfd_boolean
@@ -974,11 +981,11 @@ avr_stub_is_required_for_16_bit_reloc (bfd_vma relocation)
 
 static bfd_vma
 avr_get_stub_addr (bfd_vma srel,
-                   struct elf32_avr_link_hash_table *htab)
+                  struct elf32_avr_link_hash_table *htab)
 {
   unsigned int sindex;
   bfd_vma stub_sec_addr =
-              (htab->stub_sec->output_section->vma +
+             (htab->stub_sec->output_section->vma +
               htab->stub_sec->output_offset);
 
   for (sindex = 0; sindex < htab->amt_max_entry_cnt; sindex ++)
@@ -995,11 +1002,11 @@ avr_get_stub_addr (bfd_vma srel,
 static bfd_reloc_status_type
 bfd_elf_avr_diff_reloc (bfd *abfd ATTRIBUTE_UNUSED,
                      arelent *reloc_entry ATTRIBUTE_UNUSED,
-              asymbol *symbol ATTRIBUTE_UNUSED,
-              void *data ATTRIBUTE_UNUSED,
-              asection *input_section ATTRIBUTE_UNUSED,
-              bfd *output_bfd ATTRIBUTE_UNUSED,
-              char **error_message ATTRIBUTE_UNUSED)
+             asymbol *symbol ATTRIBUTE_UNUSED,
+             void *data ATTRIBUTE_UNUSED,
+             asection *input_section ATTRIBUTE_UNUSED,
+             bfd *output_bfd ATTRIBUTE_UNUSED,
+             char **error_message ATTRIBUTE_UNUSED)
 {
   return bfd_reloc_ok;
 }
@@ -1009,21 +1016,21 @@ bfd_elf_avr_diff_reloc (bfd *abfd ATTRIBUTE_UNUSED,
    routines, but a few relocs, we have to do them ourselves.  */
 
 static bfd_reloc_status_type
-avr_final_link_relocate (reloc_howto_type *                 howto,
-                        bfd *                              input_bfd,
-                        asection *                         input_section,
-                        bfd_byte *                         contents,
-                        Elf_Internal_Rela *                rel,
-                         bfd_vma                            relocation,
-                         struct elf32_avr_link_hash_table * htab)
+avr_final_link_relocate (reloc_howto_type *                howto,
+                        bfd *                              input_bfd,
+                        asection *                         input_section,
+                        bfd_byte *                         contents,
+                        Elf_Internal_Rela *                rel,
+                        bfd_vma                            relocation,
+                        struct elf32_avr_link_hash_table * htab)
 {
   bfd_reloc_status_type r = bfd_reloc_ok;
-  bfd_vma               x;
+  bfd_vma              x;
   bfd_signed_vma       srel;
   bfd_signed_vma       reloc_addr;
-  bfd_boolean           use_stubs = FALSE;
+  bfd_boolean          use_stubs = FALSE;
   /* Usually is 0, unless we are generating code for a bootloader.  */
-  bfd_signed_vma        base_addr = htab->vector_base;
+  bfd_signed_vma       base_addr = htab->vector_base;
 
   /* Absolute addr of the reloc in the final excecutable.  */
   reloc_addr = rel->r_offset + input_section->output_section->vma
@@ -1069,7 +1076,7 @@ avr_final_link_relocate (reloc_howto_type *                 howto,
       /* Check for overflow.  */
       if (srel < -2048 || srel > 2047)
        {
-          /* Relative distance is too large.  */
+         /* Relative distance is too large.  */
 
          /* Always apply WRAPAROUND for avr2, avr25, and avr4.  */
          switch (bfd_get_mach (input_bfd))
@@ -1102,8 +1109,8 @@ avr_final_link_relocate (reloc_howto_type *                 howto,
       srel = (bfd_signed_vma) relocation + rel->r_addend;
       if (((srel > 0) && (srel & 0xffff) > 255)
          || ((srel < 0) && ((-srel) & 0xffff) > 128))
-        /* Remove offset for data/eeprom section.  */
-        return bfd_reloc_overflow;
+       /* Remove offset for data/eeprom section.  */
+       return bfd_reloc_overflow;
 
       x = bfd_get_16 (input_bfd, contents);
       x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
@@ -1118,7 +1125,7 @@ avr_final_link_relocate (reloc_howto_type *                 howto,
        return bfd_reloc_overflow;
       x = bfd_get_16 (input_bfd, contents);
       x = (x & 0xd3f8) | ((srel & 7) | ((srel & (3 << 3)) << 7)
-                       | ((srel & (1 << 5)) << 8));
+                      | ((srel & (1 << 5)) << 8));
       bfd_put_16 (input_bfd, x, contents);
       break;
 
@@ -1207,22 +1214,22 @@ avr_final_link_relocate (reloc_howto_type *                 howto,
       srel = (bfd_signed_vma) relocation + rel->r_addend;
 
       if (use_stubs
-          && avr_stub_is_required_for_16_bit_reloc (srel - base_addr))
-        {
-          bfd_vma old_srel = srel;
-
-          /* We need to use the address of the stub instead.  */
-          srel = avr_get_stub_addr (srel, htab);
-          if (debug_stubs)
-            printf ("LD: Using jump stub (at 0x%x) with destination 0x%x for "
-                    "reloc at address 0x%x.\n",
-                    (unsigned int) srel,
-                    (unsigned int) old_srel,
-                    (unsigned int) reloc_addr);
+         && avr_stub_is_required_for_16_bit_reloc (srel - base_addr))
+       {
+         bfd_vma old_srel = srel;
+
+         /* We need to use the address of the stub instead.  */
+         srel = avr_get_stub_addr (srel, htab);
+         if (debug_stubs)
+           printf ("LD: Using jump stub (at 0x%x) with destination 0x%x for "
+                   "reloc at address 0x%x.\n",
+                   (unsigned int) srel,
+                   (unsigned int) old_srel,
+                   (unsigned int) reloc_addr);
 
          if (avr_stub_is_required_for_16_bit_reloc (srel - base_addr))
            return bfd_reloc_outofrange;
-        }
+       }
 
       if (srel & 1)
        return bfd_reloc_outofrange;
@@ -1240,22 +1247,22 @@ avr_final_link_relocate (reloc_howto_type *                 howto,
       srel = (bfd_signed_vma) relocation + rel->r_addend;
 
       if (use_stubs
-          && avr_stub_is_required_for_16_bit_reloc (srel - base_addr))
-        {
-          bfd_vma old_srel = srel;
-
-          /* We need to use the address of the stub instead.  */
-          srel = avr_get_stub_addr (srel, htab);
-          if (debug_stubs)
-            printf ("LD: Using jump stub (at 0x%x) with destination 0x%x for "
-                    "reloc at address 0x%x.\n",
-                    (unsigned int) srel,
-                    (unsigned int) old_srel,
-                    (unsigned int) reloc_addr);
+         && avr_stub_is_required_for_16_bit_reloc (srel - base_addr))
+       {
+         bfd_vma old_srel = srel;
+
+         /* We need to use the address of the stub instead.  */
+         srel = avr_get_stub_addr (srel, htab);
+         if (debug_stubs)
+           printf ("LD: Using jump stub (at 0x%x) with destination 0x%x for "
+                   "reloc at address 0x%x.\n",
+                   (unsigned int) srel,
+                   (unsigned int) old_srel,
+                   (unsigned int) reloc_addr);
 
          if (avr_stub_is_required_for_16_bit_reloc (srel - base_addr))
            return bfd_reloc_outofrange;
-        }
+       }
 
       if (srel & 1)
        return bfd_reloc_outofrange;
@@ -1334,22 +1341,22 @@ avr_final_link_relocate (reloc_howto_type *                 howto,
       srel = (bfd_signed_vma) relocation + rel->r_addend;
 
       if (use_stubs
-          && avr_stub_is_required_for_16_bit_reloc (srel - base_addr))
-        {
-          bfd_vma old_srel = srel;
-
-          /* We need to use the address of the stub instead.  */
-          srel = avr_get_stub_addr (srel,htab);
-          if (debug_stubs)
-            printf ("LD: Using jump stub (at 0x%x) with destination 0x%x for "
-                    "reloc at address 0x%x.\n",
-                    (unsigned int) srel,
-                    (unsigned int) old_srel,
-                    (unsigned int) reloc_addr);
+         && avr_stub_is_required_for_16_bit_reloc (srel - base_addr))
+       {
+         bfd_vma old_srel = srel;
+
+         /* We need to use the address of the stub instead.  */
+         srel = avr_get_stub_addr (srel,htab);
+         if (debug_stubs)
+           printf ("LD: Using jump stub (at 0x%x) with destination 0x%x for "
+                   "reloc at address 0x%x.\n",
+                   (unsigned int) srel,
+                   (unsigned int) old_srel,
+                   (unsigned int) reloc_addr);
 
          if (avr_stub_is_required_for_16_bit_reloc (srel - base_addr))
            return bfd_reloc_outofrange;
-        }
+       }
 
       if (srel & 1)
        return bfd_reloc_outofrange;
@@ -1368,7 +1375,7 @@ avr_final_link_relocate (reloc_howto_type *                 howto,
       contents += rel->r_offset;
       srel = (bfd_signed_vma) relocation + rel->r_addend;
       if ((srel & 0xFFFF) < 0x40 || (srel & 0xFFFF) > 0xbf)
-        return bfd_reloc_outofrange;
+       return bfd_reloc_outofrange;
       srel = srel & 0x7f;
       x = bfd_get_16 (input_bfd, contents);
       x |= (srel & 0x0f) | ((srel & 0x30) << 5) | ((srel & 0x40) << 2);
@@ -1379,7 +1386,7 @@ avr_final_link_relocate (reloc_howto_type *                 howto,
       contents += rel->r_offset;
       srel = (bfd_signed_vma) relocation + rel->r_addend;
       if ((srel & 0xffff) > 0x3f)
-        return bfd_reloc_outofrange;
+       return bfd_reloc_outofrange;
       x = bfd_get_16 (input_bfd, contents);
       x = (x & 0xf9f0) | ((srel & 0x30) << 5) | (srel & 0x0f);
       bfd_put_16 (input_bfd, x, contents);
@@ -1389,7 +1396,7 @@ avr_final_link_relocate (reloc_howto_type *                 howto,
       contents += rel->r_offset;
       srel = (bfd_signed_vma) relocation + rel->r_addend;
       if ((srel & 0xffff) > 0x1f)
-        return bfd_reloc_outofrange;
+       return bfd_reloc_outofrange;
       x = bfd_get_16 (input_bfd, contents);
       x = (x & 0xff07) | ((srel & 0x1f) << 3);
       bfd_put_16 (input_bfd, x, contents);
@@ -1416,10 +1423,10 @@ elf32_avr_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
                            Elf_Internal_Sym *local_syms,
                            asection **local_sections)
 {
-  Elf_Internal_Shdr *           symtab_hdr;
+  Elf_Internal_Shdr *          symtab_hdr;
   struct elf_link_hash_entry ** sym_hashes;
-  Elf_Internal_Rela *           rel;
-  Elf_Internal_Rela *           relend;
+  Elf_Internal_Rela *          rel;
+  Elf_Internal_Rela *          relend;
   struct elf32_avr_link_hash_table * htab = avr_link_hash_table (info);
 
   if (htab == NULL)
@@ -1431,15 +1438,15 @@ elf32_avr_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
 
   for (rel = relocs; rel < relend; rel ++)
     {
-      reloc_howto_type *           howto;
-      unsigned long                r_symndx;
-      Elf_Internal_Sym *           sym;
-      asection *                   sec;
+      reloc_howto_type *          howto;
+      unsigned long               r_symndx;
+      Elf_Internal_Sym *          sym;
+      asection *                  sec;
       struct elf_link_hash_entry * h;
-      bfd_vma                      relocation;
-      bfd_reloc_status_type        r;
-      const char *                 name;
-      int                          r_type;
+      bfd_vma                     relocation;
+      bfd_reloc_status_type       r;
+      const char *                name;
+      int                         r_type;
 
       r_type = ELF32_R_TYPE (rel->r_info);
       r_symndx = ELF32_R_SYM (rel->r_info);
@@ -1456,7 +1463,7 @@ elf32_avr_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
 
          name = bfd_elf_string_from_elf_section
            (input_bfd, symtab_hdr->sh_link, sym->st_name);
-         name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
+         name = name == NULL ? bfd_section_name (sec) : name;
        }
       else
        {
@@ -1527,9 +1534,8 @@ elf32_avr_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
    file.  This gets the AVR architecture right based on the machine
    number.  */
 
-static void
-bfd_elf_avr_final_write_processing (bfd *abfd,
-                                   bfd_boolean linker ATTRIBUTE_UNUSED)
+static bfd_boolean
+bfd_elf_avr_final_write_processing (bfd *abfd)
 {
   unsigned long val;
 
@@ -1612,6 +1618,7 @@ bfd_elf_avr_final_write_processing (bfd *abfd,
   elf_elfheader (abfd)->e_machine = EM_AVR;
   elf_elfheader (abfd)->e_flags &= ~ EF_AVR_MACH;
   elf_elfheader (abfd)->e_flags |= val;
+  return _bfd_elf_final_write_processing (abfd);
 }
 
 /* Set the right machine number.  */
@@ -1712,8 +1719,8 @@ static bfd_boolean
 elf32_avr_is_diff_reloc (Elf_Internal_Rela *irel)
 {
   return (ELF32_R_TYPE (irel->r_info) == R_AVR_DIFF8
-          ||ELF32_R_TYPE (irel->r_info) == R_AVR_DIFF16
-          || ELF32_R_TYPE (irel->r_info) == R_AVR_DIFF32);
+         ||ELF32_R_TYPE (irel->r_info) == R_AVR_DIFF16
+         || ELF32_R_TYPE (irel->r_info) == R_AVR_DIFF32);
 }
 
 /* Reduce the diff value written in the section by count if the shrinked
@@ -1722,11 +1729,11 @@ elf32_avr_is_diff_reloc (Elf_Internal_Rela *irel)
 
 static void
 elf32_avr_adjust_diff_reloc_value (bfd *abfd,
-                                   struct bfd_section *isec,
-                                   Elf_Internal_Rela *irel,
-                                   bfd_vma symval,
-                                   bfd_vma shrinked_insn_address,
-                                   int count)
+                                  struct bfd_section *isec,
+                                  Elf_Internal_Rela *irel,
+                                  bfd_vma symval,
+                                  bfd_vma shrinked_insn_address,
+                                  int count)
 {
   unsigned char *reloc_contents = NULL;
   unsigned char *isec_contents = elf_section_data (isec)->this_hdr.contents;
@@ -1741,22 +1748,22 @@ elf32_avr_adjust_diff_reloc_value (bfd *abfd,
   reloc_contents = isec_contents + irel->r_offset;
 
   /* Read value written in object file. */
bfd_vma x = 0;
 bfd_signed_vma x = 0;
   switch (ELF32_R_TYPE (irel->r_info))
   {
   case R_AVR_DIFF8:
     {
-      x = *reloc_contents;
+      x = bfd_get_signed_8 (abfd, reloc_contents);
       break;
     }
   case R_AVR_DIFF16:
     {
-      x = bfd_get_16 (abfd, reloc_contents);
+      x = bfd_get_signed_16 (abfd, reloc_contents);
       break;
     }
   case R_AVR_DIFF32:
     {
-      x = bfd_get_32 (abfd, reloc_contents);
+      x = bfd_get_signed_32 (abfd, reloc_contents);
       break;
     }
   default:
@@ -1770,51 +1777,140 @@ elf32_avr_adjust_diff_reloc_value (bfd *abfd,
      symval (<start_of_section>) + reloc addend. Compute the start and end
      addresses and check if the shrinked insn falls between sym1 and sym2. */
 
-  bfd_vma end_address = symval + irel->r_addend;
-  bfd_vma start_address = end_address - x;
+  bfd_vma sym2_address = symval + irel->r_addend;
+  bfd_vma sym1_address = sym2_address - x;
+
+  /* Don't assume sym2 is bigger than sym1 - the difference
+     could be negative. Compute start and end addresses, and
+     use those to see if they span shrinked_insn_address. */
+
+  bfd_vma start_address = sym1_address < sym2_address
+    ? sym1_address : sym2_address;
+  bfd_vma end_address = sym1_address > sym2_address
+    ? sym1_address : sym2_address;
 
-  /* Reduce the diff value by count bytes and write it back into section
-    contents. */
 
   if (shrinked_insn_address >= start_address
-      && shrinked_insn_address <= end_address)
+      && shrinked_insn_address < end_address)
   {
+    /* Reduce the diff value by count bytes and write it back into section
+       contents. */
+    bfd_signed_vma new_diff = x < 0 ? x + count : x - count;
+
+    if (sym2_address > shrinked_insn_address)
+      irel->r_addend -= count;
+
     switch (ELF32_R_TYPE (irel->r_info))
     {
     case R_AVR_DIFF8:
       {
-        *reloc_contents = (x - count);
-        break;
+       bfd_put_signed_8 (abfd, new_diff, reloc_contents);
+       break;
       }
     case R_AVR_DIFF16:
       {
-        bfd_put_16 (abfd, (x - count) & 0xFFFF, reloc_contents);
-        break;
+       bfd_put_signed_16 (abfd, new_diff & 0xFFFF, reloc_contents);
+       break;
       }
     case R_AVR_DIFF32:
       {
-        bfd_put_32 (abfd, (x - count) & 0xFFFFFFFF, reloc_contents);
-        break;
+       bfd_put_signed_32 (abfd, new_diff & 0xFFFFFFFF, reloc_contents);
+       break;
       }
     default:
       {
-        BFD_FAIL();
+       BFD_FAIL();
       }
     }
 
   }
 }
 
+static void
+elf32_avr_adjust_reloc_if_spans_insn (bfd *abfd,
+                                     asection *isec,
+                                     Elf_Internal_Rela *irel,  bfd_vma symval,
+                                     bfd_vma shrinked_insn_address,
+                                     bfd_vma shrink_boundary,
+                                     int count)
+{
+
+  if (elf32_avr_is_diff_reloc (irel))
+    {
+      elf32_avr_adjust_diff_reloc_value (abfd, isec, irel,
+                                        symval,
+                                        shrinked_insn_address,
+                                        count);
+    }
+  else
+    {
+      bfd_vma reloc_value = symval + irel->r_addend;
+      bfd_boolean addend_within_shrink_boundary =
+       (reloc_value <= shrink_boundary);
+
+      bfd_boolean reloc_spans_insn =
+       (symval <= shrinked_insn_address
+        && reloc_value > shrinked_insn_address
+        && addend_within_shrink_boundary);
+
+      if (! reloc_spans_insn)
+       return;
+
+      irel->r_addend -= count;
+
+      if (debug_relax)
+       printf ("Relocation's addend needed to be fixed \n");
+    }
+}
+
+static bfd_boolean
+avr_should_move_sym (symvalue symval,
+                    bfd_vma start,
+                    bfd_vma end,
+                    bfd_boolean did_pad)
+{
+  bfd_boolean sym_within_boundary =
+         did_pad ? symval < end : symval <= end;
+  return (symval > start && sym_within_boundary);
+}
+
+static bfd_boolean
+avr_should_reduce_sym_size (symvalue symval,
+                           symvalue symend,
+                           bfd_vma start,
+                           bfd_vma end,
+                           bfd_boolean did_pad)
+{
+  bfd_boolean sym_end_within_boundary =
+         did_pad ? symend < end : symend <= end;
+  return (symval <= start && symend > start && sym_end_within_boundary);
+}
+
+static bfd_boolean
+avr_should_increase_sym_size (symvalue symval,
+                             symvalue symend,
+                             bfd_vma start,
+                             bfd_vma end,
+                             bfd_boolean did_pad)
+{
+  return avr_should_move_sym (symval, start, end, did_pad)
+         && symend >= end && did_pad;
+}
+
 /* Delete some bytes from a section while changing the size of an instruction.
    The parameter "addr" denotes the section-relative offset pointing just
    behind the shrinked instruction. "addr+count" point at the first
-   byte just behind the original unshrinked instruction.  */
+   byte just behind the original unshrinked instruction. If delete_shrinks_insn
+   is FALSE, we are deleting redundant padding bytes from relax_info prop
+   record handling. In that case, addr is section-relative offset of start
+   of padding, and count is the number of padding bytes to delete. */
 
 static bfd_boolean
 elf32_avr_relax_delete_bytes (bfd *abfd,
-                              asection *sec,
-                              bfd_vma addr,
-                              int count)
+                             asection *sec,
+                             bfd_vma addr,
+                             int count,
+                             bfd_boolean delete_shrinks_insn)
 {
   Elf_Internal_Shdr *symtab_hdr;
   unsigned int sec_shndx;
@@ -1829,6 +1925,7 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
   struct avr_relax_info *relax_info;
   struct avr_property_record *prop_record = NULL;
   bfd_boolean did_shrink = FALSE;
+  bfd_boolean did_pad = FALSE;
 
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
@@ -1840,23 +1937,23 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
   if (relax_info->records.count > 0)
     {
       /* There should be no property record within the range of deleted
-         bytes, however, there might be a property record for ADDR, this is
-         how we handle alignment directives.
-         Find the next (if any) property record after the deleted bytes.  */
+        bytes, however, there might be a property record for ADDR, this is
+        how we handle alignment directives.
+        Find the next (if any) property record after the deleted bytes.  */
       unsigned int i;
 
       for (i = 0; i < relax_info->records.count; ++i)
-        {
-          bfd_vma offset = relax_info->records.items [i].offset;
-
-          BFD_ASSERT (offset <= addr || offset >= (addr + count));
-          if (offset >= (addr + count))
-            {
-              prop_record = &relax_info->records.items [i];
-              toaddr = offset;
-              break;
-            }
-        }
+       {
+         bfd_vma offset = relax_info->records.items [i].offset;
+
+         BFD_ASSERT (offset <= addr || offset >= (addr + count));
+         if (offset >= (addr + count))
+           {
+             prop_record = &relax_info->records.items [i];
+             toaddr = offset;
+             break;
+           }
+       }
     }
 
   irel = elf_section_data (sec)->relocs;
@@ -1866,7 +1963,7 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
   if (toaddr - addr - count > 0)
     {
       memmove (contents + addr, contents + addr + count,
-               (size_t) (toaddr - addr - count));
+              (size_t) (toaddr - addr - count));
       did_shrink = TRUE;
     }
   if (prop_record == NULL)
@@ -1879,29 +1976,26 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
       /* Use the property record to fill in the bytes we've opened up.  */
       int fill = 0;
       switch (prop_record->type)
-        {
-        case RECORD_ORG_AND_FILL:
-          fill = prop_record->data.org.fill;
-          /* Fall through.  */
-        case RECORD_ORG:
-          break;
-        case RECORD_ALIGN_AND_FILL:
-          fill = prop_record->data.align.fill;
-          /* Fall through.  */
-        case RECORD_ALIGN:
-          prop_record->data.align.preceding_deleted += count;
-          break;
-        };
+       {
+       case RECORD_ORG_AND_FILL:
+         fill = prop_record->data.org.fill;
+         /* Fall through.  */
+       case RECORD_ORG:
+         break;
+       case RECORD_ALIGN_AND_FILL:
+         fill = prop_record->data.align.fill;
+         /* Fall through.  */
+       case RECORD_ALIGN:
+         prop_record->data.align.preceding_deleted += count;
+         break;
+       };
       /* If toaddr == (addr + count), then we didn't delete anything, yet
-         we fill count bytes backwards from toaddr. This is still ok - we
-         end up overwriting the bytes we would have deleted. We just need
-         to remember we didn't delete anything i.e. don't set did_shrink,
-         so that we don't corrupt reloc offsets or symbol values.*/
+        we fill count bytes backwards from toaddr. This is still ok - we
+        end up overwriting the bytes we would have deleted. We just need
+        to remember we didn't delete anything i.e. don't set did_shrink,
+        so that we don't corrupt reloc offsets or symbol values.*/
       memset (contents + toaddr - count, fill, count);
-
-      /* Adjust the TOADDR to avoid moving symbols located at the address
-         of the property record, which has not moved.  */
-      toaddr -= count;
+      did_pad = TRUE;
     }
 
   if (!did_shrink)
@@ -1913,28 +2007,28 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
       bfd_vma old_reloc_address;
 
       old_reloc_address = (sec->output_section->vma
-                           + sec->output_offset + irel->r_offset);
+                          + sec->output_offset + irel->r_offset);
 
       /* Get the new reloc address.  */
       if ((irel->r_offset > addr
-           && irel->r_offset < toaddr))
-        {
-          if (debug_relax)
-            printf ("Relocation at address 0x%x needs to be moved.\n"
-                    "Old section offset: 0x%x, New section offset: 0x%x \n",
-                    (unsigned int) old_reloc_address,
-                    (unsigned int) irel->r_offset,
-                    (unsigned int) ((irel->r_offset) - count));
-
-          irel->r_offset -= count;
-        }
+          && irel->r_offset < toaddr))
+       {
+         if (debug_relax)
+           printf ("Relocation at address 0x%x needs to be moved.\n"
+                   "Old section offset: 0x%x, New section offset: 0x%x \n",
+                   (unsigned int) old_reloc_address,
+                   (unsigned int) irel->r_offset,
+                   (unsigned int) ((irel->r_offset) - count));
+
+         irel->r_offset -= count;
+       }
 
     }
 
    /* The reloc's own addresses are now ok. However, we need to readjust
       the reloc's addend, i.e. the reloc's value if two conditions are met:
       1.) the reloc is relative to a symbol in this section that
-          is located in front of the shrinked instruction
+         is located in front of the shrinked instruction
       2.) symbol plus addend end up behind the shrinked instruction.
 
       The most common case where this happens are relocs relative to
@@ -1954,73 +2048,70 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
         continue;
 
        shrinked_insn_address = (sec->output_section->vma
-                                + sec->output_offset + addr - count);
+                               + sec->output_offset + addr);
+       if (delete_shrinks_insn)
+        shrinked_insn_address -= count;
 
        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);
+        irel = _bfd_elf_link_read_relocs (abfd, isec, NULL, NULL, TRUE);
 
        for (irelend = irel + isec->reloc_count;
-            irel < irelend;
-            irel++)
-         {
-           /* 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)
-                 return FALSE;
-             }
-
-           /* 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.  */
-               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 == sec)
-                 {
-                   symval += sym_sec->output_section->vma
-                             + sym_sec->output_offset;
-
-                   if (debug_relax)
-                     printf ("Checking if the relocation's "
-                             "addend needs corrections.\n"
-                             "Address of anchor symbol: 0x%x \n"
-                             "Address of relocation target: 0x%x \n"
-                             "Address of relaxed insn: 0x%x \n",
-                             (unsigned int) symval,
-                             (unsigned int) (symval + irel->r_addend),
-                             (unsigned int) shrinked_insn_address);
-
-                   if (symval <= shrinked_insn_address
-                       && (symval + irel->r_addend) > shrinked_insn_address)
-                     {
-                       if (elf32_avr_is_diff_reloc (irel))
-                         {
-                           elf32_avr_adjust_diff_reloc_value (abfd, isec, irel,
-                                                         symval,
-                                                         shrinked_insn_address,
-                                                        count);
-                         }
-
-                       irel->r_addend -= count;
-
-                       if (debug_relax)
-                         printf ("Relocation's addend needed to be fixed \n");
-                     }
-                 }
+           irel < irelend;
+           irel++)
+        {
+          /* 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)
+                return FALSE;
+            }
+
+          /* 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.  */
+              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 == sec)
+                {
+                  /* If there is an alignment boundary, we only need to
+                     adjust addends that end up below the boundary. */
+                  bfd_vma shrink_boundary = (toaddr
+                                             + sec->output_section->vma
+                                             + sec->output_offset);
+
+                  symval += sym_sec->output_section->vma
+                            + sym_sec->output_offset;
+
+                  if (debug_relax)
+                    printf ("Checking if the relocation's "
+                            "addend needs corrections.\n"
+                            "Address of anchor symbol: 0x%x \n"
+                            "Address of relocation target: 0x%x \n"
+                            "Address of relaxed insn: 0x%x \n",
+                            (unsigned int) symval,
+                            (unsigned int) (symval + irel->r_addend),
+                            (unsigned int) shrinked_insn_address);
+
+                  elf32_avr_adjust_reloc_if_spans_insn (abfd, isec, irel,
+                                                        symval,
+                                                        shrinked_insn_address,
+                                                        shrink_boundary,
+                                                        count);
+                }
               /* else...Reference symbol is absolute.  No adjustment needed.  */
             }
           /* else...Reference symbol is extern.  No need for adjusting
@@ -2040,51 +2131,59 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
       for (; isym < isymend; isym++)
        {
          if (isym->st_shndx == sec_shndx)
-            {
-             if (isym->st_value > addr
-                  && isym->st_value <= toaddr)
-                isym->st_value -= count;
-
-              if (isym->st_value <= addr
-                  && isym->st_value + isym->st_size > addr)
-                {
-                  /* If this assert fires then we have a symbol that ends
-                     part way through an instruction.  Does that make
-                     sense?  */
-                  BFD_ASSERT (isym->st_value + isym->st_size >= addr + count);
-                  isym->st_size -= count;
-                }
-            }
+           {
+             symvalue symval = isym->st_value;
+             symvalue symend = symval + isym->st_size;
+             if (avr_should_reduce_sym_size (symval, symend,
+                                     addr, toaddr, did_pad))
+               {
+                 /* If this assert fires then we have a symbol that ends
+                    part way through an instruction.  Does that make
+                    sense?  */
+                 BFD_ASSERT (isym->st_value + isym->st_size >= addr + count);
+                 isym->st_size -= count;
+               }
+             else if (avr_should_increase_sym_size (symval, symend,
+                                     addr, toaddr, did_pad))
+               isym->st_size += count;
+
+             if (avr_should_move_sym (symval, addr, toaddr, did_pad))
+               isym->st_value -= count;
+           }
        }
     }
 
   /* Now adjust the global symbols defined in this section.  */
   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
-              - symtab_hdr->sh_info);
+             - 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)
-        {
-          if (sym_hash->root.u.def.value > addr
-              && sym_hash->root.u.def.value <= toaddr)
-            sym_hash->root.u.def.value -= count;
-
-          if (sym_hash->root.u.def.value <= addr
-              && (sym_hash->root.u.def.value + sym_hash->size > addr))
-            {
-              /* If this assert fires then we have a symbol that ends
-                 part way through an instruction.  Does that make
-                 sense?  */
-              BFD_ASSERT (sym_hash->root.u.def.value + sym_hash->size
-                          >= addr + count);
-              sym_hash->size -= count;
-            }
-        }
+          || sym_hash->root.type == bfd_link_hash_defweak)
+         && sym_hash->root.u.def.section == sec)
+       {
+         symvalue symval = sym_hash->root.u.def.value;
+         symvalue symend = symval + sym_hash->size;
+
+         if (avr_should_reduce_sym_size (symval, symend,
+                                 addr, toaddr, did_pad))
+           {
+             /* If this assert fires then we have a symbol that ends
+                part way through an instruction.  Does that make
+                sense?  */
+             BFD_ASSERT (symend >= addr + count);
+             sym_hash->size -= count;
+           }
+         else if (avr_should_increase_sym_size (symval, symend,
+                                 addr, toaddr, did_pad))
+             sym_hash->size += count;
+
+         if (avr_should_move_sym (symval, addr, toaddr, did_pad))
+           sym_hash->root.u.def.value -= count;
+       }
     }
 
   return TRUE;
@@ -2148,8 +2247,8 @@ get_elf_r_symndx_section (bfd *abfd, unsigned long r_symndx)
       struct elf_link_hash_entry *h = elf_sym_hashes (abfd)[indx];
 
       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;
+            || h->root.type == bfd_link_hash_warning)
+       h = (struct elf_link_hash_entry *) h->root.u.i.link;
 
       switch (h->root.type)
        {
@@ -2193,10 +2292,10 @@ get_elf_r_symndx_offset (bfd *abfd, unsigned long r_symndx)
        elf_sym_hashes (abfd)[indx];
 
       while (h->root.type == bfd_link_hash_indirect
-             || h->root.type == bfd_link_hash_warning)
+            || h->root.type == bfd_link_hash_warning)
        h = (struct elf_link_hash_entry *) h->root.u.i.link;
       if (h->root.type == bfd_link_hash_defined
-          || h->root.type == bfd_link_hash_defweak)
+         || h->root.type == bfd_link_hash_defweak)
        offset = h->root.u.def.value;
     }
   return offset;
@@ -2219,21 +2318,21 @@ avr_elf32_assign_records_to_sections (struct avr_property_record_list *r_list)
       BFD_ASSERT (relax_info != NULL);
 
       if (relax_info->records.count
-          == relax_info->records.allocated)
-        {
-          /* Allocate more space.  */
-          bfd_size_type size;
-
-          relax_info->records.allocated += 10;
-          size = (sizeof (struct avr_property_record)
-                  * relax_info->records.allocated);
-          relax_info->records.items
-            = bfd_realloc (relax_info->records.items, size);
-        }
+         == relax_info->records.allocated)
+       {
+         /* Allocate more space.  */
+         bfd_size_type size;
+
+         relax_info->records.allocated += 10;
+         size = (sizeof (struct avr_property_record)
+                 * relax_info->records.allocated);
+         relax_info->records.items
+           = bfd_realloc (relax_info->records.items, size);
+       }
 
       memcpy (&relax_info->records.items [relax_info->records.count],
-              &r_list->records [i],
-              sizeof (struct avr_property_record));
+             &r_list->records [i],
+             sizeof (struct avr_property_record));
       relax_info->records.count++;
     }
 }
@@ -2253,8 +2352,7 @@ avr_property_record_compare (const void *ap, const void *bp)
     return (a->offset - b->offset);
 
   if (a->section != b->section)
-    return (bfd_get_section_vma (a->section->owner, a->section)
-            - bfd_get_section_vma (b->section->owner, b->section));
+    return bfd_section_vma (a->section) - bfd_section_vma (b->section);
 
   return (a->type - b->type);
 }
@@ -2284,7 +2382,7 @@ avr_load_all_property_sections (struct bfd_link_info *link_info)
 
       r_list = avr_elf32_load_property_records (abfd);
       if (r_list != NULL)
-        avr_elf32_assign_records_to_sections (r_list);
+       avr_elf32_assign_records_to_sections (r_list);
 
       free (r_list);
     }
@@ -2294,32 +2392,32 @@ avr_load_all_property_sections (struct bfd_link_info *link_info)
   for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link.next)
     for (sec = abfd->sections; sec != NULL; sec = sec->next)
       {
-        struct avr_relax_info *relax_info = get_avr_relax_info (sec);
-        if (relax_info && relax_info->records.count > 0)
-          {
-            unsigned int i;
-
-            qsort (relax_info->records.items,
-                   relax_info->records.count,
-                   sizeof (struct avr_property_record),
-                   avr_property_record_compare);
-
-            /* For debug purposes, list all the descriptors.  */
-            for (i = 0; i < relax_info->records.count; ++i)
-              {
-                switch (relax_info->records.items [i].type)
-                  {
-                  case RECORD_ORG:
-                    break;
-                  case RECORD_ORG_AND_FILL:
-                    break;
-                  case RECORD_ALIGN:
-                    break;
-                  case RECORD_ALIGN_AND_FILL:
-                    break;
-                  };
-              }
-          }
+       struct avr_relax_info *relax_info = get_avr_relax_info (sec);
+       if (relax_info && relax_info->records.count > 0)
+         {
+           unsigned int i;
+
+           qsort (relax_info->records.items,
+                  relax_info->records.count,
+                  sizeof (struct avr_property_record),
+                  avr_property_record_compare);
+
+           /* For debug purposes, list all the descriptors.  */
+           for (i = 0; i < relax_info->records.count; ++i)
+             {
+               switch (relax_info->records.items [i].type)
+                 {
+                 case RECORD_ORG:
+                   break;
+                 case RECORD_ORG_AND_FILL:
+                   break;
+                 case RECORD_ALIGN:
+                   break;
+                 case RECORD_ALIGN_AND_FILL:
+                   break;
+                 };
+             }
+         }
       }
 }
 
@@ -2357,8 +2455,8 @@ avr_load_all_property_sections (struct bfd_link_info *link_info)
 static bfd_boolean
 elf32_avr_relax_section (bfd *abfd,
                         asection *sec,
-                         struct bfd_link_info *link_info,
-                         bfd_boolean *again)
+                        struct bfd_link_info *link_info,
+                        bfd_boolean *again)
 {
   Elf_Internal_Shdr *symtab_hdr;
   Elf_Internal_Rela *internal_relocs;
@@ -2404,19 +2502,19 @@ elf32_avr_relax_section (bfd *abfd,
       bfd_size_type last_estimated_stub_section_size = htab->stub_sec->size;
 
       if (debug_relax)
-        printf ("Relaxing the stub section. Size prior to this pass: %i\n",
-                (int) last_estimated_stub_section_size);
+       printf ("Relaxing the stub section. Size prior to this pass: %i\n",
+               (int) last_estimated_stub_section_size);
 
       elf32_avr_size_stubs (htab->stub_sec->output_section->owner,
-                            link_info, FALSE);
+                           link_info, FALSE);
 
       /* Check if the number of trampolines changed.  */
       if (last_estimated_stub_section_size != htab->stub_sec->size)
-        *again = TRUE;
+       *again = TRUE;
 
       if (debug_relax)
-        printf ("Size of stub section after this pass: %i\n",
-                (int) htab->stub_sec->size);
+       printf ("Size of stub section after this pass: %i\n",
+               (int) htab->stub_sec->size);
 
       return TRUE;
     }
@@ -2439,7 +2537,7 @@ elf32_avr_relax_section (bfd *abfd,
 
   /* Get a copy of the native relocations.  */
   internal_relocs = (_bfd_elf_link_read_relocs
-                     (abfd, sec, NULL, NULL, link_info->keep_memory));
+                    (abfd, sec, NULL, NULL, link_info->keep_memory));
   if (internal_relocs == NULL)
     goto error_return;
 
@@ -2452,114 +2550,126 @@ elf32_avr_relax_section (bfd *abfd,
       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)
-        continue;
+       continue;
 
       /* Get the section contents if we haven't done so already.  */
       if (contents == NULL)
-        {
-          /* Get cached copy if it exists.  */
-          if (elf_section_data (sec)->this_hdr.contents != NULL)
-            contents = elf_section_data (sec)->this_hdr.contents;
-          else
-            {
-              /* Go get them off disk.  */
-              if (! bfd_malloc_and_get_section (abfd, sec, &contents))
-                goto error_return;
-            }
-        }
+       {
+         /* Get cached copy if it exists.  */
+         if (elf_section_data (sec)->this_hdr.contents != NULL)
+           contents = elf_section_data (sec)->this_hdr.contents;
+         else
+           {
+             /* Go get them off disk.  */
+             if (! bfd_malloc_and_get_section (abfd, sec, &contents))
+               goto error_return;
+           }
+       }
 
       /* 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)
-            goto error_return;
-        }
+       {
+         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)
+           goto error_return;
+       }
 
 
       /* 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;
-        }
+       {
+         /* 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;
+       }
       else
-        {
-          unsigned long indx;
-          struct elf_link_hash_entry *h;
-
-          /* An external symbol.  */
-          indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
-          h = elf_sym_hashes (abfd)[indx];
-          BFD_ASSERT (h != NULL);
-          if (h->root.type != bfd_link_hash_defined
-              && h->root.type != bfd_link_hash_defweak)
+       {
+         unsigned long indx;
+         struct elf_link_hash_entry *h;
+
+         /* An external symbol.  */
+         indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
+         h = elf_sym_hashes (abfd)[indx];
+         BFD_ASSERT (h != NULL);
+         if (h->root.type != bfd_link_hash_defined
+             && h->root.type != bfd_link_hash_defweak)
            /* This appears to be a reference to an undefined
               symbol.  Just ignore it--it will be caught by the
               regular reloc processing.  */
            continue;
 
-          symval = (h->root.u.def.value
-                    + h->root.u.def.section->output_section->vma
-                    + h->root.u.def.section->output_offset);
-        }
+         symval = (h->root.u.def.value
+                   + h->root.u.def.section->output_section->vma
+                   + h->root.u.def.section->output_offset);
+       }
 
       /* For simplicity of coding, we are going to modify the section
-         contents, the section relocs, and the BFD symbol table.  We
-         must tell the rest of the code not to free up this
-         information.  It would be possible to instead create a table
-         of changes which have to be made, as is done in coff-mips.c;
-         that would be more work, but would require less memory when
-         the linker is run.  */
+        contents, the section relocs, and the BFD symbol table.  We
+        must tell the rest of the code not to free up this
+        information.  It would be possible to instead create a table
+        of changes which have to be made, as is done in coff-mips.c;
+        that would be more work, but would require less memory when
+        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:
-          {
-            bfd_vma value = symval + irel->r_addend;
-            bfd_vma dot, gap;
-            int distance_short_enough = 0;
-
-            /* Get the address of this instruction.  */
-            dot = (sec->output_section->vma
-                   + sec->output_offset + irel->r_offset);
-
-            /* Compute the distance from this insn to the branch target.  */
-            gap = value - dot;
-
-            /* 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
-               we could use a rjmp to jump from address 0x100 to 0x3d00!
-               In order to make this work properly, we need to fill the
-               vaiable avr_pc_wrap_around with the appropriate value.
-               I.e. 0x4000 for a 16k device.  */
-            {
+         {
+           bfd_vma value = symval + irel->r_addend;
+           bfd_vma dot, gap;
+           int distance_short_enough = 0;
+
+           /* Get the address of this instruction.  */
+           dot = (sec->output_section->vma
+                  + sec->output_offset + irel->r_offset);
+
+           /* Compute the distance from this insn to the branch target.  */
+           gap = value - dot;
+
+           /* The ISA manual states that addressable range is PC - 2k + 1 to
+              PC + 2k. In bytes, that would be -4094 <= PC <= 4096. The range
+              is shifted one word to the right, because pc-relative instructions
+              implicitly add one word i.e. rjmp 0 jumps to next insn, not the
+              current one.
+              Therefore, for the !shrinkable case, the range is as above.
+              If shrinkable, then the current code only deletes bytes 3 and
+              4 of the absolute call/jmp, so the forward jump range increases
+              by 2 bytes, but the backward (negative) jump range remains
+              the same. */
+
+
+           /* 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 >= -4094 && (int) gap <= 4096))
+             distance_short_enough = 1;
+           /* If shrinkable, then we can check for a range of distance which
+              is two bytes farther on the positive direction because the call
+              or jump target will be closer by two bytes after the
+              relaxation. */
+           else if (shrinkable && ((int) gap >= -4094 && (int) gap <= 4098))
+             distance_short_enough = 1;
+
+           /* Here we handle the wrap-around case.  E.g. for a 16k device
+              we could use a rjmp to jump from address 0x100 to 0x3d00!
+              In order to make this work properly, we need to fill the
+              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
@@ -2581,256 +2691,258 @@ elf32_avr_relax_section (bfd *abfd,
              if (rgap >= (-4092 + safety_margin)
                  && rgap <= (4094 - safety_margin))
                distance_short_enough = 1;
-            }
-
-            if (distance_short_enough)
-              {
-                unsigned char code_msb;
-                unsigned char code_lsb;
-
-                if (debug_relax)
-                  printf ("shrinking jump/call instruction at address 0x%x"
-                          " in section %s\n\n",
-                          (int) dot, sec->name);
-
-                /* Note that we've changed the relocs, section contents,
-                   etc.  */
-                elf_section_data (sec)->relocs = internal_relocs;
-                elf_section_data (sec)->this_hdr.contents = contents;
-                symtab_hdr->contents = (unsigned char *) isymbuf;
-
-                /* Get the instruction code for relaxing.  */
-                code_lsb = bfd_get_8 (abfd, contents + irel->r_offset);
-                code_msb = bfd_get_8 (abfd, contents + irel->r_offset + 1);
-
-                /* Mask out the relocation bits.  */
-                code_msb &= 0x94;
-                code_lsb &= 0x0E;
-                if (code_msb == 0x94 && code_lsb == 0x0E)
-                  {
-                    /* we are changing call -> rcall .  */
-                    bfd_put_8 (abfd, 0x00, contents + irel->r_offset);
-                    bfd_put_8 (abfd, 0xD0, contents + irel->r_offset + 1);
-                  }
-                else if (code_msb == 0x94 && code_lsb == 0x0C)
-                  {
-                    /* we are changeing jump -> rjmp.  */
-                    bfd_put_8 (abfd, 0x00, contents + irel->r_offset);
-                    bfd_put_8 (abfd, 0xC0, contents + irel->r_offset + 1);
-                  }
-                else
-                  abort ();
-
-                /* Fix the relocation's type.  */
-                irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
-                                             R_AVR_13_PCREL);
-
-                /* 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);
-                    bfd_put_8 (abfd, 0x00, contents + irel->r_offset + 3);
-                  }
-                else
-                  {
-                    /* Delete two bytes of data.  */
-                    if (!elf32_avr_relax_delete_bytes (abfd, sec,
-                                                       irel->r_offset + 2, 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;
-                  }
-              }
-          }
-
-        default:
-          {
-            unsigned char code_msb;
-            unsigned char code_lsb;
-            bfd_vma dot;
-
-            code_msb = bfd_get_8 (abfd, contents + irel->r_offset + 1);
-            code_lsb = bfd_get_8 (abfd, contents + irel->r_offset + 0);
-
-            /* Get the address of this instruction.  */
-            dot = (sec->output_section->vma
-                   + sec->output_offset + irel->r_offset);
-
-            /* Here we look for rcall/ret or call/ret sequences that could be
-               safely replaced by rjmp/ret or jmp/ret.  */
-            if (((code_msb & 0xf0) == 0xd0)
-                && avr_replace_call_ret_sequences)
-              {
-                /* This insn is a rcall.  */
-                unsigned char next_insn_msb = 0;
-                unsigned char next_insn_lsb = 0;
-
-                if (irel->r_offset + 3 < sec->size)
-                  {
-                    next_insn_msb =
+           }
+
+           if (distance_short_enough)
+             {
+               unsigned char code_msb;
+               unsigned char code_lsb;
+
+               if (debug_relax)
+                 printf ("shrinking jump/call instruction at address 0x%x"
+                         " in section %s\n\n",
+                         (int) dot, sec->name);
+
+               /* Note that we've changed the relocs, section contents,
+                  etc.  */
+               elf_section_data (sec)->relocs = internal_relocs;
+               elf_section_data (sec)->this_hdr.contents = contents;
+               symtab_hdr->contents = (unsigned char *) isymbuf;
+
+               /* Get the instruction code for relaxing.  */
+               code_lsb = bfd_get_8 (abfd, contents + irel->r_offset);
+               code_msb = bfd_get_8 (abfd, contents + irel->r_offset + 1);
+
+               /* Mask out the relocation bits.  */
+               code_msb &= 0x94;
+               code_lsb &= 0x0E;
+               if (code_msb == 0x94 && code_lsb == 0x0E)
+                 {
+                   /* we are changing call -> rcall .  */
+                   bfd_put_8 (abfd, 0x00, contents + irel->r_offset);
+                   bfd_put_8 (abfd, 0xD0, contents + irel->r_offset + 1);
+                 }
+               else if (code_msb == 0x94 && code_lsb == 0x0C)
+                 {
+                   /* we are changeing jump -> rjmp.  */
+                   bfd_put_8 (abfd, 0x00, contents + irel->r_offset);
+                   bfd_put_8 (abfd, 0xC0, contents + irel->r_offset + 1);
+                 }
+               else
+                 abort ();
+
+               /* Fix the relocation's type.  */
+               irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+                                            R_AVR_13_PCREL);
+
+               /* 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);
+                   bfd_put_8 (abfd, 0x00, contents + irel->r_offset + 3);
+                 }
+               else
+                 {
+                   /* Delete two bytes of data.  */
+                   if (!elf32_avr_relax_delete_bytes (abfd, sec,
+                                                      irel->r_offset + 2, 2,
+                                                      TRUE))
+                     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;
+                 }
+             }
+         }
+         /* Fall through.  */
+
+       default:
+         {
+           unsigned char code_msb;
+           unsigned char code_lsb;
+           bfd_vma dot;
+
+           code_msb = bfd_get_8 (abfd, contents + irel->r_offset + 1);
+           code_lsb = bfd_get_8 (abfd, contents + irel->r_offset + 0);
+
+           /* Get the address of this instruction.  */
+           dot = (sec->output_section->vma
+                  + sec->output_offset + irel->r_offset);
+
+           /* Here we look for rcall/ret or call/ret sequences that could be
+              safely replaced by rjmp/ret or jmp/ret.  */
+           if (((code_msb & 0xf0) == 0xd0)
+               && avr_replace_call_ret_sequences)
+             {
+               /* This insn is a rcall.  */
+               unsigned char next_insn_msb = 0;
+               unsigned char next_insn_lsb = 0;
+
+               if (irel->r_offset + 3 < sec->size)
+                 {
+                   next_insn_msb =
                      bfd_get_8 (abfd, contents + irel->r_offset + 3);
-                    next_insn_lsb =
+                   next_insn_lsb =
                      bfd_get_8 (abfd, contents + irel->r_offset + 2);
-                  }
+                 }
 
                if ((0x95 == next_insn_msb) && (0x08 == next_insn_lsb))
-                  {
-                    /* The next insn is a ret. We now convert the rcall insn
-                       into a rjmp instruction.  */
-                    code_msb &= 0xef;
-                    bfd_put_8 (abfd, code_msb, contents + irel->r_offset + 1);
-                    if (debug_relax)
-                      printf ("converted rcall/ret sequence at address 0x%x"
-                              " into rjmp/ret sequence. Section is %s\n\n",
-                              (int) dot, sec->name);
-                    *again = TRUE;
-                    break;
-                  }
-              }
-            else if ((0x94 == (code_msb & 0xfe))
+                 {
+                   /* The next insn is a ret. We now convert the rcall insn
+                      into a rjmp instruction.  */
+                   code_msb &= 0xef;
+                   bfd_put_8 (abfd, code_msb, contents + irel->r_offset + 1);
+                   if (debug_relax)
+                     printf ("converted rcall/ret sequence at address 0x%x"
+                             " into rjmp/ret sequence. Section is %s\n\n",
+                             (int) dot, sec->name);
+                   *again = TRUE;
+                   break;
+                 }
+             }
+           else if ((0x94 == (code_msb & 0xfe))
                     && (0x0e == (code_lsb & 0x0e))
                     && avr_replace_call_ret_sequences)
-              {
-                /* This insn is a call.  */
-                unsigned char next_insn_msb = 0;
-                unsigned char next_insn_lsb = 0;
-
-                if (irel->r_offset + 5 < sec->size)
-                  {
-                    next_insn_msb =
+             {
+               /* This insn is a call.  */
+               unsigned char next_insn_msb = 0;
+               unsigned char next_insn_lsb = 0;
+
+               if (irel->r_offset + 5 < sec->size)
+                 {
+                   next_insn_msb =
                      bfd_get_8 (abfd, contents + irel->r_offset + 5);
-                    next_insn_lsb =
+                   next_insn_lsb =
                      bfd_get_8 (abfd, contents + irel->r_offset + 4);
-                  }
-
-                if ((0x95 == next_insn_msb) && (0x08 == next_insn_lsb))
-                  {
-                    /* The next insn is a ret. We now convert the call insn
-                       into a jmp instruction.  */
-
-                    code_lsb &= 0xfd;
-                    bfd_put_8 (abfd, code_lsb, contents + irel->r_offset);
-                    if (debug_relax)
-                      printf ("converted call/ret sequence at address 0x%x"
-                              " into jmp/ret sequence. Section is %s\n\n",
-                              (int) dot, sec->name);
-                    *again = TRUE;
-                    break;
-                  }
-              }
-            else if ((0xc0 == (code_msb & 0xf0))
-                     || ((0x94 == (code_msb & 0xfe))
-                         && (0x0c == (code_lsb & 0x0e))))
-              {
-                /* This insn is a rjmp or a jmp.  */
-                unsigned char next_insn_msb = 0;
-                unsigned char next_insn_lsb = 0;
-                int insn_size;
-
-                if (0xc0 == (code_msb & 0xf0))
-                  insn_size = 2; /* rjmp insn */
-                else
-                  insn_size = 4; /* jmp insn */
-
-                if (irel->r_offset + insn_size + 1 < sec->size)
-                  {
-                    next_insn_msb =
+                 }
+
+               if ((0x95 == next_insn_msb) && (0x08 == next_insn_lsb))
+                 {
+                   /* The next insn is a ret. We now convert the call insn
+                      into a jmp instruction.  */
+
+                   code_lsb &= 0xfd;
+                   bfd_put_8 (abfd, code_lsb, contents + irel->r_offset);
+                   if (debug_relax)
+                     printf ("converted call/ret sequence at address 0x%x"
+                             " into jmp/ret sequence. Section is %s\n\n",
+                             (int) dot, sec->name);
+                   *again = TRUE;
+                   break;
+                 }
+             }
+           else if ((0xc0 == (code_msb & 0xf0))
+                    || ((0x94 == (code_msb & 0xfe))
+                        && (0x0c == (code_lsb & 0x0e))))
+             {
+               /* This insn is a rjmp or a jmp.  */
+               unsigned char next_insn_msb = 0;
+               unsigned char next_insn_lsb = 0;
+               int insn_size;
+
+               if (0xc0 == (code_msb & 0xf0))
+                 insn_size = 2; /* rjmp insn */
+               else
+                 insn_size = 4; /* jmp insn */
+
+               if (irel->r_offset + insn_size + 1 < sec->size)
+                 {
+                   next_insn_msb =
                      bfd_get_8 (abfd, contents + irel->r_offset
                                 + insn_size + 1);
-                    next_insn_lsb =
+                   next_insn_lsb =
                      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 preceding
-                       sbis/sbic/sbrs or cpse "skip" instructions.  */
-
-                    int there_is_preceding_non_skip_insn = 1;
-                    bfd_vma address_of_ret;
-
-                    address_of_ret = dot + insn_size;
-
-                    if (debug_relax && (insn_size == 2))
-                      printf ("found rjmp / ret sequence at address 0x%x\n",
-                              (int) dot);
-                    if (debug_relax && (insn_size == 4))
-                      printf ("found jmp / ret sequence at address 0x%x\n",
-                              (int) dot);
+                 }
 
-                    /* We have to make sure that there is a preceding insn.  */
-                    if (irel->r_offset >= 2)
-                      {
-                        unsigned char preceding_msb;
-                        unsigned char preceding_lsb;
-
-                        preceding_msb =
+               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 preceding
+                      sbis/sbic/sbrs or cpse "skip" instructions.  */
+
+                   int there_is_preceding_non_skip_insn = 1;
+                   bfd_vma address_of_ret;
+
+                   address_of_ret = dot + insn_size;
+
+                   if (debug_relax && (insn_size == 2))
+                     printf ("found rjmp / ret sequence at address 0x%x\n",
+                             (int) dot);
+                   if (debug_relax && (insn_size == 4))
+                     printf ("found jmp / ret sequence at address 0x%x\n",
+                             (int) dot);
+
+                   /* We have to make sure that there is a preceding insn.  */
+                   if (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 =
+                       preceding_lsb =
                          bfd_get_8 (abfd, contents + irel->r_offset - 2);
 
-                        /* sbic.  */
-                        if (0x99 == preceding_msb)
-                          there_is_preceding_non_skip_insn = 0;
+                       /* sbic.  */
+                       if (0x99 == preceding_msb)
+                         there_is_preceding_non_skip_insn = 0;
 
-                        /* sbis.  */
-                        if (0x9b == preceding_msb)
-                          there_is_preceding_non_skip_insn = 0;
+                       /* sbis.  */
+                       if (0x9b == preceding_msb)
+                         there_is_preceding_non_skip_insn = 0;
 
-                        /* sbrc */
-                        if ((0xfc == (preceding_msb & 0xfe)
+                       /* sbrc */
+                       if ((0xfc == (preceding_msb & 0xfe)
                             && (0x00 == (preceding_lsb & 0x08))))
-                          there_is_preceding_non_skip_insn = 0;
+                         there_is_preceding_non_skip_insn = 0;
 
-                        /* sbrs */
-                        if ((0xfe == (preceding_msb & 0xfe)
+                       /* sbrs */
+                       if ((0xfe == (preceding_msb & 0xfe)
                             && (0x00 == (preceding_lsb & 0x08))))
-                          there_is_preceding_non_skip_insn = 0;
-
-                        /* cpse */
-                        if (0x10 == (preceding_msb & 0xfc))
-                          there_is_preceding_non_skip_insn = 0;
-
-                        if (there_is_preceding_non_skip_insn == 0)
-                          if (debug_relax)
-                            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_preceding_non_skip_insn = 0;
-                      }
-
-                    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
-                           instruction and that there is no local relocation
-                           in this section pointing to the ret.  */
-
-                        int deleting_ret_is_safe = 1;
-                        unsigned int section_offset_of_ret_insn =
+                         there_is_preceding_non_skip_insn = 0;
+
+                       /* cpse */
+                       if (0x10 == (preceding_msb & 0xfc))
+                         there_is_preceding_non_skip_insn = 0;
+
+                       if (there_is_preceding_non_skip_insn == 0)
+                         if (debug_relax)
+                           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_preceding_non_skip_insn = 0;
+                     }
+
+                   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
+                          instruction and that there is no local relocation
+                          in this section pointing to the ret.  */
+
+                       int deleting_ret_is_safe = 1;
+                       unsigned int section_offset_of_ret_insn =
                          irel->r_offset + insn_size;
-                        Elf_Internal_Sym *isym, *isymend;
-                        unsigned int sec_shndx;
+                       Elf_Internal_Sym *isym, *isymend;
+                       unsigned int sec_shndx;
                        struct bfd_section *isec;
 
-                        sec_shndx =
+                       sec_shndx =
                          _bfd_elf_section_from_bfd_section (abfd, sec);
 
-                        /* Check for local symbols.  */
-                        isym = (Elf_Internal_Sym *) symtab_hdr->contents;
-                        isymend = isym + symtab_hdr->sh_info;
+                       /* Check for local symbols.  */
+                       isym = (Elf_Internal_Sym *) symtab_hdr->contents;
+                       isymend = isym + symtab_hdr->sh_info;
                        /* PR 6019: There may not be any local symbols.  */
-                        for (; isym != NULL && isym < isymend; isym++)
+                       for (; isym != NULL && isym < isymend; isym++)
                          {
                            if (isym->st_value == section_offset_of_ret_insn
                                && isym->st_shndx == sec_shndx)
@@ -2961,7 +3073,8 @@ elf32_avr_relax_section (bfd *abfd,
 
                            /* Delete two bytes of data.  */
                            if (!elf32_avr_relax_delete_bytes (abfd, sec,
-                                                              irel->r_offset + insn_size, 2))
+                                                              irel->r_offset + insn_size, 2,
+                                                              TRUE))
                              goto error_return;
 
                            /* That will change things, so, we should relax
@@ -2970,102 +3083,98 @@ elf32_avr_relax_section (bfd *abfd,
                            *again = TRUE;
                            break;
                          }
-                      }
-                  }
-              }
-            break;
-          }
-        }
+                     }
+                 }
+             }
+           break;
+         }
+       }
     }
 
   if (!*again)
     {
       /* Look through all the property records in this section to see if
-         there's any alignment records that can be moved.  */
+        there's any alignment records that can be moved.  */
       struct avr_relax_info *relax_info;
 
       relax_info = get_avr_relax_info (sec);
       if (relax_info->records.count > 0)
-        {
-          unsigned int i;
-
-          for (i = 0; i < relax_info->records.count; ++i)
-            {
-              switch (relax_info->records.items [i].type)
-                {
-                case RECORD_ORG:
-                case RECORD_ORG_AND_FILL:
-                  break;
-                case RECORD_ALIGN:
-                case RECORD_ALIGN_AND_FILL:
-                  {
-                    struct avr_property_record *record;
-                    unsigned long bytes_to_align;
-                    int count = 0;
-
-                    /* Look for alignment directives that have had enough
-                       bytes deleted before them, such that the directive
-                       can be moved backwards and still maintain the
-                       required alignment.  */
-                    record = &relax_info->records.items [i];
-                    bytes_to_align
-                      = (unsigned long) (1 << record->data.align.bytes);
-                    while (record->data.align.preceding_deleted >=
-                           bytes_to_align)
-                      {
-                        record->data.align.preceding_deleted
-                          -= bytes_to_align;
-                        count += bytes_to_align;
-                      }
-
-                    if (count > 0)
-                      {
-                        bfd_vma addr = record->offset;
-
-                        /* We can delete COUNT bytes and this alignment
-                           directive will still be correctly aligned.
-                           First move the alignment directive, then delete
-                           the bytes.  */
-                        record->offset -= count;
-                        elf32_avr_relax_delete_bytes (abfd, sec,
-                                                      addr - count,
-                                                      count);
-                        *again = TRUE;
-                      }
-                  }
-                  break;
-                }
-            }
-        }
+       {
+         unsigned int i;
+
+         for (i = 0; i < relax_info->records.count; ++i)
+           {
+             switch (relax_info->records.items [i].type)
+               {
+               case RECORD_ORG:
+               case RECORD_ORG_AND_FILL:
+                 break;
+               case RECORD_ALIGN:
+               case RECORD_ALIGN_AND_FILL:
+                 {
+                   struct avr_property_record *record;
+                   unsigned long bytes_to_align;
+                   int count = 0;
+
+                   /* Look for alignment directives that have had enough
+                      bytes deleted before them, such that the directive
+                      can be moved backwards and still maintain the
+                      required alignment.  */
+                   record = &relax_info->records.items [i];
+                   bytes_to_align
+                     = (unsigned long) (1 << record->data.align.bytes);
+                   while (record->data.align.preceding_deleted >=
+                          bytes_to_align)
+                     {
+                       record->data.align.preceding_deleted
+                         -= bytes_to_align;
+                       count += bytes_to_align;
+                     }
+
+                   if (count > 0)
+                     {
+                       bfd_vma addr = record->offset;
+
+                       /* We can delete COUNT bytes and this alignment
+                          directive will still be correctly aligned.
+                          First move the alignment directive, then delete
+                          the bytes.  */
+                       record->offset -= count;
+                       elf32_avr_relax_delete_bytes (abfd, sec,
+                                                     addr - count,
+                                                     count, FALSE);
+                       *again = TRUE;
+                     }
+                 }
+                 break;
+               }
+           }
+       }
     }
 
   if (contents != NULL
       && elf_section_data (sec)->this_hdr.contents != contents)
     {
       if (! link_info->keep_memory)
-        free (contents);
+       free (contents);
       else
-        {
-          /* Cache the section contents for elf_link_input_bfd.  */
-          elf_section_data (sec)->this_hdr.contents = contents;
-        }
+       {
+         /* Cache the section contents for elf_link_input_bfd.  */
+         elf_section_data (sec)->this_hdr.contents = contents;
+       }
     }
 
-  if (internal_relocs != NULL
-      && elf_section_data (sec)->relocs != internal_relocs)
+  if (elf_section_data (sec)->relocs != internal_relocs)
     free (internal_relocs);
 
   return TRUE;
 
  error_return:
-  if (isymbuf != NULL
-      && symtab_hdr->contents != (unsigned char *) isymbuf)
+  if (symtab_hdr->contents != (unsigned char *) isymbuf)
     free (isymbuf);
-  if (contents != NULL
-      && elf_section_data (sec)->this_hdr.contents != contents)
+  if (elf_section_data (sec)->this_hdr.contents != contents)
     free (contents);
-  if (internal_relocs != NULL
-      && elf_section_data (sec)->relocs != internal_relocs)
+  if (elf_section_data (sec)->relocs != internal_relocs)
     free (internal_relocs);
 
   return FALSE;
@@ -3081,11 +3190,11 @@ elf32_avr_relax_section (bfd *abfd,
 
 static bfd_byte *
 elf32_avr_get_relocated_section_contents (bfd *output_bfd,
-                                          struct bfd_link_info *link_info,
-                                          struct bfd_link_order *link_order,
-                                          bfd_byte *data,
-                                          bfd_boolean relocatable,
-                                          asymbol **symbols)
+                                         struct bfd_link_info *link_info,
+                                         struct bfd_link_order *link_order,
+                                         bfd_byte *data,
+                                         bfd_boolean relocatable,
+                                         asymbol **symbols)
 {
   Elf_Internal_Shdr *symtab_hdr;
   asection *input_section = link_order->u.indirect.section;
@@ -3099,13 +3208,13 @@ elf32_avr_get_relocated_section_contents (bfd *output_bfd,
   if (relocatable
       || elf_section_data (input_section)->this_hdr.contents == NULL)
     return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
-                                                       link_order, data,
-                                                       relocatable,
-                                                       symbols);
+                                                      link_order, data,
+                                                      relocatable,
+                                                      symbols);
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
 
   memcpy (data, elf_section_data (input_section)->this_hdr.contents,
-          (size_t) input_section->size);
+         (size_t) input_section->size);
 
   if ((input_section->flags & SEC_RELOC) != 0
       && input_section->reloc_count > 0)
@@ -3115,68 +3224,63 @@ elf32_avr_get_relocated_section_contents (bfd *output_bfd,
       bfd_size_type amt;
 
       internal_relocs = (_bfd_elf_link_read_relocs
-                         (input_bfd, input_section, NULL, NULL, FALSE));
+                        (input_bfd, input_section, NULL, NULL, FALSE));
       if (internal_relocs == NULL)
-        goto error_return;
+       goto error_return;
 
       if (symtab_hdr->sh_info != 0)
-        {
-          isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
-          if (isymbuf == NULL)
-            isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
-                                            symtab_hdr->sh_info, 0,
-                                            NULL, NULL, NULL);
-          if (isymbuf == NULL)
-            goto error_return;
-        }
+       {
+         isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+         if (isymbuf == NULL)
+           isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
+                                           symtab_hdr->sh_info, 0,
+                                           NULL, NULL, NULL);
+         if (isymbuf == NULL)
+           goto error_return;
+       }
 
       amt = symtab_hdr->sh_info;
       amt *= sizeof (asection *);
       sections = bfd_malloc (amt);
       if (sections == NULL && amt != 0)
-        goto error_return;
+       goto error_return;
 
       isymend = isymbuf + symtab_hdr->sh_info;
       for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
-        {
-          asection *isec;
-
-          if (isym->st_shndx == SHN_UNDEF)
-            isec = bfd_und_section_ptr;
-          else if (isym->st_shndx == SHN_ABS)
-            isec = bfd_abs_section_ptr;
-          else if (isym->st_shndx == SHN_COMMON)
-            isec = bfd_com_section_ptr;
-          else
-            isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
-
-          *secpp = isec;
-        }
+       {
+         asection *isec;
+
+         if (isym->st_shndx == SHN_UNDEF)
+           isec = bfd_und_section_ptr;
+         else if (isym->st_shndx == SHN_ABS)
+           isec = bfd_abs_section_ptr;
+         else if (isym->st_shndx == SHN_COMMON)
+           isec = bfd_com_section_ptr;
+         else
+           isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
+
+         *secpp = isec;
+       }
 
       if (! elf32_avr_relocate_section (output_bfd, link_info, input_bfd,
-                                        input_section, data, internal_relocs,
-                                        isymbuf, sections))
-        goto error_return;
-
-      if (sections != NULL)
-        free (sections);
-      if (isymbuf != NULL
-          && symtab_hdr->contents != (unsigned char *) isymbuf)
-        free (isymbuf);
+                                       input_section, data, internal_relocs,
+                                       isymbuf, sections))
+       goto error_return;
+
+      free (sections);
+      if (symtab_hdr->contents != (unsigned char *) isymbuf)
+       free (isymbuf);
       if (elf_section_data (input_section)->relocs != internal_relocs)
-        free (internal_relocs);
+       free (internal_relocs);
     }
 
   return data;
 
  error_return:
-  if (sections != NULL)
-    free (sections);
-  if (isymbuf != NULL
-      && symtab_hdr->contents != (unsigned char *) isymbuf)
+  free (sections);
+  if (symtab_hdr->contents != (unsigned char *) isymbuf)
     free (isymbuf);
-  if (internal_relocs != NULL
-      && elf_section_data (input_section)->relocs != internal_relocs)
+  if (elf_section_data (input_section)->relocs != internal_relocs)
     free (internal_relocs);
   return NULL;
 }
@@ -3188,18 +3292,18 @@ elf32_avr_get_relocated_section_contents (bfd *output_bfd,
 
 static char *
 avr_stub_name (const asection *symbol_section,
-               const bfd_vma symbol_offset,
-               const Elf_Internal_Rela *rela)
+              const bfd_vma symbol_offset,
+              const Elf_Internal_Rela *rela)
 {
   char *stub_name;
   bfd_size_type len;
 
   len = 8 + 1 + 8 + 1 + 1;
   stub_name = bfd_malloc (len);
-
-  sprintf (stub_name, "%08x+%08x",
-           symbol_section->id & 0xffffffff,
-           (unsigned int) ((rela->r_addend & 0xffffffff) + symbol_offset));
+  if (stub_name != NULL)
+    sprintf (stub_name, "%08x+%08x",
+            symbol_section->id & 0xffffffff,
+            (unsigned int) ((rela->r_addend & 0xffffffff) + symbol_offset));
 
   return stub_name;
 }
@@ -3210,7 +3314,7 @@ avr_stub_name (const asection *symbol_section,
 
 static struct elf32_avr_stub_hash_entry *
 avr_add_stub (const char *stub_name,
-              struct elf32_avr_link_hash_table *htab)
+             struct elf32_avr_link_hash_table *htab)
 {
   struct elf32_avr_stub_hash_entry *hsh;
 
@@ -3219,8 +3323,8 @@ avr_add_stub (const char *stub_name,
 
   if (hsh == NULL)
     {
-      (*_bfd_error_handler) (_("%B: cannot create stub entry %s"),
-                             NULL, stub_name);
+      /* xgettext:c-format */
+      _bfd_error_handler (_("cannot create stub entry %s"), stub_name);
       return NULL;
     }
 
@@ -3272,8 +3376,8 @@ avr_build_one_stub (struct bfd_hash_entry *bh, void *in_arg)
 
   if (debug_stubs)
     printf ("Building one Stub. Address: 0x%x, Offset: 0x%x\n",
-             (unsigned int) target,
-             (unsigned int) hsh->stub_offset);
+            (unsigned int) target,
+            (unsigned int) hsh->stub_offset);
 
   /* We now have to add the information on the jump target to the bare
      opcode bits already set in jmp_insn.  */
@@ -3297,10 +3401,10 @@ avr_build_one_stub (struct bfd_hash_entry *bh, void *in_arg)
     nr = htab->amt_entry_cnt + 1;
     if (nr <= htab->amt_max_entry_cnt)
       {
-        htab->amt_entry_cnt = nr;
+       htab->amt_entry_cnt = nr;
 
-        htab->amt_stub_offsets[nr - 1] = hsh->stub_offset;
-        htab->amt_destination_addr[nr - 1] = target;
+       htab->amt_stub_offsets[nr - 1] = hsh->stub_offset;
+       htab->amt_destination_addr[nr - 1] = target;
       }
   }
 
@@ -3309,7 +3413,7 @@ 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 ATTRIBUTE_UNUSED)
+                                  void *in_arg ATTRIBUTE_UNUSED)
 {
   struct elf32_avr_stub_hash_entry *hsh;
 
@@ -3341,13 +3445,13 @@ avr_size_one_stub (struct bfd_hash_entry *bh, void *in_arg)
 
 void
 elf32_avr_setup_params (struct bfd_link_info *info,
-                        bfd *avr_stub_bfd,
-                        asection *avr_stub_section,
-                        bfd_boolean no_stubs,
-                        bfd_boolean deb_stubs,
-                        bfd_boolean deb_relax,
-                        bfd_vma pc_wrap_around,
-                        bfd_boolean call_ret_replacement)
+                       bfd *avr_stub_bfd,
+                       asection *avr_stub_section,
+                       bfd_boolean no_stubs,
+                       bfd_boolean deb_stubs,
+                       bfd_boolean deb_relax,
+                       bfd_vma pc_wrap_around,
+                       bfd_boolean call_ret_replacement)
 {
   struct elf32_avr_link_hash_table *htab = avr_link_hash_table (info);
 
@@ -3372,14 +3476,14 @@ elf32_avr_setup_params (struct bfd_link_info *info,
 
 int
 elf32_avr_setup_section_lists (bfd *output_bfd,
-                               struct bfd_link_info *info)
+                              struct bfd_link_info *info)
 {
   bfd *input_bfd;
   unsigned int bfd_count;
   unsigned int top_id, top_index;
   asection *section;
   asection **input_list, **list;
-  bfd_size_type amt;
+  size_t amt;
   struct elf32_avr_link_hash_table *htab = avr_link_hash_table (info);
 
   if (htab == NULL || htab->no_stubs)
@@ -3392,8 +3496,8 @@ elf32_avr_setup_section_lists (bfd *output_bfd,
     {
       bfd_count += 1;
       for (section = input_bfd->sections;
-           section != NULL;
-           section = section->next)
+          section != NULL;
+          section = section->next)
        if (top_id < section->id)
          top_id = section->id;
     }
@@ -3443,7 +3547,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;
+  size_t amt;
 
   if (htab == NULL)
     return -1;
@@ -3494,8 +3598,8 @@ get_local_syms (bfd *input_bfd, struct bfd_link_info *info)
 
 bfd_boolean
 elf32_avr_size_stubs (bfd *output_bfd,
-                      struct bfd_link_info *info,
-                      bfd_boolean is_prealloc_run)
+                     struct bfd_link_info *info,
+                     bfd_boolean is_prealloc_run)
 {
   struct elf32_avr_link_hash_table *htab;
   int stub_changed = 0;
@@ -3534,89 +3638,89 @@ elf32_avr_size_stubs (bfd *output_bfd,
       unsigned int bfd_indx;
 
       /* We will have to re-generate the stub hash table each time anything
-         in memory has changed.  */
+        in memory has changed.  */
 
       bfd_hash_traverse (&htab->bstab, avr_mark_stub_not_to_be_necessary, htab);
       for (input_bfd = info->input_bfds, bfd_indx = 0;
-           input_bfd != NULL;
-           input_bfd = input_bfd->link.next, bfd_indx++)
-        {
-          Elf_Internal_Shdr *symtab_hdr;
-          asection *section;
-          Elf_Internal_Sym *local_syms;
-
-          /* We'll need the symbol table in a second.  */
-          symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
-          if (symtab_hdr->sh_info == 0)
-            continue;
-
-          local_syms = htab->all_local_syms[bfd_indx];
-
-          /* Walk over each section attached to the input bfd.  */
-          for (section = input_bfd->sections;
-               section != NULL;
-               section = section->next)
-            {
-              Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
-
-              /* If there aren't any relocs, then there's nothing more
-                 to do.  */
-              if ((section->flags & SEC_RELOC) == 0
-                  || section->reloc_count == 0)
-                continue;
-
-              /* If this section is a link-once section that will be
-                 discarded, then don't create any stubs.  */
-              if (section->output_section == NULL
-                  || section->output_section->owner != output_bfd)
-                continue;
-
-              /* Get the relocs.  */
-              internal_relocs
-                = _bfd_elf_link_read_relocs (input_bfd, section, NULL, NULL,
-                                             info->keep_memory);
-              if (internal_relocs == NULL)
-                goto error_ret_free_local;
-
-              /* Now examine each relocation.  */
-              irela = internal_relocs;
-              irelaend = irela + section->reloc_count;
-              for (; irela < irelaend; irela++)
-                {
-                  unsigned int r_type, r_indx;
-                  struct elf32_avr_stub_hash_entry *hsh;
-                  asection *sym_sec;
-                  bfd_vma sym_value;
-                  bfd_vma destination;
-                  struct elf_link_hash_entry *hh;
-                  char *stub_name;
-
-                  r_type = ELF32_R_TYPE (irela->r_info);
-                  r_indx = ELF32_R_SYM (irela->r_info);
-
-                  /* Only look for 16 bit GS relocs. No other reloc will need a
-                     stub.  */
-                  if (!((r_type == R_AVR_16_PM)
-                        || (r_type == R_AVR_LO8_LDI_GS)
-                        || (r_type == R_AVR_HI8_LDI_GS)))
-                    continue;
-
-                  /* Now determine the call target, its name, value,
-                     section.  */
-                  sym_sec = NULL;
-                  sym_value = 0;
-                  destination = 0;
-                  hh = NULL;
-                  if (r_indx < symtab_hdr->sh_info)
-                    {
-                      /* It's a local symbol.  */
-                      Elf_Internal_Sym *sym;
-                      Elf_Internal_Shdr *hdr;
+          input_bfd != NULL;
+          input_bfd = input_bfd->link.next, bfd_indx++)
+       {
+         Elf_Internal_Shdr *symtab_hdr;
+         asection *section;
+         Elf_Internal_Sym *local_syms;
+
+         /* We'll need the symbol table in a second.  */
+         symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+         if (symtab_hdr->sh_info == 0)
+           continue;
+
+         local_syms = htab->all_local_syms[bfd_indx];
+
+         /* Walk over each section attached to the input bfd.  */
+         for (section = input_bfd->sections;
+              section != NULL;
+              section = section->next)
+           {
+             Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
+
+             /* If there aren't any relocs, then there's nothing more
+                to do.  */
+             if ((section->flags & SEC_RELOC) == 0
+                 || section->reloc_count == 0)
+               continue;
+
+             /* If this section is a link-once section that will be
+                discarded, then don't create any stubs.  */
+             if (section->output_section == NULL
+                 || section->output_section->owner != output_bfd)
+               continue;
+
+             /* Get the relocs.  */
+             internal_relocs
+               = _bfd_elf_link_read_relocs (input_bfd, section, NULL, NULL,
+                                            info->keep_memory);
+             if (internal_relocs == NULL)
+               goto error_ret_free_local;
+
+             /* Now examine each relocation.  */
+             irela = internal_relocs;
+             irelaend = irela + section->reloc_count;
+             for (; irela < irelaend; irela++)
+               {
+                 unsigned int r_type, r_indx;
+                 struct elf32_avr_stub_hash_entry *hsh;
+                 asection *sym_sec;
+                 bfd_vma sym_value;
+                 bfd_vma destination;
+                 struct elf_link_hash_entry *hh;
+                 char *stub_name;
+
+                 r_type = ELF32_R_TYPE (irela->r_info);
+                 r_indx = ELF32_R_SYM (irela->r_info);
+
+                 /* Only look for 16 bit GS relocs. No other reloc will need a
+                    stub.  */
+                 if (!((r_type == R_AVR_16_PM)
+                       || (r_type == R_AVR_LO8_LDI_GS)
+                       || (r_type == R_AVR_HI8_LDI_GS)))
+                   continue;
+
+                 /* Now determine the call target, its name, value,
+                    section.  */
+                 sym_sec = NULL;
+                 sym_value = 0;
+                 destination = 0;
+                 hh = NULL;
+                 if (r_indx < symtab_hdr->sh_info)
+                   {
+                     /* It's a local symbol.  */
+                     Elf_Internal_Sym *sym;
+                     Elf_Internal_Shdr *hdr;
                      unsigned int shndx;
 
-                      sym = local_syms + r_indx;
-                      if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
-                        sym_value = sym->st_value;
+                     sym = local_syms + r_indx;
+                     if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
+                       sym_value = sym->st_value;
                      shndx = sym->st_shndx;
                      if (shndx < elf_numsections (input_bfd))
                        {
@@ -3626,116 +3730,116 @@ elf32_avr_size_stubs (bfd *output_bfd,
                                         + sym_sec->output_offset
                                         + sym_sec->output_section->vma);
                        }
-                    }
-                  else
-                    {
-                      /* It's an external symbol.  */
-                      int e_indx;
-
-                      e_indx = r_indx - symtab_hdr->sh_info;
-                      hh = elf_sym_hashes (input_bfd)[e_indx];
-
-                      while (hh->root.type == bfd_link_hash_indirect
-                             || hh->root.type == bfd_link_hash_warning)
-                        hh = (struct elf_link_hash_entry *)
-                              (hh->root.u.i.link);
-
-                      if (hh->root.type == bfd_link_hash_defined
-                          || hh->root.type == bfd_link_hash_defweak)
-                        {
-                          sym_sec = hh->root.u.def.section;
-                          sym_value = hh->root.u.def.value;
-                          if (sym_sec->output_section != NULL)
-                          destination = (sym_value + irela->r_addend
-                                         + sym_sec->output_offset
-                                         + sym_sec->output_section->vma);
-                        }
-                      else if (hh->root.type == bfd_link_hash_undefweak)
-                        {
-                          if (! bfd_link_pic (info))
-                            continue;
-                        }
-                      else if (hh->root.type == bfd_link_hash_undefined)
-                        {
-                          if (! (info->unresolved_syms_in_objects == RM_IGNORE
-                                 && (ELF_ST_VISIBILITY (hh->other)
-                                     == STV_DEFAULT)))
-                             continue;
-                        }
-                      else
-                        {
-                          bfd_set_error (bfd_error_bad_value);
-
-                          error_ret_free_internal:
-                          if (elf_section_data (section)->relocs == NULL)
-                            free (internal_relocs);
-                          goto error_ret_free_local;
-                        }
-                    }
-
-                  if (! avr_stub_is_required_for_16_bit_reloc
+                   }
+                 else
+                   {
+                     /* It's an external symbol.  */
+                     int e_indx;
+
+                     e_indx = r_indx - symtab_hdr->sh_info;
+                     hh = elf_sym_hashes (input_bfd)[e_indx];
+
+                     while (hh->root.type == bfd_link_hash_indirect
+                            || hh->root.type == bfd_link_hash_warning)
+                       hh = (struct elf_link_hash_entry *)
+                             (hh->root.u.i.link);
+
+                     if (hh->root.type == bfd_link_hash_defined
+                         || hh->root.type == bfd_link_hash_defweak)
+                       {
+                         sym_sec = hh->root.u.def.section;
+                         sym_value = hh->root.u.def.value;
+                         if (sym_sec->output_section != NULL)
+                         destination = (sym_value + irela->r_addend
+                                        + sym_sec->output_offset
+                                        + sym_sec->output_section->vma);
+                       }
+                     else if (hh->root.type == bfd_link_hash_undefweak)
+                       {
+                         if (! bfd_link_pic (info))
+                           continue;
+                       }
+                     else if (hh->root.type == bfd_link_hash_undefined)
+                       {
+                         if (! (info->unresolved_syms_in_objects == RM_IGNORE
+                                && (ELF_ST_VISIBILITY (hh->other)
+                                    == STV_DEFAULT)))
+                            continue;
+                       }
+                     else
+                       {
+                         bfd_set_error (bfd_error_bad_value);
+
+                         error_ret_free_internal:
+                         if (elf_section_data (section)->relocs == NULL)
+                           free (internal_relocs);
+                         goto error_ret_free_local;
+                       }
+                   }
+
+                 if (! avr_stub_is_required_for_16_bit_reloc
                      (destination - htab->vector_base))
-                    {
-                      if (!is_prealloc_run)
+                   {
+                     if (!is_prealloc_run)
                        /* We are having a reloc that does't need a stub.  */
                        continue;
 
                      /* We don't right now know if a stub will be needed.
                         Let's rather be on the safe side.  */
-                    }
-
-                  /* Get the name of this stub.  */
-                  stub_name = avr_stub_name (sym_sec, sym_value, irela);
-
-                  if (!stub_name)
-                    goto error_ret_free_internal;
-
-
-                  hsh = avr_stub_hash_lookup (&htab->bstab,
-                                              stub_name,
-                                              FALSE, FALSE);
-                  if (hsh != NULL)
-                    {
-                      /* The proper stub has already been created.  Mark it
-                         to be used and write the possibly changed destination
-                         value.  */
-                      hsh->is_actually_needed = TRUE;
-                      hsh->target_value = destination;
-                      free (stub_name);
-                      continue;
-                    }
-
-                  hsh = avr_add_stub (stub_name, htab);
-                  if (hsh == NULL)
-                    {
-                      free (stub_name);
-                      goto error_ret_free_internal;
-                    }
-
-                  hsh->is_actually_needed = TRUE;
-                  hsh->target_value = destination;
-
-                  if (debug_stubs)
-                    printf ("Adding stub with destination 0x%x to the"
-                            " hash table.\n", (unsigned int) destination);
-                  if (debug_stubs)
-                    printf ("(Pre-Alloc run: %i)\n", is_prealloc_run);
-
-                  stub_changed = TRUE;
-                }
-
-              /* We're done with the internal relocs, free them.  */
-              if (elf_section_data (section)->relocs == NULL)
-                free (internal_relocs);
-            }
-        }
+                   }
+
+                 /* Get the name of this stub.  */
+                 stub_name = avr_stub_name (sym_sec, sym_value, irela);
+
+                 if (!stub_name)
+                   goto error_ret_free_internal;
+
+
+                 hsh = avr_stub_hash_lookup (&htab->bstab,
+                                             stub_name,
+                                             FALSE, FALSE);
+                 if (hsh != NULL)
+                   {
+                     /* The proper stub has already been created.  Mark it
+                        to be used and write the possibly changed destination
+                        value.  */
+                     hsh->is_actually_needed = TRUE;
+                     hsh->target_value = destination;
+                     free (stub_name);
+                     continue;
+                   }
+
+                 hsh = avr_add_stub (stub_name, htab);
+                 if (hsh == NULL)
+                   {
+                     free (stub_name);
+                     goto error_ret_free_internal;
+                   }
+
+                 hsh->is_actually_needed = TRUE;
+                 hsh->target_value = destination;
+
+                 if (debug_stubs)
+                   printf ("Adding stub with destination 0x%x to the"
+                           " hash table.\n", (unsigned int) destination);
+                 if (debug_stubs)
+                   printf ("(Pre-Alloc run: %i)\n", is_prealloc_run);
+
+                 stub_changed = TRUE;
+               }
+
+             /* We're done with the internal relocs, free them.  */
+             if (elf_section_data (section)->relocs == NULL)
+               free (internal_relocs);
+           }
+       }
 
       /* Re-Calculate the number of needed stubs.  */
       htab->stub_sec->size = 0;
       bfd_hash_traverse (&htab->bstab, avr_size_one_stub, htab);
 
       if (!stub_changed)
-        break;
+       break;
 
       stub_changed = FALSE;
     }
@@ -3788,7 +3892,7 @@ elf32_avr_build_stubs (struct bfd_link_info *info)
   htab->amt_entry_cnt = 0;
   htab->amt_max_entry_cnt = total_size / 4;
   htab->amt_stub_offsets = bfd_malloc (sizeof (bfd_vma)
-                                       * htab->amt_max_entry_cnt);
+                                      * htab->amt_max_entry_cnt);
   htab->amt_destination_addr = bfd_malloc (sizeof (bfd_vma)
                                           * htab->amt_max_entry_cnt );
 
@@ -3832,12 +3936,12 @@ internal_reloc_compare (const void *ap, const void *bp)
 /* Return true if ADDRESS is within the vma range of SECTION from ABFD.  */
 
 static bfd_boolean
-avr_is_section_for_address (bfd *abfd, asection *section, bfd_vma address)
+avr_is_section_for_address (asection *section, bfd_vma address)
 {
   bfd_vma vma;
   bfd_size_type size;
 
-  vma = bfd_get_section_vma (abfd, section);
+  vma = bfd_section_vma (section);
   if (address < vma)
     return FALSE;
 
@@ -3869,8 +3973,8 @@ struct avr_find_section_data
    perform any checks, and just returns.  */
 
 static void
-avr_find_section_for_address (bfd *abfd,
-                              asection *section, void *data)
+avr_find_section_for_address (bfd *abfd ATTRIBUTE_UNUSED,
+                             asection *section, void *data)
 {
   struct avr_find_section_data *fs_data
     = (struct avr_find_section_data *) data;
@@ -3880,11 +3984,11 @@ avr_find_section_for_address (bfd *abfd,
     return;
 
   /* If this section isn't part of the addressable code content, skip it.  */
-  if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0
-      && (bfd_get_section_flags (abfd, section) & SEC_CODE) == 0)
+  if ((bfd_section_flags (section) & SEC_ALLOC) == 0
+      && (bfd_section_flags (section) & SEC_CODE) == 0)
     return;
 
-  if (avr_is_section_for_address (abfd, section, fs_data->address))
+  if (avr_is_section_for_address (section, fs_data->address))
     fs_data->section = section;
 }
 
@@ -3907,7 +4011,7 @@ avr_elf32_load_records_from_section (bfd *abfd, asection *sec)
 
   fs_data.section = NULL;
 
-  size = bfd_get_section_size (sec);
+  size = bfd_section_size (sec);
   contents = bfd_malloc (size);
   bfd_get_section_contents (abfd, sec, contents, 0, size);
   ptr = contents;
@@ -3915,10 +4019,10 @@ avr_elf32_load_records_from_section (bfd *abfd, asection *sec)
   /* Load the relocations for the '.avr.prop' section if there are any, and
      sort them.  */
   internal_relocs = (_bfd_elf_link_read_relocs
-                     (abfd, sec, NULL, NULL, FALSE));
+                    (abfd, sec, NULL, NULL, FALSE));
   if (internal_relocs)
     qsort (internal_relocs, sec->reloc_count,
-           sizeof (Elf_Internal_Rela), internal_reloc_compare);
+          sizeof (Elf_Internal_Rela), internal_reloc_compare);
 
   /* There is a header at the start of the property record section SEC, the
      format of this header is:
@@ -3966,116 +4070,115 @@ avr_elf32_load_records_from_section (bfd *abfd, asection *sec)
       bfd_vma address;
 
       /* Each entry is a 32-bit address, followed by a single byte type.
-         After that is the type specific data.  We must take care to
-         ensure that we don't read beyond the end of the section data.  */
+        After that is the type specific data.  We must take care to
+        ensure that we don't read beyond the end of the section data.  */
       if (size < 5)
-        goto load_failed;
+       goto load_failed;
 
       r_list->records [i].section = NULL;
       r_list->records [i].offset = 0;
 
       if (rel)
-        {
-          /* The offset of the address within the .avr.prop section.  */
-          size_t offset = ptr - contents;
+       {
+         /* The offset of the address within the .avr.prop section.  */
+         size_t offset = ptr - contents;
 
-          while (rel < rel_end && rel->r_offset < offset)
-            ++rel;
+         while (rel < rel_end && rel->r_offset < offset)
+           ++rel;
 
-          if (rel == rel_end)
-            rel = NULL;
-          else if (rel->r_offset == offset)
-            {
-              /* Find section and section offset.  */
-              unsigned long r_symndx;
+         if (rel == rel_end)
+           rel = NULL;
+         else if (rel->r_offset == offset)
+           {
+             /* Find section and section offset.  */
+             unsigned long r_symndx;
 
-              asection * rel_sec;
-              bfd_vma sec_offset;
+             asection * rel_sec;
+             bfd_vma sec_offset;
 
-              r_symndx = ELF32_R_SYM (rel->r_info);
-              rel_sec = get_elf_r_symndx_section (abfd, r_symndx);
-              sec_offset = get_elf_r_symndx_offset (abfd, r_symndx)
-                + rel->r_addend;
+             r_symndx = ELF32_R_SYM (rel->r_info);
+             rel_sec = get_elf_r_symndx_section (abfd, r_symndx);
+             sec_offset = get_elf_r_symndx_offset (abfd, r_symndx)
+               + rel->r_addend;
 
-              r_list->records [i].section = rel_sec;
-              r_list->records [i].offset = sec_offset;
-            }
-        }
+             r_list->records [i].section = rel_sec;
+             r_list->records [i].offset = sec_offset;
+           }
+       }
 
       address = *((uint32_t *) ptr);
       ptr += 4;
       size -= 4;
 
       if (r_list->records [i].section == NULL)
-        {
-          /* Try to find section and offset from address.  */
-          if (fs_data.section != NULL
-              && !avr_is_section_for_address (abfd, fs_data.section,
-                                              address))
-            fs_data.section = NULL;
-
-          if (fs_data.section == NULL)
-            {
-              fs_data.address = address;
-              bfd_map_over_sections (abfd, avr_find_section_for_address,
-                                     &fs_data);
-            }
-
-          if (fs_data.section == NULL)
-            {
-              fprintf (stderr, "Failed to find matching section.\n");
-              goto load_failed;
-            }
-
-          r_list->records [i].section = fs_data.section;
-          r_list->records [i].offset
-            = address - bfd_get_section_vma (abfd, fs_data.section);
-        }
+       {
+         /* Try to find section and offset from address.  */
+         if (fs_data.section != NULL
+             && !avr_is_section_for_address (fs_data.section, address))
+           fs_data.section = NULL;
+
+         if (fs_data.section == NULL)
+           {
+             fs_data.address = address;
+             bfd_map_over_sections (abfd, avr_find_section_for_address,
+                                    &fs_data);
+           }
+
+         if (fs_data.section == NULL)
+           {
+             fprintf (stderr, "Failed to find matching section.\n");
+             goto load_failed;
+           }
+
+         r_list->records [i].section = fs_data.section;
+         r_list->records [i].offset
+           = address - bfd_section_vma (fs_data.section);
+       }
 
       r_list->records [i].type = *((bfd_byte *) ptr);
       ptr += 1;
       size -= 1;
 
       switch (r_list->records [i].type)
-        {
-        case RECORD_ORG:
-          /* Nothing else to load.  */
-          break;
-        case RECORD_ORG_AND_FILL:
-          /* Just a 4-byte fill to load.  */
-          if (size < 4)
-            goto load_failed;
-          r_list->records [i].data.org.fill = *((uint32_t *) ptr);
-          ptr += 4;
-          size -= 4;
-          break;
-        case RECORD_ALIGN:
-          /* Just a 4-byte alignment to load.  */
-          if (size < 4)
-            goto load_failed;
-          r_list->records [i].data.align.bytes = *((uint32_t *) ptr);
-          ptr += 4;
-          size -= 4;
-          /* Just initialise PRECEDING_DELETED field, this field is
-             used during linker relaxation.  */
-          r_list->records [i].data.align.preceding_deleted = 0;
-          break;
-        case RECORD_ALIGN_AND_FILL:
-          /* A 4-byte alignment, and a 4-byte fill to load.  */
-          if (size < 8)
-            goto load_failed;
-          r_list->records [i].data.align.bytes = *((uint32_t *) ptr);
-          ptr += 4;
-          r_list->records [i].data.align.fill = *((uint32_t *) ptr);
-          ptr += 4;
-          size -= 8;
-          /* Just initialise PRECEDING_DELETED field, this field is
-             used during linker relaxation.  */
-          r_list->records [i].data.align.preceding_deleted = 0;
-          break;
-        default:
-          goto load_failed;
-        }
+       {
+       case RECORD_ORG:
+         /* Nothing else to load.  */
+         break;
+       case RECORD_ORG_AND_FILL:
+         /* Just a 4-byte fill to load.  */
+         if (size < 4)
+           goto load_failed;
+         r_list->records [i].data.org.fill = *((uint32_t *) ptr);
+         ptr += 4;
+         size -= 4;
+         break;
+       case RECORD_ALIGN:
+         /* Just a 4-byte alignment to load.  */
+         if (size < 4)
+           goto load_failed;
+         r_list->records [i].data.align.bytes = *((uint32_t *) ptr);
+         ptr += 4;
+         size -= 4;
+         /* Just initialise PRECEDING_DELETED field, this field is
+            used during linker relaxation.  */
+         r_list->records [i].data.align.preceding_deleted = 0;
+         break;
+       case RECORD_ALIGN_AND_FILL:
+         /* A 4-byte alignment, and a 4-byte fill to load.  */
+         if (size < 8)
+           goto load_failed;
+         r_list->records [i].data.align.bytes = *((uint32_t *) ptr);
+         ptr += 4;
+         r_list->records [i].data.align.fill = *((uint32_t *) ptr);
+         ptr += 4;
+         size -= 8;
+         /* Just initialise PRECEDING_DELETED field, this field is
+            used during linker relaxation.  */
+         r_list->records [i].data.align.preceding_deleted = 0;
+         break;
+       default:
+         goto load_failed;
+       }
     }
 
   free (contents);
@@ -4139,15 +4242,15 @@ avr_elf32_property_record_name (struct avr_property_record *rec)
 #define ELF_MACHINE_ALT1       EM_AVR_OLD
 #define ELF_MAXPAGESIZE                1
 
-#define TARGET_LITTLE_SYM       avr_elf32_vec
+#define TARGET_LITTLE_SYM      avr_elf32_vec
 #define TARGET_LITTLE_NAME     "elf32-avr"
 
 #define bfd_elf32_bfd_link_hash_table_create elf32_avr_link_hash_table_create
 
-#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_can_gc_sections          1
+#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_can_gc_sections         1
 #define elf_backend_rela_normal                     1
 #define elf_backend_final_write_processing \
                                        bfd_elf_avr_final_write_processing
@@ -4155,7 +4258,8 @@ avr_elf32_property_record_name (struct avr_property_record *rec)
 
 #define bfd_elf32_bfd_relax_section elf32_avr_relax_section
 #define bfd_elf32_bfd_get_relocated_section_contents \
-                                        elf32_avr_get_relocated_section_contents
+                                       elf32_avr_get_relocated_section_contents
 #define bfd_elf32_new_section_hook     elf_avr_new_section_hook
+#define elf_backend_special_sections   elf_avr_special_sections
 
 #include "elf32-target.h"
This page took 0.081292 seconds and 4 git commands to generate.