[arch-commits] Commit in avr-binutils/trunk (PKGBUILD fix_relaxation.patch)
Anatol Pomozov
anatolik at archlinux.org
Sun Oct 30 18:01:29 UTC 2016
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.selvaraj at 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.selvaraj at 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 at 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
+
More information about the arch-commits
mailing list