[LowerTypeTests] Add debug info to jump table entries#192736
Conversation
Created using spr 1.3.7 [skip ci]
Created using spr 1.3.7
|
@llvm/pr-subscribers-llvm-transforms Author: Vitaly Buka (vitalybuka) ChangesWhen Control Flow Integrity (CFI) is enabled, jump tables are used to Full diff: https://github.com/llvm/llvm-project/pull/192736.diff 3 Files Affected:
diff --git a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
index a390b983b1ded..cf653ab15beea 100644
--- a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
+++ b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
@@ -1529,11 +1529,46 @@ Triple::ArchType LowerTypeTestsModule::selectJumpTableArmEncoding(
return ArmCount > ThumbCount ? Triple::arm : Triple::thumb;
}
+static llvm::DILocation *createDebugInfo(Function *F) {
+ 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);
+ llvm::DIFile *File = DIB.createFile("ubsan_interface.h", "sanitizer");
+ if (!CU) {
+ CU = DIB.createCompileUnit(
+ DISourceLanguageName(dwarf::DW_LANG_C), File, "llvm", true, "", 0, "",
+ DICompileUnit::DebugEmissionKind::LineTablesOnly);
+ }
+
+ DISubroutineType *DIFnTy = DIB.createSubroutineType(nullptr);
+
+ llvm::DISubprogram *NormalSP = DIB.createFunction(
+ File, F->getName(), StringRef(), File, 0, DIFnTy, 0,
+ DINode::FlagArtificial, DISubprogram::SPFlagDefinition);
+ F->setSubprogram(NormalSP);
+
+ llvm::DISubprogram *InlineSP = DIB.createFunction(
+ File, "__ubsan_check_cfi_icall_jt", StringRef(), File, 0, DIFnTy, 0,
+ DINode::FlagArtificial, DISubprogram::SPFlagDefinition);
+
+ DIB.finalize();
+
+ return llvm::DILocation::get(
+ M.getContext(), 0, 0, InlineSP,
+ llvm::DILocation::get(M.getContext(), 0, 0, NormalSP));
+}
+
void LowerTypeTestsModule::createJumpTable(
Function *F, ArrayRef<GlobalTypeMember *> Functions,
Triple::ArchType JumpTableArch) {
BasicBlock *BB = BasicBlock::Create(M.getContext(), "entry", F);
IRBuilder<> IRB(BB);
+ if (ClAnnotateDebugInfo)
+ IRB.SetCurrentDebugLocation(createDebugInfo(F));
InlineAsm *JumpTableAsm = createJumpTableEntryAsm(JumpTableArch);
diff --git a/llvm/test/Transforms/LowerTypeTests/aarch64-jumptable.ll b/llvm/test/Transforms/LowerTypeTests/aarch64-jumptable.ll
index 00c11b5b85bc7..e3e6de3d76c31 100644
--- a/llvm/test/Transforms/LowerTypeTests/aarch64-jumptable.ll
+++ b/llvm/test/Transforms/LowerTypeTests/aarch64-jumptable.ll
@@ -85,9 +85,9 @@ define i1 @foo(ptr %p) {
; AARCH64_DBG: Function Attrs: naked noinline
; AARCH64_DBG-LABEL: @.cfi.jumptable(
; AARCH64_DBG-NEXT: entry:
-; AARCH64_DBG-NEXT: call void asm sideeffect "bti c\0Ab $0\0A", "s"(ptr @f.cfi)
-; AARCH64_DBG-NEXT: call void asm sideeffect "bti c\0Ab $0\0A", "s"(ptr @g.cfi)
-; AARCH64_DBG-NEXT: unreachable
+; AARCH64_DBG-NEXT: call void asm sideeffect "bti c\0Ab $0\0A", "s"(ptr @f.cfi), !dbg [[DBG6:![0-9]+]]
+; AARCH64_DBG-NEXT: call void asm sideeffect "bti c\0Ab $0\0A", "s"(ptr @g.cfi), !dbg [[DBG6]]
+; AARCH64_DBG-NEXT: unreachable, !dbg [[DBG6]]
;
;.
; AARCH64: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
@@ -102,5 +102,12 @@ define i1 @foo(ptr %p) {
; AARCH64: [[META1:![0-9]+]] = !{i32 0, !"typeid1"}
;.
; AARCH64_DBG: [[META0:![0-9]+]] = !{i32 4, !"branch-target-enforcement", i32 1}
-; AARCH64_DBG: [[META1:![0-9]+]] = !{i32 0, !"typeid1"}
+; AARCH64_DBG: [[META1:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C, file: [[META2:![0-9]+]], producer: "llvm", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly)
+; AARCH64_DBG: [[META2]] = !DIFile(filename: "{{.*}}ubsan_interface.h", directory: {{.*}})
+; AARCH64_DBG: [[META3:![0-9]+]] = !{i32 0, !"typeid1"}
+; AARCH64_DBG: [[META4:![0-9]+]] = distinct !DISubprogram(name: ".cfi.jumptable", scope: [[META2]], file: [[META2]], type: [[META5:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META1]])
+; AARCH64_DBG: [[META5]] = !DISubroutineType(types: null)
+; AARCH64_DBG: [[DBG6]] = !DILocation(line: 0, scope: [[META7:![0-9]+]], inlinedAt: [[META8:![0-9]+]])
+; AARCH64_DBG: [[META7]] = distinct !DISubprogram(name: "__ubsan_check_cfi_icall_jt", scope: [[META2]], file: [[META2]], type: [[META5]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META1]])
+; AARCH64_DBG: [[META8]] = !DILocation(line: 0, scope: [[META4]])
;.
diff --git a/llvm/test/Transforms/LowerTypeTests/x86-jumptable.ll b/llvm/test/Transforms/LowerTypeTests/x86-jumptable.ll
index 4a8cb0166cc12..e752392b1f058 100644
--- a/llvm/test/Transforms/LowerTypeTests/x86-jumptable.ll
+++ b/llvm/test/Transforms/LowerTypeTests/x86-jumptable.ll
@@ -112,9 +112,9 @@ define i1 @foo(ptr %p) {
;
; X86_32_DBG-LABEL: @.cfi.jumptable(
; X86_32_DBG-NEXT: entry:
-; X86_32_DBG-NEXT: call void asm sideeffect "endbr32\0Ajmp ${0:c}@plt\0A.balign 16, 0xcc\0A", "s"(ptr @f.cfi)
-; X86_32_DBG-NEXT: call void asm sideeffect "endbr32\0Ajmp ${0:c}@plt\0A.balign 16, 0xcc\0A", "s"(ptr @g.cfi)
-; X86_32_DBG-NEXT: unreachable
+; X86_32_DBG-NEXT: call void asm sideeffect "endbr32\0Ajmp ${0:c}@plt\0A.balign 16, 0xcc\0A", "s"(ptr @f.cfi), !dbg [[DBG6:![0-9]+]]
+; X86_32_DBG-NEXT: call void asm sideeffect "endbr32\0Ajmp ${0:c}@plt\0A.balign 16, 0xcc\0A", "s"(ptr @g.cfi), !dbg [[DBG6]]
+; X86_32_DBG-NEXT: unreachable, !dbg [[DBG6]]
;
;
; X86_64_DBG-LABEL: @f.cfi(
@@ -135,9 +135,9 @@ define i1 @foo(ptr %p) {
;
; X86_64_DBG-LABEL: @.cfi.jumptable(
; X86_64_DBG-NEXT: entry:
-; X86_64_DBG-NEXT: call void asm sideeffect "endbr64\0Ajmp ${0:c}@plt\0A.balign 16, 0xcc\0A", "s"(ptr @f.cfi)
-; X86_64_DBG-NEXT: call void asm sideeffect "endbr64\0Ajmp ${0:c}@plt\0A.balign 16, 0xcc\0A", "s"(ptr @g.cfi)
-; X86_64_DBG-NEXT: unreachable
+; X86_64_DBG-NEXT: call void asm sideeffect "endbr64\0Ajmp ${0:c}@plt\0A.balign 16, 0xcc\0A", "s"(ptr @f.cfi), !dbg [[DBG6:![0-9]+]]
+; X86_64_DBG-NEXT: call void asm sideeffect "endbr64\0Ajmp ${0:c}@plt\0A.balign 16, 0xcc\0A", "s"(ptr @g.cfi), !dbg [[DBG6]]
+; X86_64_DBG-NEXT: unreachable, !dbg [[DBG6]]
;
;.
; X86_32: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
@@ -163,8 +163,22 @@ define i1 @foo(ptr %p) {
; X86_64: [[META1:![0-9]+]] = !{i32 0, !"typeid1"}
;.
; X86_32_DBG: [[META0:![0-9]+]] = !{i32 8, !"cf-protection-branch", i32 1}
-; X86_32_DBG: [[META1:![0-9]+]] = !{i32 0, !"typeid1"}
+; X86_32_DBG: [[META1:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C, file: [[META2:![0-9]+]], producer: "llvm", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly)
+; X86_32_DBG: [[META2]] = !DIFile(filename: "{{.*}}ubsan_interface.h", directory: {{.*}})
+; X86_32_DBG: [[META3:![0-9]+]] = !{i32 0, !"typeid1"}
+; X86_32_DBG: [[META4:![0-9]+]] = distinct !DISubprogram(name: ".cfi.jumptable", scope: [[META2]], file: [[META2]], type: [[META5:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META1]])
+; X86_32_DBG: [[META5]] = !DISubroutineType(types: null)
+; X86_32_DBG: [[DBG6]] = !DILocation(line: 0, scope: [[META7:![0-9]+]], inlinedAt: [[META8:![0-9]+]])
+; X86_32_DBG: [[META7]] = distinct !DISubprogram(name: "__ubsan_check_cfi_icall_jt", scope: [[META2]], file: [[META2]], type: [[META5]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META1]])
+; X86_32_DBG: [[META8]] = !DILocation(line: 0, scope: [[META4]])
;.
; X86_64_DBG: [[META0:![0-9]+]] = !{i32 8, !"cf-protection-branch", i32 1}
-; X86_64_DBG: [[META1:![0-9]+]] = !{i32 0, !"typeid1"}
+; X86_64_DBG: [[META1:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C, file: [[META2:![0-9]+]], producer: "llvm", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly)
+; X86_64_DBG: [[META2]] = !DIFile(filename: "{{.*}}ubsan_interface.h", directory: {{.*}})
+; X86_64_DBG: [[META3:![0-9]+]] = !{i32 0, !"typeid1"}
+; X86_64_DBG: [[META4:![0-9]+]] = distinct !DISubprogram(name: ".cfi.jumptable", scope: [[META2]], file: [[META2]], type: [[META5:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META1]])
+; X86_64_DBG: [[META5]] = !DISubroutineType(types: null)
+; X86_64_DBG: [[DBG6]] = !DILocation(line: 0, scope: [[META7:![0-9]+]], inlinedAt: [[META8:![0-9]+]])
+; X86_64_DBG: [[META7]] = distinct !DISubprogram(name: "__ubsan_check_cfi_icall_jt", scope: [[META2]], file: [[META2]], type: [[META5]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META1]])
+; X86_64_DBG: [[META8]] = !DILocation(line: 0, scope: [[META4]])
;.
|
…-check-globals (#192734) Debug information will be updated in the llvm/llvm-project#192736, so we want to track the difference.
…-check-globals (#192734) Debug information will be updated in the llvm/llvm-project#192736, so we want to track the difference.
Created using spr 1.3.7 [skip ci]
Created using spr 1.3.7
🐧 Linux x64 Test Results
✅ The build succeeded and all tests passed. |
pcc
left a comment
There was a problem hiding this comment.
Won't this make the debug info more confusing? Previously debuggers would see the jump table entry symbols from the ELF symbol table, but now it looks like they will just see a symbol name ".cfi.jumptable"? I think I would expect each jump table entry to have separate .debug_line entry named after the function, with the __ubsan_check_cfi_icall_jt inlined inside it.
… with debug info (#192735) (#193358) It just recommits test copied from non dbg version. Implementation is llvm/llvm-project#192736. This is the same as #192735, accidentally merged into spr/users branch.
Created using spr 1.3.7 [skip ci]
Created using spr 1.3.7
done |
… with debug info (#192735) (#193358) It just recommits test copied from non dbg version. Implementation is llvm/llvm-project#192736. This is the same as #192735, accidentally merged into spr/users branch.
pcc
left a comment
There was a problem hiding this comment.
s/llvm;://g throughout the patch
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/174/builds/34818 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/66/builds/29795 Here is the relevant piece of the build log for the reference |
Reverts #192736 Seems to cause buildbot failures in cross-project-tests, including on the premerge postcommit builder. https://lab.llvm.org/staging/#/builders/192/builds/28251
…ies" (#193663) Reverts llvm/llvm-project#192736 Seems to cause buildbot failures in cross-project-tests, including on the premerge postcommit builder. https://lab.llvm.org/staging/#/builders/192/builds/28251
…ies" (#193663) Reverts llvm/llvm-project#192736 Seems to cause buildbot failures in cross-project-tests, including on the premerge postcommit builder. https://lab.llvm.org/staging/#/builders/192/builds/28251
… info (llvm#192735) (llvm#193358) It just recommits test copied from non dbg version. Implementation is llvm#192736. This is the same as llvm#192735, accidentally merged into spr/users branch.
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 #2: .cfi.jumptable.81 at sanitizer/ubsan_interface.h:0:0 ``` This is reland of #192736, reverted with #193663. This version don't update debug info for "Cross-DSO CFI" mode.
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: