Fix PR ld/20254
authorSenthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
Wed, 15 Jun 2016 06:55:30 +0000 (12:25 +0530)
committerSenthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
Wed, 15 Jun 2016 07:17:46 +0000 (12:47 +0530)
This patch fixes another edge case related to alignment property
records - reloc offsets adjacent to property record offsets were not
getting adjusted during relaxation.

bfd/

PR ld/20254
* elf32-avr.c (elf32_avr_relax_delete_bytes): Adjust reloc
offsets until reloc_toaddr.

ld/

PR ld/20254
* testsuite/ld-avr/avr-prop-6.d: New test.
* testsuite/ld-avr/avr-prop-6.s: New test.

bfd/ChangeLog
bfd/elf32-avr.c
ld/ChangeLog
ld/testsuite/ld-avr/avr-prop-6.d [new file with mode: 0644]
ld/testsuite/ld-avr/avr-prop-6.s [new file with mode: 0644]

index f88e18582f27bdb0cb4b8d6fac7f4082092fbaf8..38d28f32da678671217ce5229bb58dddacc0ffac 100644 (file)
@@ -1,3 +1,9 @@
+2016-06-14  Senthil Kumar Selvaraj  <senthil_kumar.selvaraj@atmel.com>
+
+       PR ld/20254
+       * elf32-avr.c (elf32_avr_relax_delete_bytes): Adjust reloc
+       offsets until reloc_toaddr.
+
 2016-06-14  H.J. Lu  <hongjiu.lu@intel.com>
 
        * elf32-i386.c (elf_i386_reloc_type_class): Check R_386_IRELATIVE.
index b95e251e1e05f06cb5d23eabfa95cdf4cfb5ab4b..a0a5c6975edb1b9c3d88408a256df19ddae36a0d 100644 (file)
@@ -1822,7 +1822,7 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
   Elf_Internal_Rela *irel, *irelend;
   Elf_Internal_Sym *isym;
   Elf_Internal_Sym *isymbuf = NULL;
-  bfd_vma toaddr;
+  bfd_vma toaddr, reloc_toaddr;
   struct elf_link_hash_entry **sym_hashes;
   struct elf_link_hash_entry **end_hashes;
   unsigned int symcount;
@@ -1859,6 +1859,17 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
         }
     }
 
+  /* We need to look at all relocs with offsets less than toaddr. prop
+     records handling adjusts toaddr downwards to avoid moving syms at the
+     address of the property record, but all relocs with offsets between addr
+     and the current value of toaddr need to have their offsets adjusted.
+     Assume addr = 0, toaddr = 4 and count = 2. After prop records handling,
+     toaddr becomes 2, but relocs with offsets 2 and 3 still need to be
+     adjusted (to 0 and 1 respectively), as the first 2 bytes are now gone.
+     So record the current value of toaddr here, and use it when adjusting
+     reloc offsets. */
+  reloc_toaddr = toaddr;
+
   irel = elf_section_data (sec)->relocs;
   irelend = irel + sec->reloc_count;
 
@@ -1917,7 +1928,7 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
 
       /* Get the new reloc address.  */
       if ((irel->r_offset > addr
-           && irel->r_offset < toaddr))
+           && irel->r_offset < reloc_toaddr))
         {
           if (debug_relax)
             printf ("Relocation at address 0x%x needs to be moved.\n"
index 446907d3d747f3a631cae853fb80c7f449b7ed12..516b4bbb9876472ed93ec95723eed55f74ddfde6 100644 (file)
@@ -1,3 +1,9 @@
+2016-06-14  Senthil Kumar Selvaraj  <senthil_kumar.selvaraj@atmel.com>
+
+       PR ld/20254
+       * testsuite/ld-avr/avr-prop-6.d: New test.
+       * testsuite/ld-avr/avr-prop-6.s: New test.
+
 2016-06-14  Alan Modra  <amodra@gmail.com>
 
        * ldbuildid.c: Formatting.
diff --git a/ld/testsuite/ld-avr/avr-prop-6.d b/ld/testsuite/ld-avr/avr-prop-6.d
new file mode 100644 (file)
index 0000000..1bf8aa1
--- /dev/null
@@ -0,0 +1,14 @@
+#name: AVR .avr.prop, single .align sym at end of section test.
+#as: -mavrxmega2 -mlink-relax
+#ld: -mavrxmega2 --relax
+#source: avr-prop-6.s
+#objdump: -S
+#target: avr-*-*
+
+#...
+   0:  00 c0           rjmp    .+0             ; 0x2 <dest>
+
+00000002 <dest>:
+   2:  00 00           nop
+   4:  fe cf           rjmp    .-4             ; 0x2 <dest>
+#...
diff --git a/ld/testsuite/ld-avr/avr-prop-6.s b/ld/testsuite/ld-avr/avr-prop-6.s
new file mode 100644 (file)
index 0000000..4aa3e67
--- /dev/null
@@ -0,0 +1,9 @@
+        .text
+        .global _start, dest
+_start:
+  jmp dest
+  .align       1
+dest:
+  nop
+  rjmp dest
+