aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog6
-rw-r--r--bfd/elf32-avr.c21
-rw-r--r--ld/ChangeLog7
-rw-r--r--ld/testsuite/ld-avr/avr-prop-5.d10
-rw-r--r--ld/testsuite/ld-avr/avr-prop-5.s7
5 files changed, 48 insertions, 3 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index d544d02..460e68b 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,9 @@
+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-08 H.J. Lu <hongjiu.lu@intel.com>
* elf64-i386.c (elf_i386_link_hash_entry): Add tls_get_addr.
diff --git a/bfd/elf32-avr.c b/bfd/elf32-avr.c
index d463d78..b95e251 100644
--- a/bfd/elf32-avr.c
+++ b/bfd/elf32-avr.c
@@ -1828,6 +1828,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);
@@ -1863,10 +1864,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. */
@@ -1885,6 +1892,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
@@ -1892,6 +1904,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++)
{
diff --git a/ld/ChangeLog b/ld/ChangeLog
index cbb98e3..11470c5 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,4 +1,11 @@
+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-09 Pitchumani Sivanupandi <pitchumani.s@atmel.com>
+
* testsuite/ld-avr/lds-mega.d: New test.
* testsuite/ld-avr/lds-mega.s: New test source.
* testsuite/ld-avr/lds-tiny.d: New test.
diff --git a/ld/testsuite/ld-avr/avr-prop-5.d b/ld/testsuite/ld-avr/avr-prop-5.d
new file mode 100644
index 0000000..5f62ba3
--- /dev/null
+++ b/ld/testsuite/ld-avr/avr-prop-5.d
@@ -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
index 0000000..6a3359a
--- /dev/null
+++ b/ld/testsuite/ld-avr/avr-prop-5.s
@@ -0,0 +1,7 @@
+ .text
+ .global _start, dest
+_start:
+ CALL dest
+ .align 1
+dest:
+ NOP