[llvm] [BOLT] Add reading support for Linux kernel exception table (PR #83100)
Maksim Panchenko via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 27 18:58:57 PST 2024
================
@@ -949,6 +906,119 @@ Error LinuxKernelRewriter::rewriteStaticCalls() {
return Error::success();
}
+/// Instructions that access user-space memory can cause page faults. These
+/// faults will be handled by the kernel and execution will resume at the fixup
+/// code location if the address was invalid. The kernel uses the exception
+/// table to match the faulting instruction to its fixup. The table consists of
+/// the following entries:
+///
+/// struct exception_table_entry {
+/// int insn;
+/// int fixup;
+/// int data;
+/// };
+///
+/// More info at:
+/// https://www.kernel.org/doc/Documentation/x86/exception-tables.txt
+Error LinuxKernelRewriter::readExceptionTable() {
+ ExceptionsSection = BC.getUniqueSectionByName("__ex_table");
+ if (!ExceptionsSection)
+ return Error::success();
+
+ if (ExceptionsSection->getSize() % EXCEPTION_TABLE_ENTRY_SIZE)
+ return createStringError(errc::executable_format_error,
+ "exception table size error");
+
+ const uint64_t SectionAddress = ExceptionsSection->getAddress();
+ DataExtractor DE(ExceptionsSection->getContents(),
+ BC.AsmInfo->isLittleEndian(),
+ BC.AsmInfo->getCodePointerSize());
+ DataExtractor::Cursor Cursor(0);
+ uint32_t EntryID = 0;
+ while (Cursor && Cursor.tell() < ExceptionsSection->getSize()) {
+ const uint64_t InstAddress =
+ SectionAddress + Cursor.tell() + (int32_t)DE.getU32(Cursor);
----------------
maksfb wrote:
I assume you are talking about the `int` in the Linux kernel structure. We support x86 kernels only (at least at this moment) and the data structure itself is architecture-specific. So it's not just the type of the field that can vary. Some architectures don't have exception table at all, others have different fields in the structure.
https://github.com/llvm/llvm-project/pull/83100
More information about the llvm-commits
mailing list