diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Analysis/DebugInfo.cpp | 22 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 61 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfDebug.h | 15 |
3 files changed, 92 insertions, 6 deletions
diff --git a/lib/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp index 58bee90372..db5a0cbb21 100644 --- a/lib/Analysis/DebugInfo.cpp +++ b/lib/Analysis/DebugInfo.cpp @@ -531,6 +531,8 @@ void DIVariable::dump() const { errs() << " [" << getLineNumber() << "] "; getType().dump(); errs() << "\n"; + + // FIXME: Dump complex addresses } //===----------------------------------------------------------------------===// @@ -781,6 +783,26 @@ DIVariable DIFactory::CreateVariable(unsigned Tag, DIDescriptor Context, } +/// CreateComplexVariable - Create a new descriptor for the specified variable +/// which has a complex address expression for its address. +DIVariable DIFactory::CreateComplexVariable(unsigned Tag, DIDescriptor Context, + const std::string &Name, + DICompileUnit CompileUnit, + unsigned LineNo, + DIType Type, SmallVector<Value *, 9> &addr) { + SmallVector<Value *, 9> Elts; + Elts.push_back(GetTagConstant(Tag)); + Elts.push_back(Context.getNode()); + Elts.push_back(MDString::get(VMContext, Name)); + Elts.push_back(CompileUnit.getNode()); + Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), LineNo)); + Elts.push_back(Type.getNode()); + Elts.insert(Elts.end(), addr.begin(), addr.end()); + + return DIVariable(MDNode::get(VMContext, &Elts[0], 6+addr.size())); +} + + /// CreateBlock - This creates a descriptor for a lexical block with the /// specified parent VMContext. DILexicalBlock DIFactory::CreateLexicalBlock(DIDescriptor Context) { diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index f667e31569..8a74a8ee44 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -556,7 +556,7 @@ DIType DwarfDebug::GetBlockByrefType(DIType Ty, std::string Name) { unsigned tag = Ty.getTag(); if (tag == dwarf::DW_TAG_pointer_type) { - DIDerivedType DTy = DIDerivedType (Ty.getNode()); + DIDerivedType DTy = DIDerivedType(Ty.getNode()); subType = DTy.getTypeDerivedFrom(); } @@ -577,6 +577,56 @@ DIType DwarfDebug::GetBlockByrefType(DIType Ty, std::string Name) { return Ty; } +/// AddComplexAddress - Start with the address based on the location provided, +/// and generate the DWARF information necessary to find the actual variable +/// given the extra address information encoded in the DIVariable, starting from +/// the starting location. Add the DWARF information to the die. +/// +void DwarfDebug::AddComplexAddress(DbgVariable *&DV, DIE *Die, + unsigned Attribute, + const MachineLocation &Location) { + const DIVariable &VD = DV->getVariable(); + DIType Ty = VD.getType(); + + // Decode the original location, and use that as the start of the byref + // variable's location. + unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false); + DIEBlock *Block = new DIEBlock(); + + if (Location.isReg()) { + if (Reg < 32) { + AddUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg); + } else { + Reg = Reg - dwarf::DW_OP_reg0; + AddUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg); + AddUInt(Block, 0, dwarf::DW_FORM_udata, Reg); + } + } else { + if (Reg < 32) + AddUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg); + else { + AddUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx); + AddUInt(Block, 0, dwarf::DW_FORM_udata, Reg); + } + + AddUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset()); + } + + for (unsigned i = 0, N = VD.getNumAddrElements(); i < N; ++i) { + uint64_t Element = VD.getAddrElement(i); + + if (Element == DIFactory::OpPlus) { + AddUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); + AddUInt(Block, 0, dwarf::DW_FORM_udata, VD.getAddrElement(++i)); + } else if (Element == DIFactory::OpDeref) { + AddUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); + } else llvm_unreachable("unknown DIFactory Opcode"); + } + + // Now attach the location information to the DIE. + AddBlock(Die, Attribute, 0, Block); +} + /* Byref variables, in Blocks, are declared by the programmer as "SomeType VarName;", but the compiler creates a __Block_byref_x_VarName struct, and gives the variable VarName either the struct, or a pointer to the struct, as @@ -649,7 +699,7 @@ void DwarfDebug::AddBlockByrefAddress(DbgVariable *&DV, DIE *Die, const char *varName = VD.getName(); if (Tag == dwarf::DW_TAG_pointer_type) { - DIDerivedType DTy = DIDerivedType (Ty.getNode()); + DIDerivedType DTy = DIDerivedType(Ty.getNode()); TmpTy = DTy.getTypeDerivedFrom(); isPointer = true; } @@ -790,7 +840,6 @@ void DwarfDebug::AddType(CompileUnit *DW_Unit, DIE *Entity, DIType Ty) { else { assert(Ty.isDerivedType() && "Unknown kind of DIType"); ConstructTypeDIE(DW_Unit, Buffer, DIDerivedType(Ty.getNode())); - } // Add debug information entry to entity and appropriate context. @@ -1187,6 +1236,7 @@ DIE *DwarfDebug::CreateDbgScopeVariable(DbgVariable *DV, CompileUnit *Unit) { AddSourceLine(VariableDie, &VD); // Add variable type. + // FIXME: isBlockByrefVariable should be reformulated in terms of complex addresses instead. if (VD.isBlockByrefVariable()) AddType(Unit, VariableDie, GetBlockByrefType(VD.getType(), Name)); else @@ -1200,7 +1250,10 @@ DIE *DwarfDebug::CreateDbgScopeVariable(DbgVariable *DV, CompileUnit *Unit) { Location.set(RI->getFrameRegister(*MF), RI->getFrameIndexOffset(*MF, DV->getFrameIndex())); - if (VD.isBlockByrefVariable()) + + if (VD.hasComplexAddress()) + AddComplexAddress(DV, VariableDie, dwarf::DW_AT_location, Location); + else if (VD.isBlockByrefVariable()) AddBlockByrefAddress(DV, VariableDie, dwarf::DW_AT_location, Location); else AddAddress(VariableDie, dwarf::DW_AT_location, Location); diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index f582f9b829..8899529698 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -284,10 +284,20 @@ class VISIBILITY_HIDDEN DwarfDebug : public Dwarf { void AddAddress(DIE *Die, unsigned Attribute, const MachineLocation &Location); + /// AddComplexAddress - Start with the address based on the location provided, + /// and generate the DWARF information necessary to find the actual variable + /// (navigating the extra location information encoded in the type) based on + /// the starting location. Add the DWARF information to the die. + /// + void AddComplexAddress(DbgVariable *&DV, DIE *Die, unsigned Attribute, + const MachineLocation &Location); + + // FIXME: Should be reformulated in terms of AddComplexAddress. /// AddBlockByrefAddress - Start with the address based on the location /// provided, and generate the DWARF information necessary to find the /// actual Block variable (navigating the Block struct) based on the - /// starting location. Add the DWARF information to the die. + /// starting location. Add the DWARF information to the die. Obsolete, + /// please use AddComplexAddress instead. /// void AddBlockByrefAddress(DbgVariable *&DV, DIE *Die, unsigned Attribute, const MachineLocation &Location); @@ -459,8 +469,9 @@ class VISIBILITY_HIDDEN DwarfDebug : public Dwarf { void ConstructSubprogram(MDNode *N); + // FIXME: This should go away in favor of complex addresses. /// Find the type the programmer originally declared the variable to be - /// and return that type. + /// and return that type. Obsolete, use GetComplexAddrType instead. /// DIType GetBlockByrefType(DIType Ty, std::string Name); |