mirror of
https://github.com/intel/llvm.git
synced 2026-01-21 20:53:29 +08:00
[BOLT] Add ORC validation for the Linux kernel (#90660)
The Linux kernel expects ORC tables to be sorted by IP address (for binary search to work). Add a post-emit pass in LinuxKernelRewriter that validates the written .orc_unwind_ip against that expectation.
This commit is contained in:
@@ -248,6 +248,9 @@ class LinuxKernelRewriter final : public MetadataRewriter {
|
||||
/// Update ORC data in the binary.
|
||||
Error rewriteORCTables();
|
||||
|
||||
/// Validate written ORC tables after binary emission.
|
||||
Error validateORCTables();
|
||||
|
||||
/// Static call table handling.
|
||||
Error readStaticCalls();
|
||||
Error rewriteStaticCalls();
|
||||
@@ -358,6 +361,9 @@ public:
|
||||
if (Error E = updateStaticKeysJumpTablePostEmit())
|
||||
return E;
|
||||
|
||||
if (Error E = validateORCTables())
|
||||
return E;
|
||||
|
||||
return Error::success();
|
||||
}
|
||||
};
|
||||
@@ -837,6 +843,31 @@ Error LinuxKernelRewriter::rewriteORCTables() {
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error LinuxKernelRewriter::validateORCTables() {
|
||||
if (!ORCUnwindIPSection)
|
||||
return Error::success();
|
||||
|
||||
const uint64_t IPSectionAddress = ORCUnwindIPSection->getAddress();
|
||||
DataExtractor IPDE = DataExtractor(ORCUnwindIPSection->getOutputContents(),
|
||||
BC.AsmInfo->isLittleEndian(),
|
||||
BC.AsmInfo->getCodePointerSize());
|
||||
DataExtractor::Cursor IPCursor(0);
|
||||
uint64_t PrevIP = 0;
|
||||
for (uint32_t Index = 0; Index < NumORCEntries; ++Index) {
|
||||
const uint64_t IP =
|
||||
IPSectionAddress + IPCursor.tell() + (int32_t)IPDE.getU32(IPCursor);
|
||||
if (!IPCursor)
|
||||
return createStringError(errc::executable_format_error,
|
||||
"out of bounds while reading ORC IP table: %s",
|
||||
toString(IPCursor.takeError()).c_str());
|
||||
|
||||
assert(IP >= PrevIP && "Unsorted ORC table detected");
|
||||
PrevIP = IP;
|
||||
}
|
||||
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
/// The static call site table is created by objtool and contains entries in the
|
||||
/// following format:
|
||||
///
|
||||
|
||||
Reference in New Issue
Block a user