Date: Sunday, October 30, 2016 @ 18:01:28 Author: anatolik Revision: 194037
FS#49284: cherry-pick upstream fix Added: avr-binutils/trunk/fix_relaxation.patch Modified: avr-binutils/trunk/PKGBUILD ----------------------+ PKGBUILD | 12 +- fix_relaxation.patch | 256 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 265 insertions(+), 3 deletions(-) Modified: PKGBUILD =================================================================== --- PKGBUILD 2016-10-30 17:56:05 UTC (rev 194036) +++ PKGBUILD 2016-10-30 18:01:28 UTC (rev 194037) @@ -8,7 +8,7 @@ pkgname=avr-binutils pkgver=2.27 -pkgrel=1 +pkgrel=2 pkgdesc="A set of programs to assemble and manipulate binary and object files for the AVR architecture" arch=('i686' 'x86_64') url="http://www.gnu.org/software/binutils/" @@ -16,10 +16,14 @@ depends=('glibc>=2.17' 'zlib' 'binutils') options=('!distcc' '!ccache') source=(ftp://ftp.gnu.org/gnu/binutils/binutils-${pkgver}.tar.bz2{,.sig} - avr-size.patch) + avr-size.patch + # fix for https://bugs.archlinux.org/task/49284 + # from https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=bf1865065f64af2f32798c0327143baf99634e8d + fix_relaxation.patch) sha1sums=('6e472ddae565a2b1447e6f2393809bb8799982cf' 'SKIP' - 'b6d1ff7084b1f0a3fd2dee5383019ffb202e6c9a') + 'b6d1ff7084b1f0a3fd2dee5383019ffb202e6c9a' + '3c43bc9d27ecb2773afd5859864bdfdb2706d7d7') validpgpkeys=('EAF1C276A747E9ED86210CBAC3126D3B4AE55E93') # Tristan Gingold _builddir=binutils-build @@ -31,6 +35,8 @@ # And https://bugs.archlinux.org/task/40986 patch -Np0 < ${srcdir}/avr-size.patch + patch -p1 < ${srcdir}/fix_relaxation.patch + # https://bugs.archlinux.org/task/34629 sed -i "/ac_cpp=/s/\$CPPFLAGS/\$CPPFLAGS -O2/" libiberty/configure Added: fix_relaxation.patch =================================================================== --- fix_relaxation.patch (rev 0) +++ fix_relaxation.patch 2016-10-30 18:01:28 UTC (rev 194037) @@ -0,0 +1,256 @@ +From bf1865065f64af2f32798c0327143baf99634e8d Mon Sep 17 00:00:00 2001 +From: Senthil Kumar Selvaraj <senthil_kumar.selva...@atmel.com> +Date: Tue, 6 Sep 2016 12:28:37 +0530 +Subject: [PATCH] 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.selva...@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.selva...@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. +--- + bfd/ChangeLog | 10 +++++++++ + bfd/elf32-avr.c | 40 +++++++++++++++++++++++++++++++------ + ld/ChangeLog | 8 +++++++ + ld/testsuite/ld-avr/avr-prop-7.d | 15 ++++++++++++++ + ld/testsuite/ld-avr/avr-prop-7.s | 8 +++++++ + ld/testsuite/ld-avr/avr-prop-8.d | 13 ++++++++++++ + ld/testsuite/ld-avr/avr-prop-8.s | 7 ++++++ + 7 files changed, 94 insertions(+), 7 deletions(-) + create mode 100644 ld/testsuite/ld-avr/avr-prop-7.d + create mode 100644 ld/testsuite/ld-avr/avr-prop-7.s + create mode 100644 ld/testsuite/ld-avr/avr-prop-8.d + create mode 100644 ld/testsuite/ld-avr/avr-prop-8.s + +diff --git a/bfd/elf32-avr.c b/bfd/elf32-avr.c +index a0a5c69..eea76a4 100644 +--- a/bfd/elf32-avr.c ++++ b/bfd/elf32-avr.c +@@ -1808,13 +1808,17 @@ elf32_avr_adjust_diff_reloc_value (bfd *abfd, + /* Delete some bytes from a section while changing the size of an instruction. + The parameter "addr" denotes the section-relative offset pointing just + behind the shrinked instruction. "addr+count" point at the first +- byte just behind the original unshrinked instruction. */ ++ byte just behind the original unshrinked instruction. If delete_shrinks_insn ++ is FALSE, we are deleting redundant padding bytes from relax_info prop ++ record handling. In that case, addr is section-relative offset of start ++ of padding, and count is the number of padding bytes to delete. */ + + static bfd_boolean + elf32_avr_relax_delete_bytes (bfd *abfd, + asection *sec, + bfd_vma addr, +- int count) ++ int count, ++ bfd_boolean delete_shrinks_insn) + { + Elf_Internal_Shdr *symtab_hdr; + unsigned int sec_shndx; +@@ -1829,6 +1833,7 @@ elf32_avr_relax_delete_bytes (bfd *abfd, + struct avr_relax_info *relax_info; + struct avr_property_record *prop_record = NULL; + bfd_boolean did_shrink = FALSE; ++ bfd_boolean did_pad = FALSE; + + symtab_hdr = &elf_tdata (abfd)->symtab_hdr; + sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec); +@@ -1909,6 +1914,7 @@ elf32_avr_relax_delete_bytes (bfd *abfd, + 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); ++ did_pad = TRUE; + + /* Adjust the TOADDR to avoid moving symbols located at the address + of the property record, which has not moved. */ +@@ -1965,7 +1971,9 @@ elf32_avr_relax_delete_bytes (bfd *abfd, + continue; + + shrinked_insn_address = (sec->output_section->vma +- + sec->output_offset + addr - count); ++ + sec->output_offset + addr); ++ if (delete_shrinks_insn) ++ shrinked_insn_address -= count; + + irel = elf_section_data (isec)->relocs; + /* PR 12161: Read in the relocs for this section if necessary. */ +@@ -2002,6 +2010,13 @@ elf32_avr_relax_delete_bytes (bfd *abfd, + a symbol or section associated with it. */ + if (sym_sec == sec) + { ++ /* If there is an alignment boundary, we only need to ++ adjust addends that end up below the boundary. */ ++ bfd_vma shrink_boundary = (reloc_toaddr ++ + sec->output_section->vma ++ + sec->output_offset); ++ bfd_boolean addend_within_shrink_boundary = FALSE; ++ + symval += sym_sec->output_section->vma + + sym_sec->output_offset; + +@@ -2015,8 +2030,17 @@ elf32_avr_relax_delete_bytes (bfd *abfd, + (unsigned int) (symval + irel->r_addend), + (unsigned int) shrinked_insn_address); + ++ /* If we padded bytes, then the boundary didn't change, ++ so there's no need to adjust addends pointing at the boundary. ++ If we didn't pad, then we actually shrank the boundary, so ++ addends pointing at the boundary need to be adjusted too. */ ++ addend_within_shrink_boundary = did_pad ++ ? ((symval + irel->r_addend) < shrink_boundary) ++ : ((symval + irel->r_addend) <= shrink_boundary); ++ + if (symval <= shrinked_insn_address +- && (symval + irel->r_addend) > shrinked_insn_address) ++ && (symval + irel->r_addend) > shrinked_insn_address ++ && addend_within_shrink_boundary) + { + if (elf32_avr_is_diff_reloc (irel)) + { +@@ -2648,7 +2672,8 @@ elf32_avr_relax_section (bfd *abfd, + { + /* Delete two bytes of data. */ + if (!elf32_avr_relax_delete_bytes (abfd, sec, +- irel->r_offset + 2, 2)) ++ irel->r_offset + 2, 2, ++ TRUE)) + goto error_return; + + /* That will change things, so, we should relax again. +@@ -2972,7 +2997,8 @@ elf32_avr_relax_section (bfd *abfd, + + /* Delete two bytes of data. */ + if (!elf32_avr_relax_delete_bytes (abfd, sec, +- irel->r_offset + insn_size, 2)) ++ irel->r_offset + insn_size, 2, ++ TRUE)) + goto error_return; + + /* That will change things, so, we should relax +@@ -3040,7 +3066,7 @@ elf32_avr_relax_section (bfd *abfd, + record->offset -= count; + elf32_avr_relax_delete_bytes (abfd, sec, + addr - count, +- count); ++ count, FALSE); + *again = TRUE; + } + } +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 +-- +1.7.1 +