[llvm] [BOLT] Skip non-code relocs as function references (PR #215028)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 8 14:43:37 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-bolt
Author: Amir Ayupov (aaupov)
<details>
<summary>Changes</summary>
handleRelocation looked up the referenced function from the resolved "symbol + addend" address, ignoring the symbol's section. With biased array indexing the compiler folds a constant into the displacement, e.g.
```
movq const_int_rtx-0x3fe00(,%rax,8), %r14 # R_X86_64_32S const_int_rtx-0x3fe00
```
so the unbiased displacement is not a live address (only disp + rax*8 is), yet it can land inside an unrelated function. BOLT re-anchored the relocation onto that function and dropped the addend, then during disassembly registered an interprocedural reference to a mid-instruction address, producing:
```
BOLT-WARNING: corrupted control flow detected in function ...: an external
branch/call targets an invalid instruction in function ... ; ignoring both
```
With -use-old-text this causes "cannot ignore non-empty function in current mode". Observed on SPEC CPU2026 821.gcc_s built with clang15.
Check `IsToCode || IsSectionReference` prior to setting a ReferencedBF.
Test Plan:
Added bolt/test/X86/reloc-data-symbol-negative-addend.s
---
Full diff: https://github.com/llvm/llvm-project/pull/215028.diff
2 Files Affected:
- (modified) bolt/lib/Rewrite/RewriteInstance.cpp (+7-2)
- (added) bolt/test/X86/reloc-data-symbol-negative-addend.s (+40)
``````````diff
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index c122614a5ee0f..a5de2b5733355 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -3318,8 +3318,13 @@ void RewriteInstance::handleRelocation(const SectionRef &RelocatedSection,
// Occasionally we may see a reference past the last byte of the function
// typically as a result of __builtin_unreachable(). Check it here.
- BinaryFunction *ReferencedBF = BC->getBinaryFunctionContainingAddress(
- Address, /*CheckPastEnd*/ true, /*UseMaxSize*/ IsAArch64);
+ //
+ // Only look for a referenced function when the symbol itself denotes code
+ // or it is a section relocation.
+ BinaryFunction *ReferencedBF = nullptr;
+ if (IsToCode || IsSectionRelocation)
+ ReferencedBF = BC->getBinaryFunctionContainingAddress(
+ Address, /*CheckPastEnd*/ true, /*UseMaxSize*/ IsAArch64);
if (!IsSectionRelocation) {
if (BinaryFunction *BF =
diff --git a/bolt/test/X86/reloc-data-symbol-negative-addend.s b/bolt/test/X86/reloc-data-symbol-negative-addend.s
new file mode 100644
index 0000000000000..1c3a5cf21bd8f
--- /dev/null
+++ b/bolt/test/X86/reloc-data-symbol-negative-addend.s
@@ -0,0 +1,40 @@
+## Check that a relocation against a data symbol with a negative addend is not
+## mistaken for a reference into a function when "symbol + addend" happens to
+## resolve inside one. Compilers fold a bias into the displacement for indexed
+## accesses, e.g. "mov sym-0x3fe00(,%rax,8)", and the unbiased address is never
+## used on its own.
+
+# REQUIRES: system-linux
+
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o
+# RUN: ld.lld %t.o -o %t.exe -q --nostdlib -e _start --image-base=0x200000 \
+# RUN: --section-start=.text=0x200000 --section-start=.mydata=0x400000
+# RUN: llvm-bolt %t.exe -o %t.bolt --relocs 2>&1 | FileCheck %s
+
+## The biased displacement resolves into the middle of an instruction in
+## "target". BOLT used to report that as an external branch and ignore both
+## functions.
+# CHECK-NOT: corrupted control flow
+
+ .text
+ .globl target
+ .type target, @function
+target:
+## 10-byte instruction at 0x200000, so 0x200003 is not an instruction boundary.
+ movabsq $0x1122334455667788, %rax
+ retq
+ .size target, .-target
+
+ .globl _start
+ .type _start, @function
+_start:
+## datasym is at 0x400000, so datasym-0x1ffffd resolves to 0x200003, inside
+## "target" above.
+ movq datasym-0x1ffffd(,%rax,8), %r14
+ retq
+ .size _start, .-_start
+
+ .section .mydata, "aw", @progbits
+ .globl datasym
+datasym:
+ .quad 0
``````````
</details>
https://github.com/llvm/llvm-project/pull/215028
More information about the llvm-commits
mailing list