Skip to content

Commit c665e49

Browse files
authored
[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.
1 parent 1fb5083 commit c665e49

File tree

1 file changed

+31
-0
lines changed

1 file changed

+31
-0
lines changed

bolt/lib/Rewrite/LinuxKernelRewriter.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,9 @@ class LinuxKernelRewriter final : public MetadataRewriter {
248248
/// Update ORC data in the binary.
249249
Error rewriteORCTables();
250250

251+
/// Validate written ORC tables after binary emission.
252+
Error validateORCTables();
253+
251254
/// Static call table handling.
252255
Error readStaticCalls();
253256
Error rewriteStaticCalls();
@@ -358,6 +361,9 @@ class LinuxKernelRewriter final : public MetadataRewriter {
358361
if (Error E = updateStaticKeysJumpTablePostEmit())
359362
return E;
360363

364+
if (Error E = validateORCTables())
365+
return E;
366+
361367
return Error::success();
362368
}
363369
};
@@ -837,6 +843,31 @@ Error LinuxKernelRewriter::rewriteORCTables() {
837843
return Error::success();
838844
}
839845

846+
Error LinuxKernelRewriter::validateORCTables() {
847+
if (!ORCUnwindIPSection)
848+
return Error::success();
849+
850+
const uint64_t IPSectionAddress = ORCUnwindIPSection->getAddress();
851+
DataExtractor IPDE = DataExtractor(ORCUnwindIPSection->getOutputContents(),
852+
BC.AsmInfo->isLittleEndian(),
853+
BC.AsmInfo->getCodePointerSize());
854+
DataExtractor::Cursor IPCursor(0);
855+
uint64_t PrevIP = 0;
856+
for (uint32_t Index = 0; Index < NumORCEntries; ++Index) {
857+
const uint64_t IP =
858+
IPSectionAddress + IPCursor.tell() + (int32_t)IPDE.getU32(IPCursor);
859+
if (!IPCursor)
860+
return createStringError(errc::executable_format_error,
861+
"out of bounds while reading ORC IP table: %s",
862+
toString(IPCursor.takeError()).c_str());
863+
864+
assert(IP >= PrevIP && "Unsorted ORC table detected");
865+
PrevIP = IP;
866+
}
867+
868+
return Error::success();
869+
}
870+
840871
/// The static call site table is created by objtool and contains entries in the
841872
/// following format:
842873
///

0 commit comments

Comments
 (0)