aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorEric B. Weddington <eric.weddington@atmel.com>2012-02-02 18:02:10 +0000
committerEric B. Weddington <eric.weddington@atmel.com>2012-02-02 18:02:10 +0000
commit526f25b299bdd3a21bded4102a192eb680817324 (patch)
tree0c8a8570edb12cee67bc571c34cdc56d4f4dcd9c /bfd
parentc709a7c2b06cc388ab364015c433b95076d1eb56 (diff)
downloadgdb-526f25b299bdd3a21bded4102a192eb680817324.zip
gdb-526f25b299bdd3a21bded4102a192eb680817324.tar.gz
gdb-526f25b299bdd3a21bded4102a192eb680817324.tar.bz2
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.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog6
-rw-r--r--bfd/elf32-avr.c32
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 <gingold@adacore.com>
* 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);