[llvm] [BOLT] Detect Linux kernel version if the binary is a Linux kernel (PR #119088)

via llvm-commits llvm-commits at lists.llvm.org
Sat Dec 7 11:01:29 PST 2024


https://github.com/FLZ101 created https://github.com/llvm/llvm-project/pull/119088

None

>From 62a0b09d30e3c80df068eeb72ac5f1134e1a403d Mon Sep 17 00:00:00 2001
From: fengleizZZ <zhangfenglei at huawei.com>
Date: Sun, 8 Dec 2024 02:37:49 +0800
Subject: [PATCH] [BOLT] Detect Linux kernel version if the binary is a Linux
 kernel

---
 bolt/include/bolt/Core/BinaryContext.h |  3 +++
 bolt/lib/Rewrite/RewriteInstance.cpp   | 22 +++++++++++++++++++
 bolt/test/X86/linux-version.s          | 30 ++++++++++++++++++++++++++
 3 files changed, 55 insertions(+)
 create mode 100644 bolt/test/X86/linux-version.s

diff --git a/bolt/include/bolt/Core/BinaryContext.h b/bolt/include/bolt/Core/BinaryContext.h
index 115e59ca0697e5..052a145efe4a4b 100644
--- a/bolt/include/bolt/Core/BinaryContext.h
+++ b/bolt/include/bolt/Core/BinaryContext.h
@@ -670,6 +670,9 @@ class BinaryContext {
   /// Indicates if the binary is Linux kernel.
   bool IsLinuxKernel{false};
 
+  /// Linux kernel version (major, minor, reversion)
+  std::tuple<unsigned, unsigned, unsigned> LinuxKernelVersion;
+
   /// Indicates if relocations are available for usage.
   bool HasRelocations{false};
 
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 76e1f0156f828d..b88da11701b354 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -61,6 +61,7 @@
 #include <fstream>
 #include <memory>
 #include <optional>
+#include <regex>
 #include <system_error>
 
 #undef  DEBUG_TYPE
@@ -1030,6 +1031,27 @@ void RewriteInstance::discoverFileObjects() {
       continue;
     }
 
+    if (BC->IsLinuxKernel && SymName == "linux_banner") {
+      const StringRef SectionContents =
+          cantFail(Section->getContents(), "can not get section contents");
+      const std::string S =
+          SectionContents
+              .substr(SymbolAddress - Section->getAddress(), SymbolSize)
+              .str();
+
+      const std::regex Re(R"---(Linux version ((\d+)\.(\d+)(\.(\d+))?))---");
+      std::smatch Match;
+      if (std::regex_search(S, Match, Re)) {
+        unsigned Major = std::stoi(Match[2].str());
+        unsigned Minor = std::stoi(Match[3].str());
+        unsigned Rev = Match.size() > 5 ? std::stoi(Match[5].str()) : 0;
+        BC->LinuxKernelVersion = std::make_tuple(Major, Minor, Rev);
+        BC->outs() << "BOLT-INFO: Linux kernel version is " << Match[1].str();
+      } else {
+        BC->errs() << "BOLT-WARNING: Linux kernel version is unknown\n";
+      }
+    }
+
     if (!Section->isText()) {
       assert(SymbolType != SymbolRef::ST_Function &&
              "unexpected function inside non-code section");
diff --git a/bolt/test/X86/linux-version.s b/bolt/test/X86/linux-version.s
new file mode 100644
index 00000000000000..079910be931cdb
--- /dev/null
+++ b/bolt/test/X86/linux-version.s
@@ -0,0 +1,30 @@
+# REQUIRES: system-linux
+
+## Check that BOLT correctly detects the Linux kernel version
+
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o
+# RUN: %clang %cflags -nostdlib %t.o -o %t.exe \
+# RUN:   -Wl,--image-base=0xffffffff80000000,--no-dynamic-linker,--no-eh-frame-hdr
+
+# RUN: llvm-bolt %t.exe -o %t.out | FileCheck %s
+
+# CHECK: BOLT-INFO: Linux kernel version is 6.6.61
+
+	.text
+	.globl	f
+	.type	f, @function
+f:
+	ret
+	.size	f, .-f
+
+	.globl	linux_banner
+	.section	.rodata
+	.align 16
+	.type	linux_banner, @object
+	.size	linux_banner, 22
+linux_banner:
+	.string	"Linux version 6.6.61\n"
+
+## Fake Linux Kernel sections.
+  .section __ksymtab,"a", at progbits
+  .section __ksymtab_gpl,"a", at progbits



More information about the llvm-commits mailing list