aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTamar Christina <tamar.christina@arm.com>2021-04-01 17:10:38 +0100
committerAndreas K. Hüttel <dilfridge@gentoo.org>2021-04-20 17:44:57 +0200
commit0bef08db255c42c6c12682ac175071e744cf1d46 (patch)
tree373274d366b562ae0afc8a8cab4738c2624430f2
parentDWARF: Check version >= 3 for DW_FORM_ref_addr (diff)
downloadbinutils-gdb-0bef08db255c42c6c12682ac175071e744cf1d46.tar.gz
binutils-gdb-0bef08db255c42c6c12682ac175071e744cf1d46.tar.bz2
binutils-gdb-0bef08db255c42c6c12682ac175071e744cf1d46.zip
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. (cherry picked from commit 74edb473c9ecf5e2053ecf8e429ee608feafb9e1) (cherry picked from commit 0ff9fad8bf790eebb21a1c1ee378f1c2dd1971af)
-rw-r--r--bfd/ChangeLog8
-rw-r--r--bfd/cofflink.c15
-rw-r--r--ld/ChangeLog10
-rw-r--r--ld/testsuite/ld-pe/pe.exp1
-rw-r--r--ld/testsuite/ld-pe/pr26659-weak-undef-sym.d32
-rw-r--r--ld/testsuite/ld-pe/pr26659-weak-undef-sym.s38
6 files changed, 104 insertions, 0 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 24d25dc1a46..ea9d22e13bb 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,11 @@
+2021-04-01 Tamar Christina <tamar.christina@arm.com>
+
+ Backported from mainline.
+ 2021-04-01 Tamar Christina <tamar.christina@arm.com>
+
+ PR ld/26659
+ * cofflink.c (_bfd_coff_generic_relocate_section): Ignore overflow.
+
2021-03-22 H.J. Lu <hongjiu.lu@intel.com>
PR ld/27587
diff --git a/bfd/cofflink.c b/bfd/cofflink.c
index 4b0aab2a4ce..d0c027f2dce 100644
--- a/bfd/cofflink.c
+++ b/bfd/cofflink.c
@@ -3118,6 +3118,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/ChangeLog b/ld/ChangeLog
index 094ca70ad0c..87899bcd49c 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,13 @@
+2021-04-01 Tamar Christina <tamar.christina@arm.com>
+
+ Backported from mainline
+ 2021-04-01 Tamar Christina <tamar.christina@arm.com>
+
+ PR ld/26659
+ * testsuite/ld-pe/pe.exp:
+ * testsuite/ld-pe/pr26659-weak-undef-sym.d: New test.
+ * testsuite/ld-pe/pr26659-weak-undef-sym.s: New test.
+
2021-03-02 Alan Modra <amodra@gmail.com>
* testsuite/ld-powerpc/weak1.d,
diff --git a/ld/testsuite/ld-pe/pe.exp b/ld/testsuite/ld-pe/pe.exp
index de9e104f0f6..5b04b6b8075 100644
--- a/ld/testsuite/ld-pe/pe.exp
+++ b/ld/testsuite/ld-pe/pe.exp
@@ -79,6 +79,7 @@ run_dump_test "orphan_nu"
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
+