2012-02-02 Vidya Praveen (vidya.praveen@atmel.com)
authorEric B. Weddington <eric.weddington@atmel.com>
Thu, 2 Feb 2012 18:02:10 +0000 (18:02 +0000)
committerEric B. Weddington <eric.weddington@atmel.com>
Thu, 2 Feb 2012 18:02:10 +0000 (18:02 +0000)
PR bfd/13410
* bfd/elf32-avr.c (elf32_avr_relax_section): Correct the
condition that qualifies the candidates for relaxation.

bfd/ChangeLog
bfd/elf32-avr.c

index bf3166be8a264cb6239494cfb363896d3a997c0c..16d5af9c8e570ee0d5603d9c759dfb43a5ed1ced 100644 (file)
@@ -1,3 +1,9 @@
+2012-02-02  Vidya Praveen (vidya.praveen@atmel.com)
+
+       PR bfd/13410
+       * bfd/elf32-avr.c (elf32_avr_relax_section): Correct the 
+       condition that qualifies the candidates for relaxation.
+
 2012-02-02  Tristan Gingold  <gingold@adacore.com>
 
        * bfdio.c (real_fopen): Remove unused vms_modes variable.
index a7f92174136773dbe88b67be0eb649fc5e057c4f..2a10162465e2c827ec136bd76d24c5a20c69ca8b 100644 (file)
@@ -1659,6 +1659,16 @@ elf32_avr_relax_section (bfd *abfd,
   Elf_Internal_Sym *isymbuf = NULL;
   struct elf32_avr_link_hash_table *htab;
 
+  /* If 'shrinkable' is FALSE, do not shrink by deleting bytes while
+     relaxing. Such shrinking can cause issues for the sections such 
+     as .vectors and .jumptables. Instead the unused bytes should be 
+     filled with nop instructions. */
+  bfd_boolean shrinkable = TRUE;
+
+  if (!strcmp (sec->name,".vectors")
+      || !strcmp (sec->name,".jumptables"))
+    shrinkable = FALSE;
+
   if (link_info->relocatable)
     (*link_info->callbacks->einfo)
       (_("%P%F: --relax and -r may not be used together\n"));
@@ -1815,10 +1825,16 @@ elf32_avr_relax_section (bfd *abfd,
             /* Compute the distance from this insn to the branch target.  */
             gap = value - dot;
 
-            /* If the distance is within -4094..+4098 inclusive, then we can
-               relax this jump/call.  +4098 because the call/jump target
-               will be closer after the relaxation.  */
-            if ((int) gap >= -4094 && (int) gap <= 4098)
+            /* Check if the gap falls in the range that can be accommodated
+               in 13bits signed (It is 12bits when encoded, as we deal with
+               word addressing). */
+            if (!shrinkable && ((int) gap >= -4096 && (int) gap <= 4095))
+              distance_short_enough = 1;
+            /* If shrinkable, then we can check for a range of distance which
+               is two bytes farther on both the directions because the call
+               or jump target will be closer by two bytes after the 
+               relaxation. */
+            else if (shrinkable && ((int) gap >= -4094 && (int) gap <= 4097))
               distance_short_enough = 1;
 
             /* Here we handle the wrap-around case.  E.g. for a 16k device
@@ -1892,11 +1908,9 @@ elf32_avr_relax_section (bfd *abfd,
                 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
                                              R_AVR_13_PCREL);
 
-                /* Check for the vector section. There we don't want to
-                   modify the ordering!  */
-
-                if (!strcmp (sec->name,".vectors")
-                    || !strcmp (sec->name,".jumptables"))
+                /* We should not modify the ordering if 'shrinkable' is
+                   FALSE. */ 
+                if (!shrinkable)
                   {
                     /* Let's insert a nop.  */
                     bfd_put_8 (abfd, 0x00, contents + irel->r_offset + 2);