]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Fix PR 20221 - adjust syms and relocs only if relax shrunk section.
authorDenis Chertykov <chertykov@gmail.com>
Thu, 9 Jun 2016 16:17:43 +0000 (19:17 +0300)
committerSenthil Kumar Selvaraj <senthi_kumar.selvaraj@atmel.com>
Mon, 13 Jun 2016 12:09:30 +0000 (17:39 +0530)
This patch fixes an edge case in linker relaxation that causes symbol
values to be computed incorrectly in the presence of align directives
in input source code.

bfd/
* elf32-avr.c (elf32_avr_relax_delete_bytes): Adjust syms
and relocs only if shrinking occurred.

ld/
* testsuite/ld-avr/avr-prop-5.d: New.
* testsuite/ld-avr/avr-prop-5.s: New.

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

index 6d70417eb7cfdb1f8bcfd52eea917273745dea0e..c601d0057c990cec02821f0d22e27437e330abb7 100644 (file)
@@ -1,3 +1,12 @@
+2016-06-13  Senthil Kumar Selvaraj  <senthil_kumar.selvaraj@atmel.com>
+
+       Backport from master
+       2016-06-08  Senthil Kumar Selvaraj  <senthil_kumar.selvaraj@atmel.com>
+
+       PR ld/20221
+       * elf32-avr.c (elf32_avr_relax_delete_bytes): Adjust syms
+       and relocs only if shrinking occurred.
+
 2016-06-09  Alan Modra  <amodra@gmail.com>
 
        PR ld/20159
index 9aa5a68888af9e34085ed360be5674cf17a546e3..422c4aca679089241461ebfe5763ccabf45f6fa6 100644 (file)
@@ -1832,6 +1832,7 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
   unsigned int symcount;
   struct avr_relax_info *relax_info;
   struct avr_property_record *prop_record = NULL;
+  bfd_boolean did_shrink = FALSE;
 
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
@@ -1867,10 +1868,16 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
 
   /* Actually delete the bytes.  */
   if (toaddr - addr - count > 0)
-    memmove (contents + addr, contents + addr + count,
-             (size_t) (toaddr - addr - count));
+    {
+      memmove (contents + addr, contents + addr + count,
+               (size_t) (toaddr - addr - count));
+      did_shrink = TRUE;
+    }
   if (prop_record == NULL)
-    sec->size -= count;
+    {
+      sec->size -= count;
+      did_shrink = TRUE;
+    }
   else
     {
       /* Use the property record to fill in the bytes we've opened up.  */
@@ -1889,6 +1896,11 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
           prop_record->data.align.preceding_deleted += count;
           break;
         };
+      /* If toaddr == (addr + count), then we didn't delete anything, yet
+         we fill count bytes backwards from toaddr. This is still ok - we
+         end up overwriting the bytes we would have deleted. We just need
+         to remember we didn't delete anything i.e. don't set did_shrink,
+         so that we don't corrupt reloc offsets or symbol values.*/
       memset (contents + toaddr - count, fill, count);
 
       /* Adjust the TOADDR to avoid moving symbols located at the address
@@ -1896,6 +1908,9 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
       toaddr -= count;
     }
 
+  if (!did_shrink)
+    return TRUE;
+
   /* Adjust all the reloc addresses.  */
   for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
     {
index 7594faca06726aa4af23684c4c6b12942e143148..e78421634d6eb3dabce267920a44f2b66175d5b7 100644 (file)
@@ -1,3 +1,12 @@
+2016-06-13  Senthil Kumar Selvaraj  <senthil_kumar.selvaraj@atmel.com>
+
+       Backport from master
+       2016-06-08  Senthil Kumar Selvaraj  <senthil_kumar.selvaraj@atmel.com>
+
+       PR ld/20221
+       * testsuite/ld-avr/avr-prop-5.d: New.
+       * testsuite/ld-avr/avr-prop-5.s: New.
+
 2016-06-11  H.J. Lu  <hongjiu.lu@intel.com>
 
        Backport from master
diff --git a/ld/testsuite/ld-avr/avr-prop-5.d b/ld/testsuite/ld-avr/avr-prop-5.d
new file mode 100644 (file)
index 0000000..5f62ba3
--- /dev/null
@@ -0,0 +1,10 @@
+#name: AVR .avr.prop, single .align proper sym val test.
+#as: -mmcu=avrxmega2 -mlink-relax
+#ld: -mavrxmega2 --relax
+#source: avr-prop-5.s
+#objdump: -S
+#target: avr-*-*
+
+#...
+   0:  00 d0\s+rcall\s+\.\+0\s+; 0x2 <dest>
+#...
\ No newline at end of file
diff --git a/ld/testsuite/ld-avr/avr-prop-5.s b/ld/testsuite/ld-avr/avr-prop-5.s
new file mode 100644 (file)
index 0000000..6a3359a
--- /dev/null
@@ -0,0 +1,7 @@
+        .text
+        .global _start, dest
+_start:
+        CALL    dest
+        .align  1
+dest:
+        NOP