aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Chertykov <chertykov@gmail.com>2016-06-09 19:17:43 +0300
committerDenis Chertykov <chertykov@gmail.com>2016-06-09 19:17:43 +0300
commit5c41dbc302c2dd87e201e4fd1d9ae3186f6e51a0 (patch)
treef97034bca2d7f3fa8d45fc6b6931d9117a6de79e
parent1857fe72aff6f254217956d141bff4b9ca454bc5 (diff)
downloadgdb-5c41dbc302c2dd87e201e4fd1d9ae3186f6e51a0.zip
gdb-5c41dbc302c2dd87e201e4fd1d9ae3186f6e51a0.tar.gz
gdb-5c41dbc302c2dd87e201e4fd1d9ae3186f6e51a0.tar.bz2
Fix PR 20221 - adjust syms and relocs only if relax shrunk section.
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.
-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