Skip to content

Commit 20d136f

Browse files
Merge pull request #3665 from adrian-prantl/86069766
[DwarfDebug] Refuse to emit DW_OP_LLVM_arg values wider than 64 bits
2 parents 9057c80 + c7b1a38 commit 20d136f

File tree

4 files changed

+66
-22
lines changed

4 files changed

+66
-22
lines changed

llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -779,7 +779,7 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
779779
const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
780780

781781
auto AddEntry = [&](const DbgValueLocEntry &Entry,
782-
DIExpressionCursor &Cursor) {
782+
DIExpressionCursor &Cursor) {
783783
if (Entry.isLocation()) {
784784
if (!DwarfExpr.addMachineRegExpression(TRI, Cursor,
785785
Entry.getLoc().getReg()))
@@ -788,11 +788,19 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
788788
// If there is an expression, emit raw unsigned bytes.
789789
DwarfExpr.addUnsignedConstant(Entry.getInt());
790790
} else if (Entry.isConstantFP()) {
791+
// DwarfExpression does not support arguments wider than 64 bits
792+
// (see PR52584).
793+
// TODO: Consider chunking expressions containing overly wide
794+
// arguments into separate pointer-sized fragment expressions.
791795
APInt RawBytes = Entry.getConstantFP()->getValueAPF().bitcastToAPInt();
792-
DwarfExpr.addUnsignedConstant(RawBytes);
796+
if (RawBytes.getBitWidth() > 64)
797+
return false;
798+
DwarfExpr.addUnsignedConstant(RawBytes.getZExtValue());
793799
} else if (Entry.isConstantInt()) {
794800
APInt RawBytes = Entry.getConstantInt()->getValue();
795-
DwarfExpr.addUnsignedConstant(RawBytes);
801+
if (RawBytes.getBitWidth() > 64)
802+
return false;
803+
DwarfExpr.addUnsignedConstant(RawBytes.getZExtValue());
796804
} else if (Entry.isTargetIndexLocation()) {
797805
TargetIndexLocation Loc = Entry.getTargetIndexLocation();
798806
// TODO TargetIndexLocation is a target-independent. Currently only the
@@ -805,11 +813,12 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
805813
return true;
806814
};
807815

808-
DwarfExpr.addExpression(
809-
std::move(Cursor),
810-
[&](unsigned Idx, DIExpressionCursor &Cursor) -> bool {
811-
return AddEntry(DVal->getLocEntries()[Idx], Cursor);
812-
});
816+
if (!DwarfExpr.addExpression(
817+
std::move(Cursor),
818+
[&](unsigned Idx, DIExpressionCursor &Cursor) -> bool {
819+
return AddEntry(DVal->getLocEntries()[Idx], Cursor);
820+
}))
821+
return VariableDie;
813822

814823
// Now attach the location information to the DIE.
815824
addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());

llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -463,15 +463,14 @@ static bool isMemoryLocation(DIExpressionCursor ExprCursor) {
463463
return true;
464464
}
465465

466-
void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor,
467-
unsigned FragmentOffsetInBits) {
466+
void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor) {
468467
addExpression(std::move(ExprCursor),
469468
[](unsigned Idx, DIExpressionCursor &Cursor) -> bool {
470469
llvm_unreachable("unhandled opcode found in expression");
471470
});
472471
}
473472

474-
void DwarfExpression::addExpression(
473+
bool DwarfExpression::addExpression(
475474
DIExpressionCursor &&ExprCursor,
476475
llvm::function_ref<bool(unsigned, DIExpressionCursor &)> InsertArg) {
477476
// Entry values can currently only cover the initial register location,
@@ -496,7 +495,7 @@ void DwarfExpression::addExpression(
496495
case dwarf::DW_OP_LLVM_arg:
497496
if (!InsertArg(Op->getArg(0), ExprCursor)) {
498497
LocationKind = Unknown;
499-
return;
498+
return false;
500499
}
501500
break;
502501
case dwarf::DW_OP_LLVM_fragment: {
@@ -527,7 +526,7 @@ void DwarfExpression::addExpression(
527526
setSubRegisterPiece(0, 0);
528527
// Reset the location description kind.
529528
LocationKind = Unknown;
530-
return;
529+
return true;
531530
}
532531
case dwarf::DW_OP_plus_uconst:
533532
assert(!isRegisterLocation());
@@ -630,6 +629,8 @@ void DwarfExpression::addExpression(
630629
if (isImplicitLocation() && !isParameterValue())
631630
// Turn this into an implicit location description.
632631
addStackValue();
632+
633+
return true;
633634
}
634635

635636
/// add masking operations to stencil out a subregister.

llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -340,16 +340,17 @@ class DwarfExpression {
340340
/// create one if necessary.
341341
unsigned getOrCreateBaseType(unsigned BitSize, dwarf::TypeKind Encoding);
342342

343+
/// Emit all remaining operations in the DIExpressionCursor. The
344+
/// cursor must not contain any DW_OP_LLVM_arg operations.
345+
void addExpression(DIExpressionCursor &&Expr);
346+
343347
/// Emit all remaining operations in the DIExpressionCursor.
344-
///
345-
/// \param FragmentOffsetInBits If this is one fragment out of multiple
346-
/// locations, this is the offset of the
347-
/// fragment inside the entire variable.
348-
void addExpression(DIExpressionCursor &&Expr,
349-
unsigned FragmentOffsetInBits = 0);
350-
void
351-
addExpression(DIExpressionCursor &&Expr,
352-
llvm::function_ref<bool(unsigned, DIExpressionCursor &)> InsertArg);
348+
/// DW_OP_LLVM_arg operations are resolved by calling (\p InsertArg).
349+
//
350+
/// \return false if any call to (\p InsertArg) returns false.
351+
bool addExpression(
352+
DIExpressionCursor &&Expr,
353+
llvm::function_ref<bool(unsigned, DIExpressionCursor &)> InsertArg);
353354

354355
/// If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to
355356
/// the fragment described by \c Expr.

llvm/test/DebugInfo/X86/pr52584.ll

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
; RUN: llc -mtriple=x86_64-unknown-linux-gnu -filetype=obj -o - %s \
2+
; RUN: | llvm-dwarfdump - \
3+
; RUN: | FileCheck %s
4+
5+
; CHECK: DW_TAG_variable
6+
; CHECK-NOT: DW_AT_location
7+
; CHECK-NEXT: DW_AT_name ("arr")
8+
; CHECK-NOT: DW_AT_location
9+
; CHECK: DW_TAG
10+
define dso_local void @test() !dbg !4 {
11+
entry:
12+
call void @llvm.dbg.value(metadata !DIArgList(i128 0), metadata !7, metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 127)), !dbg !12
13+
ret void, !dbg !12
14+
}
15+
16+
declare void @llvm.dbg.value(metadata, metadata, metadata)
17+
18+
!llvm.dbg.cu = !{!0}
19+
!llvm.module.flags = !{!2, !3}
20+
21+
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
22+
!1 = !DIFile(filename: "test.c", directory: "")
23+
!2 = !{i32 7, !"Dwarf Version", i32 4}
24+
!3 = !{i32 2, !"Debug Info Version", i32 3}
25+
!4 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 1, type: !5, unit: !0)
26+
!5 = !DISubroutineType(types: !6)
27+
!6 = !{null}
28+
!7 = !DILocalVariable(name: "arr", scope: !4, file: !1, line: 1, type: !8)
29+
!8 = !DICompositeType(tag: DW_TAG_array_type, baseType: !9, size: 128, elements: !10)
30+
!9 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
31+
!10 = !{!11}
32+
!11 = !DISubrange(count: 16)
33+
!12 = !DILocation(line: 1, column: 1, scope: !4)

0 commit comments

Comments
 (0)