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 "DwarfExpression.h" 160b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 170b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h" 18fe6060f1SDimitry Andric #include "llvm/BinaryFormat/Dwarf.h" 190b57cec5SDimitry Andric #include "llvm/CodeGen/AsmPrinter.h" 200b57cec5SDimitry Andric #include "llvm/CodeGen/DIE.h" 210b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 220b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h" 230b57cec5SDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h" 240b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h" 250b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h" 260b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 270b57cec5SDimitry Andric #include "llvm/IR/DebugInfo.h" 280b57cec5SDimitry Andric #include "llvm/IR/GlobalVariable.h" 2906c3fb27SDimitry Andric #include "llvm/MC/MCAsmInfo.h" 300b57cec5SDimitry Andric #include "llvm/MC/MCSection.h" 310b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 320b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h" 335ffd83dbSDimitry Andric #include "llvm/MC/MCSymbolWasm.h" 340b57cec5SDimitry Andric #include "llvm/MC/MachineLocation.h" 35*0fca6ea1SDimitry Andric #include "llvm/Support/CommandLine.h" 360b57cec5SDimitry Andric #include "llvm/Target/TargetLoweringObjectFile.h" 370b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h" 380b57cec5SDimitry Andric #include "llvm/Target/TargetOptions.h" 390b57cec5SDimitry Andric #include <iterator> 40bdd1243dSDimitry Andric #include <optional> 410b57cec5SDimitry Andric #include <string> 420b57cec5SDimitry Andric #include <utility> 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric using namespace llvm; 450b57cec5SDimitry Andric 46*0fca6ea1SDimitry Andric /// Query value using AddLinkageNamesToDeclCallOriginsForTuning. 47*0fca6ea1SDimitry Andric cl::opt<cl::boolOrDefault> AddLinkageNamesToDeclCallOrigins( 48*0fca6ea1SDimitry Andric "add-linkage-names-to-declaration-call-origins", cl::Hidden, 49*0fca6ea1SDimitry Andric cl::desc("Add DW_AT_linkage_name to function declaration DIEs " 50*0fca6ea1SDimitry Andric "referenced by DW_AT_call_origin attributes. Enabled by default " 51*0fca6ea1SDimitry Andric "for -gsce debugger tuning.")); 52*0fca6ea1SDimitry Andric 53*0fca6ea1SDimitry Andric static bool AddLinkageNamesToDeclCallOriginsForTuning(const DwarfDebug *DD) { 54*0fca6ea1SDimitry Andric bool EnabledByDefault = DD->tuneForSCE(); 55*0fca6ea1SDimitry Andric if (EnabledByDefault) 56*0fca6ea1SDimitry Andric return AddLinkageNamesToDeclCallOrigins != cl::boolOrDefault::BOU_FALSE; 57*0fca6ea1SDimitry Andric return AddLinkageNamesToDeclCallOrigins == cl::boolOrDefault::BOU_TRUE; 58*0fca6ea1SDimitry Andric } 59*0fca6ea1SDimitry Andric 60480093f4SDimitry Andric static dwarf::Tag GetCompileUnitType(UnitKind Kind, DwarfDebug *DW) { 61480093f4SDimitry Andric 62480093f4SDimitry Andric // According to DWARF Debugging Information Format Version 5, 63480093f4SDimitry Andric // 3.1.2 Skeleton Compilation Unit Entries: 64480093f4SDimitry Andric // "When generating a split DWARF object file (see Section 7.3.2 65480093f4SDimitry Andric // on page 187), the compilation unit in the .debug_info section 66480093f4SDimitry Andric // is a "skeleton" compilation unit with the tag DW_TAG_skeleton_unit" 67480093f4SDimitry Andric if (DW->getDwarfVersion() >= 5 && Kind == UnitKind::Skeleton) 68480093f4SDimitry Andric return dwarf::DW_TAG_skeleton_unit; 69480093f4SDimitry Andric 70480093f4SDimitry Andric return dwarf::DW_TAG_compile_unit; 71480093f4SDimitry Andric } 72480093f4SDimitry Andric 730b57cec5SDimitry Andric DwarfCompileUnit::DwarfCompileUnit(unsigned UID, const DICompileUnit *Node, 740b57cec5SDimitry Andric AsmPrinter *A, DwarfDebug *DW, 75480093f4SDimitry Andric DwarfFile *DWU, UnitKind Kind) 765f757f3fSDimitry Andric : DwarfUnit(GetCompileUnitType(Kind, DW), Node, A, DW, DWU, UID) { 770b57cec5SDimitry Andric insertDIE(Node, &getUnitDie()); 780b57cec5SDimitry Andric MacroLabelBegin = Asm->createTempSymbol("cu_macro_begin"); 790b57cec5SDimitry Andric } 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric /// addLabelAddress - Add a dwarf label attribute data and value using 820b57cec5SDimitry Andric /// DW_FORM_addr or DW_FORM_GNU_addr_index. 830b57cec5SDimitry Andric void DwarfCompileUnit::addLabelAddress(DIE &Die, dwarf::Attribute Attribute, 840b57cec5SDimitry Andric const MCSymbol *Label) { 8581ad6265SDimitry Andric if ((Skeleton || !DD->useSplitDwarf()) && Label) 8681ad6265SDimitry Andric DD->addArangeLabel(SymbolCU(this, Label)); 8781ad6265SDimitry Andric 880b57cec5SDimitry Andric // Don't use the address pool in non-fission or in the skeleton unit itself. 890b57cec5SDimitry Andric if ((!DD->useSplitDwarf() || !Skeleton) && DD->getDwarfVersion() < 5) 900b57cec5SDimitry Andric return addLocalLabelAddress(Die, Attribute, Label); 910b57cec5SDimitry Andric 92fe6060f1SDimitry Andric bool UseAddrOffsetFormOrExpressions = 93fe6060f1SDimitry Andric DD->useAddrOffsetForm() || DD->useAddrOffsetExpressions(); 94fe6060f1SDimitry Andric 95fe6060f1SDimitry Andric const MCSymbol *Base = nullptr; 96fe6060f1SDimitry Andric if (Label->isInSection() && UseAddrOffsetFormOrExpressions) 97fe6060f1SDimitry Andric Base = DD->getSectionLabel(&Label->getSection()); 98fe6060f1SDimitry Andric 99fe6060f1SDimitry Andric if (!Base || Base == Label) { 1000b57cec5SDimitry Andric unsigned idx = DD->getAddressPool().getIndex(Label); 101fe6060f1SDimitry Andric addAttribute(Die, Attribute, 1020b57cec5SDimitry Andric DD->getDwarfVersion() >= 5 ? dwarf::DW_FORM_addrx 1030b57cec5SDimitry Andric : dwarf::DW_FORM_GNU_addr_index, 1040b57cec5SDimitry Andric DIEInteger(idx)); 105fe6060f1SDimitry Andric return; 106fe6060f1SDimitry Andric } 107fe6060f1SDimitry Andric 108fe6060f1SDimitry Andric // Could be extended to work with DWARFv4 Split DWARF if that's important for 109fe6060f1SDimitry Andric // someone. In that case DW_FORM_data would be used. 110fe6060f1SDimitry Andric assert(DD->getDwarfVersion() >= 5 && 111fe6060f1SDimitry Andric "Addr+offset expressions are only valuable when using debug_addr (to " 112fe6060f1SDimitry Andric "reduce relocations) available in DWARFv5 or higher"); 113fe6060f1SDimitry Andric if (DD->useAddrOffsetExpressions()) { 114fe6060f1SDimitry Andric auto *Loc = new (DIEValueAllocator) DIEBlock(); 115fe6060f1SDimitry Andric addPoolOpAddress(*Loc, Label); 116fe6060f1SDimitry Andric addBlock(Die, Attribute, dwarf::DW_FORM_exprloc, Loc); 117fe6060f1SDimitry Andric } else 118fe6060f1SDimitry Andric addAttribute(Die, Attribute, dwarf::DW_FORM_LLVM_addrx_offset, 119fe6060f1SDimitry Andric new (DIEValueAllocator) DIEAddrOffset( 120fe6060f1SDimitry Andric DD->getAddressPool().getIndex(Base), Label, Base)); 1210b57cec5SDimitry Andric } 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric void DwarfCompileUnit::addLocalLabelAddress(DIE &Die, 1240b57cec5SDimitry Andric dwarf::Attribute Attribute, 1250b57cec5SDimitry Andric const MCSymbol *Label) { 1260b57cec5SDimitry Andric if (Label) 127fe6060f1SDimitry Andric addAttribute(Die, Attribute, dwarf::DW_FORM_addr, DIELabel(Label)); 1280b57cec5SDimitry Andric else 129fe6060f1SDimitry Andric addAttribute(Die, Attribute, dwarf::DW_FORM_addr, DIEInteger(0)); 1300b57cec5SDimitry Andric } 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric unsigned DwarfCompileUnit::getOrCreateSourceID(const DIFile *File) { 1330b57cec5SDimitry Andric // If we print assembly, we can't separate .file entries according to 1340b57cec5SDimitry Andric // compile units. Thus all files will belong to the default compile unit. 1350b57cec5SDimitry Andric 1360b57cec5SDimitry Andric // FIXME: add a better feature test than hasRawTextSupport. Even better, 1370b57cec5SDimitry Andric // extend .file to support this. 1380b57cec5SDimitry Andric unsigned CUID = Asm->OutStreamer->hasRawTextSupport() ? 0 : getUniqueID(); 1390b57cec5SDimitry Andric if (!File) 140bdd1243dSDimitry Andric return Asm->OutStreamer->emitDwarfFileDirective(0, "", "", std::nullopt, 141bdd1243dSDimitry Andric std::nullopt, CUID); 14204eeddc0SDimitry Andric 14304eeddc0SDimitry Andric if (LastFile != File) { 14404eeddc0SDimitry Andric LastFile = File; 14504eeddc0SDimitry Andric LastFileID = Asm->OutStreamer->emitDwarfFileDirective( 146e8d8bef9SDimitry Andric 0, File->getDirectory(), File->getFilename(), DD->getMD5AsBytes(File), 1470b57cec5SDimitry Andric File->getSource(), CUID); 1480b57cec5SDimitry Andric } 14904eeddc0SDimitry Andric return LastFileID; 15004eeddc0SDimitry Andric } 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE( 1530b57cec5SDimitry Andric const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) { 1540b57cec5SDimitry Andric // Check for pre-existence. 1550b57cec5SDimitry Andric if (DIE *Die = getDIE(GV)) 1560b57cec5SDimitry Andric return Die; 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric assert(GV); 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric auto *GVContext = GV->getScope(); 1610b57cec5SDimitry Andric const DIType *GTy = GV->getType(); 1620b57cec5SDimitry Andric 1630b57cec5SDimitry Andric auto *CB = GVContext ? dyn_cast<DICommonBlock>(GVContext) : nullptr; 1640b57cec5SDimitry Andric DIE *ContextDIE = CB ? getOrCreateCommonBlock(CB, GlobalExprs) 1650b57cec5SDimitry Andric : getOrCreateContextDIE(GVContext); 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andric // Add to map. 1680b57cec5SDimitry Andric DIE *VariableDIE = &createAndAddDIE(GV->getTag(), *ContextDIE, GV); 1690b57cec5SDimitry Andric DIScope *DeclContext; 1700b57cec5SDimitry Andric if (auto *SDMDecl = GV->getStaticDataMemberDeclaration()) { 1710b57cec5SDimitry Andric DeclContext = SDMDecl->getScope(); 1720b57cec5SDimitry Andric assert(SDMDecl->isStaticMember() && "Expected static member decl"); 1730b57cec5SDimitry Andric assert(GV->isDefinition()); 1740b57cec5SDimitry Andric // We need the declaration DIE that is in the static member's class. 1750b57cec5SDimitry Andric DIE *VariableSpecDIE = getOrCreateStaticMemberDIE(SDMDecl); 1760b57cec5SDimitry Andric addDIEEntry(*VariableDIE, dwarf::DW_AT_specification, *VariableSpecDIE); 1770b57cec5SDimitry Andric // If the global variable's type is different from the one in the class 1780b57cec5SDimitry Andric // member type, assume that it's more specific and also emit it. 1790b57cec5SDimitry Andric if (GTy != SDMDecl->getBaseType()) 1800b57cec5SDimitry Andric addType(*VariableDIE, GTy); 1810b57cec5SDimitry Andric } else { 1820b57cec5SDimitry Andric DeclContext = GV->getScope(); 1830b57cec5SDimitry Andric // Add name and type. 18481ad6265SDimitry Andric StringRef DisplayName = GV->getDisplayName(); 18581ad6265SDimitry Andric if (!DisplayName.empty()) 1860b57cec5SDimitry Andric addString(*VariableDIE, dwarf::DW_AT_name, GV->getDisplayName()); 1875ffd83dbSDimitry Andric if (GTy) 1880b57cec5SDimitry Andric addType(*VariableDIE, GTy); 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric // Add scoping info. 1910b57cec5SDimitry Andric if (!GV->isLocalToUnit()) 1920b57cec5SDimitry Andric addFlag(*VariableDIE, dwarf::DW_AT_external); 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andric // Add line number info. 1950b57cec5SDimitry Andric addSourceLine(*VariableDIE, GV); 1960b57cec5SDimitry Andric } 1970b57cec5SDimitry Andric 1980b57cec5SDimitry Andric if (!GV->isDefinition()) 1990b57cec5SDimitry Andric addFlag(*VariableDIE, dwarf::DW_AT_declaration); 2000b57cec5SDimitry Andric else 2010b57cec5SDimitry Andric addGlobalName(GV->getName(), *VariableDIE, DeclContext); 2020b57cec5SDimitry Andric 203349cc55cSDimitry Andric addAnnotation(*VariableDIE, GV->getAnnotations()); 204349cc55cSDimitry Andric 2050b57cec5SDimitry Andric if (uint32_t AlignInBytes = GV->getAlignInBytes()) 2060b57cec5SDimitry Andric addUInt(*VariableDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata, 2070b57cec5SDimitry Andric AlignInBytes); 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric if (MDTuple *TP = GV->getTemplateParams()) 2100b57cec5SDimitry Andric addTemplateParams(*VariableDIE, DINodeArray(TP)); 2110b57cec5SDimitry Andric 2120b57cec5SDimitry Andric // Add location. 2130b57cec5SDimitry Andric addLocationAttribute(VariableDIE, GV, GlobalExprs); 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric return VariableDIE; 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric void DwarfCompileUnit::addLocationAttribute( 2190b57cec5SDimitry Andric DIE *VariableDIE, const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) { 2200b57cec5SDimitry Andric bool addToAccelTable = false; 2210b57cec5SDimitry Andric DIELoc *Loc = nullptr; 222bdd1243dSDimitry Andric std::optional<unsigned> NVPTXAddressSpace; 2230b57cec5SDimitry Andric std::unique_ptr<DIEDwarfExpression> DwarfExpr; 2240b57cec5SDimitry Andric for (const auto &GE : GlobalExprs) { 2250b57cec5SDimitry Andric const GlobalVariable *Global = GE.Var; 2260b57cec5SDimitry Andric const DIExpression *Expr = GE.Expr; 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric // For compatibility with DWARF 3 and earlier, 229fe6060f1SDimitry Andric // DW_AT_location(DW_OP_constu, X, DW_OP_stack_value) or 230fe6060f1SDimitry Andric // DW_AT_location(DW_OP_consts, X, DW_OP_stack_value) becomes 2310b57cec5SDimitry Andric // DW_AT_const_value(X). 2320b57cec5SDimitry Andric if (GlobalExprs.size() == 1 && Expr && Expr->isConstant()) { 2330b57cec5SDimitry Andric addToAccelTable = true; 234fe6060f1SDimitry Andric addConstantValue( 235fe6060f1SDimitry Andric *VariableDIE, 236fe6060f1SDimitry Andric DIExpression::SignedOrUnsignedConstant::UnsignedConstant == 237fe6060f1SDimitry Andric *Expr->isConstant(), 238fe6060f1SDimitry Andric Expr->getElement(1)); 2390b57cec5SDimitry Andric break; 2400b57cec5SDimitry Andric } 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric // We cannot describe the location of dllimport'd variables: the 2430b57cec5SDimitry Andric // computation of their address requires loads from the IAT. 2440b57cec5SDimitry Andric if (Global && Global->hasDLLImportStorageClass()) 2450b57cec5SDimitry Andric continue; 2460b57cec5SDimitry Andric 2470b57cec5SDimitry Andric // Nothing to describe without address or constant. 2480b57cec5SDimitry Andric if (!Global && (!Expr || !Expr->isConstant())) 2490b57cec5SDimitry Andric continue; 2500b57cec5SDimitry Andric 2510b57cec5SDimitry Andric if (Global && Global->isThreadLocal() && 2520b57cec5SDimitry Andric !Asm->getObjFileLowering().supportDebugThreadLocalLocation()) 2530b57cec5SDimitry Andric continue; 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric if (!Loc) { 2560b57cec5SDimitry Andric addToAccelTable = true; 2570b57cec5SDimitry Andric Loc = new (DIEValueAllocator) DIELoc; 2588bcb0991SDimitry Andric DwarfExpr = std::make_unique<DIEDwarfExpression>(*Asm, *this, *Loc); 2590b57cec5SDimitry Andric } 2600b57cec5SDimitry Andric 2610b57cec5SDimitry Andric if (Expr) { 2620b57cec5SDimitry Andric // According to 2630b57cec5SDimitry Andric // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf 2640b57cec5SDimitry Andric // cuda-gdb requires DW_AT_address_class for all variables to be able to 2650b57cec5SDimitry Andric // correctly interpret address space of the variable address. 2660b57cec5SDimitry Andric // Decode DW_OP_constu <DWARF Address Space> DW_OP_swap DW_OP_xderef 2670b57cec5SDimitry Andric // sequence for the NVPTX + gdb target. 2680b57cec5SDimitry Andric unsigned LocalNVPTXAddressSpace; 2690b57cec5SDimitry Andric if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) { 2700b57cec5SDimitry Andric const DIExpression *NewExpr = 2710b57cec5SDimitry Andric DIExpression::extractAddressClass(Expr, LocalNVPTXAddressSpace); 2720b57cec5SDimitry Andric if (NewExpr != Expr) { 2730b57cec5SDimitry Andric Expr = NewExpr; 2740b57cec5SDimitry Andric NVPTXAddressSpace = LocalNVPTXAddressSpace; 2750b57cec5SDimitry Andric } 2760b57cec5SDimitry Andric } 2770b57cec5SDimitry Andric DwarfExpr->addFragmentOffset(Expr); 2780b57cec5SDimitry Andric } 2790b57cec5SDimitry Andric 2800b57cec5SDimitry Andric if (Global) { 2810b57cec5SDimitry Andric const MCSymbol *Sym = Asm->getSymbol(Global); 28204eeddc0SDimitry Andric // 16-bit platforms like MSP430 and AVR take this path, so sink this 28304eeddc0SDimitry Andric // assert to platforms that use it. 28404eeddc0SDimitry Andric auto GetPointerSizedFormAndOp = [this]() { 28506c3fb27SDimitry Andric unsigned PointerSize = Asm->MAI->getCodePointerSize(); 286349cc55cSDimitry Andric assert((PointerSize == 4 || PointerSize == 8) && 287349cc55cSDimitry Andric "Add support for other sizes if necessary"); 28804eeddc0SDimitry Andric struct FormAndOp { 28904eeddc0SDimitry Andric dwarf::Form Form; 29004eeddc0SDimitry Andric dwarf::LocationAtom Op; 29104eeddc0SDimitry Andric }; 29204eeddc0SDimitry Andric return PointerSize == 4 29304eeddc0SDimitry Andric ? FormAndOp{dwarf::DW_FORM_data4, dwarf::DW_OP_const4u} 29404eeddc0SDimitry Andric : FormAndOp{dwarf::DW_FORM_data8, dwarf::DW_OP_const8u}; 29504eeddc0SDimitry Andric }; 2960b57cec5SDimitry Andric if (Global->isThreadLocal()) { 29706c3fb27SDimitry Andric if (Asm->TM.getTargetTriple().isWasm()) { 29806c3fb27SDimitry Andric // FIXME This is not guaranteed, but in practice, in static linking, 29906c3fb27SDimitry Andric // if present, __tls_base's index is 1. This doesn't hold for dynamic 30006c3fb27SDimitry Andric // linking, so TLS variables used in dynamic linking won't have 30106c3fb27SDimitry Andric // correct debug info for now. See 30206c3fb27SDimitry Andric // https://github.com/llvm/llvm-project/blob/19afbfe33156d211fa959dadeea46cd17b9c723c/lld/wasm/Driver.cpp#L786-L823 30306c3fb27SDimitry Andric addWasmRelocBaseGlobal(Loc, "__tls_base", 1); 30406c3fb27SDimitry Andric addOpAddress(*Loc, Sym); 30506c3fb27SDimitry Andric addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus); 30606c3fb27SDimitry Andric } else if (Asm->TM.useEmulatedTLS()) { 3070b57cec5SDimitry Andric // TODO: add debug info for emulated thread local mode. 3080b57cec5SDimitry Andric } else { 3090b57cec5SDimitry Andric // FIXME: Make this work with -gsplit-dwarf. 3100b57cec5SDimitry Andric // Based on GCC's support for TLS: 3110b57cec5SDimitry Andric if (!DD->useSplitDwarf()) { 31204eeddc0SDimitry Andric auto FormAndOp = GetPointerSizedFormAndOp(); 3130b57cec5SDimitry Andric // 1) Start with a constNu of the appropriate pointer size 31404eeddc0SDimitry Andric addUInt(*Loc, dwarf::DW_FORM_data1, FormAndOp.Op); 3150b57cec5SDimitry Andric // 2) containing the (relocated) offset of the TLS variable 3160b57cec5SDimitry Andric // within the module's TLS block. 31704eeddc0SDimitry Andric addExpr(*Loc, FormAndOp.Form, 3180b57cec5SDimitry Andric Asm->getObjFileLowering().getDebugThreadLocalSymbol(Sym)); 3190b57cec5SDimitry Andric } else { 3200b57cec5SDimitry Andric addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index); 3210b57cec5SDimitry Andric addUInt(*Loc, dwarf::DW_FORM_udata, 3220b57cec5SDimitry Andric DD->getAddressPool().getIndex(Sym, /* TLS */ true)); 3230b57cec5SDimitry Andric } 3240b57cec5SDimitry Andric // 3) followed by an OP to make the debugger do a TLS lookup. 3250b57cec5SDimitry Andric addUInt(*Loc, dwarf::DW_FORM_data1, 3260b57cec5SDimitry Andric DD->useGNUTLSOpcode() ? dwarf::DW_OP_GNU_push_tls_address 3270b57cec5SDimitry Andric : dwarf::DW_OP_form_tls_address); 3280b57cec5SDimitry Andric } 32906c3fb27SDimitry Andric } else if (Asm->TM.getTargetTriple().isWasm() && 33006c3fb27SDimitry Andric Asm->TM.getRelocationModel() == Reloc::PIC_) { 33106c3fb27SDimitry Andric // FIXME This is not guaranteed, but in practice, if present, 33206c3fb27SDimitry Andric // __memory_base's index is 1. See 33306c3fb27SDimitry Andric // https://github.com/llvm/llvm-project/blob/19afbfe33156d211fa959dadeea46cd17b9c723c/lld/wasm/Driver.cpp#L786-L823 33406c3fb27SDimitry Andric addWasmRelocBaseGlobal(Loc, "__memory_base", 1); 33506c3fb27SDimitry Andric addOpAddress(*Loc, Sym); 33606c3fb27SDimitry Andric addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus); 33781ad6265SDimitry Andric } else if ((Asm->TM.getRelocationModel() == Reloc::RWPI || 33881ad6265SDimitry Andric Asm->TM.getRelocationModel() == Reloc::ROPI_RWPI) && 33981ad6265SDimitry Andric !Asm->getObjFileLowering() 34081ad6265SDimitry Andric .getKindForGlobal(Global, Asm->TM) 34181ad6265SDimitry Andric .isReadOnly()) { 34204eeddc0SDimitry Andric auto FormAndOp = GetPointerSizedFormAndOp(); 343349cc55cSDimitry Andric // Constant 34404eeddc0SDimitry Andric addUInt(*Loc, dwarf::DW_FORM_data1, FormAndOp.Op); 345349cc55cSDimitry Andric // Relocation offset 34604eeddc0SDimitry Andric addExpr(*Loc, FormAndOp.Form, 347349cc55cSDimitry Andric Asm->getObjFileLowering().getIndirectSymViaRWPI(Sym)); 348349cc55cSDimitry Andric // Base register 349349cc55cSDimitry Andric Register BaseReg = Asm->getObjFileLowering().getStaticBase(); 350349cc55cSDimitry Andric BaseReg = Asm->TM.getMCRegisterInfo()->getDwarfRegNum(BaseReg, false); 351349cc55cSDimitry Andric addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + BaseReg); 352349cc55cSDimitry Andric // Offset from base register 353349cc55cSDimitry Andric addSInt(*Loc, dwarf::DW_FORM_sdata, 0); 354349cc55cSDimitry Andric // Operation 355349cc55cSDimitry Andric addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus); 3560b57cec5SDimitry Andric } else { 3570b57cec5SDimitry Andric DD->addArangeLabel(SymbolCU(this, Sym)); 3580b57cec5SDimitry Andric addOpAddress(*Loc, Sym); 3590b57cec5SDimitry Andric } 3600b57cec5SDimitry Andric } 3610b57cec5SDimitry Andric // Global variables attached to symbols are memory locations. 3620b57cec5SDimitry Andric // It would be better if this were unconditional, but malformed input that 3630b57cec5SDimitry Andric // mixes non-fragments and fragments for the same variable is too expensive 3640b57cec5SDimitry Andric // to detect in the verifier. 3650b57cec5SDimitry Andric if (DwarfExpr->isUnknownLocation()) 3660b57cec5SDimitry Andric DwarfExpr->setMemoryLocationKind(); 3670b57cec5SDimitry Andric DwarfExpr->addExpression(Expr); 3680b57cec5SDimitry Andric } 3690b57cec5SDimitry Andric if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) { 3700b57cec5SDimitry Andric // According to 3710b57cec5SDimitry Andric // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf 3720b57cec5SDimitry Andric // cuda-gdb requires DW_AT_address_class for all variables to be able to 3730b57cec5SDimitry Andric // correctly interpret address space of the variable address. 3740b57cec5SDimitry Andric const unsigned NVPTX_ADDR_global_space = 5; 3750b57cec5SDimitry Andric addUInt(*VariableDIE, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1, 376bdd1243dSDimitry Andric NVPTXAddressSpace.value_or(NVPTX_ADDR_global_space)); 3770b57cec5SDimitry Andric } 3780b57cec5SDimitry Andric if (Loc) 3790b57cec5SDimitry Andric addBlock(*VariableDIE, dwarf::DW_AT_location, DwarfExpr->finalize()); 3800b57cec5SDimitry Andric 3810b57cec5SDimitry Andric if (DD->useAllLinkageNames()) 3820b57cec5SDimitry Andric addLinkageName(*VariableDIE, GV->getLinkageName()); 3830b57cec5SDimitry Andric 3840b57cec5SDimitry Andric if (addToAccelTable) { 3855f757f3fSDimitry Andric DD->addAccelName(*this, CUNode->getNameTableKind(), GV->getName(), 3865f757f3fSDimitry Andric *VariableDIE); 3870b57cec5SDimitry Andric 3880b57cec5SDimitry Andric // If the linkage name is different than the name, go ahead and output 3890b57cec5SDimitry Andric // that as well into the name table. 3900b57cec5SDimitry Andric if (GV->getLinkageName() != "" && GV->getName() != GV->getLinkageName() && 3910b57cec5SDimitry Andric DD->useAllLinkageNames()) 3925f757f3fSDimitry Andric DD->addAccelName(*this, CUNode->getNameTableKind(), GV->getLinkageName(), 3935f757f3fSDimitry Andric *VariableDIE); 3940b57cec5SDimitry Andric } 3950b57cec5SDimitry Andric } 3960b57cec5SDimitry Andric 3970b57cec5SDimitry Andric DIE *DwarfCompileUnit::getOrCreateCommonBlock( 3980b57cec5SDimitry Andric const DICommonBlock *CB, ArrayRef<GlobalExpr> GlobalExprs) { 399349cc55cSDimitry Andric // Check for pre-existence. 4000b57cec5SDimitry Andric if (DIE *NDie = getDIE(CB)) 4010b57cec5SDimitry Andric return NDie; 402349cc55cSDimitry Andric DIE *ContextDIE = getOrCreateContextDIE(CB->getScope()); 4030b57cec5SDimitry Andric DIE &NDie = createAndAddDIE(dwarf::DW_TAG_common_block, *ContextDIE, CB); 4040b57cec5SDimitry Andric StringRef Name = CB->getName().empty() ? "_BLNK_" : CB->getName(); 4050b57cec5SDimitry Andric addString(NDie, dwarf::DW_AT_name, Name); 4060b57cec5SDimitry Andric addGlobalName(Name, NDie, CB->getScope()); 4070b57cec5SDimitry Andric if (CB->getFile()) 4080b57cec5SDimitry Andric addSourceLine(NDie, CB->getLineNo(), CB->getFile()); 4090b57cec5SDimitry Andric if (DIGlobalVariable *V = CB->getDecl()) 4100b57cec5SDimitry Andric getCU().addLocationAttribute(&NDie, V, GlobalExprs); 4110b57cec5SDimitry Andric return &NDie; 4120b57cec5SDimitry Andric } 4130b57cec5SDimitry Andric 4140b57cec5SDimitry Andric void DwarfCompileUnit::addRange(RangeSpan Range) { 4155ffd83dbSDimitry Andric DD->insertSectionLabel(Range.Begin); 4165ffd83dbSDimitry Andric 417349cc55cSDimitry Andric auto *PrevCU = DD->getPrevCU(); 418349cc55cSDimitry Andric bool SameAsPrevCU = this == PrevCU; 4190b57cec5SDimitry Andric DD->setPrevCU(this); 4200b57cec5SDimitry Andric // If we have no current ranges just add the range and return, otherwise, 4210b57cec5SDimitry Andric // check the current section and CU against the previous section and CU we 4220b57cec5SDimitry Andric // emitted into and the subprogram was contained within. If these are the 4230b57cec5SDimitry Andric // same then extend our current range, otherwise add this as a new range. 4240b57cec5SDimitry Andric if (CURanges.empty() || !SameAsPrevCU || 4258bcb0991SDimitry Andric (&CURanges.back().End->getSection() != 4268bcb0991SDimitry Andric &Range.End->getSection())) { 427349cc55cSDimitry Andric // Before a new range is added, always terminate the prior line table. 428349cc55cSDimitry Andric if (PrevCU) 429349cc55cSDimitry Andric DD->terminateLineTable(PrevCU); 4300b57cec5SDimitry Andric CURanges.push_back(Range); 4310b57cec5SDimitry Andric return; 4320b57cec5SDimitry Andric } 4330b57cec5SDimitry Andric 4348bcb0991SDimitry Andric CURanges.back().End = Range.End; 4350b57cec5SDimitry Andric } 4360b57cec5SDimitry Andric 4370b57cec5SDimitry Andric void DwarfCompileUnit::initStmtList() { 4380b57cec5SDimitry Andric if (CUNode->isDebugDirectivesOnly()) 4390b57cec5SDimitry Andric return; 4400b57cec5SDimitry Andric 4410b57cec5SDimitry Andric const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); 4420b57cec5SDimitry Andric if (DD->useSectionsAsReferences()) { 4430b57cec5SDimitry Andric LineTableStartSym = TLOF.getDwarfLineSection()->getBeginSymbol(); 4440b57cec5SDimitry Andric } else { 4450b57cec5SDimitry Andric LineTableStartSym = 4460b57cec5SDimitry Andric Asm->OutStreamer->getDwarfLineTableSymbol(getUniqueID()); 4470b57cec5SDimitry Andric } 4480b57cec5SDimitry Andric 4490b57cec5SDimitry Andric // DW_AT_stmt_list is a offset of line number information for this 4500b57cec5SDimitry Andric // compile unit in debug_line section. For split dwarf this is 4510b57cec5SDimitry Andric // left in the skeleton CU and so not included. 4520b57cec5SDimitry Andric // The line table entries are not always emitted in assembly, so it 4530b57cec5SDimitry Andric // is not okay to use line_table_start here. 4540b57cec5SDimitry Andric addSectionLabel(getUnitDie(), dwarf::DW_AT_stmt_list, LineTableStartSym, 4550b57cec5SDimitry Andric TLOF.getDwarfLineSection()->getBeginSymbol()); 4560b57cec5SDimitry Andric } 4570b57cec5SDimitry Andric 4580b57cec5SDimitry Andric void DwarfCompileUnit::applyStmtList(DIE &D) { 4595ffd83dbSDimitry Andric const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); 4605ffd83dbSDimitry Andric addSectionLabel(D, dwarf::DW_AT_stmt_list, LineTableStartSym, 4615ffd83dbSDimitry Andric TLOF.getDwarfLineSection()->getBeginSymbol()); 4620b57cec5SDimitry Andric } 4630b57cec5SDimitry Andric 4640b57cec5SDimitry Andric void DwarfCompileUnit::attachLowHighPC(DIE &D, const MCSymbol *Begin, 4650b57cec5SDimitry Andric const MCSymbol *End) { 4660b57cec5SDimitry Andric assert(Begin && "Begin label should not be null!"); 4670b57cec5SDimitry Andric assert(End && "End label should not be null!"); 4680b57cec5SDimitry Andric assert(Begin->isDefined() && "Invalid starting label"); 4690b57cec5SDimitry Andric assert(End->isDefined() && "Invalid end label"); 4700b57cec5SDimitry Andric 4710b57cec5SDimitry Andric addLabelAddress(D, dwarf::DW_AT_low_pc, Begin); 4720b57cec5SDimitry Andric if (DD->getDwarfVersion() < 4) 4730b57cec5SDimitry Andric addLabelAddress(D, dwarf::DW_AT_high_pc, End); 4740b57cec5SDimitry Andric else 4750b57cec5SDimitry Andric addLabelDelta(D, dwarf::DW_AT_high_pc, End, Begin); 4760b57cec5SDimitry Andric } 4770b57cec5SDimitry Andric 47806c3fb27SDimitry Andric // Add info for Wasm-global-based relocation. 47906c3fb27SDimitry Andric // 'GlobalIndex' is used for split dwarf, which currently relies on a few 48006c3fb27SDimitry Andric // assumptions that are not guaranteed in a formal way but work in practice. 48106c3fb27SDimitry Andric void DwarfCompileUnit::addWasmRelocBaseGlobal(DIELoc *Loc, StringRef GlobalName, 48206c3fb27SDimitry Andric uint64_t GlobalIndex) { 48306c3fb27SDimitry Andric // FIXME: duplicated from Target/WebAssembly/WebAssembly.h 48406c3fb27SDimitry Andric // don't want to depend on target specific headers in this code? 48506c3fb27SDimitry Andric const unsigned TI_GLOBAL_RELOC = 3; 48606c3fb27SDimitry Andric unsigned PointerSize = Asm->getDataLayout().getPointerSize(); 48706c3fb27SDimitry Andric auto *Sym = cast<MCSymbolWasm>(Asm->GetExternalSymbolSymbol(GlobalName)); 48806c3fb27SDimitry Andric // FIXME: this repeats what WebAssemblyMCInstLower:: 48906c3fb27SDimitry Andric // GetExternalSymbolSymbol does, since if there's no code that 49006c3fb27SDimitry Andric // refers to this symbol, we have to set it here. 49106c3fb27SDimitry Andric Sym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL); 49206c3fb27SDimitry Andric Sym->setGlobalType(wasm::WasmGlobalType{ 49306c3fb27SDimitry Andric static_cast<uint8_t>(PointerSize == 4 ? wasm::WASM_TYPE_I32 49406c3fb27SDimitry Andric : wasm::WASM_TYPE_I64), 49506c3fb27SDimitry Andric true}); 49606c3fb27SDimitry Andric addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_WASM_location); 49706c3fb27SDimitry Andric addSInt(*Loc, dwarf::DW_FORM_sdata, TI_GLOBAL_RELOC); 49806c3fb27SDimitry Andric if (!isDwoUnit()) { 49906c3fb27SDimitry Andric addLabel(*Loc, dwarf::DW_FORM_data4, Sym); 50006c3fb27SDimitry Andric } else { 50106c3fb27SDimitry Andric // FIXME: when writing dwo, we need to avoid relocations. Probably 50206c3fb27SDimitry Andric // the "right" solution is to treat globals the way func and data 50306c3fb27SDimitry Andric // symbols are (with entries in .debug_addr). 50406c3fb27SDimitry Andric // For now we hardcode the indices in the callsites. Global indices are not 50506c3fb27SDimitry Andric // fixed, but in practice a few are fixed; for example, __stack_pointer is 50606c3fb27SDimitry Andric // always index 0. 50706c3fb27SDimitry Andric addUInt(*Loc, dwarf::DW_FORM_data4, GlobalIndex); 50806c3fb27SDimitry Andric } 50906c3fb27SDimitry Andric } 51006c3fb27SDimitry Andric 5115f757f3fSDimitry Andric // Find DIE for the given subprogram and attach appropriate DW_AT_low_pc 5125f757f3fSDimitry Andric // and DW_AT_high_pc attributes. If there are global variables in this 5135f757f3fSDimitry Andric // scope then create and insert DIEs for these variables. 5145f757f3fSDimitry Andric DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP) { 5155f757f3fSDimitry Andric DIE *SPDie = getOrCreateSubprogramDIE(SP, includeMinimalInlineScopes()); 5165ffd83dbSDimitry Andric SmallVector<RangeSpan, 2> BB_List; 5175ffd83dbSDimitry Andric // If basic block sections are on, ranges for each basic block section has 5185ffd83dbSDimitry Andric // to be emitted separately. 5195ffd83dbSDimitry Andric for (const auto &R : Asm->MBBSectionRanges) 5205ffd83dbSDimitry Andric BB_List.push_back({R.second.BeginLabel, R.second.EndLabel}); 5215ffd83dbSDimitry Andric 5225ffd83dbSDimitry Andric attachRangesOrLowHighPC(*SPDie, BB_List); 5235ffd83dbSDimitry Andric 5240b57cec5SDimitry Andric if (DD->useAppleExtensionAttributes() && 5250b57cec5SDimitry Andric !DD->getCurrentFunction()->getTarget().Options.DisableFramePointerElim( 5260b57cec5SDimitry Andric *DD->getCurrentFunction())) 5270b57cec5SDimitry Andric addFlag(*SPDie, dwarf::DW_AT_APPLE_omit_frame_ptr); 5280b57cec5SDimitry Andric 5290b57cec5SDimitry Andric // Only include DW_AT_frame_base in full debug info 5300b57cec5SDimitry Andric if (!includeMinimalInlineScopes()) { 5315ffd83dbSDimitry Andric const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering(); 5325ffd83dbSDimitry Andric TargetFrameLowering::DwarfFrameBase FrameBase = 5335ffd83dbSDimitry Andric TFI->getDwarfFrameBase(*Asm->MF); 5345ffd83dbSDimitry Andric switch (FrameBase.Kind) { 5355ffd83dbSDimitry Andric case TargetFrameLowering::DwarfFrameBase::Register: { 5365ffd83dbSDimitry Andric if (Register::isPhysicalRegister(FrameBase.Location.Reg)) { 5375ffd83dbSDimitry Andric MachineLocation Location(FrameBase.Location.Reg); 5385ffd83dbSDimitry Andric addAddress(*SPDie, dwarf::DW_AT_frame_base, Location); 5395ffd83dbSDimitry Andric } 5405ffd83dbSDimitry Andric break; 5415ffd83dbSDimitry Andric } 5425ffd83dbSDimitry Andric case TargetFrameLowering::DwarfFrameBase::CFA: { 5430b57cec5SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 5440b57cec5SDimitry Andric addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_call_frame_cfa); 54506c3fb27SDimitry Andric if (FrameBase.Location.Offset != 0) { 54606c3fb27SDimitry Andric addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_consts); 54706c3fb27SDimitry Andric addSInt(*Loc, dwarf::DW_FORM_sdata, FrameBase.Location.Offset); 54806c3fb27SDimitry Andric addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus); 54906c3fb27SDimitry Andric } 5500b57cec5SDimitry Andric addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc); 5515ffd83dbSDimitry Andric break; 5525ffd83dbSDimitry Andric } 5535ffd83dbSDimitry Andric case TargetFrameLowering::DwarfFrameBase::WasmFrameBase: { 5545ffd83dbSDimitry Andric // FIXME: duplicated from Target/WebAssembly/WebAssembly.h 5555ffd83dbSDimitry Andric const unsigned TI_GLOBAL_RELOC = 3; 556fe6060f1SDimitry Andric if (FrameBase.Location.WasmLoc.Kind == TI_GLOBAL_RELOC) { 5575ffd83dbSDimitry Andric // These need to be relocatable. 5585ffd83dbSDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 55906c3fb27SDimitry Andric assert(FrameBase.Location.WasmLoc.Index == 0); // Only SP so far. 560fe6060f1SDimitry Andric // For now, since we only ever use index 0, this should work as-is. 56106c3fb27SDimitry Andric addWasmRelocBaseGlobal(Loc, "__stack_pointer", 56206c3fb27SDimitry Andric FrameBase.Location.WasmLoc.Index); 5635ffd83dbSDimitry Andric addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value); 5645ffd83dbSDimitry Andric addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc); 5650b57cec5SDimitry Andric } else { 5665ffd83dbSDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 5675ffd83dbSDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); 5685ffd83dbSDimitry Andric DIExpressionCursor Cursor({}); 5695ffd83dbSDimitry Andric DwarfExpr.addWasmLocation(FrameBase.Location.WasmLoc.Kind, 5705ffd83dbSDimitry Andric FrameBase.Location.WasmLoc.Index); 5715ffd83dbSDimitry Andric DwarfExpr.addExpression(std::move(Cursor)); 5725ffd83dbSDimitry Andric addBlock(*SPDie, dwarf::DW_AT_frame_base, DwarfExpr.finalize()); 5735ffd83dbSDimitry Andric } 5745ffd83dbSDimitry Andric break; 5755ffd83dbSDimitry Andric } 5760b57cec5SDimitry Andric } 5770b57cec5SDimitry Andric } 5780b57cec5SDimitry Andric 5790b57cec5SDimitry Andric // Add name to the name table, we do this here because we're guaranteed 5800b57cec5SDimitry Andric // to have concrete versions of our DW_TAG_subprogram nodes. 5815f757f3fSDimitry Andric DD->addSubprogramNames(*this, CUNode->getNameTableKind(), SP, *SPDie); 5820b57cec5SDimitry Andric 5830b57cec5SDimitry Andric return *SPDie; 5840b57cec5SDimitry Andric } 5850b57cec5SDimitry Andric 5860b57cec5SDimitry Andric // Construct a DIE for this scope. 5874824e7fdSDimitry Andric void DwarfCompileUnit::constructScopeDIE(LexicalScope *Scope, 5884824e7fdSDimitry Andric DIE &ParentScopeDIE) { 5890b57cec5SDimitry Andric if (!Scope || !Scope->getScopeNode()) 5900b57cec5SDimitry Andric return; 5910b57cec5SDimitry Andric 5920b57cec5SDimitry Andric auto *DS = Scope->getScopeNode(); 5930b57cec5SDimitry Andric 5940b57cec5SDimitry Andric assert((Scope->getInlinedAt() || !isa<DISubprogram>(DS)) && 5950b57cec5SDimitry Andric "Only handle inlined subprograms here, use " 5960b57cec5SDimitry Andric "constructSubprogramScopeDIE for non-inlined " 5970b57cec5SDimitry Andric "subprograms"); 5980b57cec5SDimitry Andric 5994824e7fdSDimitry Andric // Emit inlined subprograms. 6000b57cec5SDimitry Andric if (Scope->getParent() && isa<DISubprogram>(DS)) { 601bdd1243dSDimitry Andric DIE *ScopeDIE = constructInlinedScopeDIE(Scope, ParentScopeDIE); 602bdd1243dSDimitry Andric assert(ScopeDIE && "Scope DIE should not be null."); 6034824e7fdSDimitry Andric createAndAddScopeChildren(Scope, *ScopeDIE); 6044824e7fdSDimitry Andric return; 6054824e7fdSDimitry Andric } 6064824e7fdSDimitry Andric 6070b57cec5SDimitry Andric // Early exit when we know the scope DIE is going to be null. 6080b57cec5SDimitry Andric if (DD->isLexicalScopeDIENull(Scope)) 6090b57cec5SDimitry Andric return; 6100b57cec5SDimitry Andric 6114824e7fdSDimitry Andric // Emit lexical blocks. 6124824e7fdSDimitry Andric DIE *ScopeDIE = constructLexicalScopeDIE(Scope); 6130b57cec5SDimitry Andric assert(ScopeDIE && "Scope DIE should not be null."); 6140b57cec5SDimitry Andric 6154824e7fdSDimitry Andric ParentScopeDIE.addChild(ScopeDIE); 6164824e7fdSDimitry Andric createAndAddScopeChildren(Scope, *ScopeDIE); 6170b57cec5SDimitry Andric } 6180b57cec5SDimitry Andric 6190b57cec5SDimitry Andric void DwarfCompileUnit::addScopeRangeList(DIE &ScopeDIE, 6200b57cec5SDimitry Andric SmallVector<RangeSpan, 2> Range) { 6210b57cec5SDimitry Andric 6220b57cec5SDimitry Andric HasRangeLists = true; 6230b57cec5SDimitry Andric 6240b57cec5SDimitry Andric // Add the range list to the set of ranges to be emitted. 6250b57cec5SDimitry Andric auto IndexAndList = 6260b57cec5SDimitry Andric (DD->getDwarfVersion() < 5 && Skeleton ? Skeleton->DU : DU) 6270b57cec5SDimitry Andric ->addRange(*(Skeleton ? Skeleton : this), std::move(Range)); 6280b57cec5SDimitry Andric 6290b57cec5SDimitry Andric uint32_t Index = IndexAndList.first; 6300b57cec5SDimitry Andric auto &List = *IndexAndList.second; 6310b57cec5SDimitry Andric 6320b57cec5SDimitry Andric // Under fission, ranges are specified by constant offsets relative to the 6330b57cec5SDimitry Andric // CU's DW_AT_GNU_ranges_base. 6340b57cec5SDimitry Andric // FIXME: For DWARF v5, do not generate the DW_AT_ranges attribute under 6350b57cec5SDimitry Andric // fission until we support the forms using the .debug_addr section 6360b57cec5SDimitry Andric // (DW_RLE_startx_endx etc.). 6370b57cec5SDimitry Andric if (DD->getDwarfVersion() >= 5) 6380b57cec5SDimitry Andric addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_rnglistx, Index); 6398bcb0991SDimitry Andric else { 6408bcb0991SDimitry Andric const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); 6418bcb0991SDimitry Andric const MCSymbol *RangeSectionSym = 6428bcb0991SDimitry Andric TLOF.getDwarfRangesSection()->getBeginSymbol(); 6438bcb0991SDimitry Andric if (isDwoUnit()) 644480093f4SDimitry Andric addSectionDelta(ScopeDIE, dwarf::DW_AT_ranges, List.Label, 6450b57cec5SDimitry Andric RangeSectionSym); 6460b57cec5SDimitry Andric else 647480093f4SDimitry Andric addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges, List.Label, 6480b57cec5SDimitry Andric RangeSectionSym); 6490b57cec5SDimitry Andric } 6508bcb0991SDimitry Andric } 6510b57cec5SDimitry Andric 6520b57cec5SDimitry Andric void DwarfCompileUnit::attachRangesOrLowHighPC( 6530b57cec5SDimitry Andric DIE &Die, SmallVector<RangeSpan, 2> Ranges) { 654e8d8bef9SDimitry Andric assert(!Ranges.empty()); 655e8d8bef9SDimitry Andric if (!DD->useRangesSection() || 656e8d8bef9SDimitry Andric (Ranges.size() == 1 && 65706c3fb27SDimitry Andric (!DD->alwaysUseRanges(*this) || 658e8d8bef9SDimitry Andric DD->getSectionLabel(&Ranges.front().Begin->getSection()) == 659e8d8bef9SDimitry Andric Ranges.front().Begin))) { 6600b57cec5SDimitry Andric const RangeSpan &Front = Ranges.front(); 6610b57cec5SDimitry Andric const RangeSpan &Back = Ranges.back(); 6628bcb0991SDimitry Andric attachLowHighPC(Die, Front.Begin, Back.End); 6630b57cec5SDimitry Andric } else 6640b57cec5SDimitry Andric addScopeRangeList(Die, std::move(Ranges)); 6650b57cec5SDimitry Andric } 6660b57cec5SDimitry Andric 6670b57cec5SDimitry Andric void DwarfCompileUnit::attachRangesOrLowHighPC( 6680b57cec5SDimitry Andric DIE &Die, const SmallVectorImpl<InsnRange> &Ranges) { 6690b57cec5SDimitry Andric SmallVector<RangeSpan, 2> List; 6700b57cec5SDimitry Andric List.reserve(Ranges.size()); 6715ffd83dbSDimitry Andric for (const InsnRange &R : Ranges) { 6725ffd83dbSDimitry Andric auto *BeginLabel = DD->getLabelBeforeInsn(R.first); 6735ffd83dbSDimitry Andric auto *EndLabel = DD->getLabelAfterInsn(R.second); 6745ffd83dbSDimitry Andric 6755ffd83dbSDimitry Andric const auto *BeginMBB = R.first->getParent(); 6765ffd83dbSDimitry Andric const auto *EndMBB = R.second->getParent(); 6775ffd83dbSDimitry Andric 6785ffd83dbSDimitry Andric const auto *MBB = BeginMBB; 6795ffd83dbSDimitry Andric // Basic block sections allows basic block subsets to be placed in unique 6805ffd83dbSDimitry Andric // sections. For each section, the begin and end label must be added to the 6815ffd83dbSDimitry Andric // list. If there is more than one range, debug ranges must be used. 6825ffd83dbSDimitry Andric // Otherwise, low/high PC can be used. 6835ffd83dbSDimitry Andric // FIXME: Debug Info Emission depends on block order and this assumes that 6845ffd83dbSDimitry Andric // the order of blocks will be frozen beyond this point. 6855ffd83dbSDimitry Andric do { 6865ffd83dbSDimitry Andric if (MBB->sameSection(EndMBB) || MBB->isEndSection()) { 687*0fca6ea1SDimitry Andric auto MBBSectionRange = Asm->MBBSectionRanges[MBB->getSectionID()]; 6888bcb0991SDimitry Andric List.push_back( 6895ffd83dbSDimitry Andric {MBB->sameSection(BeginMBB) ? BeginLabel 6905ffd83dbSDimitry Andric : MBBSectionRange.BeginLabel, 6915ffd83dbSDimitry Andric MBB->sameSection(EndMBB) ? EndLabel : MBBSectionRange.EndLabel}); 6925ffd83dbSDimitry Andric } 6935ffd83dbSDimitry Andric if (MBB->sameSection(EndMBB)) 6945ffd83dbSDimitry Andric break; 6955ffd83dbSDimitry Andric MBB = MBB->getNextNode(); 6965ffd83dbSDimitry Andric } while (true); 6975ffd83dbSDimitry Andric } 6980b57cec5SDimitry Andric attachRangesOrLowHighPC(Die, std::move(List)); 6990b57cec5SDimitry Andric } 7000b57cec5SDimitry Andric 701bdd1243dSDimitry Andric DIE *DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope, 702bdd1243dSDimitry Andric DIE &ParentScopeDIE) { 7030b57cec5SDimitry Andric assert(Scope->getScopeNode()); 7040b57cec5SDimitry Andric auto *DS = Scope->getScopeNode(); 7050b57cec5SDimitry Andric auto *InlinedSP = getDISubprogram(DS); 7060b57cec5SDimitry Andric // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram 7070b57cec5SDimitry Andric // was inlined from another compile unit. 70806c3fb27SDimitry Andric DIE *OriginDIE = getAbstractScopeDIEs()[InlinedSP]; 7090b57cec5SDimitry Andric assert(OriginDIE && "Unable to find original DIE for an inlined subprogram."); 7100b57cec5SDimitry Andric 7110b57cec5SDimitry Andric auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_inlined_subroutine); 712bdd1243dSDimitry Andric ParentScopeDIE.addChild(ScopeDIE); 7130b57cec5SDimitry Andric addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *OriginDIE); 7140b57cec5SDimitry Andric 7150b57cec5SDimitry Andric attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges()); 7160b57cec5SDimitry Andric 7170b57cec5SDimitry Andric // Add the call site information to the DIE. 7180b57cec5SDimitry Andric const DILocation *IA = Scope->getInlinedAt(); 719bdd1243dSDimitry Andric addUInt(*ScopeDIE, dwarf::DW_AT_call_file, std::nullopt, 7200b57cec5SDimitry Andric getOrCreateSourceID(IA->getFile())); 721bdd1243dSDimitry Andric addUInt(*ScopeDIE, dwarf::DW_AT_call_line, std::nullopt, IA->getLine()); 7220b57cec5SDimitry Andric if (IA->getColumn()) 723bdd1243dSDimitry Andric addUInt(*ScopeDIE, dwarf::DW_AT_call_column, std::nullopt, IA->getColumn()); 7240b57cec5SDimitry Andric if (IA->getDiscriminator() && DD->getDwarfVersion() >= 4) 725bdd1243dSDimitry Andric addUInt(*ScopeDIE, dwarf::DW_AT_GNU_discriminator, std::nullopt, 7260b57cec5SDimitry Andric IA->getDiscriminator()); 7270b57cec5SDimitry Andric 7280b57cec5SDimitry Andric // Add name to the name table, we do this here because we're guaranteed 7290b57cec5SDimitry Andric // to have concrete versions of our DW_TAG_inlined_subprogram nodes. 7305f757f3fSDimitry Andric DD->addSubprogramNames(*this, CUNode->getNameTableKind(), InlinedSP, 7315f757f3fSDimitry Andric *ScopeDIE); 7320b57cec5SDimitry Andric 7330b57cec5SDimitry Andric return ScopeDIE; 7340b57cec5SDimitry Andric } 7350b57cec5SDimitry Andric 7360b57cec5SDimitry Andric // Construct new DW_TAG_lexical_block for this scope and attach 7370b57cec5SDimitry Andric // DW_AT_low_pc/DW_AT_high_pc labels. 7380b57cec5SDimitry Andric DIE *DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) { 7390b57cec5SDimitry Andric if (DD->isLexicalScopeDIENull(Scope)) 7400b57cec5SDimitry Andric return nullptr; 74106c3fb27SDimitry Andric const auto *DS = Scope->getScopeNode(); 7420b57cec5SDimitry Andric 7430b57cec5SDimitry Andric auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_lexical_block); 74406c3fb27SDimitry Andric if (Scope->isAbstractScope()) { 74506c3fb27SDimitry Andric assert(!getAbstractScopeDIEs().count(DS) && 74606c3fb27SDimitry Andric "Abstract DIE for this scope exists!"); 74706c3fb27SDimitry Andric getAbstractScopeDIEs()[DS] = ScopeDIE; 7480b57cec5SDimitry Andric return ScopeDIE; 74906c3fb27SDimitry Andric } 75006c3fb27SDimitry Andric if (!Scope->getInlinedAt()) { 75106c3fb27SDimitry Andric assert(!LexicalBlockDIEs.count(DS) && 75206c3fb27SDimitry Andric "Concrete out-of-line DIE for this scope exists!"); 75306c3fb27SDimitry Andric LexicalBlockDIEs[DS] = ScopeDIE; 75406c3fb27SDimitry Andric } 7550b57cec5SDimitry Andric 7560b57cec5SDimitry Andric attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges()); 7570b57cec5SDimitry Andric 7580b57cec5SDimitry Andric return ScopeDIE; 7590b57cec5SDimitry Andric } 7600b57cec5SDimitry Andric 7610b57cec5SDimitry Andric DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, bool Abstract) { 7625f757f3fSDimitry Andric auto *VariableDie = DIE::get(DIEValueAllocator, DV.getTag()); 7630b57cec5SDimitry Andric insertDIE(DV.getVariable(), VariableDie); 7645f757f3fSDimitry Andric DV.setDIE(*VariableDie); 7655f757f3fSDimitry Andric // Abstract variables don't get common attributes later, so apply them now. 7660b57cec5SDimitry Andric if (Abstract) { 7675f757f3fSDimitry Andric applyCommonDbgVariableAttributes(DV, *VariableDie); 7685f757f3fSDimitry Andric } else { 7695f757f3fSDimitry Andric std::visit( 7705f757f3fSDimitry Andric [&](const auto &V) { 7715f757f3fSDimitry Andric applyConcreteDbgVariableAttributes(V, DV, *VariableDie); 7725f757f3fSDimitry Andric }, 7735f757f3fSDimitry Andric DV.asVariant()); 7745f757f3fSDimitry Andric } 7750b57cec5SDimitry Andric return VariableDie; 7760b57cec5SDimitry Andric } 7770b57cec5SDimitry Andric 7785f757f3fSDimitry Andric void DwarfCompileUnit::applyConcreteDbgVariableAttributes( 7795f757f3fSDimitry Andric const Loc::Single &Single, const DbgVariable &DV, DIE &VariableDie) { 7805f757f3fSDimitry Andric const DbgValueLoc *DVal = &Single.getValueLoc(); 781fe6060f1SDimitry Andric if (!DVal->isVariadic()) { 782fe6060f1SDimitry Andric const DbgValueLocEntry *Entry = DVal->getLocEntries().begin(); 783fe6060f1SDimitry Andric if (Entry->isLocation()) { 7845f757f3fSDimitry Andric addVariableAddress(DV, VariableDie, Entry->getLoc()); 785fe6060f1SDimitry Andric } else if (Entry->isInt()) { 7865f757f3fSDimitry Andric auto *Expr = Single.getExpr(); 7870b57cec5SDimitry Andric if (Expr && Expr->getNumElements()) { 7880b57cec5SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 7890b57cec5SDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); 7900b57cec5SDimitry Andric // If there is an expression, emit raw unsigned bytes. 7910b57cec5SDimitry Andric DwarfExpr.addFragmentOffset(Expr); 792fe6060f1SDimitry Andric DwarfExpr.addUnsignedConstant(Entry->getInt()); 7930b57cec5SDimitry Andric DwarfExpr.addExpression(Expr); 7945f757f3fSDimitry Andric addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize()); 795480093f4SDimitry Andric if (DwarfExpr.TagOffset) 7965f757f3fSDimitry Andric addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset, 797480093f4SDimitry Andric dwarf::DW_FORM_data1, *DwarfExpr.TagOffset); 7980b57cec5SDimitry Andric } else 7995f757f3fSDimitry Andric addConstantValue(VariableDie, Entry->getInt(), DV.getType()); 800fe6060f1SDimitry Andric } else if (Entry->isConstantFP()) { 8015f757f3fSDimitry Andric addConstantFPValue(VariableDie, Entry->getConstantFP()); 802fe6060f1SDimitry Andric } else if (Entry->isConstantInt()) { 8035f757f3fSDimitry Andric addConstantValue(VariableDie, Entry->getConstantInt(), DV.getType()); 804fe6060f1SDimitry Andric } else if (Entry->isTargetIndexLocation()) { 805e8d8bef9SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 806e8d8bef9SDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); 807e8d8bef9SDimitry Andric const DIBasicType *BT = dyn_cast<DIBasicType>( 808e8d8bef9SDimitry Andric static_cast<const Metadata *>(DV.getVariable()->getType())); 809e8d8bef9SDimitry Andric DwarfDebug::emitDebugLocValue(*Asm, BT, *DVal, DwarfExpr); 8105f757f3fSDimitry Andric addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize()); 8110b57cec5SDimitry Andric } 8125f757f3fSDimitry Andric return; 8130b57cec5SDimitry Andric } 8145f757f3fSDimitry Andric // If any of the location entries are registers with the value 0, 8155f757f3fSDimitry Andric // then the location is undefined. 816fe6060f1SDimitry Andric if (any_of(DVal->getLocEntries(), [](const DbgValueLocEntry &Entry) { 817fe6060f1SDimitry Andric return Entry.isLocation() && !Entry.getLoc().getReg(); 818fe6060f1SDimitry Andric })) 8195f757f3fSDimitry Andric return; 8205f757f3fSDimitry Andric const DIExpression *Expr = Single.getExpr(); 821fe6060f1SDimitry Andric assert(Expr && "Variadic Debug Value must have an Expression."); 822fe6060f1SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 823fe6060f1SDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); 824fe6060f1SDimitry Andric DwarfExpr.addFragmentOffset(Expr); 825fe6060f1SDimitry Andric DIExpressionCursor Cursor(Expr); 826fe6060f1SDimitry Andric const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo(); 827fe6060f1SDimitry Andric 828fe6060f1SDimitry Andric auto AddEntry = [&](const DbgValueLocEntry &Entry, 829fe6060f1SDimitry Andric DIExpressionCursor &Cursor) { 830fe6060f1SDimitry Andric if (Entry.isLocation()) { 831fe6060f1SDimitry Andric if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, 832fe6060f1SDimitry Andric Entry.getLoc().getReg())) 833fe6060f1SDimitry Andric return false; 834fe6060f1SDimitry Andric } else if (Entry.isInt()) { 835fe6060f1SDimitry Andric // If there is an expression, emit raw unsigned bytes. 836fe6060f1SDimitry Andric DwarfExpr.addUnsignedConstant(Entry.getInt()); 837fe6060f1SDimitry Andric } else if (Entry.isConstantFP()) { 8389738bc28SDimitry Andric // DwarfExpression does not support arguments wider than 64 bits 8399738bc28SDimitry Andric // (see PR52584). 8409738bc28SDimitry Andric // TODO: Consider chunking expressions containing overly wide 8419738bc28SDimitry Andric // arguments into separate pointer-sized fragment expressions. 842fe6060f1SDimitry Andric APInt RawBytes = Entry.getConstantFP()->getValueAPF().bitcastToAPInt(); 8439738bc28SDimitry Andric if (RawBytes.getBitWidth() > 64) 8449738bc28SDimitry Andric return false; 8459738bc28SDimitry Andric DwarfExpr.addUnsignedConstant(RawBytes.getZExtValue()); 846fe6060f1SDimitry Andric } else if (Entry.isConstantInt()) { 847fe6060f1SDimitry Andric APInt RawBytes = Entry.getConstantInt()->getValue(); 8489738bc28SDimitry Andric if (RawBytes.getBitWidth() > 64) 8499738bc28SDimitry Andric return false; 8509738bc28SDimitry Andric DwarfExpr.addUnsignedConstant(RawBytes.getZExtValue()); 851fe6060f1SDimitry Andric } else if (Entry.isTargetIndexLocation()) { 852fe6060f1SDimitry Andric TargetIndexLocation Loc = Entry.getTargetIndexLocation(); 8535f757f3fSDimitry Andric // TODO TargetIndexLocation is a target-independent. Currently 8545f757f3fSDimitry Andric // only the WebAssembly-specific encoding is supported. 855fe6060f1SDimitry Andric assert(Asm->TM.getTargetTriple().isWasm()); 856fe6060f1SDimitry Andric DwarfExpr.addWasmLocation(Loc.Index, static_cast<uint64_t>(Loc.Offset)); 857fe6060f1SDimitry Andric } else { 858fe6060f1SDimitry Andric llvm_unreachable("Unsupported Entry type."); 859fe6060f1SDimitry Andric } 860fe6060f1SDimitry Andric return true; 861fe6060f1SDimitry Andric }; 862fe6060f1SDimitry Andric 8639738bc28SDimitry Andric if (!DwarfExpr.addExpression( 864fe6060f1SDimitry Andric std::move(Cursor), 865fe6060f1SDimitry Andric [&](unsigned Idx, DIExpressionCursor &Cursor) -> bool { 866fe6060f1SDimitry Andric return AddEntry(DVal->getLocEntries()[Idx], Cursor); 8679738bc28SDimitry Andric })) 8685f757f3fSDimitry Andric return; 869fe6060f1SDimitry Andric 870fe6060f1SDimitry Andric // Now attach the location information to the DIE. 8715f757f3fSDimitry Andric addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize()); 872fe6060f1SDimitry Andric if (DwarfExpr.TagOffset) 8735f757f3fSDimitry Andric addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1, 874fe6060f1SDimitry Andric *DwarfExpr.TagOffset); 875fe6060f1SDimitry Andric } 8760b57cec5SDimitry Andric 8775f757f3fSDimitry Andric void DwarfCompileUnit::applyConcreteDbgVariableAttributes( 8785f757f3fSDimitry Andric const Loc::Multi &Multi, const DbgVariable &DV, DIE &VariableDie) { 8795f757f3fSDimitry Andric addLocationList(VariableDie, dwarf::DW_AT_location, 8805f757f3fSDimitry Andric Multi.getDebugLocListIndex()); 8815f757f3fSDimitry Andric auto TagOffset = Multi.getDebugLocListTagOffset(); 8825f757f3fSDimitry Andric if (TagOffset) 8835f757f3fSDimitry Andric addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1, 8845f757f3fSDimitry Andric *TagOffset); 8855f757f3fSDimitry Andric } 8860b57cec5SDimitry Andric 8875f757f3fSDimitry Andric void DwarfCompileUnit::applyConcreteDbgVariableAttributes(const Loc::MMI &MMI, 8885f757f3fSDimitry Andric const DbgVariable &DV, 8895f757f3fSDimitry Andric DIE &VariableDie) { 890bdd1243dSDimitry Andric std::optional<unsigned> NVPTXAddressSpace; 8910b57cec5SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 8920b57cec5SDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); 8935f757f3fSDimitry Andric for (const auto &Fragment : MMI.getFrameIndexExprs()) { 8945ffd83dbSDimitry Andric Register FrameReg; 8950b57cec5SDimitry Andric const DIExpression *Expr = Fragment.Expr; 8960b57cec5SDimitry Andric const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering(); 897e8d8bef9SDimitry Andric StackOffset Offset = 898e8d8bef9SDimitry Andric TFI->getFrameIndexReference(*Asm->MF, Fragment.FI, FrameReg); 8990b57cec5SDimitry Andric DwarfExpr.addFragmentOffset(Expr); 900e8d8bef9SDimitry Andric 901e8d8bef9SDimitry Andric auto *TRI = Asm->MF->getSubtarget().getRegisterInfo(); 9020b57cec5SDimitry Andric SmallVector<uint64_t, 8> Ops; 903e8d8bef9SDimitry Andric TRI->getOffsetOpcodes(Offset, Ops); 904e8d8bef9SDimitry Andric 9050b57cec5SDimitry Andric // According to 9060b57cec5SDimitry Andric // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf 9075f757f3fSDimitry Andric // cuda-gdb requires DW_AT_address_class for all variables to be 9085f757f3fSDimitry Andric // able to correctly interpret address space of the variable 9095f757f3fSDimitry Andric // address. Decode DW_OP_constu <DWARF Address Space> DW_OP_swap 9105f757f3fSDimitry Andric // DW_OP_xderef sequence for the NVPTX + gdb target. 9110b57cec5SDimitry Andric unsigned LocalNVPTXAddressSpace; 9120b57cec5SDimitry Andric if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) { 9130b57cec5SDimitry Andric const DIExpression *NewExpr = 9140b57cec5SDimitry Andric DIExpression::extractAddressClass(Expr, LocalNVPTXAddressSpace); 9150b57cec5SDimitry Andric if (NewExpr != Expr) { 9160b57cec5SDimitry Andric Expr = NewExpr; 9170b57cec5SDimitry Andric NVPTXAddressSpace = LocalNVPTXAddressSpace; 9180b57cec5SDimitry Andric } 9190b57cec5SDimitry Andric } 9200b57cec5SDimitry Andric if (Expr) 9210b57cec5SDimitry Andric Ops.append(Expr->elements_begin(), Expr->elements_end()); 9220b57cec5SDimitry Andric DIExpressionCursor Cursor(Ops); 9230b57cec5SDimitry Andric DwarfExpr.setMemoryLocationKind(); 9240b57cec5SDimitry Andric if (const MCSymbol *FrameSymbol = Asm->getFunctionFrameSymbol()) 9250b57cec5SDimitry Andric addOpAddress(*Loc, FrameSymbol); 9260b57cec5SDimitry Andric else 9270b57cec5SDimitry Andric DwarfExpr.addMachineRegExpression( 9280b57cec5SDimitry Andric *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, FrameReg); 9290b57cec5SDimitry Andric DwarfExpr.addExpression(std::move(Cursor)); 9300b57cec5SDimitry Andric } 9310b57cec5SDimitry Andric if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) { 9320b57cec5SDimitry Andric // According to 9330b57cec5SDimitry Andric // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf 9345f757f3fSDimitry Andric // cuda-gdb requires DW_AT_address_class for all variables to be 9355f757f3fSDimitry Andric // able to correctly interpret address space of the variable 9365f757f3fSDimitry Andric // address. 9370b57cec5SDimitry Andric const unsigned NVPTX_ADDR_local_space = 6; 9385f757f3fSDimitry Andric addUInt(VariableDie, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1, 939bdd1243dSDimitry Andric NVPTXAddressSpace.value_or(NVPTX_ADDR_local_space)); 9400b57cec5SDimitry Andric } 9415f757f3fSDimitry Andric addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize()); 9420b57cec5SDimitry Andric if (DwarfExpr.TagOffset) 9435f757f3fSDimitry Andric addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1, 9440b57cec5SDimitry Andric *DwarfExpr.TagOffset); 9450b57cec5SDimitry Andric } 9460b57cec5SDimitry Andric 9475f757f3fSDimitry Andric void DwarfCompileUnit::applyConcreteDbgVariableAttributes( 9485f757f3fSDimitry Andric const Loc::EntryValue &EntryValue, const DbgVariable &DV, 9495f757f3fSDimitry Andric DIE &VariableDie) { 9505f757f3fSDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 9515f757f3fSDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); 9525f757f3fSDimitry Andric // Emit each expression as: EntryValue(Register) <other ops> <Fragment>. 9535f757f3fSDimitry Andric for (auto [Register, Expr] : EntryValue.EntryValues) { 9545f757f3fSDimitry Andric DwarfExpr.addFragmentOffset(&Expr); 9555f757f3fSDimitry Andric DIExpressionCursor Cursor(Expr.getElements()); 9565f757f3fSDimitry Andric DwarfExpr.beginEntryValueExpression(Cursor); 9575f757f3fSDimitry Andric DwarfExpr.addMachineRegExpression( 9585f757f3fSDimitry Andric *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, Register); 9595f757f3fSDimitry Andric DwarfExpr.addExpression(std::move(Cursor)); 9605f757f3fSDimitry Andric } 9615f757f3fSDimitry Andric addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize()); 9625f757f3fSDimitry Andric } 9635f757f3fSDimitry Andric 9645f757f3fSDimitry Andric void DwarfCompileUnit::applyConcreteDbgVariableAttributes( 9655f757f3fSDimitry Andric const std::monostate &, const DbgVariable &DV, DIE &VariableDie) {} 9665f757f3fSDimitry Andric 9670b57cec5SDimitry Andric DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, 9680b57cec5SDimitry Andric const LexicalScope &Scope, 9690b57cec5SDimitry Andric DIE *&ObjectPointer) { 9700b57cec5SDimitry Andric auto Var = constructVariableDIE(DV, Scope.isAbstractScope()); 9710b57cec5SDimitry Andric if (DV.isObjectPointer()) 9720b57cec5SDimitry Andric ObjectPointer = Var; 9730b57cec5SDimitry Andric return Var; 9740b57cec5SDimitry Andric } 9750b57cec5SDimitry Andric 9765f757f3fSDimitry Andric DIE *DwarfCompileUnit::constructLabelDIE(DbgLabel &DL, 9775f757f3fSDimitry Andric const LexicalScope &Scope) { 9785f757f3fSDimitry Andric auto LabelDie = DIE::get(DIEValueAllocator, DL.getTag()); 9795f757f3fSDimitry Andric insertDIE(DL.getLabel(), LabelDie); 9805f757f3fSDimitry Andric DL.setDIE(*LabelDie); 9815f757f3fSDimitry Andric 9825f757f3fSDimitry Andric if (Scope.isAbstractScope()) 9835f757f3fSDimitry Andric applyLabelAttributes(DL, *LabelDie); 9845f757f3fSDimitry Andric 9855f757f3fSDimitry Andric return LabelDie; 9865f757f3fSDimitry Andric } 9875f757f3fSDimitry Andric 9880b57cec5SDimitry Andric /// Return all DIVariables that appear in count: expressions. 9890b57cec5SDimitry Andric static SmallVector<const DIVariable *, 2> dependencies(DbgVariable *Var) { 9900b57cec5SDimitry Andric SmallVector<const DIVariable *, 2> Result; 9910b57cec5SDimitry Andric auto *Array = dyn_cast<DICompositeType>(Var->getType()); 9920b57cec5SDimitry Andric if (!Array || Array->getTag() != dwarf::DW_TAG_array_type) 9930b57cec5SDimitry Andric return Result; 9945ffd83dbSDimitry Andric if (auto *DLVar = Array->getDataLocation()) 9955ffd83dbSDimitry Andric Result.push_back(DLVar); 996e8d8bef9SDimitry Andric if (auto *AsVar = Array->getAssociated()) 997e8d8bef9SDimitry Andric Result.push_back(AsVar); 998e8d8bef9SDimitry Andric if (auto *AlVar = Array->getAllocated()) 999e8d8bef9SDimitry Andric Result.push_back(AlVar); 10000b57cec5SDimitry Andric for (auto *El : Array->getElements()) { 10010b57cec5SDimitry Andric if (auto *Subrange = dyn_cast<DISubrange>(El)) { 10025ffd83dbSDimitry Andric if (auto Count = Subrange->getCount()) 100306c3fb27SDimitry Andric if (auto *Dependency = dyn_cast_if_present<DIVariable *>(Count)) 10040b57cec5SDimitry Andric Result.push_back(Dependency); 10055ffd83dbSDimitry Andric if (auto LB = Subrange->getLowerBound()) 100606c3fb27SDimitry Andric if (auto *Dependency = dyn_cast_if_present<DIVariable *>(LB)) 10075ffd83dbSDimitry Andric Result.push_back(Dependency); 10085ffd83dbSDimitry Andric if (auto UB = Subrange->getUpperBound()) 100906c3fb27SDimitry Andric if (auto *Dependency = dyn_cast_if_present<DIVariable *>(UB)) 10105ffd83dbSDimitry Andric Result.push_back(Dependency); 10115ffd83dbSDimitry Andric if (auto ST = Subrange->getStride()) 101206c3fb27SDimitry Andric if (auto *Dependency = dyn_cast_if_present<DIVariable *>(ST)) 10135ffd83dbSDimitry Andric Result.push_back(Dependency); 1014e8d8bef9SDimitry Andric } else if (auto *GenericSubrange = dyn_cast<DIGenericSubrange>(El)) { 1015e8d8bef9SDimitry Andric if (auto Count = GenericSubrange->getCount()) 101606c3fb27SDimitry Andric if (auto *Dependency = dyn_cast_if_present<DIVariable *>(Count)) 1017e8d8bef9SDimitry Andric Result.push_back(Dependency); 1018e8d8bef9SDimitry Andric if (auto LB = GenericSubrange->getLowerBound()) 101906c3fb27SDimitry Andric if (auto *Dependency = dyn_cast_if_present<DIVariable *>(LB)) 1020e8d8bef9SDimitry Andric Result.push_back(Dependency); 1021e8d8bef9SDimitry Andric if (auto UB = GenericSubrange->getUpperBound()) 102206c3fb27SDimitry Andric if (auto *Dependency = dyn_cast_if_present<DIVariable *>(UB)) 1023e8d8bef9SDimitry Andric Result.push_back(Dependency); 1024e8d8bef9SDimitry Andric if (auto ST = GenericSubrange->getStride()) 102506c3fb27SDimitry Andric if (auto *Dependency = dyn_cast_if_present<DIVariable *>(ST)) 1026e8d8bef9SDimitry Andric Result.push_back(Dependency); 10270b57cec5SDimitry Andric } 10280b57cec5SDimitry Andric } 10290b57cec5SDimitry Andric return Result; 10300b57cec5SDimitry Andric } 10310b57cec5SDimitry Andric 10320b57cec5SDimitry Andric /// Sort local variables so that variables appearing inside of helper 10330b57cec5SDimitry Andric /// expressions come first. 10340b57cec5SDimitry Andric static SmallVector<DbgVariable *, 8> 10350b57cec5SDimitry Andric sortLocalVars(SmallVectorImpl<DbgVariable *> &Input) { 10360b57cec5SDimitry Andric SmallVector<DbgVariable *, 8> Result; 10370b57cec5SDimitry Andric SmallVector<PointerIntPair<DbgVariable *, 1>, 8> WorkList; 10380b57cec5SDimitry Andric // Map back from a DIVariable to its containing DbgVariable. 10390b57cec5SDimitry Andric SmallDenseMap<const DILocalVariable *, DbgVariable *> DbgVar; 10400b57cec5SDimitry Andric // Set of DbgVariables in Result. 10410b57cec5SDimitry Andric SmallDenseSet<DbgVariable *, 8> Visited; 10420b57cec5SDimitry Andric // For cycle detection. 10430b57cec5SDimitry Andric SmallDenseSet<DbgVariable *, 8> Visiting; 10440b57cec5SDimitry Andric 10450b57cec5SDimitry Andric // Initialize the worklist and the DIVariable lookup table. 1046fcaf7f86SDimitry Andric for (auto *Var : reverse(Input)) { 10470b57cec5SDimitry Andric DbgVar.insert({Var->getVariable(), Var}); 10480b57cec5SDimitry Andric WorkList.push_back({Var, 0}); 10490b57cec5SDimitry Andric } 10500b57cec5SDimitry Andric 10510b57cec5SDimitry Andric // Perform a stable topological sort by doing a DFS. 10520b57cec5SDimitry Andric while (!WorkList.empty()) { 10530b57cec5SDimitry Andric auto Item = WorkList.back(); 10540b57cec5SDimitry Andric DbgVariable *Var = Item.getPointer(); 10550b57cec5SDimitry Andric bool visitedAllDependencies = Item.getInt(); 10560b57cec5SDimitry Andric WorkList.pop_back(); 10570b57cec5SDimitry Andric 1058349cc55cSDimitry Andric assert(Var); 10590b57cec5SDimitry Andric 10600b57cec5SDimitry Andric // Already handled. 10610b57cec5SDimitry Andric if (Visited.count(Var)) 10620b57cec5SDimitry Andric continue; 10630b57cec5SDimitry Andric 10640b57cec5SDimitry Andric // Add to Result if all dependencies are visited. 10650b57cec5SDimitry Andric if (visitedAllDependencies) { 10660b57cec5SDimitry Andric Visited.insert(Var); 10670b57cec5SDimitry Andric Result.push_back(Var); 10680b57cec5SDimitry Andric continue; 10690b57cec5SDimitry Andric } 10700b57cec5SDimitry Andric 10710b57cec5SDimitry Andric // Detect cycles. 10720b57cec5SDimitry Andric auto Res = Visiting.insert(Var); 10730b57cec5SDimitry Andric if (!Res.second) { 10740b57cec5SDimitry Andric assert(false && "dependency cycle in local variables"); 10750b57cec5SDimitry Andric return Result; 10760b57cec5SDimitry Andric } 10770b57cec5SDimitry Andric 10780b57cec5SDimitry Andric // Push dependencies and this node onto the worklist, so that this node is 10790b57cec5SDimitry Andric // visited again after all of its dependencies are handled. 10800b57cec5SDimitry Andric WorkList.push_back({Var, 1}); 1081fcaf7f86SDimitry Andric for (const auto *Dependency : dependencies(Var)) { 1082349cc55cSDimitry Andric // Don't add dependency if it is in a different lexical scope or a global. 1083349cc55cSDimitry Andric if (const auto *Dep = dyn_cast<const DILocalVariable>(Dependency)) 1084349cc55cSDimitry Andric if (DbgVariable *Var = DbgVar.lookup(Dep)) 1085349cc55cSDimitry Andric WorkList.push_back({Var, 0}); 10860b57cec5SDimitry Andric } 10870b57cec5SDimitry Andric } 10880b57cec5SDimitry Andric return Result; 10890b57cec5SDimitry Andric } 10900b57cec5SDimitry Andric 10910b57cec5SDimitry Andric DIE &DwarfCompileUnit::constructSubprogramScopeDIE(const DISubprogram *Sub, 10920b57cec5SDimitry Andric LexicalScope *Scope) { 10930b57cec5SDimitry Andric DIE &ScopeDIE = updateSubprogramScopeDIE(Sub); 10940b57cec5SDimitry Andric 10950b57cec5SDimitry Andric if (Scope) { 10960b57cec5SDimitry Andric assert(!Scope->getInlinedAt()); 10970b57cec5SDimitry Andric assert(!Scope->isAbstractScope()); 10980b57cec5SDimitry Andric // Collect lexical scope children first. 10990b57cec5SDimitry Andric // ObjectPointer might be a local (non-argument) local variable if it's a 11000b57cec5SDimitry Andric // block's synthetic this pointer. 11015f757f3fSDimitry Andric if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, ScopeDIE)) 11025f757f3fSDimitry Andric addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer); 11030b57cec5SDimitry Andric } 11040b57cec5SDimitry Andric 11050b57cec5SDimitry Andric // If this is a variadic function, add an unspecified parameter. 11060b57cec5SDimitry Andric DITypeRefArray FnArgs = Sub->getType()->getTypeArray(); 11070b57cec5SDimitry Andric 11080b57cec5SDimitry Andric // If we have a single element of null, it is a function that returns void. 11090b57cec5SDimitry Andric // If we have more than one elements and the last one is null, it is a 11100b57cec5SDimitry Andric // variadic function. 11110b57cec5SDimitry Andric if (FnArgs.size() > 1 && !FnArgs[FnArgs.size() - 1] && 11120b57cec5SDimitry Andric !includeMinimalInlineScopes()) 11130b57cec5SDimitry Andric ScopeDIE.addChild( 11140b57cec5SDimitry Andric DIE::get(DIEValueAllocator, dwarf::DW_TAG_unspecified_parameters)); 11150b57cec5SDimitry Andric 11160b57cec5SDimitry Andric return ScopeDIE; 11170b57cec5SDimitry Andric } 11180b57cec5SDimitry Andric 11190b57cec5SDimitry Andric DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope, 11200b57cec5SDimitry Andric DIE &ScopeDIE) { 11214824e7fdSDimitry Andric DIE *ObjectPointer = nullptr; 11220b57cec5SDimitry Andric 11234824e7fdSDimitry Andric // Emit function arguments (order is significant). 11244824e7fdSDimitry Andric auto Vars = DU->getScopeVariables().lookup(Scope); 11254824e7fdSDimitry Andric for (auto &DV : Vars.Args) 11264824e7fdSDimitry Andric ScopeDIE.addChild(constructVariableDIE(*DV.second, *Scope, ObjectPointer)); 11274824e7fdSDimitry Andric 11284824e7fdSDimitry Andric // Emit local variables. 11294824e7fdSDimitry Andric auto Locals = sortLocalVars(Vars.Locals); 11304824e7fdSDimitry Andric for (DbgVariable *DV : Locals) 11314824e7fdSDimitry Andric ScopeDIE.addChild(constructVariableDIE(*DV, *Scope, ObjectPointer)); 11324824e7fdSDimitry Andric 11334824e7fdSDimitry Andric // Emit labels. 11344824e7fdSDimitry Andric for (DbgLabel *DL : DU->getScopeLabels().lookup(Scope)) 11354824e7fdSDimitry Andric ScopeDIE.addChild(constructLabelDIE(*DL, *Scope)); 11364824e7fdSDimitry Andric 113706c3fb27SDimitry Andric // Track other local entities (skipped in gmlt-like data). 113806c3fb27SDimitry Andric // This creates mapping between CU and a set of local declarations that 113906c3fb27SDimitry Andric // should be emitted for subprograms in this CU. 114006c3fb27SDimitry Andric if (!includeMinimalInlineScopes() && !Scope->getInlinedAt()) { 114106c3fb27SDimitry Andric auto &LocalDecls = DD->getLocalDeclsForScope(Scope->getScopeNode()); 114206c3fb27SDimitry Andric DeferredLocalDecls.insert(LocalDecls.begin(), LocalDecls.end()); 114306c3fb27SDimitry Andric } 114406c3fb27SDimitry Andric 11454824e7fdSDimitry Andric // Emit inner lexical scopes. 114606c3fb27SDimitry Andric auto skipLexicalScope = [this](LexicalScope *S) -> bool { 114706c3fb27SDimitry Andric if (isa<DISubprogram>(S->getScopeNode())) 11484824e7fdSDimitry Andric return false; 114906c3fb27SDimitry Andric auto Vars = DU->getScopeVariables().lookup(S); 115006c3fb27SDimitry Andric if (!Vars.Args.empty() || !Vars.Locals.empty()) 115106c3fb27SDimitry Andric return false; 115206c3fb27SDimitry Andric return includeMinimalInlineScopes() || 115306c3fb27SDimitry Andric DD->getLocalDeclsForScope(S->getScopeNode()).empty(); 11544824e7fdSDimitry Andric }; 11554824e7fdSDimitry Andric for (LexicalScope *LS : Scope->getChildren()) { 11564824e7fdSDimitry Andric // If the lexical block doesn't have non-scope children, skip 11574824e7fdSDimitry Andric // its emission and put its children directly to the parent scope. 115806c3fb27SDimitry Andric if (skipLexicalScope(LS)) 11594824e7fdSDimitry Andric createAndAddScopeChildren(LS, ScopeDIE); 116006c3fb27SDimitry Andric else 116106c3fb27SDimitry Andric constructScopeDIE(LS, ScopeDIE); 11624824e7fdSDimitry Andric } 11630b57cec5SDimitry Andric 11640b57cec5SDimitry Andric return ObjectPointer; 11650b57cec5SDimitry Andric } 11660b57cec5SDimitry Andric 11670b57cec5SDimitry Andric void DwarfCompileUnit::constructAbstractSubprogramScopeDIE( 11680b57cec5SDimitry Andric LexicalScope *Scope) { 11690b57cec5SDimitry Andric auto *SP = cast<DISubprogram>(Scope->getScopeNode()); 117006c3fb27SDimitry Andric if (getAbstractScopeDIEs().count(SP)) 117106c3fb27SDimitry Andric return; 11720b57cec5SDimitry Andric 11730b57cec5SDimitry Andric DIE *ContextDIE; 11740b57cec5SDimitry Andric DwarfCompileUnit *ContextCU = this; 11750b57cec5SDimitry Andric 11760b57cec5SDimitry Andric if (includeMinimalInlineScopes()) 11770b57cec5SDimitry Andric ContextDIE = &getUnitDie(); 11780b57cec5SDimitry Andric // Some of this is duplicated from DwarfUnit::getOrCreateSubprogramDIE, with 11790b57cec5SDimitry Andric // the important distinction that the debug node is not associated with the 11800b57cec5SDimitry Andric // DIE (since the debug node will be associated with the concrete DIE, if 11810b57cec5SDimitry Andric // any). It could be refactored to some common utility function. 11820b57cec5SDimitry Andric else if (auto *SPDecl = SP->getDeclaration()) { 11830b57cec5SDimitry Andric ContextDIE = &getUnitDie(); 11840b57cec5SDimitry Andric getOrCreateSubprogramDIE(SPDecl); 11850b57cec5SDimitry Andric } else { 11860b57cec5SDimitry Andric ContextDIE = getOrCreateContextDIE(SP->getScope()); 11870b57cec5SDimitry Andric // The scope may be shared with a subprogram that has already been 11880b57cec5SDimitry Andric // constructed in another CU, in which case we need to construct this 11890b57cec5SDimitry Andric // subprogram in the same CU. 11900b57cec5SDimitry Andric ContextCU = DD->lookupCU(ContextDIE->getUnitDie()); 11910b57cec5SDimitry Andric } 11920b57cec5SDimitry Andric 11930b57cec5SDimitry Andric // Passing null as the associated node because the abstract definition 11940b57cec5SDimitry Andric // shouldn't be found by lookup. 119506c3fb27SDimitry Andric DIE &AbsDef = ContextCU->createAndAddDIE(dwarf::DW_TAG_subprogram, 119606c3fb27SDimitry Andric *ContextDIE, nullptr); 119706c3fb27SDimitry Andric 119806c3fb27SDimitry Andric // Store the DIE before creating children. 119906c3fb27SDimitry Andric ContextCU->getAbstractScopeDIEs()[SP] = &AbsDef; 120006c3fb27SDimitry Andric 120106c3fb27SDimitry Andric ContextCU->applySubprogramAttributesToDefinition(SP, AbsDef); 120206c3fb27SDimitry Andric ContextCU->addSInt(AbsDef, dwarf::DW_AT_inline, 1203bdd1243dSDimitry Andric DD->getDwarfVersion() <= 4 ? std::optional<dwarf::Form>() 1204349cc55cSDimitry Andric : dwarf::DW_FORM_implicit_const, 1205349cc55cSDimitry Andric dwarf::DW_INL_inlined); 120606c3fb27SDimitry Andric if (DIE *ObjectPointer = ContextCU->createAndAddScopeChildren(Scope, AbsDef)) 120706c3fb27SDimitry Andric ContextCU->addDIEEntry(AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer); 12080b57cec5SDimitry Andric } 12090b57cec5SDimitry Andric 12105ffd83dbSDimitry Andric bool DwarfCompileUnit::useGNUAnalogForDwarf5Feature() const { 1211e8d8bef9SDimitry Andric return DD->getDwarfVersion() == 4 && !DD->tuneForLLDB(); 12128bcb0991SDimitry Andric } 12138bcb0991SDimitry Andric 12148bcb0991SDimitry Andric dwarf::Tag DwarfCompileUnit::getDwarf5OrGNUTag(dwarf::Tag Tag) const { 12155ffd83dbSDimitry Andric if (!useGNUAnalogForDwarf5Feature()) 12168bcb0991SDimitry Andric return Tag; 12178bcb0991SDimitry Andric switch (Tag) { 12188bcb0991SDimitry Andric case dwarf::DW_TAG_call_site: 12198bcb0991SDimitry Andric return dwarf::DW_TAG_GNU_call_site; 12208bcb0991SDimitry Andric case dwarf::DW_TAG_call_site_parameter: 12218bcb0991SDimitry Andric return dwarf::DW_TAG_GNU_call_site_parameter; 12228bcb0991SDimitry Andric default: 12238bcb0991SDimitry Andric llvm_unreachable("DWARF5 tag with no GNU analog"); 12248bcb0991SDimitry Andric } 12258bcb0991SDimitry Andric } 12268bcb0991SDimitry Andric 12278bcb0991SDimitry Andric dwarf::Attribute 12288bcb0991SDimitry Andric DwarfCompileUnit::getDwarf5OrGNUAttr(dwarf::Attribute Attr) const { 12295ffd83dbSDimitry Andric if (!useGNUAnalogForDwarf5Feature()) 12308bcb0991SDimitry Andric return Attr; 12318bcb0991SDimitry Andric switch (Attr) { 12328bcb0991SDimitry Andric case dwarf::DW_AT_call_all_calls: 12338bcb0991SDimitry Andric return dwarf::DW_AT_GNU_all_call_sites; 12348bcb0991SDimitry Andric case dwarf::DW_AT_call_target: 12358bcb0991SDimitry Andric return dwarf::DW_AT_GNU_call_site_target; 12368bcb0991SDimitry Andric case dwarf::DW_AT_call_origin: 12378bcb0991SDimitry Andric return dwarf::DW_AT_abstract_origin; 12385ffd83dbSDimitry Andric case dwarf::DW_AT_call_return_pc: 12398bcb0991SDimitry Andric return dwarf::DW_AT_low_pc; 12408bcb0991SDimitry Andric case dwarf::DW_AT_call_value: 12418bcb0991SDimitry Andric return dwarf::DW_AT_GNU_call_site_value; 12428bcb0991SDimitry Andric case dwarf::DW_AT_call_tail_call: 12438bcb0991SDimitry Andric return dwarf::DW_AT_GNU_tail_call; 12448bcb0991SDimitry Andric default: 12458bcb0991SDimitry Andric llvm_unreachable("DWARF5 attribute with no GNU analog"); 12468bcb0991SDimitry Andric } 12478bcb0991SDimitry Andric } 12488bcb0991SDimitry Andric 12498bcb0991SDimitry Andric dwarf::LocationAtom 12508bcb0991SDimitry Andric DwarfCompileUnit::getDwarf5OrGNULocationAtom(dwarf::LocationAtom Loc) const { 12515ffd83dbSDimitry Andric if (!useGNUAnalogForDwarf5Feature()) 12528bcb0991SDimitry Andric return Loc; 12538bcb0991SDimitry Andric switch (Loc) { 12548bcb0991SDimitry Andric case dwarf::DW_OP_entry_value: 12558bcb0991SDimitry Andric return dwarf::DW_OP_GNU_entry_value; 12568bcb0991SDimitry Andric default: 12578bcb0991SDimitry Andric llvm_unreachable("DWARF5 location atom with no GNU analog"); 12588bcb0991SDimitry Andric } 12598bcb0991SDimitry Andric } 12608bcb0991SDimitry Andric 12615ffd83dbSDimitry Andric DIE &DwarfCompileUnit::constructCallSiteEntryDIE(DIE &ScopeDIE, 126269ade1e0SDimitry Andric const DISubprogram *CalleeSP, 12635ffd83dbSDimitry Andric bool IsTail, 12645ffd83dbSDimitry Andric const MCSymbol *PCAddr, 12655ffd83dbSDimitry Andric const MCSymbol *CallAddr, 12665ffd83dbSDimitry Andric unsigned CallReg) { 12670b57cec5SDimitry Andric // Insert a call site entry DIE within ScopeDIE. 12688bcb0991SDimitry Andric DIE &CallSiteDIE = createAndAddDIE(getDwarf5OrGNUTag(dwarf::DW_TAG_call_site), 12698bcb0991SDimitry Andric ScopeDIE, nullptr); 12700b57cec5SDimitry Andric 12718bcb0991SDimitry Andric if (CallReg) { 12728bcb0991SDimitry Andric // Indirect call. 12738bcb0991SDimitry Andric addAddress(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_target), 12748bcb0991SDimitry Andric MachineLocation(CallReg)); 12750b57cec5SDimitry Andric } else { 127669ade1e0SDimitry Andric DIE *CalleeDIE = getOrCreateSubprogramDIE(CalleeSP); 127769ade1e0SDimitry Andric assert(CalleeDIE && "Could not create DIE for call site entry origin"); 1278*0fca6ea1SDimitry Andric if (AddLinkageNamesToDeclCallOriginsForTuning(DD) && 1279*0fca6ea1SDimitry Andric !CalleeSP->isDefinition() && 1280*0fca6ea1SDimitry Andric !CalleeDIE->findAttribute(dwarf::DW_AT_linkage_name)) { 1281*0fca6ea1SDimitry Andric addLinkageName(*CalleeDIE, CalleeSP->getLinkageName()); 1282*0fca6ea1SDimitry Andric } 1283*0fca6ea1SDimitry Andric 12848bcb0991SDimitry Andric addDIEEntry(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_origin), 12858bcb0991SDimitry Andric *CalleeDIE); 12868bcb0991SDimitry Andric } 12878bcb0991SDimitry Andric 12885ffd83dbSDimitry Andric if (IsTail) { 12898bcb0991SDimitry Andric // Attach DW_AT_call_tail_call to tail calls for standards compliance. 12908bcb0991SDimitry Andric addFlag(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_tail_call)); 12918bcb0991SDimitry Andric 12925ffd83dbSDimitry Andric // Attach the address of the branch instruction to allow the debugger to 12935ffd83dbSDimitry Andric // show where the tail call occurred. This attribute has no GNU analog. 12945ffd83dbSDimitry Andric // 12955ffd83dbSDimitry Andric // GDB works backwards from non-standard usage of DW_AT_low_pc (in DWARF4 12965ffd83dbSDimitry Andric // mode -- equivalently, in DWARF5 mode, DW_AT_call_return_pc) at tail-call 12975ffd83dbSDimitry Andric // site entries to figure out the PC of tail-calling branch instructions. 12985ffd83dbSDimitry Andric // This means it doesn't need the compiler to emit DW_AT_call_pc, so we 12995ffd83dbSDimitry Andric // don't emit it here. 13005ffd83dbSDimitry Andric // 13015ffd83dbSDimitry Andric // There's no need to tie non-GDB debuggers to this non-standardness, as it 13025ffd83dbSDimitry Andric // adds unnecessary complexity to the debugger. For non-GDB debuggers, emit 13035ffd83dbSDimitry Andric // the standard DW_AT_call_pc info. 13045ffd83dbSDimitry Andric if (!useGNUAnalogForDwarf5Feature()) 13055ffd83dbSDimitry Andric addLabelAddress(CallSiteDIE, dwarf::DW_AT_call_pc, CallAddr); 13065ffd83dbSDimitry Andric } 13075ffd83dbSDimitry Andric 13080b57cec5SDimitry Andric // Attach the return PC to allow the debugger to disambiguate call paths 13090b57cec5SDimitry Andric // from one function to another. 13105ffd83dbSDimitry Andric // 13115ffd83dbSDimitry Andric // The return PC is only really needed when the call /isn't/ a tail call, but 13125ffd83dbSDimitry Andric // GDB expects it in DWARF4 mode, even for tail calls (see the comment above 13135ffd83dbSDimitry Andric // the DW_AT_call_pc emission logic for an explanation). 13145ffd83dbSDimitry Andric if (!IsTail || useGNUAnalogForDwarf5Feature()) { 13155ffd83dbSDimitry Andric assert(PCAddr && "Missing return PC information for a call"); 13165ffd83dbSDimitry Andric addLabelAddress(CallSiteDIE, 13175ffd83dbSDimitry Andric getDwarf5OrGNUAttr(dwarf::DW_AT_call_return_pc), PCAddr); 13180b57cec5SDimitry Andric } 13198bcb0991SDimitry Andric 13200b57cec5SDimitry Andric return CallSiteDIE; 13210b57cec5SDimitry Andric } 13220b57cec5SDimitry Andric 13238bcb0991SDimitry Andric void DwarfCompileUnit::constructCallSiteParmEntryDIEs( 13248bcb0991SDimitry Andric DIE &CallSiteDIE, SmallVector<DbgCallSiteParam, 4> &Params) { 13258bcb0991SDimitry Andric for (const auto &Param : Params) { 13268bcb0991SDimitry Andric unsigned Register = Param.getRegister(); 13278bcb0991SDimitry Andric auto CallSiteDieParam = 13288bcb0991SDimitry Andric DIE::get(DIEValueAllocator, 13298bcb0991SDimitry Andric getDwarf5OrGNUTag(dwarf::DW_TAG_call_site_parameter)); 13308bcb0991SDimitry Andric insertDIE(CallSiteDieParam); 13318bcb0991SDimitry Andric addAddress(*CallSiteDieParam, dwarf::DW_AT_location, 13328bcb0991SDimitry Andric MachineLocation(Register)); 13338bcb0991SDimitry Andric 13348bcb0991SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 13358bcb0991SDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); 13368bcb0991SDimitry Andric DwarfExpr.setCallSiteParamValueFlag(); 13378bcb0991SDimitry Andric 13388bcb0991SDimitry Andric DwarfDebug::emitDebugLocValue(*Asm, nullptr, Param.getValue(), DwarfExpr); 13398bcb0991SDimitry Andric 13408bcb0991SDimitry Andric addBlock(*CallSiteDieParam, getDwarf5OrGNUAttr(dwarf::DW_AT_call_value), 13418bcb0991SDimitry Andric DwarfExpr.finalize()); 13428bcb0991SDimitry Andric 13438bcb0991SDimitry Andric CallSiteDIE.addChild(CallSiteDieParam); 13448bcb0991SDimitry Andric } 13458bcb0991SDimitry Andric } 13468bcb0991SDimitry Andric 13470b57cec5SDimitry Andric DIE *DwarfCompileUnit::constructImportedEntityDIE( 13480b57cec5SDimitry Andric const DIImportedEntity *Module) { 13490b57cec5SDimitry Andric DIE *IMDie = DIE::get(DIEValueAllocator, (dwarf::Tag)Module->getTag()); 13500b57cec5SDimitry Andric insertDIE(Module, IMDie); 13510b57cec5SDimitry Andric DIE *EntityDie; 13520b57cec5SDimitry Andric auto *Entity = Module->getEntity(); 13530b57cec5SDimitry Andric if (auto *NS = dyn_cast<DINamespace>(Entity)) 13540b57cec5SDimitry Andric EntityDie = getOrCreateNameSpace(NS); 13550b57cec5SDimitry Andric else if (auto *M = dyn_cast<DIModule>(Entity)) 13560b57cec5SDimitry Andric EntityDie = getOrCreateModule(M); 135706c3fb27SDimitry Andric else if (auto *SP = dyn_cast<DISubprogram>(Entity)) { 135806c3fb27SDimitry Andric // If there is an abstract subprogram, refer to it. Note that this assumes 135906c3fb27SDimitry Andric // that all the abstract subprograms have been already created (which is 136006c3fb27SDimitry Andric // correct until imported entities get emitted in DwarfDebug::endModule()). 136106c3fb27SDimitry Andric if (auto *AbsSPDie = getAbstractScopeDIEs().lookup(SP)) 136206c3fb27SDimitry Andric EntityDie = AbsSPDie; 136306c3fb27SDimitry Andric else 13640b57cec5SDimitry Andric EntityDie = getOrCreateSubprogramDIE(SP); 136506c3fb27SDimitry Andric } else if (auto *T = dyn_cast<DIType>(Entity)) 13660b57cec5SDimitry Andric EntityDie = getOrCreateTypeDIE(T); 13670b57cec5SDimitry Andric else if (auto *GV = dyn_cast<DIGlobalVariable>(Entity)) 13680b57cec5SDimitry Andric EntityDie = getOrCreateGlobalVariableDIE(GV, {}); 136906c3fb27SDimitry Andric else if (auto *IE = dyn_cast<DIImportedEntity>(Entity)) 137006c3fb27SDimitry Andric EntityDie = getOrCreateImportedEntityDIE(IE); 13710b57cec5SDimitry Andric else 13720b57cec5SDimitry Andric EntityDie = getDIE(Entity); 13730b57cec5SDimitry Andric assert(EntityDie); 13740b57cec5SDimitry Andric addSourceLine(*IMDie, Module->getLine(), Module->getFile()); 13750b57cec5SDimitry Andric addDIEEntry(*IMDie, dwarf::DW_AT_import, *EntityDie); 13760b57cec5SDimitry Andric StringRef Name = Module->getName(); 137706c3fb27SDimitry Andric if (!Name.empty()) { 13780b57cec5SDimitry Andric addString(*IMDie, dwarf::DW_AT_name, Name); 13790b57cec5SDimitry Andric 138006c3fb27SDimitry Andric // FIXME: if consumers ever start caring about handling 138106c3fb27SDimitry Andric // unnamed import declarations such as `using ::nullptr_t` 138206c3fb27SDimitry Andric // or `using namespace std::ranges`, we could add the 138306c3fb27SDimitry Andric // import declaration into the accelerator table with the 138406c3fb27SDimitry Andric // name being the one of the entity being imported. 13855f757f3fSDimitry Andric DD->addAccelNamespace(*this, CUNode->getNameTableKind(), Name, *IMDie); 138606c3fb27SDimitry Andric } 138706c3fb27SDimitry Andric 1388349cc55cSDimitry Andric // This is for imported module with renamed entities (such as variables and 1389349cc55cSDimitry Andric // subprograms). 1390349cc55cSDimitry Andric DINodeArray Elements = Module->getElements(); 1391349cc55cSDimitry Andric for (const auto *Element : Elements) { 1392349cc55cSDimitry Andric if (!Element) 1393349cc55cSDimitry Andric continue; 1394349cc55cSDimitry Andric IMDie->addChild( 1395349cc55cSDimitry Andric constructImportedEntityDIE(cast<DIImportedEntity>(Element))); 1396349cc55cSDimitry Andric } 1397349cc55cSDimitry Andric 13980b57cec5SDimitry Andric return IMDie; 13990b57cec5SDimitry Andric } 14000b57cec5SDimitry Andric 140106c3fb27SDimitry Andric DIE *DwarfCompileUnit::getOrCreateImportedEntityDIE( 140206c3fb27SDimitry Andric const DIImportedEntity *IE) { 140306c3fb27SDimitry Andric 140406c3fb27SDimitry Andric // Check for pre-existence. 140506c3fb27SDimitry Andric if (DIE *Die = getDIE(IE)) 140606c3fb27SDimitry Andric return Die; 140706c3fb27SDimitry Andric 140806c3fb27SDimitry Andric DIE *ContextDIE = getOrCreateContextDIE(IE->getScope()); 140906c3fb27SDimitry Andric assert(ContextDIE && "Empty scope for the imported entity!"); 141006c3fb27SDimitry Andric 141106c3fb27SDimitry Andric DIE *IMDie = constructImportedEntityDIE(IE); 141206c3fb27SDimitry Andric ContextDIE->addChild(IMDie); 141306c3fb27SDimitry Andric return IMDie; 141406c3fb27SDimitry Andric } 141506c3fb27SDimitry Andric 14160b57cec5SDimitry Andric void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP) { 14170b57cec5SDimitry Andric DIE *D = getDIE(SP); 141806c3fb27SDimitry Andric if (DIE *AbsSPDIE = getAbstractScopeDIEs().lookup(SP)) { 14190b57cec5SDimitry Andric if (D) 14200b57cec5SDimitry Andric // If this subprogram has an abstract definition, reference that 14210b57cec5SDimitry Andric addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE); 14220b57cec5SDimitry Andric } else { 14230b57cec5SDimitry Andric assert(D || includeMinimalInlineScopes()); 14240b57cec5SDimitry Andric if (D) 14250b57cec5SDimitry Andric // And attach the attributes 14260b57cec5SDimitry Andric applySubprogramAttributesToDefinition(SP, *D); 14270b57cec5SDimitry Andric } 14280b57cec5SDimitry Andric } 14290b57cec5SDimitry Andric 14300b57cec5SDimitry Andric void DwarfCompileUnit::finishEntityDefinition(const DbgEntity *Entity) { 14310b57cec5SDimitry Andric DbgEntity *AbsEntity = getExistingAbstractEntity(Entity->getEntity()); 14320b57cec5SDimitry Andric 14330b57cec5SDimitry Andric auto *Die = Entity->getDIE(); 14340b57cec5SDimitry Andric /// Label may be used to generate DW_AT_low_pc, so put it outside 14350b57cec5SDimitry Andric /// if/else block. 14360b57cec5SDimitry Andric const DbgLabel *Label = nullptr; 14370b57cec5SDimitry Andric if (AbsEntity && AbsEntity->getDIE()) { 14380b57cec5SDimitry Andric addDIEEntry(*Die, dwarf::DW_AT_abstract_origin, *AbsEntity->getDIE()); 14390b57cec5SDimitry Andric Label = dyn_cast<const DbgLabel>(Entity); 14400b57cec5SDimitry Andric } else { 14410b57cec5SDimitry Andric if (const DbgVariable *Var = dyn_cast<const DbgVariable>(Entity)) 14425f757f3fSDimitry Andric applyCommonDbgVariableAttributes(*Var, *Die); 14430b57cec5SDimitry Andric else if ((Label = dyn_cast<const DbgLabel>(Entity))) 14440b57cec5SDimitry Andric applyLabelAttributes(*Label, *Die); 14450b57cec5SDimitry Andric else 14460b57cec5SDimitry Andric llvm_unreachable("DbgEntity must be DbgVariable or DbgLabel."); 14470b57cec5SDimitry Andric } 14480b57cec5SDimitry Andric 14495f757f3fSDimitry Andric if (!Label) 14505f757f3fSDimitry Andric return; 14515f757f3fSDimitry Andric 14525f757f3fSDimitry Andric const auto *Sym = Label->getSymbol(); 14535f757f3fSDimitry Andric if (!Sym) 14545f757f3fSDimitry Andric return; 14555f757f3fSDimitry Andric 14560b57cec5SDimitry Andric addLabelAddress(*Die, dwarf::DW_AT_low_pc, Sym); 14575f757f3fSDimitry Andric 14585f757f3fSDimitry Andric // A TAG_label with a name and an AT_low_pc must be placed in debug_names. 14595f757f3fSDimitry Andric if (StringRef Name = Label->getName(); !Name.empty()) 14605f757f3fSDimitry Andric getDwarfDebug().addAccelName(*this, CUNode->getNameTableKind(), Name, *Die); 14610b57cec5SDimitry Andric } 14620b57cec5SDimitry Andric 14630b57cec5SDimitry Andric DbgEntity *DwarfCompileUnit::getExistingAbstractEntity(const DINode *Node) { 14640b57cec5SDimitry Andric auto &AbstractEntities = getAbstractEntities(); 14650b57cec5SDimitry Andric auto I = AbstractEntities.find(Node); 14660b57cec5SDimitry Andric if (I != AbstractEntities.end()) 14670b57cec5SDimitry Andric return I->second.get(); 14680b57cec5SDimitry Andric return nullptr; 14690b57cec5SDimitry Andric } 14700b57cec5SDimitry Andric 14710b57cec5SDimitry Andric void DwarfCompileUnit::createAbstractEntity(const DINode *Node, 14720b57cec5SDimitry Andric LexicalScope *Scope) { 14730b57cec5SDimitry Andric assert(Scope && Scope->isAbstractScope()); 14740b57cec5SDimitry Andric auto &Entity = getAbstractEntities()[Node]; 14750b57cec5SDimitry Andric if (isa<const DILocalVariable>(Node)) { 147606c3fb27SDimitry Andric Entity = std::make_unique<DbgVariable>(cast<const DILocalVariable>(Node), 147706c3fb27SDimitry Andric nullptr /* IA */); 14780b57cec5SDimitry Andric DU->addScopeVariable(Scope, cast<DbgVariable>(Entity.get())); 14790b57cec5SDimitry Andric } else if (isa<const DILabel>(Node)) { 14808bcb0991SDimitry Andric Entity = std::make_unique<DbgLabel>( 14810b57cec5SDimitry Andric cast<const DILabel>(Node), nullptr /* IA */); 14820b57cec5SDimitry Andric DU->addScopeLabel(Scope, cast<DbgLabel>(Entity.get())); 14830b57cec5SDimitry Andric } 14840b57cec5SDimitry Andric } 14850b57cec5SDimitry Andric 14860b57cec5SDimitry Andric void DwarfCompileUnit::emitHeader(bool UseOffsets) { 14870b57cec5SDimitry Andric // Don't bother labeling the .dwo unit, as its offset isn't used. 14880b57cec5SDimitry Andric if (!Skeleton && !DD->useSectionsAsReferences()) { 14890b57cec5SDimitry Andric LabelBegin = Asm->createTempSymbol("cu_begin"); 14905ffd83dbSDimitry Andric Asm->OutStreamer->emitLabel(LabelBegin); 14910b57cec5SDimitry Andric } 14920b57cec5SDimitry Andric 14930b57cec5SDimitry Andric dwarf::UnitType UT = Skeleton ? dwarf::DW_UT_split_compile 14940b57cec5SDimitry Andric : DD->useSplitDwarf() ? dwarf::DW_UT_skeleton 14950b57cec5SDimitry Andric : dwarf::DW_UT_compile; 14960b57cec5SDimitry Andric DwarfUnit::emitCommonHeader(UseOffsets, UT); 14970b57cec5SDimitry Andric if (DD->getDwarfVersion() >= 5 && UT != dwarf::DW_UT_compile) 14980b57cec5SDimitry Andric Asm->emitInt64(getDWOId()); 14990b57cec5SDimitry Andric } 15000b57cec5SDimitry Andric 15010b57cec5SDimitry Andric bool DwarfCompileUnit::hasDwarfPubSections() const { 15020b57cec5SDimitry Andric switch (CUNode->getNameTableKind()) { 15030b57cec5SDimitry Andric case DICompileUnit::DebugNameTableKind::None: 15040b57cec5SDimitry Andric return false; 15050b57cec5SDimitry Andric // Opting in to GNU Pubnames/types overrides the default to ensure these are 15060b57cec5SDimitry Andric // generated for things like Gold's gdb_index generation. 15070b57cec5SDimitry Andric case DICompileUnit::DebugNameTableKind::GNU: 15080b57cec5SDimitry Andric return true; 150906c3fb27SDimitry Andric case DICompileUnit::DebugNameTableKind::Apple: 151006c3fb27SDimitry Andric return false; 15110b57cec5SDimitry Andric case DICompileUnit::DebugNameTableKind::Default: 15120b57cec5SDimitry Andric return DD->tuneForGDB() && !includeMinimalInlineScopes() && 15130b57cec5SDimitry Andric !CUNode->isDebugDirectivesOnly() && 15140b57cec5SDimitry Andric DD->getAccelTableKind() != AccelTableKind::Apple && 15150b57cec5SDimitry Andric DD->getDwarfVersion() < 5; 15160b57cec5SDimitry Andric } 15170b57cec5SDimitry Andric llvm_unreachable("Unhandled DICompileUnit::DebugNameTableKind enum"); 15180b57cec5SDimitry Andric } 15190b57cec5SDimitry Andric 15200b57cec5SDimitry Andric /// addGlobalName - Add a new global name to the compile unit. 15210b57cec5SDimitry Andric void DwarfCompileUnit::addGlobalName(StringRef Name, const DIE &Die, 15220b57cec5SDimitry Andric const DIScope *Context) { 15230b57cec5SDimitry Andric if (!hasDwarfPubSections()) 15240b57cec5SDimitry Andric return; 15250b57cec5SDimitry Andric std::string FullName = getParentContextString(Context) + Name.str(); 15260b57cec5SDimitry Andric GlobalNames[FullName] = &Die; 15270b57cec5SDimitry Andric } 15280b57cec5SDimitry Andric 15290b57cec5SDimitry Andric void DwarfCompileUnit::addGlobalNameForTypeUnit(StringRef Name, 15300b57cec5SDimitry Andric const DIScope *Context) { 15310b57cec5SDimitry Andric if (!hasDwarfPubSections()) 15320b57cec5SDimitry Andric return; 15330b57cec5SDimitry Andric std::string FullName = getParentContextString(Context) + Name.str(); 15340b57cec5SDimitry Andric // Insert, allowing the entry to remain as-is if it's already present 15350b57cec5SDimitry Andric // This way the CU-level type DIE is preferred over the "can't describe this 15360b57cec5SDimitry Andric // type as a unit offset because it's not really in the CU at all, it's only 15370b57cec5SDimitry Andric // in a type unit" 15380b57cec5SDimitry Andric GlobalNames.insert(std::make_pair(std::move(FullName), &getUnitDie())); 15390b57cec5SDimitry Andric } 15400b57cec5SDimitry Andric 15410b57cec5SDimitry Andric /// Add a new global type to the unit. 1542*0fca6ea1SDimitry Andric void DwarfCompileUnit::addGlobalTypeImpl(const DIType *Ty, const DIE &Die, 15430b57cec5SDimitry Andric const DIScope *Context) { 15440b57cec5SDimitry Andric if (!hasDwarfPubSections()) 15450b57cec5SDimitry Andric return; 15460b57cec5SDimitry Andric std::string FullName = getParentContextString(Context) + Ty->getName().str(); 15470b57cec5SDimitry Andric GlobalTypes[FullName] = &Die; 15480b57cec5SDimitry Andric } 15490b57cec5SDimitry Andric 15500b57cec5SDimitry Andric void DwarfCompileUnit::addGlobalTypeUnitType(const DIType *Ty, 15510b57cec5SDimitry Andric const DIScope *Context) { 15520b57cec5SDimitry Andric if (!hasDwarfPubSections()) 15530b57cec5SDimitry Andric return; 15540b57cec5SDimitry Andric std::string FullName = getParentContextString(Context) + Ty->getName().str(); 15550b57cec5SDimitry Andric // Insert, allowing the entry to remain as-is if it's already present 15560b57cec5SDimitry Andric // This way the CU-level type DIE is preferred over the "can't describe this 15570b57cec5SDimitry Andric // type as a unit offset because it's not really in the CU at all, it's only 15580b57cec5SDimitry Andric // in a type unit" 15590b57cec5SDimitry Andric GlobalTypes.insert(std::make_pair(std::move(FullName), &getUnitDie())); 15600b57cec5SDimitry Andric } 15610b57cec5SDimitry Andric 15620b57cec5SDimitry Andric void DwarfCompileUnit::addVariableAddress(const DbgVariable &DV, DIE &Die, 15630b57cec5SDimitry Andric MachineLocation Location) { 15645f757f3fSDimitry Andric auto *Single = std::get_if<Loc::Single>(&DV); 15655f757f3fSDimitry Andric if (Single && Single->getExpr()) 15665f757f3fSDimitry Andric addComplexAddress(Single->getExpr(), Die, dwarf::DW_AT_location, Location); 15670b57cec5SDimitry Andric else 15680b57cec5SDimitry Andric addAddress(Die, dwarf::DW_AT_location, Location); 15690b57cec5SDimitry Andric } 15700b57cec5SDimitry Andric 15710b57cec5SDimitry Andric /// Add an address attribute to a die based on the location provided. 15720b57cec5SDimitry Andric void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute, 15730b57cec5SDimitry Andric const MachineLocation &Location) { 15740b57cec5SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 15750b57cec5SDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); 15760b57cec5SDimitry Andric if (Location.isIndirect()) 15770b57cec5SDimitry Andric DwarfExpr.setMemoryLocationKind(); 15780b57cec5SDimitry Andric 15790b57cec5SDimitry Andric DIExpressionCursor Cursor({}); 15800b57cec5SDimitry Andric const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo(); 15810b57cec5SDimitry Andric if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg())) 15820b57cec5SDimitry Andric return; 15830b57cec5SDimitry Andric DwarfExpr.addExpression(std::move(Cursor)); 15840b57cec5SDimitry Andric 15850b57cec5SDimitry Andric // Now attach the location information to the DIE. 15860b57cec5SDimitry Andric addBlock(Die, Attribute, DwarfExpr.finalize()); 1587480093f4SDimitry Andric 1588480093f4SDimitry Andric if (DwarfExpr.TagOffset) 1589480093f4SDimitry Andric addUInt(Die, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1, 1590480093f4SDimitry Andric *DwarfExpr.TagOffset); 15910b57cec5SDimitry Andric } 15920b57cec5SDimitry Andric 15930b57cec5SDimitry Andric /// Start with the address based on the location provided, and generate the 15940b57cec5SDimitry Andric /// DWARF information necessary to find the actual variable given the extra 15950b57cec5SDimitry Andric /// address information encoded in the DbgVariable, starting from the starting 15960b57cec5SDimitry Andric /// location. Add the DWARF information to the die. 15975f757f3fSDimitry Andric void DwarfCompileUnit::addComplexAddress(const DIExpression *DIExpr, DIE &Die, 15980b57cec5SDimitry Andric dwarf::Attribute Attribute, 15990b57cec5SDimitry Andric const MachineLocation &Location) { 16000b57cec5SDimitry Andric DIELoc *Loc = new (DIEValueAllocator) DIELoc; 16010b57cec5SDimitry Andric DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); 16020b57cec5SDimitry Andric DwarfExpr.addFragmentOffset(DIExpr); 16035ffd83dbSDimitry Andric DwarfExpr.setLocation(Location, DIExpr); 16040b57cec5SDimitry Andric 16050b57cec5SDimitry Andric DIExpressionCursor Cursor(DIExpr); 16060b57cec5SDimitry Andric 16075ffd83dbSDimitry Andric if (DIExpr->isEntryValue()) 16088bcb0991SDimitry Andric DwarfExpr.beginEntryValueExpression(Cursor); 16090b57cec5SDimitry Andric 16100b57cec5SDimitry Andric const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo(); 16110b57cec5SDimitry Andric if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg())) 16120b57cec5SDimitry Andric return; 16130b57cec5SDimitry Andric DwarfExpr.addExpression(std::move(Cursor)); 16140b57cec5SDimitry Andric 16150b57cec5SDimitry Andric // Now attach the location information to the DIE. 16160b57cec5SDimitry Andric addBlock(Die, Attribute, DwarfExpr.finalize()); 1617480093f4SDimitry Andric 1618480093f4SDimitry Andric if (DwarfExpr.TagOffset) 1619480093f4SDimitry Andric addUInt(Die, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1, 1620480093f4SDimitry Andric *DwarfExpr.TagOffset); 16210b57cec5SDimitry Andric } 16220b57cec5SDimitry Andric 16230b57cec5SDimitry Andric /// Add a Dwarf loclistptr attribute data and value. 16240b57cec5SDimitry Andric void DwarfCompileUnit::addLocationList(DIE &Die, dwarf::Attribute Attribute, 16250b57cec5SDimitry Andric unsigned Index) { 1626e8d8bef9SDimitry Andric dwarf::Form Form = (DD->getDwarfVersion() >= 5) 1627e8d8bef9SDimitry Andric ? dwarf::DW_FORM_loclistx 1628e8d8bef9SDimitry Andric : DD->getDwarfSectionOffsetForm(); 1629fe6060f1SDimitry Andric addAttribute(Die, Attribute, Form, DIELocList(Index)); 16300b57cec5SDimitry Andric } 16310b57cec5SDimitry Andric 16325f757f3fSDimitry Andric void DwarfCompileUnit::applyCommonDbgVariableAttributes(const DbgVariable &Var, 16330b57cec5SDimitry Andric DIE &VariableDie) { 16340b57cec5SDimitry Andric StringRef Name = Var.getName(); 16350b57cec5SDimitry Andric if (!Name.empty()) 16360b57cec5SDimitry Andric addString(VariableDie, dwarf::DW_AT_name, Name); 16370b57cec5SDimitry Andric const auto *DIVar = Var.getVariable(); 1638349cc55cSDimitry Andric if (DIVar) { 16390b57cec5SDimitry Andric if (uint32_t AlignInBytes = DIVar->getAlignInBytes()) 16400b57cec5SDimitry Andric addUInt(VariableDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata, 16410b57cec5SDimitry Andric AlignInBytes); 1642349cc55cSDimitry Andric addAnnotation(VariableDie, DIVar->getAnnotations()); 1643349cc55cSDimitry Andric } 16440b57cec5SDimitry Andric 16450b57cec5SDimitry Andric addSourceLine(VariableDie, DIVar); 16460b57cec5SDimitry Andric addType(VariableDie, Var.getType()); 16470b57cec5SDimitry Andric if (Var.isArtificial()) 16480b57cec5SDimitry Andric addFlag(VariableDie, dwarf::DW_AT_artificial); 16490b57cec5SDimitry Andric } 16500b57cec5SDimitry Andric 16510b57cec5SDimitry Andric void DwarfCompileUnit::applyLabelAttributes(const DbgLabel &Label, 16520b57cec5SDimitry Andric DIE &LabelDie) { 16530b57cec5SDimitry Andric StringRef Name = Label.getName(); 16540b57cec5SDimitry Andric if (!Name.empty()) 16550b57cec5SDimitry Andric addString(LabelDie, dwarf::DW_AT_name, Name); 16560b57cec5SDimitry Andric const auto *DILabel = Label.getLabel(); 16570b57cec5SDimitry Andric addSourceLine(LabelDie, DILabel); 16580b57cec5SDimitry Andric } 16590b57cec5SDimitry Andric 16600b57cec5SDimitry Andric /// Add a Dwarf expression attribute data and value. 16610b57cec5SDimitry Andric void DwarfCompileUnit::addExpr(DIELoc &Die, dwarf::Form Form, 16620b57cec5SDimitry Andric const MCExpr *Expr) { 1663fe6060f1SDimitry Andric addAttribute(Die, (dwarf::Attribute)0, Form, DIEExpr(Expr)); 16640b57cec5SDimitry Andric } 16650b57cec5SDimitry Andric 16660b57cec5SDimitry Andric void DwarfCompileUnit::applySubprogramAttributesToDefinition( 16670b57cec5SDimitry Andric const DISubprogram *SP, DIE &SPDie) { 16680b57cec5SDimitry Andric auto *SPDecl = SP->getDeclaration(); 16690b57cec5SDimitry Andric auto *Context = SPDecl ? SPDecl->getScope() : SP->getScope(); 16700b57cec5SDimitry Andric applySubprogramAttributes(SP, SPDie, includeMinimalInlineScopes()); 16710b57cec5SDimitry Andric addGlobalName(SP->getName(), SPDie, Context); 16720b57cec5SDimitry Andric } 16730b57cec5SDimitry Andric 16740b57cec5SDimitry Andric bool DwarfCompileUnit::isDwoUnit() const { 16750b57cec5SDimitry Andric return DD->useSplitDwarf() && Skeleton; 16760b57cec5SDimitry Andric } 16770b57cec5SDimitry Andric 16780b57cec5SDimitry Andric void DwarfCompileUnit::finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) { 16790b57cec5SDimitry Andric constructTypeDIE(D, CTy); 16800b57cec5SDimitry Andric } 16810b57cec5SDimitry Andric 16820b57cec5SDimitry Andric bool DwarfCompileUnit::includeMinimalInlineScopes() const { 16830b57cec5SDimitry Andric return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly || 16840b57cec5SDimitry Andric (DD->useSplitDwarf() && !Skeleton); 16850b57cec5SDimitry Andric } 16860b57cec5SDimitry Andric 16870b57cec5SDimitry Andric void DwarfCompileUnit::addAddrTableBase() { 16880b57cec5SDimitry Andric const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); 16890b57cec5SDimitry Andric MCSymbol *Label = DD->getAddressPool().getLabel(); 16900b57cec5SDimitry Andric addSectionLabel(getUnitDie(), 1691e8d8bef9SDimitry Andric DD->getDwarfVersion() >= 5 ? dwarf::DW_AT_addr_base 16920b57cec5SDimitry Andric : dwarf::DW_AT_GNU_addr_base, 16930b57cec5SDimitry Andric Label, TLOF.getDwarfAddrSection()->getBeginSymbol()); 16940b57cec5SDimitry Andric } 16950b57cec5SDimitry Andric 16960b57cec5SDimitry Andric void DwarfCompileUnit::addBaseTypeRef(DIEValueList &Die, int64_t Idx) { 1697fe6060f1SDimitry Andric addAttribute(Die, (dwarf::Attribute)0, dwarf::DW_FORM_udata, 16980b57cec5SDimitry Andric new (DIEValueAllocator) DIEBaseTypeRef(this, Idx)); 16990b57cec5SDimitry Andric } 17000b57cec5SDimitry Andric 17010b57cec5SDimitry Andric void DwarfCompileUnit::createBaseTypeDIEs() { 17020b57cec5SDimitry Andric // Insert the base_type DIEs directly after the CU so that their offsets will 17030b57cec5SDimitry Andric // fit in the fixed size ULEB128 used inside the location expressions. 17040b57cec5SDimitry Andric // Maintain order by iterating backwards and inserting to the front of CU 17050b57cec5SDimitry Andric // child list. 17060b57cec5SDimitry Andric for (auto &Btr : reverse(ExprRefedBaseTypes)) { 17070b57cec5SDimitry Andric DIE &Die = getUnitDie().addChildFront( 17080b57cec5SDimitry Andric DIE::get(DIEValueAllocator, dwarf::DW_TAG_base_type)); 17090b57cec5SDimitry Andric SmallString<32> Str; 17100b57cec5SDimitry Andric addString(Die, dwarf::DW_AT_name, 17110b57cec5SDimitry Andric Twine(dwarf::AttributeEncodingString(Btr.Encoding) + 17120b57cec5SDimitry Andric "_" + Twine(Btr.BitSize)).toStringRef(Str)); 17130b57cec5SDimitry Andric addUInt(Die, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Btr.Encoding); 171404eeddc0SDimitry Andric // Round up to smallest number of bytes that contains this number of bits. 1715bdd1243dSDimitry Andric addUInt(Die, dwarf::DW_AT_byte_size, std::nullopt, 1716bdd1243dSDimitry Andric divideCeil(Btr.BitSize, 8)); 17170b57cec5SDimitry Andric 17180b57cec5SDimitry Andric Btr.Die = &Die; 17190b57cec5SDimitry Andric } 17200b57cec5SDimitry Andric } 172106c3fb27SDimitry Andric 172206c3fb27SDimitry Andric DIE *DwarfCompileUnit::getLexicalBlockDIE(const DILexicalBlock *LB) { 172306c3fb27SDimitry Andric // Assume if there is an abstract tree all the DIEs are already emitted. 172406c3fb27SDimitry Andric bool isAbstract = getAbstractScopeDIEs().count(LB->getSubprogram()); 172506c3fb27SDimitry Andric if (isAbstract && getAbstractScopeDIEs().count(LB)) 172606c3fb27SDimitry Andric return getAbstractScopeDIEs()[LB]; 172706c3fb27SDimitry Andric assert(!isAbstract && "Missed lexical block DIE in abstract tree!"); 172806c3fb27SDimitry Andric 172906c3fb27SDimitry Andric // Return a concrete DIE if it exists or nullptr otherwise. 173006c3fb27SDimitry Andric return LexicalBlockDIEs.lookup(LB); 173106c3fb27SDimitry Andric } 173206c3fb27SDimitry Andric 173306c3fb27SDimitry Andric DIE *DwarfCompileUnit::getOrCreateContextDIE(const DIScope *Context) { 173406c3fb27SDimitry Andric if (isa_and_nonnull<DILocalScope>(Context)) { 173506c3fb27SDimitry Andric if (auto *LFScope = dyn_cast<DILexicalBlockFile>(Context)) 173606c3fb27SDimitry Andric Context = LFScope->getNonLexicalBlockFileScope(); 173706c3fb27SDimitry Andric if (auto *LScope = dyn_cast<DILexicalBlock>(Context)) 173806c3fb27SDimitry Andric return getLexicalBlockDIE(LScope); 173906c3fb27SDimitry Andric 174006c3fb27SDimitry Andric // Otherwise the context must be a DISubprogram. 174106c3fb27SDimitry Andric auto *SPScope = cast<DISubprogram>(Context); 174206c3fb27SDimitry Andric if (getAbstractScopeDIEs().count(SPScope)) 174306c3fb27SDimitry Andric return getAbstractScopeDIEs()[SPScope]; 174406c3fb27SDimitry Andric } 174506c3fb27SDimitry Andric return DwarfUnit::getOrCreateContextDIE(Context); 174606c3fb27SDimitry Andric } 1747