Skip to content

Commit 2e0782c

Browse files
linsinan1995tru
authored andcommitted
[BOLT] Skip PLT search for zero-value weak reference symbols (llvm#69136)
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@PLT, leading to incorrect runtime behavior. (cherry picked from commit 6c8933e)
1 parent eb4619c commit 2e0782c

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed

bolt/lib/Rewrite/RewriteInstance.cpp

+10-1
Original file line numberDiff line numberDiff line change
@@ -2143,6 +2143,14 @@ bool RewriteInstance::analyzeRelocation(
21432143
if (!Relocation::isSupported(RType))
21442144
return false;
21452145

2146+
auto IsWeakReference = [](const SymbolRef &Symbol) {
2147+
Expected<uint32_t> SymFlagsOrErr = Symbol.getFlags();
2148+
if (!SymFlagsOrErr)
2149+
return false;
2150+
return (*SymFlagsOrErr & SymbolRef::SF_Undefined) &&
2151+
(*SymFlagsOrErr & SymbolRef::SF_Weak);
2152+
};
2153+
21462154
const bool IsAArch64 = BC->isAArch64();
21472155

21482156
const size_t RelSize = Relocation::getSizeForType(RType);
@@ -2174,7 +2182,8 @@ bool RewriteInstance::analyzeRelocation(
21742182
// Section symbols are marked as ST_Debug.
21752183
IsSectionRelocation = (cantFail(Symbol.getType()) == SymbolRef::ST_Debug);
21762184
// Check for PLT entry registered with symbol name
2177-
if (!SymbolAddress && (IsAArch64 || BC->isRISCV())) {
2185+
if (!SymbolAddress && !IsWeakReference(Symbol) &&
2186+
(IsAArch64 || BC->isRISCV())) {
21782187
const BinaryData *BD = BC->getPLTBinaryDataByName(SymbolName);
21792188
SymbolAddress = BD ? BD->getAddress() : 0;
21802189
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// This test checks whether BOLT can correctly handle relocations against weak symbols.
2+
3+
// RUN: %clang %cflags -Wl,-z,notext -shared -Wl,-q %s -o %t.so
4+
// RUN: llvm-bolt %t.so -o %t.so.bolt
5+
// RUN: llvm-nm -n %t.so.bolt > %t.out.txt
6+
// RUN: llvm-objdump -dj .rodata %t.so.bolt >> %t.out.txt
7+
// RUN: FileCheck %s --input-file=%t.out.txt
8+
9+
# CHECK: w func_1
10+
# CHECK: {{0+}}[[#%x,ADDR:]] W func_2
11+
12+
# CHECK: {{.*}} <.rodata>:
13+
# CHECK-NEXT: {{.*}} .word 0x00000000
14+
# CHECK-NEXT: {{.*}} .word 0x00000000
15+
# CHECK-NEXT: {{.*}} .word 0x{{[0]+}}[[#ADDR]]
16+
# CHECK-NEXT: {{.*}} .word 0x00000000
17+
18+
.text
19+
.weak func_2
20+
.weak func_1
21+
.global wow
22+
.type wow, %function
23+
wow:
24+
bl func_1
25+
bl func_2
26+
ret
27+
.type func_2, %function
28+
func_2:
29+
ret
30+
.section .rodata
31+
.LC0:
32+
.xword func_1
33+
.LC1:
34+
.xword func_2

0 commit comments

Comments
 (0)