[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