summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorKeno Fischer <kfischer@college.harvard.edu>2015-06-09 01:53:59 +0000
committerKeno Fischer <kfischer@college.harvard.edu>2015-06-09 01:53:59 +0000
commite34147ce2f6a633b942b832a932184ec69e11944 (patch)
tree5845f9f10ea60a386528ae100db9707a18b611a3 /llvm/lib
parent119046098a1b0a862b292c2937c5b625880a19ef (diff)
downloadbcm5719-llvm-e34147ce2f6a633b942b832a932184ec69e11944.tar.gz
bcm5719-llvm-e34147ce2f6a633b942b832a932184ec69e11944.zip
[DWARF] Fix a few corner cases in expression emission
Summary: I noticed an object file with `DW_OP_reg4 DW_OP_breg4 0` as a DWARF expression, which I traced to a missing break (and `++I`) in this code snippet. While I was at it, I also added support for a few other corner cases along the same lines that I could think of. Test Plan: Hand-crafted test case to exercises these cases is included. Reviewers: echristo, dblaikie, aprantl Reviewed By: aprantl Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D10302 llvm-svn: 239380
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp2
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp37
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h3
3 files changed, 33 insertions, 9 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index e891ab9896b..3f6665bd576 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -1562,6 +1562,8 @@ void DwarfDebug::emitDebugLoc() {
Asm->OutStreamer->EmitLabel(List.Label);
const DwarfCompileUnit *CU = List.CU;
for (const auto &Entry : DebugLocs.getEntries(List)) {
+ if (Entry.BeginSym == Entry.EndSym)
+ continue;
// Set up the range. This range is relative to the entry point of the
// compile unit. This is a hard coded 0 for low_pc when we're emitting
// ranges, or the DW_AT_low_pc on the compile unit otherwise.
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
index a2799b8d630..d56982712d5 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
@@ -65,6 +65,11 @@ void DwarfExpression::AddShr(unsigned ShiftBy) {
EmitOp(dwarf::DW_OP_shr);
}
+void DwarfExpression::AddOpStackValue() {
+ if (DwarfVersion >= 4)
+ EmitOp(dwarf::DW_OP_stack_value);
+}
+
bool DwarfExpression::AddMachineRegIndirect(unsigned MachineReg, int Offset) {
if (isFrameRegister(MachineReg)) {
// If variable offset is based in frame register then use fbreg.
@@ -172,16 +177,14 @@ void DwarfExpression::AddSignedConstant(int Value) {
// value, so the producers and consumers started to rely on heuristics
// to disambiguate the value vs. location status of the expression.
// See PR21176 for more details.
- if (DwarfVersion >= 4)
- EmitOp(dwarf::DW_OP_stack_value);
+ AddOpStackValue();
}
void DwarfExpression::AddUnsignedConstant(unsigned Value) {
EmitOp(dwarf::DW_OP_constu);
EmitUnsigned(Value);
// cf. comment in DwarfExpression::AddSignedConstant().
- if (DwarfVersion >= 4)
- EmitOp(dwarf::DW_OP_stack_value);
+ AddOpStackValue();
}
static unsigned getOffsetOrZero(unsigned OffsetInBits,
@@ -212,15 +215,30 @@ bool DwarfExpression::AddMachineRegExpression(const DIExpression *Expr,
getOffsetOrZero(OffsetInBits, PieceOffsetInBits));
}
case dwarf::DW_OP_plus: {
- // [DW_OP_reg,Offset,DW_OP_plus,DW_OP_deref] --> [DW_OP_breg,Offset].
auto N = I.getNext();
+ unsigned Offset = I->getArg(0);
+ // First combine all DW_OP_plus until we hit either a DW_OP_deref or a
+ // DW_OP_bit_piece
+ while (N != E && N->getOp() == dwarf::DW_OP_plus) {
+ Offset += N->getArg(0);
+ ++I;
+ N = I.getNext();
+ }
if (N != E && N->getOp() == dwarf::DW_OP_deref) {
- unsigned Offset = I->getArg(0);
+ // [DW_OP_reg,Offset,DW_OP_plus,DW_OP_deref] --> [DW_OP_breg,Offset].
ValidReg = AddMachineRegIndirect(MachineReg, Offset);
std::advance(I, 2);
- break;
- } else
- ValidReg = AddMachineRegPiece(MachineReg);
+ } else {
+ assert ((N == E) || (N->getOp() == dwarf::DW_OP_bit_piece));
+ if (Offset == 0) {
+ ValidReg = AddMachineRegPiece(MachineReg);
+ } else {
+ ValidReg = AddMachineRegIndirect(MachineReg, Offset);
+ AddOpStackValue();
+ }
+ ++I;
+ }
+ break;
}
case dwarf::DW_OP_deref: {
// [DW_OP_reg,DW_OP_deref] --> [DW_OP_breg].
@@ -237,6 +255,7 @@ bool DwarfExpression::AddMachineRegExpression(const DIExpression *Expr,
// Emit remaining elements of the expression.
AddExpression(I, E, PieceOffsetInBits);
+
return true;
}
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
index 78ec937a6b6..f6249fff425 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
@@ -83,6 +83,9 @@ public:
bool AddMachineRegPiece(unsigned MachineReg, unsigned PieceSizeInBits = 0,
unsigned PieceOffsetInBits = 0);
+ /// Emit a DW_OP_stack_value
+ void AddOpStackValue();
+
/// Emit a signed constant.
void AddSignedConstant(int Value);
/// Emit an unsigned constant.
OpenPOWER on IntegriCloud