Skip to content

[BOLT][Linux] Fix linux_banner lookup #144962

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 20, 2025
Merged

[BOLT][Linux] Fix linux_banner lookup #144962

merged 1 commit into from
Jun 20, 2025

Conversation

maksfb
Copy link
Contributor

@maksfb maksfb commented Jun 19, 2025

While detecting the Linux kernel version, look for linux_banner symbol with local visibility if the global one was not found.

Fixes #144847

While detecting the Linux kernel version, look for `linux_banner`
symbol with local visibility if the global one was not found.

Fixes llvm#144847
@llvmbot
Copy link
Member

llvmbot commented Jun 19, 2025

@llvm/pr-subscribers-bolt

Author: Maksim Panchenko (maksfb)

Changes

While detecting the Linux kernel version, look for linux_banner symbol with local visibility if the global one was not found.

Fixes #144847


Full diff: https://github.com/llvm/llvm-project/pull/144962.diff

2 Files Affected:

  • (modified) bolt/lib/Rewrite/LinuxKernelRewriter.cpp (+25-17)
  • (modified) bolt/test/X86/linux-version.S (+11)
diff --git a/bolt/lib/Rewrite/LinuxKernelRewriter.cpp b/bolt/lib/Rewrite/LinuxKernelRewriter.cpp
index 5a5e044184d0b..174721a3a0539 100644
--- a/bolt/lib/Rewrite/LinuxKernelRewriter.cpp
+++ b/bolt/lib/Rewrite/LinuxKernelRewriter.cpp
@@ -432,25 +432,33 @@ class LinuxKernelRewriter final : public MetadataRewriter {
 };
 
 Error LinuxKernelRewriter::detectLinuxKernelVersion() {
-  if (BinaryData *BD = BC.getBinaryDataByName("linux_banner")) {
-    const BinarySection &Section = BD->getSection();
-    const std::string S =
-        Section.getContents().substr(BD->getOffset(), BD->getSize()).str();
-
-    const std::regex Re(R"---(Linux version ((\d+)\.(\d+)(\.(\d+))?))---");
-    std::smatch Match;
-    if (std::regex_search(S, Match, Re)) {
-      const unsigned Major = std::stoi(Match[2].str());
-      const unsigned Minor = std::stoi(Match[3].str());
-      const unsigned Rev = Match[5].matched ? std::stoi(Match[5].str()) : 0;
-      LinuxKernelVersion = LKVersion(Major, Minor, Rev);
-      BC.outs() << "BOLT-INFO: Linux kernel version is " << Match[1].str()
-                << "\n";
-      return Error::success();
-    }
+  // Check for global and local linux_banner symbol.
+  BinaryData *BD = BC.getBinaryDataByName("linux_banner");
+  if (!BD)
+    BD = BC.getBinaryDataByName("linux_banner/1");
+
+  if (!BD)
+    return createStringError(errc::executable_format_error,
+                             "unable to locate linux_banner");
+
+  const BinarySection &Section = BD->getSection();
+  const std::string S =
+      Section.getContents().substr(BD->getOffset(), BD->getSize()).str();
+
+  const std::regex Re(R"---(Linux version ((\d+)\.(\d+)(\.(\d+))?))---");
+  std::smatch Match;
+  if (std::regex_search(S, Match, Re)) {
+    const unsigned Major = std::stoi(Match[2].str());
+    const unsigned Minor = std::stoi(Match[3].str());
+    const unsigned Rev = Match[5].matched ? std::stoi(Match[5].str()) : 0;
+    LinuxKernelVersion = LKVersion(Major, Minor, Rev);
+    BC.outs() << "BOLT-INFO: Linux kernel version is " << Match[1].str()
+              << "\n";
+    return Error::success();
   }
+
   return createStringError(errc::executable_format_error,
-                           "Linux kernel version is unknown");
+                           "Linux kernel version is unknown: " + S);
 }
 
 void LinuxKernelRewriter::processLKSections() {
diff --git a/bolt/test/X86/linux-version.S b/bolt/test/X86/linux-version.S
index e680d0d64a21f..a3d7f365304aa 100644
--- a/bolt/test/X86/linux-version.S
+++ b/bolt/test/X86/linux-version.S
@@ -17,6 +17,11 @@
 # RUN:   -Wl,--image-base=0xffffffff80000000,--no-dynamic-linker,--no-eh-frame-hdr
 # RUN: llvm-bolt %t.exe -o %t.out 2>&1 | FileCheck --check-prefix=CHECK-C %s
 
+# RUN: %clang -DD -target x86_64-unknown-unknown \
+# RUN:   %cflags -nostdlib %s -o %t.exe \
+# RUN:   -Wl,--image-base=0xffffffff80000000,--no-dynamic-linker,--no-eh-frame-hdr
+# RUN: llvm-bolt %t.exe -o %t.out 2>&1 | FileCheck --check-prefix=CHECK-D %s
+
   .text
   .globl foo
   .type foo, %function
@@ -46,6 +51,12 @@ linux_banner:
 #endif
 # CHECK-C: BOLT-INFO: Linux kernel version is 6.6
 
+#ifdef D
+  .hidden linux_banner
+  .string  "Linux version 6.6.15.2-2-xxx\n"
+#endif
+# CHECK-D: BOLT-INFO: Linux kernel version is 6.6
+
   .size  linux_banner, . - linux_banner
 
 ## Fake Linux Kernel sections.

@maksfb maksfb merged commit b8d3efa into llvm:main Jun 20, 2025
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Linux kernel version is unknown
3 participants