Skip to content

Commit

Permalink
[BOLT] Skip PLT search for zero-value weak reference symbols (llvm#69136
Browse files Browse the repository at this point in the history
)

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)
  • Loading branch information
linsinan1995 authored and llvmbot committed Aug 7, 2024
1 parent d033ae1 commit f30f9cb
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 1 deletion.
11 changes: 10 additions & 1 deletion bolt/lib/Rewrite/RewriteInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2143,6 +2143,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);
Expand Down Expand Up @@ -2174,7 +2182,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;
}
Expand Down
34 changes: 34 additions & 0 deletions bolt/test/AArch64/update-weak-reference-symbol.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// 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

.text
.weak func_2
.weak func_1
.global wow
.type wow, %function
wow:
bl func_1
bl func_2
ret
.type func_2, %function
func_2:
ret
.section .rodata
.LC0:
.xword func_1
.LC1:
.xword func_2

0 comments on commit f30f9cb

Please sign in to comment.