[compiler-rt] [llvm] [LowerTypeTests] Add debug info to jump table entries (PR #194493)

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 28 17:09:35 PDT 2026


================
@@ -1523,25 +1524,87 @@ Triple::ArchType LowerTypeTestsModule::selectJumpTableArmEncoding(
   return ArmCount > ThumbCount ? Triple::arm : Triple::thumb;
 }
 
+// Create location for each function entry which should look like this:
+// frame #0: c::c() (.cfi_jt) at sanitizer/ubsan_interface.h:0:0
+// frame #1: __ubsan_check_cfi_icall_jt at sanitizer/ubsan_interface.h:0
+// frame #2: .cfi.jumptable.81 at sanitizer/ubsan_interface.h:0:0
+static SmallVector<DILocation *>
+createJumpTableDebugInfo(Function *F, ArrayRef<GlobalTypeMember *> Functions) {
+  Module &M = *F->getParent();
+  DICompileUnit *CU = nullptr;
+  auto CUs = M.debug_compile_units();
+  if (!CUs.empty())
+    CU = *CUs.begin();
+
+  DIBuilder DIB(M, /*AllowUnresolved=*/true, CU);
+  DIFile *File = DIB.createFile("ubsan_interface.h", "sanitizer");
+  if (!CU) {
+    // Even with debug info enabled it can be missing if not info yet.
+    CU = DIB.createCompileUnit(
+        DISourceLanguageName(dwarf::DW_LANG_C), File, "llvm", true, "", 0, "",
+        DICompileUnit::DebugEmissionKind::LineTablesOnly);
+  }
+
+  DISubroutineType *DIFnTy = DIB.createSubroutineType(nullptr);
+
+  DISubprogram *JTSP = DIB.createFunction(CU, F->getName(), {}, File, 0, DIFnTy,
+                                          0, DINode::FlagArtificial,
+                                          DISubprogram::SPFlagDefinition);
+  F->setSubprogram(JTSP);
+
+  DILocation *JTLoc = DILocation::get(M.getContext(), 0, 0, JTSP);
+
+  DISubprogram *UbsanSP = DIB.createFunction(
+      CU, "__ubsan_check_cfi_icall_jt", {}, File, 0, DIFnTy, 0,
+      DINode::FlagArtificial, DISubprogram::SPFlagDefinition);
+
+  SmallVector<DILocation *> Locations;
+  Locations.reserve(Functions.size());
+
+  for (auto *Func : Functions) {
+    StringRef FuncName = Func->getGlobal()->getName();
+    FuncName.consume_back(".cfi");
+    DISubprogram *JumpSP = DIB.createFunction(
+        CU, (FuncName + ".cfi_jt").str(), {}, File, 0, DIFnTy, 0,
+        DINode::FlagArtificial, DISubprogram::SPFlagDefinition);
+
+    DILocation *EntryLoc = JTLoc;
+    EntryLoc = DILocation::get(M.getContext(), 0, 0, UbsanSP, EntryLoc);
+    EntryLoc = DILocation::get(M.getContext(), 0, 0, JumpSP, EntryLoc);
+    Locations.push_back(EntryLoc);
+  }
+
+  DIB.finalize();
+
+  return Locations;
+}
+
 void LowerTypeTestsModule::createJumpTable(
     Function *F, ArrayRef<GlobalTypeMember *> Functions,
     Triple::ArchType JumpTableArch) {
   BasicBlock *BB = BasicBlock::Create(M.getContext(), "entry", F);
   IRBuilder<> IRB(BB);
 
+  SmallVector<DILocation *> Locations;
+  if (M.getDwarfVersion() != 0)
+    Locations = createJumpTableDebugInfo(F, Functions);
----------------
vitalybuka wrote:

@pcc asked, and I agree: the amount of debug info from here is very limited in comparison to Ubsan  from clang.

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


More information about the llvm-commits mailing list