mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-23 17:29:19 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223428 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
af25a5d9b7
commit
74fb019dd0
@ -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);
|
||||
|
@ -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).
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user