[LowerTypeTests] Add debug info to jump table entries#194493
Conversation
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
🐧 Linux x64 Test Results
✅ The build succeeded and all tests passed. |
🪟 Windows x64 Test Results
✅ The build succeeded and all tests passed. |
|
@llvm/pr-subscribers-compiler-rt-sanitizer @llvm/pr-subscribers-llvm-transforms Author: Vitaly Buka (vitalybuka) Changes[LowerTypeTests] Add debug info to jump table entries (#192736) When Control Flow Integrity (CFI) is enabled, jump tables are used to Now stack trace, when stopped on jump table entry will looks like this: Following up on previous attempts #192736 and #193670, this PR is Full diff: https://github.com/llvm/llvm-project/pull/194493.diff 8 Files Affected:
diff --git a/compiler-rt/lib/ubsan/ubsan_handlers.cpp b/compiler-rt/lib/ubsan/ubsan_handlers.cpp
index 63319f46734a4..4adcd4737b375 100644
--- a/compiler-rt/lib/ubsan/ubsan_handlers.cpp
+++ b/compiler-rt/lib/ubsan/ubsan_handlers.cpp
@@ -855,6 +855,28 @@ void __ubsan::__ubsan_handle_pointer_overflow_abort(PointerOverflowData *Data,
Die();
}
+// Returns true if this is a special location created by
+// `LowerTypeTestsModule::createJumpTable`.
+static bool isArtificialStack(const SymbolizedStack *S) {
+ static constexpr char kSuffix[] = "ubsan_interface.h";
+ if (!S || !S->info.function || !S->info.file)
+ return false;
+ const char *File = S->info.file;
+ File += internal_strlen(File) - internal_strlen(kSuffix);
+ return internal_strcmp(File, kSuffix) == 0;
+}
+
+// Preserve behavior before introducing artificial debug location. It's was not
+// ideal, but better than printing in `ubsan_interface.h` as location. Drop file
+// name, so `Diag` will print a module name.
+static SymbolizedStack *filterOutArtifialStack(SymbolizedStack *FS) {
+ for (SymbolizedStack *S = FS; S; S = S->next) {
+ if (isArtificialStack(S))
+ S->info.file = nullptr;
+ }
+ return FS;
+}
+
static void handleCFIBadIcall(CFICheckFailData *Data, ValueHandle Function,
ReportOptions Opts) {
if (Data->CheckKind != CFITCK_ICall && Data->CheckKind != CFITCK_NVMFCall)
@@ -875,7 +897,9 @@ static void handleCFIBadIcall(CFICheckFailData *Data, ValueHandle Function,
"control flow integrity check for type %0 failed during %1")
<< Data->Type << CheckKindStr;
- SymbolizedStackHolder FLoc(getSymbolizedLocation(Function));
+ SymbolizedStackHolder FLoc(
+ filterOutArtifialStack(getSymbolizedLocation(Function)));
+
const char *FName = FLoc.get()->info.function;
if (!FName)
FName = "(unknown)";
diff --git a/compiler-rt/test/cfi/cross-dso/icall/diag.cpp b/compiler-rt/test/cfi/cross-dso/icall/diag.cpp
index a8c7f36608980..fadbdefd066ce 100644
--- a/compiler-rt/test/cfi/cross-dso/icall/diag.cpp
+++ b/compiler-rt/test/cfi/cross-dso/icall/diag.cpp
@@ -113,7 +113,7 @@ int main(int argc, char *argv[]) {
void *p;
if (argv[1][0] == 'i') {
// ICALL-DIAG: runtime error: control flow integrity check for type 'void *(int)' failed during indirect function call
- // ICALL-DIAG-NEXT: dynamic.so+0x{{[[:xdigit:]]+}}): note: create_B() defined here
+ // ICALL-DIAG-NEXT: dynamic.so+0x{{[[:xdigit:]]+}}): note: create_B() {{(\(.cfi_jt\) )?}}defined here
// ICALL-NODIAG-NOT: runtime error: control flow integrity check {{.*}} during indirect function call
p = ((void *(*)(int))create_B)(42);
} else {
diff --git a/compiler-rt/test/cfi/cross-dso/icall/icall-from-dso.cpp b/compiler-rt/test/cfi/cross-dso/icall/icall-from-dso.cpp
index d9f128ddf1026..3364d54fdfadb 100644
--- a/compiler-rt/test/cfi/cross-dso/icall/icall-from-dso.cpp
+++ b/compiler-rt/test/cfi/cross-dso/icall/icall-from-dso.cpp
@@ -18,7 +18,7 @@ void f() {
// CHECK: =2=
fprintf(stderr, "=2=\n");
// CFI-DIAG: runtime error: control flow integrity check for type 'void (int)' failed during indirect function call
- // CFI-DIAG-NEXT: ({{.*}}exe+0x{{[[:xdigit:]]+}}): note: g() defined here
+ // CFI-DIAG-NEXT: ({{.*}}exe+0x{{[[:xdigit:]]+}}): note: g() {{(\(.cfi_jt\) )?}}defined here
((void (*)(int))g)(42); // UB here
// CHECK-DIAG: =3=
// CHECK-NOT: =3=
diff --git a/compiler-rt/test/cfi/cross-dso/icall/icall.cpp b/compiler-rt/test/cfi/cross-dso/icall/icall.cpp
index 479047a6b05d6..671d6f1d7fdb7 100644
--- a/compiler-rt/test/cfi/cross-dso/icall/icall.cpp
+++ b/compiler-rt/test/cfi/cross-dso/icall/icall.cpp
@@ -21,7 +21,7 @@ int main() {
// CHECK: =2=
fprintf(stderr, "=2=\n");
// CFI-DIAG: runtime error: control flow integrity check for type 'void (int)' failed during indirect function call
- // CFI-DIAG-NEXT: ({{.*}}dynamic.so+0x{{[[:xdigit:]]+}}): note: f() defined here
+ // CFI-DIAG-NEXT: ({{.*}}dynamic.so+0x{{[[:xdigit:]]+}}): note: f() {{(\(.cfi_jt\) )?}}defined here
((void (*)(int))f)(42); // UB here
// CHECK-DIAG: =3=
// CHECK-NOT: =3=
diff --git a/compiler-rt/test/cfi/mfcall.cpp b/compiler-rt/test/cfi/mfcall.cpp
index d4666df8d5333..7ed31e9cc0851 100644
--- a/compiler-rt/test/cfi/mfcall.cpp
+++ b/compiler-rt/test/cfi/mfcall.cpp
@@ -63,12 +63,12 @@ int main(int argc, char **argv) {
switch (argv[1][0]) {
case 'a':
// A: runtime error: control flow integrity check for type 'int (S::*)()' failed during non-virtual pointer to member function call
- // A: note: S::f1() defined here
+ // A: note: S::f1() {{(\(.cfi_jt\) )?}}defined here
(s.*bitcast<S_int>(&S::f1))();
break;
case 'b':
// B: runtime error: control flow integrity check for type 'int (T::*)()' failed during non-virtual pointer to member function call
- // B: note: S::f2() defined here
+ // B: note: S::f2() {{(\(.cfi_jt\) )?}}defined here
(t.*bitcast<T_int>(&S::f2))();
break;
case 'c':
diff --git a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
index 323df2a6a0abf..8bc63dcc260f7 100644
--- a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
+++ b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
@@ -35,6 +35,7 @@
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
@@ -1523,12 +1524,71 @@ 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);
+
InlineAsm *JumpTableAsm = createJumpTableEntryAsm(JumpTableArch);
// Check if all entries have the NoUnwind attribute.
@@ -1536,12 +1596,15 @@ void LowerTypeTestsModule::createJumpTable(
// cfi.jumptable as NoUnwind, otherwise, direct calls
// to the jump table will not handle exceptions properly
bool areAllEntriesNounwind = true;
- for (GlobalTypeMember *GTM : Functions) {
- if (!llvm::cast<llvm::Function>(GTM->getGlobal())
- ->hasFnAttribute(llvm::Attribute::NoUnwind)) {
+ assert(Locations.empty() || Functions.size() == Locations.size());
+ for (auto [GTM, Loc] : zip_longest(Functions, Locations)) {
+ if (Loc.has_value())
+ IRB.SetCurrentDebugLocation(*Loc);
+ if (!cast<Function>((*GTM)->getGlobal())
+ ->hasFnAttribute(Attribute::NoUnwind)) {
areAllEntriesNounwind = false;
}
- IRB.CreateCall(JumpTableAsm, GTM->getGlobal());
+ IRB.CreateCall(JumpTableAsm, (*GTM)->getGlobal());
}
IRB.CreateUnreachable();
diff --git a/llvm/test/Transforms/LowerTypeTests/aarch64-jumptable-dbg.ll b/llvm/test/Transforms/LowerTypeTests/aarch64-jumptable-dbg.ll
index c10f16bf1f4d3..1c4df8b387e21 100644
--- a/llvm/test/Transforms/LowerTypeTests/aarch64-jumptable-dbg.ll
+++ b/llvm/test/Transforms/LowerTypeTests/aarch64-jumptable-dbg.ll
@@ -56,9 +56,9 @@ define i1 @foo(ptr %p) {
; AARCH64: Function Attrs: naked noinline
; AARCH64-LABEL: @.cfi.jumptable(
; AARCH64-NEXT: entry:
-; AARCH64-NEXT: call void asm sideeffect "bti c\0Ab $0\0A", "s"(ptr @f.cfi)
-; AARCH64-NEXT: call void asm sideeffect "bti c\0Ab $0\0A", "s"(ptr @g.cfi)
-; AARCH64-NEXT: unreachable
+; AARCH64-NEXT: call void asm sideeffect "bti c\0Ab $0\0A", "s"(ptr @f.cfi), !dbg [[DBG8:![0-9]+]]
+; AARCH64-NEXT: call void asm sideeffect "bti c\0Ab $0\0A", "s"(ptr @g.cfi), !dbg [[DBG13:![0-9]+]]
+; AARCH64-NEXT: unreachable, !dbg [[DBG13]]
;
;.
; AARCH64: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
@@ -68,5 +68,16 @@ define i1 @foo(ptr %p) {
; AARCH64: [[META0:![0-9]+]] = !{i32 4, !"branch-target-enforcement", i32 1}
; AARCH64: [[META1:![0-9]+]] = !{i32 7, !"Dwarf Version", i32 5}
; AARCH64: [[META2:![0-9]+]] = !{i32 2, !"Debug Info Version", i32 3}
-; AARCH64: [[META3:![0-9]+]] = !{i32 0, !"typeid1"}
+; AARCH64: [[META3:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C, file: [[META4:![0-9]+]], producer: "llvm", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly)
+; AARCH64: [[META4]] = !DIFile(filename: "{{.*}}ubsan_interface.h", directory: {{.*}})
+; AARCH64: [[META5:![0-9]+]] = !{i32 0, !"typeid1"}
+; AARCH64: [[META6:![0-9]+]] = distinct !DISubprogram(name: ".cfi.jumptable", scope: null, file: [[META4]], type: [[META7:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META3]])
+; AARCH64: [[META7]] = !DISubroutineType(types: null)
+; AARCH64: [[DBG8]] = !DILocation(line: 0, scope: [[META9:![0-9]+]], inlinedAt: [[META10:![0-9]+]])
+; AARCH64: [[META9]] = distinct !DISubprogram(name: "f.cfi_jt", scope: null, file: [[META4]], type: [[META7]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META3]])
+; AARCH64: [[META10]] = !DILocation(line: 0, scope: [[META11:![0-9]+]], inlinedAt: [[META12:![0-9]+]])
+; AARCH64: [[META11]] = distinct !DISubprogram(name: "__ubsan_check_cfi_icall_jt", scope: null, file: [[META4]], type: [[META7]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META3]])
+; AARCH64: [[META12]] = !DILocation(line: 0, scope: [[META6]])
+; AARCH64: [[DBG13]] = !DILocation(line: 0, scope: [[META14:![0-9]+]], inlinedAt: [[META10]])
+; AARCH64: [[META14]] = distinct !DISubprogram(name: "g.cfi_jt", scope: null, file: [[META4]], type: [[META7]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META3]])
;.
diff --git a/llvm/test/Transforms/LowerTypeTests/x86-jumptable-dbg.ll b/llvm/test/Transforms/LowerTypeTests/x86-jumptable-dbg.ll
index d21ca284f911e..39b7f853fabc6 100644
--- a/llvm/test/Transforms/LowerTypeTests/x86-jumptable-dbg.ll
+++ b/llvm/test/Transforms/LowerTypeTests/x86-jumptable-dbg.ll
@@ -56,9 +56,9 @@ define i1 @foo(ptr %p) {
;
; X86_32-LABEL: @.cfi.jumptable(
; X86_32-NEXT: entry:
-; X86_32-NEXT: call void asm sideeffect "endbr32\0Ajmp ${0:c}@plt\0A.balign 16, 0xcc\0A", "s"(ptr @f.cfi)
-; X86_32-NEXT: call void asm sideeffect "endbr32\0Ajmp ${0:c}@plt\0A.balign 16, 0xcc\0A", "s"(ptr @g.cfi)
-; X86_32-NEXT: unreachable
+; X86_32-NEXT: call void asm sideeffect "endbr32\0Ajmp ${0:c}@plt\0A.balign 16, 0xcc\0A", "s"(ptr @f.cfi), !dbg [[DBG8:![0-9]+]]
+; X86_32-NEXT: call void asm sideeffect "endbr32\0Ajmp ${0:c}@plt\0A.balign 16, 0xcc\0A", "s"(ptr @g.cfi), !dbg [[DBG13:![0-9]+]]
+; X86_32-NEXT: unreachable, !dbg [[DBG13]]
;
;
; X86_64-LABEL: @f.cfi(
@@ -79,9 +79,9 @@ define i1 @foo(ptr %p) {
;
; X86_64-LABEL: @.cfi.jumptable(
; X86_64-NEXT: entry:
-; X86_64-NEXT: call void asm sideeffect "endbr64\0Ajmp ${0:c}@plt\0A.balign 16, 0xcc\0A", "s"(ptr @f.cfi)
-; X86_64-NEXT: call void asm sideeffect "endbr64\0Ajmp ${0:c}@plt\0A.balign 16, 0xcc\0A", "s"(ptr @g.cfi)
-; X86_64-NEXT: unreachable
+; X86_64-NEXT: call void asm sideeffect "endbr64\0Ajmp ${0:c}@plt\0A.balign 16, 0xcc\0A", "s"(ptr @f.cfi), !dbg [[DBG8:![0-9]+]]
+; X86_64-NEXT: call void asm sideeffect "endbr64\0Ajmp ${0:c}@plt\0A.balign 16, 0xcc\0A", "s"(ptr @g.cfi), !dbg [[DBG13:![0-9]+]]
+; X86_64-NEXT: unreachable, !dbg [[DBG13]]
;
;.
; X86_32: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
@@ -95,10 +95,32 @@ define i1 @foo(ptr %p) {
; X86_32: [[META0:![0-9]+]] = !{i32 8, !"cf-protection-branch", i32 1}
; X86_32: [[META1:![0-9]+]] = !{i32 7, !"Dwarf Version", i32 5}
; X86_32: [[META2:![0-9]+]] = !{i32 2, !"Debug Info Version", i32 3}
-; X86_32: [[META3:![0-9]+]] = !{i32 0, !"typeid1"}
+; X86_32: [[META3:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C, file: [[META4:![0-9]+]], producer: "llvm", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly)
+; X86_32: [[META4]] = !DIFile(filename: "{{.*}}ubsan_interface.h", directory: {{.*}})
+; X86_32: [[META5:![0-9]+]] = !{i32 0, !"typeid1"}
+; X86_32: [[META6:![0-9]+]] = distinct !DISubprogram(name: ".cfi.jumptable", scope: null, file: [[META4]], type: [[META7:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META3]])
+; X86_32: [[META7]] = !DISubroutineType(types: null)
+; X86_32: [[DBG8]] = !DILocation(line: 0, scope: [[META9:![0-9]+]], inlinedAt: [[META10:![0-9]+]])
+; X86_32: [[META9]] = distinct !DISubprogram(name: "f.cfi_jt", scope: null, file: [[META4]], type: [[META7]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META3]])
+; X86_32: [[META10]] = !DILocation(line: 0, scope: [[META11:![0-9]+]], inlinedAt: [[META12:![0-9]+]])
+; X86_32: [[META11]] = distinct !DISubprogram(name: "__ubsan_check_cfi_icall_jt", scope: null, file: [[META4]], type: [[META7]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META3]])
+; X86_32: [[META12]] = !DILocation(line: 0, scope: [[META6]])
+; X86_32: [[DBG13]] = !DILocation(line: 0, scope: [[META14:![0-9]+]], inlinedAt: [[META10]])
+; X86_32: [[META14]] = distinct !DISubprogram(name: "g.cfi_jt", scope: null, file: [[META4]], type: [[META7]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META3]])
;.
; X86_64: [[META0:![0-9]+]] = !{i32 8, !"cf-protection-branch", i32 1}
; X86_64: [[META1:![0-9]+]] = !{i32 7, !"Dwarf Version", i32 5}
; X86_64: [[META2:![0-9]+]] = !{i32 2, !"Debug Info Version", i32 3}
-; X86_64: [[META3:![0-9]+]] = !{i32 0, !"typeid1"}
+; X86_64: [[META3:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C, file: [[META4:![0-9]+]], producer: "llvm", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly)
+; X86_64: [[META4]] = !DIFile(filename: "{{.*}}ubsan_interface.h", directory: {{.*}})
+; X86_64: [[META5:![0-9]+]] = !{i32 0, !"typeid1"}
+; X86_64: [[META6:![0-9]+]] = distinct !DISubprogram(name: ".cfi.jumptable", scope: null, file: [[META4]], type: [[META7:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META3]])
+; X86_64: [[META7]] = !DISubroutineType(types: null)
+; X86_64: [[DBG8]] = !DILocation(line: 0, scope: [[META9:![0-9]+]], inlinedAt: [[META10:![0-9]+]])
+; X86_64: [[META9]] = distinct !DISubprogram(name: "f.cfi_jt", scope: null, file: [[META4]], type: [[META7]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META3]])
+; X86_64: [[META10]] = !DILocation(line: 0, scope: [[META11:![0-9]+]], inlinedAt: [[META12:![0-9]+]])
+; X86_64: [[META11]] = distinct !DISubprogram(name: "__ubsan_check_cfi_icall_jt", scope: null, file: [[META4]], type: [[META7]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META3]])
+; X86_64: [[META12]] = !DILocation(line: 0, scope: [[META6]])
+; X86_64: [[DBG13]] = !DILocation(line: 0, scope: [[META14:![0-9]+]], inlinedAt: [[META10]])
+; X86_64: [[META14]] = distinct !DISubprogram(name: "g.cfi_jt", scope: null, file: [[META4]], type: [[META7]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META3]])
;.
|
45d6a81 to
186f5f4
Compare
…l switch (#195373) For llvm/llvm-project#194493
…l switch (#195373) For llvm/llvm-project#194493
When Control Flow Integrity (CFI) is enabled, jump tables are used to redirect indirect calls. Previously, these jump table entries lacked debug information, making it difficult for profilers and debuggers to attribute execution time correctly. Now stack trace, when stopped on jump table entry will looks like this: ``` #0: __ubsan_check_cfi_icall_jt at sanitizer/ubsan_interface.h:0 #1: c::c() (.cfi_jt) at sanitizer/ubsan_interface.h:0:0 llvm#2: .cfi.jumptable.81 at sanitizer/ubsan_interface.h:0:0 ```
Probably no difference from the File.
This it would be easier to make consistent runtime behavior.
…l switch (#195373) For llvm/llvm-project#194493
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/88/builds/22984 Here is the relevant piece of the build log for the reference |
[LowerTypeTests] Add debug info to jump table entries (llvm#192736) When Control Flow Integrity (CFI) is enabled, jump tables are used to redirect indirect calls. Previously, these jump table entries lacked debug information, making it difficult for profilers and debuggers to attribute execution time correctly. Now stack trace, when stopped on jump table entry will looks like this: ``` #0: c::c() (.cfi_jt) at sanitizer/ubsan_interface.h:0:0 llvm#1: __ubsan_check_cfi_icall_jt at sanitizer/ubsan_interface.h:0 ``` Following up on previous attempts llvm#192736 and llvm#193670, this PR is essentially llvm#192736 but with the `(.cfi_jt)` and `__ubsan_check_cfi_icall_jt` frames swapped. While the specific order of `__ubsan_check_cfi_icall_jt` isn't strictly necessary, swapping them helps maintain existing diagnostics behavior. Additionally, the diagnostics must remove `ubsan_interface.h` to allow for a fallback to printing the module name. See "Commits" tab for details.
[LowerTypeTests] Add debug info to jump table entries (llvm#192736) When Control Flow Integrity (CFI) is enabled, jump tables are used to redirect indirect calls. Previously, these jump table entries lacked debug information, making it difficult for profilers and debuggers to attribute execution time correctly. Now stack trace, when stopped on jump table entry will looks like this: ``` #0: c::c() (.cfi_jt) at sanitizer/ubsan_interface.h:0:0 #1: __ubsan_check_cfi_icall_jt at sanitizer/ubsan_interface.h:0 ``` Following up on previous attempts llvm#192736 and llvm#193670, this PR is essentially llvm#192736 but with the `(.cfi_jt)` and `__ubsan_check_cfi_icall_jt` frames swapped. While the specific order of `__ubsan_check_cfi_icall_jt` isn't strictly necessary, swapping them helps maintain existing diagnostics behavior. Additionally, the diagnostics must remove `ubsan_interface.h` to allow for a fallback to printing the module name. See "Commits" tab for details.
[LowerTypeTests] Add debug info to jump table entries (#192736)
When Control Flow Integrity (CFI) is enabled, jump tables are used to
redirect indirect calls. Previously, these jump table entries lacked
debug information, making it difficult for profilers and debuggers to
attribute execution time correctly.
Now stack trace, when stopped on jump table entry will looks like this:
Following up on previous attempts #192736 and #193670, this PR is
essentially #192736 but with the
(.cfi_jt)and__ubsan_check_cfi_icall_jtframes swapped. While the specific order of
__ubsan_check_cfi_icall_jtisn't strictly necessary, swapping them helps maintain existing diagnostics
behavior.
Additionally, the diagnostics must remove
ubsan_interface.hto allowfor a fallback to printing the module name.
See "Commits" tab for details.