1855 lines · cpp
1//===- llvm/CodeGen/DwarfCompileUnit.cpp - Dwarf Compile Units ------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains support for constructing a dwarf compile unit.10//11//===----------------------------------------------------------------------===//12 13#include "DwarfCompileUnit.h"14#include "AddressPool.h"15#include "DwarfExpression.h"16#include "llvm/ADT/STLExtras.h"17#include "llvm/ADT/SmallString.h"18#include "llvm/BinaryFormat/Dwarf.h"19#include "llvm/CodeGen/AsmPrinter.h"20#include "llvm/CodeGen/DIE.h"21#include "llvm/CodeGen/MachineFunction.h"22#include "llvm/CodeGen/MachineInstr.h"23#include "llvm/CodeGen/TargetFrameLowering.h"24#include "llvm/CodeGen/TargetRegisterInfo.h"25#include "llvm/CodeGen/TargetSubtargetInfo.h"26#include "llvm/IR/DataLayout.h"27#include "llvm/IR/DebugInfo.h"28#include "llvm/IR/GlobalVariable.h"29#include "llvm/MC/MCAsmInfo.h"30#include "llvm/MC/MCSection.h"31#include "llvm/MC/MCStreamer.h"32#include "llvm/MC/MCSymbol.h"33#include "llvm/MC/MCSymbolWasm.h"34#include "llvm/MC/MachineLocation.h"35#include "llvm/Support/CommandLine.h"36#include "llvm/Support/NVPTXAddrSpace.h"37#include "llvm/Target/TargetLoweringObjectFile.h"38#include "llvm/Target/TargetMachine.h"39#include "llvm/Target/TargetOptions.h"40#include <optional>41#include <string>42#include <utility>43 44using namespace llvm;45 46/// Query value using AddLinkageNamesToDeclCallOriginsForTuning.47static cl::opt<cl::boolOrDefault> AddLinkageNamesToDeclCallOrigins(48 "add-linkage-names-to-declaration-call-origins", cl::Hidden,49 cl::desc("Add DW_AT_linkage_name to function declaration DIEs "50 "referenced by DW_AT_call_origin attributes. Enabled by default "51 "for -gsce debugger tuning."));52 53static cl::opt<bool> EmitFuncLineTableOffsetsOption(54 "emit-func-debug-line-table-offsets", cl::Hidden,55 cl::desc("Include line table offset in function's debug info and emit end "56 "sequence after each function's line data."),57 cl::init(false));58 59static bool AddLinkageNamesToDeclCallOriginsForTuning(const DwarfDebug *DD) {60 bool EnabledByDefault = DD->tuneForSCE();61 if (EnabledByDefault)62 return AddLinkageNamesToDeclCallOrigins != cl::boolOrDefault::BOU_FALSE;63 return AddLinkageNamesToDeclCallOrigins == cl::boolOrDefault::BOU_TRUE;64}65 66static dwarf::Tag GetCompileUnitType(UnitKind Kind, DwarfDebug *DW) {67 68 // According to DWARF Debugging Information Format Version 5,69 // 3.1.2 Skeleton Compilation Unit Entries:70 // "When generating a split DWARF object file (see Section 7.3.271 // on page 187), the compilation unit in the .debug_info section72 // is a "skeleton" compilation unit with the tag DW_TAG_skeleton_unit"73 if (DW->getDwarfVersion() >= 5 && Kind == UnitKind::Skeleton)74 return dwarf::DW_TAG_skeleton_unit;75 76 return dwarf::DW_TAG_compile_unit;77}78 79/// Translate NVVM IR address space code to DWARF correspondent value80static unsigned translateToNVVMDWARFAddrSpace(unsigned AddrSpace) {81 switch (AddrSpace) {82 case NVPTXAS::ADDRESS_SPACE_GENERIC:83 return NVPTXAS::DWARF_ADDR_generic_space;84 case NVPTXAS::ADDRESS_SPACE_GLOBAL:85 return NVPTXAS::DWARF_ADDR_global_space;86 case NVPTXAS::ADDRESS_SPACE_SHARED:87 return NVPTXAS::DWARF_ADDR_shared_space;88 case NVPTXAS::ADDRESS_SPACE_CONST:89 return NVPTXAS::DWARF_ADDR_const_space;90 case NVPTXAS::ADDRESS_SPACE_LOCAL:91 return NVPTXAS::DWARF_ADDR_local_space;92 default:93 llvm_unreachable(94 "Cannot translate unknown address space to DWARF address space");95 return AddrSpace;96 }97}98 99DwarfCompileUnit::DwarfCompileUnit(unsigned UID, const DICompileUnit *Node,100 AsmPrinter *A, DwarfDebug *DW,101 DwarfFile *DWU, UnitKind Kind)102 : DwarfUnit(GetCompileUnitType(Kind, DW), Node, A, DW, DWU, UID) {103 insertDIE(Node, &getUnitDie());104 MacroLabelBegin = Asm->createTempSymbol("cu_macro_begin");105}106 107/// addLabelAddress - Add a dwarf label attribute data and value using108/// DW_FORM_addr or DW_FORM_GNU_addr_index.109void DwarfCompileUnit::addLabelAddress(DIE &Die, dwarf::Attribute Attribute,110 const MCSymbol *Label) {111 if ((Skeleton || !DD->useSplitDwarf()) && Label)112 DD->addArangeLabel(SymbolCU(this, Label));113 114 // Don't use the address pool in non-fission or in the skeleton unit itself.115 if ((!DD->useSplitDwarf() || !Skeleton) && DD->getDwarfVersion() < 5)116 return addLocalLabelAddress(Die, Attribute, Label);117 118 bool UseAddrOffsetFormOrExpressions =119 DD->useAddrOffsetForm() || DD->useAddrOffsetExpressions();120 121 const MCSymbol *Base = nullptr;122 if (Label->isInSection() && UseAddrOffsetFormOrExpressions)123 Base = DD->getSectionLabel(&Label->getSection());124 125 if (!Base || Base == Label) {126 unsigned idx = DD->getAddressPool().getIndex(Label);127 addAttribute(Die, Attribute,128 DD->getDwarfVersion() >= 5 ? dwarf::DW_FORM_addrx129 : dwarf::DW_FORM_GNU_addr_index,130 DIEInteger(idx));131 return;132 }133 134 // Could be extended to work with DWARFv4 Split DWARF if that's important for135 // someone. In that case DW_FORM_data would be used.136 assert(DD->getDwarfVersion() >= 5 &&137 "Addr+offset expressions are only valuable when using debug_addr (to "138 "reduce relocations) available in DWARFv5 or higher");139 if (DD->useAddrOffsetExpressions()) {140 auto *Loc = new (DIEValueAllocator) DIEBlock();141 addPoolOpAddress(*Loc, Label);142 addBlock(Die, Attribute, dwarf::DW_FORM_exprloc, Loc);143 } else144 addAttribute(Die, Attribute, dwarf::DW_FORM_LLVM_addrx_offset,145 new (DIEValueAllocator) DIEAddrOffset(146 DD->getAddressPool().getIndex(Base), Label, Base));147}148 149void DwarfCompileUnit::addLocalLabelAddress(DIE &Die,150 dwarf::Attribute Attribute,151 const MCSymbol *Label) {152 if (Label)153 addAttribute(Die, Attribute, dwarf::DW_FORM_addr, DIELabel(Label));154 else155 addAttribute(Die, Attribute, dwarf::DW_FORM_addr, DIEInteger(0));156}157 158unsigned DwarfCompileUnit::getOrCreateSourceID(const DIFile *File) {159 // If we print assembly, we can't separate .file entries according to160 // compile units. Thus all files will belong to the default compile unit.161 162 // FIXME: add a better feature test than hasRawTextSupport. Even better,163 // extend .file to support this.164 unsigned CUID = Asm->OutStreamer->hasRawTextSupport() ? 0 : getUniqueID();165 if (!File)166 return Asm->OutStreamer->emitDwarfFileDirective(0, "", "", std::nullopt,167 std::nullopt, CUID);168 169 if (LastFile != File) {170 LastFile = File;171 LastFileID = Asm->OutStreamer->emitDwarfFileDirective(172 0, File->getDirectory(), File->getFilename(), DD->getMD5AsBytes(File),173 File->getSource(), CUID);174 }175 return LastFileID;176}177 178DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(179 const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) {180 // Check for pre-existence.181 if (DIE *Die = getDIE(GV))182 return Die;183 184 assert(GV);185 186 auto *GVContext = GV->getScope();187 const DIType *GTy = GV->getType();188 189 auto *CB = GVContext ? dyn_cast<DICommonBlock>(GVContext) : nullptr;190 DIE *ContextDIE = CB ? getOrCreateCommonBlock(CB, GlobalExprs)191 : getOrCreateContextDIE(GVContext);192 193 // Add to map.194 DIE *VariableDIE = &createAndAddDIE(GV->getTag(), *ContextDIE, GV);195 DIScope *DeclContext;196 if (auto *SDMDecl = GV->getStaticDataMemberDeclaration()) {197 DeclContext = SDMDecl->getScope();198 assert(SDMDecl->isStaticMember() && "Expected static member decl");199 assert(GV->isDefinition());200 // We need the declaration DIE that is in the static member's class.201 DIE *VariableSpecDIE = getOrCreateStaticMemberDIE(SDMDecl);202 addDIEEntry(*VariableDIE, dwarf::DW_AT_specification, *VariableSpecDIE);203 // If the global variable's type is different from the one in the class204 // member type, assume that it's more specific and also emit it.205 if (GTy != SDMDecl->getBaseType())206 addType(*VariableDIE, GTy);207 } else {208 DeclContext = GV->getScope();209 // Add name and type.210 StringRef DisplayName = GV->getDisplayName();211 if (!DisplayName.empty())212 addString(*VariableDIE, dwarf::DW_AT_name, GV->getDisplayName());213 if (GTy)214 addType(*VariableDIE, GTy);215 216 // Add scoping info.217 if (!GV->isLocalToUnit())218 addFlag(*VariableDIE, dwarf::DW_AT_external);219 220 // Add line number info.221 addSourceLine(*VariableDIE, GV);222 }223 224 if (!GV->isDefinition())225 addFlag(*VariableDIE, dwarf::DW_AT_declaration);226 else227 addGlobalName(GV->getName(), *VariableDIE, DeclContext);228 229 addAnnotation(*VariableDIE, GV->getAnnotations());230 231 if (uint32_t AlignInBytes = GV->getAlignInBytes())232 addUInt(*VariableDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,233 AlignInBytes);234 235 if (MDTuple *TP = GV->getTemplateParams())236 addTemplateParams(*VariableDIE, DINodeArray(TP));237 238 // Add location.239 addLocationAttribute(VariableDIE, GV, GlobalExprs);240 241 return VariableDIE;242}243 244void DwarfCompileUnit::addLocationAttribute(245 DIE *VariableDIE, const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) {246 bool addToAccelTable = false;247 DIELoc *Loc = nullptr;248 std::optional<unsigned> NVPTXAddressSpace;249 std::unique_ptr<DIEDwarfExpression> DwarfExpr;250 for (const auto &GE : GlobalExprs) {251 const GlobalVariable *Global = GE.Var;252 const DIExpression *Expr = GE.Expr;253 254 // For compatibility with DWARF 3 and earlier,255 // DW_AT_location(DW_OP_constu, X, DW_OP_stack_value) or256 // DW_AT_location(DW_OP_consts, X, DW_OP_stack_value) becomes257 // DW_AT_const_value(X).258 if (GlobalExprs.size() == 1 && Expr && Expr->isConstant()) {259 addToAccelTable = true;260 addConstantValue(261 *VariableDIE,262 DIExpression::SignedOrUnsignedConstant::UnsignedConstant ==263 *Expr->isConstant(),264 Expr->getElement(1));265 break;266 }267 268 // We cannot describe the location of dllimport'd variables: the269 // computation of their address requires loads from the IAT.270 if (Global && Global->hasDLLImportStorageClass())271 continue;272 273 // Nothing to describe without address or constant.274 if (!Global && (!Expr || !Expr->isConstant()))275 continue;276 277 if (Global && Global->isThreadLocal() &&278 !Asm->getObjFileLowering().supportDebugThreadLocalLocation())279 continue;280 281 if (!Loc) {282 addToAccelTable = true;283 Loc = new (DIEValueAllocator) DIELoc;284 DwarfExpr = std::make_unique<DIEDwarfExpression>(*Asm, *this, *Loc);285 }286 287 if (Expr) {288 // cuda-gdb special requirement. See NVPTXAS::DWARF_AddressSpace289 // Decode DW_OP_constu <DWARF Address Space> DW_OP_swap DW_OP_xderef290 // sequence to specify corresponding address space.291 if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {292 unsigned LocalNVPTXAddressSpace;293 const DIExpression *NewExpr =294 DIExpression::extractAddressClass(Expr, LocalNVPTXAddressSpace);295 if (NewExpr != Expr) {296 Expr = NewExpr;297 NVPTXAddressSpace = LocalNVPTXAddressSpace;298 }299 }300 DwarfExpr->addFragmentOffset(Expr);301 }302 303 if (Global) {304 const MCSymbol *Sym = Asm->getSymbol(Global);305 // 16-bit platforms like MSP430 and AVR take this path, so sink this306 // assert to platforms that use it.307 auto GetPointerSizedFormAndOp = [this]() {308 unsigned PointerSize = Asm->MAI->getCodePointerSize();309 assert((PointerSize == 4 || PointerSize == 8) &&310 "Add support for other sizes if necessary");311 struct FormAndOp {312 dwarf::Form Form;313 dwarf::LocationAtom Op;314 };315 return PointerSize == 4316 ? FormAndOp{dwarf::DW_FORM_data4, dwarf::DW_OP_const4u}317 : FormAndOp{dwarf::DW_FORM_data8, dwarf::DW_OP_const8u};318 };319 if (Global->isThreadLocal()) {320 if (Asm->TM.getTargetTriple().isWasm()) {321 // FIXME This is not guaranteed, but in practice, in static linking,322 // if present, __tls_base's index is 1. This doesn't hold for dynamic323 // linking, so TLS variables used in dynamic linking won't have324 // correct debug info for now. See325 // https://github.com/llvm/llvm-project/blob/19afbfe33156d211fa959dadeea46cd17b9c723c/lld/wasm/Driver.cpp#L786-L823326 addWasmRelocBaseGlobal(Loc, "__tls_base", 1);327 addOpAddress(*Loc, Sym);328 addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);329 } else if (Asm->TM.useEmulatedTLS()) {330 // TODO: add debug info for emulated thread local mode.331 } else {332 // FIXME: Make this work with -gsplit-dwarf.333 // Based on GCC's support for TLS:334 if (!DD->useSplitDwarf()) {335 auto FormAndOp = GetPointerSizedFormAndOp();336 // 1) Start with a constNu of the appropriate pointer size337 addUInt(*Loc, dwarf::DW_FORM_data1, FormAndOp.Op);338 // 2) containing the (relocated) offset of the TLS variable339 // within the module's TLS block.340 addExpr(*Loc, FormAndOp.Form,341 Asm->getObjFileLowering().getDebugThreadLocalSymbol(Sym));342 } else {343 addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index);344 addUInt(*Loc, dwarf::DW_FORM_udata,345 DD->getAddressPool().getIndex(Sym, /* TLS */ true));346 }347 // 3) followed by an OP to make the debugger do a TLS lookup.348 addUInt(*Loc, dwarf::DW_FORM_data1,349 DD->useGNUTLSOpcode() ? dwarf::DW_OP_GNU_push_tls_address350 : dwarf::DW_OP_form_tls_address);351 }352 } else if (Asm->TM.getTargetTriple().isWasm() &&353 Asm->TM.getRelocationModel() == Reloc::PIC_) {354 // FIXME This is not guaranteed, but in practice, if present,355 // __memory_base's index is 1. See356 // https://github.com/llvm/llvm-project/blob/19afbfe33156d211fa959dadeea46cd17b9c723c/lld/wasm/Driver.cpp#L786-L823357 addWasmRelocBaseGlobal(Loc, "__memory_base", 1);358 addOpAddress(*Loc, Sym);359 addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);360 } else if ((Asm->TM.getRelocationModel() == Reloc::RWPI ||361 Asm->TM.getRelocationModel() == Reloc::ROPI_RWPI) &&362 !Asm->getObjFileLowering()363 .getKindForGlobal(Global, Asm->TM)364 .isReadOnly()) {365 auto FormAndOp = GetPointerSizedFormAndOp();366 // Constant367 addUInt(*Loc, dwarf::DW_FORM_data1, FormAndOp.Op);368 // Relocation offset369 addExpr(*Loc, FormAndOp.Form,370 Asm->getObjFileLowering().getIndirectSymViaRWPI(Sym));371 // Base register372 Register BaseReg = Asm->getObjFileLowering().getStaticBase();373 unsigned DwarfBaseReg =374 Asm->TM.getMCRegisterInfo()->getDwarfRegNum(BaseReg, false);375 addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + DwarfBaseReg);376 // Offset from base register377 addSInt(*Loc, dwarf::DW_FORM_sdata, 0);378 // Operation379 addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);380 } else {381 DD->addArangeLabel(SymbolCU(this, Sym));382 addOpAddress(*Loc, Sym);383 }384 if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB() &&385 !NVPTXAddressSpace)386 NVPTXAddressSpace =387 translateToNVVMDWARFAddrSpace(Global->getType()->getAddressSpace());388 }389 // Global variables attached to symbols are memory locations.390 // It would be better if this were unconditional, but malformed input that391 // mixes non-fragments and fragments for the same variable is too expensive392 // to detect in the verifier.393 if (DwarfExpr->isUnknownLocation())394 DwarfExpr->setMemoryLocationKind();395 DwarfExpr->addExpression(Expr);396 }397 if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {398 // cuda-gdb special requirement. See NVPTXAS::DWARF_AddressSpace399 addUInt(*VariableDIE, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1,400 NVPTXAddressSpace.value_or(NVPTXAS::DWARF_ADDR_global_space));401 }402 if (Loc)403 addBlock(*VariableDIE, dwarf::DW_AT_location, DwarfExpr->finalize());404 405 if (DD->useAllLinkageNames())406 addLinkageName(*VariableDIE, GV->getLinkageName());407 408 if (addToAccelTable) {409 DD->addAccelName(*this, CUNode->getNameTableKind(), GV->getName(),410 *VariableDIE);411 412 // If the linkage name is different than the name, go ahead and output413 // that as well into the name table.414 if (GV->getLinkageName() != "" && GV->getName() != GV->getLinkageName() &&415 DD->useAllLinkageNames())416 DD->addAccelName(*this, CUNode->getNameTableKind(), GV->getLinkageName(),417 *VariableDIE);418 }419}420 421DIE *DwarfCompileUnit::getOrCreateCommonBlock(422 const DICommonBlock *CB, ArrayRef<GlobalExpr> GlobalExprs) {423 // Check for pre-existence.424 if (DIE *NDie = getDIE(CB))425 return NDie;426 DIE *ContextDIE = getOrCreateContextDIE(CB->getScope());427 DIE &NDie = createAndAddDIE(dwarf::DW_TAG_common_block, *ContextDIE, CB);428 StringRef Name = CB->getName().empty() ? "_BLNK_" : CB->getName();429 addString(NDie, dwarf::DW_AT_name, Name);430 addGlobalName(Name, NDie, CB->getScope());431 if (CB->getFile())432 addSourceLine(NDie, CB->getLineNo(), /*Column*/ 0, CB->getFile());433 if (DIGlobalVariable *V = CB->getDecl())434 getCU().addLocationAttribute(&NDie, V, GlobalExprs);435 return &NDie;436}437 438void DwarfCompileUnit::addRange(RangeSpan Range) {439 DD->insertSectionLabel(Range.Begin);440 441 auto *PrevCU = DD->getPrevCU();442 bool SameAsPrevCU = this == PrevCU;443 DD->setPrevCU(this);444 // If we have no current ranges just add the range and return, otherwise,445 // check the current section and CU against the previous section and CU we446 // emitted into and the subprogram was contained within. If these are the447 // same then extend our current range, otherwise add this as a new range.448 if (CURanges.empty() || !SameAsPrevCU ||449 (&CURanges.back().End->getSection() !=450 &Range.End->getSection())) {451 // Before a new range is added, always terminate the prior line table.452 if (PrevCU)453 DD->terminateLineTable(PrevCU);454 CURanges.push_back(Range);455 return;456 }457 458 CURanges.back().End = Range.End;459}460 461void DwarfCompileUnit::initStmtList() {462 if (CUNode->isDebugDirectivesOnly())463 return;464 465 const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();466 if (DD->useSectionsAsReferences()) {467 LineTableStartSym = TLOF.getDwarfLineSection()->getBeginSymbol();468 } else {469 LineTableStartSym =470 Asm->OutStreamer->getDwarfLineTableSymbol(getUniqueID());471 }472 473 // DW_AT_stmt_list is a offset of line number information for this474 // compile unit in debug_line section. For split dwarf this is475 // left in the skeleton CU and so not included.476 // The line table entries are not always emitted in assembly, so it477 // is not okay to use line_table_start here.478 addSectionLabel(getUnitDie(), dwarf::DW_AT_stmt_list, LineTableStartSym,479 TLOF.getDwarfLineSection()->getBeginSymbol());480}481 482void DwarfCompileUnit::applyStmtList(DIE &D) {483 const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();484 addSectionLabel(D, dwarf::DW_AT_stmt_list, LineTableStartSym,485 TLOF.getDwarfLineSection()->getBeginSymbol());486}487 488void DwarfCompileUnit::attachLowHighPC(DIE &D, const MCSymbol *Begin,489 const MCSymbol *End) {490 assert(Begin && "Begin label should not be null!");491 assert(End && "End label should not be null!");492 assert(Begin->isDefined() && "Invalid starting label");493 assert(End->isDefined() && "Invalid end label");494 495 addLabelAddress(D, dwarf::DW_AT_low_pc, Begin);496 if (DD->getDwarfVersion() >= 4 &&497 (!isDwoUnit() || !llvm::isRangeRelaxable(Begin, End))) {498 addLabelDelta(D, dwarf::DW_AT_high_pc, End, Begin);499 return;500 }501 addLabelAddress(D, dwarf::DW_AT_high_pc, End);502}503 504// Add info for Wasm-global-based relocation.505// 'GlobalIndex' is used for split dwarf, which currently relies on a few506// assumptions that are not guaranteed in a formal way but work in practice.507void DwarfCompileUnit::addWasmRelocBaseGlobal(DIELoc *Loc, StringRef GlobalName,508 uint64_t GlobalIndex) {509 // FIXME: duplicated from Target/WebAssembly/WebAssembly.h510 // don't want to depend on target specific headers in this code?511 const unsigned TI_GLOBAL_RELOC = 3;512 unsigned PointerSize = Asm->getDataLayout().getPointerSize();513 auto *Sym =514 static_cast<MCSymbolWasm *>(Asm->GetExternalSymbolSymbol(GlobalName));515 // FIXME: this repeats what WebAssemblyMCInstLower::516 // GetExternalSymbolSymbol does, since if there's no code that517 // refers to this symbol, we have to set it here.518 Sym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);519 Sym->setGlobalType(wasm::WasmGlobalType{520 static_cast<uint8_t>(PointerSize == 4 ? wasm::WASM_TYPE_I32521 : wasm::WASM_TYPE_I64),522 true});523 addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_WASM_location);524 addSInt(*Loc, dwarf::DW_FORM_sdata, TI_GLOBAL_RELOC);525 if (!isDwoUnit()) {526 addLabel(*Loc, dwarf::DW_FORM_data4, Sym);527 } else {528 // FIXME: when writing dwo, we need to avoid relocations. Probably529 // the "right" solution is to treat globals the way func and data530 // symbols are (with entries in .debug_addr).531 // For now we hardcode the indices in the callsites. Global indices are not532 // fixed, but in practice a few are fixed; for example, __stack_pointer is533 // always index 0.534 addUInt(*Loc, dwarf::DW_FORM_data4, GlobalIndex);535 }536}537 538// Find DIE for the given subprogram and attach appropriate DW_AT_low_pc539// and DW_AT_high_pc attributes. If there are global variables in this540// scope then create and insert DIEs for these variables.541DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP,542 const Function &F,543 MCSymbol *LineTableSym) {544 DIE *SPDie = getOrCreateSubprogramDIE(SP, &F, includeMinimalInlineScopes());545 SmallVector<RangeSpan, 2> BB_List;546 // If basic block sections are on, ranges for each basic block section has547 // to be emitted separately.548 for (const auto &R : Asm->MBBSectionRanges)549 BB_List.push_back({R.second.BeginLabel, R.second.EndLabel});550 551 attachRangesOrLowHighPC(*SPDie, BB_List);552 553 if (DD->useAppleExtensionAttributes() &&554 !DD->getCurrentFunction()->getTarget().Options.DisableFramePointerElim(555 *DD->getCurrentFunction()))556 addFlag(*SPDie, dwarf::DW_AT_APPLE_omit_frame_ptr);557 558 if (emitFuncLineTableOffsets() && LineTableSym) {559 addSectionLabel(560 *SPDie, dwarf::DW_AT_LLVM_stmt_sequence, LineTableSym,561 Asm->getObjFileLowering().getDwarfLineSection()->getBeginSymbol());562 }563 564 // Only include DW_AT_frame_base in full debug info565 if (!includeMinimalInlineScopes()) {566 const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();567 TargetFrameLowering::DwarfFrameBase FrameBase =568 TFI->getDwarfFrameBase(*Asm->MF);569 switch (FrameBase.Kind) {570 case TargetFrameLowering::DwarfFrameBase::Register: {571 if (Register::isPhysicalRegister(FrameBase.Location.Reg)) {572 MachineLocation Location(FrameBase.Location.Reg);573 addAddress(*SPDie, dwarf::DW_AT_frame_base, Location);574 }575 break;576 }577 case TargetFrameLowering::DwarfFrameBase::CFA: {578 DIELoc *Loc = new (DIEValueAllocator) DIELoc;579 addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_call_frame_cfa);580 if (FrameBase.Location.Offset != 0) {581 addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_consts);582 addSInt(*Loc, dwarf::DW_FORM_sdata, FrameBase.Location.Offset);583 addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);584 }585 addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc);586 break;587 }588 case TargetFrameLowering::DwarfFrameBase::WasmFrameBase: {589 // FIXME: duplicated from Target/WebAssembly/WebAssembly.h590 const unsigned TI_GLOBAL_RELOC = 3;591 if (FrameBase.Location.WasmLoc.Kind == TI_GLOBAL_RELOC) {592 // These need to be relocatable.593 DIELoc *Loc = new (DIEValueAllocator) DIELoc;594 assert(FrameBase.Location.WasmLoc.Index == 0); // Only SP so far.595 // For now, since we only ever use index 0, this should work as-is.596 addWasmRelocBaseGlobal(Loc, "__stack_pointer",597 FrameBase.Location.WasmLoc.Index);598 addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value);599 addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc);600 } else {601 DIELoc *Loc = new (DIEValueAllocator) DIELoc;602 DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);603 DIExpressionCursor Cursor({});604 DwarfExpr.addWasmLocation(FrameBase.Location.WasmLoc.Kind,605 FrameBase.Location.WasmLoc.Index);606 DwarfExpr.addExpression(std::move(Cursor));607 addBlock(*SPDie, dwarf::DW_AT_frame_base, DwarfExpr.finalize());608 }609 break;610 }611 }612 }613 614 // Add name to the name table, we do this here because we're guaranteed615 // to have concrete versions of our DW_TAG_subprogram nodes.616 DD->addSubprogramNames(*this, CUNode->getNameTableKind(), SP, *SPDie);617 618 return *SPDie;619}620 621// Construct a DIE for this scope.622void DwarfCompileUnit::constructScopeDIE(LexicalScope *Scope,623 DIE &ParentScopeDIE) {624 if (!Scope || !Scope->getScopeNode())625 return;626 627 auto *DS = Scope->getScopeNode();628 629 assert((Scope->getInlinedAt() || !isa<DISubprogram>(DS)) &&630 "Only handle inlined subprograms here, use "631 "constructSubprogramScopeDIE for non-inlined "632 "subprograms");633 634 // Emit inlined subprograms.635 if (Scope->getParent() && isa<DISubprogram>(DS)) {636 DIE *ScopeDIE = constructInlinedScopeDIE(Scope, ParentScopeDIE);637 assert(ScopeDIE && "Scope DIE should not be null.");638 createAndAddScopeChildren(Scope, *ScopeDIE);639 return;640 }641 642 // Early exit when we know the scope DIE is going to be null.643 if (DD->isLexicalScopeDIENull(Scope))644 return;645 646 // Emit lexical blocks.647 DIE *ScopeDIE = constructLexicalScopeDIE(Scope);648 assert(ScopeDIE && "Scope DIE should not be null.");649 650 ParentScopeDIE.addChild(ScopeDIE);651 createAndAddScopeChildren(Scope, *ScopeDIE);652}653 654void DwarfCompileUnit::addScopeRangeList(DIE &ScopeDIE,655 SmallVector<RangeSpan, 2> Range) {656 657 HasRangeLists = true;658 659 // Add the range list to the set of ranges to be emitted.660 auto IndexAndList =661 (DD->getDwarfVersion() < 5 && Skeleton ? Skeleton->DU : DU)662 ->addRange(*(Skeleton ? Skeleton : this), std::move(Range));663 664 uint32_t Index = IndexAndList.first;665 auto &List = *IndexAndList.second;666 667 // Under fission, ranges are specified by constant offsets relative to the668 // CU's DW_AT_GNU_ranges_base.669 // FIXME: For DWARF v5, do not generate the DW_AT_ranges attribute under670 // fission until we support the forms using the .debug_addr section671 // (DW_RLE_startx_endx etc.).672 if (DD->getDwarfVersion() >= 5)673 addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_rnglistx, Index);674 else {675 const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();676 const MCSymbol *RangeSectionSym =677 TLOF.getDwarfRangesSection()->getBeginSymbol();678 if (isDwoUnit())679 addSectionDelta(ScopeDIE, dwarf::DW_AT_ranges, List.Label,680 RangeSectionSym);681 else682 addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges, List.Label,683 RangeSectionSym);684 }685}686 687void DwarfCompileUnit::attachRangesOrLowHighPC(688 DIE &Die, SmallVector<RangeSpan, 2> Ranges) {689 assert(!Ranges.empty());690 if (!DD->useRangesSection() ||691 (Ranges.size() == 1 &&692 (!DD->alwaysUseRanges(*this) ||693 DD->getSectionLabel(&Ranges.front().Begin->getSection()) ==694 Ranges.front().Begin))) {695 const RangeSpan &Front = Ranges.front();696 const RangeSpan &Back = Ranges.back();697 attachLowHighPC(Die, Front.Begin, Back.End);698 } else699 addScopeRangeList(Die, std::move(Ranges));700}701 702void DwarfCompileUnit::attachRangesOrLowHighPC(703 DIE &Die, const SmallVectorImpl<InsnRange> &Ranges) {704 SmallVector<RangeSpan, 2> List;705 List.reserve(Ranges.size());706 for (const InsnRange &R : Ranges) {707 auto *BeginLabel = DD->getLabelBeforeInsn(R.first);708 auto *EndLabel = DD->getLabelAfterInsn(R.second);709 710 const auto *BeginMBB = R.first->getParent();711 const auto *EndMBB = R.second->getParent();712 713 const auto *MBB = BeginMBB;714 // Basic block sections allows basic block subsets to be placed in unique715 // sections. For each section, the begin and end label must be added to the716 // list. If there is more than one range, debug ranges must be used.717 // Otherwise, low/high PC can be used.718 // FIXME: Debug Info Emission depends on block order and this assumes that719 // the order of blocks will be frozen beyond this point.720 do {721 if (MBB->sameSection(EndMBB) || MBB->isEndSection()) {722 auto MBBSectionRange = Asm->MBBSectionRanges[MBB->getSectionID()];723 List.push_back(724 {MBB->sameSection(BeginMBB) ? BeginLabel725 : MBBSectionRange.BeginLabel,726 MBB->sameSection(EndMBB) ? EndLabel : MBBSectionRange.EndLabel});727 }728 if (MBB->sameSection(EndMBB))729 break;730 MBB = MBB->getNextNode();731 } while (true);732 }733 attachRangesOrLowHighPC(Die, std::move(List));734}735 736DIE *DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope,737 DIE &ParentScopeDIE) {738 assert(Scope->getScopeNode());739 auto *DS = Scope->getScopeNode();740 auto *InlinedSP = getDISubprogram(DS);741 // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram742 // was inlined from another compile unit.743 DIE *OriginDIE = getAbstractScopeDIEs()[InlinedSP];744 assert(OriginDIE && "Unable to find original DIE for an inlined subprogram.");745 746 auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_inlined_subroutine);747 ParentScopeDIE.addChild(ScopeDIE);748 addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *OriginDIE);749 750 attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges());751 752 // Add the call site information to the DIE.753 const DILocation *IA = Scope->getInlinedAt();754 addUInt(*ScopeDIE, dwarf::DW_AT_call_file, std::nullopt,755 getOrCreateSourceID(IA->getFile()));756 addUInt(*ScopeDIE, dwarf::DW_AT_call_line, std::nullopt, IA->getLine());757 if (IA->getColumn())758 addUInt(*ScopeDIE, dwarf::DW_AT_call_column, std::nullopt, IA->getColumn());759 if (IA->getDiscriminator() && DD->getDwarfVersion() >= 4)760 addUInt(*ScopeDIE, dwarf::DW_AT_GNU_discriminator, std::nullopt,761 IA->getDiscriminator());762 763 // Add name to the name table, we do this here because we're guaranteed764 // to have concrete versions of our DW_TAG_inlined_subprogram nodes.765 DD->addSubprogramNames(*this, CUNode->getNameTableKind(), InlinedSP,766 *ScopeDIE);767 768 return ScopeDIE;769}770 771// Construct new DW_TAG_lexical_block for this scope and attach772// DW_AT_low_pc/DW_AT_high_pc labels.773DIE *DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) {774 if (DD->isLexicalScopeDIENull(Scope))775 return nullptr;776 const auto *DS = Scope->getScopeNode();777 778 auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_lexical_block);779 if (Scope->isAbstractScope()) {780 assert(!getAbstractScopeDIEs().count(DS) &&781 "Abstract DIE for this scope exists!");782 getAbstractScopeDIEs()[DS] = ScopeDIE;783 return ScopeDIE;784 }785 if (!Scope->getInlinedAt()) {786 assert(!LexicalBlockDIEs.count(DS) &&787 "Concrete out-of-line DIE for this scope exists!");788 LexicalBlockDIEs[DS] = ScopeDIE;789 } else {790 InlinedLocalScopeDIEs[DS].push_back(ScopeDIE);791 }792 793 attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges());794 795 return ScopeDIE;796}797 798DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, bool Abstract) {799 auto *VariableDie = DIE::get(DIEValueAllocator, DV.getTag());800 insertDIE(DV.getVariable(), VariableDie);801 DV.setDIE(*VariableDie);802 // Abstract variables don't get common attributes later, so apply them now.803 if (Abstract) {804 applyCommonDbgVariableAttributes(DV, *VariableDie);805 } else {806 std::visit(807 [&](const auto &V) {808 applyConcreteDbgVariableAttributes(V, DV, *VariableDie);809 },810 DV.asVariant());811 }812 return VariableDie;813}814 815void DwarfCompileUnit::applyConcreteDbgVariableAttributes(816 const Loc::Single &Single, const DbgVariable &DV, DIE &VariableDie) {817 const DbgValueLoc *DVal = &Single.getValueLoc();818 if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB() &&819 !Single.getExpr()) {820 // cuda-gdb special requirement. See NVPTXAS::DWARF_AddressSpace821 // Lack of expression means it is a register.822 addUInt(VariableDie, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1,823 NVPTXAS::DWARF_ADDR_reg_space);824 }825 if (!DVal->isVariadic()) {826 const DbgValueLocEntry *Entry = DVal->getLocEntries().begin();827 if (Entry->isLocation()) {828 addVariableAddress(DV, VariableDie, Entry->getLoc());829 } else if (Entry->isInt()) {830 auto *Expr = Single.getExpr();831 if (Expr && Expr->getNumElements()) {832 DIELoc *Loc = new (DIEValueAllocator) DIELoc;833 DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);834 // If there is an expression, emit raw unsigned bytes.835 DwarfExpr.addFragmentOffset(Expr);836 DwarfExpr.addUnsignedConstant(Entry->getInt());837 DwarfExpr.addExpression(Expr);838 addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());839 if (DwarfExpr.TagOffset)840 addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset,841 dwarf::DW_FORM_data1, *DwarfExpr.TagOffset);842 } else843 addConstantValue(VariableDie, Entry->getInt(), DV.getType());844 } else if (Entry->isConstantFP()) {845 addConstantFPValue(VariableDie, Entry->getConstantFP());846 } else if (Entry->isConstantInt()) {847 addConstantValue(VariableDie, Entry->getConstantInt(), DV.getType());848 } else if (Entry->isTargetIndexLocation()) {849 DIELoc *Loc = new (DIEValueAllocator) DIELoc;850 DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);851 const DIBasicType *BT = dyn_cast<DIBasicType>(852 static_cast<const Metadata *>(DV.getVariable()->getType()));853 DwarfDebug::emitDebugLocValue(*Asm, BT, *DVal, DwarfExpr);854 addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());855 }856 return;857 }858 // If any of the location entries are registers with the value 0,859 // then the location is undefined.860 if (any_of(DVal->getLocEntries(), [](const DbgValueLocEntry &Entry) {861 return Entry.isLocation() && !Entry.getLoc().getReg();862 }))863 return;864 const DIExpression *Expr = Single.getExpr();865 assert(Expr && "Variadic Debug Value must have an Expression.");866 DIELoc *Loc = new (DIEValueAllocator) DIELoc;867 DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);868 DwarfExpr.addFragmentOffset(Expr);869 DIExpressionCursor Cursor(Expr);870 const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();871 872 auto AddEntry = [&](const DbgValueLocEntry &Entry,873 DIExpressionCursor &Cursor) {874 if (Entry.isLocation()) {875 if (!DwarfExpr.addMachineRegExpression(TRI, Cursor,876 Entry.getLoc().getReg()))877 return false;878 } else if (Entry.isInt()) {879 // If there is an expression, emit raw unsigned bytes.880 DwarfExpr.addUnsignedConstant(Entry.getInt());881 } else if (Entry.isConstantFP()) {882 // DwarfExpression does not support arguments wider than 64 bits883 // (see PR52584).884 // TODO: Consider chunking expressions containing overly wide885 // arguments into separate pointer-sized fragment expressions.886 APInt RawBytes = Entry.getConstantFP()->getValueAPF().bitcastToAPInt();887 if (RawBytes.getBitWidth() > 64)888 return false;889 DwarfExpr.addUnsignedConstant(RawBytes.getZExtValue());890 } else if (Entry.isConstantInt()) {891 APInt RawBytes = Entry.getConstantInt()->getValue();892 if (RawBytes.getBitWidth() > 64)893 return false;894 DwarfExpr.addUnsignedConstant(RawBytes.getZExtValue());895 } else if (Entry.isTargetIndexLocation()) {896 TargetIndexLocation Loc = Entry.getTargetIndexLocation();897 // TODO TargetIndexLocation is a target-independent. Currently898 // only the WebAssembly-specific encoding is supported.899 assert(Asm->TM.getTargetTriple().isWasm());900 DwarfExpr.addWasmLocation(Loc.Index, static_cast<uint64_t>(Loc.Offset));901 } else {902 llvm_unreachable("Unsupported Entry type.");903 }904 return true;905 };906 907 if (!DwarfExpr.addExpression(908 std::move(Cursor),909 [&](unsigned Idx, DIExpressionCursor &Cursor) -> bool {910 return AddEntry(DVal->getLocEntries()[Idx], Cursor);911 }))912 return;913 914 // Now attach the location information to the DIE.915 addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());916 if (DwarfExpr.TagOffset)917 addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,918 *DwarfExpr.TagOffset);919}920 921void DwarfCompileUnit::applyConcreteDbgVariableAttributes(922 const Loc::Multi &Multi, const DbgVariable &DV, DIE &VariableDie) {923 addLocationList(VariableDie, dwarf::DW_AT_location,924 Multi.getDebugLocListIndex());925 auto TagOffset = Multi.getDebugLocListTagOffset();926 if (TagOffset)927 addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,928 *TagOffset);929}930 931void DwarfCompileUnit::applyConcreteDbgVariableAttributes(const Loc::MMI &MMI,932 const DbgVariable &DV,933 DIE &VariableDie) {934 std::optional<unsigned> NVPTXAddressSpace;935 DIELoc *Loc = new (DIEValueAllocator) DIELoc;936 DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);937 for (const auto &Fragment : MMI.getFrameIndexExprs()) {938 Register FrameReg;939 const DIExpression *Expr = Fragment.Expr;940 const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();941 StackOffset Offset =942 TFI->getFrameIndexReference(*Asm->MF, Fragment.FI, FrameReg);943 DwarfExpr.addFragmentOffset(Expr);944 945 auto *TRI = Asm->MF->getSubtarget().getRegisterInfo();946 SmallVector<uint64_t, 8> Ops;947 TRI->getOffsetOpcodes(Offset, Ops);948 949 // cuda-gdb special requirement. See NVPTXAS::DWARF_AddressSpace.950 // Decode DW_OP_constu <DWARF Address Space> DW_OP_swap951 // DW_OP_xderef sequence to specify address space.952 if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {953 unsigned LocalNVPTXAddressSpace;954 const DIExpression *NewExpr =955 DIExpression::extractAddressClass(Expr, LocalNVPTXAddressSpace);956 if (NewExpr != Expr) {957 Expr = NewExpr;958 NVPTXAddressSpace = LocalNVPTXAddressSpace;959 }960 }961 if (Expr)962 Ops.append(Expr->elements_begin(), Expr->elements_end());963 DIExpressionCursor Cursor(Ops);964 DwarfExpr.setMemoryLocationKind();965 if (const MCSymbol *FrameSymbol = Asm->getFunctionFrameSymbol())966 addOpAddress(*Loc, FrameSymbol);967 else968 DwarfExpr.addMachineRegExpression(969 *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, FrameReg);970 DwarfExpr.addExpression(std::move(Cursor));971 }972 if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {973 // cuda-gdb special requirement. See NVPTXAS::DWARF_AddressSpace.974 addUInt(VariableDie, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1,975 NVPTXAddressSpace.value_or(NVPTXAS::DWARF_ADDR_local_space));976 }977 addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());978 if (DwarfExpr.TagOffset)979 addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,980 *DwarfExpr.TagOffset);981}982 983void DwarfCompileUnit::applyConcreteDbgVariableAttributes(984 const Loc::EntryValue &EntryValue, const DbgVariable &DV,985 DIE &VariableDie) {986 DIELoc *Loc = new (DIEValueAllocator) DIELoc;987 DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);988 // Emit each expression as: EntryValue(Register) <other ops> <Fragment>.989 for (auto [Register, Expr] : EntryValue.EntryValues) {990 DwarfExpr.addFragmentOffset(&Expr);991 DIExpressionCursor Cursor(Expr.getElements());992 DwarfExpr.beginEntryValueExpression(Cursor);993 DwarfExpr.addMachineRegExpression(994 *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, Register);995 DwarfExpr.addExpression(std::move(Cursor));996 }997 addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());998}999 1000void DwarfCompileUnit::applyConcreteDbgVariableAttributes(1001 const std::monostate &, const DbgVariable &DV, DIE &VariableDie) {}1002 1003DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV,1004 const LexicalScope &Scope,1005 DIE *&ObjectPointer) {1006 auto Var = constructVariableDIE(DV, Scope.isAbstractScope());1007 if (DV.isObjectPointer())1008 ObjectPointer = Var;1009 return Var;1010}1011 1012DIE *DwarfCompileUnit::constructLabelDIE(DbgLabel &DL,1013 const LexicalScope &Scope) {1014 auto LabelDie = DIE::get(DIEValueAllocator, DL.getTag());1015 insertDIE(DL.getLabel(), LabelDie);1016 DL.setDIE(*LabelDie);1017 1018 if (Scope.isAbstractScope())1019 applyLabelAttributes(DL, *LabelDie);1020 1021 return LabelDie;1022}1023 1024/// Return all DIVariables that appear in count: expressions.1025static SmallVector<const DIVariable *, 2> dependencies(DbgVariable *Var) {1026 SmallVector<const DIVariable *, 2> Result;1027 auto *Array = dyn_cast<DICompositeType>(Var->getType());1028 if (!Array || Array->getTag() != dwarf::DW_TAG_array_type)1029 return Result;1030 if (auto *DLVar = Array->getDataLocation())1031 Result.push_back(DLVar);1032 if (auto *AsVar = Array->getAssociated())1033 Result.push_back(AsVar);1034 if (auto *AlVar = Array->getAllocated())1035 Result.push_back(AlVar);1036 for (auto *El : Array->getElements()) {1037 if (auto *Subrange = dyn_cast<DISubrange>(El)) {1038 if (auto Count = Subrange->getCount())1039 if (auto *Dependency = dyn_cast_if_present<DIVariable *>(Count))1040 Result.push_back(Dependency);1041 if (auto LB = Subrange->getLowerBound())1042 if (auto *Dependency = dyn_cast_if_present<DIVariable *>(LB))1043 Result.push_back(Dependency);1044 if (auto UB = Subrange->getUpperBound())1045 if (auto *Dependency = dyn_cast_if_present<DIVariable *>(UB))1046 Result.push_back(Dependency);1047 if (auto ST = Subrange->getStride())1048 if (auto *Dependency = dyn_cast_if_present<DIVariable *>(ST))1049 Result.push_back(Dependency);1050 } else if (auto *GenericSubrange = dyn_cast<DIGenericSubrange>(El)) {1051 if (auto Count = GenericSubrange->getCount())1052 if (auto *Dependency = dyn_cast_if_present<DIVariable *>(Count))1053 Result.push_back(Dependency);1054 if (auto LB = GenericSubrange->getLowerBound())1055 if (auto *Dependency = dyn_cast_if_present<DIVariable *>(LB))1056 Result.push_back(Dependency);1057 if (auto UB = GenericSubrange->getUpperBound())1058 if (auto *Dependency = dyn_cast_if_present<DIVariable *>(UB))1059 Result.push_back(Dependency);1060 if (auto ST = GenericSubrange->getStride())1061 if (auto *Dependency = dyn_cast_if_present<DIVariable *>(ST))1062 Result.push_back(Dependency);1063 }1064 }1065 return Result;1066}1067 1068/// Sort local variables so that variables appearing inside of helper1069/// expressions come first.1070static SmallVector<DbgVariable *, 8>1071sortLocalVars(SmallVectorImpl<DbgVariable *> &Input) {1072 SmallVector<DbgVariable *, 8> Result;1073 SmallVector<PointerIntPair<DbgVariable *, 1>, 8> WorkList;1074 // Map back from a DIVariable to its containing DbgVariable.1075 SmallDenseMap<const DILocalVariable *, DbgVariable *> DbgVar;1076 // Set of DbgVariables in Result.1077 SmallDenseSet<DbgVariable *, 8> Visited;1078 // For cycle detection.1079 SmallDenseSet<DbgVariable *, 8> Visiting;1080 1081 // Initialize the worklist and the DIVariable lookup table.1082 for (auto *Var : reverse(Input)) {1083 DbgVar.insert({Var->getVariable(), Var});1084 WorkList.push_back({Var, 0});1085 }1086 1087 // Perform a stable topological sort by doing a DFS.1088 while (!WorkList.empty()) {1089 auto Item = WorkList.back();1090 DbgVariable *Var = Item.getPointer();1091 bool visitedAllDependencies = Item.getInt();1092 WorkList.pop_back();1093 1094 assert(Var);1095 1096 // Already handled.1097 if (Visited.count(Var))1098 continue;1099 1100 // Add to Result if all dependencies are visited.1101 if (visitedAllDependencies) {1102 Visited.insert(Var);1103 Result.push_back(Var);1104 continue;1105 }1106 1107 // Detect cycles.1108 auto Res = Visiting.insert(Var);1109 if (!Res.second) {1110 assert(false && "dependency cycle in local variables");1111 return Result;1112 }1113 1114 // Push dependencies and this node onto the worklist, so that this node is1115 // visited again after all of its dependencies are handled.1116 WorkList.push_back({Var, 1});1117 for (const auto *Dependency : dependencies(Var)) {1118 // Don't add dependency if it is in a different lexical scope or a global.1119 if (const auto *Dep = dyn_cast<const DILocalVariable>(Dependency))1120 if (DbgVariable *Var = DbgVar.lookup(Dep))1121 WorkList.push_back({Var, 0});1122 }1123 }1124 return Result;1125}1126 1127DIE &DwarfCompileUnit::constructSubprogramScopeDIE(const DISubprogram *Sub,1128 const Function &F,1129 LexicalScope *Scope,1130 MCSymbol *LineTableSym) {1131 DIE &ScopeDIE = updateSubprogramScopeDIE(Sub, F, LineTableSym);1132 1133 if (Scope) {1134 assert(!Scope->getInlinedAt());1135 assert(!Scope->isAbstractScope());1136 // Collect lexical scope children first.1137 // ObjectPointer might be a local (non-argument) local variable if it's a1138 // block's synthetic this pointer.1139 if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, ScopeDIE))1140 addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer);1141 }1142 1143 // If this is a variadic function, add an unspecified parameter.1144 DITypeRefArray FnArgs = Sub->getType()->getTypeArray();1145 1146 // If we have a single element of null, it is a function that returns void.1147 // If we have more than one elements and the last one is null, it is a1148 // variadic function.1149 if (FnArgs.size() > 1 && !FnArgs[FnArgs.size() - 1] &&1150 !includeMinimalInlineScopes())1151 ScopeDIE.addChild(1152 DIE::get(DIEValueAllocator, dwarf::DW_TAG_unspecified_parameters));1153 1154 return ScopeDIE;1155}1156 1157DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope,1158 DIE &ScopeDIE) {1159 DIE *ObjectPointer = nullptr;1160 1161 // Emit function arguments (order is significant).1162 auto Vars = DU->getScopeVariables().lookup(Scope);1163 for (auto &DV : Vars.Args)1164 ScopeDIE.addChild(constructVariableDIE(*DV.second, *Scope, ObjectPointer));1165 1166 // Emit local variables.1167 auto Locals = sortLocalVars(Vars.Locals);1168 for (DbgVariable *DV : Locals)1169 ScopeDIE.addChild(constructVariableDIE(*DV, *Scope, ObjectPointer));1170 1171 // Emit labels.1172 for (DbgLabel *DL : DU->getScopeLabels().lookup(Scope))1173 ScopeDIE.addChild(constructLabelDIE(*DL, *Scope));1174 1175 // Track other local entities (skipped in gmlt-like data).1176 // This creates mapping between CU and a set of local declarations that1177 // should be emitted for subprograms in this CU.1178 if (!includeMinimalInlineScopes() && !Scope->getInlinedAt()) {1179 auto &LocalDecls = DD->getLocalDeclsForScope(Scope->getScopeNode());1180 DeferredLocalDecls.insert_range(LocalDecls);1181 }1182 1183 // Emit inner lexical scopes.1184 auto skipLexicalScope = [this](LexicalScope *S) -> bool {1185 if (isa<DISubprogram>(S->getScopeNode()))1186 return false;1187 auto Vars = DU->getScopeVariables().lookup(S);1188 if (!Vars.Args.empty() || !Vars.Locals.empty())1189 return false;1190 return includeMinimalInlineScopes() ||1191 DD->getLocalDeclsForScope(S->getScopeNode()).empty();1192 };1193 for (LexicalScope *LS : Scope->getChildren()) {1194 // If the lexical block doesn't have non-scope children, skip1195 // its emission and put its children directly to the parent scope.1196 if (skipLexicalScope(LS))1197 createAndAddScopeChildren(LS, ScopeDIE);1198 else1199 constructScopeDIE(LS, ScopeDIE);1200 }1201 1202 return ObjectPointer;1203}1204 1205DIE &DwarfCompileUnit::getOrCreateAbstractSubprogramDIE(1206 const DISubprogram *SP) {1207 if (auto *AbsDef = getAbstractScopeDIEs().lookup(SP))1208 return *AbsDef;1209 1210 auto [ContextDIE, ContextCU] = getOrCreateAbstractSubprogramContextDIE(SP);1211 return createAbstractSubprogramDIE(SP, ContextDIE, ContextCU);1212}1213 1214DIE &DwarfCompileUnit::createAbstractSubprogramDIE(1215 const DISubprogram *SP, DIE *ContextDIE, DwarfCompileUnit *ContextCU) {1216 // Passing null as the associated node because the abstract definition1217 // shouldn't be found by lookup.1218 DIE &AbsDef = ContextCU->createAndAddDIE(dwarf::DW_TAG_subprogram,1219 *ContextDIE, nullptr);1220 1221 // Store the DIE before creating children.1222 ContextCU->getAbstractScopeDIEs()[SP] = &AbsDef;1223 1224 ContextCU->applySubprogramAttributesToDefinition(SP, AbsDef);1225 ContextCU->addSInt(AbsDef, dwarf::DW_AT_inline,1226 DD->getDwarfVersion() <= 4 ? std::optional<dwarf::Form>()1227 : dwarf::DW_FORM_implicit_const,1228 dwarf::DW_INL_inlined);1229 1230 return AbsDef;1231}1232 1233std::pair<DIE *, DwarfCompileUnit *>1234DwarfCompileUnit::getOrCreateAbstractSubprogramContextDIE(1235 const DISubprogram *SP) {1236 bool Minimal = includeMinimalInlineScopes();1237 bool IgnoreScope = shouldPlaceInUnitDIE(SP, Minimal);1238 DIE *ContextDIE = getOrCreateSubprogramContextDIE(SP, IgnoreScope);1239 1240 if (auto *SPDecl = SP->getDeclaration())1241 if (!Minimal)1242 getOrCreateSubprogramDIE(SPDecl, nullptr);1243 1244 // The scope may be shared with a subprogram that has already been1245 // constructed in another CU, in which case we need to construct this1246 // subprogram in the same CU.1247 auto *ContextCU = IgnoreScope ? this : DD->lookupCU(ContextDIE->getUnitDie());1248 1249 return std::make_pair(ContextDIE, ContextCU);1250}1251 1252void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(1253 LexicalScope *Scope) {1254 auto *SP = cast<DISubprogram>(Scope->getScopeNode());1255 1256 // Populate subprogram DIE only once.1257 if (!getFinalizedAbstractSubprograms().insert(SP).second)1258 return;1259 1260 auto [ContextDIE, ContextCU] = getOrCreateAbstractSubprogramContextDIE(SP);1261 DIE *AbsDef = getAbstractScopeDIEs().lookup(SP);1262 if (!AbsDef)1263 AbsDef = &createAbstractSubprogramDIE(SP, ContextDIE, ContextCU);1264 1265 if (DIE *ObjectPointer = ContextCU->createAndAddScopeChildren(Scope, *AbsDef))1266 ContextCU->addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer,1267 *ObjectPointer);1268}1269 1270bool DwarfCompileUnit::useGNUAnalogForDwarf5Feature() const {1271 return DD->getDwarfVersion() <= 4 && !DD->tuneForLLDB();1272}1273 1274dwarf::Tag DwarfCompileUnit::getDwarf5OrGNUTag(dwarf::Tag Tag) const {1275 if (!useGNUAnalogForDwarf5Feature())1276 return Tag;1277 switch (Tag) {1278 case dwarf::DW_TAG_call_site:1279 return dwarf::DW_TAG_GNU_call_site;1280 case dwarf::DW_TAG_call_site_parameter:1281 return dwarf::DW_TAG_GNU_call_site_parameter;1282 default:1283 llvm_unreachable("DWARF5 tag with no GNU analog");1284 }1285}1286 1287dwarf::Attribute1288DwarfCompileUnit::getDwarf5OrGNUAttr(dwarf::Attribute Attr) const {1289 if (!useGNUAnalogForDwarf5Feature())1290 return Attr;1291 switch (Attr) {1292 case dwarf::DW_AT_call_all_calls:1293 return dwarf::DW_AT_GNU_all_call_sites;1294 case dwarf::DW_AT_call_target:1295 return dwarf::DW_AT_GNU_call_site_target;1296 case dwarf::DW_AT_call_origin:1297 return dwarf::DW_AT_abstract_origin;1298 case dwarf::DW_AT_call_return_pc:1299 return dwarf::DW_AT_low_pc;1300 case dwarf::DW_AT_call_value:1301 return dwarf::DW_AT_GNU_call_site_value;1302 case dwarf::DW_AT_call_tail_call:1303 return dwarf::DW_AT_GNU_tail_call;1304 default:1305 llvm_unreachable("DWARF5 attribute with no GNU analog");1306 }1307}1308 1309dwarf::LocationAtom1310DwarfCompileUnit::getDwarf5OrGNULocationAtom(dwarf::LocationAtom Loc) const {1311 if (!useGNUAnalogForDwarf5Feature())1312 return Loc;1313 switch (Loc) {1314 case dwarf::DW_OP_entry_value:1315 return dwarf::DW_OP_GNU_entry_value;1316 default:1317 llvm_unreachable("DWARF5 location atom with no GNU analog");1318 }1319}1320 1321DIE &DwarfCompileUnit::constructCallSiteEntryDIE(1322 DIE &ScopeDIE, const DISubprogram *CalleeSP, const Function *CalleeF,1323 bool IsTail, const MCSymbol *PCAddr, const MCSymbol *CallAddr,1324 unsigned CallReg, DIType *AllocSiteTy) {1325 // Insert a call site entry DIE within ScopeDIE.1326 DIE &CallSiteDIE = createAndAddDIE(getDwarf5OrGNUTag(dwarf::DW_TAG_call_site),1327 ScopeDIE, nullptr);1328 1329 if (CallReg) {1330 // Indirect call.1331 addAddress(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_target),1332 MachineLocation(CallReg));1333 } else if (CalleeSP) {1334 DIE *CalleeDIE = getOrCreateSubprogramDIE(CalleeSP, CalleeF);1335 assert(CalleeDIE && "Could not create DIE for call site entry origin");1336 if (AddLinkageNamesToDeclCallOriginsForTuning(DD) &&1337 !CalleeSP->isDefinition() &&1338 !CalleeDIE->findAttribute(dwarf::DW_AT_linkage_name)) {1339 addLinkageName(*CalleeDIE, CalleeSP->getLinkageName());1340 }1341 1342 addDIEEntry(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_origin),1343 *CalleeDIE);1344 }1345 1346 if (IsTail) {1347 // Attach DW_AT_call_tail_call to tail calls for standards compliance.1348 addFlag(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_tail_call));1349 1350 // Attach the address of the branch instruction to allow the debugger to1351 // show where the tail call occurred. This attribute has no GNU analog.1352 //1353 // GDB works backwards from non-standard usage of DW_AT_low_pc (in DWARF41354 // mode -- equivalently, in DWARF5 mode, DW_AT_call_return_pc) at tail-call1355 // site entries to figure out the PC of tail-calling branch instructions.1356 // This means it doesn't need the compiler to emit DW_AT_call_pc, so we1357 // don't emit it here.1358 //1359 // There's no need to tie non-GDB debuggers to this non-standardness, as it1360 // adds unnecessary complexity to the debugger. For non-GDB debuggers, emit1361 // the standard DW_AT_call_pc info.1362 if (!useGNUAnalogForDwarf5Feature())1363 addLabelAddress(CallSiteDIE, dwarf::DW_AT_call_pc, CallAddr);1364 }1365 1366 // Attach the return PC to allow the debugger to disambiguate call paths1367 // from one function to another.1368 //1369 // The return PC is only really needed when the call /isn't/ a tail call, but1370 // GDB expects it in DWARF4 mode, even for tail calls (see the comment above1371 // the DW_AT_call_pc emission logic for an explanation).1372 if (!IsTail || useGNUAnalogForDwarf5Feature()) {1373 assert(PCAddr && "Missing return PC information for a call");1374 addLabelAddress(CallSiteDIE,1375 getDwarf5OrGNUAttr(dwarf::DW_AT_call_return_pc), PCAddr);1376 }1377 1378 if (AllocSiteTy)1379 addType(CallSiteDIE, AllocSiteTy, dwarf::DW_AT_LLVM_alloc_type);1380 1381 return CallSiteDIE;1382}1383 1384void DwarfCompileUnit::constructCallSiteParmEntryDIEs(1385 DIE &CallSiteDIE, SmallVector<DbgCallSiteParam, 4> &Params) {1386 for (const auto &Param : Params) {1387 unsigned Register = Param.getRegister();1388 auto CallSiteDieParam =1389 DIE::get(DIEValueAllocator,1390 getDwarf5OrGNUTag(dwarf::DW_TAG_call_site_parameter));1391 insertDIE(CallSiteDieParam);1392 addAddress(*CallSiteDieParam, dwarf::DW_AT_location,1393 MachineLocation(Register));1394 1395 DIELoc *Loc = new (DIEValueAllocator) DIELoc;1396 DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);1397 DwarfExpr.setCallSiteParamValueFlag();1398 1399 DwarfDebug::emitDebugLocValue(*Asm, nullptr, Param.getValue(), DwarfExpr);1400 1401 addBlock(*CallSiteDieParam, getDwarf5OrGNUAttr(dwarf::DW_AT_call_value),1402 DwarfExpr.finalize());1403 1404 CallSiteDIE.addChild(CallSiteDieParam);1405 }1406}1407 1408DIE *DwarfCompileUnit::constructImportedEntityDIE(1409 const DIImportedEntity *Module) {1410 DIE *IMDie = DIE::get(DIEValueAllocator, Module->getTag());1411 insertDIE(Module, IMDie);1412 DIE *EntityDie;1413 auto *Entity = Module->getEntity();1414 if (auto *NS = dyn_cast<DINamespace>(Entity))1415 EntityDie = getOrCreateNameSpace(NS);1416 else if (auto *M = dyn_cast<DIModule>(Entity))1417 EntityDie = getOrCreateModule(M);1418 else if (auto *SP = dyn_cast<DISubprogram>(Entity)) {1419 // If there is an abstract subprogram, refer to it. Note that this assumes1420 // that all the abstract subprograms have been already created (which is1421 // correct until imported entities get emitted in DwarfDebug::endModule()).1422 if (auto *AbsSPDie = getAbstractScopeDIEs().lookup(SP))1423 EntityDie = AbsSPDie;1424 else1425 EntityDie = getOrCreateSubprogramDIE(SP, nullptr);1426 } else if (auto *T = dyn_cast<DIType>(Entity))1427 EntityDie = getOrCreateTypeDIE(T);1428 else if (auto *GV = dyn_cast<DIGlobalVariable>(Entity))1429 EntityDie = getOrCreateGlobalVariableDIE(GV, {});1430 else if (auto *IE = dyn_cast<DIImportedEntity>(Entity))1431 EntityDie = getOrCreateImportedEntityDIE(IE);1432 else1433 EntityDie = getDIE(Entity);1434 assert(EntityDie);1435 addSourceLine(*IMDie, Module->getLine(), /*Column*/ 0, Module->getFile());1436 addDIEEntry(*IMDie, dwarf::DW_AT_import, *EntityDie);1437 StringRef Name = Module->getName();1438 if (!Name.empty()) {1439 addString(*IMDie, dwarf::DW_AT_name, Name);1440 1441 // FIXME: if consumers ever start caring about handling1442 // unnamed import declarations such as `using ::nullptr_t`1443 // or `using namespace std::ranges`, we could add the1444 // import declaration into the accelerator table with the1445 // name being the one of the entity being imported.1446 DD->addAccelNamespace(*this, CUNode->getNameTableKind(), Name, *IMDie);1447 }1448 1449 // This is for imported module with renamed entities (such as variables and1450 // subprograms).1451 DINodeArray Elements = Module->getElements();1452 for (const auto *Element : Elements) {1453 if (!Element)1454 continue;1455 IMDie->addChild(1456 constructImportedEntityDIE(cast<DIImportedEntity>(Element)));1457 }1458 1459 return IMDie;1460}1461 1462DIE *DwarfCompileUnit::getOrCreateImportedEntityDIE(1463 const DIImportedEntity *IE) {1464 1465 // Check for pre-existence.1466 if (DIE *Die = getDIE(IE))1467 return Die;1468 1469 DIE *ContextDIE = getOrCreateContextDIE(IE->getScope());1470 assert(ContextDIE && "Empty scope for the imported entity!");1471 1472 DIE *IMDie = constructImportedEntityDIE(IE);1473 ContextDIE->addChild(IMDie);1474 return IMDie;1475}1476 1477void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP) {1478 DIE *D = getDIE(SP);1479 if (DIE *AbsSPDIE = getAbstractScopeDIEs().lookup(SP)) {1480 if (D)1481 // If this subprogram has an abstract definition, reference that1482 addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE);1483 } else {1484 assert(D || includeMinimalInlineScopes());1485 if (D)1486 // And attach the attributes1487 applySubprogramAttributesToDefinition(SP, *D);1488 }1489}1490 1491void DwarfCompileUnit::finishEntityDefinition(const DbgEntity *Entity) {1492 DbgEntity *AbsEntity = getExistingAbstractEntity(Entity->getEntity());1493 1494 auto *Die = Entity->getDIE();1495 /// Label may be used to generate DW_AT_low_pc, so put it outside1496 /// if/else block.1497 const DbgLabel *Label = nullptr;1498 if (AbsEntity && AbsEntity->getDIE()) {1499 addDIEEntry(*Die, dwarf::DW_AT_abstract_origin, *AbsEntity->getDIE());1500 Label = dyn_cast<const DbgLabel>(Entity);1501 } else {1502 if (const DbgVariable *Var = dyn_cast<const DbgVariable>(Entity))1503 applyCommonDbgVariableAttributes(*Var, *Die);1504 else if ((Label = dyn_cast<const DbgLabel>(Entity)))1505 applyLabelAttributes(*Label, *Die);1506 else1507 llvm_unreachable("DbgEntity must be DbgVariable or DbgLabel.");1508 }1509 1510 if (!Label)1511 return;1512 1513 const auto *Sym = Label->getSymbol();1514 if (!Sym)1515 return;1516 1517 addLabelAddress(*Die, dwarf::DW_AT_low_pc, Sym);1518 1519 // A TAG_label with a name and an AT_low_pc must be placed in debug_names.1520 if (StringRef Name = Label->getName(); !Name.empty())1521 getDwarfDebug().addAccelName(*this, CUNode->getNameTableKind(), Name, *Die);1522}1523 1524void DwarfCompileUnit::attachLexicalScopesAbstractOrigins() {1525 auto AttachAO = [&](const DILocalScope *LS, DIE *ScopeDIE) {1526 if (auto *AbsLSDie = getAbstractScopeDIEs().lookup(LS))1527 addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *AbsLSDie);1528 };1529 1530 for (auto [LScope, ScopeDIE] : LexicalBlockDIEs)1531 AttachAO(LScope, ScopeDIE);1532 for (auto &[LScope, ScopeDIEs] : InlinedLocalScopeDIEs)1533 for (auto *ScopeDIE : ScopeDIEs)1534 AttachAO(LScope, ScopeDIE);1535}1536 1537DbgEntity *DwarfCompileUnit::getExistingAbstractEntity(const DINode *Node) {1538 auto &AbstractEntities = getAbstractEntities();1539 auto I = AbstractEntities.find(Node);1540 if (I != AbstractEntities.end())1541 return I->second.get();1542 return nullptr;1543}1544 1545void DwarfCompileUnit::createAbstractEntity(const DINode *Node,1546 LexicalScope *Scope) {1547 assert(Scope && Scope->isAbstractScope());1548 auto &Entity = getAbstractEntities()[Node];1549 if (isa<const DILocalVariable>(Node)) {1550 Entity = std::make_unique<DbgVariable>(cast<const DILocalVariable>(Node),1551 nullptr /* IA */);1552 DU->addScopeVariable(Scope, cast<DbgVariable>(Entity.get()));1553 } else if (isa<const DILabel>(Node)) {1554 Entity = std::make_unique<DbgLabel>(1555 cast<const DILabel>(Node), nullptr /* IA */);1556 DU->addScopeLabel(Scope, cast<DbgLabel>(Entity.get()));1557 }1558}1559 1560void DwarfCompileUnit::emitHeader(bool UseOffsets) {1561 // Don't bother labeling the .dwo unit, as its offset isn't used.1562 if (!Skeleton && !DD->useSectionsAsReferences()) {1563 LabelBegin = Asm->createTempSymbol("cu_begin");1564 Asm->OutStreamer->emitLabel(LabelBegin);1565 }1566 1567 dwarf::UnitType UT = Skeleton ? dwarf::DW_UT_split_compile1568 : DD->useSplitDwarf() ? dwarf::DW_UT_skeleton1569 : dwarf::DW_UT_compile;1570 DwarfUnit::emitCommonHeader(UseOffsets, UT);1571 if (DD->getDwarfVersion() >= 5 && UT != dwarf::DW_UT_compile)1572 Asm->emitInt64(getDWOId());1573}1574 1575bool DwarfCompileUnit::hasDwarfPubSections() const {1576 switch (CUNode->getNameTableKind()) {1577 case DICompileUnit::DebugNameTableKind::None:1578 return false;1579 // Opting in to GNU Pubnames/types overrides the default to ensure these are1580 // generated for things like Gold's gdb_index generation.1581 case DICompileUnit::DebugNameTableKind::GNU:1582 return true;1583 case DICompileUnit::DebugNameTableKind::Apple:1584 return false;1585 case DICompileUnit::DebugNameTableKind::Default:1586 return DD->tuneForGDB() && !includeMinimalInlineScopes() &&1587 !CUNode->isDebugDirectivesOnly() &&1588 DD->getAccelTableKind() != AccelTableKind::Apple &&1589 DD->getDwarfVersion() < 5;1590 }1591 llvm_unreachable("Unhandled DICompileUnit::DebugNameTableKind enum");1592}1593 1594/// addGlobalName - Add a new global name to the compile unit.1595void DwarfCompileUnit::addGlobalName(StringRef Name, const DIE &Die,1596 const DIScope *Context) {1597 if (!hasDwarfPubSections())1598 return;1599 std::string FullName = getParentContextString(Context) + Name.str();1600 GlobalNames[FullName] = &Die;1601}1602 1603void DwarfCompileUnit::addGlobalNameForTypeUnit(StringRef Name,1604 const DIScope *Context) {1605 if (!hasDwarfPubSections())1606 return;1607 std::string FullName = getParentContextString(Context) + Name.str();1608 // Insert, allowing the entry to remain as-is if it's already present1609 // This way the CU-level type DIE is preferred over the "can't describe this1610 // type as a unit offset because it's not really in the CU at all, it's only1611 // in a type unit"1612 GlobalNames.insert(std::make_pair(std::move(FullName), &getUnitDie()));1613}1614 1615/// Add a new global type to the unit.1616void DwarfCompileUnit::addGlobalTypeImpl(const DIType *Ty, const DIE &Die,1617 const DIScope *Context) {1618 if (!hasDwarfPubSections())1619 return;1620 std::string FullName = getParentContextString(Context) + Ty->getName().str();1621 GlobalTypes[FullName] = &Die;1622}1623 1624void DwarfCompileUnit::addGlobalTypeUnitType(const DIType *Ty,1625 const DIScope *Context) {1626 if (!hasDwarfPubSections())1627 return;1628 std::string FullName = getParentContextString(Context) + Ty->getName().str();1629 // Insert, allowing the entry to remain as-is if it's already present1630 // This way the CU-level type DIE is preferred over the "can't describe this1631 // type as a unit offset because it's not really in the CU at all, it's only1632 // in a type unit"1633 GlobalTypes.insert(std::make_pair(std::move(FullName), &getUnitDie()));1634}1635 1636void DwarfCompileUnit::addVariableAddress(const DbgVariable &DV, DIE &Die,1637 MachineLocation Location) {1638 auto *Single = std::get_if<Loc::Single>(&DV);1639 if (Single && Single->getExpr())1640 addComplexAddress(Single->getExpr(), Die, dwarf::DW_AT_location, Location);1641 else1642 addAddress(Die, dwarf::DW_AT_location, Location);1643}1644 1645/// Add an address attribute to a die based on the location provided.1646void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute,1647 const MachineLocation &Location) {1648 DIELoc *Loc = new (DIEValueAllocator) DIELoc;1649 DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);1650 if (Location.isIndirect())1651 DwarfExpr.setMemoryLocationKind();1652 1653 DIExpressionCursor Cursor({});1654 const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();1655 if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))1656 return;1657 DwarfExpr.addExpression(std::move(Cursor));1658 1659 // Now attach the location information to the DIE.1660 addBlock(Die, Attribute, DwarfExpr.finalize());1661 1662 if (DwarfExpr.TagOffset)1663 addUInt(Die, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,1664 *DwarfExpr.TagOffset);1665}1666 1667/// Start with the address based on the location provided, and generate the1668/// DWARF information necessary to find the actual variable given the extra1669/// address information encoded in the DbgVariable, starting from the starting1670/// location. Add the DWARF information to the die.1671void DwarfCompileUnit::addComplexAddress(const DIExpression *DIExpr, DIE &Die,1672 dwarf::Attribute Attribute,1673 const MachineLocation &Location) {1674 DIELoc *Loc = new (DIEValueAllocator) DIELoc;1675 DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);1676 DwarfExpr.addFragmentOffset(DIExpr);1677 DwarfExpr.setLocation(Location, DIExpr);1678 1679 DIExpressionCursor Cursor(DIExpr);1680 1681 if (DIExpr->isEntryValue())1682 DwarfExpr.beginEntryValueExpression(Cursor);1683 1684 const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();1685 if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))1686 return;1687 DwarfExpr.addExpression(std::move(Cursor));1688 1689 // Now attach the location information to the DIE.1690 addBlock(Die, Attribute, DwarfExpr.finalize());1691 1692 if (DwarfExpr.TagOffset)1693 addUInt(Die, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,1694 *DwarfExpr.TagOffset);1695}1696 1697/// Add a Dwarf loclistptr attribute data and value.1698void DwarfCompileUnit::addLocationList(DIE &Die, dwarf::Attribute Attribute,1699 unsigned Index) {1700 dwarf::Form Form = (DD->getDwarfVersion() >= 5)1701 ? dwarf::DW_FORM_loclistx1702 : DD->getDwarfSectionOffsetForm();1703 addAttribute(Die, Attribute, Form, DIELocList(Index));1704}1705 1706void DwarfCompileUnit::applyCommonDbgVariableAttributes(const DbgVariable &Var,1707 DIE &VariableDie) {1708 StringRef Name = Var.getName();1709 if (!Name.empty())1710 addString(VariableDie, dwarf::DW_AT_name, Name);1711 const auto *DIVar = Var.getVariable();1712 if (DIVar) {1713 if (uint32_t AlignInBytes = DIVar->getAlignInBytes())1714 addUInt(VariableDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,1715 AlignInBytes);1716 addAnnotation(VariableDie, DIVar->getAnnotations());1717 }1718 1719 addSourceLine(VariableDie, DIVar);1720 addType(VariableDie, Var.getType());1721 if (Var.isArtificial())1722 addFlag(VariableDie, dwarf::DW_AT_artificial);1723}1724 1725void DwarfCompileUnit::applyLabelAttributes(const DbgLabel &Label,1726 DIE &LabelDie) {1727 StringRef Name = Label.getName();1728 if (!Name.empty())1729 addString(LabelDie, dwarf::DW_AT_name, Name);1730 const auto *DILabel = Label.getLabel();1731 addSourceLine(LabelDie, DILabel);1732 if (DILabel->isArtificial())1733 addFlag(LabelDie, dwarf::DW_AT_artificial);1734 if (DILabel->getCoroSuspendIdx())1735 addUInt(LabelDie, dwarf::DW_AT_LLVM_coro_suspend_idx, std::nullopt,1736 *DILabel->getCoroSuspendIdx());1737}1738 1739/// Add a Dwarf expression attribute data and value.1740void DwarfCompileUnit::addExpr(DIELoc &Die, dwarf::Form Form,1741 const MCExpr *Expr) {1742 addAttribute(Die, (dwarf::Attribute)0, Form, DIEExpr(Expr));1743}1744 1745void DwarfCompileUnit::applySubprogramAttributesToDefinition(1746 const DISubprogram *SP, DIE &SPDie) {1747 auto *SPDecl = SP->getDeclaration();1748 auto *Context = SPDecl ? SPDecl->getScope() : SP->getScope();1749 applySubprogramAttributes(SP, SPDie, includeMinimalInlineScopes());1750 addGlobalName(SP->getName(), SPDie, Context);1751}1752 1753bool DwarfCompileUnit::isDwoUnit() const {1754 return DD->useSplitDwarf() && Skeleton;1755}1756 1757void DwarfCompileUnit::finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) {1758 constructTypeDIE(D, CTy);1759}1760 1761bool DwarfCompileUnit::includeMinimalInlineScopes() const {1762 return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly ||1763 (DD->useSplitDwarf() && !Skeleton);1764}1765 1766bool DwarfCompileUnit::emitFuncLineTableOffsets() const {1767 return EmitFuncLineTableOffsetsOption;1768}1769 1770void DwarfCompileUnit::addAddrTableBase() {1771 const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();1772 MCSymbol *Label = DD->getAddressPool().getLabel();1773 addSectionLabel(getUnitDie(),1774 DD->getDwarfVersion() >= 5 ? dwarf::DW_AT_addr_base1775 : dwarf::DW_AT_GNU_addr_base,1776 Label, TLOF.getDwarfAddrSection()->getBeginSymbol());1777}1778 1779void DwarfCompileUnit::addBaseTypeRef(DIEValueList &Die, int64_t Idx) {1780 addAttribute(Die, (dwarf::Attribute)0, dwarf::DW_FORM_udata,1781 new (DIEValueAllocator) DIEBaseTypeRef(this, Idx));1782}1783 1784void DwarfCompileUnit::createBaseTypeDIEs() {1785 // Insert the base_type DIEs directly after the CU so that their offsets will1786 // fit in the fixed size ULEB128 used inside the location expressions.1787 // Maintain order by iterating backwards and inserting to the front of CU1788 // child list.1789 for (auto &Btr : reverse(ExprRefedBaseTypes)) {1790 DIE &Die = getUnitDie().addChildFront(1791 DIE::get(DIEValueAllocator, dwarf::DW_TAG_base_type));1792 SmallString<32> Str;1793 addString(Die, dwarf::DW_AT_name,1794 Twine(dwarf::AttributeEncodingString(Btr.Encoding) +1795 "_" + Twine(Btr.BitSize)).toStringRef(Str));1796 addUInt(Die, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Btr.Encoding);1797 // Round up to smallest number of bytes that contains this number of bits.1798 // ExprRefedBaseTypes is populated with types referenced by1799 // DW_OP_LLVM_convert operations in location expressions. These are often1800 // byte-sized, but one common counter-example is 1-bit sized conversions1801 // from `i1` types. TODO: Should these use DW_AT_bit_size? See1802 // DwarfUnit::constructTypeDIE.1803 addUInt(Die, dwarf::DW_AT_byte_size, std::nullopt,1804 divideCeil(Btr.BitSize, 8));1805 Btr.Die = &Die;1806 }1807}1808 1809DIE *DwarfCompileUnit::getLexicalBlockDIE(const DILexicalBlock *LB) {1810 // Assume if there is an abstract tree all the DIEs are already emitted.1811 bool isAbstract = getAbstractScopeDIEs().count(LB->getSubprogram());1812 if (isAbstract) {1813 auto &DIEs = getAbstractScopeDIEs();1814 if (auto It = DIEs.find(LB); It != DIEs.end())1815 return It->second;1816 }1817 assert(!isAbstract && "Missed lexical block DIE in abstract tree!");1818 1819 // Return a concrete DIE if it exists or nullptr otherwise.1820 return LexicalBlockDIEs.lookup(LB);1821}1822 1823DIE *DwarfCompileUnit::getOrCreateContextDIE(const DIScope *Context) {1824 if (isa_and_nonnull<DILocalScope>(Context)) {1825 if (auto *LFScope = dyn_cast<DILexicalBlockFile>(Context))1826 Context = LFScope->getNonLexicalBlockFileScope();1827 if (auto *LScope = dyn_cast<DILexicalBlock>(Context))1828 return getLexicalBlockDIE(LScope);1829 1830 // Otherwise the context must be a DISubprogram.1831 auto *SPScope = cast<DISubprogram>(Context);1832 const auto &DIEs = getAbstractScopeDIEs();1833 if (auto It = DIEs.find(SPScope); It != DIEs.end())1834 return It->second;1835 }1836 return DwarfUnit::getOrCreateContextDIE(Context);1837}1838 1839DIE *DwarfCompileUnit::getOrCreateSubprogramDIE(const DISubprogram *SP,1840 const Function *F,1841 bool Minimal) {1842 if (!F && SP->isDefinition()) {1843 F = DD->getLexicalScopes().getFunction(SP);1844 1845 if (!F) {1846 // SP may belong to another CU. Determine the CU similarly1847 // to DwarfDebug::constructAbstractSubprogramScopeDIE.1848 return &DD->getOrCreateAbstractSubprogramCU(SP, *this)1849 .getOrCreateAbstractSubprogramDIE(SP);1850 }1851 }1852 1853 return DwarfUnit::getOrCreateSubprogramDIE(SP, F, Minimal);1854}1855