[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