[llvm] [BOLT] Add support for Linux kernel static calls table (PR #82072)

Maksim Panchenko via llvm-commits llvm-commits at lists.llvm.org
Sun Feb 18 17:17:46 PST 2024


================
@@ -793,6 +821,133 @@ Error LinuxKernelRewriter::rewriteORCTables() {
   return Error::success();
 }
 
+/// The static call site table is created by objtool and contains entries in the
+/// following format:
+///
+///    struct static_call_site {
+///      s32 addr;
+///      s32 key;
+///    };
+///
+Error LinuxKernelRewriter::readStaticCalls() {
+  const BinaryData *StaticCallTable =
+      BC.getBinaryDataByName("__start_static_call_sites");
+  if (!StaticCallTable)
+    return Error::success();
+
+  StaticCallTableAddress = StaticCallTable->getAddress();
+
+  const BinaryData *Stop = BC.getBinaryDataByName("__stop_static_call_sites");
+  if (!Stop)
+    return createStringError(errc::executable_format_error,
+                             "missing __stop_static_call_sites symbol");
+
+  ErrorOr<BinarySection &> ErrorOrSection =
+      BC.getSectionForAddress(StaticCallTableAddress);
+  if (!ErrorOrSection)
+    return createStringError(errc::executable_format_error,
+                             "no section matching __start_static_call_sites");
+
+  StaticCallSection = *ErrorOrSection;
+  if (!StaticCallSection->containsAddress(Stop->getAddress() - 1))
+    return createStringError(errc::executable_format_error,
+                             "__stop_static_call_sites not in the same section "
+                             "as __start_static_call_sites");
+
+  if ((Stop->getAddress() - StaticCallTableAddress) % STATIC_CALL_ENTRY_SIZE)
+    return createStringError(errc::executable_format_error,
+                             "static call table size error");
+
+  const uint64_t SectionAddress = StaticCallSection->getAddress();
+  DataExtractor DE(StaticCallSection->getContents(),
+                   BC.AsmInfo->isLittleEndian(),
+                   BC.AsmInfo->getCodePointerSize());
+  DataExtractor::Cursor Cursor(StaticCallTableAddress - SectionAddress);
+  uint32_t EntryID = 0;
+  while (Cursor && Cursor.tell() < Stop->getAddress() - SectionAddress) {
+    const uint64_t CallAddress =
+        SectionAddress + Cursor.tell() + (int32_t)DE.getU32(Cursor);
+    const uint64_t KeyAddress =
+        SectionAddress + Cursor.tell() + (int32_t)DE.getU32(Cursor);
+
+    // Consume the status of the cursor.
+    if (!Cursor)
+      return createStringError(errc::executable_format_error,
+                               "out of bounds while reading static calls");
+
+    ++EntryID;
+
+    if (opts::DumpStaticCalls) {
+      outs() << "Static Call Site: " << EntryID << '\n';
----------------
maksfb wrote:

`LinuxKernelRewriter` was not included in #81524. Will make the switch in a separate PR.

https://github.com/llvm/llvm-project/pull/82072


More information about the llvm-commits mailing list