aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2022-01-29 21:28:12 +0000
committerDimitry Andric <dim@FreeBSD.org>2022-01-29 21:28:24 +0000
commit9738bc28abe85f7890d92c007a8e5b1d6eeebb53 (patch)
treebb8a25078ad0154119724ec58b09e8a219052421
parent79afae3b3f245ffa79726ae097cc843628ae9d92 (diff)
downloadsrc-9738bc28abe85f7890d92c007a8e5b1d6eeebb53.tar.gz
src-9738bc28abe85f7890d92c007a8e5b1d6eeebb53.zip
Apply llvm fix for assertion failure compiling recent libc++
Merge commit c7c84b90879f from llvm git (by Adrian Prantl): [DwarfDebug] Refuse to emit DW_OP_LLVM_arg values wider than 64 bits DwarfExpression::addUnsignedConstant(const APInt &Value) only supports wider-than-64-bit values when it is used to emit a top-level DWARF expression representing the location of a variable. Before this change, it was possible to call addUnsignedConstant on >64 bit values within a subexpression when substituting DW_OP_LLVM_arg values. This can trigger an assertion failure (e.g. PR52584, PR52333) when it happens in a fragment (DW_OP_LLVM_fragment) expression, as addUnsignedConstant on >64 bit values splits the constant into separate DW_OP_pieces, which modifies DwarfExpression::OffsetInBits. This change papers over the assertion errors by bailing on overly wide DW_OP_LLVM_arg values. A more comprehensive fix might be to be to split wide values into pointer-sized fragments. [0] https://github.com/llvm/llvm-project/blob/e71fa03/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp#L799-L805 Patch by Ricky Zhou! Differential Revision: https://reviews.llvm.org/D115343 MFC after: 3 days
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp25
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp11
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h19
3 files changed, 33 insertions, 22 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 7edc44c48bbd..a3bf4be09fbe 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -779,7 +779,7 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
auto AddEntry = [&](const DbgValueLocEntry &Entry,
- DIExpressionCursor &Cursor) {
+ DIExpressionCursor &Cursor) {
if (Entry.isLocation()) {
if (!DwarfExpr.addMachineRegExpression(TRI, Cursor,
Entry.getLoc().getReg()))
@@ -788,11 +788,19 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
// If there is an expression, emit raw unsigned bytes.
DwarfExpr.addUnsignedConstant(Entry.getInt());
} else if (Entry.isConstantFP()) {
+ // DwarfExpression does not support arguments wider than 64 bits
+ // (see PR52584).
+ // TODO: Consider chunking expressions containing overly wide
+ // arguments into separate pointer-sized fragment expressions.
APInt RawBytes = Entry.getConstantFP()->getValueAPF().bitcastToAPInt();
- DwarfExpr.addUnsignedConstant(RawBytes);
+ if (RawBytes.getBitWidth() > 64)
+ return false;
+ DwarfExpr.addUnsignedConstant(RawBytes.getZExtValue());
} else if (Entry.isConstantInt()) {
APInt RawBytes = Entry.getConstantInt()->getValue();
- DwarfExpr.addUnsignedConstant(RawBytes);
+ if (RawBytes.getBitWidth() > 64)
+ return false;
+ DwarfExpr.addUnsignedConstant(RawBytes.getZExtValue());
} else if (Entry.isTargetIndexLocation()) {
TargetIndexLocation Loc = Entry.getTargetIndexLocation();
// TODO TargetIndexLocation is a target-independent. Currently only the
@@ -805,11 +813,12 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
return true;
};
- DwarfExpr.addExpression(
- std::move(Cursor),
- [&](unsigned Idx, DIExpressionCursor &Cursor) -> bool {
- return AddEntry(DVal->getLocEntries()[Idx], Cursor);
- });
+ if (!DwarfExpr.addExpression(
+ std::move(Cursor),
+ [&](unsigned Idx, DIExpressionCursor &Cursor) -> bool {
+ return AddEntry(DVal->getLocEntries()[Idx], Cursor);
+ }))
+ return VariableDie;
// Now attach the location information to the DIE.
addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
index 6409c39e7849..37407c98e75f 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
@@ -463,15 +463,14 @@ static bool isMemoryLocation(DIExpressionCursor ExprCursor) {
return true;
}
-void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor,
- unsigned FragmentOffsetInBits) {
+void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor) {
addExpression(std::move(ExprCursor),
[](unsigned Idx, DIExpressionCursor &Cursor) -> bool {
llvm_unreachable("unhandled opcode found in expression");
});
}
-void DwarfExpression::addExpression(
+bool DwarfExpression::addExpression(
DIExpressionCursor &&ExprCursor,
llvm::function_ref<bool(unsigned, DIExpressionCursor &)> InsertArg) {
// Entry values can currently only cover the initial register location,
@@ -496,7 +495,7 @@ void DwarfExpression::addExpression(
case dwarf::DW_OP_LLVM_arg:
if (!InsertArg(Op->getArg(0), ExprCursor)) {
LocationKind = Unknown;
- return;
+ return false;
}
break;
case dwarf::DW_OP_LLVM_fragment: {
@@ -527,7 +526,7 @@ void DwarfExpression::addExpression(
setSubRegisterPiece(0, 0);
// Reset the location description kind.
LocationKind = Unknown;
- return;
+ return true;
}
case dwarf::DW_OP_plus_uconst:
assert(!isRegisterLocation());
@@ -630,6 +629,8 @@ void DwarfExpression::addExpression(
if (isImplicitLocation() && !isParameterValue())
// Turn this into an implicit location description.
addStackValue();
+
+ return true;
}
/// add masking operations to stencil out a subregister.
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
index 513e9072309e..e605fe2f7d39 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
@@ -340,16 +340,17 @@ public:
/// create one if necessary.
unsigned getOrCreateBaseType(unsigned BitSize, dwarf::TypeKind Encoding);
+ /// Emit all remaining operations in the DIExpressionCursor. The
+ /// cursor must not contain any DW_OP_LLVM_arg operations.
+ void addExpression(DIExpressionCursor &&Expr);
+
/// Emit all remaining operations in the DIExpressionCursor.
- ///
- /// \param FragmentOffsetInBits If this is one fragment out of multiple
- /// locations, this is the offset of the
- /// fragment inside the entire variable.
- void addExpression(DIExpressionCursor &&Expr,
- unsigned FragmentOffsetInBits = 0);
- void
- addExpression(DIExpressionCursor &&Expr,
- llvm::function_ref<bool(unsigned, DIExpressionCursor &)> InsertArg);
+ /// DW_OP_LLVM_arg operations are resolved by calling (\p InsertArg).
+ //
+ /// \return false if any call to (\p InsertArg) returns false.
+ bool addExpression(
+ DIExpressionCursor &&Expr,
+ llvm::function_ref<bool(unsigned, DIExpressionCursor &)> InsertArg);
/// If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to
/// the fragment described by \c Expr.