[llvm] [Draft][BOLT] fix hugify for old kernels (#201813) (PR #201818)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 8 07:55:59 PDT 2026


https://github.com/DmitriiMartynov updated https://github.com/llvm/llvm-project/pull/201818

>From 4b84bba05862fe239ab03c6f25641aa9a2621446 Mon Sep 17 00:00:00 2001
From: Dmitrii Martynov <martynovdmitryvladimirovich at yandex.ru>
Date: Fri, 5 Jun 2026 13:03:50 +0300
Subject: [PATCH] [BOLT] fix hugify for old kernels (#201813)

The PIE binary optimized with hugify option might crash on pre-5.10
kernels due to unexpected segment alignment.
---
 bolt/lib/Passes/LongJmp.cpp          |  4 ++--
 bolt/lib/Rewrite/RewriteInstance.cpp |  2 +-
 bolt/test/runtime/hugify.c           | 12 ++++++++++++
 3 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/bolt/lib/Passes/LongJmp.cpp b/bolt/lib/Passes/LongJmp.cpp
index f085500fccbd3..8b3360049361e 100644
--- a/bolt/lib/Passes/LongJmp.cpp
+++ b/bolt/lib/Passes/LongJmp.cpp
@@ -367,11 +367,11 @@ LongJmpPass::tentativeLayoutRelocMode(const BinaryContext &BC,
   CurrentIndex = 0;
   bool ColdLayoutDone = false;
   auto runColdLayout = [&]() {
-    // Mirror the extra hugify alignment inserted by final section allocation
+    // Mirror the extra hugify page inserted by final section allocation
     // after the last non-cold section. Account for it before assigning cold
     // fragment addresses so range checks see the hot-to-cold gap.
     if (opts::Hugify && !BC.HasFixedLoadAddress && !opts::HotFunctionsAtEnd)
-      DotAddress = alignTo(DotAddress, opts::AlignText);
+      DotAddress += BC.PageAlign;
     DotAddress = tentativeLayoutRelocColdPart(BC, SortedFunctions, DotAddress);
     ColdLayoutDone = true;
     if (opts::HotFunctionsAtEnd)
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 9364e32939982..4c08836e36f13 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -4253,7 +4253,7 @@ void RewriteInstance::mapCodeSections(BOLTLinker::SectionMapper MapSection) {
       // weird ASLR mapping addresses (4KB aligned)
       if (opts::Hugify && !BC->HasFixedLoadAddress &&
           Section->getName() == LastNonColdSectionName)
-        Address = alignTo(Address, Section->getAlignment());
+        Address += BC->PageAlign;
     }
 
     // Make sure we allocate enough space for huge pages.
diff --git a/bolt/test/runtime/hugify.c b/bolt/test/runtime/hugify.c
index a4a718a1160df..acfe4dda63e5b 100644
--- a/bolt/test/runtime/hugify.c
+++ b/bolt/test/runtime/hugify.c
@@ -2,6 +2,18 @@
 
 #include <stdio.h>
 
+// The dummy var is used for testing the hugify feature on pre-5.10 kernels,
+// which do not include the patch "fs/binfmt_elf: use PT_LOAD p_align values for
+// suitable start address".
+// The code size of the hugify test with the dummy var is about 2 MB. This
+// allows testing a corner case where the left (rounded down) and right (rounded
+// up) boundaries are located in different hugepages when the segment is mapped
+// with page alignment instead of the expected segment alignment. It is expected
+// that the hugified binary (PIE only) doesn't crash with a segfault, even in
+// the case of unexpected segment alignment, on pre-5.10 kernels.
+const char dummy_const_var_in_text[2 * 1024 * 1024 - 0x1000]
+    __attribute__((section(".text")));
+
 int main(int argc, char **argv) {
   printf("Hello world\n");
   return 0;



More information about the llvm-commits mailing list