aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSenthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>2017-06-27 14:46:08 +0530
committerSenthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>2017-06-27 14:47:02 +0530
commit6806377956c76c23ae96a3844e29412ae117e07a (patch)
tree95d2cf350f127603871f0e99a5cbcc7eb1dc7ca6
parentdb665f427ca781d631d9e29b1bb744fb11ffcbba (diff)
downloadgdb-6806377956c76c23ae96a3844e29412ae117e07a.zip
gdb-6806377956c76c23ae96a3844e29412ae117e07a.tar.gz
gdb-6806377956c76c23ae96a3844e29412ae117e07a.tar.bz2
Fix PR 13402
Fix incorrect adjustment of diff relocs when relaxing, and thus the resulting source line to address mismatch. Fix two issues when adjusting diff relocs to account for deleted bytes. 1. Don't adjust the difference if the end address is the shrinked insn's address i.e. use < instead of <=. The relaxation code deletes count bytes from or after shrinked_insn_address, so the difference between start_address and end_address should remain unchanged in this case. 2. Adjust the reloc addend if the difference is to be adjusted and symval + reloc addend is past the shrinked insn address. This is because for a typical sym1 - sym2 diff reloc, sym1 is .text + irel->r_addend, and the addend should be reduced to account for the shrinked insn. For example, assume the reloc value is .text + 0x8 with .text = 0, the diff value in the object file = 0x4, and shrinked_insn_address = 0x4 with count = 0x2. Then the existing code writes 0x2 into the object file to account for the deleted bytes, as shrinked_insn_address lies between 0x8 and 0x8 - 0x4 = 0x4, but leaves the addend as is. The next time the reloc is looked at, the code sees if a shrinked_insn_address lies between 0x8 and 0x8 - 0x2 = 0x6, instead of 0x6 and 0x4. If there happens to be one, then the diff value in the object file ends up getting reduced again. bfd/ 2017-06-27 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com> PR ld/13402 * elf32-avr.c (elf32_avr_adjust_diff_reloc_value): Adjust reloc addend if necessary. Adjust diff only if shrinked_insn_address < end_address. ld/ 2017-06-27 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com> PR ld/13402 * testsuite/ld-avr/pr13402.d: New test. * testsuite/ld-avr/pr13402.s: New test.
-rw-r--r--bfd/ChangeLog7
-rw-r--r--bfd/elf32-avr.c5
-rw-r--r--ld/ChangeLog6
-rw-r--r--ld/testsuite/ld-avr/pr13402.d16
-rw-r--r--ld/testsuite/ld-avr/pr13402.s9
5 files changed, 42 insertions, 1 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 5f840a1..272da0c 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,10 @@
+2017-06-27 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
+
+ PR ld/13402
+ * elf32-avr.c (elf32_avr_adjust_diff_reloc_value): Adjust
+ reloc addend if necessary. Adjust diff only if
+ shrinked_insn_address < end_address.
+
2017-06-27 Alan Modra <amodra@gmail.com>
PR binutils/21665
diff --git a/bfd/elf32-avr.c b/bfd/elf32-avr.c
index f140aa7..830da28 100644
--- a/bfd/elf32-avr.c
+++ b/bfd/elf32-avr.c
@@ -1785,12 +1785,15 @@ elf32_avr_adjust_diff_reloc_value (bfd *abfd,
if (shrinked_insn_address >= start_address
- && shrinked_insn_address <= end_address)
+ && shrinked_insn_address < end_address)
{
/* Reduce the diff value by count bytes and write it back into section
contents. */
bfd_signed_vma new_diff = x < 0 ? x + count : x - count;
+ if (sym2_address > shrinked_insn_address)
+ irel->r_addend -= count;
+
switch (ELF32_R_TYPE (irel->r_info))
{
case R_AVR_DIFF8:
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 92d0003..fec44c9 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,9 @@
+2017-06-27 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
+
+ PR ld/13402
+ * testsuite/ld-avr/pr13402.d: New test.
+ * testsuite/ld-avr/pr13402.s: New test.
+
2017-06-27 Maciej W. Rozycki <macro@imgtec.com>
* testsuite/ld-mips-elf/mips-elf-flags.exp (good_combination):
diff --git a/ld/testsuite/ld-avr/pr13402.d b/ld/testsuite/ld-avr/pr13402.d
new file mode 100644
index 0000000..6663950
--- /dev/null
+++ b/ld/testsuite/ld-avr/pr13402.d
@@ -0,0 +1,16 @@
+#name: AVR fix broken sync between debug_line and code addresses
+#as: -mmcu=avrxmega2 -mlink-relax -gdwarf-2
+#ld: -mavrxmega2 --relax
+#source: pr13402.s
+#objdump: -S
+#target: avr-*-*
+
+#...
+main:
+call a
+ 0: 02 d0 rcall .+4 ; 0x6 <_etext>
+call b
+ 2: 01 d0 rcall .+2 ; 0x6 <_etext>
+call c
+ 4: 00 d0 rcall .+0 ; 0x6 <_etext>
+#...
diff --git a/ld/testsuite/ld-avr/pr13402.s b/ld/testsuite/ld-avr/pr13402.s
new file mode 100644
index 0000000..9539829
--- /dev/null
+++ b/ld/testsuite/ld-avr/pr13402.s
@@ -0,0 +1,9 @@
+.global main
+main:
+call a
+call b
+call c
+
+a:
+b:
+c: