[llvm] [Bolt] fix a wrong relocation update issue with weak references (PR #69136)

via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 5 02:17:45 PST 2023


https://github.com/linsinan1995 updated https://github.com/llvm/llvm-project/pull/69136

>From 6a25f55d949350890374fe17e8fce7059a3d0a3e Mon Sep 17 00:00:00 2001
From: Sinan Lin <sinan.lin at linux.alibaba.com>
Date: Mon, 16 Oct 2023 09:51:48 +0800
Subject: [PATCH] [BOLT] do not search for PLT entries if the relocation is
 against a weak reference symbol.

Take a common weak reference pattern for example
```
__attribute__((weak)) void undef_weak_fun();

  if (&undef_weak_fun)
    undef_weak_fun();
```

In this case, an undefined weak symbol `undef_weak_fun` has an address
of zero, and Bolt incorrectly changes the relocation for the
corresponding symbol to symbol at PLT, leading to incorrect runtime
behavior.
---
 bolt/lib/Rewrite/RewriteInstance.cpp          | 11 ++-
 .../AArch64/update-weak-reference-symbol.s    | 77 +++++++++++++++++++
 2 files changed, 87 insertions(+), 1 deletion(-)
 create mode 100644 bolt/test/AArch64/update-weak-reference-symbol.s

diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 81c9cbff726bb..ea94d0d0a6551 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -2067,6 +2067,14 @@ bool RewriteInstance::analyzeRelocation(
   if (!Relocation::isSupported(RType))
     return false;
 
+  auto IsWeakReference = [](const SymbolRef &Symbol) {
+    Expected<uint32_t> SymFlagsOrErr = Symbol.getFlags();
+    if (!SymFlagsOrErr)
+      return false;
+    return (*SymFlagsOrErr & SymbolRef::SF_Undefined) &&
+           (*SymFlagsOrErr & SymbolRef::SF_Weak);
+  };
+
   const bool IsAArch64 = BC->isAArch64();
 
   const size_t RelSize = Relocation::getSizeForType(RType);
@@ -2098,7 +2106,8 @@ bool RewriteInstance::analyzeRelocation(
     // Section symbols are marked as ST_Debug.
     IsSectionRelocation = (cantFail(Symbol.getType()) == SymbolRef::ST_Debug);
     // Check for PLT entry registered with symbol name
-    if (!SymbolAddress && (IsAArch64 || BC->isRISCV())) {
+    if (!SymbolAddress && !IsWeakReference(Symbol) &&
+        (IsAArch64 || BC->isRISCV())) {
       const BinaryData *BD = BC->getPLTBinaryDataByName(SymbolName);
       SymbolAddress = BD ? BD->getAddress() : 0;
     }
diff --git a/bolt/test/AArch64/update-weak-reference-symbol.s b/bolt/test/AArch64/update-weak-reference-symbol.s
new file mode 100644
index 0000000000000..6de4ce5dfdccf
--- /dev/null
+++ b/bolt/test/AArch64/update-weak-reference-symbol.s
@@ -0,0 +1,77 @@
+// This test checks whether BOLT can correctly handle relocations against weak symbols.
+
+// RUN: %clang %cflags -Wl,-z,notext -shared -Wl,-q %s -o %t.so
+// RUN: llvm-bolt %t.so -o %t.so.bolt
+
+// RUN: llvm-nm -n %t.so.bolt > %t.out.txt
+// RUN: llvm-objdump -dj .rodata %t.so.bolt >> %t.out.txt
+// RUN: FileCheck %s --input-file=%t.out.txt
+
+# CHECK: w func_1
+# CHECK: {{0+}}[[#%x,ADDR:]] W func_2
+
+# CHECK: {{.*}} <.rodata>:
+# CHECK-NEXT: {{.*}} .word 0x00000000
+# CHECK-NEXT: {{.*}} .word 0x00000000
+# CHECK-NEXT: {{.*}} .word 0x{{[0]+}}[[#ADDR]]
+# CHECK-NEXT: {{.*}} .word 0x00000000
+
+	.arch armv8-a
+	.text
+	.align	2
+	.global	wow
+	.type	wow, %function
+wow:
+.LFB0:
+	.cfi_startproc
+	stp	x29, x30, [sp, -16]!
+	.cfi_def_cfa_offset 16
+	.cfi_offset 29, -16
+	.cfi_offset 30, -8
+	mov	x29, sp
+	adrp	x0, .LC0
+	add	x0, x0, :lo12:.LC0
+	ldr	x0, [x0]
+	cmp	x0, 0
+	beq	.L2
+	bl	func_1
+.L2:
+	adrp	x0, .LC1
+	add	x0, x0, :lo12:.LC1
+	ldr	x0, [x0]
+	cmp	x0, 0
+	beq	.L5
+	bl	func_2
+	nop
+.L5:
+	nop
+	ldp	x29, x30, [sp], 16
+	.cfi_restore 30
+	.cfi_restore 29
+	.cfi_def_cfa_offset 0
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	wow, .-wow
+	.section	.rodata
+	.align	3
+.LC0:
+	.xword	func_1
+	.align	3
+.LC1:
+	.xword	func_2
+	.weak	func_2
+	.weak	func_1
+	.text
+	.align  2
+	.weak func_2
+	.type   func_2, %function
+func_2:
+.LFB1:
+	.cfi_startproc
+	nop
+	ret
+	.cfi_endproc
+.LFE1:
+  .size   func_2, .-func_2
+	.section	.note.GNU-stack,"", at progbits



More information about the llvm-commits mailing list