From ab255fcd09a6fac10e597fbd8f92fd70dd321a6d Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Fri, 5 Dec 2014 01:02:46 +0000 Subject: [PATCH] Cleanup: Calls to getDwarfRegNum() may actually fail, if there is no DWARF register number mapping, or if the register was a virtual register that was never materialized. Previously, we would just emit a bogus location, after this patch we don't emit a location at all by doing an early exit. After my bugfix in r223401 today, this doesn't actually happen on any target that I tested this with, but it's still preferable to make the possibility of a failure explicit. llvm-svn: 223428 --- llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 33 ++++++++++++++---------- llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 26 ++++++++++++------- llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h | 12 ++++++--- 3 files changed, 44 insertions(+), 27 deletions(-) diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 38100bc..6901d22 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -746,14 +746,17 @@ void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute, bool Indirect) { DIELoc *Loc = new (DIEValueAllocator) DIELoc(); + bool validReg; if (Location.isReg() && !Indirect) - addRegisterOpPiece(*Loc, Location.getReg()); - else { - addRegisterOffset(*Loc, Location.getReg(), Location.getOffset()); - if (Indirect && !Location.isReg()) { - addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); - } - } + validReg = addRegisterOpPiece(*Loc, Location.getReg()); + else + validReg = addRegisterOffset(*Loc, Location.getReg(), Location.getOffset()); + + if (!validReg) + return; + + if (!Location.isReg() && Indirect) + addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); // Now attach the location information to the DIE. addBlock(Die, Attribute, Loc); @@ -769,25 +772,29 @@ void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die, DIELoc *Loc = new (DIEValueAllocator) DIELoc(); unsigned N = DV.getNumAddrElements(); unsigned i = 0; + bool validReg; if (Location.isReg()) { if (N >= 2 && DV.getAddrElement(0) == dwarf::DW_OP_plus) { assert(!DV.getVariable().isIndirect() && "double indirection not handled"); // If first address element is OpPlus then emit // DW_OP_breg + Offset instead of DW_OP_reg + Offset. - addRegisterOffset(*Loc, Location.getReg(), DV.getAddrElement(1)); + validReg = addRegisterOffset(*Loc, Location.getReg(), DV.getAddrElement(1)); i = 2; } else if (N >= 2 && DV.getAddrElement(0) == dwarf::DW_OP_deref) { assert(!DV.getVariable().isIndirect() && "double indirection not handled"); - addRegisterOpPiece(*Loc, Location.getReg(), - DV.getExpression().getPieceSize(), - DV.getExpression().getPieceOffset()); + validReg = addRegisterOpPiece(*Loc, Location.getReg(), + DV.getExpression().getPieceSize(), + DV.getExpression().getPieceOffset()); i = 3; } else - addRegisterOpPiece(*Loc, Location.getReg()); + validReg = addRegisterOpPiece(*Loc, Location.getReg()); } else - addRegisterOffset(*Loc, Location.getReg(), Location.getOffset()); + validReg = addRegisterOffset(*Loc, Location.getReg(), Location.getOffset()); + + if (!validReg) + return; for (; i < N; ++i) { uint64_t Element = DV.getAddrElement(i); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index 919d9d2..9394eaf 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -401,7 +401,7 @@ void DwarfUnit::addSourceLine(DIE &Die, DINameSpace NS) { /// addRegisterOp - Add register operand. // FIXME: Ideally, this would share the implementation with // AsmPrinter::EmitDwarfRegOpPiece. -void DwarfUnit::addRegisterOpPiece(DIELoc &TheDie, unsigned Reg, +bool DwarfUnit::addRegisterOpPiece(DIELoc &TheDie, unsigned Reg, unsigned SizeInBits, unsigned OffsetInBits) { const TargetRegisterInfo *RI = Asm->TM.getSubtargetImpl()->getRegisterInfo(); int DWReg = RI->getDwarfRegNum(Reg, false); @@ -416,11 +416,8 @@ void DwarfUnit::addRegisterOpPiece(DIELoc &TheDie, unsigned Reg, Idx = RI->getSubRegIndex(*SR, Reg); } - if (DWReg < 0) { - DEBUG(dbgs() << "Invalid Dwarf register number.\n"); - addUInt(TheDie, dwarf::DW_FORM_data1, dwarf::DW_OP_nop); - return; - } + if (DWReg < 0) + return false; // Emit register. if (DWReg < 32) @@ -460,13 +457,17 @@ void DwarfUnit::addRegisterOpPiece(DIELoc &TheDie, unsigned Reg, addUInt(TheDie, dwarf::DW_FORM_data1, PieceSizeInBits/SizeOfByte); } } + return true; } /// addRegisterOffset - Add register offset. -void DwarfUnit::addRegisterOffset(DIELoc &TheDie, unsigned Reg, +bool DwarfUnit::addRegisterOffset(DIELoc &TheDie, unsigned Reg, int64_t Offset) { const TargetRegisterInfo *RI = Asm->TM.getSubtargetImpl()->getRegisterInfo(); - unsigned DWReg = RI->getDwarfRegNum(Reg, false); + int DWReg = RI->getDwarfRegNum(Reg, false); + if (DWReg < 0) + return false; + const TargetRegisterInfo *TRI = Asm->TM.getSubtargetImpl()->getRegisterInfo(); if (Reg == TRI->getFrameRegister(*Asm->MF)) // If variable offset is based in frame register then use fbreg. @@ -478,6 +479,7 @@ void DwarfUnit::addRegisterOffset(DIELoc &TheDie, unsigned Reg, addUInt(TheDie, dwarf::DW_FORM_udata, DWReg); } addSInt(TheDie, dwarf::DW_FORM_sdata, Offset); + return true; } /* Byref variables, in Blocks, are declared by the programmer as "SomeType @@ -581,10 +583,14 @@ void DwarfUnit::addBlockByrefAddress(const DbgVariable &DV, DIE &Die, // variable's location. DIELoc *Loc = new (DIEValueAllocator) DIELoc(); + bool validReg; if (Location.isReg()) - addRegisterOpPiece(*Loc, Location.getReg()); + validReg = addRegisterOpPiece(*Loc, Location.getReg()); else - addRegisterOffset(*Loc, Location.getReg(), Location.getOffset()); + validReg = addRegisterOffset(*Loc, Location.getReg(), Location.getOffset()); + + if (!validReg) + return; // If we started with a pointer to the __Block_byref... struct, then // the first thing we need to do is dereference the pointer (DW_OP_deref). diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h index f40c937..80b2abc 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h @@ -253,12 +253,16 @@ public: /// addTemplateParams - Add template parameters in buffer. void addTemplateParams(DIE &Buffer, DIArray TParams); - /// addRegisterOp - Add register operand. - void addRegisterOpPiece(DIELoc &TheDie, unsigned Reg, + /// \brief Add register operand. + /// \returns false if the register does not exist, e.g., because it was never + /// materialized. + bool addRegisterOpPiece(DIELoc &TheDie, unsigned Reg, unsigned SizeInBits = 0, unsigned OffsetInBits = 0); - /// addRegisterOffset - Add register offset. - void addRegisterOffset(DIELoc &TheDie, unsigned Reg, int64_t Offset); + /// \brief Add register offset. + /// \returns false if the register does not exist, e.g., because it was never + /// materialized. + bool addRegisterOffset(DIELoc &TheDie, unsigned Reg, int64_t Offset); // FIXME: Should be reformulated in terms of addComplexAddress. /// addBlockByrefAddress - Start with the address based on the location -- 2.7.4