diff options
author | Keno Fischer <kfischer@college.harvard.edu> | 2015-06-09 01:53:59 +0000 |
---|---|---|
committer | Keno Fischer <kfischer@college.harvard.edu> | 2015-06-09 01:53:59 +0000 |
commit | e34147ce2f6a633b942b832a932184ec69e11944 (patch) | |
tree | 5845f9f10ea60a386528ae100db9707a18b611a3 /llvm/lib | |
parent | 119046098a1b0a862b292c2937c5b625880a19ef (diff) | |
download | bcm5719-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.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp | 37 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h | 3 |
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. |