aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorSenthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>2016-09-06 12:28:37 +0530
committerSenthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>2016-09-06 12:28:37 +0530
commitbf1865065f64af2f32798c0327143baf99634e8d (patch)
tree766dff0c11f035524bff7d74ad5de1971057520f /ld
parent3b276c08506b32359570e56698dfc7fc4d9e43c4 (diff)
downloadgdb-bf1865065f64af2f32798c0327143baf99634e8d.zip
gdb-bf1865065f64af2f32798c0327143baf99634e8d.tar.gz
gdb-bf1865065f64af2f32798c0327143baf99634e8d.tar.bz2
Fix PR ld/20545 - relaxation bugs in avr backend
Prior to the patch, addends for relocs were being adjusted even if they went beyond an alignment boundary. This is wrong - to preserve alignment constraints, the relaxation logic adds as many padding bytes at the alignment boundary as was deleted, so addends beyond the boundary should not be adjusted. avr-prop-7.s reproduces this scenario. Also, prior to this patch, the relaxation logic assumed that the addr parameter pointed to the middle of the instruction to be deleted, and that addr - count would therefore be the shrinked instruction's address. This is true when actually shrinking instructions. The alignment constraints handling logic also invokes the same logic though, with addr as the starting offset of padding bytes and with count as the number of bytes to be deleted. Calculating the shrinked insn's address as addr - count is obviously wrong in this case - that offset would point to count bytes before the last non-padded byte. avr-prop-8.s reproduces this scenario. To fix scenario 1, the patch adds an additional check to ensure reloc addends aren't adjusted if they cross a shrink boundary. The shrink boundary is either the section size or an alignment boundary. Addends pointing at an alignment boundary don't need to be adjusted, as padding would occur and keep the boundary the same. Addends pointing at section size need to be adjusted though, as no padding occurs and the section size itself would get decremented. The patch records whether padding occured (did_pad) and uses that to detect and handle this condition. To fix scenario 2, the patch adds an additional parameter (delete_shrinks_insn) to elf32_avr_relax_delete_bytes to distinguish instruction bytes deletion from padding bytes deletion. It then uses that to correctly set shrinked_insn_address. bfd/ChangeLog: 2016-09-02 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com> PR ld/20545 * elf32-avr.c (elf32_avr_relax_delete_bytes): Add parameter delete_shrinks_insn. Modify computation of shrinked_insn_address. Compute shrink_boundary and adjust addend only if addend_within_shrink_boundary. (elf32_avr_relax_section): Modify calls to elf32_avr_relax_delete_bytes to pass extra parameter. ld/ChangeLog: 2016-09-02 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com> PR ld/20545 * testsuite/ld-avr/avr-prop-7.d: New test. * testsuite/ld-avr/avr-prop-7.s: New test. * testsuite/ld-avr/avr-prop-8.d: New test. * testsuite/ld-avr/avr-prop-8.s: New test.
Diffstat (limited to 'ld')
-rw-r--r--ld/ChangeLog8
-rw-r--r--ld/testsuite/ld-avr/avr-prop-7.d15
-rw-r--r--ld/testsuite/ld-avr/avr-prop-7.s8
-rw-r--r--ld/testsuite/ld-avr/avr-prop-8.d13
-rw-r--r--ld/testsuite/ld-avr/avr-prop-8.s7
5 files changed, 51 insertions, 0 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 8ef9e51..a13c8d1 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,11 @@
+2016-09-02 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
+
+ PR ld/20545
+ * testsuite/ld-avr/avr-prop-7.d: New test.
+ * testsuite/ld-avr/avr-prop-7.s: New test.
+ * testsuite/ld-avr/avr-prop-8.d: New test.
+ * testsuite/ld-avr/avr-prop-8.s: New test.
+
2016-09-02 H.J. Lu <hongjiu.lu@intel.com>
* testsuite/ld-elf/pr20513c.d: Limit to *-*-linux* and *-*-gnu*
diff --git a/ld/testsuite/ld-avr/avr-prop-7.d b/ld/testsuite/ld-avr/avr-prop-7.d
new file mode 100644
index 0000000..9f2cea9
--- /dev/null
+++ b/ld/testsuite/ld-avr/avr-prop-7.d
@@ -0,0 +1,15 @@
+#name: AVR .avr.prop, AVR_7_PCREL after align
+#as: -mavrxmega2 -mlink-relax
+#ld: -mavrxmega2 --relax
+#source: avr-prop-7.s
+#objdump: -S
+#target: avr-*-*
+
+#...
+00000000 <__ctors_end>:
+ 0: 04 d0 rcall .+8 ; 0xa <foo>
+ 2: 00 00 nop
+ 4: 00 00 nop
+ 6: 86 e0 ldi r24, 0x06 ; 6
+ 8: f0 f7 brcc .-4 ; 0x6 <__ctors_end\+0x6>
+#...
diff --git a/ld/testsuite/ld-avr/avr-prop-7.s b/ld/testsuite/ld-avr/avr-prop-7.s
new file mode 100644
index 0000000..38276ba
--- /dev/null
+++ b/ld/testsuite/ld-avr/avr-prop-7.s
@@ -0,0 +1,8 @@
+ call foo
+ nop
+ .p2align 1
+ nop
+.L618:
+ ldi r24,lo8(6)
+ brsh .L618
+foo: nop
diff --git a/ld/testsuite/ld-avr/avr-prop-8.d b/ld/testsuite/ld-avr/avr-prop-8.d
new file mode 100644
index 0000000..2905f98
--- /dev/null
+++ b/ld/testsuite/ld-avr/avr-prop-8.d
@@ -0,0 +1,13 @@
+#name: AVR .avr.prop, AVR_7_PCREL just before align
+#as: -mavrxmega2 -mlink-relax
+#ld: -mavrxmega2 --relax
+#source: avr-prop-8.s
+#objdump: -S
+#target: avr-*-*
+
+#...
+00000000 <__ctors_end>:
+ 0: ff cf rjmp .-2 ; 0x0 <__ctors_end>
+ 2: fe df rcall .-4 ; 0x0 <__ctors_end>
+ 4: f8 f7 brcc .-2 ; 0x4 <__ctors_end\+0x4>
+#...
diff --git a/ld/testsuite/ld-avr/avr-prop-8.s b/ld/testsuite/ld-avr/avr-prop-8.s
new file mode 100644
index 0000000..34554f2
--- /dev/null
+++ b/ld/testsuite/ld-avr/avr-prop-8.s
@@ -0,0 +1,7 @@
+foo:
+ jmp foo
+ call foo
+.L1:
+ brsh .L1
+.p2align 1
+ nop