[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