16e07bfd0SEugene Zelenko //===- llvm/CodeGen/DwarfCompileUnit.cpp - Dwarf Compile Units ------------===// 23443575cSPaul Robinson // 33443575cSPaul Robinson // The LLVM Compiler Infrastructure 43443575cSPaul Robinson // 53443575cSPaul Robinson // This file is distributed under the University of Illinois Open Source 63443575cSPaul Robinson // License. See LICENSE.TXT for details. 73443575cSPaul Robinson // 83443575cSPaul Robinson //===----------------------------------------------------------------------===// 93443575cSPaul Robinson // 103443575cSPaul Robinson // This file contains support for constructing a dwarf compile unit. 113443575cSPaul Robinson // 123443575cSPaul Robinson //===----------------------------------------------------------------------===// 133443575cSPaul Robinson 1437c52310SDavid Blaikie #include "DwarfCompileUnit.h" 156e07bfd0SEugene Zelenko #include "AddressPool.h" 166e07bfd0SEugene Zelenko #include "DwarfDebug.h" 177813d9c9SAdrian Prantl #include "DwarfExpression.h" 186e07bfd0SEugene Zelenko #include "DwarfUnit.h" 196e07bfd0SEugene Zelenko #include "llvm/ADT/None.h" 206e07bfd0SEugene Zelenko #include "llvm/ADT/STLExtras.h" 216e07bfd0SEugene Zelenko #include "llvm/ADT/SmallVector.h" 226e07bfd0SEugene Zelenko #include "llvm/ADT/StringRef.h" 236e07bfd0SEugene Zelenko #include "llvm/BinaryFormat/Dwarf.h" 246e07bfd0SEugene Zelenko #include "llvm/CodeGen/AsmPrinter.h" 256e07bfd0SEugene Zelenko #include "llvm/CodeGen/DIE.h" 266e07bfd0SEugene Zelenko #include "llvm/CodeGen/LexicalScopes.h" 27cda2aa82SDavid Blaikie #include "llvm/CodeGen/MachineFunction.h" 286e07bfd0SEugene Zelenko #include "llvm/CodeGen/MachineInstr.h" 296e07bfd0SEugene Zelenko #include "llvm/CodeGen/MachineOperand.h" 30b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetFrameLowering.h" 31b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetRegisterInfo.h" 32b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetSubtargetInfo.h" 3337c52310SDavid Blaikie #include "llvm/IR/DataLayout.h" 346e07bfd0SEugene Zelenko #include "llvm/IR/DebugInfo.h" 356e07bfd0SEugene Zelenko #include "llvm/IR/DebugInfoMetadata.h" 3637c52310SDavid Blaikie #include "llvm/IR/GlobalVariable.h" 376e07bfd0SEugene Zelenko #include "llvm/MC/MCSection.h" 3837c52310SDavid Blaikie #include "llvm/MC/MCStreamer.h" 396e07bfd0SEugene Zelenko #include "llvm/MC/MCSymbol.h" 40b3bde2eaSDavid Blaikie #include "llvm/MC/MachineLocation.h" 416e07bfd0SEugene Zelenko #include "llvm/Support/Casting.h" 426054e650SDavid Blaikie #include "llvm/Target/TargetLoweringObjectFile.h" 43cda2aa82SDavid Blaikie #include "llvm/Target/TargetMachine.h" 446e07bfd0SEugene Zelenko #include "llvm/Target/TargetOptions.h" 456e07bfd0SEugene Zelenko #include <algorithm> 466e07bfd0SEugene Zelenko #include <cassert> 476e07bfd0SEugene Zelenko #include <cstdint> 486e07bfd0SEugene Zelenko #include <iterator> 496e07bfd0SEugene Zelenko #include <memory> 506e07bfd0SEugene Zelenko #include <string> 516e07bfd0SEugene Zelenko #include <utility> 5237c52310SDavid Blaikie 536e07bfd0SEugene Zelenko using namespace llvm; 5437c52310SDavid Blaikie 55a9308c49SDuncan P. N. Exon Smith DwarfCompileUnit::DwarfCompileUnit(unsigned UID, const DICompileUnit *Node, 5637c52310SDavid Blaikie AsmPrinter *A, DwarfDebug *DW, 5737c52310SDavid Blaikie DwarfFile *DWU) 586e07bfd0SEugene Zelenko : DwarfUnit(dwarf::DW_TAG_compile_unit, Node, A, DW, DWU), UniqueID(UID) { 5937c52310SDavid Blaikie insertDIE(Node, &getUnitDie()); 608bbce8adSAmjad Aboud MacroLabelBegin = Asm->createTempSymbol("cu_macro_begin"); 6137c52310SDavid Blaikie } 6237c52310SDavid Blaikie 6337c52310SDavid Blaikie /// addLabelAddress - Add a dwarf label attribute data and value using 6437c52310SDavid Blaikie /// DW_FORM_addr or DW_FORM_GNU_addr_index. 6537c52310SDavid Blaikie void DwarfCompileUnit::addLabelAddress(DIE &Die, dwarf::Attribute Attribute, 6637c52310SDavid Blaikie const MCSymbol *Label) { 6737c52310SDavid Blaikie // Don't use the address pool in non-fission or in the skeleton unit itself. 6837c52310SDavid Blaikie // FIXME: Once GDB supports this, it's probably worthwhile using the address 6937c52310SDavid Blaikie // pool from the skeleton - maybe even in non-fission (possibly fewer 7037c52310SDavid Blaikie // relocations by sharing them in the pool, but we have other ideas about how 7137c52310SDavid Blaikie // to reduce the number of relocations as well/instead). 72161dd3c1SDavid Blaikie if ((!DD->useSplitDwarf() || !Skeleton) && DD->getDwarfVersion() < 5) 7337c52310SDavid Blaikie return addLocalLabelAddress(Die, Attribute, Label); 7437c52310SDavid Blaikie 7537c52310SDavid Blaikie if (Label) 7637c52310SDavid Blaikie DD->addArangeLabel(SymbolCU(this, Label)); 7737c52310SDavid Blaikie 7837c52310SDavid Blaikie unsigned idx = DD->getAddressPool().getIndex(Label); 79161dd3c1SDavid Blaikie Die.addValue(DIEValueAllocator, Attribute, 80161dd3c1SDavid Blaikie DD->getDwarfVersion() >= 5 ? dwarf::DW_FORM_addrx 81161dd3c1SDavid Blaikie : dwarf::DW_FORM_GNU_addr_index, 824fb1f9cdSDuncan P. N. Exon Smith DIEInteger(idx)); 8337c52310SDavid Blaikie } 8437c52310SDavid Blaikie 8537c52310SDavid Blaikie void DwarfCompileUnit::addLocalLabelAddress(DIE &Die, 8637c52310SDavid Blaikie dwarf::Attribute Attribute, 8737c52310SDavid Blaikie const MCSymbol *Label) { 8837c52310SDavid Blaikie if (Label) 8937c52310SDavid Blaikie DD->addArangeLabel(SymbolCU(this, Label)); 9037c52310SDavid Blaikie 91815a6eb5SDuncan P. N. Exon Smith if (Label) 924fb1f9cdSDuncan P. N. Exon Smith Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_addr, 934fb1f9cdSDuncan P. N. Exon Smith DIELabel(Label)); 94815a6eb5SDuncan P. N. Exon Smith else 954fb1f9cdSDuncan P. N. Exon Smith Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_addr, 964fb1f9cdSDuncan P. N. Exon Smith DIEInteger(0)); 9737c52310SDavid Blaikie } 9837c52310SDavid Blaikie 99612e89d7SPaul Robinson unsigned DwarfCompileUnit::getOrCreateSourceID(const DIFile *File) { 10037c52310SDavid Blaikie // If we print assembly, we can't separate .file entries according to 10137c52310SDavid Blaikie // compile units. Thus all files will belong to the default compile unit. 10237c52310SDavid Blaikie 10337c52310SDavid Blaikie // FIXME: add a better feature test than hasRawTextSupport. Even better, 10437c52310SDavid Blaikie // extend .file to support this. 105612e89d7SPaul Robinson unsigned CUID = Asm->OutStreamer->hasRawTextSupport() ? 0 : getUniqueID(); 106612e89d7SPaul Robinson if (!File) 10716c7bdafSScott Linder return Asm->OutStreamer->EmitDwarfFileDirective(0, "", "", nullptr, None, CUID); 1089ff69c8fSLang Hames return Asm->OutStreamer->EmitDwarfFileDirective( 10916c7bdafSScott Linder 0, File->getDirectory(), File->getFilename(), getMD5AsBytes(File), 11016c7bdafSScott Linder File->getSource(), CUID); 11137c52310SDavid Blaikie } 11237c52310SDavid Blaikie 11360635e39SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE( 114bceaaa96SAdrian Prantl const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) { 11537c52310SDavid Blaikie // Check for pre-existence. 11637c52310SDavid Blaikie if (DIE *Die = getDIE(GV)) 11737c52310SDavid Blaikie return Die; 11837c52310SDavid Blaikie 119e686f159SDuncan P. N. Exon Smith assert(GV); 12037c52310SDavid Blaikie 121be9e4fe7SDuncan P. N. Exon Smith auto *GVContext = GV->getScope(); 122be9e4fe7SDuncan P. N. Exon Smith auto *GTy = DD->resolve(GV->getType()); 12337c52310SDavid Blaikie 12437c52310SDavid Blaikie // Construct the context before querying for the existence of the DIE in 12537c52310SDavid Blaikie // case such construction creates the DIE. 12672da9391SAmjad Aboud DIE *ContextDIE = getOrCreateContextDIE(GVContext); 12737c52310SDavid Blaikie 12872da9391SAmjad Aboud // Add to map. 12972da9391SAmjad Aboud DIE *VariableDIE = &createAndAddDIE(GV->getTag(), *ContextDIE, GV); 130a9308c49SDuncan P. N. Exon Smith DIScope *DeclContext; 131b1055640SDuncan P. N. Exon Smith if (auto *SDMDecl = GV->getStaticDataMemberDeclaration()) { 132b1055640SDuncan P. N. Exon Smith DeclContext = resolve(SDMDecl->getScope()); 133b1055640SDuncan P. N. Exon Smith assert(SDMDecl->isStaticMember() && "Expected static member decl"); 1347348ddaaSDuncan P. N. Exon Smith assert(GV->isDefinition()); 13549cfc8caSDavid Blaikie // We need the declaration DIE that is in the static member's class. 13649cfc8caSDavid Blaikie DIE *VariableSpecDIE = getOrCreateStaticMemberDIE(SDMDecl); 13749cfc8caSDavid Blaikie addDIEEntry(*VariableDIE, dwarf::DW_AT_specification, *VariableSpecDIE); 1383502f208SAdrian Prantl // If the global variable's type is different from the one in the class 1393502f208SAdrian Prantl // member type, assume that it's more specific and also emit it. 1403502f208SAdrian Prantl if (GTy != DD->resolve(SDMDecl->getBaseType())) 1413502f208SAdrian Prantl addType(*VariableDIE, GTy); 14249cfc8caSDavid Blaikie } else { 1437348ddaaSDuncan P. N. Exon Smith DeclContext = GV->getScope(); 14437c52310SDavid Blaikie // Add name and type. 1457348ddaaSDuncan P. N. Exon Smith addString(*VariableDIE, dwarf::DW_AT_name, GV->getDisplayName()); 14637c52310SDavid Blaikie addType(*VariableDIE, GTy); 14737c52310SDavid Blaikie 14837c52310SDavid Blaikie // Add scoping info. 1497348ddaaSDuncan P. N. Exon Smith if (!GV->isLocalToUnit()) 15037c52310SDavid Blaikie addFlag(*VariableDIE, dwarf::DW_AT_external); 15137c52310SDavid Blaikie 15237c52310SDavid Blaikie // Add line number info. 15337c52310SDavid Blaikie addSourceLine(*VariableDIE, GV); 15437c52310SDavid Blaikie } 15537c52310SDavid Blaikie 1567348ddaaSDuncan P. N. Exon Smith if (!GV->isDefinition()) 15749cfc8caSDavid Blaikie addFlag(*VariableDIE, dwarf::DW_AT_declaration); 158877354a2SDavid Blaikie else 159877354a2SDavid Blaikie addGlobalName(GV->getName(), *VariableDIE, DeclContext); 16049cfc8caSDavid Blaikie 1613c989984SVictor Leschuk if (uint32_t AlignInBytes = GV->getAlignInBytes()) 1623c989984SVictor Leschuk addUInt(*VariableDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata, 1633c989984SVictor Leschuk AlignInBytes); 1643c989984SVictor Leschuk 165f8ab35a4SMatthew Voss if (MDTuple *TP = GV->getTemplateParams()) 166f8ab35a4SMatthew Voss addTemplateParams(*VariableDIE, DINodeArray(TP)); 167f8ab35a4SMatthew Voss 16837c52310SDavid Blaikie // Add location. 16937c52310SDavid Blaikie bool addToAccelTable = false; 170bceaaa96SAdrian Prantl DIELoc *Loc = nullptr; 171bceaaa96SAdrian Prantl std::unique_ptr<DIEDwarfExpression> DwarfExpr; 172bceaaa96SAdrian Prantl for (const auto &GE : GlobalExprs) { 173bceaaa96SAdrian Prantl const GlobalVariable *Global = GE.Var; 174bceaaa96SAdrian Prantl const DIExpression *Expr = GE.Expr; 175b216e3e9SAdrian Prantl 176d4135bbcSPeter Collingbourne // For compatibility with DWARF 3 and earlier, 177d4135bbcSPeter Collingbourne // DW_AT_location(DW_OP_constu, X, DW_OP_stack_value) becomes 178d4135bbcSPeter Collingbourne // DW_AT_const_value(X). 179bceaaa96SAdrian Prantl if (GlobalExprs.size() == 1 && Expr && Expr->isConstant()) { 180b216e3e9SAdrian Prantl addToAccelTable = true; 181d4135bbcSPeter Collingbourne addConstantValue(*VariableDIE, /*Unsigned=*/true, Expr->getElement(1)); 182b216e3e9SAdrian Prantl break; 183b216e3e9SAdrian Prantl } 184b216e3e9SAdrian Prantl 185bceaaa96SAdrian Prantl // We cannot describe the location of dllimport'd variables: the 186bceaaa96SAdrian Prantl // computation of their address requires loads from the IAT. 187b216e3e9SAdrian Prantl if (Global && Global->hasDLLImportStorageClass()) 188b216e3e9SAdrian Prantl continue; 189b216e3e9SAdrian Prantl 190b216e3e9SAdrian Prantl // Nothing to describe without address or constant. 191b216e3e9SAdrian Prantl if (!Global && (!Expr || !Expr->isConstant())) 192b216e3e9SAdrian Prantl continue; 193b216e3e9SAdrian Prantl 1948e422b84SLei Liu if (Global && Global->isThreadLocal() && 1958e422b84SLei Liu !Asm->getObjFileLowering().supportDebugThreadLocalLocation()) 1968e422b84SLei Liu continue; 1978e422b84SLei Liu 198bceaaa96SAdrian Prantl if (!Loc) { 199b216e3e9SAdrian Prantl addToAccelTable = true; 200bceaaa96SAdrian Prantl Loc = new (DIEValueAllocator) DIELoc; 201bceaaa96SAdrian Prantl DwarfExpr = llvm::make_unique<DIEDwarfExpression>(*Asm, *this, *Loc); 202bceaaa96SAdrian Prantl } 203b216e3e9SAdrian Prantl 204a9e31537SMikael Holmen if (Expr) 205a9e31537SMikael Holmen DwarfExpr->addFragmentOffset(Expr); 206a9e31537SMikael Holmen 207bceaaa96SAdrian Prantl if (Global) { 208cca5f68eSDuncan P. N. Exon Smith const MCSymbol *Sym = Asm->getSymbol(Global); 209cca5f68eSDuncan P. N. Exon Smith if (Global->isThreadLocal()) { 2109f9e4681SChih-Hung Hsieh if (Asm->TM.useEmulatedTLS()) { 2111e859582SChih-Hung Hsieh // TODO: add debug info for emulated thread local mode. 2121e859582SChih-Hung Hsieh } else { 21337c52310SDavid Blaikie // FIXME: Make this work with -gsplit-dwarf. 21437c52310SDavid Blaikie unsigned PointerSize = Asm->getDataLayout().getPointerSize(); 21537c52310SDavid Blaikie assert((PointerSize == 4 || PointerSize == 8) && 21637c52310SDavid Blaikie "Add support for other sizes if necessary"); 21737c52310SDavid Blaikie // Based on GCC's support for TLS: 21837c52310SDavid Blaikie if (!DD->useSplitDwarf()) { 21937c52310SDavid Blaikie // 1) Start with a constNu of the appropriate pointer size 220bceaaa96SAdrian Prantl addUInt(*Loc, dwarf::DW_FORM_data1, 221bceaaa96SAdrian Prantl PointerSize == 4 ? dwarf::DW_OP_const4u 22254511353SDehao Chen : dwarf::DW_OP_const8u); 22337c52310SDavid Blaikie // 2) containing the (relocated) offset of the TLS variable 22437c52310SDavid Blaikie // within the module's TLS block. 22537c52310SDavid Blaikie addExpr(*Loc, dwarf::DW_FORM_udata, 22637c52310SDavid Blaikie Asm->getObjFileLowering().getDebugThreadLocalSymbol(Sym)); 22737c52310SDavid Blaikie } else { 22837c52310SDavid Blaikie addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index); 22937c52310SDavid Blaikie addUInt(*Loc, dwarf::DW_FORM_udata, 23037c52310SDavid Blaikie DD->getAddressPool().getIndex(Sym, /* TLS */ true)); 23137c52310SDavid Blaikie } 23278cc0821SPaul Robinson // 3) followed by an OP to make the debugger do a TLS lookup. 23378cc0821SPaul Robinson addUInt(*Loc, dwarf::DW_FORM_data1, 23478cc0821SPaul Robinson DD->useGNUTLSOpcode() ? dwarf::DW_OP_GNU_push_tls_address 23578cc0821SPaul Robinson : dwarf::DW_OP_form_tls_address); 2361e859582SChih-Hung Hsieh } 23737c52310SDavid Blaikie } else { 23837c52310SDavid Blaikie DD->addArangeLabel(SymbolCU(this, Sym)); 23937c52310SDavid Blaikie addOpAddress(*Loc, Sym); 24037c52310SDavid Blaikie } 241bceaaa96SAdrian Prantl } 2424b542c6eSAdrian Prantl // Global variables attached to symbols are memory locations. 2434b542c6eSAdrian Prantl // It would be better if this were unconditional, but malformed input that 2444b542c6eSAdrian Prantl // mixes non-fragments and fragments for the same variable is too expensive 2454b542c6eSAdrian Prantl // to detect in the verifier. 2463edc63a5SAdrian Prantl if (DwarfExpr->isUnknownLocation()) 2474b542c6eSAdrian Prantl DwarfExpr->setMemoryLocationKind(); 248a63b8e82SAdrian Prantl DwarfExpr->addExpression(Expr); 249d4135bbcSPeter Collingbourne } 250bceaaa96SAdrian Prantl if (Loc) 251bceaaa96SAdrian Prantl addBlock(*VariableDIE, dwarf::DW_AT_location, DwarfExpr->finalize()); 252d4135bbcSPeter Collingbourne 25343d1e453SPaul Robinson if (DD->useAllLinkageNames()) 2547348ddaaSDuncan P. N. Exon Smith addLinkageName(*VariableDIE, GV->getLinkageName()); 25537c52310SDavid Blaikie 25637c52310SDavid Blaikie if (addToAccelTable) { 25766cf14d0SDavid Blaikie DD->addAccelName(*CUNode, GV->getName(), *VariableDIE); 25837c52310SDavid Blaikie 25937c52310SDavid Blaikie // If the linkage name is different than the name, go ahead and output 26037c52310SDavid Blaikie // that as well into the name table. 2612a6afe5fSPavel Labath if (GV->getLinkageName() != "" && GV->getName() != GV->getLinkageName() && 2622a6afe5fSPavel Labath DD->useAllLinkageNames()) 26366cf14d0SDavid Blaikie DD->addAccelName(*CUNode, GV->getLinkageName(), *VariableDIE); 26437c52310SDavid Blaikie } 26537c52310SDavid Blaikie 26649cfc8caSDavid Blaikie return VariableDIE; 26737c52310SDavid Blaikie } 26837c52310SDavid Blaikie 26937c52310SDavid Blaikie void DwarfCompileUnit::addRange(RangeSpan Range) { 27037c52310SDavid Blaikie bool SameAsPrevCU = this == DD->getPrevCU(); 27137c52310SDavid Blaikie DD->setPrevCU(this); 27237c52310SDavid Blaikie // If we have no current ranges just add the range and return, otherwise, 27337c52310SDavid Blaikie // check the current section and CU against the previous section and CU we 27437c52310SDavid Blaikie // emitted into and the subprogram was contained within. If these are the 27537c52310SDavid Blaikie // same then extend our current range, otherwise add this as a new range. 27637c52310SDavid Blaikie if (CURanges.empty() || !SameAsPrevCU || 27737c52310SDavid Blaikie (&CURanges.back().getEnd()->getSection() != 27837c52310SDavid Blaikie &Range.getEnd()->getSection())) { 27937c52310SDavid Blaikie CURanges.push_back(Range); 280*60fddac9SDavid Blaikie DD->addSectionLabel(Range.getStart()); 28137c52310SDavid Blaikie return; 28237c52310SDavid Blaikie } 28337c52310SDavid Blaikie 28437c52310SDavid Blaikie CURanges.back().setEnd(Range.getEnd()); 28537c52310SDavid Blaikie } 28637c52310SDavid Blaikie 287063d725fSRafael Espindola void DwarfCompileUnit::initStmtList() { 288d4dd7215SAlexey Bataev if (CUNode->isDebugDirectivesOnly()) 289d4dd7215SAlexey Bataev return; 290d4dd7215SAlexey Bataev 29137c52310SDavid Blaikie // Define start line table label for each Compile Unit. 292bff36086SAlexey Bataev MCSymbol *LineTableStartSym; 293bff36086SAlexey Bataev const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); 294bff36086SAlexey Bataev if (DD->useSectionsAsReferences()) { 295bff36086SAlexey Bataev LineTableStartSym = TLOF.getDwarfLineSection()->getBeginSymbol(); 296bff36086SAlexey Bataev } else { 297bff36086SAlexey Bataev LineTableStartSym = 2989ff69c8fSLang Hames Asm->OutStreamer->getDwarfLineTableSymbol(getUniqueID()); 299bff36086SAlexey Bataev } 30037c52310SDavid Blaikie 30137c52310SDavid Blaikie // DW_AT_stmt_list is a offset of line number information for this 30237c52310SDavid Blaikie // compile unit in debug_line section. For split dwarf this is 30337c52310SDavid Blaikie // left in the skeleton CU and so not included. 30437c52310SDavid Blaikie // The line table entries are not always emitted in assembly, so it 30537c52310SDavid Blaikie // is not okay to use line_table_start here. 3064fb1f9cdSDuncan P. N. Exon Smith StmtListValue = 30735630c33SGreg Clayton addSectionLabel(getUnitDie(), dwarf::DW_AT_stmt_list, LineTableStartSym, 308063d725fSRafael Espindola TLOF.getDwarfLineSection()->getBeginSymbol()); 30937c52310SDavid Blaikie } 31037c52310SDavid Blaikie 31137c52310SDavid Blaikie void DwarfCompileUnit::applyStmtList(DIE &D) { 3124fb1f9cdSDuncan P. N. Exon Smith D.addValue(DIEValueAllocator, *StmtListValue); 31337c52310SDavid Blaikie } 31437c52310SDavid Blaikie 31514499a7dSDavid Blaikie void DwarfCompileUnit::attachLowHighPC(DIE &D, const MCSymbol *Begin, 31614499a7dSDavid Blaikie const MCSymbol *End) { 31714499a7dSDavid Blaikie assert(Begin && "Begin label should not be null!"); 31814499a7dSDavid Blaikie assert(End && "End label should not be null!"); 31914499a7dSDavid Blaikie assert(Begin->isDefined() && "Invalid starting label"); 32014499a7dSDavid Blaikie assert(End->isDefined() && "Invalid end label"); 32114499a7dSDavid Blaikie 32214499a7dSDavid Blaikie addLabelAddress(D, dwarf::DW_AT_low_pc, Begin); 32314499a7dSDavid Blaikie if (DD->getDwarfVersion() < 4) 32414499a7dSDavid Blaikie addLabelAddress(D, dwarf::DW_AT_high_pc, End); 32514499a7dSDavid Blaikie else 32614499a7dSDavid Blaikie addLabelDelta(D, dwarf::DW_AT_high_pc, End, Begin); 32714499a7dSDavid Blaikie } 32814499a7dSDavid Blaikie 329cda2aa82SDavid Blaikie // Find DIE for the given subprogram and attach appropriate DW_AT_low_pc 330cda2aa82SDavid Blaikie // and DW_AT_high_pc attributes. If there are global variables in this 331cda2aa82SDavid Blaikie // scope then create and insert DIEs for these variables. 332a9308c49SDuncan P. N. Exon Smith DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP) { 3333a443c29SDavid Blaikie DIE *SPDie = getOrCreateSubprogramDIE(SP, includeMinimalInlineScopes()); 334cda2aa82SDavid Blaikie 33507c03d31SRafael Espindola attachLowHighPC(*SPDie, Asm->getFunctionBegin(), Asm->getFunctionEnd()); 336c53e18d9SDavid Blaikie if (DD->useAppleExtensionAttributes() && 337c53e18d9SDavid Blaikie !DD->getCurrentFunction()->getTarget().Options.DisableFramePointerElim( 338cda2aa82SDavid Blaikie *DD->getCurrentFunction())) 339cda2aa82SDavid Blaikie addFlag(*SPDie, dwarf::DW_AT_APPLE_omit_frame_ptr); 340cda2aa82SDavid Blaikie 341cda2aa82SDavid Blaikie // Only include DW_AT_frame_base in full debug info 3423a443c29SDavid Blaikie if (!includeMinimalInlineScopes()) { 3437ae86fe7SAlexey Bataev if (Asm->MF->getTarget().getTargetTriple().isNVPTX()) { 3447ae86fe7SAlexey Bataev DIELoc *Loc = new (DIEValueAllocator) DIELoc; 3457ae86fe7SAlexey Bataev addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_call_frame_cfa); 3467ae86fe7SAlexey Bataev addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc); 3477ae86fe7SAlexey Bataev } else { 348d4e723f2SEric Christopher const TargetRegisterInfo *RI = Asm->MF->getSubtarget().getRegisterInfo(); 349cda2aa82SDavid Blaikie MachineLocation Location(RI->getFrameRegister(*Asm->MF)); 3508efadbf8SAdrian Prantl if (RI->isPhysicalRegister(Location.getReg())) 351cda2aa82SDavid Blaikie addAddress(*SPDie, dwarf::DW_AT_frame_base, Location); 352cda2aa82SDavid Blaikie } 3537ae86fe7SAlexey Bataev } 354cda2aa82SDavid Blaikie 355cda2aa82SDavid Blaikie // Add name to the name table, we do this here because we're guaranteed 356cda2aa82SDavid Blaikie // to have concrete versions of our DW_TAG_subprogram nodes. 35766cf14d0SDavid Blaikie DD->addSubprogramNames(*CUNode, SP, *SPDie); 358cda2aa82SDavid Blaikie 359cda2aa82SDavid Blaikie return *SPDie; 360cda2aa82SDavid Blaikie } 361cda2aa82SDavid Blaikie 3629c65b135SDavid Blaikie // Construct a DIE for this scope. 3639c65b135SDavid Blaikie void DwarfCompileUnit::constructScopeDIE( 364827200c8SDuncan P. N. Exon Smith LexicalScope *Scope, SmallVectorImpl<DIE *> &FinalChildren) { 3659c65b135SDavid Blaikie if (!Scope || !Scope->getScopeNode()) 3669c65b135SDavid Blaikie return; 3679c65b135SDavid Blaikie 368be9e4fe7SDuncan P. N. Exon Smith auto *DS = Scope->getScopeNode(); 3699c65b135SDavid Blaikie 370a9308c49SDuncan P. N. Exon Smith assert((Scope->getInlinedAt() || !isa<DISubprogram>(DS)) && 3719c65b135SDavid Blaikie "Only handle inlined subprograms here, use " 3729c65b135SDavid Blaikie "constructSubprogramScopeDIE for non-inlined " 3739c65b135SDavid Blaikie "subprograms"); 3749c65b135SDavid Blaikie 375827200c8SDuncan P. N. Exon Smith SmallVector<DIE *, 8> Children; 3769c65b135SDavid Blaikie 3779c65b135SDavid Blaikie // We try to create the scope DIE first, then the children DIEs. This will 3789c65b135SDavid Blaikie // avoid creating un-used children then removing them later when we find out 3799c65b135SDavid Blaikie // the scope DIE is null. 380827200c8SDuncan P. N. Exon Smith DIE *ScopeDIE; 381a9308c49SDuncan P. N. Exon Smith if (Scope->getParent() && isa<DISubprogram>(DS)) { 38201b48a84SDavid Blaikie ScopeDIE = constructInlinedScopeDIE(Scope); 3839c65b135SDavid Blaikie if (!ScopeDIE) 3849c65b135SDavid Blaikie return; 3859c65b135SDavid Blaikie // We create children when the scope DIE is not null. 3868b2fdb83SDavid Blaikie createScopeChildrenDIE(Scope, Children); 3879c65b135SDavid Blaikie } else { 3889c65b135SDavid Blaikie // Early exit when we know the scope DIE is going to be null. 3899c65b135SDavid Blaikie if (DD->isLexicalScopeDIENull(Scope)) 3909c65b135SDavid Blaikie return; 3919c65b135SDavid Blaikie 3922195e136SDavid Blaikie bool HasNonScopeChildren = false; 3939c65b135SDavid Blaikie 3949c65b135SDavid Blaikie // We create children here when we know the scope DIE is not going to be 3959c65b135SDavid Blaikie // null and the children will be added to the scope DIE. 3962195e136SDavid Blaikie createScopeChildrenDIE(Scope, Children, &HasNonScopeChildren); 3973a443c29SDavid Blaikie 3989c65b135SDavid Blaikie // If there are only other scopes as children, put them directly in the 3999c65b135SDavid Blaikie // parent instead, as this scope would serve no purpose. 4002195e136SDavid Blaikie if (!HasNonScopeChildren) { 4019c65b135SDavid Blaikie FinalChildren.insert(FinalChildren.end(), 4029c65b135SDavid Blaikie std::make_move_iterator(Children.begin()), 4039c65b135SDavid Blaikie std::make_move_iterator(Children.end())); 4049c65b135SDavid Blaikie return; 4059c65b135SDavid Blaikie } 4060fbf8bdbSDavid Blaikie ScopeDIE = constructLexicalScopeDIE(Scope); 4079c65b135SDavid Blaikie assert(ScopeDIE && "Scope DIE should not be null."); 4089c65b135SDavid Blaikie } 4099c65b135SDavid Blaikie 4109c65b135SDavid Blaikie // Add children 4119c65b135SDavid Blaikie for (auto &I : Children) 4129c65b135SDavid Blaikie ScopeDIE->addChild(std::move(I)); 4139c65b135SDavid Blaikie 4149c65b135SDavid Blaikie FinalChildren.push_back(std::move(ScopeDIE)); 4159c65b135SDavid Blaikie } 4169c65b135SDavid Blaikie 4175b02a19fSDavid Blaikie void DwarfCompileUnit::addScopeRangeList(DIE &ScopeDIE, 4185b02a19fSDavid Blaikie SmallVector<RangeSpan, 2> Range) { 419063d725fSRafael Espindola const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); 420063d725fSRafael Espindola 421fcf3810cSWolfgang Pieb // Emit the offset into .debug_ranges or .debug_rnglists as a relocatable 422fcf3810cSWolfgang Pieb // label. emitDIE() will handle emitting it appropriately. 423063d725fSRafael Espindola const MCSymbol *RangeSectionSym = 424fcf3810cSWolfgang Pieb DD->getDwarfVersion() >= 5 425fcf3810cSWolfgang Pieb ? TLOF.getDwarfRnglistsSection()->getBeginSymbol() 426fcf3810cSWolfgang Pieb : TLOF.getDwarfRangesSection()->getBeginSymbol(); 42752400200SDavid Blaikie 428c4af8bf2SDavid Blaikie HasRangeLists = true; 429c4af8bf2SDavid Blaikie 430c4af8bf2SDavid Blaikie // Add the range list to the set of ranges to be emitted. 431c4af8bf2SDavid Blaikie auto IndexAndList = 432c4af8bf2SDavid Blaikie (DD->getDwarfVersion() < 5 && Skeleton ? Skeleton->DU : DU) 433c4af8bf2SDavid Blaikie ->addRange((Skeleton ? Skeleton->BaseAddress : BaseAddress), 434c4af8bf2SDavid Blaikie std::move(Range)); 435c4af8bf2SDavid Blaikie 436c4af8bf2SDavid Blaikie uint32_t Index = IndexAndList.first; 437c4af8bf2SDavid Blaikie auto &List = *IndexAndList.second; 4385b02a19fSDavid Blaikie 43952400200SDavid Blaikie // Under fission, ranges are specified by constant offsets relative to the 44052400200SDavid Blaikie // CU's DW_AT_GNU_ranges_base. 441fcf3810cSWolfgang Pieb // FIXME: For DWARF v5, do not generate the DW_AT_ranges attribute under 442fcf3810cSWolfgang Pieb // fission until we support the forms using the .debug_addr section 443fcf3810cSWolfgang Pieb // (DW_RLE_startx_endx etc.). 44432e09de9SDavid Blaikie if (DD->getDwarfVersion() >= 5) 44532e09de9SDavid Blaikie addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_rnglistx, Index); 44632e09de9SDavid Blaikie else if (isDwoUnit()) 4475b02a19fSDavid Blaikie addSectionDelta(ScopeDIE, dwarf::DW_AT_ranges, List.getSym(), 4485b02a19fSDavid Blaikie RangeSectionSym); 449c4af8bf2SDavid Blaikie else 4505b02a19fSDavid Blaikie addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges, List.getSym(), 4515b02a19fSDavid Blaikie RangeSectionSym); 452fcf3810cSWolfgang Pieb } 45352400200SDavid Blaikie 454de12375cSDavid Blaikie void DwarfCompileUnit::attachRangesOrLowHighPC( 4555b02a19fSDavid Blaikie DIE &Die, SmallVector<RangeSpan, 2> Ranges) { 456858a7dd6SAlexey Bataev if (Ranges.size() == 1 || !DD->useRangesSection()) { 457858a7dd6SAlexey Bataev const RangeSpan &Front = Ranges.front(); 458858a7dd6SAlexey Bataev const RangeSpan &Back = Ranges.back(); 459858a7dd6SAlexey Bataev attachLowHighPC(Die, Front.getStart(), Back.getEnd()); 4605b02a19fSDavid Blaikie } else 4615b02a19fSDavid Blaikie addScopeRangeList(Die, std::move(Ranges)); 4625b02a19fSDavid Blaikie } 4635b02a19fSDavid Blaikie 4645b02a19fSDavid Blaikie void DwarfCompileUnit::attachRangesOrLowHighPC( 465de12375cSDavid Blaikie DIE &Die, const SmallVectorImpl<InsnRange> &Ranges) { 4665b02a19fSDavid Blaikie SmallVector<RangeSpan, 2> List; 4675b02a19fSDavid Blaikie List.reserve(Ranges.size()); 4685b02a19fSDavid Blaikie for (const InsnRange &R : Ranges) 4695b02a19fSDavid Blaikie List.push_back(RangeSpan(DD->getLabelBeforeInsn(R.first), 4705b02a19fSDavid Blaikie DD->getLabelAfterInsn(R.second))); 4715b02a19fSDavid Blaikie attachRangesOrLowHighPC(Die, std::move(List)); 472de12375cSDavid Blaikie } 473de12375cSDavid Blaikie 47401b48a84SDavid Blaikie // This scope represents inlined body of a function. Construct DIE to 47501b48a84SDavid Blaikie // represent this concrete inlined copy of the function. 476827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope) { 47701b48a84SDavid Blaikie assert(Scope->getScopeNode()); 478be9e4fe7SDuncan P. N. Exon Smith auto *DS = Scope->getScopeNode(); 479be9e4fe7SDuncan P. N. Exon Smith auto *InlinedSP = getDISubprogram(DS); 48001b48a84SDavid Blaikie // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram 48101b48a84SDavid Blaikie // was inlined from another compile unit. 482488393f8SDavid Blaikie DIE *OriginDIE = getAbstractSPDies()[InlinedSP]; 48301b48a84SDavid Blaikie assert(OriginDIE && "Unable to find original DIE for an inlined subprogram."); 48401b48a84SDavid Blaikie 485827200c8SDuncan P. N. Exon Smith auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_inlined_subroutine); 48601b48a84SDavid Blaikie addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *OriginDIE); 48701b48a84SDavid Blaikie 48801b48a84SDavid Blaikie attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges()); 48901b48a84SDavid Blaikie 49001b48a84SDavid Blaikie // Add the call site information to the DIE. 491a9308c49SDuncan P. N. Exon Smith const DILocation *IA = Scope->getInlinedAt(); 49201b48a84SDavid Blaikie addUInt(*ScopeDIE, dwarf::DW_AT_call_file, None, 493612e89d7SPaul Robinson getOrCreateSourceID(IA->getFile())); 494b7e221baSDuncan P. N. Exon Smith addUInt(*ScopeDIE, dwarf::DW_AT_call_line, None, IA->getLine()); 4956e0c8446SDehao Chen if (IA->getDiscriminator() && DD->getDwarfVersion() >= 4) 49654511353SDehao Chen addUInt(*ScopeDIE, dwarf::DW_AT_GNU_discriminator, None, 49754511353SDehao Chen IA->getDiscriminator()); 49801b48a84SDavid Blaikie 49901b48a84SDavid Blaikie // Add name to the name table, we do this here because we're guaranteed 50001b48a84SDavid Blaikie // to have concrete versions of our DW_TAG_inlined_subprogram nodes. 50166cf14d0SDavid Blaikie DD->addSubprogramNames(*CUNode, InlinedSP, *ScopeDIE); 50201b48a84SDavid Blaikie 50301b48a84SDavid Blaikie return ScopeDIE; 50401b48a84SDavid Blaikie } 50501b48a84SDavid Blaikie 5060fbf8bdbSDavid Blaikie // Construct new DW_TAG_lexical_block for this scope and attach 5070fbf8bdbSDavid Blaikie // DW_AT_low_pc/DW_AT_high_pc labels. 508827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) { 5090fbf8bdbSDavid Blaikie if (DD->isLexicalScopeDIENull(Scope)) 5100fbf8bdbSDavid Blaikie return nullptr; 5110fbf8bdbSDavid Blaikie 512827200c8SDuncan P. N. Exon Smith auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_lexical_block); 5130fbf8bdbSDavid Blaikie if (Scope->isAbstractScope()) 5140fbf8bdbSDavid Blaikie return ScopeDIE; 5150fbf8bdbSDavid Blaikie 5160fbf8bdbSDavid Blaikie attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges()); 5170fbf8bdbSDavid Blaikie 5180fbf8bdbSDavid Blaikie return ScopeDIE; 5190fbf8bdbSDavid Blaikie } 5200fbf8bdbSDavid Blaikie 521ee7df553SDavid Blaikie /// constructVariableDIE - Construct a DIE for the given DbgVariable. 522827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, bool Abstract) { 523ee7df553SDavid Blaikie auto D = constructVariableDIEImpl(DV, Abstract); 524ee7df553SDavid Blaikie DV.setDIE(*D); 525ee7df553SDavid Blaikie return D; 526ee7df553SDavid Blaikie } 527ee7df553SDavid Blaikie 5282532ac88SHsiangkai Wang DIE *DwarfCompileUnit::constructLabelDIE(DbgLabel &DL, 5292532ac88SHsiangkai Wang const LexicalScope &Scope) { 5302532ac88SHsiangkai Wang auto LabelDie = DIE::get(DIEValueAllocator, DL.getTag()); 5312532ac88SHsiangkai Wang insertDIE(DL.getLabel(), LabelDie); 5322532ac88SHsiangkai Wang DL.setDIE(*LabelDie); 5332532ac88SHsiangkai Wang 5342532ac88SHsiangkai Wang if (Scope.isAbstractScope()) 5352532ac88SHsiangkai Wang applyLabelAttributes(DL, *LabelDie); 5362532ac88SHsiangkai Wang 5372532ac88SHsiangkai Wang return LabelDie; 5382532ac88SHsiangkai Wang } 5392532ac88SHsiangkai Wang 540827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV, 541ee7df553SDavid Blaikie bool Abstract) { 542ee7df553SDavid Blaikie // Define variable debug information entry. 543827200c8SDuncan P. N. Exon Smith auto VariableDie = DIE::get(DIEValueAllocator, DV.getTag()); 544dc00becdSSander de Smalen insertDIE(DV.getVariable(), VariableDie); 545ee7df553SDavid Blaikie 546ee7df553SDavid Blaikie if (Abstract) { 547ee7df553SDavid Blaikie applyVariableAttributes(DV, *VariableDie); 548ee7df553SDavid Blaikie return VariableDie; 549ee7df553SDavid Blaikie } 550ee7df553SDavid Blaikie 551ee7df553SDavid Blaikie // Add variable address. 552ee7df553SDavid Blaikie 553364a3005SDuncan P. N. Exon Smith unsigned Offset = DV.getDebugLocListIndex(); 554ee7df553SDavid Blaikie if (Offset != ~0U) { 555ee7df553SDavid Blaikie addLocationList(*VariableDie, dwarf::DW_AT_location, Offset); 556ee7df553SDavid Blaikie return VariableDie; 557ee7df553SDavid Blaikie } 558ee7df553SDavid Blaikie 559ee7df553SDavid Blaikie // Check if variable is described by a DBG_VALUE instruction. 560ee7df553SDavid Blaikie if (const MachineInstr *DVInsn = DV.getMInsn()) { 561ee7df553SDavid Blaikie assert(DVInsn->getNumOperands() == 4); 562ee7df553SDavid Blaikie if (DVInsn->getOperand(0).isReg()) { 563bd6d291cSAdrian Prantl auto RegOp = DVInsn->getOperand(0); 564bd6d291cSAdrian Prantl auto Op1 = DVInsn->getOperand(1); 565ee7df553SDavid Blaikie // If the second operand is an immediate, this is an indirect value. 566bd6d291cSAdrian Prantl assert((!Op1.isImm() || (Op1.getImm() == 0)) && "unexpected offset"); 567bd6d291cSAdrian Prantl MachineLocation Location(RegOp.getReg(), Op1.isImm()); 568ee7df553SDavid Blaikie addVariableAddress(DV, *VariableDie, Location); 5693b89e663SAdrian Prantl } else if (DVInsn->getOperand(0).isImm()) { 5703b89e663SAdrian Prantl // This variable is described by a single constant. 5713b89e663SAdrian Prantl // Check whether it has a DIExpression. 5723b89e663SAdrian Prantl auto *Expr = DV.getSingleExpression(); 5733b89e663SAdrian Prantl if (Expr && Expr->getNumElements()) { 5743b89e663SAdrian Prantl DIELoc *Loc = new (DIEValueAllocator) DIELoc; 5753b89e663SAdrian Prantl DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); 5763b89e663SAdrian Prantl // If there is an expression, emit raw unsigned bytes. 5778fafb8d3SAdrian Prantl DwarfExpr.addFragmentOffset(Expr); 578a63b8e82SAdrian Prantl DwarfExpr.addUnsignedConstant(DVInsn->getOperand(0).getImm()); 579a63b8e82SAdrian Prantl DwarfExpr.addExpression(Expr); 580bceaaa96SAdrian Prantl addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize()); 5813b89e663SAdrian Prantl } else 582ee7df553SDavid Blaikie addConstantValue(*VariableDie, DVInsn->getOperand(0), DV.getType()); 5833b89e663SAdrian Prantl } else if (DVInsn->getOperand(0).isFPImm()) 584ee7df553SDavid Blaikie addConstantFPValue(*VariableDie, DVInsn->getOperand(0)); 585ee7df553SDavid Blaikie else if (DVInsn->getOperand(0).isCImm()) 586ee7df553SDavid Blaikie addConstantValue(*VariableDie, DVInsn->getOperand(0).getCImm(), 587ee7df553SDavid Blaikie DV.getType()); 588ee7df553SDavid Blaikie 589ee7df553SDavid Blaikie return VariableDie; 590ee7df553SDavid Blaikie } 591ee7df553SDavid Blaikie 592ee7df553SDavid Blaikie // .. else use frame index. 59367c24422SAdrian Prantl if (!DV.hasFrameIndexExprs()) 594ca7e4702SAdrian Prantl return VariableDie; 595ca7e4702SAdrian Prantl 596e7e1d0c7SDuncan P. N. Exon Smith DIELoc *Loc = new (DIEValueAllocator) DIELoc; 597ca7e4702SAdrian Prantl DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); 59867c24422SAdrian Prantl for (auto &Fragment : DV.getFrameIndexExprs()) { 599ee7df553SDavid Blaikie unsigned FrameReg = 0; 6006825fb64SAdrian Prantl const DIExpression *Expr = Fragment.Expr; 601d4e723f2SEric Christopher const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering(); 60267c24422SAdrian Prantl int Offset = TFI->getFrameIndexReference(*Asm->MF, Fragment.FI, FrameReg); 6036825fb64SAdrian Prantl DwarfExpr.addFragmentOffset(Expr); 604956484b7SAdrian Prantl SmallVector<uint64_t, 8> Ops; 605ffc498dfSFlorian Hahn Ops.push_back(dwarf::DW_OP_plus_uconst); 606956484b7SAdrian Prantl Ops.push_back(Offset); 6076825fb64SAdrian Prantl Ops.append(Expr->elements_begin(), Expr->elements_end()); 6086825fb64SAdrian Prantl DIExpressionCursor Cursor(Ops); 609c12cee36SAdrian Prantl DwarfExpr.setMemoryLocationKind(); 6104dd7558fSAlexey Bataev if (const MCSymbol *FrameSymbol = Asm->getFunctionFrameSymbol()) 6114dd7558fSAlexey Bataev addOpAddress(*Loc, FrameSymbol); 6124dd7558fSAlexey Bataev else 613c12cee36SAdrian Prantl DwarfExpr.addMachineRegExpression( 614c12cee36SAdrian Prantl *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, FrameReg); 6156825fb64SAdrian Prantl DwarfExpr.addExpression(std::move(Cursor)); 616ee7df553SDavid Blaikie } 617bceaaa96SAdrian Prantl addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize()); 618ee7df553SDavid Blaikie 619ee7df553SDavid Blaikie return VariableDie; 620ee7df553SDavid Blaikie } 621ee7df553SDavid Blaikie 622827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, 623827200c8SDuncan P. N. Exon Smith const LexicalScope &Scope, 624827200c8SDuncan P. N. Exon Smith DIE *&ObjectPointer) { 6254a1a44e3SDavid Blaikie auto Var = constructVariableDIE(DV, Scope.isAbstractScope()); 6264a1a44e3SDavid Blaikie if (DV.isObjectPointer()) 627827200c8SDuncan P. N. Exon Smith ObjectPointer = Var; 6284a1a44e3SDavid Blaikie return Var; 6294a1a44e3SDavid Blaikie } 6304a1a44e3SDavid Blaikie 63103dd6f57SAdrian Prantl /// Return all DIVariables that appear in count: expressions. 63203dd6f57SAdrian Prantl static SmallVector<const DIVariable *, 2> dependencies(DbgVariable *Var) { 63303dd6f57SAdrian Prantl SmallVector<const DIVariable *, 2> Result; 63403dd6f57SAdrian Prantl auto *Array = dyn_cast<DICompositeType>(Var->getType()); 635c929f7adSAdrian Prantl if (!Array || Array->getTag() != dwarf::DW_TAG_array_type) 63603dd6f57SAdrian Prantl return Result; 63703dd6f57SAdrian Prantl for (auto *El : Array->getElements()) { 638c929f7adSAdrian Prantl if (auto *Subrange = dyn_cast<DISubrange>(El)) { 639c929f7adSAdrian Prantl auto Count = Subrange->getCount(); 64003dd6f57SAdrian Prantl if (auto *Dependency = Count.dyn_cast<DIVariable *>()) 64103dd6f57SAdrian Prantl Result.push_back(Dependency); 642c929f7adSAdrian Prantl } 64303dd6f57SAdrian Prantl } 64403dd6f57SAdrian Prantl return Result; 645c929f7adSAdrian Prantl } 646c929f7adSAdrian Prantl 647c929f7adSAdrian Prantl /// Sort local variables so that variables appearing inside of helper 648c929f7adSAdrian Prantl /// expressions come first. 64903dd6f57SAdrian Prantl static SmallVector<DbgVariable *, 8> 65003dd6f57SAdrian Prantl sortLocalVars(SmallVectorImpl<DbgVariable *> &Input) { 65103dd6f57SAdrian Prantl SmallVector<DbgVariable *, 8> Result; 65203dd6f57SAdrian Prantl SmallVector<PointerIntPair<DbgVariable *, 1>, 8> WorkList; 65303dd6f57SAdrian Prantl // Map back from a DIVariable to its containing DbgVariable. 65403dd6f57SAdrian Prantl SmallDenseMap<const DILocalVariable *, DbgVariable *> DbgVar; 65503dd6f57SAdrian Prantl // Set of DbgVariables in Result. 65603dd6f57SAdrian Prantl SmallDenseSet<DbgVariable *, 8> Visited; 65703dd6f57SAdrian Prantl // For cycle detection. 65803dd6f57SAdrian Prantl SmallDenseSet<DbgVariable *, 8> Visiting; 65903dd6f57SAdrian Prantl 66003dd6f57SAdrian Prantl // Initialize the worklist and the DIVariable lookup table. 66103dd6f57SAdrian Prantl for (auto Var : reverse(Input)) { 66203dd6f57SAdrian Prantl DbgVar.insert({Var->getVariable(), Var}); 66303dd6f57SAdrian Prantl WorkList.push_back({Var, 0}); 66403dd6f57SAdrian Prantl } 66503dd6f57SAdrian Prantl 66603dd6f57SAdrian Prantl // Perform a stable topological sort by doing a DFS. 66703dd6f57SAdrian Prantl while (!WorkList.empty()) { 66803dd6f57SAdrian Prantl auto Item = WorkList.back(); 66903dd6f57SAdrian Prantl DbgVariable *Var = Item.getPointer(); 67003dd6f57SAdrian Prantl bool visitedAllDependencies = Item.getInt(); 67103dd6f57SAdrian Prantl WorkList.pop_back(); 67203dd6f57SAdrian Prantl 67303dd6f57SAdrian Prantl // Dependency is in a different lexical scope or a global. 67403dd6f57SAdrian Prantl if (!Var) 67503dd6f57SAdrian Prantl continue; 67603dd6f57SAdrian Prantl 67703dd6f57SAdrian Prantl // Already handled. 67803dd6f57SAdrian Prantl if (Visited.count(Var)) 67903dd6f57SAdrian Prantl continue; 68003dd6f57SAdrian Prantl 68103dd6f57SAdrian Prantl // Add to Result if all dependencies are visited. 68203dd6f57SAdrian Prantl if (visitedAllDependencies) { 68303dd6f57SAdrian Prantl Visited.insert(Var); 68403dd6f57SAdrian Prantl Result.push_back(Var); 68503dd6f57SAdrian Prantl continue; 68603dd6f57SAdrian Prantl } 68703dd6f57SAdrian Prantl 68803dd6f57SAdrian Prantl // Detect cycles. 68903dd6f57SAdrian Prantl auto Res = Visiting.insert(Var); 69003dd6f57SAdrian Prantl if (!Res.second) { 69103dd6f57SAdrian Prantl assert(false && "dependency cycle in local variables"); 69203dd6f57SAdrian Prantl return Result; 69303dd6f57SAdrian Prantl } 69403dd6f57SAdrian Prantl 69503dd6f57SAdrian Prantl // Push dependencies and this node onto the worklist, so that this node is 69603dd6f57SAdrian Prantl // visited again after all of its dependencies are handled. 69703dd6f57SAdrian Prantl WorkList.push_back({Var, 1}); 69803dd6f57SAdrian Prantl for (auto *Dependency : dependencies(Var)) { 69903dd6f57SAdrian Prantl auto Dep = dyn_cast_or_null<const DILocalVariable>(Dependency); 70003dd6f57SAdrian Prantl WorkList.push_back({DbgVar[Dep], 0}); 70103dd6f57SAdrian Prantl } 70203dd6f57SAdrian Prantl } 70303dd6f57SAdrian Prantl return Result; 704c929f7adSAdrian Prantl } 705c929f7adSAdrian Prantl 706827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::createScopeChildrenDIE(LexicalScope *Scope, 707827200c8SDuncan P. N. Exon Smith SmallVectorImpl<DIE *> &Children, 7082195e136SDavid Blaikie bool *HasNonScopeChildren) { 7092195e136SDavid Blaikie assert(Children.empty()); 7108b2fdb83SDavid Blaikie DIE *ObjectPointer = nullptr; 7118b2fdb83SDavid Blaikie 712c929f7adSAdrian Prantl // Emit function arguments (order is significant). 713c929f7adSAdrian Prantl auto Vars = DU->getScopeVariables().lookup(Scope); 714c929f7adSAdrian Prantl for (auto &DV : Vars.Args) 715c929f7adSAdrian Prantl Children.push_back(constructVariableDIE(*DV.second, *Scope, ObjectPointer)); 716c929f7adSAdrian Prantl 717c929f7adSAdrian Prantl // Emit local variables. 71803dd6f57SAdrian Prantl auto Locals = sortLocalVars(Vars.Locals); 71903dd6f57SAdrian Prantl for (DbgVariable *DV : Locals) 7208b2fdb83SDavid Blaikie Children.push_back(constructVariableDIE(*DV, *Scope, ObjectPointer)); 7218b2fdb83SDavid Blaikie 7222195e136SDavid Blaikie // Skip imported directives in gmlt-like data. 7232195e136SDavid Blaikie if (!includeMinimalInlineScopes()) { 7242195e136SDavid Blaikie // There is no need to emit empty lexical block DIE. 7252195e136SDavid Blaikie for (const auto *IE : ImportedEntities[Scope->getScopeNode()]) 7262195e136SDavid Blaikie Children.push_back( 7272195e136SDavid Blaikie constructImportedEntityDIE(cast<DIImportedEntity>(IE))); 7282195e136SDavid Blaikie } 7292195e136SDavid Blaikie 7302195e136SDavid Blaikie if (HasNonScopeChildren) 7312195e136SDavid Blaikie *HasNonScopeChildren = !Children.empty(); 7328b2fdb83SDavid Blaikie 7332532ac88SHsiangkai Wang for (DbgLabel *DL : DU->getScopeLabels().lookup(Scope)) 7342532ac88SHsiangkai Wang Children.push_back(constructLabelDIE(*DL, *Scope)); 7352532ac88SHsiangkai Wang 7368b2fdb83SDavid Blaikie for (LexicalScope *LS : Scope->getChildren()) 7378b2fdb83SDavid Blaikie constructScopeDIE(LS, Children); 7388b2fdb83SDavid Blaikie 7398b2fdb83SDavid Blaikie return ObjectPointer; 7408b2fdb83SDavid Blaikie } 7418b2fdb83SDavid Blaikie 7425931b4e5SVedant Kumar DIE &DwarfCompileUnit::constructSubprogramScopeDIE(const DISubprogram *Sub, 7435931b4e5SVedant Kumar LexicalScope *Scope) { 7441d072348SDavid Blaikie DIE &ScopeDIE = updateSubprogramScopeDIE(Sub); 7451d072348SDavid Blaikie 7463e3eb33eSDavid Blaikie if (Scope) { 7473e3eb33eSDavid Blaikie assert(!Scope->getInlinedAt()); 7483e3eb33eSDavid Blaikie assert(!Scope->isAbstractScope()); 7491dd573dbSDavid Blaikie // Collect lexical scope children first. 7501dd573dbSDavid Blaikie // ObjectPointer might be a local (non-argument) local variable if it's a 7511dd573dbSDavid Blaikie // block's synthetic this pointer. 7521dd573dbSDavid Blaikie if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, ScopeDIE)) 7531dd573dbSDavid Blaikie addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer); 7543e3eb33eSDavid Blaikie } 7553e3eb33eSDavid Blaikie 7563e3eb33eSDavid Blaikie // If this is a variadic function, add an unspecified parameter. 7573e3eb33eSDavid Blaikie DITypeRefArray FnArgs = Sub->getType()->getTypeArray(); 7581dd573dbSDavid Blaikie 7591d072348SDavid Blaikie // If we have a single element of null, it is a function that returns void. 7601d072348SDavid Blaikie // If we have more than one elements and the last one is null, it is a 7611d072348SDavid Blaikie // variadic function. 762000fa2c6SDuncan P. N. Exon Smith if (FnArgs.size() > 1 && !FnArgs[FnArgs.size() - 1] && 7633a443c29SDavid Blaikie !includeMinimalInlineScopes()) 764827200c8SDuncan P. N. Exon Smith ScopeDIE.addChild( 765827200c8SDuncan P. N. Exon Smith DIE::get(DIEValueAllocator, dwarf::DW_TAG_unspecified_parameters)); 7665931b4e5SVedant Kumar 7675931b4e5SVedant Kumar return ScopeDIE; 7681d072348SDavid Blaikie } 7691d072348SDavid Blaikie 77078b65b6fSDavid Blaikie DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope, 77178b65b6fSDavid Blaikie DIE &ScopeDIE) { 77278b65b6fSDavid Blaikie // We create children when the scope DIE is not null. 773827200c8SDuncan P. N. Exon Smith SmallVector<DIE *, 8> Children; 77478b65b6fSDavid Blaikie DIE *ObjectPointer = createScopeChildrenDIE(Scope, Children); 77578b65b6fSDavid Blaikie 77678b65b6fSDavid Blaikie // Add children 77778b65b6fSDavid Blaikie for (auto &I : Children) 77878b65b6fSDavid Blaikie ScopeDIE.addChild(std::move(I)); 77978b65b6fSDavid Blaikie 78078b65b6fSDavid Blaikie return ObjectPointer; 78178b65b6fSDavid Blaikie } 78278b65b6fSDavid Blaikie 78354511353SDehao Chen void DwarfCompileUnit::constructAbstractSubprogramScopeDIE( 78454511353SDehao Chen LexicalScope *Scope) { 785488393f8SDavid Blaikie DIE *&AbsDef = getAbstractSPDies()[Scope->getScopeNode()]; 78649be5b35SDavid Blaikie if (AbsDef) 78749be5b35SDavid Blaikie return; 78849be5b35SDavid Blaikie 789a9308c49SDuncan P. N. Exon Smith auto *SP = cast<DISubprogram>(Scope->getScopeNode()); 79058410f24SDavid Blaikie 79158410f24SDavid Blaikie DIE *ContextDIE; 792294e6895SJonas Devlieghere DwarfCompileUnit *ContextCU = this; 79358410f24SDavid Blaikie 7943a443c29SDavid Blaikie if (includeMinimalInlineScopes()) 7953a443c29SDavid Blaikie ContextDIE = &getUnitDie(); 79658410f24SDavid Blaikie // Some of this is duplicated from DwarfUnit::getOrCreateSubprogramDIE, with 7977c60f20eSDuncan P. N. Exon Smith // the important distinction that the debug node is not associated with the 7987c60f20eSDuncan P. N. Exon Smith // DIE (since the debug node will be associated with the concrete DIE, if 79958410f24SDavid Blaikie // any). It could be refactored to some common utility function. 800537b4a81SDuncan P. N. Exon Smith else if (auto *SPDecl = SP->getDeclaration()) { 80158410f24SDavid Blaikie ContextDIE = &getUnitDie(); 80258410f24SDavid Blaikie getOrCreateSubprogramDIE(SPDecl); 803294e6895SJonas Devlieghere } else { 804537b4a81SDuncan P. N. Exon Smith ContextDIE = getOrCreateContextDIE(resolve(SP->getScope())); 805294e6895SJonas Devlieghere // The scope may be shared with a subprogram that has already been 806294e6895SJonas Devlieghere // constructed in another CU, in which case we need to construct this 807294e6895SJonas Devlieghere // subprogram in the same CU. 808294e6895SJonas Devlieghere ContextCU = DD->lookupCU(ContextDIE->getUnitDie()); 809294e6895SJonas Devlieghere } 81058410f24SDavid Blaikie 8117c60f20eSDuncan P. N. Exon Smith // Passing null as the associated node because the abstract definition 81258410f24SDavid Blaikie // shouldn't be found by lookup. 813294e6895SJonas Devlieghere AbsDef = &ContextCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, nullptr); 814294e6895SJonas Devlieghere ContextCU->applySubprogramAttributesToDefinition(SP, *AbsDef); 81558410f24SDavid Blaikie 816294e6895SJonas Devlieghere if (!ContextCU->includeMinimalInlineScopes()) 817294e6895SJonas Devlieghere ContextCU->addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined); 818294e6895SJonas Devlieghere if (DIE *ObjectPointer = ContextCU->createAndAddScopeChildren(Scope, *AbsDef)) 819294e6895SJonas Devlieghere ContextCU->addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer); 82058410f24SDavid Blaikie } 82158410f24SDavid Blaikie 8225931b4e5SVedant Kumar DIE &DwarfCompileUnit::constructCallSiteEntryDIE(DIE &ScopeDIE, 8235931b4e5SVedant Kumar const DISubprogram &CalleeSP, 8245931b4e5SVedant Kumar bool IsTail, 82574533bd3SVedant Kumar const MCExpr *PCOffset) { 8265931b4e5SVedant Kumar // Insert a call site entry DIE within ScopeDIE. 8275931b4e5SVedant Kumar DIE &CallSiteDIE = 8285931b4e5SVedant Kumar createAndAddDIE(dwarf::DW_TAG_call_site, ScopeDIE, nullptr); 8295931b4e5SVedant Kumar 8305931b4e5SVedant Kumar // For the purposes of showing tail call frames in backtraces, a key piece of 8315931b4e5SVedant Kumar // information is DW_AT_call_origin, a pointer to the callee DIE. 8325931b4e5SVedant Kumar DIE *CalleeDIE = getOrCreateSubprogramDIE(&CalleeSP); 8335931b4e5SVedant Kumar assert(CalleeDIE && "Could not create DIE for call site entry origin"); 8345931b4e5SVedant Kumar addDIEEntry(CallSiteDIE, dwarf::DW_AT_call_origin, *CalleeDIE); 8355931b4e5SVedant Kumar 8365931b4e5SVedant Kumar if (IsTail) { 8375931b4e5SVedant Kumar // Attach DW_AT_call_tail_call to tail calls for standards compliance. 8385931b4e5SVedant Kumar addFlag(CallSiteDIE, dwarf::DW_AT_call_tail_call); 8395931b4e5SVedant Kumar } else { 8405931b4e5SVedant Kumar // Attach the return PC to allow the debugger to disambiguate call paths 8415931b4e5SVedant Kumar // from one function to another. 84274533bd3SVedant Kumar assert(PCOffset && "Missing return PC information for a call"); 84374533bd3SVedant Kumar addAddressExpr(CallSiteDIE, dwarf::DW_AT_call_return_pc, PCOffset); 8445931b4e5SVedant Kumar } 8455931b4e5SVedant Kumar return CallSiteDIE; 8465931b4e5SVedant Kumar } 8475931b4e5SVedant Kumar 848827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::constructImportedEntityDIE( 849827200c8SDuncan P. N. Exon Smith const DIImportedEntity *Module) { 85072da9391SAmjad Aboud DIE *IMDie = DIE::get(DIEValueAllocator, (dwarf::Tag)Module->getTag()); 85172da9391SAmjad Aboud insertDIE(Module, IMDie); 852987fe227SFrederic Riss DIE *EntityDie; 853de8e4273SDuncan P. N. Exon Smith auto *Entity = resolve(Module->getEntity()); 854a9308c49SDuncan P. N. Exon Smith if (auto *NS = dyn_cast<DINamespace>(Entity)) 855e686f159SDuncan P. N. Exon Smith EntityDie = getOrCreateNameSpace(NS); 85608a388baSAdrian Prantl else if (auto *M = dyn_cast<DIModule>(Entity)) 85708a388baSAdrian Prantl EntityDie = getOrCreateModule(M); 858a9308c49SDuncan P. N. Exon Smith else if (auto *SP = dyn_cast<DISubprogram>(Entity)) 859e686f159SDuncan P. N. Exon Smith EntityDie = getOrCreateSubprogramDIE(SP); 860a9308c49SDuncan P. N. Exon Smith else if (auto *T = dyn_cast<DIType>(Entity)) 861e686f159SDuncan P. N. Exon Smith EntityDie = getOrCreateTypeDIE(T); 862a9308c49SDuncan P. N. Exon Smith else if (auto *GV = dyn_cast<DIGlobalVariable>(Entity)) 863bceaaa96SAdrian Prantl EntityDie = getOrCreateGlobalVariableDIE(GV, {}); 864987fe227SFrederic Riss else 865987fe227SFrederic Riss EntityDie = getDIE(Entity); 866987fe227SFrederic Riss assert(EntityDie); 867612e89d7SPaul Robinson addSourceLine(*IMDie, Module->getLine(), Module->getFile()); 868987fe227SFrederic Riss addDIEEntry(*IMDie, dwarf::DW_AT_import, *EntityDie); 869de8e4273SDuncan P. N. Exon Smith StringRef Name = Module->getName(); 870987fe227SFrederic Riss if (!Name.empty()) 871987fe227SFrederic Riss addString(*IMDie, dwarf::DW_AT_name, Name); 872987fe227SFrederic Riss 873987fe227SFrederic Riss return IMDie; 874987fe227SFrederic Riss } 875987fe227SFrederic Riss 876a9308c49SDuncan P. N. Exon Smith void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP) { 87772da9391SAmjad Aboud DIE *D = getDIE(SP); 878488393f8SDavid Blaikie if (DIE *AbsSPDIE = getAbstractSPDies().lookup(SP)) { 87972da9391SAmjad Aboud if (D) 8804191cbceSDavid Blaikie // If this subprogram has an abstract definition, reference that 8814191cbceSDavid Blaikie addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE); 88272da9391SAmjad Aboud } else { 8833e3eb33eSDavid Blaikie assert(D || includeMinimalInlineScopes()); 88472da9391SAmjad Aboud if (D) 8854191cbceSDavid Blaikie // And attach the attributes 8864191cbceSDavid Blaikie applySubprogramAttributesToDefinition(SP, *D); 8874191cbceSDavid Blaikie } 8884191cbceSDavid Blaikie } 8894191cbceSDavid Blaikie 8902532ac88SHsiangkai Wang void DwarfCompileUnit::finishEntityDefinition(const DbgEntity *Entity) { 8912532ac88SHsiangkai Wang DbgEntity *AbsEntity = getExistingAbstractEntity(Entity->getEntity()); 8922532ac88SHsiangkai Wang 8932532ac88SHsiangkai Wang auto *Die = Entity->getDIE(); 8942532ac88SHsiangkai Wang /// Label may be used to generate DW_AT_low_pc, so put it outside 8952532ac88SHsiangkai Wang /// if/else block. 8962532ac88SHsiangkai Wang const DbgLabel *Label = nullptr; 8972532ac88SHsiangkai Wang if (AbsEntity && AbsEntity->getDIE()) { 8982532ac88SHsiangkai Wang addDIEEntry(*Die, dwarf::DW_AT_abstract_origin, *AbsEntity->getDIE()); 8992532ac88SHsiangkai Wang Label = dyn_cast<const DbgLabel>(Entity); 9002532ac88SHsiangkai Wang } else { 9012532ac88SHsiangkai Wang if (const DbgVariable *Var = dyn_cast<const DbgVariable>(Entity)) 9022532ac88SHsiangkai Wang applyVariableAttributes(*Var, *Die); 9032532ac88SHsiangkai Wang else if ((Label = dyn_cast<const DbgLabel>(Entity))) 9042532ac88SHsiangkai Wang applyLabelAttributes(*Label, *Die); 9052532ac88SHsiangkai Wang else 9062532ac88SHsiangkai Wang llvm_unreachable("DbgEntity must be DbgVariable or DbgLabel."); 907488393f8SDavid Blaikie } 908488393f8SDavid Blaikie 90955321d82SHsiangkai Wang if (Label) 91055321d82SHsiangkai Wang if (const auto *Sym = Label->getSymbol()) 9112532ac88SHsiangkai Wang addLabelAddress(*Die, dwarf::DW_AT_low_pc, Sym); 9122532ac88SHsiangkai Wang } 913488393f8SDavid Blaikie 9142532ac88SHsiangkai Wang DbgEntity *DwarfCompileUnit::getExistingAbstractEntity(const DINode *Node) { 9152532ac88SHsiangkai Wang auto &AbstractEntities = getAbstractEntities(); 9162532ac88SHsiangkai Wang auto I = AbstractEntities.find(Node); 9172532ac88SHsiangkai Wang if (I != AbstractEntities.end()) 918488393f8SDavid Blaikie return I->second.get(); 919488393f8SDavid Blaikie return nullptr; 920488393f8SDavid Blaikie } 921488393f8SDavid Blaikie 9222532ac88SHsiangkai Wang void DwarfCompileUnit::createAbstractEntity(const DINode *Node, 923488393f8SDavid Blaikie LexicalScope *Scope) { 924488393f8SDavid Blaikie assert(Scope && Scope->isAbstractScope()); 9252532ac88SHsiangkai Wang auto &Entity = getAbstractEntities()[Node]; 9262532ac88SHsiangkai Wang if (isa<const DILocalVariable>(Node)) { 9272532ac88SHsiangkai Wang Entity = llvm::make_unique<DbgVariable>( 9282532ac88SHsiangkai Wang cast<const DILocalVariable>(Node), nullptr /* IA */);; 9292532ac88SHsiangkai Wang DU->addScopeVariable(Scope, cast<DbgVariable>(Entity.get())); 9302532ac88SHsiangkai Wang } else if (isa<const DILabel>(Node)) { 9312532ac88SHsiangkai Wang Entity = llvm::make_unique<DbgLabel>( 9322532ac88SHsiangkai Wang cast<const DILabel>(Node), nullptr /* IA */); 9332532ac88SHsiangkai Wang DU->addScopeLabel(Scope, cast<DbgLabel>(Entity.get())); 9342532ac88SHsiangkai Wang } 935488393f8SDavid Blaikie } 936488393f8SDavid Blaikie 937063d725fSRafael Espindola void DwarfCompileUnit::emitHeader(bool UseOffsets) { 938b6726a9eSDavid Blaikie // Don't bother labeling the .dwo unit, as its offset isn't used. 939bff36086SAlexey Bataev if (!Skeleton && !DD->useSectionsAsReferences()) { 9409ab09237SRafael Espindola LabelBegin = Asm->createTempSymbol("cu_begin"); 9419ff69c8fSLang Hames Asm->OutStreamer->EmitLabel(LabelBegin); 9423c311148SRafael Espindola } 943ae57e66eSDavid Blaikie 944cddd6044SPaul Robinson dwarf::UnitType UT = Skeleton ? dwarf::DW_UT_split_compile 945cddd6044SPaul Robinson : DD->useSplitDwarf() ? dwarf::DW_UT_skeleton 946cddd6044SPaul Robinson : dwarf::DW_UT_compile; 947cddd6044SPaul Robinson DwarfUnit::emitCommonHeader(UseOffsets, UT); 948543c0e1dSPaul Robinson if (DD->getDwarfVersion() >= 5 && UT != dwarf::DW_UT_compile) 949543c0e1dSPaul Robinson Asm->emitInt64(getDWOId()); 950ae57e66eSDavid Blaikie } 951ae57e66eSDavid Blaikie 952b52e2366SPeter Collingbourne bool DwarfCompileUnit::hasDwarfPubSections() const { 95366cf14d0SDavid Blaikie switch (CUNode->getNameTableKind()) { 95466cf14d0SDavid Blaikie case DICompileUnit::DebugNameTableKind::None: 95566cf14d0SDavid Blaikie return false; 956b52e2366SPeter Collingbourne // Opting in to GNU Pubnames/types overrides the default to ensure these are 957b52e2366SPeter Collingbourne // generated for things like Gold's gdb_index generation. 95866cf14d0SDavid Blaikie case DICompileUnit::DebugNameTableKind::GNU: 959b52e2366SPeter Collingbourne return true; 96066cf14d0SDavid Blaikie case DICompileUnit::DebugNameTableKind::Default: 9610e03047eSDavid Blaikie return DD->tuneForGDB() && !includeMinimalInlineScopes() && 9620e03047eSDavid Blaikie !CUNode->isDebugDirectivesOnly(); 963b52e2366SPeter Collingbourne } 96422d580f2SSimon Pilgrim llvm_unreachable("Unhandled DICompileUnit::DebugNameTableKind enum"); 96566cf14d0SDavid Blaikie } 966b52e2366SPeter Collingbourne 967192b45c1SDavid Blaikie /// addGlobalName - Add a new global name to the compile unit. 968a0e3c751SDavid Blaikie void DwarfCompileUnit::addGlobalName(StringRef Name, const DIE &Die, 969a9308c49SDuncan P. N. Exon Smith const DIScope *Context) { 970b52e2366SPeter Collingbourne if (!hasDwarfPubSections()) 971192b45c1SDavid Blaikie return; 972192b45c1SDavid Blaikie std::string FullName = getParentContextString(Context) + Name.str(); 973192b45c1SDavid Blaikie GlobalNames[FullName] = &Die; 974192b45c1SDavid Blaikie } 975192b45c1SDavid Blaikie 976a0e3c751SDavid Blaikie void DwarfCompileUnit::addGlobalNameForTypeUnit(StringRef Name, 977a0e3c751SDavid Blaikie const DIScope *Context) { 978b52e2366SPeter Collingbourne if (!hasDwarfPubSections()) 979a0e3c751SDavid Blaikie return; 980a0e3c751SDavid Blaikie std::string FullName = getParentContextString(Context) + Name.str(); 981a0e3c751SDavid Blaikie // Insert, allowing the entry to remain as-is if it's already present 982a0e3c751SDavid Blaikie // This way the CU-level type DIE is preferred over the "can't describe this 983a0e3c751SDavid Blaikie // type as a unit offset because it's not really in the CU at all, it's only 984a0e3c751SDavid Blaikie // in a type unit" 985a0e3c751SDavid Blaikie GlobalNames.insert(std::make_pair(std::move(FullName), &getUnitDie())); 986a0e3c751SDavid Blaikie } 987a0e3c751SDavid Blaikie 988192b45c1SDavid Blaikie /// Add a new global type to the unit. 989a9308c49SDuncan P. N. Exon Smith void DwarfCompileUnit::addGlobalType(const DIType *Ty, const DIE &Die, 990a9308c49SDuncan P. N. Exon Smith const DIScope *Context) { 991b52e2366SPeter Collingbourne if (!hasDwarfPubSections()) 992192b45c1SDavid Blaikie return; 993b1055640SDuncan P. N. Exon Smith std::string FullName = getParentContextString(Context) + Ty->getName().str(); 994192b45c1SDavid Blaikie GlobalTypes[FullName] = &Die; 995192b45c1SDavid Blaikie } 996ae57e66eSDavid Blaikie 997a0e3c751SDavid Blaikie void DwarfCompileUnit::addGlobalTypeUnitType(const DIType *Ty, 998a0e3c751SDavid Blaikie const DIScope *Context) { 999b52e2366SPeter Collingbourne if (!hasDwarfPubSections()) 1000a0e3c751SDavid Blaikie return; 1001a0e3c751SDavid Blaikie std::string FullName = getParentContextString(Context) + Ty->getName().str(); 1002a0e3c751SDavid Blaikie // Insert, allowing the entry to remain as-is if it's already present 1003a0e3c751SDavid Blaikie // This way the CU-level type DIE is preferred over the "can't describe this 1004a0e3c751SDavid Blaikie // type as a unit offset because it's not really in the CU at all, it's only 1005a0e3c751SDavid Blaikie // in a type unit" 1006a0e3c751SDavid Blaikie GlobalTypes.insert(std::make_pair(std::move(FullName), &getUnitDie())); 1007a0e3c751SDavid Blaikie } 1008a0e3c751SDavid Blaikie 10097d48be2bSDavid Blaikie /// addVariableAddress - Add DW_AT_location attribute for a 10107d48be2bSDavid Blaikie /// DbgVariable based on provided MachineLocation. 10117d48be2bSDavid Blaikie void DwarfCompileUnit::addVariableAddress(const DbgVariable &DV, DIE &Die, 10127d48be2bSDavid Blaikie MachineLocation Location) { 1013a2f9e3a6SAdrian Prantl // addBlockByrefAddress is obsolete and will be removed soon. 1014a2f9e3a6SAdrian Prantl // The clang frontend always generates block byref variables with a 1015a2f9e3a6SAdrian Prantl // complex expression that encodes exactly what addBlockByrefAddress 1016a2f9e3a6SAdrian Prantl // would do. 1017a2f9e3a6SAdrian Prantl assert((!DV.isBlockByrefVariable() || DV.hasComplexAddress()) && 1018a2f9e3a6SAdrian Prantl "block byref variable without a complex expression"); 1019e6cc531bSDuncan P. N. Exon Smith if (DV.hasComplexAddress()) 10207d48be2bSDavid Blaikie addComplexAddress(DV, Die, dwarf::DW_AT_location, Location); 10217d48be2bSDavid Blaikie else 10225883af3fSAdrian Prantl addAddress(Die, dwarf::DW_AT_location, Location); 10237d48be2bSDavid Blaikie } 1024f7435ee6SDavid Blaikie 1025f7435ee6SDavid Blaikie /// Add an address attribute to a die based on the location provided. 1026f7435ee6SDavid Blaikie void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute, 10275883af3fSAdrian Prantl const MachineLocation &Location) { 1028e7e1d0c7SDuncan P. N. Exon Smith DIELoc *Loc = new (DIEValueAllocator) DIELoc; 1029956484b7SAdrian Prantl DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); 1030c12cee36SAdrian Prantl if (Location.isIndirect()) 1031c12cee36SAdrian Prantl DwarfExpr.setMemoryLocationKind(); 1032f7435ee6SDavid Blaikie 10332049c0d7SAdrian Prantl DIExpressionCursor Cursor({}); 1034956484b7SAdrian Prantl const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo(); 1035c12cee36SAdrian Prantl if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg())) 1036ab255fcdSAdrian Prantl return; 1037956484b7SAdrian Prantl DwarfExpr.addExpression(std::move(Cursor)); 1038ab255fcdSAdrian Prantl 1039f7435ee6SDavid Blaikie // Now attach the location information to the DIE. 1040956484b7SAdrian Prantl addBlock(Die, Attribute, DwarfExpr.finalize()); 1041f7435ee6SDavid Blaikie } 104277895fb2SDavid Blaikie 104377895fb2SDavid Blaikie /// Start with the address based on the location provided, and generate the 104477895fb2SDavid Blaikie /// DWARF information necessary to find the actual variable given the extra 104577895fb2SDavid Blaikie /// address information encoded in the DbgVariable, starting from the starting 104677895fb2SDavid Blaikie /// location. Add the DWARF information to the die. 104777895fb2SDavid Blaikie void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die, 104877895fb2SDavid Blaikie dwarf::Attribute Attribute, 104977895fb2SDavid Blaikie const MachineLocation &Location) { 1050e7e1d0c7SDuncan P. N. Exon Smith DIELoc *Loc = new (DIEValueAllocator) DIELoc; 10517813d9c9SAdrian Prantl DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); 1052956484b7SAdrian Prantl const DIExpression *DIExpr = DV.getSingleExpression(); 1053956484b7SAdrian Prantl DwarfExpr.addFragmentOffset(DIExpr); 1054c12cee36SAdrian Prantl if (Location.isIndirect()) 1055c12cee36SAdrian Prantl DwarfExpr.setMemoryLocationKind(); 1056956484b7SAdrian Prantl 10572049c0d7SAdrian Prantl DIExpressionCursor Cursor(DIExpr); 105896c9ae6aSPeter Collingbourne const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo(); 1059c12cee36SAdrian Prantl if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg())) 106054286bdaSAdrian Prantl return; 1061956484b7SAdrian Prantl DwarfExpr.addExpression(std::move(Cursor)); 106277895fb2SDavid Blaikie 106377895fb2SDavid Blaikie // Now attach the location information to the DIE. 1064956484b7SAdrian Prantl addBlock(Die, Attribute, DwarfExpr.finalize()); 106577895fb2SDavid Blaikie } 10664bc0881aSDavid Blaikie 10674bc0881aSDavid Blaikie /// Add a Dwarf loclistptr attribute data and value. 10684bc0881aSDavid Blaikie void DwarfCompileUnit::addLocationList(DIE &Die, dwarf::Attribute Attribute, 10694bc0881aSDavid Blaikie unsigned Index) { 10704bc0881aSDavid Blaikie dwarf::Form Form = DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset 10714bc0881aSDavid Blaikie : dwarf::DW_FORM_data4; 10724fb1f9cdSDuncan P. N. Exon Smith Die.addValue(DIEValueAllocator, Attribute, Form, DIELocList(Index)); 10734bc0881aSDavid Blaikie } 107402a6333bSDavid Blaikie 10758c485b5dSDavid Blaikie void DwarfCompileUnit::applyVariableAttributes(const DbgVariable &Var, 107602a6333bSDavid Blaikie DIE &VariableDie) { 107702a6333bSDavid Blaikie StringRef Name = Var.getName(); 107802a6333bSDavid Blaikie if (!Name.empty()) 107902a6333bSDavid Blaikie addString(VariableDie, dwarf::DW_AT_name, Name); 10803c989984SVictor Leschuk const auto *DIVar = Var.getVariable(); 10813c989984SVictor Leschuk if (DIVar) 10823c989984SVictor Leschuk if (uint32_t AlignInBytes = DIVar->getAlignInBytes()) 10833c989984SVictor Leschuk addUInt(VariableDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata, 10843c989984SVictor Leschuk AlignInBytes); 10853c989984SVictor Leschuk 10863c989984SVictor Leschuk addSourceLine(VariableDie, DIVar); 108702a6333bSDavid Blaikie addType(VariableDie, Var.getType()); 108802a6333bSDavid Blaikie if (Var.isArtificial()) 108902a6333bSDavid Blaikie addFlag(VariableDie, dwarf::DW_AT_artificial); 109002a6333bSDavid Blaikie } 109197802080SDavid Blaikie 10922532ac88SHsiangkai Wang void DwarfCompileUnit::applyLabelAttributes(const DbgLabel &Label, 10932532ac88SHsiangkai Wang DIE &LabelDie) { 10942532ac88SHsiangkai Wang StringRef Name = Label.getName(); 10952532ac88SHsiangkai Wang if (!Name.empty()) 10962532ac88SHsiangkai Wang addString(LabelDie, dwarf::DW_AT_name, Name); 10972532ac88SHsiangkai Wang const auto *DILabel = Label.getLabel(); 10982532ac88SHsiangkai Wang addSourceLine(LabelDie, DILabel); 10992532ac88SHsiangkai Wang } 11002532ac88SHsiangkai Wang 110197802080SDavid Blaikie /// Add a Dwarf expression attribute data and value. 110297802080SDavid Blaikie void DwarfCompileUnit::addExpr(DIELoc &Die, dwarf::Form Form, 110397802080SDavid Blaikie const MCExpr *Expr) { 11044fb1f9cdSDuncan P. N. Exon Smith Die.addValue(DIEValueAllocator, (dwarf::Attribute)0, Form, DIEExpr(Expr)); 110597802080SDavid Blaikie } 11063363a57cSDavid Blaikie 110774533bd3SVedant Kumar void DwarfCompileUnit::addAddressExpr(DIE &Die, dwarf::Attribute Attribute, 110874533bd3SVedant Kumar const MCExpr *Expr) { 110974533bd3SVedant Kumar Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_addr, 111074533bd3SVedant Kumar DIEExpr(Expr)); 111174533bd3SVedant Kumar } 111274533bd3SVedant Kumar 11132fbe1354SDuncan P. N. Exon Smith void DwarfCompileUnit::applySubprogramAttributesToDefinition( 1114a9308c49SDuncan P. N. Exon Smith const DISubprogram *SP, DIE &SPDie) { 1115537b4a81SDuncan P. N. Exon Smith auto *SPDecl = SP->getDeclaration(); 1116be9e4fe7SDuncan P. N. Exon Smith auto *Context = resolve(SPDecl ? SPDecl->getScope() : SP->getScope()); 11173a443c29SDavid Blaikie applySubprogramAttributes(SP, SPDie, includeMinimalInlineScopes()); 1118537b4a81SDuncan P. N. Exon Smith addGlobalName(SP->getName(), SPDie, Context); 11193363a57cSDavid Blaikie } 1120cafd962dSDavid Blaikie 1121cafd962dSDavid Blaikie bool DwarfCompileUnit::isDwoUnit() const { 1122cafd962dSDavid Blaikie return DD->useSplitDwarf() && Skeleton; 1123cafd962dSDavid Blaikie } 11243a443c29SDavid Blaikie 11253a443c29SDavid Blaikie bool DwarfCompileUnit::includeMinimalInlineScopes() const { 1126b939a257SAdrian Prantl return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly || 11273a443c29SDavid Blaikie (DD->useSplitDwarf() && !Skeleton); 11283a443c29SDavid Blaikie } 1129