[llvm] [BOLT] Detect Linux kernel version if the binary is a Linux kernel (PR #119088)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 25 17:14:39 PST 2024
https://github.com/FLZ101 updated https://github.com/llvm/llvm-project/pull/119088
>From 69554a819ef782199d1b25039e484b174a48cdaf Mon Sep 17 00:00:00 2001
From: fengleizZZ <zhangfenglei at huawei.com>
Date: Sun, 8 Dec 2024 02:37:49 +0800
Subject: [PATCH 1/6] [BOLT] Detect Linux kernel version if the binary is a
Linux kernel
This makes it easier to handle differences (e.g. of exception table
entry size) between versions of Linux kernel
---
bolt/include/bolt/Core/BinaryContext.h | 3 +++
bolt/lib/Rewrite/RewriteInstance.cpp | 23 ++++++++++++++++++++
bolt/test/X86/linux-version.s | 30 ++++++++++++++++++++++++++
3 files changed, 56 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..48617dc8ea5946 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,25 @@ 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();
+ }
+ }
+
if (!Section->isText()) {
assert(SymbolType != SymbolRef::ST_Function &&
"unexpected function inside non-code section");
@@ -1205,6 +1225,9 @@ void RewriteInstance::discoverFileObjects() {
PreviousFunction = BF;
}
+ if (BC->IsLinuxKernel && !std::get<0>(BC->LinuxKernelVersion))
+ BC->errs() << "BOLT-WARNING: Linux kernel version is unknown\n";
+
// Read dynamic relocation first as their presence affects the way we process
// static relocations. E.g. we will ignore a static relocation at an address
// that is a subject to dynamic relocation processing.
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
>From 6b931b37b0a0b40828c018f2e095b25d778c4b9d Mon Sep 17 00:00:00 2001
From: fengleizZZ <zhangfenglei at huawei.com>
Date: Mon, 9 Dec 2024 00:27:31 +0800
Subject: [PATCH 2/6] [BOLT] Detect Linux kernel version if the binary is a
Linux kernel
Use struct instead of tuple to represent Linux kernel version
---
bolt/include/bolt/Core/BinaryContext.h | 31 ++++++++++++++++++++++++--
bolt/lib/Rewrite/RewriteInstance.cpp | 4 ++--
bolt/unittests/Core/BinaryContext.cpp | 14 ++++++++++++
3 files changed, 45 insertions(+), 4 deletions(-)
diff --git a/bolt/include/bolt/Core/BinaryContext.h b/bolt/include/bolt/Core/BinaryContext.h
index 052a145efe4a4b..7d49dd003ca02a 100644
--- a/bolt/include/bolt/Core/BinaryContext.h
+++ b/bolt/include/bolt/Core/BinaryContext.h
@@ -180,6 +180,34 @@ struct JournalingStreams {
Error createNonFatalBOLTError(const Twine &S);
Error createFatalBOLTError(const Twine &S);
+/// Linux kernel version
+struct LKVersion {
+ LKVersion() {}
+ LKVersion(unsigned Major, unsigned Minor, unsigned Rev)
+ : Major(Major), Minor(Minor), Rev(Rev) {}
+
+ bool operator<(const LKVersion &Other) const {
+ return std::make_tuple(Major, Minor, Rev) <
+ std::make_tuple(Other.Major, Other.Minor, Other.Rev);
+ }
+
+ bool operator>(const LKVersion &Other) const { return Other < *this; }
+
+ bool operator<=(const LKVersion &Other) const { return !(*this > Other); }
+
+ bool operator>=(const LKVersion &Other) const { return !(*this < Other); }
+
+ bool operator==(const LKVersion &Other) const {
+ return Major == Other.Major && Minor == Other.Minor && Rev == Other.Rev;
+ }
+
+ bool operator!=(const LKVersion &Other) const { return !(*this == Other); }
+
+ unsigned Major{0};
+ unsigned Minor{0};
+ unsigned Rev{0};
+};
+
class BinaryContext {
BinaryContext() = delete;
@@ -670,8 +698,7 @@ class BinaryContext {
/// Indicates if the binary is Linux kernel.
bool IsLinuxKernel{false};
- /// Linux kernel version (major, minor, reversion)
- std::tuple<unsigned, unsigned, unsigned> LinuxKernelVersion;
+ LKVersion 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 48617dc8ea5946..85a753b3cb0554 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -1045,7 +1045,7 @@ void RewriteInstance::discoverFileObjects() {
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->LinuxKernelVersion = LKVersion(Major, Minor, Rev);
BC->outs() << "BOLT-INFO: Linux kernel version is " << Match[1].str();
}
}
@@ -1225,7 +1225,7 @@ void RewriteInstance::discoverFileObjects() {
PreviousFunction = BF;
}
- if (BC->IsLinuxKernel && !std::get<0>(BC->LinuxKernelVersion))
+ if (BC->IsLinuxKernel && !BC->LinuxKernelVersion.Major)
BC->errs() << "BOLT-WARNING: Linux kernel version is unknown\n";
// Read dynamic relocation first as their presence affects the way we process
diff --git a/bolt/unittests/Core/BinaryContext.cpp b/bolt/unittests/Core/BinaryContext.cpp
index 9819a8c2b777b7..d8400d9b18174f 100644
--- a/bolt/unittests/Core/BinaryContext.cpp
+++ b/bolt/unittests/Core/BinaryContext.cpp
@@ -218,3 +218,17 @@ TEST_P(BinaryContextTester, BaseAddressSegmentsSmallerThanAlignment) {
ASSERT_TRUE(BaseAddress.has_value());
ASSERT_EQ(*BaseAddress, 0xaaaaaaaa0000ULL);
}
+
+TEST(BinaryContextTester, LKVersion) {
+ LKVersion V1;
+ LKVersion V2(5, 9, 15);
+ LKVersion V3(6, 12, 1);
+
+ V1 = V3;
+ ASSERT_TRUE(V1 == V3);
+ ASSERT_TRUE(V2 != V3);
+ ASSERT_TRUE(V2 < V3);
+ ASSERT_TRUE(V2 <= V3);
+ ASSERT_TRUE(V3 > V2);
+ ASSERT_TRUE(V3 >= V2);
+}
>From bb683eb25d229aa31a55abe804c784843be1affc Mon Sep 17 00:00:00 2001
From: fengleizZZ <zhangfenglei at huawei.com>
Date: Mon, 9 Dec 2024 23:23:50 +0800
Subject: [PATCH 3/6] [BOLT] Detect Linux kernel version if the binary is a
Linux kernel
Move LinuxKernelVersion to LinuxKernelRewriter
---
bolt/include/bolt/Core/BinaryContext.h | 30 ------------
bolt/include/bolt/Core/BinaryData.h | 5 ++
bolt/lib/Core/BinaryContext.cpp | 1 +
bolt/lib/Rewrite/LinuxKernelRewriter.cpp | 59 ++++++++++++++++++++++++
bolt/lib/Rewrite/RewriteInstance.cpp | 23 ---------
bolt/test/X86/linux-alt-instruction.s | 9 ++++
bolt/test/X86/linux-bug-table.s | 9 ++++
bolt/test/X86/linux-exceptions.s | 9 ++++
bolt/test/X86/linux-orc.s | 9 ++++
bolt/test/X86/linux-parainstructions.s | 9 ++++
bolt/test/X86/linux-pci-fixup.s | 9 ++++
bolt/test/X86/linux-smp-locks.s | 9 ++++
bolt/test/X86/linux-static-calls.s | 9 ++++
bolt/test/X86/linux-static-keys.s | 9 ++++
bolt/test/X86/linux-version.s | 30 ------------
bolt/unittests/Core/BinaryContext.cpp | 14 ------
16 files changed, 146 insertions(+), 97 deletions(-)
delete 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 7d49dd003ca02a..115e59ca0697e5 100644
--- a/bolt/include/bolt/Core/BinaryContext.h
+++ b/bolt/include/bolt/Core/BinaryContext.h
@@ -180,34 +180,6 @@ struct JournalingStreams {
Error createNonFatalBOLTError(const Twine &S);
Error createFatalBOLTError(const Twine &S);
-/// Linux kernel version
-struct LKVersion {
- LKVersion() {}
- LKVersion(unsigned Major, unsigned Minor, unsigned Rev)
- : Major(Major), Minor(Minor), Rev(Rev) {}
-
- bool operator<(const LKVersion &Other) const {
- return std::make_tuple(Major, Minor, Rev) <
- std::make_tuple(Other.Major, Other.Minor, Other.Rev);
- }
-
- bool operator>(const LKVersion &Other) const { return Other < *this; }
-
- bool operator<=(const LKVersion &Other) const { return !(*this > Other); }
-
- bool operator>=(const LKVersion &Other) const { return !(*this < Other); }
-
- bool operator==(const LKVersion &Other) const {
- return Major == Other.Major && Minor == Other.Minor && Rev == Other.Rev;
- }
-
- bool operator!=(const LKVersion &Other) const { return !(*this == Other); }
-
- unsigned Major{0};
- unsigned Minor{0};
- unsigned Rev{0};
-};
-
class BinaryContext {
BinaryContext() = delete;
@@ -698,8 +670,6 @@ class BinaryContext {
/// Indicates if the binary is Linux kernel.
bool IsLinuxKernel{false};
- LKVersion LinuxKernelVersion;
-
/// Indicates if relocations are available for usage.
bool HasRelocations{false};
diff --git a/bolt/include/bolt/Core/BinaryData.h b/bolt/include/bolt/Core/BinaryData.h
index 6a773c4cb70678..4ab628030ff0d2 100644
--- a/bolt/include/bolt/Core/BinaryData.h
+++ b/bolt/include/bolt/Core/BinaryData.h
@@ -169,6 +169,11 @@ class BinaryData {
return Parent && (Parent == BD || Parent->isAncestorOf(BD));
}
+ void updateSize(uint64_t N) {
+ if (N > Size)
+ Size = N;
+ }
+
void setIsMoveable(bool Flag) { IsMoveable = Flag; }
void setSection(BinarySection &NewSection);
void setOutputSection(BinarySection &NewSection) {
diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp
index ac96b836ed5796..8ff8254f1eb140 100644
--- a/bolt/lib/Core/BinaryContext.cpp
+++ b/bolt/lib/Core/BinaryContext.cpp
@@ -1076,6 +1076,7 @@ MCSymbol *BinaryContext::registerNameAtAddress(StringRef Name, uint64_t Address,
BD = GAI->second;
if (!BD->hasName(Name)) {
GlobalSymbols[Name] = BD;
+ BD->updateSize(Size);
BD->Symbols.push_back(Symbol);
}
}
diff --git a/bolt/lib/Rewrite/LinuxKernelRewriter.cpp b/bolt/lib/Rewrite/LinuxKernelRewriter.cpp
index 03b414b71caca7..e233217b9e66fa 100644
--- a/bolt/lib/Rewrite/LinuxKernelRewriter.cpp
+++ b/bolt/lib/Rewrite/LinuxKernelRewriter.cpp
@@ -21,6 +21,8 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Errc.h"
+#include "llvm/Support/ErrorOr.h"
+#include <regex>
#define DEBUG_TYPE "bolt-linux"
@@ -89,6 +91,34 @@ static cl::opt<bool>
} // namespace opts
+/// Linux kernel version
+struct LKVersion {
+ LKVersion() {}
+ LKVersion(unsigned Major, unsigned Minor, unsigned Rev)
+ : Major(Major), Minor(Minor), Rev(Rev) {}
+
+ bool operator<(const LKVersion &Other) const {
+ return std::make_tuple(Major, Minor, Rev) <
+ std::make_tuple(Other.Major, Other.Minor, Other.Rev);
+ }
+
+ bool operator>(const LKVersion &Other) const { return Other < *this; }
+
+ bool operator<=(const LKVersion &Other) const { return !(*this > Other); }
+
+ bool operator>=(const LKVersion &Other) const { return !(*this < Other); }
+
+ bool operator==(const LKVersion &Other) const {
+ return Major == Other.Major && Minor == Other.Minor && Rev == Other.Rev;
+ }
+
+ bool operator!=(const LKVersion &Other) const { return !(*this == Other); }
+
+ unsigned Major{0};
+ unsigned Minor{0};
+ unsigned Rev{0};
+};
+
/// Linux Kernel supports stack unwinding using ORC (oops rewind capability).
/// ORC state at every IP can be described by the following data structure.
struct ORCState {
@@ -124,6 +154,8 @@ inline raw_ostream &operator<<(raw_ostream &OS, const ORCState &E) {
namespace {
class LinuxKernelRewriter final : public MetadataRewriter {
+ LKVersion LinuxKernelVersion;
+
/// Information required for updating metadata referencing an instruction.
struct InstructionFixup {
BinarySection &Section; // Section referencing the instruction.
@@ -225,6 +257,8 @@ class LinuxKernelRewriter final : public MetadataRewriter {
ErrorOr<BinarySection &> PCIFixupSection = std::errc::bad_address;
static constexpr size_t PCI_FIXUP_ENTRY_SIZE = 16;
+ Error detectLinuxKernelVersion();
+
/// Process linux kernel special sections and their relocations.
void processLKSections();
@@ -290,6 +324,9 @@ class LinuxKernelRewriter final : public MetadataRewriter {
: MetadataRewriter("linux-kernel-rewriter", BC) {}
Error preCFGInitializer() override {
+ if (Error E = detectLinuxKernelVersion())
+ return E;
+
processLKSections();
if (Error E = processSMPLocks())
@@ -370,6 +407,28 @@ 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.size() > 5 ? 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");
+}
+
void LinuxKernelRewriter::processLKSections() {
processLKKSymtab();
processLKKSymtab(true);
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 85a753b3cb0554..76e1f0156f828d 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -61,7 +61,6 @@
#include <fstream>
#include <memory>
#include <optional>
-#include <regex>
#include <system_error>
#undef DEBUG_TYPE
@@ -1031,25 +1030,6 @@ 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 = LKVersion(Major, Minor, Rev);
- BC->outs() << "BOLT-INFO: Linux kernel version is " << Match[1].str();
- }
- }
-
if (!Section->isText()) {
assert(SymbolType != SymbolRef::ST_Function &&
"unexpected function inside non-code section");
@@ -1225,9 +1205,6 @@ void RewriteInstance::discoverFileObjects() {
PreviousFunction = BF;
}
- if (BC->IsLinuxKernel && !BC->LinuxKernelVersion.Major)
- BC->errs() << "BOLT-WARNING: Linux kernel version is unknown\n";
-
// Read dynamic relocation first as their presence affects the way we process
// static relocations. E.g. we will ignore a static relocation at an address
// that is a subject to dynamic relocation processing.
diff --git a/bolt/test/X86/linux-alt-instruction.s b/bolt/test/X86/linux-alt-instruction.s
index fe3abbfc2b4c93..83d2cd0634d085 100644
--- a/bolt/test/X86/linux-alt-instruction.s
+++ b/bolt/test/X86/linux-alt-instruction.s
@@ -142,6 +142,15 @@ _start:
.section .orc_unwind_ip
.long .L0 + 2 - .
+## Linux kernel version
+ .rodata
+ .align 16
+ .globl linux_banner
+ .type linux_banner, @object
+linux_banner:
+ .string "Linux version 6.6.61\n"
+ .size linux_banner, . - linux_banner
+
## Fake Linux Kernel sections.
.section __ksymtab,"a", at progbits
.section __ksymtab_gpl,"a", at progbits
diff --git a/bolt/test/X86/linux-bug-table.s b/bolt/test/X86/linux-bug-table.s
index 07a4729ade7374..2965daab2b2656 100644
--- a/bolt/test/X86/linux-bug-table.s
+++ b/bolt/test/X86/linux-bug-table.s
@@ -56,6 +56,15 @@ _start:
.long .L1 - . # instruction
.org 2b + 12
+## Linux kernel version
+ .rodata
+ .align 16
+ .globl linux_banner
+ .type linux_banner, @object
+linux_banner:
+ .string "Linux version 6.6.61\n"
+ .size linux_banner, . - linux_banner
+
## Fake Linux Kernel sections.
.section __ksymtab,"a", at progbits
.section __ksymtab_gpl,"a", at progbits
diff --git a/bolt/test/X86/linux-exceptions.s b/bolt/test/X86/linux-exceptions.s
index 20b8c965f853a9..b0e7641af1cd9c 100644
--- a/bolt/test/X86/linux-exceptions.s
+++ b/bolt/test/X86/linux-exceptions.s
@@ -59,6 +59,15 @@ foo:
.long .LF0 - . # fixup
.long 0 # data
+## Linux kernel version
+ .rodata
+ .align 16
+ .globl linux_banner
+ .type linux_banner, @object
+linux_banner:
+ .string "Linux version 6.6.61\n"
+ .size linux_banner, . - linux_banner
+
## Fake Linux Kernel sections.
.section __ksymtab,"a", at progbits
.section __ksymtab_gpl,"a", at progbits
diff --git a/bolt/test/X86/linux-orc.s b/bolt/test/X86/linux-orc.s
index 1b0e681b1dbf96..133b0df690e623 100644
--- a/bolt/test/X86/linux-orc.s
+++ b/bolt/test/X86/linux-orc.s
@@ -157,6 +157,15 @@ bar:
.section .orc_unwind_ip
.long .L4 - .
+## Linux kernel version
+ .rodata
+ .align 16
+ .globl linux_banner
+ .type linux_banner, @object
+linux_banner:
+ .string "Linux version 6.6.61\n"
+ .size linux_banner, . - linux_banner
+
## Fake Linux Kernel sections.
.section __ksymtab,"a", at progbits
.section __ksymtab_gpl,"a", at progbits
diff --git a/bolt/test/X86/linux-parainstructions.s b/bolt/test/X86/linux-parainstructions.s
index 07fca6bbedafab..facfcb168b1662 100644
--- a/bolt/test/X86/linux-parainstructions.s
+++ b/bolt/test/X86/linux-parainstructions.s
@@ -49,6 +49,15 @@ _start:
.byte 1 # type
.byte 7 # length
+## Linux kernel version
+ .rodata
+ .align 16
+ .globl linux_banner
+ .type linux_banner, @object
+linux_banner:
+ .string "Linux version 6.6.61\n"
+ .size linux_banner, . - linux_banner
+
## Fake Linux Kernel sections.
.section __ksymtab,"a", at progbits
.section __ksymtab_gpl,"a", at progbits
diff --git a/bolt/test/X86/linux-pci-fixup.s b/bolt/test/X86/linux-pci-fixup.s
index 42504c108d339c..d8df91a4e9bcd1 100644
--- a/bolt/test/X86/linux-pci-fixup.s
+++ b/bolt/test/X86/linux-pci-fixup.s
@@ -36,6 +36,15 @@ _start:
.long 0x0 # class shift
.long .L0 - . # fixup
+## Linux kernel version
+ .rodata
+ .align 16
+ .globl linux_banner
+ .type linux_banner, @object
+linux_banner:
+ .string "Linux version 6.6.61\n"
+ .size linux_banner, . - linux_banner
+
## Fake Linux Kernel sections.
.section __ksymtab,"a", at progbits
.section __ksymtab_gpl,"a", at progbits
diff --git a/bolt/test/X86/linux-smp-locks.s b/bolt/test/X86/linux-smp-locks.s
index 50d9e632b11720..2fc136fd78cda5 100644
--- a/bolt/test/X86/linux-smp-locks.s
+++ b/bolt/test/X86/linux-smp-locks.s
@@ -35,6 +35,15 @@ _start:
.long .L0 - .
.long .L1 - .
+## Linux kernel version
+ .rodata
+ .align 16
+ .globl linux_banner
+ .type linux_banner, @object
+linux_banner:
+ .string "Linux version 6.6.61\n"
+ .size linux_banner, . - linux_banner
+
## Fake Linux Kernel sections.
.section __ksymtab,"a", at progbits
.section __ksymtab_gpl,"a", at progbits
diff --git a/bolt/test/X86/linux-static-calls.s b/bolt/test/X86/linux-static-calls.s
index ce90f4bb79c094..758e1395d88462 100644
--- a/bolt/test/X86/linux-static-calls.s
+++ b/bolt/test/X86/linux-static-calls.s
@@ -54,6 +54,15 @@ __start_static_call_sites:
.type __stop_static_call_sites, %object
__stop_static_call_sites:
+## Linux kernel version
+ .rodata
+ .align 16
+ .globl linux_banner
+ .type linux_banner, @object
+linux_banner:
+ .string "Linux version 6.6.61\n"
+ .size linux_banner, . - linux_banner
+
## Fake Linux Kernel sections.
.section __ksymtab,"a", at progbits
.section __ksymtab_gpl,"a", at progbits
diff --git a/bolt/test/X86/linux-static-keys.s b/bolt/test/X86/linux-static-keys.s
index 0bd17a375d8824..d3ca74c1ec2518 100644
--- a/bolt/test/X86/linux-static-keys.s
+++ b/bolt/test/X86/linux-static-keys.s
@@ -79,6 +79,15 @@ __start___jump_table:
.type __stop___jump_table, %object
__stop___jump_table:
+## Linux kernel version
+ .rodata
+ .align 16
+ .globl linux_banner
+ .type linux_banner, @object
+linux_banner:
+ .string "Linux version 6.6.61\n"
+ .size linux_banner, . - linux_banner
+
## Fake Linux Kernel sections.
.section __ksymtab,"a", at progbits
.section __ksymtab_gpl,"a", at progbits
diff --git a/bolt/test/X86/linux-version.s b/bolt/test/X86/linux-version.s
deleted file mode 100644
index 079910be931cdb..00000000000000
--- a/bolt/test/X86/linux-version.s
+++ /dev/null
@@ -1,30 +0,0 @@
-# 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
diff --git a/bolt/unittests/Core/BinaryContext.cpp b/bolt/unittests/Core/BinaryContext.cpp
index d8400d9b18174f..9819a8c2b777b7 100644
--- a/bolt/unittests/Core/BinaryContext.cpp
+++ b/bolt/unittests/Core/BinaryContext.cpp
@@ -218,17 +218,3 @@ TEST_P(BinaryContextTester, BaseAddressSegmentsSmallerThanAlignment) {
ASSERT_TRUE(BaseAddress.has_value());
ASSERT_EQ(*BaseAddress, 0xaaaaaaaa0000ULL);
}
-
-TEST(BinaryContextTester, LKVersion) {
- LKVersion V1;
- LKVersion V2(5, 9, 15);
- LKVersion V3(6, 12, 1);
-
- V1 = V3;
- ASSERT_TRUE(V1 == V3);
- ASSERT_TRUE(V2 != V3);
- ASSERT_TRUE(V2 < V3);
- ASSERT_TRUE(V2 <= V3);
- ASSERT_TRUE(V3 > V2);
- ASSERT_TRUE(V3 >= V2);
-}
>From 2268ec6dcf7bbaba9075a4b07fa06393d664502f Mon Sep 17 00:00:00 2001
From: fengleizZZ <zhangfenglei at huawei.com>
Date: Sat, 14 Dec 2024 00:10:20 +0800
Subject: [PATCH 4/6] [BOLT] Detect Linux kernel version if the binary is a
Linux kernel
Add tests
---
bolt/lib/Rewrite/LinuxKernelRewriter.cpp | 2 +-
bolt/test/X86/linux-version.S | 54 ++++++++++++++++++++++++
2 files changed, 55 insertions(+), 1 deletion(-)
create mode 100644 bolt/test/X86/linux-version.S
diff --git a/bolt/lib/Rewrite/LinuxKernelRewriter.cpp b/bolt/lib/Rewrite/LinuxKernelRewriter.cpp
index e233217b9e66fa..aeb82ef3558d68 100644
--- a/bolt/lib/Rewrite/LinuxKernelRewriter.cpp
+++ b/bolt/lib/Rewrite/LinuxKernelRewriter.cpp
@@ -418,7 +418,7 @@ Error LinuxKernelRewriter::detectLinuxKernelVersion() {
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.size() > 5 ? std::stoi(Match[5].str()) : 0;
+ 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";
diff --git a/bolt/test/X86/linux-version.S b/bolt/test/X86/linux-version.S
new file mode 100644
index 00000000000000..d1d8c3f2b73f13
--- /dev/null
+++ b/bolt/test/X86/linux-version.S
@@ -0,0 +1,54 @@
+# REQUIRES: system-linux
+
+## Check that BOLT correctly detects the Linux kernel version
+
+# RUN: %clang -DA -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-A %s
+
+# CHECK-A: BOLT-INFO: Linux kernel version is 6.6.61
+
+# RUN: %clang -DB -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-B %s
+
+# CHECK-B: BOLT-INFO: Linux kernel version is 6.6.50
+
+# RUN: %clang -DC -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-C %s
+
+# CHECK-C: BOLT-INFO: Linux kernel version is 6.6
+
+ .text
+ .globl foo
+ .type foo, %function
+foo:
+ ret
+ .size foo, .-foo
+
+## Linux kernel version
+ .rodata
+ .align 16
+ .globl linux_banner
+ .type linux_banner, @object
+linux_banner:
+
+#ifdef A
+ .string "Linux version 6.6.61\n"
+#endif
+#ifdef B
+ .string "Linux version 6.6.50-rc4\n"
+#endif
+#ifdef C
+ .string "Linux version 6.6\n"
+#endif
+
+ .size linux_banner, . - linux_banner
+
+## Fake Linux Kernel sections.
+ .section __ksymtab,"a", at progbits
+ .section __ksymtab_gpl,"a", at progbits
>From e932882c98bd73e37f8409cd2878bf379f39904d Mon Sep 17 00:00:00 2001
From: Franklin <zhangfenglei at huawei.com>
Date: Sat, 14 Dec 2024 12:14:31 +0800
Subject: [PATCH 5/6] [BOLT] Detect Linux kernel version if the binary is a
Linux kernel
Fix linux-version.S
---
bolt/test/X86/linux-version.S | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/bolt/test/X86/linux-version.S b/bolt/test/X86/linux-version.S
index d1d8c3f2b73f13..9a0b5c7f11c0ce 100644
--- a/bolt/test/X86/linux-version.S
+++ b/bolt/test/X86/linux-version.S
@@ -4,21 +4,21 @@
# RUN: %clang -DA -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: -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-A %s
# CHECK-A: BOLT-INFO: Linux kernel version is 6.6.61
# RUN: %clang -DB -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: -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-B %s
# CHECK-B: BOLT-INFO: Linux kernel version is 6.6.50
# RUN: %clang -DC -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: -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
# CHECK-C: BOLT-INFO: Linux kernel version is 6.6
>From 035668eafad278ea50700efa16e6daca6700300a Mon Sep 17 00:00:00 2001
From: Franklin <zhangfenglei at huawei.com>
Date: Tue, 17 Dec 2024 14:28:33 +0800
Subject: [PATCH 6/6] [BOLT] Detect Linux kernel version if the binary is a
Linux kernel
---
bolt/test/X86/linux-version.S | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/bolt/test/X86/linux-version.S b/bolt/test/X86/linux-version.S
index 9a0b5c7f11c0ce..e680d0d64a21f9 100644
--- a/bolt/test/X86/linux-version.S
+++ b/bolt/test/X86/linux-version.S
@@ -7,22 +7,16 @@
# 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-A %s
-# CHECK-A: BOLT-INFO: Linux kernel version is 6.6.61
-
# RUN: %clang -DB -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-B %s
-# CHECK-B: BOLT-INFO: Linux kernel version is 6.6.50
-
# RUN: %clang -DC -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-C %s
-# CHECK-C: BOLT-INFO: Linux kernel version is 6.6
-
.text
.globl foo
.type foo, %function
@@ -40,12 +34,17 @@ linux_banner:
#ifdef A
.string "Linux version 6.6.61\n"
#endif
+# CHECK-A: BOLT-INFO: Linux kernel version is 6.6.61
+
#ifdef B
.string "Linux version 6.6.50-rc4\n"
#endif
+# CHECK-B: BOLT-INFO: Linux kernel version is 6.6.50
+
#ifdef C
.string "Linux version 6.6\n"
#endif
+# CHECK-C: BOLT-INFO: Linux kernel version is 6.6
.size linux_banner, . - linux_banner
More information about the llvm-commits
mailing list