From 526f25b299bdd3a21bded4102a192eb680817324 Mon Sep 17 00:00:00 2001 From: "Eric B. Weddington" Date: Thu, 2 Feb 2012 18:02:10 +0000 Subject: [PATCH] 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. --- bfd/ChangeLog | 6 ++++++ bfd/elf32-avr.c | 32 +++++++++++++++++++++++--------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index bf3166b..16d5af9 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -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 * bfdio.c (real_fopen): Remove unused vms_modes variable. diff --git a/bfd/elf32-avr.c b/bfd/elf32-avr.c index a7f9217..2a10162 100644 --- a/bfd/elf32-avr.c +++ b/bfd/elf32-avr.c @@ -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); -- 2.7.4