[BOLT][Linux] Fix linux_banner lookup (#144962)
While detecting the Linux kernel version, look for `linux_banner` symbol with local visibility if the global one was not found. Fixes #144847
This commit is contained in:
parent
69974658f0
commit
b8d3efa189
@ -432,25 +432,33 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
Error LinuxKernelRewriter::detectLinuxKernelVersion() {
|
Error LinuxKernelRewriter::detectLinuxKernelVersion() {
|
||||||
if (BinaryData *BD = BC.getBinaryDataByName("linux_banner")) {
|
// Check for global and local linux_banner symbol.
|
||||||
const BinarySection &Section = BD->getSection();
|
BinaryData *BD = BC.getBinaryDataByName("linux_banner");
|
||||||
const std::string S =
|
if (!BD)
|
||||||
Section.getContents().substr(BD->getOffset(), BD->getSize()).str();
|
BD = BC.getBinaryDataByName("linux_banner/1");
|
||||||
|
|
||||||
const std::regex Re(R"---(Linux version ((\d+)\.(\d+)(\.(\d+))?))---");
|
if (!BD)
|
||||||
std::smatch Match;
|
return createStringError(errc::executable_format_error,
|
||||||
if (std::regex_search(S, Match, Re)) {
|
"unable to locate linux_banner");
|
||||||
const unsigned Major = std::stoi(Match[2].str());
|
|
||||||
const unsigned Minor = std::stoi(Match[3].str());
|
const BinarySection &Section = BD->getSection();
|
||||||
const unsigned Rev = Match[5].matched ? std::stoi(Match[5].str()) : 0;
|
const std::string S =
|
||||||
LinuxKernelVersion = LKVersion(Major, Minor, Rev);
|
Section.getContents().substr(BD->getOffset(), BD->getSize()).str();
|
||||||
BC.outs() << "BOLT-INFO: Linux kernel version is " << Match[1].str()
|
|
||||||
<< "\n";
|
const std::regex Re(R"---(Linux version ((\d+)\.(\d+)(\.(\d+))?))---");
|
||||||
return Error::success();
|
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,
|
return createStringError(errc::executable_format_error,
|
||||||
"Linux kernel version is unknown");
|
"Linux kernel version is unknown: " + S);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinuxKernelRewriter::processLKSections() {
|
void LinuxKernelRewriter::processLKSections() {
|
||||||
|
@ -17,6 +17,11 @@
|
|||||||
# 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
|
# 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
|
.text
|
||||||
.globl foo
|
.globl foo
|
||||||
.type foo, %function
|
.type foo, %function
|
||||||
@ -46,6 +51,12 @@ linux_banner:
|
|||||||
#endif
|
#endif
|
||||||
# CHECK-C: BOLT-INFO: Linux kernel version is 6.6
|
# 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
|
.size linux_banner, . - linux_banner
|
||||||
|
|
||||||
## Fake Linux Kernel sections.
|
## Fake Linux Kernel sections.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user