diff options
author | Eric B. Weddington <eric.weddington@atmel.com> | 2012-02-02 18:02:10 +0000 |
---|---|---|
committer | Eric B. Weddington <eric.weddington@atmel.com> | 2012-02-02 18:02:10 +0000 |
commit | 526f25b299bdd3a21bded4102a192eb680817324 (patch) | |
tree | 0c8a8570edb12cee67bc571c34cdc56d4f4dcd9c /bfd | |
parent | c709a7c2b06cc388ab364015c433b95076d1eb56 (diff) | |
download | gdb-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/ChangeLog | 6 | ||||
-rw-r--r-- | 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 <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); |