Skip to content

Commit 13c6f1e

Browse files
OCHyamsOCHyams
authored and
OCHyams
committed
Reapply [hwasan] Update dbg.assign intrinsics in HWAsan pass #78606
llvm.dbg.assign intrinsics have 2 {value, expression} pairs; fix hwasan to update the second expression. Fixes #76545
1 parent 1f9de23 commit 13c6f1e

File tree

7 files changed

+214
-8
lines changed

7 files changed

+214
-8
lines changed

llvm/lib/IR/DebugInfo.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2200,10 +2200,6 @@ bool AssignmentTrackingPass::runOnFunction(Function &F) {
22002200
if (F.hasFnAttribute(Attribute::OptimizeNone))
22012201
return /*Changed*/ false;
22022202

2203-
// FIXME: https://github.com/llvm/llvm-project/issues/76545
2204-
if (F.hasFnAttribute(Attribute::SanitizeHWAddress))
2205-
return /*Changed*/ false;
2206-
22072203
bool Changed = false;
22082204
auto *DL = &F.getParent()->getDataLayout();
22092205
// Collect a map of {backing storage : dbg.declares} (currently "backing

llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1435,6 +1435,11 @@ bool HWAddressSanitizer::instrumentStack(memtag::StackInfo &SInfo,
14351435
if (DDI->getVariableLocationOp(LocNo) == AI)
14361436
DDI->setExpression(DIExpression::appendOpsToArg(DDI->getExpression(),
14371437
NewOps, LocNo));
1438+
if (auto *DAI = dyn_cast<DbgAssignIntrinsic>(DDI)) {
1439+
if (DAI->getAddress() == AI)
1440+
DAI->setAddressExpression(DIExpression::prependOpcodes(
1441+
DAI->getAddressExpression(), NewOps));
1442+
}
14381443
}
14391444

14401445
auto TagEnd = [&](Instruction *Node) {

llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,16 +138,20 @@ void StackInfoBuilder::visit(Instruction &Inst) {
138138
return;
139139
}
140140
if (auto *DVI = dyn_cast<DbgVariableIntrinsic>(&Inst)) {
141-
for (Value *V : DVI->location_ops()) {
141+
auto AddIfInteresting = [&](Value *V) {
142142
if (auto *AI = dyn_cast_or_null<AllocaInst>(V)) {
143143
if (!isInterestingAlloca(*AI))
144-
continue;
144+
return;
145145
AllocaInfo &AInfo = Info.AllocasToInstrument[AI];
146146
auto &DVIVec = AInfo.DbgVariableIntrinsics;
147147
if (DVIVec.empty() || DVIVec.back() != DVI)
148148
DVIVec.push_back(DVI);
149149
}
150-
}
150+
};
151+
for (Value *V : DVI->location_ops())
152+
AddIfInteresting(V);
153+
if (auto *DAI = dyn_cast<DbgAssignIntrinsic>(DVI))
154+
AddIfInteresting(DAI->getAddress());
151155
}
152156
Instruction *ExitUntag = getUntagLocationIfFunctionExit(Inst);
153157
if (ExitUntag)
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
; RUN: llc -filetype=obj -o - %s | llvm-dwarfdump - | FileCheck %s
2+
3+
;; Similar to dbg-assign-tag-offset.ll except the variable 'x' has been removed
4+
;; and 'y' has an implicit location range as well as stack location range
5+
;; (according to the hand-modified debug info -- see the dbg.value).
6+
7+
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
8+
target triple = "aarch64-unknown-linux-android24"
9+
10+
; CHECK: DW_TAG_variable
11+
; CHECK-NOT: DW_TAG
12+
; CHECK: DW_AT_LLVM_tag_offset (0x80)
13+
; CHECK-NEXT: DW_AT_name ("y")
14+
15+
define dso_local void @f() !dbg !14 {
16+
%1 = alloca i32, align 4, !DIAssignID !31
17+
%2 = alloca i32, align 4, !DIAssignID !32
18+
call void @llvm.dbg.assign(metadata i1 undef, metadata !20, metadata !DIExpression(), metadata !32, metadata ptr %2, metadata !DIExpression(DW_OP_LLVM_tag_offset, 128)), !dbg !22
19+
call void @llvm.dbg.value(metadata i32 2, metadata !20, metadata !DIExpression()), !dbg !22
20+
call void @use(ptr null), !dbg !28
21+
store i32 1, ptr %2, align 4, !dbg !23, !tbaa !24, !DIAssignID !33
22+
call void @llvm.dbg.assign(metadata i32 1, metadata !20, metadata !DIExpression(), metadata !33, metadata ptr %2, metadata !DIExpression(DW_OP_LLVM_tag_offset, 128)), !dbg !22
23+
call void @use(ptr nonnull %1), !dbg !28
24+
call void @use(ptr nonnull %2), !dbg !29
25+
ret void, !dbg !30
26+
}
27+
28+
declare !dbg !5 void @use(ptr)
29+
30+
declare void @llvm.dbg.value(metadata, metadata, metadata)
31+
declare void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata)
32+
33+
!llvm.dbg.cu = !{!0}
34+
!llvm.module.flags = !{!8, !9, !10, !11, !12, !34}
35+
!llvm.ident = !{!13}
36+
37+
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 10.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None)
38+
!1 = !DIFile(filename: "dbg.cc", directory: "/tmp")
39+
!2 = !{}
40+
!3 = !{!4, !5}
41+
!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64)
42+
!5 = !DISubprogram(name: "use", scope: !1, file: !1, line: 2, type: !6, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2)
43+
!6 = !DISubroutineType(types: !7)
44+
!7 = !{null, !4}
45+
!8 = !{i32 7, !"Dwarf Version", i32 4}
46+
!9 = !{i32 2, !"Debug Info Version", i32 3}
47+
!10 = !{i32 1, !"wchar_size", i32 4}
48+
!11 = !{i32 7, !"PIC Level", i32 2}
49+
!12 = !{i32 7, !"PIE Level", i32 2}
50+
!13 = !{!"clang version 10.0.0"}
51+
!14 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 4, type: !15, scopeLine: 4, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !17)
52+
!15 = !DISubroutineType(types: !16)
53+
!16 = !{null}
54+
!17 = !{!18, !20}
55+
!18 = !DILocalVariable(name: "x", scope: !14, file: !1, line: 5, type: !19)
56+
!19 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
57+
!20 = !DILocalVariable(name: "y", scope: !14, file: !1, line: 5, type: !19)
58+
!21 = !DILocation(line: 5, column: 3, scope: !14)
59+
!22 = !DILocation(line: 0, scope: !14)
60+
!23 = !DILocation(line: 5, column: 10, scope: !14)
61+
!24 = !{!25, !25, i64 0}
62+
!25 = !{!"int", !26, i64 0}
63+
!26 = !{!"omnipotent char", !27, i64 0}
64+
!27 = !{!"Simple C++ TBAA"}
65+
!28 = !DILocation(line: 6, column: 3, scope: !14)
66+
!29 = !DILocation(line: 7, column: 3, scope: !14)
67+
!30 = !DILocation(line: 8, column: 1, scope: !14)
68+
!31 = distinct !DIAssignID()
69+
!32 = distinct !DIAssignID()
70+
!33 = distinct !DIAssignID()
71+
!34 = !{i32 7, !"debug-info-assignment-tracking", i1 true}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
; RUN: llc -filetype=obj -o - %s | llvm-dwarfdump - | FileCheck %s
2+
3+
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
4+
target triple = "aarch64-unknown-linux-android24"
5+
6+
; CHECK: DW_TAG_variable
7+
; CHECK-NOT: DW_TAG
8+
; CHECK: DW_AT_LLVM_tag_offset (0x00)
9+
; CHECK-NEXT: DW_AT_name ("x")
10+
11+
; CHECK: DW_TAG_variable
12+
; CHECK-NOT: DW_TAG
13+
; CHECK: DW_AT_LLVM_tag_offset (0x80)
14+
; CHECK-NEXT: DW_AT_name ("y")
15+
16+
define dso_local void @f() !dbg !14 {
17+
%1 = alloca i32, align 4, !DIAssignID !31
18+
call void @llvm.dbg.assign(metadata i1 undef, metadata !18, metadata !DIExpression(), metadata !31, metadata ptr %1, metadata !DIExpression(DW_OP_LLVM_tag_offset, 0)), !dbg !22
19+
%2 = alloca i32, align 4, !DIAssignID !32
20+
call void @llvm.dbg.assign(metadata i1 undef, metadata !20, metadata !DIExpression(), metadata !32, metadata ptr %2, metadata !DIExpression(DW_OP_LLVM_tag_offset, 128)), !dbg !22
21+
store i32 1, ptr %2, align 4, !dbg !23, !tbaa !24, !DIAssignID !33
22+
call void @llvm.dbg.assign(metadata i32 1, metadata !20, metadata !DIExpression(), metadata !33, metadata ptr %2, metadata !DIExpression(DW_OP_LLVM_tag_offset, 128)), !dbg !22
23+
call void @use(ptr nonnull %1), !dbg !28
24+
call void @use(ptr nonnull %2), !dbg !29
25+
ret void, !dbg !30
26+
}
27+
28+
declare !dbg !5 void @use(ptr)
29+
30+
declare void @llvm.dbg.value(metadata, metadata, metadata)
31+
declare void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata)
32+
33+
!llvm.dbg.cu = !{!0}
34+
!llvm.module.flags = !{!8, !9, !10, !11, !12, !34}
35+
!llvm.ident = !{!13}
36+
37+
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 10.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None)
38+
!1 = !DIFile(filename: "dbg.cc", directory: "/tmp")
39+
!2 = !{}
40+
!3 = !{!4, !5}
41+
!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64)
42+
!5 = !DISubprogram(name: "use", scope: !1, file: !1, line: 2, type: !6, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2)
43+
!6 = !DISubroutineType(types: !7)
44+
!7 = !{null, !4}
45+
!8 = !{i32 7, !"Dwarf Version", i32 4}
46+
!9 = !{i32 2, !"Debug Info Version", i32 3}
47+
!10 = !{i32 1, !"wchar_size", i32 4}
48+
!11 = !{i32 7, !"PIC Level", i32 2}
49+
!12 = !{i32 7, !"PIE Level", i32 2}
50+
!13 = !{!"clang version 10.0.0"}
51+
!14 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 4, type: !15, scopeLine: 4, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !17)
52+
!15 = !DISubroutineType(types: !16)
53+
!16 = !{null}
54+
!17 = !{!18, !20}
55+
!18 = !DILocalVariable(name: "x", scope: !14, file: !1, line: 5, type: !19)
56+
!19 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
57+
!20 = !DILocalVariable(name: "y", scope: !14, file: !1, line: 5, type: !19)
58+
!21 = !DILocation(line: 5, column: 3, scope: !14)
59+
!22 = !DILocation(line: 0, scope: !14)
60+
!23 = !DILocation(line: 5, column: 10, scope: !14)
61+
!24 = !{!25, !25, i64 0}
62+
!25 = !{!"int", !26, i64 0}
63+
!26 = !{!"omnipotent char", !27, i64 0}
64+
!27 = !{!"Simple C++ TBAA"}
65+
!28 = !DILocation(line: 6, column: 3, scope: !14)
66+
!29 = !DILocation(line: 7, column: 3, scope: !14)
67+
!30 = !DILocation(line: 8, column: 1, scope: !14)
68+
!31 = distinct !DIAssignID()
69+
!32 = distinct !DIAssignID()
70+
!33 = distinct !DIAssignID()
71+
!34 = !{i32 7, !"debug-info-assignment-tracking", i1 true}

llvm/test/DebugInfo/Generic/assignment-tracking/declare-to-assign/hwasan.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
; RUN: opt %s -S -passes=declare-to-assign -o - | FileCheck %s
22

3-
; CHECK: call void @llvm.dbg.declare
3+
; CHECK: call void @llvm.dbg.assign
44

55
define dso_local void @f() sanitize_hwaddress !dbg !9 {
66
entry:
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
; RUN: opt -passes=hwasan -S -o - %s | FileCheck %s
2+
3+
source_filename = "test.ll"
4+
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
5+
target triple = "aarch64--linux-android"
6+
7+
declare void @g(ptr, ptr, ptr, ptr, ptr, ptr)
8+
9+
; Function Attrs: sanitize_hwaddress
10+
define void @f() #0 !dbg !7 {
11+
entry:
12+
%nodebug0 = alloca ptr, align 8
13+
%nodebug1 = alloca ptr, align 8
14+
%nodebug2 = alloca ptr, align 8
15+
%nodebug3 = alloca ptr, align 8
16+
; CHECK: %a = alloca{{.*}} !DIAssignID ![[ID1:[0-9]+]]
17+
%a = alloca ptr, align 8, !DIAssignID !13
18+
; CHECK: @llvm.dbg.assign{{.*}} metadata ![[ID1]]{{.*}} !DIExpression(DW_OP_LLVM_tag_offset, 32)
19+
call void @llvm.dbg.assign(metadata i1 undef, metadata !14, metadata !DIExpression(), metadata !13, metadata ptr %a, metadata !DIExpression()), !dbg !15
20+
; CHECK: %b = alloca{{.*}} !DIAssignID ![[ID2:[0-9]+]]
21+
%b = alloca ptr, align 8, !DIAssignID !16
22+
; CHECK: @llvm.dbg.assign{{.*}} metadata ![[ID2]]{{.*}} !DIExpression(DW_OP_LLVM_tag_offset, 96)
23+
call void @llvm.dbg.assign(metadata i1 undef, metadata !17, metadata !DIExpression(DW_OP_plus_uconst, 1), metadata !16, metadata ptr %b, metadata !DIExpression()), !dbg !15
24+
call void @g(ptr %nodebug0, ptr %nodebug1, ptr %nodebug2, ptr %nodebug3, ptr %a, ptr %b)
25+
ret void, !dbg !18
26+
}
27+
28+
; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
29+
declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
30+
31+
; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
32+
declare void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata) #1
33+
34+
attributes #0 = { sanitize_hwaddress }
35+
attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
36+
37+
!llvm.dbg.cu = !{!0}
38+
!llvm.module.flags = !{!3, !4, !5}
39+
!llvm.ident = !{!6}
40+
41+
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
42+
!1 = !DIFile(filename: "x.c", directory: "/")
43+
!2 = !{}
44+
!3 = !{i32 2, !"Dwarf Version", i32 4}
45+
!4 = !{i32 2, !"Debug Info Version", i32 3}
46+
!5 = !{i32 7, !"debug-info-assignment-tracking", i1 true}
47+
!6 = !{!"clang"}
48+
!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
49+
!8 = !DISubroutineType(types: !9)
50+
!9 = !{null, !10}
51+
!10 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !11, size: 64)
52+
!11 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !12)
53+
!12 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
54+
!13 = distinct !DIAssignID()
55+
!14 = !DILocalVariable(name: "a", scope: !7, file: !1, line: 1, type: !10)
56+
!15 = !DILocation(line: 0, scope: !7)
57+
!16 = distinct !DIAssignID()
58+
!17 = !DILocalVariable(name: "b", scope: !7, file: !1, line: 1, type: !10)
59+
!18 = !DILocation(line: 1, column: 37, scope: !7)

0 commit comments

Comments
 (0)