[llvm] [BOLT] Update LSDA encoding for x86-64 large code model (PR #190685)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 6 14:03:16 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-bolt
Author: Farid Zakaria (fzakaria)
<details>
<summary>Changes</summary>
BOLT hardcoded 4-byte LSDA (exception table) encoding for x86-64. This is insufficient for large code model binaries where functions in .ltext sections may be placed at addresses above 2GB, exceeding the range of DW_EH_PE_udata4/DW_EH_PE_sdata4 encodings.
Detect large code model by checking for .ltext sections (SHF_X86_64_LARGE) and update LSDAEncoding to use 8-byte pointers:
- Non-PIC: DW_EH_PE_absptr (8-byte absolute)
- PIC: DW_EH_PE_pcrel | DW_EH_PE_sdata8 (8-byte PC-relative)
This was pulled out from https://github.com/llvm/llvm-project/pull/190637
---
Full diff: https://github.com/llvm/llvm-project/pull/190685.diff
4 Files Affected:
- (modified) bolt/include/bolt/Core/BinaryContext.h (+3)
- (modified) bolt/lib/Core/BinaryContext.cpp (+3-1)
- (modified) bolt/lib/Rewrite/RewriteInstance.cpp (+13)
- (added) bolt/test/X86/ltext-lsda-encoding.s (+38)
``````````diff
diff --git a/bolt/include/bolt/Core/BinaryContext.h b/bolt/include/bolt/Core/BinaryContext.h
index f8a0be0418433..c6de5094f66c3 100644
--- a/bolt/include/bolt/Core/BinaryContext.h
+++ b/bolt/include/bolt/Core/BinaryContext.h
@@ -726,6 +726,9 @@ class BinaryContext {
/// FunctionFragment::getFragmentNum() == FragmentNum::warm()
bool HasWarmSection{false};
+ /// Indicates if the binary has large code model sections (.ltext).
+ bool HasLargeCodeModel{false};
+
/// Is the binary always loaded at a fixed address. Shared objects and
/// position-independent executables (PIEs) are examples of binaries that
/// will have HasFixedLoadAddress set to false.
diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp
index 5b3baf1669624..e8c1234ca5497 100644
--- a/bolt/lib/Core/BinaryContext.cpp
+++ b/bolt/lib/Core/BinaryContext.cpp
@@ -256,7 +256,9 @@ Expected<std::unique_ptr<BinaryContext>> BinaryContext::createBinaryContext(
std::unique_ptr<MCObjectFileInfo> MOFI(
TheTarget->createMCObjectFileInfo(*Ctx, IsPIC));
Ctx->setObjectFileInfo(MOFI.get());
- // We do not support X86 Large code model. Change this in the future.
+ // Use large code model encoding for AArch64 (always). For X86 large code
+ // model, LSDAEncoding is updated later in readSpecialSections() after
+ // detecting .ltext sections.
bool Large = false;
if (TheTriple.getArch() == llvm::Triple::aarch64)
Large = true;
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index b3208ac024ae6..d522615fd8b67 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -2237,6 +2237,19 @@ Error RewriteInstance::readSpecialSections() {
"Use -update-debug-sections to keep it.\n";
}
+ // Detect large code model sections (.ltext) and update LSDA encoding to
+ // use 8-byte pointers for exception handling in large code model binaries.
+ if (BC->getUniqueSectionByName(".ltext")) {
+ BC->HasLargeCodeModel = true;
+ BC->outs()
+ << "BOLT-INFO: large code model detected (.ltext section found)\n";
+ if (BC->isX86()) {
+ BC->LSDAEncoding = BC->HasFixedLoadAddress
+ ? dwarf::DW_EH_PE_absptr
+ : (dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8);
+ }
+ }
+
HasTextRelocations = (bool)BC->getUniqueSectionByName(
".rela" + std::string(BC->getMainCodeSectionName()));
HasSymbolTable = (bool)BC->getUniqueSectionByName(".symtab");
diff --git a/bolt/test/X86/ltext-lsda-encoding.s b/bolt/test/X86/ltext-lsda-encoding.s
new file mode 100644
index 0000000000000..1636bee69be81
--- /dev/null
+++ b/bolt/test/X86/ltext-lsda-encoding.s
@@ -0,0 +1,38 @@
+## Test that BOLT detects large code model binaries (.ltext sections) and
+## updates the LSDA encoding to use 8-byte pointers for exception handling.
+## Without this, exception tables for functions at addresses above 2GB would
+## use 4-byte encodings that cannot represent the addresses.
+
+# REQUIRES: system-linux
+
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o -o %t.exe --emit-relocs -e _start
+# RUN: llvm-readelf -S %t.exe | FileCheck %s --check-prefix=CHECK-INPUT
+# RUN: llvm-bolt %t.exe -o %t.bolt --reorder-blocks=none 2>&1 \
+# RUN: | FileCheck %s --check-prefix=CHECK-BOLT
+
+## Verify input has .ltext with SHF_X86_64_LARGE.
+# CHECK-INPUT: .ltext {{.*}} AXl
+
+## Verify BOLT detects large code model.
+# CHECK-BOLT: large code model detected (.ltext section found)
+
+ .text
+ .globl _start
+ .type _start, @function
+_start:
+ call large_func
+ xorl %eax, %eax
+ retq
+ .size _start, .-_start
+
+ .section .ltext,"axl", at progbits
+ .globl large_func
+ .type large_func, @function
+large_func:
+ pushq %rbp
+ movq %rsp, %rbp
+ movl $42, %eax
+ popq %rbp
+ retq
+ .size large_func, .-large_func
``````````
</details>
https://github.com/llvm/llvm-project/pull/190685
More information about the llvm-commits
mailing list