aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorSenthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>2016-11-16 16:11:46 +0530
committerSenthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>2016-11-16 16:11:46 +0530
commit4cb771f214ed6a2102e37bce255c6be5d0642f3a (patch)
tree8f26e644fa755b972db065f59973d0afaaf7e1f2 /ld
parentff7ba33e8aae2ee8ec607d3f1f4b96f7cb1a92b9 (diff)
downloadgdb-4cb771f214ed6a2102e37bce255c6be5d0642f3a.zip
gdb-4cb771f214ed6a2102e37bce255c6be5d0642f3a.tar.gz
gdb-4cb771f214ed6a2102e37bce255c6be5d0642f3a.tar.bz2
Fix PR20789 - relaxation with negative valued diff relocs
Fix issues with diff relocs that have a negative value i.e. sym2 - sym1 where sym2 is lesser than sym1. The assembler generates a diff reloc with symbol as start of section and addend as sym2 offset, and encodes assembly time difference at the reloc offset. The existing relaxation logic adjusts addends if the relaxed insn lies between symbol and addend. That doesn't work for diff relocs where sym2 is less than sym1 *and* the relaxed insn happens to be between sym2 and sym1. Fix the problems by 1. Using signed handling of the difference value (bfd_signed_vma instead of bfd_vma, bfd_{get,set}_signed_xxx instead of bfd_{get,set}_xxx). 2. Not assuming sym2 is bigger than sym1. It instead computes the actual addresses and sets the lower and higher addresses as start and end addresses respectively and then sees if insn is between start and end. 3. Creating a new function elf32_avr_adjust_reloc_if_spans_insn to centralize reloc adjustment, and ensuring diff relocs get adjusted correctly even if their sym + addend doesn't overlap a relaxed insn. It also removes a redundant variable did_pad. It is never set if did_shrink is TRUE, and the code does a early return if did_shrink is FALSE. bfd/ChangeLog 2016-11-15 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com> PR ld/20789 * bfd/elf32-avr.c (elf32_avr_adjust_diff_reloc_value): Do signed manipulation of diff value, and don't assume sym2 is less than sym1. (elf32_avr_adjust_reloc_if_spans_insn): New function. (elf32_avr_relax_delete_bytes): Use elf32_avr_adjust_diff_reloc_value, and remove redundant did_pad. ld/ChangeLog 2016-11-15 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com> PR ld/20789 * ld/testsuite/ld-avr/pr20789.d: New test. * ld/testsuite/ld-avr/pr20789.s: New test.
Diffstat (limited to 'ld')
-rw-r--r--ld/ChangeLog7
-rw-r--r--ld/testsuite/ld-avr/pr20789.d14
-rw-r--r--ld/testsuite/ld-avr/pr20789.s12
3 files changed, 33 insertions, 0 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index f0f6694..7add280 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,10 @@
+2016-11-15 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
+
+ PR ld/20789
+ * ld/testsuite/ld-avr/pr20789.d: New test.
+ * ld/testsuite/ld-avr/pr20789.s: New test.
+
+
2016-11-14 H.J. Lu <hongjiu.lu@intel.com>
PR ld/20800
diff --git a/ld/testsuite/ld-avr/pr20789.d b/ld/testsuite/ld-avr/pr20789.d
new file mode 100644
index 0000000..fb1114b
--- /dev/null
+++ b/ld/testsuite/ld-avr/pr20789.d
@@ -0,0 +1,14 @@
+#name: AVR Account for relaxation in negative label differences
+#as: -mmcu=avrxmega2 -mlink-relax
+#ld: -mavrxmega2 --relax
+#source: pr20789.s
+#objdump: -s
+#target: avr-*-*
+
+.*: file format elf32-avr
+
+Contents of section .text:
+ 0000 ffcf .*
+Contents of section .data:
+ 802000 feff .*
+
diff --git a/ld/testsuite/ld-avr/pr20789.s b/ld/testsuite/ld-avr/pr20789.s
new file mode 100644
index 0000000..cee46e7
--- /dev/null
+++ b/ld/testsuite/ld-avr/pr20789.s
@@ -0,0 +1,12 @@
+ .file "pr20789.s"
+.section .text,"ax",@progbits
+main:
+L1:
+ jmp L1
+L2:
+.global x
+ .section .data
+ .type x, @object
+ .size x, 2
+x:
+ .word L1 - L2