From 31eef93e717c59975b3e6f37619ab956302ca37a Mon Sep 17 00:00:00 2001 From: Senthil Kumar Selvaraj Date: Wed, 15 Jun 2016 12:25:30 +0530 Subject: [PATCH] Fix PR ld/20254 This patch fixes another edge case related to alignment property records - reloc offsets adjacent to property record offsets were not getting adjusted during relaxation. bfd/ PR ld/20254 * elf32-avr.c (elf32_avr_relax_delete_bytes): Adjust reloc offsets until reloc_toaddr. ld/ PR ld/20254 * testsuite/ld-avr/avr-prop-6.d: New test. * testsuite/ld-avr/avr-prop-6.s: New test. --- bfd/ChangeLog | 6 ++++++ bfd/elf32-avr.c | 15 +++++++++++++-- ld/ChangeLog | 6 ++++++ ld/testsuite/ld-avr/avr-prop-6.d | 14 ++++++++++++++ ld/testsuite/ld-avr/avr-prop-6.s | 9 +++++++++ 5 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 ld/testsuite/ld-avr/avr-prop-6.d create mode 100644 ld/testsuite/ld-avr/avr-prop-6.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index f88e185..38d28f3 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2016-06-14 Senthil Kumar Selvaraj + + PR ld/20254 + * elf32-avr.c (elf32_avr_relax_delete_bytes): Adjust reloc + offsets until reloc_toaddr. + 2016-06-14 H.J. Lu * elf32-i386.c (elf_i386_reloc_type_class): Check R_386_IRELATIVE. diff --git a/bfd/elf32-avr.c b/bfd/elf32-avr.c index b95e251..a0a5c69 100644 --- a/bfd/elf32-avr.c +++ b/bfd/elf32-avr.c @@ -1822,7 +1822,7 @@ elf32_avr_relax_delete_bytes (bfd *abfd, Elf_Internal_Rela *irel, *irelend; Elf_Internal_Sym *isym; Elf_Internal_Sym *isymbuf = NULL; - bfd_vma toaddr; + bfd_vma toaddr, reloc_toaddr; struct elf_link_hash_entry **sym_hashes; struct elf_link_hash_entry **end_hashes; unsigned int symcount; @@ -1859,6 +1859,17 @@ elf32_avr_relax_delete_bytes (bfd *abfd, } } + /* We need to look at all relocs with offsets less than toaddr. prop + records handling adjusts toaddr downwards to avoid moving syms at the + address of the property record, but all relocs with offsets between addr + and the current value of toaddr need to have their offsets adjusted. + Assume addr = 0, toaddr = 4 and count = 2. After prop records handling, + toaddr becomes 2, but relocs with offsets 2 and 3 still need to be + adjusted (to 0 and 1 respectively), as the first 2 bytes are now gone. + So record the current value of toaddr here, and use it when adjusting + reloc offsets. */ + reloc_toaddr = toaddr; + irel = elf_section_data (sec)->relocs; irelend = irel + sec->reloc_count; @@ -1917,7 +1928,7 @@ elf32_avr_relax_delete_bytes (bfd *abfd, /* Get the new reloc address. */ if ((irel->r_offset > addr - && irel->r_offset < toaddr)) + && irel->r_offset < reloc_toaddr)) { if (debug_relax) printf ("Relocation at address 0x%x needs to be moved.\n" diff --git a/ld/ChangeLog b/ld/ChangeLog index 446907d..516b4bb 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,9 @@ +2016-06-14 Senthil Kumar Selvaraj + + PR ld/20254 + * testsuite/ld-avr/avr-prop-6.d: New test. + * testsuite/ld-avr/avr-prop-6.s: New test. + 2016-06-14 Alan Modra * ldbuildid.c: Formatting. diff --git a/ld/testsuite/ld-avr/avr-prop-6.d b/ld/testsuite/ld-avr/avr-prop-6.d new file mode 100644 index 0000000..1bf8aa1 --- /dev/null +++ b/ld/testsuite/ld-avr/avr-prop-6.d @@ -0,0 +1,14 @@ +#name: AVR .avr.prop, single .align sym at end of section test. +#as: -mavrxmega2 -mlink-relax +#ld: -mavrxmega2 --relax +#source: avr-prop-6.s +#objdump: -S +#target: avr-*-* + +#... + 0: 00 c0 rjmp .+0 ; 0x2 + +00000002 : + 2: 00 00 nop + 4: fe cf rjmp .-4 ; 0x2 +#... diff --git a/ld/testsuite/ld-avr/avr-prop-6.s b/ld/testsuite/ld-avr/avr-prop-6.s new file mode 100644 index 0000000..4aa3e67 --- /dev/null +++ b/ld/testsuite/ld-avr/avr-prop-6.s @@ -0,0 +1,9 @@ + .text + .global _start, dest +_start: + jmp dest + .align 1 +dest: + nop + rjmp dest + -- 2.7.4