10b57cec5SDimitry Andric //===- llvm/CodeGen/DwarfCompileUnit.cpp - Dwarf Compile Units ------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file contains support for constructing a dwarf compile unit. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "DwarfCompileUnit.h" 140b57cec5SDimitry Andric #include "AddressPool.h" 150b57cec5SDimitry Andric #include "DwarfDebug.h" 160b57cec5SDimitry Andric #include "DwarfExpression.h" 170b57cec5SDimitry Andric #include "DwarfUnit.h" 180b57cec5SDimitry Andric #include "llvm/ADT/None.h" 190b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 200b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h" 210b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 220b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 230b57cec5SDimitry Andric #include "llvm/BinaryFormat/Dwarf.h" 240b57cec5SDimitry Andric #include "llvm/CodeGen/AsmPrinter.h" 250b57cec5SDimitry Andric #include "llvm/CodeGen/DIE.h" 260b57cec5SDimitry Andric #include "llvm/CodeGen/LexicalScopes.h" 270b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 280b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h" 290b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h" 300b57cec5SDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h" 310b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h" 320b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h" 330b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 340b57cec5SDimitry Andric #include "llvm/IR/DebugInfo.h" 350b57cec5SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h" 360b57cec5SDimitry Andric #include "llvm/IR/GlobalVariable.h" 370b57cec5SDimitry Andric #include "llvm/MC/MCSection.h" 380b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 390b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h" 400b57cec5SDimitry Andric #include "llvm/MC/MachineLocation.h" 410b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 420b57cec5SDimitry Andric #include "llvm/Target/TargetLoweringObjectFile.h" 430b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h" 440b57cec5SDimitry Andric #include "llvm/Target/TargetOptions.h" 450b57cec5SDimitry Andric #include <algorithm> 460b57cec5SDimitry Andric #include <cassert> 470b57cec5SDimitry Andric #include <cstdint> 480b57cec5SDimitry Andric #include <iterator> 490b57cec5SDimitry Andric #include <memory> 500b57cec5SDimitry Andric #include <string> 510b57cec5SDimitry Andric #include <utility> 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric using namespace llvm; 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric DwarfCompileUnit::DwarfCompileUnit(unsigned UID, const DICompileUnit *Node, 560b57cec5SDimitry Andric AsmPrinter *A, DwarfDebug *DW, 570b57cec5SDimitry Andric DwarfFile *DWU) 580b57cec5SDimitry Andric : DwarfUnit(dwarf::DW_TAG_compile_unit, Node, A, DW, DWU), UniqueID(UID) { 590b57cec5SDimitry Andric insertDIE(Node, &getUnitDie()); 600b57cec5SDimitry Andric MacroLabelBegin = Asm->createTempSymbol("cu_macro_begin"); 610b57cec5SDimitry Andric } 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric /// addLabelAddress - Add a dwarf label attribute data and value using 640b57cec5SDimitry Andric /// DW_FORM_addr or DW_FORM_GNU_addr_index. 650b57cec5SDimitry Andric void DwarfCompileUnit::addLabelAddress(DIE &Die, dwarf::Attribute Attribute, 660b57cec5SDimitry Andric const MCSymbol *Label) { 670b57cec5SDimitry Andric // Don't use the address pool in non-fission or in the skeleton unit itself. 680b57cec5SDimitry Andric // FIXME: Once GDB supports this, it's probably worthwhile using the address 690b57cec5SDimitry Andric // pool from the skeleton - maybe even in non-fission (possibly fewer 700b57cec5SDimitry Andric // relocations by sharing them in the pool, but we have other ideas about how 710b57cec5SDimitry Andric // to reduce the number of relocations as well/instead). 720b57cec5SDimitry Andric if ((!DD->useSplitDwarf() || !Skeleton) && DD->getDwarfVersion() < 5) 730b57cec5SDimitry Andric return addLocalLabelAddress(Die, Attribute, Label); 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric if (Label) 760b57cec5SDimitry Andric DD->addArangeLabel(SymbolCU(this, Label)); 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric unsigned idx = DD->getAddressPool().getIndex(Label); 790b57cec5SDimitry Andric Die.addValue(DIEValueAllocator, Attribute, 800b57cec5SDimitry Andric DD->getDwarfVersion() >= 5 ? dwarf::DW_FORM_addrx 810b57cec5SDimitry Andric : dwarf::DW_FORM_GNU_addr_index, 820b57cec5SDimitry Andric DIEInteger(idx)); 830b57cec5SDimitry Andric } 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric void DwarfCompileUnit::addLocalLabelAddress(DIE &Die, 860b57cec5SDimitry Andric dwarf::Attribute Attribute, 870b57cec5SDimitry Andric const MCSymbol *Label) { 880b57cec5SDimitry Andric if (Label) 890b57cec5SDimitry Andric DD->addArangeLabel(SymbolCU(this, Label)); 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric if (Label) 920b57cec5SDimitry Andric Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_addr, 930b57cec5SDimitry Andric DIELabel(Label)); 940b57cec5SDimitry Andric else 950b57cec5SDimitry Andric Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_addr, 960b57cec5SDimitry Andric DIEInteger(0)); 970b57cec5SDimitry Andric } 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric unsigned DwarfCompileUnit::getOrCreateSourceID(const DIFile *File) { 1000b57cec5SDimitry Andric // If we print assembly, we can't separate .file entries according to 1010b57cec5SDimitry Andric // compile units. Thus all files will belong to the default compile unit. 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric // FIXME: add a better feature test than hasRawTextSupport. Even better, 1040b57cec5SDimitry Andric // extend .file to support this. 1050b57cec5SDimitry Andric unsigned CUID = Asm->OutStreamer->hasRawTextSupport() ? 0 : getUniqueID(); 1060b57cec5SDimitry Andric if (!File) 1070b57cec5SDimitry Andric return Asm->OutStreamer->EmitDwarfFileDirective(0, "", "", None, None, CUID); 1080b57cec5SDimitry Andric return Asm->OutStreamer->EmitDwarfFileDirective( 1090b57cec5SDimitry Andric 0, File->getDirectory(), File->getFilename(), getMD5AsBytes(File), 1100b57cec5SDimitry Andric File->getSource(), CUID); 1110b57cec5SDimitry Andric } 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE( 1140b57cec5SDimitry Andric const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) { 1150b57cec5SDimitry Andric // Check for pre-existence. 1160b57cec5SDimitry Andric if (DIE *Die = getDIE(GV)) 1170b57cec5SDimitry Andric return Die; 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andric assert(GV); 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric auto *GVContext = GV->getScope(); 1220b57cec5SDimitry Andric const DIType *GTy = GV->getType(); 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric // Construct the context before querying for the existence of the DIE in 1250b57cec5SDimitry Andric // case such construction creates the DIE. 1260b57cec5SDimitry Andric auto *CB = GVContext ? dyn_cast<DICommonBlock>(GVContext) : nullptr; 1270b57cec5SDimitry Andric DIE *ContextDIE = CB ? getOrCreateCommonBlock(CB, GlobalExprs) 1280b57cec5SDimitry Andric : getOrCreateContextDIE(GVContext); 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric // Add to map. 1310b57cec5SDimitry Andric DIE *VariableDIE = &createAndAddDIE(GV->getTag(), *ContextDIE, GV); 1320b57cec5SDimitry Andric DIScope *DeclContext; 1330b57cec5SDimitry Andric if (auto *SDMDecl = GV->getStaticDataMemberDeclaration()) { 1340b57cec5SDimitry Andric DeclContext = SDMDecl->getScope(); 1350b57cec5SDimitry Andric assert(SDMDecl->isStaticMember() && "Expected static member decl"); 1360b57cec5SDimitry Andric assert(GV->isDefinition()); 1370b57cec5SDimitry Andric // We need the declaration DIE that is in the static member's class. 1380b57cec5SDimitry Andric DIE *VariableSpecDIE = getOrCreateStaticMemberDIE(SDMDecl); 1390b57cec5SDimitry Andric addDIEEntry(*VariableDIE, dwarf::DW_AT_specification, *VariableSpecDIE); 1400b57cec5SDimitry Andric // If the global variable's type is different from the one in the class 1410b57cec5SDimitry Andric // member type, assume that it's more specific and also emit it. 1420b57cec5SDimitry Andric if (GTy != SDMDecl->getBaseType()) 1430b57cec5SDimitry Andric addType(*VariableDIE, GTy); 1440b57cec5SDimitry Andric } else { 1450b57cec5SDimitry Andric DeclContext = GV->getScope(); 1460b57cec5SDimitry Andric // Add name and type. 1470b57cec5SDimitry Andric addString(*VariableDIE, dwarf::DW_AT_name, GV->getDisplayName()); 1480b57cec5SDimitry Andric addType(*VariableDIE, GTy); 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andric // Add scoping info. 1510b57cec5SDimitry Andric if (!GV->isLocalToUnit()) 1520b57cec5SDimitry Andric addFlag(*VariableDIE, dwarf::DW_AT_external); 1530b57cec5SDimitry Andric 1540b57cec5SDimitry Andric // Add line number info. 1550b57cec5SDimitry Andric addSourceLine(*VariableDIE, GV); 1560b57cec5SDimitry Andric } 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric if (!GV->isDefinition()) 1590b57cec5SDimitry Andric addFlag(*VariableDIE, dwarf::DW_AT_declaration); 1600b57cec5SDimitry Andric else 1610b57cec5SDimitry Andric addGlobalName(GV->getName(), *VariableDIE, DeclContext); 1620b57cec5SDimitry Andric 1630b57cec5SDimitry Andric if (uint32_t AlignInBytes = GV->getAlignInBytes()) 1640b57cec5SDimitry Andric addUInt(*VariableDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata, 1650b57cec5SDimitry Andric AlignInBytes); 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andric if (MDTuple *TP = GV->getTemplateParams()) 1680b57cec5SDimitry Andric addTemplateParams(*VariableDIE, DINodeArray(TP)); 1690b57cec5SDimitry Andric 1700b57cec5SDimitry Andric // Add location. 1710b57cec5SDimitry Andric addLocationAttribute(VariableDIE, GV, GlobalExprs); 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric return VariableDIE; 1740b57cec5SDimitry Andric } 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric void DwarfCompileUnit::addLocationAttribute( 1770b57cec5SDimitry Andric DIE *VariableDIE, const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) { 1780b57cec5SDimitry Andric bool addToAccelTable = false; 1790b57cec5SDimitry Andric DIELoc *Loc = nullptr; 1800b57cec5SDimitry Andric Optional<unsigned> NVPTXAddressSpace; 1810b57cec5SDimitry Andric std::unique_ptr<DIEDwarfExpression> DwarfExpr; 1820b57cec5SDimitry Andric for (const auto &GE : GlobalExprs) { 1830b57cec5SDimitry Andric const GlobalVariable *Global = GE.Var; 1840b57cec5SDimitry Andric const DIExpression *Expr = GE.Expr; 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andric // For compatibility with DWARF 3 and earlier, 1870b57cec5SDimitry Andric // DW_AT_location(DW_OP_constu, X, DW_OP_stack_value) becomes 1880b57cec5SDimitry Andric // DW_AT_const_value(X). 1890b57cec5SDimitry Andric if (GlobalExprs.size() == 1 && Expr && Expr->isConstant()) { 1900b57cec5SDimitry Andric addToAccelTable = true; 1910b57cec5SDimitry Andric addConstantValue(*VariableDIE, /*Unsigned=*/true, Expr->getElement(1)); 1920b57cec5SDimitry Andric break; 1930b57cec5SDimitry Andric } 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andric // We cannot describe the location of dllimport'd variables: the 1960b57cec5SDimitry Andric // computation of their address requires loads from the IAT. 1970b57cec5SDimitry Andric if (Global && Global->hasDLLImportStorageClass()) 1980b57cec5SDimitry Andric continue; 1990b57cec5SDimitry Andric 2000b57cec5SDimitry Andric // Nothing to describe without address or constant. 2010b57cec5SDimitry Andric if (!Global && (!Expr || !Expr->isConstant())) 2020b57cec5SDimitry Andric continue; 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andric if (Global && Global->isThreadLocal() && 2050b57cec5SDimitry Andric !Asm->getObjFileLowering().supportDebugThreadLocalLocation()) 2060b57cec5SDimitry Andric continue; 2070b57cec5SDimitry Andric 2080b57cec5SDimitry Andric if (!Loc) { 2090b57cec5SDimitry Andric addToAccelTable = true; 2100b57cec5SDimitry Andric Loc = new (DIEValueAllocator) DIELoc; 211*8bcb0991SDimitry Andric DwarfExpr = std::make_unique<DIEDwarfExpression>(*Asm, *this, *Loc); 2120b57cec5SDimitry Andric } 2130b57cec5SDimitry Andric 2140b57cec5SDimitry Andric if (Expr) { 2150b57cec5SDimitry Andric // According to 2160b57cec5SDimitry Andric // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf 2170b57cec5SDimitry Andric // cuda-gdb requires DW_AT_address_class for all variables to be able to 2180b57cec5SDimitry Andric // correctly interpret address space of the variable address. 2190b57cec5SDimitry Andric // Decode DW_OP_constu <DWARF Address Space> DW_OP_swap DW_OP_xderef 2200b57cec5SDimitry Andric // sequence for the NVPTX + gdb target. 2210b57cec5SDimitry Andric unsigned LocalNVPTXAddressSpace; 2220b57cec5SDimitry Andric if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) { 2230b57cec5SDimitry Andric const DIExpression *NewExpr = 2240b57cec5SDimitry Andric DIExpression::extractAddressClass(Expr, LocalNVPTXAddressSpace); 2250b57cec5SDimitry Andric if (NewExpr != Expr) { 2260b57cec5SDimitry Andric Expr = NewExpr; 2270b57cec5SDimitry Andric NVPTXAddressSpace = LocalNVPTXAddressSpace; 2280b57cec5SDimitry Andric } 2290b57cec5SDimitry Andric } 2300b57cec5SDimitry Andric DwarfExpr->addFragmentOffset(Expr); 2310b57cec5SDimitry Andric } 2320b57cec5SDimitry Andric 2330b57cec5SDimitry Andric if (Global) { 2340b57cec5SDimitry Andric const MCSymbol *Sym = Asm->getSymbol(Global); 2350b57cec5SDimitry Andric if (Global->isThreadLocal()) { 2360b57cec5SDimitry Andric if (Asm->TM.useEmulatedTLS()) { 2370b57cec5SDimitry Andric // TODO: add debug info for emulated thread local mode. 2380b57cec5SDimitry Andric } else { 2390b57cec5SDimitry Andric // FIXME: Make this work with -gsplit-dwarf. 2400b57cec5SDimitry Andric unsigned PointerSize = Asm->getDataLayout().getPointerSize(); 2410b57cec5SDimitry Andric assert((PointerSize == 4 || PointerSize == 8) && 2420b57cec5SDimitry Andric "Add support for other sizes if necessary"); 2430b57cec5SDimitry Andric // Based on GCC's support for TLS: 2440b57cec5SDimitry Andric if (!DD->useSplitDwarf()) { 2450b57cec5SDimitry Andric // 1) Start with a constNu of the appropriate pointer size 2460b57cec5SDimitry Andric addUInt(*Loc, dwarf::DW_FORM_data1, 2470b57cec5SDimitry Andric PointerSize == 4 ? dwarf::DW_OP_const4u 2480b57cec5SDimitry Andric : dwarf::DW_OP_const8u); 2490b57cec5SDimitry Andric // 2) containing the (relocated) offset of the TLS variable 2500b57cec5SDimitry Andric // within the module's TLS block. 2510b57cec5SDimitry Andric addExpr(*Loc, dwarf::DW_FORM_udata, 2520b57cec5SDimitry Andric Asm->getObjFileLowering().getDebugThreadLocalSymbol(Sym)); 2530b57cec5SDimitry Andric } else { 2540b57cec5SDimitry Andric addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index); 2550b57cec5SDimitry Andric addUInt(*Loc, dwarf::DW_FORM_udata, 2560b57cec5SDimitry Andric DD->getAddressPool().getIndex(Sym, /* TLS */ true)); 2570b57cec5SDimitry Andric } 2580b57cec5SDimitry Andric // 3) followed by an OP to make the debugger do a TLS lookup. 2590b57cec5SDimitry Andric addUInt(*Loc, dwarf::DW_FORM_data1, 2600b57cec5SDimitry Andric DD->useGNUTLSOpcode() ? dwarf::DW_OP_GNU_push_tls_address 2610b57cec5SDimitry Andric : dwarf::DW_OP_form_tls_address); 2620b57cec5SDimitry Andric } 2630b57cec5SDimitry Andric } else { 2640b57cec5SDimitry Andric DD->addArangeLabel(SymbolCU(this, Sym)); 2650b57cec5SDimitry Andric addOpAddress(*Loc, Sym); 2660b57cec5SDimitry Andric } 2670b57cec5SDimitry Andric } 2680b57cec5SDimitry Andric // Global variables attached to symbols are memory locations. 2690b57cec5SDimitry Andric // It would be better if this were unconditional, but malformed input that 2700b57cec5SDimitry Andric // mixes non-fragments and fragments for the same variable is too expensive 2710b57cec5SDimitry Andric // to detect in the verifier. 2720b57cec5SDimitry Andric if (DwarfExpr->isUnknownLocation()) 2730b57cec5SDimitry Andric DwarfExpr->setMemoryLocationKind(); 2740b57cec5SDimitry Andric DwarfExpr->addExpression(Expr); 2750b57cec5SDimitry Andric } 2760b57cec5SDimitry Andric if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) { 2770b57cec5SDimitry Andric // According to 2780b57cec5SDimitry Andric // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf 2790b57cec5SDimitry Andric // cuda-gdb requires DW_AT_address_class for all variables to be able to 2800b57cec5SDimitry Andric // correctly interpret address space of the variable address. 2810b57cec5SDimitry Andric const unsigned NVPTX_ADDR_global_space = 5; 2820b57cec5SDimitry Andric addUInt(*VariableDIE, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1, 2830b57cec5SDimitry Andric NVPTXAddressSpace ? *NVPTXAddressSpace : NVPTX_ADDR_global_space); 2840b57cec5SDimitry Andric } 2850b57cec5SDimitry Andric if (Loc) 2860b57cec5SDimitry Andric addBlock(*VariableDIE, dwarf::DW_AT_location, DwarfExpr->finalize()); 2870b57cec5SDimitry Andric 2880b57cec5SDimitry Andric if (DD->useAllLinkageNames()) 2890b57cec5SDimitry Andric addLinkageName(*VariableDIE, GV->getLinkageName()); 2900b57cec5SDimitry Andric 2910b57cec5SDimitry Andric if (addToAccelTable) { 2920b57cec5SDimitry Andric DD->addAccelName(*CUNode, GV->getName(), *VariableDIE); 2930b57cec5SDimitry Andric 2940b57cec5SDimitry Andric // If the linkage name is different than the name, go ahead and output 2950b57cec5SDimitry Andric // that as well into the name table. 2960b57cec5SDimitry Andric if (GV->getLinkageName() != "" && GV->getName() != GV->getLinkageName() && 2970b57cec5SDimitry Andric DD->useAllLinkageNames()) 2980b57cec5SDimitry Andric DD->addAccelName(*CUNode, GV->getLinkageName(), *VariableDIE); 2990b57cec5SDimitry Andric } 3000b57cec5SDimitry Andric } 3010b57cec5SDimitry Andric 3020b57cec5SDimitry Andric DIE *DwarfCompileUnit::getOrCreateCommonBlock( 3030b57cec5SDimitry Andric const DICommonBlock *CB, ArrayRef<GlobalExpr> GlobalExprs) { 3040b57cec5SDimitry Andric // Construct the context before querying for the existence of the DIE in case 3050b57cec5SDimitry Andric // such construction creates the DIE. 3060b57cec5SDimitry Andric DIE *ContextDIE = getOrCreateContextDIE(CB->getScope()); 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andric if (DIE *NDie = getDIE(CB)) 3090b57cec5SDimitry Andric return NDie; 3100b57cec5SDimitry Andric DIE &NDie = createAndAddDIE(dwarf::DW_TAG_common_block, *ContextDIE, CB); 3110b57cec5SDimitry Andric StringRef Name = CB->getName().empty() ? "_BLNK_" : CB->getName(); 3120b57cec5SDimitry Andric addString(NDie, dwarf::DW_AT_name, Name); 3130b57cec5SDimitry Andric addGlobalName(Name, NDie, CB->getScope()); 3140b57cec5SDimitry Andric if (CB->getFile()) 3150b57cec5SDimitry Andric addSourceLine(NDie, CB->getLineNo(), CB->getFile()); 3160b57cec5SDimitry Andric if (DIGlobalVariable *V = CB->getDecl()) 3170b57cec5SDimitry Andric getCU().addLocationAttribute(&NDie, V, GlobalExprs); 3180b57cec5SDimitry Andric return &NDie; 3190b57cec5SDimitry Andric } 3200b57cec5SDimitry Andric 3210b57cec5SDimitry Andric void DwarfCompileUnit::addRange(RangeSpan Range) { 3220b57cec5SDimitry Andric bool SameAsPrevCU = this == DD->getPrevCU(); 3230b57cec5SDimitry Andric DD->setPrevCU(this); 3240b57cec5SDimitry Andric // If we have no current ranges just add the range and return, otherwise, 3250b57cec5SDimitry Andric // check the current section and CU against the previous section and CU we 3260b57cec5SDimitry Andric // emitted into and the subprogram was contained within. If these are the 3270b57cec5SDimitry Andric // same then extend our current range, otherwise add this as a new range. 3280b57cec5SDimitry Andric if (CURanges.empty() || !SameAsPrevCU || 329*8bcb0991SDimitry Andric (&CURanges.back().End->getSection() != 330*8bcb0991SDimitry Andric &Range.End->getSection())) { 3310b57cec5SDimitry Andric CURanges.push_back(Range); 3320b57cec5SDimitry Andric return; 3330b57cec5SDimitry Andric } 3340b57cec5SDimitry Andric 335*8bcb0991SDimitry Andric CURanges.back().End = Range.End; 3360b57cec5SDimitry Andric } 3370b57cec5SDimitry Andric 3380b57cec5SDimitry Andric void DwarfCompileUnit::initStmtList() { 3390b57cec5SDimitry Andric if (CUNode->isDebugDirectivesOnly()) 3400b57cec5SDimitry Andric return; 3410b57cec5SDimitry Andric 3420b57cec5SDimitry Andric // Define start line table label for each Compile Unit. 3430b57cec5SDimitry Andric MCSymbol *LineTableStartSym; 3440b57cec5SDimitry Andric const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); 3450b57cec5SDimitry Andric if (DD->useSectionsAsReferences()) { 3460b57cec5SDimitry Andric LineTableStartSym = TLOF.getDwarfLineSection()->getBeginSymbol(); 3470b57cec5SDimitry Andric } else { 3480b57cec5SDimitry Andric LineTableStartSym = 3490b57cec5SDimitry Andric Asm->OutStreamer->getDwarfLineTableSymbol(getUniqueID()); 3500b57cec5SDimitry Andric } 3510b57cec5SDimitry Andric 3520b57cec5SDimitry Andric // DW_AT_stmt_list is a offset of line number information for this 3530b57cec5SDimitry Andric // compile unit in debug_line section. For split dwarf this is 3540b57cec5SDimitry Andric // left in the skeleton CU and so not included. 3550b57cec5SDimitry Andric // The line table entries are not always emitted in assembly, so it 3560b57cec5SDimitry Andric // is not okay to use line_table_start here. 3570b57cec5SDimitry Andric StmtListValue = 3580b57cec5SDimitry Andric addSectionLabel(getUnitDie(), dwarf::DW_AT_stmt_list, LineTableStartSym, 3590b57cec5SDimitry Andric TLOF.getDwarfLineSection()->getBeginSymbol()); 3600b57cec5SDimitry Andric } 3610b57cec5SDimitry Andric 3620b57cec5SDimitry Andric void DwarfCompileUnit::applyStmtList(DIE &D) { 3630b57cec5SDimitry Andric D.addValue(DIEValueAllocator, *StmtListValue); 3640b57cec5SDimitry Andric } 3650b57cec5SDimitry Andric 3660b57cec5SDimitry Andric void DwarfCompileUnit::attachLowHighPC(DIE &D, const MCSymbol *Begin, 3670b57cec5SDimitry Andric const MCSymbol *End) { 3680b57cec5SDimitry Andric assert(Begin && "Begin label should not be null!"); 3690b57cec5SDimitry Andric assert(End && "End label should not be null!"); 3700b57cec5SDimitry Andric assert(Begin->isDefined() && "Invalid starting label"); 3710b57cec5SDimitry Andric assert(End->isDefined() && "Invalid end label"); 3720b57cec5SDimitry Andric 3730b57cec5SDimitry Andric addLabelAddress(D, dwarf::DW_AT_low_pc, Begin); 3740b57cec5SDimitry Andric if (DD->getDwarfVersion() < 4) 3750b57cec5SDimitry Andric addLabelAddress(D, dwarf::DW_AT_high_pc, End); 3760b57cec5SDimitry Andric else 3770b57cec5SDimitry Andric addLabelDelta(D, dwarf::DW_AT_high_pc, End, Begin); 3780b57cec5SDimitry Andric } 3790b57cec5SDimitry Andric 3800b57cec5SDimitry Andric // Find DIE for the given subprogram and attach appropriate DW_AT_low_pc 3810b57cec5SDimitry Andric // and DW_AT_high_pc attributes. If there are global variables in this 3820b57cec5SDimitry Andric // scope then create and insert DIEs for these variables. 3830b57cec5SDimitry Andric DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP) { 3840b57cec5SDimitry Andric DIE *SPDie = getOrCreateSubprogramDIE(SP, includeMinimalInlineScopes()); 3850b57cec5SDimitry Andric 3860b57cec5SDimitry Andric attachLowHighPC(*SPDie, Asm->getFunctionBegin(), Asm->getFunctionEnd()); 3870b57cec5SDimitry Andric if (DD->useAppleExtensionAttributes() && 3880b57cec5SDimitry Andric !DD->getCurrentFunction()->getTarget().Options.DisableFramePointerElim( 3890b57cec5SDimitry Andric *DD->getCurrentFunction())) 3900b57cec5SDimitry Andric addFlag(*SPDie, dwarf::DW_AT_APPLE_omit_frame_ptr); 3910b57cec5SDimitry Andric 3920b57cec5SDimitry Andric // Only include DW_AT_frame_base in full debug info 3930b57cec5SDimitry Andric if (!includeMinimalInlineScopes()) { 3940b57cec5SDimitry Andric if (Asm->MF->getTarget().getTargetTriple().isNVPTX()) { 3950b57cec5SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 3960b57cec5SDimitry Andric addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_call_frame_cfa); 3970b57cec5SDimitry Andric addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc); 3980b57cec5SDimitry Andric } else { 3990b57cec5SDimitry Andric const TargetRegisterInfo *RI = Asm->MF->getSubtarget().getRegisterInfo(); 4000b57cec5SDimitry Andric MachineLocation Location(RI->getFrameRegister(*Asm->MF)); 401*8bcb0991SDimitry Andric if (Register::isPhysicalRegister(Location.getReg())) 4020b57cec5SDimitry Andric addAddress(*SPDie, dwarf::DW_AT_frame_base, Location); 4030b57cec5SDimitry Andric } 4040b57cec5SDimitry Andric } 4050b57cec5SDimitry Andric 4060b57cec5SDimitry Andric // Add name to the name table, we do this here because we're guaranteed 4070b57cec5SDimitry Andric // to have concrete versions of our DW_TAG_subprogram nodes. 4080b57cec5SDimitry Andric DD->addSubprogramNames(*CUNode, SP, *SPDie); 4090b57cec5SDimitry Andric 4100b57cec5SDimitry Andric return *SPDie; 4110b57cec5SDimitry Andric } 4120b57cec5SDimitry Andric 4130b57cec5SDimitry Andric // Construct a DIE for this scope. 4140b57cec5SDimitry Andric void DwarfCompileUnit::constructScopeDIE( 4150b57cec5SDimitry Andric LexicalScope *Scope, SmallVectorImpl<DIE *> &FinalChildren) { 4160b57cec5SDimitry Andric if (!Scope || !Scope->getScopeNode()) 4170b57cec5SDimitry Andric return; 4180b57cec5SDimitry Andric 4190b57cec5SDimitry Andric auto *DS = Scope->getScopeNode(); 4200b57cec5SDimitry Andric 4210b57cec5SDimitry Andric assert((Scope->getInlinedAt() || !isa<DISubprogram>(DS)) && 4220b57cec5SDimitry Andric "Only handle inlined subprograms here, use " 4230b57cec5SDimitry Andric "constructSubprogramScopeDIE for non-inlined " 4240b57cec5SDimitry Andric "subprograms"); 4250b57cec5SDimitry Andric 4260b57cec5SDimitry Andric SmallVector<DIE *, 8> Children; 4270b57cec5SDimitry Andric 4280b57cec5SDimitry Andric // We try to create the scope DIE first, then the children DIEs. This will 4290b57cec5SDimitry Andric // avoid creating un-used children then removing them later when we find out 4300b57cec5SDimitry Andric // the scope DIE is null. 4310b57cec5SDimitry Andric DIE *ScopeDIE; 4320b57cec5SDimitry Andric if (Scope->getParent() && isa<DISubprogram>(DS)) { 4330b57cec5SDimitry Andric ScopeDIE = constructInlinedScopeDIE(Scope); 4340b57cec5SDimitry Andric if (!ScopeDIE) 4350b57cec5SDimitry Andric return; 4360b57cec5SDimitry Andric // We create children when the scope DIE is not null. 4370b57cec5SDimitry Andric createScopeChildrenDIE(Scope, Children); 4380b57cec5SDimitry Andric } else { 4390b57cec5SDimitry Andric // Early exit when we know the scope DIE is going to be null. 4400b57cec5SDimitry Andric if (DD->isLexicalScopeDIENull(Scope)) 4410b57cec5SDimitry Andric return; 4420b57cec5SDimitry Andric 4430b57cec5SDimitry Andric bool HasNonScopeChildren = false; 4440b57cec5SDimitry Andric 4450b57cec5SDimitry Andric // We create children here when we know the scope DIE is not going to be 4460b57cec5SDimitry Andric // null and the children will be added to the scope DIE. 4470b57cec5SDimitry Andric createScopeChildrenDIE(Scope, Children, &HasNonScopeChildren); 4480b57cec5SDimitry Andric 4490b57cec5SDimitry Andric // If there are only other scopes as children, put them directly in the 4500b57cec5SDimitry Andric // parent instead, as this scope would serve no purpose. 4510b57cec5SDimitry Andric if (!HasNonScopeChildren) { 4520b57cec5SDimitry Andric FinalChildren.insert(FinalChildren.end(), 4530b57cec5SDimitry Andric std::make_move_iterator(Children.begin()), 4540b57cec5SDimitry Andric std::make_move_iterator(Children.end())); 4550b57cec5SDimitry Andric return; 4560b57cec5SDimitry Andric } 4570b57cec5SDimitry Andric ScopeDIE = constructLexicalScopeDIE(Scope); 4580b57cec5SDimitry Andric assert(ScopeDIE && "Scope DIE should not be null."); 4590b57cec5SDimitry Andric } 4600b57cec5SDimitry Andric 4610b57cec5SDimitry Andric // Add children 4620b57cec5SDimitry Andric for (auto &I : Children) 4630b57cec5SDimitry Andric ScopeDIE->addChild(std::move(I)); 4640b57cec5SDimitry Andric 4650b57cec5SDimitry Andric FinalChildren.push_back(std::move(ScopeDIE)); 4660b57cec5SDimitry Andric } 4670b57cec5SDimitry Andric 4680b57cec5SDimitry Andric void DwarfCompileUnit::addScopeRangeList(DIE &ScopeDIE, 4690b57cec5SDimitry Andric SmallVector<RangeSpan, 2> Range) { 4700b57cec5SDimitry Andric 4710b57cec5SDimitry Andric HasRangeLists = true; 4720b57cec5SDimitry Andric 4730b57cec5SDimitry Andric // Add the range list to the set of ranges to be emitted. 4740b57cec5SDimitry Andric auto IndexAndList = 4750b57cec5SDimitry Andric (DD->getDwarfVersion() < 5 && Skeleton ? Skeleton->DU : DU) 4760b57cec5SDimitry Andric ->addRange(*(Skeleton ? Skeleton : this), std::move(Range)); 4770b57cec5SDimitry Andric 4780b57cec5SDimitry Andric uint32_t Index = IndexAndList.first; 4790b57cec5SDimitry Andric auto &List = *IndexAndList.second; 4800b57cec5SDimitry Andric 4810b57cec5SDimitry Andric // Under fission, ranges are specified by constant offsets relative to the 4820b57cec5SDimitry Andric // CU's DW_AT_GNU_ranges_base. 4830b57cec5SDimitry Andric // FIXME: For DWARF v5, do not generate the DW_AT_ranges attribute under 4840b57cec5SDimitry Andric // fission until we support the forms using the .debug_addr section 4850b57cec5SDimitry Andric // (DW_RLE_startx_endx etc.). 4860b57cec5SDimitry Andric if (DD->getDwarfVersion() >= 5) 4870b57cec5SDimitry Andric addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_rnglistx, Index); 488*8bcb0991SDimitry Andric else { 489*8bcb0991SDimitry Andric const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); 490*8bcb0991SDimitry Andric const MCSymbol *RangeSectionSym = 491*8bcb0991SDimitry Andric TLOF.getDwarfRangesSection()->getBeginSymbol(); 492*8bcb0991SDimitry Andric if (isDwoUnit()) 4930b57cec5SDimitry Andric addSectionDelta(ScopeDIE, dwarf::DW_AT_ranges, List.getSym(), 4940b57cec5SDimitry Andric RangeSectionSym); 4950b57cec5SDimitry Andric else 4960b57cec5SDimitry Andric addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges, List.getSym(), 4970b57cec5SDimitry Andric RangeSectionSym); 4980b57cec5SDimitry Andric } 499*8bcb0991SDimitry Andric } 5000b57cec5SDimitry Andric 5010b57cec5SDimitry Andric void DwarfCompileUnit::attachRangesOrLowHighPC( 5020b57cec5SDimitry Andric DIE &Die, SmallVector<RangeSpan, 2> Ranges) { 5030b57cec5SDimitry Andric if (Ranges.size() == 1 || !DD->useRangesSection()) { 5040b57cec5SDimitry Andric const RangeSpan &Front = Ranges.front(); 5050b57cec5SDimitry Andric const RangeSpan &Back = Ranges.back(); 506*8bcb0991SDimitry Andric attachLowHighPC(Die, Front.Begin, Back.End); 5070b57cec5SDimitry Andric } else 5080b57cec5SDimitry Andric addScopeRangeList(Die, std::move(Ranges)); 5090b57cec5SDimitry Andric } 5100b57cec5SDimitry Andric 5110b57cec5SDimitry Andric void DwarfCompileUnit::attachRangesOrLowHighPC( 5120b57cec5SDimitry Andric DIE &Die, const SmallVectorImpl<InsnRange> &Ranges) { 5130b57cec5SDimitry Andric SmallVector<RangeSpan, 2> List; 5140b57cec5SDimitry Andric List.reserve(Ranges.size()); 5150b57cec5SDimitry Andric for (const InsnRange &R : Ranges) 516*8bcb0991SDimitry Andric List.push_back( 517*8bcb0991SDimitry Andric {DD->getLabelBeforeInsn(R.first), DD->getLabelAfterInsn(R.second)}); 5180b57cec5SDimitry Andric attachRangesOrLowHighPC(Die, std::move(List)); 5190b57cec5SDimitry Andric } 5200b57cec5SDimitry Andric 5210b57cec5SDimitry Andric // This scope represents inlined body of a function. Construct DIE to 5220b57cec5SDimitry Andric // represent this concrete inlined copy of the function. 5230b57cec5SDimitry Andric DIE *DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope) { 5240b57cec5SDimitry Andric assert(Scope->getScopeNode()); 5250b57cec5SDimitry Andric auto *DS = Scope->getScopeNode(); 5260b57cec5SDimitry Andric auto *InlinedSP = getDISubprogram(DS); 5270b57cec5SDimitry Andric // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram 5280b57cec5SDimitry Andric // was inlined from another compile unit. 5290b57cec5SDimitry Andric DIE *OriginDIE = getAbstractSPDies()[InlinedSP]; 5300b57cec5SDimitry Andric assert(OriginDIE && "Unable to find original DIE for an inlined subprogram."); 5310b57cec5SDimitry Andric 5320b57cec5SDimitry Andric auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_inlined_subroutine); 5330b57cec5SDimitry Andric addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *OriginDIE); 5340b57cec5SDimitry Andric 5350b57cec5SDimitry Andric attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges()); 5360b57cec5SDimitry Andric 5370b57cec5SDimitry Andric // Add the call site information to the DIE. 5380b57cec5SDimitry Andric const DILocation *IA = Scope->getInlinedAt(); 5390b57cec5SDimitry Andric addUInt(*ScopeDIE, dwarf::DW_AT_call_file, None, 5400b57cec5SDimitry Andric getOrCreateSourceID(IA->getFile())); 5410b57cec5SDimitry Andric addUInt(*ScopeDIE, dwarf::DW_AT_call_line, None, IA->getLine()); 5420b57cec5SDimitry Andric if (IA->getColumn()) 5430b57cec5SDimitry Andric addUInt(*ScopeDIE, dwarf::DW_AT_call_column, None, IA->getColumn()); 5440b57cec5SDimitry Andric if (IA->getDiscriminator() && DD->getDwarfVersion() >= 4) 5450b57cec5SDimitry Andric addUInt(*ScopeDIE, dwarf::DW_AT_GNU_discriminator, None, 5460b57cec5SDimitry Andric IA->getDiscriminator()); 5470b57cec5SDimitry Andric 5480b57cec5SDimitry Andric // Add name to the name table, we do this here because we're guaranteed 5490b57cec5SDimitry Andric // to have concrete versions of our DW_TAG_inlined_subprogram nodes. 5500b57cec5SDimitry Andric DD->addSubprogramNames(*CUNode, InlinedSP, *ScopeDIE); 5510b57cec5SDimitry Andric 5520b57cec5SDimitry Andric return ScopeDIE; 5530b57cec5SDimitry Andric } 5540b57cec5SDimitry Andric 5550b57cec5SDimitry Andric // Construct new DW_TAG_lexical_block for this scope and attach 5560b57cec5SDimitry Andric // DW_AT_low_pc/DW_AT_high_pc labels. 5570b57cec5SDimitry Andric DIE *DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) { 5580b57cec5SDimitry Andric if (DD->isLexicalScopeDIENull(Scope)) 5590b57cec5SDimitry Andric return nullptr; 5600b57cec5SDimitry Andric 5610b57cec5SDimitry Andric auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_lexical_block); 5620b57cec5SDimitry Andric if (Scope->isAbstractScope()) 5630b57cec5SDimitry Andric return ScopeDIE; 5640b57cec5SDimitry Andric 5650b57cec5SDimitry Andric attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges()); 5660b57cec5SDimitry Andric 5670b57cec5SDimitry Andric return ScopeDIE; 5680b57cec5SDimitry Andric } 5690b57cec5SDimitry Andric 5700b57cec5SDimitry Andric /// constructVariableDIE - Construct a DIE for the given DbgVariable. 5710b57cec5SDimitry Andric DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, bool Abstract) { 5720b57cec5SDimitry Andric auto D = constructVariableDIEImpl(DV, Abstract); 5730b57cec5SDimitry Andric DV.setDIE(*D); 5740b57cec5SDimitry Andric return D; 5750b57cec5SDimitry Andric } 5760b57cec5SDimitry Andric 5770b57cec5SDimitry Andric DIE *DwarfCompileUnit::constructLabelDIE(DbgLabel &DL, 5780b57cec5SDimitry Andric const LexicalScope &Scope) { 5790b57cec5SDimitry Andric auto LabelDie = DIE::get(DIEValueAllocator, DL.getTag()); 5800b57cec5SDimitry Andric insertDIE(DL.getLabel(), LabelDie); 5810b57cec5SDimitry Andric DL.setDIE(*LabelDie); 5820b57cec5SDimitry Andric 5830b57cec5SDimitry Andric if (Scope.isAbstractScope()) 5840b57cec5SDimitry Andric applyLabelAttributes(DL, *LabelDie); 5850b57cec5SDimitry Andric 5860b57cec5SDimitry Andric return LabelDie; 5870b57cec5SDimitry Andric } 5880b57cec5SDimitry Andric 5890b57cec5SDimitry Andric DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV, 5900b57cec5SDimitry Andric bool Abstract) { 5910b57cec5SDimitry Andric // Define variable debug information entry. 5920b57cec5SDimitry Andric auto VariableDie = DIE::get(DIEValueAllocator, DV.getTag()); 5930b57cec5SDimitry Andric insertDIE(DV.getVariable(), VariableDie); 5940b57cec5SDimitry Andric 5950b57cec5SDimitry Andric if (Abstract) { 5960b57cec5SDimitry Andric applyVariableAttributes(DV, *VariableDie); 5970b57cec5SDimitry Andric return VariableDie; 5980b57cec5SDimitry Andric } 5990b57cec5SDimitry Andric 6000b57cec5SDimitry Andric // Add variable address. 6010b57cec5SDimitry Andric 6020b57cec5SDimitry Andric unsigned Offset = DV.getDebugLocListIndex(); 6030b57cec5SDimitry Andric if (Offset != ~0U) { 6040b57cec5SDimitry Andric addLocationList(*VariableDie, dwarf::DW_AT_location, Offset); 6050b57cec5SDimitry Andric return VariableDie; 6060b57cec5SDimitry Andric } 6070b57cec5SDimitry Andric 6080b57cec5SDimitry Andric // Check if variable has a single location description. 6090b57cec5SDimitry Andric if (auto *DVal = DV.getValueLoc()) { 6100b57cec5SDimitry Andric if (DVal->isLocation()) 6110b57cec5SDimitry Andric addVariableAddress(DV, *VariableDie, DVal->getLoc()); 6120b57cec5SDimitry Andric else if (DVal->isInt()) { 6130b57cec5SDimitry Andric auto *Expr = DV.getSingleExpression(); 6140b57cec5SDimitry Andric if (Expr && Expr->getNumElements()) { 6150b57cec5SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 6160b57cec5SDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); 6170b57cec5SDimitry Andric // If there is an expression, emit raw unsigned bytes. 6180b57cec5SDimitry Andric DwarfExpr.addFragmentOffset(Expr); 6190b57cec5SDimitry Andric DwarfExpr.addUnsignedConstant(DVal->getInt()); 6200b57cec5SDimitry Andric DwarfExpr.addExpression(Expr); 6210b57cec5SDimitry Andric addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize()); 6220b57cec5SDimitry Andric } else 6230b57cec5SDimitry Andric addConstantValue(*VariableDie, DVal->getInt(), DV.getType()); 6240b57cec5SDimitry Andric } else if (DVal->isConstantFP()) { 6250b57cec5SDimitry Andric addConstantFPValue(*VariableDie, DVal->getConstantFP()); 6260b57cec5SDimitry Andric } else if (DVal->isConstantInt()) { 6270b57cec5SDimitry Andric addConstantValue(*VariableDie, DVal->getConstantInt(), DV.getType()); 6280b57cec5SDimitry Andric } 6290b57cec5SDimitry Andric return VariableDie; 6300b57cec5SDimitry Andric } 6310b57cec5SDimitry Andric 6320b57cec5SDimitry Andric // .. else use frame index. 6330b57cec5SDimitry Andric if (!DV.hasFrameIndexExprs()) 6340b57cec5SDimitry Andric return VariableDie; 6350b57cec5SDimitry Andric 6360b57cec5SDimitry Andric Optional<unsigned> NVPTXAddressSpace; 6370b57cec5SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 6380b57cec5SDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); 6390b57cec5SDimitry Andric for (auto &Fragment : DV.getFrameIndexExprs()) { 6400b57cec5SDimitry Andric unsigned FrameReg = 0; 6410b57cec5SDimitry Andric const DIExpression *Expr = Fragment.Expr; 6420b57cec5SDimitry Andric const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering(); 6430b57cec5SDimitry Andric int Offset = TFI->getFrameIndexReference(*Asm->MF, Fragment.FI, FrameReg); 6440b57cec5SDimitry Andric DwarfExpr.addFragmentOffset(Expr); 6450b57cec5SDimitry Andric SmallVector<uint64_t, 8> Ops; 646*8bcb0991SDimitry Andric DIExpression::appendOffset(Ops, Offset); 6470b57cec5SDimitry Andric // According to 6480b57cec5SDimitry Andric // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf 6490b57cec5SDimitry Andric // cuda-gdb requires DW_AT_address_class for all variables to be able to 6500b57cec5SDimitry Andric // correctly interpret address space of the variable address. 6510b57cec5SDimitry Andric // Decode DW_OP_constu <DWARF Address Space> DW_OP_swap DW_OP_xderef 6520b57cec5SDimitry Andric // sequence for the NVPTX + gdb target. 6530b57cec5SDimitry Andric unsigned LocalNVPTXAddressSpace; 6540b57cec5SDimitry Andric if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) { 6550b57cec5SDimitry Andric const DIExpression *NewExpr = 6560b57cec5SDimitry Andric DIExpression::extractAddressClass(Expr, LocalNVPTXAddressSpace); 6570b57cec5SDimitry Andric if (NewExpr != Expr) { 6580b57cec5SDimitry Andric Expr = NewExpr; 6590b57cec5SDimitry Andric NVPTXAddressSpace = LocalNVPTXAddressSpace; 6600b57cec5SDimitry Andric } 6610b57cec5SDimitry Andric } 6620b57cec5SDimitry Andric if (Expr) 6630b57cec5SDimitry Andric Ops.append(Expr->elements_begin(), Expr->elements_end()); 6640b57cec5SDimitry Andric DIExpressionCursor Cursor(Ops); 6650b57cec5SDimitry Andric DwarfExpr.setMemoryLocationKind(); 6660b57cec5SDimitry Andric if (const MCSymbol *FrameSymbol = Asm->getFunctionFrameSymbol()) 6670b57cec5SDimitry Andric addOpAddress(*Loc, FrameSymbol); 6680b57cec5SDimitry Andric else 6690b57cec5SDimitry Andric DwarfExpr.addMachineRegExpression( 6700b57cec5SDimitry Andric *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, FrameReg); 6710b57cec5SDimitry Andric DwarfExpr.addExpression(std::move(Cursor)); 6720b57cec5SDimitry Andric } 6730b57cec5SDimitry Andric if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) { 6740b57cec5SDimitry Andric // According to 6750b57cec5SDimitry Andric // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf 6760b57cec5SDimitry Andric // cuda-gdb requires DW_AT_address_class for all variables to be able to 6770b57cec5SDimitry Andric // correctly interpret address space of the variable address. 6780b57cec5SDimitry Andric const unsigned NVPTX_ADDR_local_space = 6; 6790b57cec5SDimitry Andric addUInt(*VariableDie, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1, 6800b57cec5SDimitry Andric NVPTXAddressSpace ? *NVPTXAddressSpace : NVPTX_ADDR_local_space); 6810b57cec5SDimitry Andric } 6820b57cec5SDimitry Andric addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize()); 6830b57cec5SDimitry Andric if (DwarfExpr.TagOffset) 6840b57cec5SDimitry Andric addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1, 6850b57cec5SDimitry Andric *DwarfExpr.TagOffset); 6860b57cec5SDimitry Andric 6870b57cec5SDimitry Andric return VariableDie; 6880b57cec5SDimitry Andric } 6890b57cec5SDimitry Andric 6900b57cec5SDimitry Andric DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, 6910b57cec5SDimitry Andric const LexicalScope &Scope, 6920b57cec5SDimitry Andric DIE *&ObjectPointer) { 6930b57cec5SDimitry Andric auto Var = constructVariableDIE(DV, Scope.isAbstractScope()); 6940b57cec5SDimitry Andric if (DV.isObjectPointer()) 6950b57cec5SDimitry Andric ObjectPointer = Var; 6960b57cec5SDimitry Andric return Var; 6970b57cec5SDimitry Andric } 6980b57cec5SDimitry Andric 6990b57cec5SDimitry Andric /// Return all DIVariables that appear in count: expressions. 7000b57cec5SDimitry Andric static SmallVector<const DIVariable *, 2> dependencies(DbgVariable *Var) { 7010b57cec5SDimitry Andric SmallVector<const DIVariable *, 2> Result; 7020b57cec5SDimitry Andric auto *Array = dyn_cast<DICompositeType>(Var->getType()); 7030b57cec5SDimitry Andric if (!Array || Array->getTag() != dwarf::DW_TAG_array_type) 7040b57cec5SDimitry Andric return Result; 7050b57cec5SDimitry Andric for (auto *El : Array->getElements()) { 7060b57cec5SDimitry Andric if (auto *Subrange = dyn_cast<DISubrange>(El)) { 7070b57cec5SDimitry Andric auto Count = Subrange->getCount(); 7080b57cec5SDimitry Andric if (auto *Dependency = Count.dyn_cast<DIVariable *>()) 7090b57cec5SDimitry Andric Result.push_back(Dependency); 7100b57cec5SDimitry Andric } 7110b57cec5SDimitry Andric } 7120b57cec5SDimitry Andric return Result; 7130b57cec5SDimitry Andric } 7140b57cec5SDimitry Andric 7150b57cec5SDimitry Andric /// Sort local variables so that variables appearing inside of helper 7160b57cec5SDimitry Andric /// expressions come first. 7170b57cec5SDimitry Andric static SmallVector<DbgVariable *, 8> 7180b57cec5SDimitry Andric sortLocalVars(SmallVectorImpl<DbgVariable *> &Input) { 7190b57cec5SDimitry Andric SmallVector<DbgVariable *, 8> Result; 7200b57cec5SDimitry Andric SmallVector<PointerIntPair<DbgVariable *, 1>, 8> WorkList; 7210b57cec5SDimitry Andric // Map back from a DIVariable to its containing DbgVariable. 7220b57cec5SDimitry Andric SmallDenseMap<const DILocalVariable *, DbgVariable *> DbgVar; 7230b57cec5SDimitry Andric // Set of DbgVariables in Result. 7240b57cec5SDimitry Andric SmallDenseSet<DbgVariable *, 8> Visited; 7250b57cec5SDimitry Andric // For cycle detection. 7260b57cec5SDimitry Andric SmallDenseSet<DbgVariable *, 8> Visiting; 7270b57cec5SDimitry Andric 7280b57cec5SDimitry Andric // Initialize the worklist and the DIVariable lookup table. 7290b57cec5SDimitry Andric for (auto Var : reverse(Input)) { 7300b57cec5SDimitry Andric DbgVar.insert({Var->getVariable(), Var}); 7310b57cec5SDimitry Andric WorkList.push_back({Var, 0}); 7320b57cec5SDimitry Andric } 7330b57cec5SDimitry Andric 7340b57cec5SDimitry Andric // Perform a stable topological sort by doing a DFS. 7350b57cec5SDimitry Andric while (!WorkList.empty()) { 7360b57cec5SDimitry Andric auto Item = WorkList.back(); 7370b57cec5SDimitry Andric DbgVariable *Var = Item.getPointer(); 7380b57cec5SDimitry Andric bool visitedAllDependencies = Item.getInt(); 7390b57cec5SDimitry Andric WorkList.pop_back(); 7400b57cec5SDimitry Andric 7410b57cec5SDimitry Andric // Dependency is in a different lexical scope or a global. 7420b57cec5SDimitry Andric if (!Var) 7430b57cec5SDimitry Andric continue; 7440b57cec5SDimitry Andric 7450b57cec5SDimitry Andric // Already handled. 7460b57cec5SDimitry Andric if (Visited.count(Var)) 7470b57cec5SDimitry Andric continue; 7480b57cec5SDimitry Andric 7490b57cec5SDimitry Andric // Add to Result if all dependencies are visited. 7500b57cec5SDimitry Andric if (visitedAllDependencies) { 7510b57cec5SDimitry Andric Visited.insert(Var); 7520b57cec5SDimitry Andric Result.push_back(Var); 7530b57cec5SDimitry Andric continue; 7540b57cec5SDimitry Andric } 7550b57cec5SDimitry Andric 7560b57cec5SDimitry Andric // Detect cycles. 7570b57cec5SDimitry Andric auto Res = Visiting.insert(Var); 7580b57cec5SDimitry Andric if (!Res.second) { 7590b57cec5SDimitry Andric assert(false && "dependency cycle in local variables"); 7600b57cec5SDimitry Andric return Result; 7610b57cec5SDimitry Andric } 7620b57cec5SDimitry Andric 7630b57cec5SDimitry Andric // Push dependencies and this node onto the worklist, so that this node is 7640b57cec5SDimitry Andric // visited again after all of its dependencies are handled. 7650b57cec5SDimitry Andric WorkList.push_back({Var, 1}); 7660b57cec5SDimitry Andric for (auto *Dependency : dependencies(Var)) { 7670b57cec5SDimitry Andric auto Dep = dyn_cast_or_null<const DILocalVariable>(Dependency); 7680b57cec5SDimitry Andric WorkList.push_back({DbgVar[Dep], 0}); 7690b57cec5SDimitry Andric } 7700b57cec5SDimitry Andric } 7710b57cec5SDimitry Andric return Result; 7720b57cec5SDimitry Andric } 7730b57cec5SDimitry Andric 7740b57cec5SDimitry Andric DIE *DwarfCompileUnit::createScopeChildrenDIE(LexicalScope *Scope, 7750b57cec5SDimitry Andric SmallVectorImpl<DIE *> &Children, 7760b57cec5SDimitry Andric bool *HasNonScopeChildren) { 7770b57cec5SDimitry Andric assert(Children.empty()); 7780b57cec5SDimitry Andric DIE *ObjectPointer = nullptr; 7790b57cec5SDimitry Andric 7800b57cec5SDimitry Andric // Emit function arguments (order is significant). 7810b57cec5SDimitry Andric auto Vars = DU->getScopeVariables().lookup(Scope); 7820b57cec5SDimitry Andric for (auto &DV : Vars.Args) 7830b57cec5SDimitry Andric Children.push_back(constructVariableDIE(*DV.second, *Scope, ObjectPointer)); 7840b57cec5SDimitry Andric 7850b57cec5SDimitry Andric // Emit local variables. 7860b57cec5SDimitry Andric auto Locals = sortLocalVars(Vars.Locals); 7870b57cec5SDimitry Andric for (DbgVariable *DV : Locals) 7880b57cec5SDimitry Andric Children.push_back(constructVariableDIE(*DV, *Scope, ObjectPointer)); 7890b57cec5SDimitry Andric 7900b57cec5SDimitry Andric // Skip imported directives in gmlt-like data. 7910b57cec5SDimitry Andric if (!includeMinimalInlineScopes()) { 7920b57cec5SDimitry Andric // There is no need to emit empty lexical block DIE. 7930b57cec5SDimitry Andric for (const auto *IE : ImportedEntities[Scope->getScopeNode()]) 7940b57cec5SDimitry Andric Children.push_back( 7950b57cec5SDimitry Andric constructImportedEntityDIE(cast<DIImportedEntity>(IE))); 7960b57cec5SDimitry Andric } 7970b57cec5SDimitry Andric 7980b57cec5SDimitry Andric if (HasNonScopeChildren) 7990b57cec5SDimitry Andric *HasNonScopeChildren = !Children.empty(); 8000b57cec5SDimitry Andric 8010b57cec5SDimitry Andric for (DbgLabel *DL : DU->getScopeLabels().lookup(Scope)) 8020b57cec5SDimitry Andric Children.push_back(constructLabelDIE(*DL, *Scope)); 8030b57cec5SDimitry Andric 8040b57cec5SDimitry Andric for (LexicalScope *LS : Scope->getChildren()) 8050b57cec5SDimitry Andric constructScopeDIE(LS, Children); 8060b57cec5SDimitry Andric 8070b57cec5SDimitry Andric return ObjectPointer; 8080b57cec5SDimitry Andric } 8090b57cec5SDimitry Andric 8100b57cec5SDimitry Andric DIE &DwarfCompileUnit::constructSubprogramScopeDIE(const DISubprogram *Sub, 8110b57cec5SDimitry Andric LexicalScope *Scope) { 8120b57cec5SDimitry Andric DIE &ScopeDIE = updateSubprogramScopeDIE(Sub); 8130b57cec5SDimitry Andric 8140b57cec5SDimitry Andric if (Scope) { 8150b57cec5SDimitry Andric assert(!Scope->getInlinedAt()); 8160b57cec5SDimitry Andric assert(!Scope->isAbstractScope()); 8170b57cec5SDimitry Andric // Collect lexical scope children first. 8180b57cec5SDimitry Andric // ObjectPointer might be a local (non-argument) local variable if it's a 8190b57cec5SDimitry Andric // block's synthetic this pointer. 8200b57cec5SDimitry Andric if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, ScopeDIE)) 8210b57cec5SDimitry Andric addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer); 8220b57cec5SDimitry Andric } 8230b57cec5SDimitry Andric 8240b57cec5SDimitry Andric // If this is a variadic function, add an unspecified parameter. 8250b57cec5SDimitry Andric DITypeRefArray FnArgs = Sub->getType()->getTypeArray(); 8260b57cec5SDimitry Andric 8270b57cec5SDimitry Andric // If we have a single element of null, it is a function that returns void. 8280b57cec5SDimitry Andric // If we have more than one elements and the last one is null, it is a 8290b57cec5SDimitry Andric // variadic function. 8300b57cec5SDimitry Andric if (FnArgs.size() > 1 && !FnArgs[FnArgs.size() - 1] && 8310b57cec5SDimitry Andric !includeMinimalInlineScopes()) 8320b57cec5SDimitry Andric ScopeDIE.addChild( 8330b57cec5SDimitry Andric DIE::get(DIEValueAllocator, dwarf::DW_TAG_unspecified_parameters)); 8340b57cec5SDimitry Andric 8350b57cec5SDimitry Andric return ScopeDIE; 8360b57cec5SDimitry Andric } 8370b57cec5SDimitry Andric 8380b57cec5SDimitry Andric DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope, 8390b57cec5SDimitry Andric DIE &ScopeDIE) { 8400b57cec5SDimitry Andric // We create children when the scope DIE is not null. 8410b57cec5SDimitry Andric SmallVector<DIE *, 8> Children; 8420b57cec5SDimitry Andric DIE *ObjectPointer = createScopeChildrenDIE(Scope, Children); 8430b57cec5SDimitry Andric 8440b57cec5SDimitry Andric // Add children 8450b57cec5SDimitry Andric for (auto &I : Children) 8460b57cec5SDimitry Andric ScopeDIE.addChild(std::move(I)); 8470b57cec5SDimitry Andric 8480b57cec5SDimitry Andric return ObjectPointer; 8490b57cec5SDimitry Andric } 8500b57cec5SDimitry Andric 8510b57cec5SDimitry Andric void DwarfCompileUnit::constructAbstractSubprogramScopeDIE( 8520b57cec5SDimitry Andric LexicalScope *Scope) { 8530b57cec5SDimitry Andric DIE *&AbsDef = getAbstractSPDies()[Scope->getScopeNode()]; 8540b57cec5SDimitry Andric if (AbsDef) 8550b57cec5SDimitry Andric return; 8560b57cec5SDimitry Andric 8570b57cec5SDimitry Andric auto *SP = cast<DISubprogram>(Scope->getScopeNode()); 8580b57cec5SDimitry Andric 8590b57cec5SDimitry Andric DIE *ContextDIE; 8600b57cec5SDimitry Andric DwarfCompileUnit *ContextCU = this; 8610b57cec5SDimitry Andric 8620b57cec5SDimitry Andric if (includeMinimalInlineScopes()) 8630b57cec5SDimitry Andric ContextDIE = &getUnitDie(); 8640b57cec5SDimitry Andric // Some of this is duplicated from DwarfUnit::getOrCreateSubprogramDIE, with 8650b57cec5SDimitry Andric // the important distinction that the debug node is not associated with the 8660b57cec5SDimitry Andric // DIE (since the debug node will be associated with the concrete DIE, if 8670b57cec5SDimitry Andric // any). It could be refactored to some common utility function. 8680b57cec5SDimitry Andric else if (auto *SPDecl = SP->getDeclaration()) { 8690b57cec5SDimitry Andric ContextDIE = &getUnitDie(); 8700b57cec5SDimitry Andric getOrCreateSubprogramDIE(SPDecl); 8710b57cec5SDimitry Andric } else { 8720b57cec5SDimitry Andric ContextDIE = getOrCreateContextDIE(SP->getScope()); 8730b57cec5SDimitry Andric // The scope may be shared with a subprogram that has already been 8740b57cec5SDimitry Andric // constructed in another CU, in which case we need to construct this 8750b57cec5SDimitry Andric // subprogram in the same CU. 8760b57cec5SDimitry Andric ContextCU = DD->lookupCU(ContextDIE->getUnitDie()); 8770b57cec5SDimitry Andric } 8780b57cec5SDimitry Andric 8790b57cec5SDimitry Andric // Passing null as the associated node because the abstract definition 8800b57cec5SDimitry Andric // shouldn't be found by lookup. 8810b57cec5SDimitry Andric AbsDef = &ContextCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, nullptr); 8820b57cec5SDimitry Andric ContextCU->applySubprogramAttributesToDefinition(SP, *AbsDef); 8830b57cec5SDimitry Andric 8840b57cec5SDimitry Andric if (!ContextCU->includeMinimalInlineScopes()) 8850b57cec5SDimitry Andric ContextCU->addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined); 8860b57cec5SDimitry Andric if (DIE *ObjectPointer = ContextCU->createAndAddScopeChildren(Scope, *AbsDef)) 8870b57cec5SDimitry Andric ContextCU->addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer); 8880b57cec5SDimitry Andric } 8890b57cec5SDimitry Andric 890*8bcb0991SDimitry Andric /// Whether to use the GNU analog for a DWARF5 tag, attribute, or location atom. 891*8bcb0991SDimitry Andric static bool useGNUAnalogForDwarf5Feature(DwarfDebug *DD) { 892*8bcb0991SDimitry Andric return DD->getDwarfVersion() == 4 && DD->tuneForGDB(); 893*8bcb0991SDimitry Andric } 894*8bcb0991SDimitry Andric 895*8bcb0991SDimitry Andric dwarf::Tag DwarfCompileUnit::getDwarf5OrGNUTag(dwarf::Tag Tag) const { 896*8bcb0991SDimitry Andric if (!useGNUAnalogForDwarf5Feature(DD)) 897*8bcb0991SDimitry Andric return Tag; 898*8bcb0991SDimitry Andric switch (Tag) { 899*8bcb0991SDimitry Andric case dwarf::DW_TAG_call_site: 900*8bcb0991SDimitry Andric return dwarf::DW_TAG_GNU_call_site; 901*8bcb0991SDimitry Andric case dwarf::DW_TAG_call_site_parameter: 902*8bcb0991SDimitry Andric return dwarf::DW_TAG_GNU_call_site_parameter; 903*8bcb0991SDimitry Andric default: 904*8bcb0991SDimitry Andric llvm_unreachable("DWARF5 tag with no GNU analog"); 905*8bcb0991SDimitry Andric } 906*8bcb0991SDimitry Andric } 907*8bcb0991SDimitry Andric 908*8bcb0991SDimitry Andric dwarf::Attribute 909*8bcb0991SDimitry Andric DwarfCompileUnit::getDwarf5OrGNUAttr(dwarf::Attribute Attr) const { 910*8bcb0991SDimitry Andric if (!useGNUAnalogForDwarf5Feature(DD)) 911*8bcb0991SDimitry Andric return Attr; 912*8bcb0991SDimitry Andric switch (Attr) { 913*8bcb0991SDimitry Andric case dwarf::DW_AT_call_all_calls: 914*8bcb0991SDimitry Andric return dwarf::DW_AT_GNU_all_call_sites; 915*8bcb0991SDimitry Andric case dwarf::DW_AT_call_target: 916*8bcb0991SDimitry Andric return dwarf::DW_AT_GNU_call_site_target; 917*8bcb0991SDimitry Andric case dwarf::DW_AT_call_origin: 918*8bcb0991SDimitry Andric return dwarf::DW_AT_abstract_origin; 919*8bcb0991SDimitry Andric case dwarf::DW_AT_call_pc: 920*8bcb0991SDimitry Andric return dwarf::DW_AT_low_pc; 921*8bcb0991SDimitry Andric case dwarf::DW_AT_call_value: 922*8bcb0991SDimitry Andric return dwarf::DW_AT_GNU_call_site_value; 923*8bcb0991SDimitry Andric case dwarf::DW_AT_call_tail_call: 924*8bcb0991SDimitry Andric return dwarf::DW_AT_GNU_tail_call; 925*8bcb0991SDimitry Andric default: 926*8bcb0991SDimitry Andric llvm_unreachable("DWARF5 attribute with no GNU analog"); 927*8bcb0991SDimitry Andric } 928*8bcb0991SDimitry Andric } 929*8bcb0991SDimitry Andric 930*8bcb0991SDimitry Andric dwarf::LocationAtom 931*8bcb0991SDimitry Andric DwarfCompileUnit::getDwarf5OrGNULocationAtom(dwarf::LocationAtom Loc) const { 932*8bcb0991SDimitry Andric if (!useGNUAnalogForDwarf5Feature(DD)) 933*8bcb0991SDimitry Andric return Loc; 934*8bcb0991SDimitry Andric switch (Loc) { 935*8bcb0991SDimitry Andric case dwarf::DW_OP_entry_value: 936*8bcb0991SDimitry Andric return dwarf::DW_OP_GNU_entry_value; 937*8bcb0991SDimitry Andric default: 938*8bcb0991SDimitry Andric llvm_unreachable("DWARF5 location atom with no GNU analog"); 939*8bcb0991SDimitry Andric } 940*8bcb0991SDimitry Andric } 941*8bcb0991SDimitry Andric 942*8bcb0991SDimitry Andric DIE &DwarfCompileUnit::constructCallSiteEntryDIE( 943*8bcb0991SDimitry Andric DIE &ScopeDIE, const DISubprogram *CalleeSP, bool IsTail, 944*8bcb0991SDimitry Andric const MCSymbol *PCAddr, const MCExpr *PCOffset, unsigned CallReg) { 9450b57cec5SDimitry Andric // Insert a call site entry DIE within ScopeDIE. 946*8bcb0991SDimitry Andric DIE &CallSiteDIE = createAndAddDIE(getDwarf5OrGNUTag(dwarf::DW_TAG_call_site), 947*8bcb0991SDimitry Andric ScopeDIE, nullptr); 9480b57cec5SDimitry Andric 949*8bcb0991SDimitry Andric if (CallReg) { 950*8bcb0991SDimitry Andric // Indirect call. 951*8bcb0991SDimitry Andric addAddress(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_target), 952*8bcb0991SDimitry Andric MachineLocation(CallReg)); 9530b57cec5SDimitry Andric } else { 954*8bcb0991SDimitry Andric DIE *CalleeDIE = getOrCreateSubprogramDIE(CalleeSP); 955*8bcb0991SDimitry Andric assert(CalleeDIE && "Could not create DIE for call site entry origin"); 956*8bcb0991SDimitry Andric addDIEEntry(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_origin), 957*8bcb0991SDimitry Andric *CalleeDIE); 958*8bcb0991SDimitry Andric } 959*8bcb0991SDimitry Andric 960*8bcb0991SDimitry Andric if (IsTail) 961*8bcb0991SDimitry Andric // Attach DW_AT_call_tail_call to tail calls for standards compliance. 962*8bcb0991SDimitry Andric addFlag(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_tail_call)); 963*8bcb0991SDimitry Andric 9640b57cec5SDimitry Andric // Attach the return PC to allow the debugger to disambiguate call paths 9650b57cec5SDimitry Andric // from one function to another. 966*8bcb0991SDimitry Andric if (DD->getDwarfVersion() == 4 && DD->tuneForGDB()) { 967*8bcb0991SDimitry Andric assert(PCAddr && "Missing PC information for a call"); 968*8bcb0991SDimitry Andric addLabelAddress(CallSiteDIE, dwarf::DW_AT_low_pc, PCAddr); 969*8bcb0991SDimitry Andric } else if (!IsTail || DD->tuneForGDB()) { 9700b57cec5SDimitry Andric assert(PCOffset && "Missing return PC information for a call"); 9710b57cec5SDimitry Andric addAddressExpr(CallSiteDIE, dwarf::DW_AT_call_return_pc, PCOffset); 9720b57cec5SDimitry Andric } 973*8bcb0991SDimitry Andric 9740b57cec5SDimitry Andric return CallSiteDIE; 9750b57cec5SDimitry Andric } 9760b57cec5SDimitry Andric 977*8bcb0991SDimitry Andric void DwarfCompileUnit::constructCallSiteParmEntryDIEs( 978*8bcb0991SDimitry Andric DIE &CallSiteDIE, SmallVector<DbgCallSiteParam, 4> &Params) { 979*8bcb0991SDimitry Andric for (const auto &Param : Params) { 980*8bcb0991SDimitry Andric unsigned Register = Param.getRegister(); 981*8bcb0991SDimitry Andric auto CallSiteDieParam = 982*8bcb0991SDimitry Andric DIE::get(DIEValueAllocator, 983*8bcb0991SDimitry Andric getDwarf5OrGNUTag(dwarf::DW_TAG_call_site_parameter)); 984*8bcb0991SDimitry Andric insertDIE(CallSiteDieParam); 985*8bcb0991SDimitry Andric addAddress(*CallSiteDieParam, dwarf::DW_AT_location, 986*8bcb0991SDimitry Andric MachineLocation(Register)); 987*8bcb0991SDimitry Andric 988*8bcb0991SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 989*8bcb0991SDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); 990*8bcb0991SDimitry Andric DwarfExpr.setCallSiteParamValueFlag(); 991*8bcb0991SDimitry Andric 992*8bcb0991SDimitry Andric DwarfDebug::emitDebugLocValue(*Asm, nullptr, Param.getValue(), DwarfExpr); 993*8bcb0991SDimitry Andric 994*8bcb0991SDimitry Andric addBlock(*CallSiteDieParam, getDwarf5OrGNUAttr(dwarf::DW_AT_call_value), 995*8bcb0991SDimitry Andric DwarfExpr.finalize()); 996*8bcb0991SDimitry Andric 997*8bcb0991SDimitry Andric CallSiteDIE.addChild(CallSiteDieParam); 998*8bcb0991SDimitry Andric } 999*8bcb0991SDimitry Andric } 1000*8bcb0991SDimitry Andric 10010b57cec5SDimitry Andric DIE *DwarfCompileUnit::constructImportedEntityDIE( 10020b57cec5SDimitry Andric const DIImportedEntity *Module) { 10030b57cec5SDimitry Andric DIE *IMDie = DIE::get(DIEValueAllocator, (dwarf::Tag)Module->getTag()); 10040b57cec5SDimitry Andric insertDIE(Module, IMDie); 10050b57cec5SDimitry Andric DIE *EntityDie; 10060b57cec5SDimitry Andric auto *Entity = Module->getEntity(); 10070b57cec5SDimitry Andric if (auto *NS = dyn_cast<DINamespace>(Entity)) 10080b57cec5SDimitry Andric EntityDie = getOrCreateNameSpace(NS); 10090b57cec5SDimitry Andric else if (auto *M = dyn_cast<DIModule>(Entity)) 10100b57cec5SDimitry Andric EntityDie = getOrCreateModule(M); 10110b57cec5SDimitry Andric else if (auto *SP = dyn_cast<DISubprogram>(Entity)) 10120b57cec5SDimitry Andric EntityDie = getOrCreateSubprogramDIE(SP); 10130b57cec5SDimitry Andric else if (auto *T = dyn_cast<DIType>(Entity)) 10140b57cec5SDimitry Andric EntityDie = getOrCreateTypeDIE(T); 10150b57cec5SDimitry Andric else if (auto *GV = dyn_cast<DIGlobalVariable>(Entity)) 10160b57cec5SDimitry Andric EntityDie = getOrCreateGlobalVariableDIE(GV, {}); 10170b57cec5SDimitry Andric else 10180b57cec5SDimitry Andric EntityDie = getDIE(Entity); 10190b57cec5SDimitry Andric assert(EntityDie); 10200b57cec5SDimitry Andric addSourceLine(*IMDie, Module->getLine(), Module->getFile()); 10210b57cec5SDimitry Andric addDIEEntry(*IMDie, dwarf::DW_AT_import, *EntityDie); 10220b57cec5SDimitry Andric StringRef Name = Module->getName(); 10230b57cec5SDimitry Andric if (!Name.empty()) 10240b57cec5SDimitry Andric addString(*IMDie, dwarf::DW_AT_name, Name); 10250b57cec5SDimitry Andric 10260b57cec5SDimitry Andric return IMDie; 10270b57cec5SDimitry Andric } 10280b57cec5SDimitry Andric 10290b57cec5SDimitry Andric void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP) { 10300b57cec5SDimitry Andric DIE *D = getDIE(SP); 10310b57cec5SDimitry Andric if (DIE *AbsSPDIE = getAbstractSPDies().lookup(SP)) { 10320b57cec5SDimitry Andric if (D) 10330b57cec5SDimitry Andric // If this subprogram has an abstract definition, reference that 10340b57cec5SDimitry Andric addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE); 10350b57cec5SDimitry Andric } else { 10360b57cec5SDimitry Andric assert(D || includeMinimalInlineScopes()); 10370b57cec5SDimitry Andric if (D) 10380b57cec5SDimitry Andric // And attach the attributes 10390b57cec5SDimitry Andric applySubprogramAttributesToDefinition(SP, *D); 10400b57cec5SDimitry Andric } 10410b57cec5SDimitry Andric } 10420b57cec5SDimitry Andric 10430b57cec5SDimitry Andric void DwarfCompileUnit::finishEntityDefinition(const DbgEntity *Entity) { 10440b57cec5SDimitry Andric DbgEntity *AbsEntity = getExistingAbstractEntity(Entity->getEntity()); 10450b57cec5SDimitry Andric 10460b57cec5SDimitry Andric auto *Die = Entity->getDIE(); 10470b57cec5SDimitry Andric /// Label may be used to generate DW_AT_low_pc, so put it outside 10480b57cec5SDimitry Andric /// if/else block. 10490b57cec5SDimitry Andric const DbgLabel *Label = nullptr; 10500b57cec5SDimitry Andric if (AbsEntity && AbsEntity->getDIE()) { 10510b57cec5SDimitry Andric addDIEEntry(*Die, dwarf::DW_AT_abstract_origin, *AbsEntity->getDIE()); 10520b57cec5SDimitry Andric Label = dyn_cast<const DbgLabel>(Entity); 10530b57cec5SDimitry Andric } else { 10540b57cec5SDimitry Andric if (const DbgVariable *Var = dyn_cast<const DbgVariable>(Entity)) 10550b57cec5SDimitry Andric applyVariableAttributes(*Var, *Die); 10560b57cec5SDimitry Andric else if ((Label = dyn_cast<const DbgLabel>(Entity))) 10570b57cec5SDimitry Andric applyLabelAttributes(*Label, *Die); 10580b57cec5SDimitry Andric else 10590b57cec5SDimitry Andric llvm_unreachable("DbgEntity must be DbgVariable or DbgLabel."); 10600b57cec5SDimitry Andric } 10610b57cec5SDimitry Andric 10620b57cec5SDimitry Andric if (Label) 10630b57cec5SDimitry Andric if (const auto *Sym = Label->getSymbol()) 10640b57cec5SDimitry Andric addLabelAddress(*Die, dwarf::DW_AT_low_pc, Sym); 10650b57cec5SDimitry Andric } 10660b57cec5SDimitry Andric 10670b57cec5SDimitry Andric DbgEntity *DwarfCompileUnit::getExistingAbstractEntity(const DINode *Node) { 10680b57cec5SDimitry Andric auto &AbstractEntities = getAbstractEntities(); 10690b57cec5SDimitry Andric auto I = AbstractEntities.find(Node); 10700b57cec5SDimitry Andric if (I != AbstractEntities.end()) 10710b57cec5SDimitry Andric return I->second.get(); 10720b57cec5SDimitry Andric return nullptr; 10730b57cec5SDimitry Andric } 10740b57cec5SDimitry Andric 10750b57cec5SDimitry Andric void DwarfCompileUnit::createAbstractEntity(const DINode *Node, 10760b57cec5SDimitry Andric LexicalScope *Scope) { 10770b57cec5SDimitry Andric assert(Scope && Scope->isAbstractScope()); 10780b57cec5SDimitry Andric auto &Entity = getAbstractEntities()[Node]; 10790b57cec5SDimitry Andric if (isa<const DILocalVariable>(Node)) { 1080*8bcb0991SDimitry Andric Entity = std::make_unique<DbgVariable>( 10810b57cec5SDimitry Andric cast<const DILocalVariable>(Node), nullptr /* IA */);; 10820b57cec5SDimitry Andric DU->addScopeVariable(Scope, cast<DbgVariable>(Entity.get())); 10830b57cec5SDimitry Andric } else if (isa<const DILabel>(Node)) { 1084*8bcb0991SDimitry Andric Entity = std::make_unique<DbgLabel>( 10850b57cec5SDimitry Andric cast<const DILabel>(Node), nullptr /* IA */); 10860b57cec5SDimitry Andric DU->addScopeLabel(Scope, cast<DbgLabel>(Entity.get())); 10870b57cec5SDimitry Andric } 10880b57cec5SDimitry Andric } 10890b57cec5SDimitry Andric 10900b57cec5SDimitry Andric void DwarfCompileUnit::emitHeader(bool UseOffsets) { 10910b57cec5SDimitry Andric // Don't bother labeling the .dwo unit, as its offset isn't used. 10920b57cec5SDimitry Andric if (!Skeleton && !DD->useSectionsAsReferences()) { 10930b57cec5SDimitry Andric LabelBegin = Asm->createTempSymbol("cu_begin"); 10940b57cec5SDimitry Andric Asm->OutStreamer->EmitLabel(LabelBegin); 10950b57cec5SDimitry Andric } 10960b57cec5SDimitry Andric 10970b57cec5SDimitry Andric dwarf::UnitType UT = Skeleton ? dwarf::DW_UT_split_compile 10980b57cec5SDimitry Andric : DD->useSplitDwarf() ? dwarf::DW_UT_skeleton 10990b57cec5SDimitry Andric : dwarf::DW_UT_compile; 11000b57cec5SDimitry Andric DwarfUnit::emitCommonHeader(UseOffsets, UT); 11010b57cec5SDimitry Andric if (DD->getDwarfVersion() >= 5 && UT != dwarf::DW_UT_compile) 11020b57cec5SDimitry Andric Asm->emitInt64(getDWOId()); 11030b57cec5SDimitry Andric } 11040b57cec5SDimitry Andric 11050b57cec5SDimitry Andric bool DwarfCompileUnit::hasDwarfPubSections() const { 11060b57cec5SDimitry Andric switch (CUNode->getNameTableKind()) { 11070b57cec5SDimitry Andric case DICompileUnit::DebugNameTableKind::None: 11080b57cec5SDimitry Andric return false; 11090b57cec5SDimitry Andric // Opting in to GNU Pubnames/types overrides the default to ensure these are 11100b57cec5SDimitry Andric // generated for things like Gold's gdb_index generation. 11110b57cec5SDimitry Andric case DICompileUnit::DebugNameTableKind::GNU: 11120b57cec5SDimitry Andric return true; 11130b57cec5SDimitry Andric case DICompileUnit::DebugNameTableKind::Default: 11140b57cec5SDimitry Andric return DD->tuneForGDB() && !includeMinimalInlineScopes() && 11150b57cec5SDimitry Andric !CUNode->isDebugDirectivesOnly() && 11160b57cec5SDimitry Andric DD->getAccelTableKind() != AccelTableKind::Apple && 11170b57cec5SDimitry Andric DD->getDwarfVersion() < 5; 11180b57cec5SDimitry Andric } 11190b57cec5SDimitry Andric llvm_unreachable("Unhandled DICompileUnit::DebugNameTableKind enum"); 11200b57cec5SDimitry Andric } 11210b57cec5SDimitry Andric 11220b57cec5SDimitry Andric /// addGlobalName - Add a new global name to the compile unit. 11230b57cec5SDimitry Andric void DwarfCompileUnit::addGlobalName(StringRef Name, const DIE &Die, 11240b57cec5SDimitry Andric const DIScope *Context) { 11250b57cec5SDimitry Andric if (!hasDwarfPubSections()) 11260b57cec5SDimitry Andric return; 11270b57cec5SDimitry Andric std::string FullName = getParentContextString(Context) + Name.str(); 11280b57cec5SDimitry Andric GlobalNames[FullName] = &Die; 11290b57cec5SDimitry Andric } 11300b57cec5SDimitry Andric 11310b57cec5SDimitry Andric void DwarfCompileUnit::addGlobalNameForTypeUnit(StringRef Name, 11320b57cec5SDimitry Andric const DIScope *Context) { 11330b57cec5SDimitry Andric if (!hasDwarfPubSections()) 11340b57cec5SDimitry Andric return; 11350b57cec5SDimitry Andric std::string FullName = getParentContextString(Context) + Name.str(); 11360b57cec5SDimitry Andric // Insert, allowing the entry to remain as-is if it's already present 11370b57cec5SDimitry Andric // This way the CU-level type DIE is preferred over the "can't describe this 11380b57cec5SDimitry Andric // type as a unit offset because it's not really in the CU at all, it's only 11390b57cec5SDimitry Andric // in a type unit" 11400b57cec5SDimitry Andric GlobalNames.insert(std::make_pair(std::move(FullName), &getUnitDie())); 11410b57cec5SDimitry Andric } 11420b57cec5SDimitry Andric 11430b57cec5SDimitry Andric /// Add a new global type to the unit. 11440b57cec5SDimitry Andric void DwarfCompileUnit::addGlobalType(const DIType *Ty, const DIE &Die, 11450b57cec5SDimitry Andric const DIScope *Context) { 11460b57cec5SDimitry Andric if (!hasDwarfPubSections()) 11470b57cec5SDimitry Andric return; 11480b57cec5SDimitry Andric std::string FullName = getParentContextString(Context) + Ty->getName().str(); 11490b57cec5SDimitry Andric GlobalTypes[FullName] = &Die; 11500b57cec5SDimitry Andric } 11510b57cec5SDimitry Andric 11520b57cec5SDimitry Andric void DwarfCompileUnit::addGlobalTypeUnitType(const DIType *Ty, 11530b57cec5SDimitry Andric const DIScope *Context) { 11540b57cec5SDimitry Andric if (!hasDwarfPubSections()) 11550b57cec5SDimitry Andric return; 11560b57cec5SDimitry Andric std::string FullName = getParentContextString(Context) + Ty->getName().str(); 11570b57cec5SDimitry Andric // Insert, allowing the entry to remain as-is if it's already present 11580b57cec5SDimitry Andric // This way the CU-level type DIE is preferred over the "can't describe this 11590b57cec5SDimitry Andric // type as a unit offset because it's not really in the CU at all, it's only 11600b57cec5SDimitry Andric // in a type unit" 11610b57cec5SDimitry Andric GlobalTypes.insert(std::make_pair(std::move(FullName), &getUnitDie())); 11620b57cec5SDimitry Andric } 11630b57cec5SDimitry Andric 11640b57cec5SDimitry Andric void DwarfCompileUnit::addVariableAddress(const DbgVariable &DV, DIE &Die, 11650b57cec5SDimitry Andric MachineLocation Location) { 11660b57cec5SDimitry Andric if (DV.hasComplexAddress()) 11670b57cec5SDimitry Andric addComplexAddress(DV, Die, dwarf::DW_AT_location, Location); 11680b57cec5SDimitry Andric else 11690b57cec5SDimitry Andric addAddress(Die, dwarf::DW_AT_location, Location); 11700b57cec5SDimitry Andric } 11710b57cec5SDimitry Andric 11720b57cec5SDimitry Andric /// Add an address attribute to a die based on the location provided. 11730b57cec5SDimitry Andric void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute, 11740b57cec5SDimitry Andric const MachineLocation &Location) { 11750b57cec5SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 11760b57cec5SDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); 11770b57cec5SDimitry Andric if (Location.isIndirect()) 11780b57cec5SDimitry Andric DwarfExpr.setMemoryLocationKind(); 11790b57cec5SDimitry Andric 11800b57cec5SDimitry Andric DIExpressionCursor Cursor({}); 11810b57cec5SDimitry Andric const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo(); 11820b57cec5SDimitry Andric if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg())) 11830b57cec5SDimitry Andric return; 11840b57cec5SDimitry Andric DwarfExpr.addExpression(std::move(Cursor)); 11850b57cec5SDimitry Andric 11860b57cec5SDimitry Andric // Now attach the location information to the DIE. 11870b57cec5SDimitry Andric addBlock(Die, Attribute, DwarfExpr.finalize()); 11880b57cec5SDimitry Andric } 11890b57cec5SDimitry Andric 11900b57cec5SDimitry Andric /// Start with the address based on the location provided, and generate the 11910b57cec5SDimitry Andric /// DWARF information necessary to find the actual variable given the extra 11920b57cec5SDimitry Andric /// address information encoded in the DbgVariable, starting from the starting 11930b57cec5SDimitry Andric /// location. Add the DWARF information to the die. 11940b57cec5SDimitry Andric void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die, 11950b57cec5SDimitry Andric dwarf::Attribute Attribute, 11960b57cec5SDimitry Andric const MachineLocation &Location) { 11970b57cec5SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 11980b57cec5SDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); 11990b57cec5SDimitry Andric const DIExpression *DIExpr = DV.getSingleExpression(); 12000b57cec5SDimitry Andric DwarfExpr.addFragmentOffset(DIExpr); 12010b57cec5SDimitry Andric if (Location.isIndirect()) 12020b57cec5SDimitry Andric DwarfExpr.setMemoryLocationKind(); 12030b57cec5SDimitry Andric 12040b57cec5SDimitry Andric DIExpressionCursor Cursor(DIExpr); 12050b57cec5SDimitry Andric 12060b57cec5SDimitry Andric if (DIExpr->isEntryValue()) { 12070b57cec5SDimitry Andric DwarfExpr.setEntryValueFlag(); 1208*8bcb0991SDimitry Andric DwarfExpr.beginEntryValueExpression(Cursor); 12090b57cec5SDimitry Andric } 12100b57cec5SDimitry Andric 12110b57cec5SDimitry Andric const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo(); 12120b57cec5SDimitry Andric if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg())) 12130b57cec5SDimitry Andric return; 12140b57cec5SDimitry Andric DwarfExpr.addExpression(std::move(Cursor)); 12150b57cec5SDimitry Andric 12160b57cec5SDimitry Andric // Now attach the location information to the DIE. 12170b57cec5SDimitry Andric addBlock(Die, Attribute, DwarfExpr.finalize()); 12180b57cec5SDimitry Andric } 12190b57cec5SDimitry Andric 12200b57cec5SDimitry Andric /// Add a Dwarf loclistptr attribute data and value. 12210b57cec5SDimitry Andric void DwarfCompileUnit::addLocationList(DIE &Die, dwarf::Attribute Attribute, 12220b57cec5SDimitry Andric unsigned Index) { 12230b57cec5SDimitry Andric dwarf::Form Form = DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset 12240b57cec5SDimitry Andric : dwarf::DW_FORM_data4; 12250b57cec5SDimitry Andric Die.addValue(DIEValueAllocator, Attribute, Form, DIELocList(Index)); 12260b57cec5SDimitry Andric } 12270b57cec5SDimitry Andric 12280b57cec5SDimitry Andric void DwarfCompileUnit::applyVariableAttributes(const DbgVariable &Var, 12290b57cec5SDimitry Andric DIE &VariableDie) { 12300b57cec5SDimitry Andric StringRef Name = Var.getName(); 12310b57cec5SDimitry Andric if (!Name.empty()) 12320b57cec5SDimitry Andric addString(VariableDie, dwarf::DW_AT_name, Name); 12330b57cec5SDimitry Andric const auto *DIVar = Var.getVariable(); 12340b57cec5SDimitry Andric if (DIVar) 12350b57cec5SDimitry Andric if (uint32_t AlignInBytes = DIVar->getAlignInBytes()) 12360b57cec5SDimitry Andric addUInt(VariableDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata, 12370b57cec5SDimitry Andric AlignInBytes); 12380b57cec5SDimitry Andric 12390b57cec5SDimitry Andric addSourceLine(VariableDie, DIVar); 12400b57cec5SDimitry Andric addType(VariableDie, Var.getType()); 12410b57cec5SDimitry Andric if (Var.isArtificial()) 12420b57cec5SDimitry Andric addFlag(VariableDie, dwarf::DW_AT_artificial); 12430b57cec5SDimitry Andric } 12440b57cec5SDimitry Andric 12450b57cec5SDimitry Andric void DwarfCompileUnit::applyLabelAttributes(const DbgLabel &Label, 12460b57cec5SDimitry Andric DIE &LabelDie) { 12470b57cec5SDimitry Andric StringRef Name = Label.getName(); 12480b57cec5SDimitry Andric if (!Name.empty()) 12490b57cec5SDimitry Andric addString(LabelDie, dwarf::DW_AT_name, Name); 12500b57cec5SDimitry Andric const auto *DILabel = Label.getLabel(); 12510b57cec5SDimitry Andric addSourceLine(LabelDie, DILabel); 12520b57cec5SDimitry Andric } 12530b57cec5SDimitry Andric 12540b57cec5SDimitry Andric /// Add a Dwarf expression attribute data and value. 12550b57cec5SDimitry Andric void DwarfCompileUnit::addExpr(DIELoc &Die, dwarf::Form Form, 12560b57cec5SDimitry Andric const MCExpr *Expr) { 12570b57cec5SDimitry Andric Die.addValue(DIEValueAllocator, (dwarf::Attribute)0, Form, DIEExpr(Expr)); 12580b57cec5SDimitry Andric } 12590b57cec5SDimitry Andric 12600b57cec5SDimitry Andric void DwarfCompileUnit::addAddressExpr(DIE &Die, dwarf::Attribute Attribute, 12610b57cec5SDimitry Andric const MCExpr *Expr) { 12620b57cec5SDimitry Andric Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_addr, 12630b57cec5SDimitry Andric DIEExpr(Expr)); 12640b57cec5SDimitry Andric } 12650b57cec5SDimitry Andric 12660b57cec5SDimitry Andric void DwarfCompileUnit::applySubprogramAttributesToDefinition( 12670b57cec5SDimitry Andric const DISubprogram *SP, DIE &SPDie) { 12680b57cec5SDimitry Andric auto *SPDecl = SP->getDeclaration(); 12690b57cec5SDimitry Andric auto *Context = SPDecl ? SPDecl->getScope() : SP->getScope(); 12700b57cec5SDimitry Andric applySubprogramAttributes(SP, SPDie, includeMinimalInlineScopes()); 12710b57cec5SDimitry Andric addGlobalName(SP->getName(), SPDie, Context); 12720b57cec5SDimitry Andric } 12730b57cec5SDimitry Andric 12740b57cec5SDimitry Andric bool DwarfCompileUnit::isDwoUnit() const { 12750b57cec5SDimitry Andric return DD->useSplitDwarf() && Skeleton; 12760b57cec5SDimitry Andric } 12770b57cec5SDimitry Andric 12780b57cec5SDimitry Andric void DwarfCompileUnit::finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) { 12790b57cec5SDimitry Andric constructTypeDIE(D, CTy); 12800b57cec5SDimitry Andric } 12810b57cec5SDimitry Andric 12820b57cec5SDimitry Andric bool DwarfCompileUnit::includeMinimalInlineScopes() const { 12830b57cec5SDimitry Andric return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly || 12840b57cec5SDimitry Andric (DD->useSplitDwarf() && !Skeleton); 12850b57cec5SDimitry Andric } 12860b57cec5SDimitry Andric 12870b57cec5SDimitry Andric void DwarfCompileUnit::addAddrTableBase() { 12880b57cec5SDimitry Andric const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); 12890b57cec5SDimitry Andric MCSymbol *Label = DD->getAddressPool().getLabel(); 12900b57cec5SDimitry Andric addSectionLabel(getUnitDie(), 12910b57cec5SDimitry Andric getDwarfVersion() >= 5 ? dwarf::DW_AT_addr_base 12920b57cec5SDimitry Andric : dwarf::DW_AT_GNU_addr_base, 12930b57cec5SDimitry Andric Label, TLOF.getDwarfAddrSection()->getBeginSymbol()); 12940b57cec5SDimitry Andric } 12950b57cec5SDimitry Andric 12960b57cec5SDimitry Andric void DwarfCompileUnit::addBaseTypeRef(DIEValueList &Die, int64_t Idx) { 12970b57cec5SDimitry Andric Die.addValue(DIEValueAllocator, (dwarf::Attribute)0, dwarf::DW_FORM_udata, 12980b57cec5SDimitry Andric new (DIEValueAllocator) DIEBaseTypeRef(this, Idx)); 12990b57cec5SDimitry Andric } 13000b57cec5SDimitry Andric 13010b57cec5SDimitry Andric void DwarfCompileUnit::createBaseTypeDIEs() { 13020b57cec5SDimitry Andric // Insert the base_type DIEs directly after the CU so that their offsets will 13030b57cec5SDimitry Andric // fit in the fixed size ULEB128 used inside the location expressions. 13040b57cec5SDimitry Andric // Maintain order by iterating backwards and inserting to the front of CU 13050b57cec5SDimitry Andric // child list. 13060b57cec5SDimitry Andric for (auto &Btr : reverse(ExprRefedBaseTypes)) { 13070b57cec5SDimitry Andric DIE &Die = getUnitDie().addChildFront( 13080b57cec5SDimitry Andric DIE::get(DIEValueAllocator, dwarf::DW_TAG_base_type)); 13090b57cec5SDimitry Andric SmallString<32> Str; 13100b57cec5SDimitry Andric addString(Die, dwarf::DW_AT_name, 13110b57cec5SDimitry Andric Twine(dwarf::AttributeEncodingString(Btr.Encoding) + 13120b57cec5SDimitry Andric "_" + Twine(Btr.BitSize)).toStringRef(Str)); 13130b57cec5SDimitry Andric addUInt(Die, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Btr.Encoding); 13140b57cec5SDimitry Andric addUInt(Die, dwarf::DW_AT_byte_size, None, Btr.BitSize / 8); 13150b57cec5SDimitry Andric 13160b57cec5SDimitry Andric Btr.Die = &Die; 13170b57cec5SDimitry Andric } 13180b57cec5SDimitry Andric } 1319