Skip to content

Commit 1cbddce

Browse files
[DebugInfo] Use DW_OP_deref_size for DW_OP_LLVM_extract_bits (#97609)
Using DW_OP_deref can result in the debugger reading past the end of an object into inaccessible memory, causing an error. Instead use DW_OP_deref_size to make sure we don't read any bytes beyond what we need to.
1 parent fb5a38b commit 1cbddce

File tree

2 files changed

+35
-5
lines changed

2 files changed

+35
-5
lines changed

llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -552,9 +552,13 @@ bool DwarfExpression::addExpression(
552552
unsigned SizeInBits = Op->getArg(1);
553553
unsigned BitOffset = Op->getArg(0);
554554

555-
// If we have a memory location then dereference to get the value
556-
if (isMemoryLocation())
557-
emitOp(dwarf::DW_OP_deref);
555+
// If we have a memory location then dereference to get the value, though
556+
// we have to make sure we don't dereference any bytes past the end of the
557+
// object.
558+
if (isMemoryLocation()) {
559+
emitOp(dwarf::DW_OP_deref_size);
560+
emitUnsigned(alignTo(BitOffset + SizeInBits, 8) / 8);
561+
}
558562

559563
// Extract the bits by a shift left (to shift out the bits after what we
560564
// want to extract) followed by shift right (to shift the bits to position

llvm/test/DebugInfo/X86/DW_OP_LLVM_extract_bits.ll

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
; CHECK-LABEL: DW_TAG_subprogram
99
; CHECK: DW_AT_name ("test1")
1010
; CHECK: DW_TAG_variable
11-
; CHECK: DW_AT_location (DW_OP_fbreg -1, DW_OP_deref, DW_OP_constu 0x3d, DW_OP_shl, DW_OP_constu 0x3d, DW_OP_shr, DW_OP_stack_value)
11+
; CHECK: DW_AT_location (DW_OP_fbreg -1, DW_OP_deref_size 0x1, DW_OP_constu 0x3d, DW_OP_shl, DW_OP_constu 0x3d, DW_OP_shr, DW_OP_stack_value)
1212
; CHECK: DW_AT_name ("x")
1313
; CHECK: DW_TAG_variable
14-
; CHECK: DW_AT_location (DW_OP_fbreg -1, DW_OP_deref, DW_OP_constu 0x39, DW_OP_shl, DW_OP_constu 0x3c, DW_OP_shra, DW_OP_stack_value)
14+
; CHECK: DW_AT_location (DW_OP_fbreg -1, DW_OP_deref_size 0x1, DW_OP_constu 0x39, DW_OP_shl, DW_OP_constu 0x3c, DW_OP_shra, DW_OP_stack_value)
1515
; CHECK: DW_AT_name ("y")
1616

1717
define i32 @test1() !dbg !13 {
@@ -56,6 +56,27 @@ entry:
5656
ret i64 %0, !dbg !26
5757
}
5858

59+
; CHECK-LABEL: DW_TAG_subprogram
60+
; CHECK: DW_AT_name ("test4")
61+
; CHECK: DW_TAG_variable
62+
; CHECK: DW_AT_location (DW_OP_fbreg -4, DW_OP_deref_size 0x4, DW_OP_constu 0x20, DW_OP_shl, DW_OP_constu 0x3f, DW_OP_shr, DW_OP_stack_value)
63+
; CHECK: DW_AT_name ("x")
64+
; CHECK: DW_TAG_variable
65+
; CHECK: DW_AT_location (DW_OP_fbreg -4, DW_OP_deref_size 0x4, DW_OP_constu 0x20, DW_OP_shl, DW_OP_constu 0x21, DW_OP_shra, DW_OP_stack_value)
66+
; CHECK: DW_AT_name ("y")
67+
; CHECK: DW_TAG_variable
68+
; CHECK: DW_AT_location (DW_OP_fbreg -4, DW_OP_plus_uconst 0x3, DW_OP_deref_size 0x1, DW_OP_constu 0x38, DW_OP_shl, DW_OP_constu 0x39, DW_OP_shr, DW_OP_stack_value)
69+
; CHECK: DW_AT_name ("z")
70+
71+
define i32 @test4() !dbg !28 {
72+
entry:
73+
%0 = alloca i32, align 4
74+
tail call void @llvm.dbg.declare(metadata ptr %0, metadata !29, metadata !DIExpression(DW_OP_LLVM_extract_bits_zext, 31, 1)), !dbg !30
75+
tail call void @llvm.dbg.declare(metadata ptr %0, metadata !31, metadata !DIExpression(DW_OP_LLVM_extract_bits_sext, 1, 31)), !dbg !30
76+
tail call void @llvm.dbg.declare(metadata ptr %0, metadata !32, metadata !DIExpression(DW_OP_plus_uconst, 3, DW_OP_LLVM_extract_bits_zext, 1, 7)), !dbg !30
77+
ret i32 0, !dbg !30
78+
}
79+
5980
declare void @llvm.dbg.declare(metadata, metadata, metadata)
6081
declare void @llvm.dbg.value(metadata, metadata, metadata)
6182

@@ -90,3 +111,8 @@ declare void @llvm.dbg.value(metadata, metadata, metadata)
90111
!25 = !DILocalVariable(name: "x", scope: !24, file: !3, type: !9)
91112
!26 = !DILocation(line: 0, scope: !24)
92113
!27 = !DILocalVariable(name: "y", scope: !24, file: !3, type: !19)
114+
!28 = distinct !DISubprogram(name: "test4", linkageName: "test4", scope: !3, file: !3, type: !14, spFlags: DISPFlagDefinition, unit: !2)
115+
!29 = !DILocalVariable(name: "x", scope: !28, file: !3, type: !9)
116+
!30 = !DILocation(line: 0, scope: !28)
117+
!31 = !DILocalVariable(name: "y", scope: !28, file: !3, type: !19)
118+
!32 = !DILocalVariable(name: "z", scope: !28, file: !3, type: !9)

0 commit comments

Comments
 (0)