summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
diff options
context:
space:
mode:
authorAdrian Prantl <aprantl@apple.com>2016-12-09 20:43:40 +0000
committerAdrian Prantl <aprantl@apple.com>2016-12-09 20:43:40 +0000
commit8fafb8d37861378bfc7432891edd8c75a3589f71 (patch)
tree767b8dd7d993e271d72a45f9332b317f79a6ce20 /llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
parent34359cf0fa03ba36487390d7c2a98f6a014e3430 (diff)
downloadbcm5719-llvm-8fafb8d37861378bfc7432891edd8c75a3589f71.tar.gz
bcm5719-llvm-8fafb8d37861378bfc7432891edd8c75a3589f71.zip
Fix LLVM's use of DW_OP_bit_piece in DWARF expressions.
LLVM's use of DW_OP_bit_piece is incorrect and a based on a misunderstanding of the wording in the DWARF specification. The offset argument of DW_OP_bit_piece refers to the offset into the location that is on the top of the DWARF expression stack, and not an offset into the source variable. This has since also been clarified in the DWARF specification. This patch fixes all uses of DW_OP_bit_piece to emit the correct offset and simplifies the DwarfExpression class to semi-automaticaly emit empty DW_OP_pieces to adjust the offset of the source variable, thus simplifying the code using DwarfExpression. While this is an incompatible bugfix, in practice I don't expect this to be much of a problem since LLVM's old interpretation and the correct interpretation of DW_OP_bit_piece differ only when there are gaps in the fragmented locations of the described variables or if individual fragments are smaller than a byte. LLDB at least won't interpret locations with gaps in them because is has no way to present undefined bits in a variable, and there is a high probability that an old-form expression will be malformed when interpreted correctly, because the DW_OP_bit_piece offset will be outside of the location at the top of the stack. As a nice side-effect, this patch enables us to use a more efficient encoding for subregisters: In order to express a sub-register at a non-zero offset we now use a DW_OP_bit_piece instead of shifting the value into place manually. This patch also adds missing test coverage for code paths that weren't exercised before. <rdar://problem/29335809> Differential Revision: https://reviews.llvm.org/D27550 llvm-svn: 289266
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp20
1 files changed, 17 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index c615cea1d7c..024f6d27836 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -180,7 +180,9 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(
if (Expr) {
DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
+ DwarfExpr.addFragmentOffset(Expr);
DwarfExpr.AddExpression(Expr);
+ DwarfExpr.finalize();
}
}
@@ -498,8 +500,10 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
// If there is an expression, emit raw unsigned bytes.
+ DwarfExpr.addFragmentOffset(Expr);
DwarfExpr.AddUnsignedConstant(DVInsn->getOperand(0).getImm());
DwarfExpr.AddExpression(Expr);
+ DwarfExpr.finalize();
addBlock(*VariableDie, dwarf::DW_AT_location, Loc);
} else
addConstantValue(*VariableDie, DVInsn->getOperand(0), DV.getType());
@@ -524,11 +528,13 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();
int Offset = TFI->getFrameIndexReference(*Asm->MF, FI, FrameReg);
assert(Expr != DV.getExpression().end() && "Wrong number of expressions");
+ DwarfExpr.addFragmentOffset(*Expr);
DwarfExpr.AddMachineRegIndirect(*Asm->MF->getSubtarget().getRegisterInfo(),
FrameReg, Offset);
DwarfExpr.AddExpression(*Expr);
++Expr;
}
+ DwarfExpr.finalize();
addBlock(*VariableDie, dwarf::DW_AT_location, Loc);
return VariableDie;
@@ -727,16 +733,22 @@ void DwarfCompileUnit::addVariableAddress(const DbgVariable &DV, DIE &Die,
void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute,
const MachineLocation &Location) {
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
+ DIEDwarfExpression Expr(*Asm, *this, *Loc);
bool validReg;
if (Location.isReg())
- validReg = addRegisterFragment(*Loc, Location.getReg());
+ validReg = Expr.AddMachineReg(*Asm->MF->getSubtarget().getRegisterInfo(),
+ Location.getReg());
else
- validReg = addRegisterOffset(*Loc, Location.getReg(), Location.getOffset());
+ validReg =
+ Expr.AddMachineRegIndirect(*Asm->MF->getSubtarget().getRegisterInfo(),
+ Location.getReg(), Location.getOffset());
if (!validReg)
return;
+ Expr.finalize();
+
// Now attach the location information to the DIE.
addBlock(Die, Attribute, Loc);
}
@@ -750,9 +762,11 @@ void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die,
const MachineLocation &Location) {
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
- DIExpressionCursor ExprCursor(DV.getSingleExpression());
+ const DIExpression *Expr = DV.getSingleExpression();
+ DIExpressionCursor ExprCursor(Expr);
const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
auto Reg = Location.getReg();
+ DwarfExpr.addFragmentOffset(Expr);
bool ValidReg =
Location.getOffset()
? DwarfExpr.AddMachineRegIndirect(TRI, Reg, Location.getOffset())
OpenPOWER on IntegriCloud