mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2026-04-21 08:17:40 +00:00
Add a DIELoc class to cover the DW_FORM_exprloc set of expressions
alongside DIEBlock and replace uses accordingly. Use DW_FORM_exprloc in DWARF4 and later code. Update testcases. Adding a DIELoc instead of using extra forms inside DIEBlock so that we can keep location expressions separate from other uses. No direct use at the moment, however, it's not a lot of code and using a separately named class keeps it somewhat more obvious what's going on in various locations. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@201481 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -57,13 +57,14 @@ DwarfCompileUnit::DwarfCompileUnit(unsigned UID, DIE *D, DICompileUnit Node,
|
||||
|
||||
DwarfTypeUnit::DwarfTypeUnit(unsigned UID, DIE *D, DwarfCompileUnit &CU,
|
||||
AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU)
|
||||
: DwarfUnit(UID, D, CU.getCUNode(), A, DW, DWU), CU(CU) {
|
||||
}
|
||||
: DwarfUnit(UID, D, CU.getCUNode(), A, DW, DWU), CU(CU) {}
|
||||
|
||||
/// ~Unit - Destructor for compile unit.
|
||||
DwarfUnit::~DwarfUnit() {
|
||||
for (unsigned j = 0, M = DIEBlocks.size(); j < M; ++j)
|
||||
DIEBlocks[j]->~DIEBlock();
|
||||
for (unsigned j = 0, M = DIELocs.size(); j < M; ++j)
|
||||
DIELocs[j]->~DIELoc();
|
||||
}
|
||||
|
||||
/// createDIEEntry - Creates a new DIEEntry to be a proxy for a debug
|
||||
@@ -171,7 +172,7 @@ void DwarfUnit::addUInt(DIE *Die, dwarf::Attribute Attribute,
|
||||
Die->addValue(Attribute, *Form, Value);
|
||||
}
|
||||
|
||||
void DwarfUnit::addUInt(DIEBlock *Block, dwarf::Form Form, uint64_t Integer) {
|
||||
void DwarfUnit::addUInt(DIE *Block, dwarf::Form Form, uint64_t Integer) {
|
||||
addUInt(Block, (dwarf::Attribute)0, Form, Integer);
|
||||
}
|
||||
|
||||
@@ -185,7 +186,7 @@ void DwarfUnit::addSInt(DIE *Die, dwarf::Attribute Attribute,
|
||||
Die->addValue(Attribute, *Form, Value);
|
||||
}
|
||||
|
||||
void DwarfUnit::addSInt(DIEBlock *Die, Optional<dwarf::Form> Form,
|
||||
void DwarfUnit::addSInt(DIELoc *Die, Optional<dwarf::Form> Form,
|
||||
int64_t Integer) {
|
||||
addSInt(Die, (dwarf::Attribute)0, Form, Integer);
|
||||
}
|
||||
@@ -225,7 +226,7 @@ void DwarfUnit::addLocalString(DIE *Die, dwarf::Attribute Attribute,
|
||||
|
||||
/// addExpr - Add a Dwarf expression attribute data and value.
|
||||
///
|
||||
void DwarfUnit::addExpr(DIEBlock *Die, dwarf::Form Form, const MCExpr *Expr) {
|
||||
void DwarfUnit::addExpr(DIELoc *Die, dwarf::Form Form, const MCExpr *Expr) {
|
||||
DIEValue *Value = new (DIEValueAllocator) DIEExpr(Expr);
|
||||
Die->addValue((dwarf::Attribute)0, Form, Value);
|
||||
}
|
||||
@@ -238,8 +239,7 @@ void DwarfUnit::addLabel(DIE *Die, dwarf::Attribute Attribute, dwarf::Form Form,
|
||||
Die->addValue(Attribute, Form, Value);
|
||||
}
|
||||
|
||||
void DwarfUnit::addLabel(DIEBlock *Die, dwarf::Form Form,
|
||||
const MCSymbol *Label) {
|
||||
void DwarfUnit::addLabel(DIELoc *Die, dwarf::Form Form, const MCSymbol *Label) {
|
||||
addLabel(Die, (dwarf::Attribute)0, Form, Label);
|
||||
}
|
||||
|
||||
@@ -289,7 +289,7 @@ void DwarfCompileUnit::addLabelAddress(DIE *Die, dwarf::Attribute Attribute,
|
||||
/// addOpAddress - Add a dwarf op address data and value using the
|
||||
/// form given and an op of either DW_FORM_addr or DW_FORM_GNU_addr_index.
|
||||
///
|
||||
void DwarfUnit::addOpAddress(DIEBlock *Die, const MCSymbol *Sym) {
|
||||
void DwarfUnit::addOpAddress(DIELoc *Die, const MCSymbol *Sym) {
|
||||
if (!DD->useSplitDwarf()) {
|
||||
addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
|
||||
addLabel(Die, dwarf::DW_FORM_udata, Sym);
|
||||
@@ -347,6 +347,12 @@ DIE *DwarfUnit::createAndAddDIE(unsigned Tag, DIE &Parent, DIDescriptor N) {
|
||||
|
||||
/// addBlock - Add block data.
|
||||
///
|
||||
void DwarfUnit::addBlock(DIE *Die, dwarf::Attribute Attribute, DIELoc *Loc) {
|
||||
Loc->ComputeSize(Asm);
|
||||
DIELocs.push_back(Loc); // Memoize so we can call the destructor later on.
|
||||
Die->addValue(Attribute, Loc->BestForm(DD->getDwarfVersion()), Loc);
|
||||
}
|
||||
|
||||
void DwarfUnit::addBlock(DIE *Die, dwarf::Attribute Attribute,
|
||||
DIEBlock *Block) {
|
||||
Block->ComputeSize(Asm);
|
||||
@@ -433,7 +439,7 @@ void DwarfUnit::addVariableAddress(const DbgVariable &DV, DIE *Die,
|
||||
}
|
||||
|
||||
/// addRegisterOp - Add register operand.
|
||||
void DwarfUnit::addRegisterOp(DIEBlock *TheDie, unsigned Reg) {
|
||||
void DwarfUnit::addRegisterOp(DIELoc *TheDie, unsigned Reg) {
|
||||
const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
|
||||
int DWReg = RI->getDwarfRegNum(Reg, false);
|
||||
bool isSubRegister = DWReg < 0;
|
||||
@@ -478,7 +484,7 @@ void DwarfUnit::addRegisterOp(DIEBlock *TheDie, unsigned Reg) {
|
||||
}
|
||||
|
||||
/// addRegisterOffset - Add register offset.
|
||||
void DwarfUnit::addRegisterOffset(DIEBlock *TheDie, unsigned Reg,
|
||||
void DwarfUnit::addRegisterOffset(DIELoc *TheDie, unsigned Reg,
|
||||
int64_t Offset) {
|
||||
const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
|
||||
unsigned DWReg = RI->getDwarfRegNum(Reg, false);
|
||||
@@ -499,19 +505,19 @@ void DwarfUnit::addRegisterOffset(DIEBlock *TheDie, unsigned Reg,
|
||||
/// provided.
|
||||
void DwarfUnit::addAddress(DIE *Die, dwarf::Attribute Attribute,
|
||||
const MachineLocation &Location, bool Indirect) {
|
||||
DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
|
||||
DIELoc *Loc = new (DIEValueAllocator) DIELoc();
|
||||
|
||||
if (Location.isReg() && !Indirect)
|
||||
addRegisterOp(Block, Location.getReg());
|
||||
addRegisterOp(Loc, Location.getReg());
|
||||
else {
|
||||
addRegisterOffset(Block, Location.getReg(), Location.getOffset());
|
||||
addRegisterOffset(Loc, Location.getReg(), Location.getOffset());
|
||||
if (Indirect && !Location.isReg()) {
|
||||
addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
|
||||
addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
|
||||
}
|
||||
}
|
||||
|
||||
// Now attach the location information to the DIE.
|
||||
addBlock(Die, Attribute, Block);
|
||||
addBlock(Die, Attribute, Loc);
|
||||
}
|
||||
|
||||
/// addComplexAddress - Start with the address based on the location provided,
|
||||
@@ -522,34 +528,34 @@ void DwarfUnit::addAddress(DIE *Die, dwarf::Attribute Attribute,
|
||||
void DwarfUnit::addComplexAddress(const DbgVariable &DV, DIE *Die,
|
||||
dwarf::Attribute Attribute,
|
||||
const MachineLocation &Location) {
|
||||
DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
|
||||
DIELoc *Loc = new (DIEValueAllocator) DIELoc();
|
||||
unsigned N = DV.getNumAddrElements();
|
||||
unsigned i = 0;
|
||||
if (Location.isReg()) {
|
||||
if (N >= 2 && DV.getAddrElement(0) == DIBuilder::OpPlus) {
|
||||
// If first address element is OpPlus then emit
|
||||
// DW_OP_breg + Offset instead of DW_OP_reg + Offset.
|
||||
addRegisterOffset(Block, Location.getReg(), DV.getAddrElement(1));
|
||||
addRegisterOffset(Loc, Location.getReg(), DV.getAddrElement(1));
|
||||
i = 2;
|
||||
} else
|
||||
addRegisterOp(Block, Location.getReg());
|
||||
addRegisterOp(Loc, Location.getReg());
|
||||
} else
|
||||
addRegisterOffset(Block, Location.getReg(), Location.getOffset());
|
||||
addRegisterOffset(Loc, Location.getReg(), Location.getOffset());
|
||||
|
||||
for (; i < N; ++i) {
|
||||
uint64_t Element = DV.getAddrElement(i);
|
||||
if (Element == DIBuilder::OpPlus) {
|
||||
addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
|
||||
addUInt(Block, dwarf::DW_FORM_udata, DV.getAddrElement(++i));
|
||||
addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
|
||||
addUInt(Loc, dwarf::DW_FORM_udata, DV.getAddrElement(++i));
|
||||
} else if (Element == DIBuilder::OpDeref) {
|
||||
if (!Location.isReg())
|
||||
addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
|
||||
addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
|
||||
} else
|
||||
llvm_unreachable("unknown DIBuilder Opcode");
|
||||
}
|
||||
|
||||
// Now attach the location information to the DIE.
|
||||
addBlock(Die, Attribute, Block);
|
||||
addBlock(Die, Attribute, Loc);
|
||||
}
|
||||
|
||||
/* Byref variables, in Blocks, are declared by the programmer as "SomeType
|
||||
@@ -651,40 +657,40 @@ void DwarfUnit::addBlockByrefAddress(const DbgVariable &DV, DIE *Die,
|
||||
|
||||
// Decode the original location, and use that as the start of the byref
|
||||
// variable's location.
|
||||
DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
|
||||
DIELoc *Loc = new (DIEValueAllocator) DIELoc();
|
||||
|
||||
if (Location.isReg())
|
||||
addRegisterOp(Block, Location.getReg());
|
||||
addRegisterOp(Loc, Location.getReg());
|
||||
else
|
||||
addRegisterOffset(Block, Location.getReg(), Location.getOffset());
|
||||
addRegisterOffset(Loc, Location.getReg(), Location.getOffset());
|
||||
|
||||
// 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).
|
||||
if (isPointer)
|
||||
addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
|
||||
addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
|
||||
|
||||
// Next add the offset for the '__forwarding' field:
|
||||
// DW_OP_plus_uconst ForwardingFieldOffset. Note there's no point in
|
||||
// adding the offset if it's 0.
|
||||
if (forwardingFieldOffset > 0) {
|
||||
addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
|
||||
addUInt(Block, dwarf::DW_FORM_udata, forwardingFieldOffset);
|
||||
addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
|
||||
addUInt(Loc, dwarf::DW_FORM_udata, forwardingFieldOffset);
|
||||
}
|
||||
|
||||
// Now dereference the __forwarding field to get to the real __Block_byref
|
||||
// struct: DW_OP_deref.
|
||||
addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
|
||||
addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
|
||||
|
||||
// Now that we've got the real __Block_byref... struct, add the offset
|
||||
// for the variable's field to get to the location of the actual variable:
|
||||
// DW_OP_plus_uconst varFieldOffset. Again, don't add if it's 0.
|
||||
if (varFieldOffset > 0) {
|
||||
addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
|
||||
addUInt(Block, dwarf::DW_FORM_udata, varFieldOffset);
|
||||
addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
|
||||
addUInt(Loc, dwarf::DW_FORM_udata, varFieldOffset);
|
||||
}
|
||||
|
||||
// Now attach the location information to the DIE.
|
||||
addBlock(Die, Attribute, Block);
|
||||
addBlock(Die, Attribute, Loc);
|
||||
}
|
||||
|
||||
/// isTypeSigned - Return true if the type is signed.
|
||||
@@ -788,6 +794,7 @@ void DwarfUnit::addConstantValue(DIE *Die, const MachineOperand &MO,
|
||||
/// addConstantFPValue - Add constant value entry in variable DIE.
|
||||
void DwarfUnit::addConstantFPValue(DIE *Die, const MachineOperand &MO) {
|
||||
assert(MO.isFPImm() && "Invalid machine operand!");
|
||||
// FIXME-echristo: Use a block here.
|
||||
DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
|
||||
APFloat FPImm = MO.getFPImm()->getValueAPF();
|
||||
|
||||
@@ -1331,12 +1338,12 @@ DwarfUnit::constructTemplateValueParameterDIE(DIE &Buffer,
|
||||
else if (GlobalValue *GV = dyn_cast<GlobalValue>(Val)) {
|
||||
// For declaration non-type template parameters (such as global values and
|
||||
// functions)
|
||||
DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
|
||||
addOpAddress(Block, Asm->getSymbol(GV));
|
||||
DIELoc *Loc = new (DIEValueAllocator) DIELoc();
|
||||
addOpAddress(Loc, Asm->getSymbol(GV));
|
||||
// Emit DW_OP_stack_value to use the address as the immediate value of the
|
||||
// parameter, rather than a pointer to it.
|
||||
addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value);
|
||||
addBlock(ParamDIE, dwarf::DW_AT_location, Block);
|
||||
addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value);
|
||||
addBlock(ParamDIE, dwarf::DW_AT_location, Loc);
|
||||
} else if (VP.getTag() == dwarf::DW_TAG_GNU_template_template_param) {
|
||||
assert(isa<MDString>(Val));
|
||||
addString(ParamDIE, dwarf::DW_AT_GNU_template_name,
|
||||
@@ -1438,7 +1445,7 @@ DIE *DwarfUnit::getOrCreateSubprogramDIE(DISubprogram SP) {
|
||||
unsigned VK = SP.getVirtuality();
|
||||
if (VK) {
|
||||
addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1, VK);
|
||||
DIEBlock *Block = getDIEBlock();
|
||||
DIELoc *Block = getDIELoc();
|
||||
addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
|
||||
addUInt(Block, dwarf::DW_FORM_udata, SP.getVirtualIndex());
|
||||
addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, Block);
|
||||
@@ -1573,7 +1580,7 @@ void DwarfCompileUnit::createGlobalVariableDIE(DIGlobalVariable GV) {
|
||||
bool isGlobalVariable = GV.getGlobal() != NULL;
|
||||
if (isGlobalVariable) {
|
||||
addToAccelTable = true;
|
||||
DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
|
||||
DIELoc *Loc = new (DIEValueAllocator) DIELoc();
|
||||
const MCSymbol *Sym = Asm->getSymbol(GV.getGlobal());
|
||||
if (GV.getGlobal()->isThreadLocal()) {
|
||||
// FIXME: Make this work with -gsplit-dwarf.
|
||||
@@ -1583,22 +1590,22 @@ void DwarfCompileUnit::createGlobalVariableDIE(DIGlobalVariable GV) {
|
||||
// Based on GCC's support for TLS:
|
||||
if (!DD->useSplitDwarf()) {
|
||||
// 1) Start with a constNu of the appropriate pointer size
|
||||
addUInt(Block, dwarf::DW_FORM_data1,
|
||||
addUInt(Loc, dwarf::DW_FORM_data1,
|
||||
PointerSize == 4 ? dwarf::DW_OP_const4u : dwarf::DW_OP_const8u);
|
||||
// 2) containing the (relocated) offset of the TLS variable
|
||||
// within the module's TLS block.
|
||||
addExpr(Block, dwarf::DW_FORM_udata,
|
||||
addExpr(Loc, dwarf::DW_FORM_udata,
|
||||
Asm->getObjFileLowering().getDebugThreadLocalSymbol(Sym));
|
||||
} else {
|
||||
addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index);
|
||||
addUInt(Block, dwarf::DW_FORM_udata,
|
||||
addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index);
|
||||
addUInt(Loc, dwarf::DW_FORM_udata,
|
||||
DU->getAddrPoolIndex(Sym, /* TLS */ true));
|
||||
}
|
||||
// 3) followed by a custom OP to make the debugger do a TLS lookup.
|
||||
addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_push_tls_address);
|
||||
addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_push_tls_address);
|
||||
} else {
|
||||
DD->addArangeLabel(SymbolCU(this, Sym));
|
||||
addOpAddress(Block, Sym);
|
||||
addOpAddress(Loc, Sym);
|
||||
}
|
||||
// Do not create specification DIE if context is either compile unit
|
||||
// or a subprogram.
|
||||
@@ -1607,12 +1614,12 @@ void DwarfCompileUnit::createGlobalVariableDIE(DIGlobalVariable GV) {
|
||||
// Create specification DIE.
|
||||
VariableSpecDIE = createAndAddDIE(dwarf::DW_TAG_variable, *UnitDie);
|
||||
addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification, VariableDIE);
|
||||
addBlock(VariableSpecDIE, dwarf::DW_AT_location, Block);
|
||||
addBlock(VariableSpecDIE, dwarf::DW_AT_location, Loc);
|
||||
// A static member's declaration is already flagged as such.
|
||||
if (!SDMDecl.Verify())
|
||||
addFlag(VariableDIE, dwarf::DW_AT_declaration);
|
||||
} else {
|
||||
addBlock(VariableDIE, dwarf::DW_AT_location, Block);
|
||||
addBlock(VariableDIE, dwarf::DW_AT_location, Loc);
|
||||
}
|
||||
// Add the linkage name.
|
||||
StringRef LinkageName = GV.getLinkageName();
|
||||
@@ -1634,17 +1641,17 @@ void DwarfCompileUnit::createGlobalVariableDIE(DIGlobalVariable GV) {
|
||||
} else if (const ConstantExpr *CE = getMergedGlobalExpr(GV->getOperand(11))) {
|
||||
addToAccelTable = true;
|
||||
// GV is a merged global.
|
||||
DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
|
||||
DIELoc *Loc = new (DIEValueAllocator) DIELoc();
|
||||
Value *Ptr = CE->getOperand(0);
|
||||
MCSymbol *Sym = Asm->getSymbol(cast<GlobalValue>(Ptr));
|
||||
DD->addArangeLabel(SymbolCU(this, Sym));
|
||||
addOpAddress(Block, Sym);
|
||||
addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
|
||||
addOpAddress(Loc, Sym);
|
||||
addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
|
||||
SmallVector<Value *, 3> Idx(CE->op_begin() + 1, CE->op_end());
|
||||
addUInt(Block, dwarf::DW_FORM_udata,
|
||||
addUInt(Loc, dwarf::DW_FORM_udata,
|
||||
Asm->getDataLayout().getIndexedOffset(Ptr->getType(), Idx));
|
||||
addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
|
||||
addBlock(VariableDIE, dwarf::DW_AT_location, Block);
|
||||
addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
|
||||
addBlock(VariableDIE, dwarf::DW_AT_location, Loc);
|
||||
}
|
||||
|
||||
if (addToAccelTable) {
|
||||
@@ -1848,7 +1855,7 @@ void DwarfUnit::constructMemberDIE(DIE &Buffer, DIDerivedType DT) {
|
||||
// expression to extract appropriate offset from vtable.
|
||||
// BaseAddr = ObAddr + *((*ObAddr) - Offset)
|
||||
|
||||
DIEBlock *VBaseLocationDie = new (DIEValueAllocator) DIEBlock();
|
||||
DIELoc *VBaseLocationDie = new (DIEValueAllocator) DIELoc();
|
||||
addUInt(VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_dup);
|
||||
addUInt(VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
|
||||
addUInt(VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
|
||||
@@ -1888,7 +1895,7 @@ void DwarfUnit::constructMemberDIE(DIE &Buffer, DIDerivedType DT) {
|
||||
OffsetInBytes = DT.getOffsetInBits() >> 3;
|
||||
|
||||
if (DD->getDwarfVersion() <= 2) {
|
||||
DIEBlock *MemLocationDie = new (DIEValueAllocator) DIEBlock();
|
||||
DIELoc *MemLocationDie = new (DIEValueAllocator) DIELoc();
|
||||
addUInt(MemLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
|
||||
addUInt(MemLocationDie, dwarf::DW_FORM_udata, OffsetInBytes);
|
||||
addBlock(MemberDie, dwarf::DW_AT_data_member_location, MemLocationDie);
|
||||
|
||||
Reference in New Issue
Block a user