Merge pull request #8259 from lazka/binutils-reloc-backport
binutils: backport fix for "relocation truncated to fit" errors
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
From 74edb473c9ecf5e2053ecf8e429ee608feafb9e1 Mon Sep 17 00:00:00 2001
|
||||
From: Tamar Christina <tamar.christina@arm.com>
|
||||
Date: Thu, 1 Apr 2021 17:10:38 +0100
|
||||
Subject: [PATCH] PE/Windows x86_64: Fix weak undef symbols after image base
|
||||
change
|
||||
|
||||
The change in PR19011 changed the image load address from being in the lower
|
||||
32-bit address space to the higher 64-bit address space.
|
||||
|
||||
However when you have a weak undef symbol which stays undef at the end of
|
||||
linking the linker has to resolve this (Windows loader does not support undef
|
||||
symbols). As such typically these would resolve to 0.
|
||||
|
||||
The relocation used for these weak symbols are the normal 32-bit PC_REL call
|
||||
relocs. So when doing the overflow check LD checks if the distance between the
|
||||
symbol and the call is within range. However now that the load address is
|
||||
> 32-bits and the symbol val is 0 this overflow check will always fail.
|
||||
|
||||
As such the linker gives a bogus error. This patch makes the linker not emit
|
||||
the overflow failure but chooses to still let the check be performed (as it's
|
||||
mid-end code).
|
||||
|
||||
One down side of this is that it does break the common convention that the call
|
||||
be to sym at 0x0. i.e. before you'd get
|
||||
|
||||
401015: 74 05 je 40101c
|
||||
401017: e8 e4 ef bf ff callq 0
|
||||
|
||||
and now you get
|
||||
|
||||
140001015: 74 05 je 14000101c
|
||||
140001017: e8 e4 ef ff bf call 100000000
|
||||
|
||||
since the call is PC_REL there's no way to get the range large enough to
|
||||
resolve to 0. As such I have chosen to leave it as the furthest simple range
|
||||
that we can still represent.
|
||||
|
||||
By only ignoring the error we leave the symbol value itself to still be 0
|
||||
such that the if(<symbol>) checks still work correctly.
|
||||
|
||||
bfd/ChangeLog:
|
||||
|
||||
2021-04-01 Tamar Christina <tamar.christina@arm.com>
|
||||
|
||||
PR ld/26659
|
||||
* cofflink.c (_bfd_coff_generic_relocate_section): Ignore overflow.
|
||||
|
||||
ld/ChangeLog:
|
||||
|
||||
2021-04-01 Tamar Christina <tamar.christina@arm.com>
|
||||
|
||||
PR ld/26659
|
||||
* testsuite/ld-pe/pe.exp: Add test.
|
||||
* testsuite/ld-pe/pr26659-weak-undef-sym.d: New test.
|
||||
* testsuite/ld-pe/pr26659-weak-undef-sym.s: New test.
|
||||
---
|
||||
bfd/ChangeLog | 5 +++
|
||||
bfd/cofflink.c | 15 ++++++++
|
||||
ld/ChangeLog | 7 ++++
|
||||
ld/testsuite/ld-pe/pe.exp | 1 +
|
||||
ld/testsuite/ld-pe/pr26659-weak-undef-sym.d | 32 +++++++++++++++++
|
||||
ld/testsuite/ld-pe/pr26659-weak-undef-sym.s | 38 +++++++++++++++++++++
|
||||
6 files changed, 98 insertions(+)
|
||||
create mode 100644 ld/testsuite/ld-pe/pr26659-weak-undef-sym.d
|
||||
create mode 100644 ld/testsuite/ld-pe/pr26659-weak-undef-sym.s
|
||||
|
||||
diff --git a/bfd/cofflink.c b/bfd/cofflink.c
|
||||
index c6b65c761d7..dd3e8dd4bf6 100644
|
||||
--- a/bfd/cofflink.c
|
||||
+++ b/bfd/cofflink.c
|
||||
@@ -3129,6 +3129,21 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd,
|
||||
return false;
|
||||
case bfd_reloc_overflow:
|
||||
{
|
||||
+
|
||||
+ /* Ignore any weak undef symbols that may have overflowed. Due to
|
||||
+ PR ld/19011 the base address is now in the upper 64-bit address
|
||||
+ range. This means that when _bfd_final_link_relocate calculates
|
||||
+ the overlow it takes the distance between the symbol and the VMA
|
||||
+ which will now always overflow as 0 - 64-bit addr > 32-bit range
|
||||
+ of the relocation. This ends up creating PR ld/26659. */
|
||||
+ if (val == 0
|
||||
+ /* Reverse the hack where 4 is subtracted from the addend. */
|
||||
+ && (addend + 4) == 0
|
||||
+ && sym->n_sclass == C_NT_WEAK
|
||||
+ && bfd_coff_classify_symbol (output_bfd, sym)
|
||||
+ == COFF_SYMBOL_UNDEFINED)
|
||||
+ break;
|
||||
+
|
||||
const char *name;
|
||||
char buf[SYMNMLEN + 1];
|
||||
|
||||
diff --git a/ld/testsuite/ld-pe/pe.exp b/ld/testsuite/ld-pe/pe.exp
|
||||
index b1a200180be..a536b51c3e6 100644
|
||||
--- a/ld/testsuite/ld-pe/pe.exp
|
||||
+++ b/ld/testsuite/ld-pe/pe.exp
|
||||
@@ -81,6 +81,7 @@ run_dump_test "reloc"
|
||||
run_dump_test "weakdef-1"
|
||||
|
||||
run_dump_test "pr19803"
|
||||
+run_dump_test "pr26659-weak-undef-sym"
|
||||
set pr19803_dll {
|
||||
{ "PR 19803: not exporting swept symbols"
|
||||
"-shared --out-implib dx.dll --gc-sections"
|
||||
diff --git a/ld/testsuite/ld-pe/pr26659-weak-undef-sym.d b/ld/testsuite/ld-pe/pr26659-weak-undef-sym.d
|
||||
new file mode 100644
|
||||
index 00000000000..0b48994877d
|
||||
--- /dev/null
|
||||
+++ b/ld/testsuite/ld-pe/pr26659-weak-undef-sym.d
|
||||
@@ -0,0 +1,32 @@
|
||||
+#source: pr26659-weak-undef-sym.s
|
||||
+#target: x86_64-*-cygwin* x86_64-*-pe x86_64-*-mingw*
|
||||
+#ld: -e0
|
||||
+#objdump: -d
|
||||
+
|
||||
+#...
|
||||
+0000000140001000 <foo>:
|
||||
+ 140001000: 55 push %rbp
|
||||
+ 140001001: 48 89 e5 mov %rsp,%rbp
|
||||
+ 140001004: 48 83 ec 20 sub \$0x20,%rsp
|
||||
+ 140001008: 89 4d 10 mov %ecx,0x10\(%rbp\)
|
||||
+ 14000100b: 48 8b 05 ee 0f 00 00 mov 0xfee\(%rip\),%rax # 140002000 <__data_end__>
|
||||
+ 140001012: 48 85 c0 test %rax,%rax
|
||||
+ 140001015: 74 05 je 14000101c <foo\+0x1c>
|
||||
+ 140001017: e8 e4 ef ff bf call 100000000 <__size_of_stack_reserve__\+0xffe00000>
|
||||
+ 14000101c: 48 8b 05 ed 0f 00 00 mov 0xfed\(%rip\),%rax # 140002010 <.refptr.bar2>
|
||||
+ 140001023: 48 85 c0 test %rax,%rax
|
||||
+ 140001026: 74 05 je 14000102d <foo\+0x2d>
|
||||
+ 140001028: e8 d3 ef ff bf call 100000000 <__size_of_stack_reserve__\+0xffe00000>
|
||||
+ 14000102d: 8b 45 10 mov 0x10\(%rbp\),%eax
|
||||
+ 140001030: 0f af c0 imul %eax,%eax
|
||||
+ 140001033: 48 83 c4 20 add \$0x20,%rsp
|
||||
+ 140001037: 5d pop %rbp
|
||||
+ 140001038: c3 ret
|
||||
+ 140001039: 90 nop
|
||||
+ 14000103a: 90 nop
|
||||
+ 14000103b: 90 nop
|
||||
+ 14000103c: 90 nop
|
||||
+ 14000103d: 90 nop
|
||||
+ 14000103e: 90 nop
|
||||
+ 14000103f: 90 nop
|
||||
+#pass
|
||||
diff --git a/ld/testsuite/ld-pe/pr26659-weak-undef-sym.s b/ld/testsuite/ld-pe/pr26659-weak-undef-sym.s
|
||||
new file mode 100644
|
||||
index 00000000000..7a42759e752
|
||||
--- /dev/null
|
||||
+++ b/ld/testsuite/ld-pe/pr26659-weak-undef-sym.s
|
||||
@@ -0,0 +1,38 @@
|
||||
+ .text
|
||||
+ .globl foo
|
||||
+ .def foo; .scl 2; .type 32; .endef
|
||||
+foo:
|
||||
+ pushq %rbp
|
||||
+ movq %rsp, %rbp
|
||||
+ subq $32, %rsp
|
||||
+ movl %ecx, 16(%rbp)
|
||||
+ movq .refptr.bar1(%rip), %rax
|
||||
+ testq %rax, %rax
|
||||
+ je .L2
|
||||
+ call bar1
|
||||
+.L2:
|
||||
+ movq .refptr.bar2(%rip), %rax
|
||||
+ testq %rax, %rax
|
||||
+ je .L3
|
||||
+ call bar2
|
||||
+.L3:
|
||||
+ movl 16(%rbp), %eax
|
||||
+ imull %eax, %eax
|
||||
+ addq $32, %rsp
|
||||
+ popq %rbp
|
||||
+ ret
|
||||
+ .weak bar2
|
||||
+ .weak bar1
|
||||
+ .def bar1; .scl 2; .type 32; .endef
|
||||
+ .def bar2; .scl 2; .type 32; .endef
|
||||
+ .section .rdata$.refptr.bar2, "dr"
|
||||
+ .globl .refptr.bar2
|
||||
+ .linkonce discard
|
||||
+.refptr.bar2:
|
||||
+ .quad bar2
|
||||
+ .section .rdata$.refptr.bar1, "dr"
|
||||
+ .globl .refptr.bar1
|
||||
+ .linkonce discard
|
||||
+.refptr.bar1:
|
||||
+ .quad bar1
|
||||
+
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@@ -6,7 +6,7 @@ _realname=binutils
|
||||
pkgbase=mingw-w64-${_realname}
|
||||
pkgname=("${MINGW_PACKAGE_PREFIX}-${_realname}")
|
||||
pkgver=2.36.1
|
||||
pkgrel=2
|
||||
pkgrel=3
|
||||
pkgdesc="A set of programs to assemble and manipulate binary and object files (mingw-w64)"
|
||||
arch=('any')
|
||||
mingw_arch=('mingw32' 'mingw64' 'ucrt64')
|
||||
@@ -21,6 +21,7 @@ source=(https://ftp.gnu.org/gnu/binutils/${_realname}-${pkgver}.tar.xz{,.sig}
|
||||
0010-bfd-Increase-_bfd_coff_max_nscns-to-65279.patch
|
||||
0110-binutils-mingw-gnu-print.patch
|
||||
0410-windres-handle-spaces.patch
|
||||
0500-fix-weak-undef-symbols-after-image-base-change.patch
|
||||
2001-ld-option-to-move-default-bases-under-4GB.patch)
|
||||
sha256sums=('e81d9edf373f193af428a0f256674aea62a9d74dfe93f65192d4eae030b0f3b0'
|
||||
'SKIP'
|
||||
@@ -28,6 +29,7 @@ sha256sums=('e81d9edf373f193af428a0f256674aea62a9d74dfe93f65192d4eae030b0f3b0'
|
||||
'604e76e0f702ced493ee22aa3c1768b4776b2008a7d70ae0dd35fe5be3522141'
|
||||
'ec199975c6af5586f00730b7246b1db7d956879ef569c023d998226aa7960a1f'
|
||||
'8d8608dc18a697138f9e51415e0c6559a85c49b11943700a823a74fb205419e9'
|
||||
'd0cd7344421054fb38339cf8b6622e4e80ecda94750ffb429b702b247a5f28ae'
|
||||
'35518b99189914b4700fad7a42b3268f67b5b6f4e23ffcc6cd9ef31b7b2b7c9f')
|
||||
validpgpkeys=('EAF1C276A747E9ED86210CBAC3126D3B4AE55E93'
|
||||
'3A24BC1E8FB409FA9F14371813FCEF89DD9E3C4F')
|
||||
@@ -55,6 +57,9 @@ prepare() {
|
||||
# https://github.com/msys2/MINGW-packages/issues/7027
|
||||
# https://github.com/msys2/MINGW-packages/issues/7023
|
||||
apply_patch_with_msg 2001-ld-option-to-move-default-bases-under-4GB.patch
|
||||
|
||||
# https://sourceware.org/pipermail/binutils/2021-April/116019.html
|
||||
apply_patch_with_msg 0500-fix-weak-undef-symbols-after-image-base-change.patch
|
||||
}
|
||||
|
||||
build() {
|
||||
|
||||
Reference in New Issue
Block a user