109467b48Spatrick //===- llvm/CodeGen/DwarfCompileUnit.cpp - Dwarf Compile Units ------------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // This file contains support for constructing a dwarf compile unit.
1009467b48Spatrick //
1109467b48Spatrick //===----------------------------------------------------------------------===//
1209467b48Spatrick
1309467b48Spatrick #include "DwarfCompileUnit.h"
1409467b48Spatrick #include "AddressPool.h"
1509467b48Spatrick #include "DwarfExpression.h"
1609467b48Spatrick #include "llvm/ADT/STLExtras.h"
1709467b48Spatrick #include "llvm/ADT/SmallString.h"
1809467b48Spatrick #include "llvm/BinaryFormat/Dwarf.h"
1909467b48Spatrick #include "llvm/CodeGen/AsmPrinter.h"
2009467b48Spatrick #include "llvm/CodeGen/DIE.h"
2109467b48Spatrick #include "llvm/CodeGen/MachineFunction.h"
2209467b48Spatrick #include "llvm/CodeGen/MachineInstr.h"
2309467b48Spatrick #include "llvm/CodeGen/TargetFrameLowering.h"
2409467b48Spatrick #include "llvm/CodeGen/TargetRegisterInfo.h"
2509467b48Spatrick #include "llvm/CodeGen/TargetSubtargetInfo.h"
2609467b48Spatrick #include "llvm/IR/DataLayout.h"
2709467b48Spatrick #include "llvm/IR/DebugInfo.h"
2809467b48Spatrick #include "llvm/IR/GlobalVariable.h"
2909467b48Spatrick #include "llvm/MC/MCSection.h"
3009467b48Spatrick #include "llvm/MC/MCStreamer.h"
3109467b48Spatrick #include "llvm/MC/MCSymbol.h"
32097a140dSpatrick #include "llvm/MC/MCSymbolWasm.h"
3309467b48Spatrick #include "llvm/MC/MachineLocation.h"
3409467b48Spatrick #include "llvm/Target/TargetLoweringObjectFile.h"
3509467b48Spatrick #include "llvm/Target/TargetMachine.h"
3609467b48Spatrick #include "llvm/Target/TargetOptions.h"
3709467b48Spatrick #include <iterator>
38*d415bd75Srobert #include <optional>
3909467b48Spatrick #include <string>
4009467b48Spatrick #include <utility>
4109467b48Spatrick
4209467b48Spatrick using namespace llvm;
4309467b48Spatrick
GetCompileUnitType(UnitKind Kind,DwarfDebug * DW)4409467b48Spatrick static dwarf::Tag GetCompileUnitType(UnitKind Kind, DwarfDebug *DW) {
4509467b48Spatrick
4609467b48Spatrick // According to DWARF Debugging Information Format Version 5,
4709467b48Spatrick // 3.1.2 Skeleton Compilation Unit Entries:
4809467b48Spatrick // "When generating a split DWARF object file (see Section 7.3.2
4909467b48Spatrick // on page 187), the compilation unit in the .debug_info section
5009467b48Spatrick // is a "skeleton" compilation unit with the tag DW_TAG_skeleton_unit"
5109467b48Spatrick if (DW->getDwarfVersion() >= 5 && Kind == UnitKind::Skeleton)
5209467b48Spatrick return dwarf::DW_TAG_skeleton_unit;
5309467b48Spatrick
5409467b48Spatrick return dwarf::DW_TAG_compile_unit;
5509467b48Spatrick }
5609467b48Spatrick
DwarfCompileUnit(unsigned UID,const DICompileUnit * Node,AsmPrinter * A,DwarfDebug * DW,DwarfFile * DWU,UnitKind Kind)5709467b48Spatrick DwarfCompileUnit::DwarfCompileUnit(unsigned UID, const DICompileUnit *Node,
5809467b48Spatrick AsmPrinter *A, DwarfDebug *DW,
5909467b48Spatrick DwarfFile *DWU, UnitKind Kind)
6009467b48Spatrick : DwarfUnit(GetCompileUnitType(Kind, DW), Node, A, DW, DWU), UniqueID(UID) {
6109467b48Spatrick insertDIE(Node, &getUnitDie());
6209467b48Spatrick MacroLabelBegin = Asm->createTempSymbol("cu_macro_begin");
6309467b48Spatrick }
6409467b48Spatrick
6509467b48Spatrick /// addLabelAddress - Add a dwarf label attribute data and value using
6609467b48Spatrick /// DW_FORM_addr or DW_FORM_GNU_addr_index.
addLabelAddress(DIE & Die,dwarf::Attribute Attribute,const MCSymbol * Label)6709467b48Spatrick void DwarfCompileUnit::addLabelAddress(DIE &Die, dwarf::Attribute Attribute,
6809467b48Spatrick const MCSymbol *Label) {
69*d415bd75Srobert if ((Skeleton || !DD->useSplitDwarf()) && Label)
70*d415bd75Srobert DD->addArangeLabel(SymbolCU(this, Label));
71*d415bd75Srobert
7209467b48Spatrick // Don't use the address pool in non-fission or in the skeleton unit itself.
7309467b48Spatrick if ((!DD->useSplitDwarf() || !Skeleton) && DD->getDwarfVersion() < 5)
7409467b48Spatrick return addLocalLabelAddress(Die, Attribute, Label);
7509467b48Spatrick
7673471bf0Spatrick bool UseAddrOffsetFormOrExpressions =
7773471bf0Spatrick DD->useAddrOffsetForm() || DD->useAddrOffsetExpressions();
7873471bf0Spatrick
7973471bf0Spatrick const MCSymbol *Base = nullptr;
8073471bf0Spatrick if (Label->isInSection() && UseAddrOffsetFormOrExpressions)
8173471bf0Spatrick Base = DD->getSectionLabel(&Label->getSection());
8273471bf0Spatrick
8373471bf0Spatrick if (!Base || Base == Label) {
8409467b48Spatrick unsigned idx = DD->getAddressPool().getIndex(Label);
8573471bf0Spatrick addAttribute(Die, Attribute,
8609467b48Spatrick DD->getDwarfVersion() >= 5 ? dwarf::DW_FORM_addrx
8709467b48Spatrick : dwarf::DW_FORM_GNU_addr_index,
8809467b48Spatrick DIEInteger(idx));
8973471bf0Spatrick return;
9073471bf0Spatrick }
9173471bf0Spatrick
9273471bf0Spatrick // Could be extended to work with DWARFv4 Split DWARF if that's important for
9373471bf0Spatrick // someone. In that case DW_FORM_data would be used.
9473471bf0Spatrick assert(DD->getDwarfVersion() >= 5 &&
9573471bf0Spatrick "Addr+offset expressions are only valuable when using debug_addr (to "
9673471bf0Spatrick "reduce relocations) available in DWARFv5 or higher");
9773471bf0Spatrick if (DD->useAddrOffsetExpressions()) {
9873471bf0Spatrick auto *Loc = new (DIEValueAllocator) DIEBlock();
9973471bf0Spatrick addPoolOpAddress(*Loc, Label);
10073471bf0Spatrick addBlock(Die, Attribute, dwarf::DW_FORM_exprloc, Loc);
10173471bf0Spatrick } else
10273471bf0Spatrick addAttribute(Die, Attribute, dwarf::DW_FORM_LLVM_addrx_offset,
10373471bf0Spatrick new (DIEValueAllocator) DIEAddrOffset(
10473471bf0Spatrick DD->getAddressPool().getIndex(Base), Label, Base));
10509467b48Spatrick }
10609467b48Spatrick
addLocalLabelAddress(DIE & Die,dwarf::Attribute Attribute,const MCSymbol * Label)10709467b48Spatrick void DwarfCompileUnit::addLocalLabelAddress(DIE &Die,
10809467b48Spatrick dwarf::Attribute Attribute,
10909467b48Spatrick const MCSymbol *Label) {
11009467b48Spatrick if (Label)
11173471bf0Spatrick addAttribute(Die, Attribute, dwarf::DW_FORM_addr, DIELabel(Label));
11209467b48Spatrick else
11373471bf0Spatrick addAttribute(Die, Attribute, dwarf::DW_FORM_addr, DIEInteger(0));
11409467b48Spatrick }
11509467b48Spatrick
getOrCreateSourceID(const DIFile * File)11609467b48Spatrick unsigned DwarfCompileUnit::getOrCreateSourceID(const DIFile *File) {
11709467b48Spatrick // If we print assembly, we can't separate .file entries according to
11809467b48Spatrick // compile units. Thus all files will belong to the default compile unit.
11909467b48Spatrick
12009467b48Spatrick // FIXME: add a better feature test than hasRawTextSupport. Even better,
12109467b48Spatrick // extend .file to support this.
12209467b48Spatrick unsigned CUID = Asm->OutStreamer->hasRawTextSupport() ? 0 : getUniqueID();
12309467b48Spatrick if (!File)
124*d415bd75Srobert return Asm->OutStreamer->emitDwarfFileDirective(0, "", "", std::nullopt,
125*d415bd75Srobert std::nullopt, CUID);
126*d415bd75Srobert
127*d415bd75Srobert if (LastFile != File) {
128*d415bd75Srobert LastFile = File;
129*d415bd75Srobert LastFileID = Asm->OutStreamer->emitDwarfFileDirective(
13073471bf0Spatrick 0, File->getDirectory(), File->getFilename(), DD->getMD5AsBytes(File),
13109467b48Spatrick File->getSource(), CUID);
13209467b48Spatrick }
133*d415bd75Srobert return LastFileID;
134*d415bd75Srobert }
13509467b48Spatrick
getOrCreateGlobalVariableDIE(const DIGlobalVariable * GV,ArrayRef<GlobalExpr> GlobalExprs)13609467b48Spatrick DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(
13709467b48Spatrick const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) {
13809467b48Spatrick // Check for pre-existence.
13909467b48Spatrick if (DIE *Die = getDIE(GV))
14009467b48Spatrick return Die;
14109467b48Spatrick
14209467b48Spatrick assert(GV);
14309467b48Spatrick
14409467b48Spatrick auto *GVContext = GV->getScope();
14509467b48Spatrick const DIType *GTy = GV->getType();
14609467b48Spatrick
14709467b48Spatrick auto *CB = GVContext ? dyn_cast<DICommonBlock>(GVContext) : nullptr;
14809467b48Spatrick DIE *ContextDIE = CB ? getOrCreateCommonBlock(CB, GlobalExprs)
14909467b48Spatrick : getOrCreateContextDIE(GVContext);
15009467b48Spatrick
15109467b48Spatrick // Add to map.
15209467b48Spatrick DIE *VariableDIE = &createAndAddDIE(GV->getTag(), *ContextDIE, GV);
15309467b48Spatrick DIScope *DeclContext;
15409467b48Spatrick if (auto *SDMDecl = GV->getStaticDataMemberDeclaration()) {
15509467b48Spatrick DeclContext = SDMDecl->getScope();
15609467b48Spatrick assert(SDMDecl->isStaticMember() && "Expected static member decl");
15709467b48Spatrick assert(GV->isDefinition());
15809467b48Spatrick // We need the declaration DIE that is in the static member's class.
15909467b48Spatrick DIE *VariableSpecDIE = getOrCreateStaticMemberDIE(SDMDecl);
16009467b48Spatrick addDIEEntry(*VariableDIE, dwarf::DW_AT_specification, *VariableSpecDIE);
16109467b48Spatrick // If the global variable's type is different from the one in the class
16209467b48Spatrick // member type, assume that it's more specific and also emit it.
16309467b48Spatrick if (GTy != SDMDecl->getBaseType())
16409467b48Spatrick addType(*VariableDIE, GTy);
16509467b48Spatrick } else {
16609467b48Spatrick DeclContext = GV->getScope();
16709467b48Spatrick // Add name and type.
168*d415bd75Srobert StringRef DisplayName = GV->getDisplayName();
169*d415bd75Srobert if (!DisplayName.empty())
17009467b48Spatrick addString(*VariableDIE, dwarf::DW_AT_name, GV->getDisplayName());
171097a140dSpatrick if (GTy)
17209467b48Spatrick addType(*VariableDIE, GTy);
17309467b48Spatrick
17409467b48Spatrick // Add scoping info.
17509467b48Spatrick if (!GV->isLocalToUnit())
17609467b48Spatrick addFlag(*VariableDIE, dwarf::DW_AT_external);
17709467b48Spatrick
17809467b48Spatrick // Add line number info.
17909467b48Spatrick addSourceLine(*VariableDIE, GV);
18009467b48Spatrick }
18109467b48Spatrick
18209467b48Spatrick if (!GV->isDefinition())
18309467b48Spatrick addFlag(*VariableDIE, dwarf::DW_AT_declaration);
18409467b48Spatrick else
18509467b48Spatrick addGlobalName(GV->getName(), *VariableDIE, DeclContext);
18609467b48Spatrick
187*d415bd75Srobert addAnnotation(*VariableDIE, GV->getAnnotations());
188*d415bd75Srobert
18909467b48Spatrick if (uint32_t AlignInBytes = GV->getAlignInBytes())
19009467b48Spatrick addUInt(*VariableDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
19109467b48Spatrick AlignInBytes);
19209467b48Spatrick
19309467b48Spatrick if (MDTuple *TP = GV->getTemplateParams())
19409467b48Spatrick addTemplateParams(*VariableDIE, DINodeArray(TP));
19509467b48Spatrick
19609467b48Spatrick // Add location.
19709467b48Spatrick addLocationAttribute(VariableDIE, GV, GlobalExprs);
19809467b48Spatrick
19909467b48Spatrick return VariableDIE;
20009467b48Spatrick }
20109467b48Spatrick
addLocationAttribute(DIE * VariableDIE,const DIGlobalVariable * GV,ArrayRef<GlobalExpr> GlobalExprs)20209467b48Spatrick void DwarfCompileUnit::addLocationAttribute(
20309467b48Spatrick DIE *VariableDIE, const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) {
20409467b48Spatrick bool addToAccelTable = false;
20509467b48Spatrick DIELoc *Loc = nullptr;
206*d415bd75Srobert std::optional<unsigned> NVPTXAddressSpace;
20709467b48Spatrick std::unique_ptr<DIEDwarfExpression> DwarfExpr;
20809467b48Spatrick for (const auto &GE : GlobalExprs) {
20909467b48Spatrick const GlobalVariable *Global = GE.Var;
21009467b48Spatrick const DIExpression *Expr = GE.Expr;
21109467b48Spatrick
21209467b48Spatrick // For compatibility with DWARF 3 and earlier,
21373471bf0Spatrick // DW_AT_location(DW_OP_constu, X, DW_OP_stack_value) or
21473471bf0Spatrick // DW_AT_location(DW_OP_consts, X, DW_OP_stack_value) becomes
21509467b48Spatrick // DW_AT_const_value(X).
21609467b48Spatrick if (GlobalExprs.size() == 1 && Expr && Expr->isConstant()) {
21709467b48Spatrick addToAccelTable = true;
21873471bf0Spatrick addConstantValue(
21973471bf0Spatrick *VariableDIE,
22073471bf0Spatrick DIExpression::SignedOrUnsignedConstant::UnsignedConstant ==
22173471bf0Spatrick *Expr->isConstant(),
22273471bf0Spatrick Expr->getElement(1));
22309467b48Spatrick break;
22409467b48Spatrick }
22509467b48Spatrick
22609467b48Spatrick // We cannot describe the location of dllimport'd variables: the
22709467b48Spatrick // computation of their address requires loads from the IAT.
22809467b48Spatrick if (Global && Global->hasDLLImportStorageClass())
22909467b48Spatrick continue;
23009467b48Spatrick
23109467b48Spatrick // Nothing to describe without address or constant.
23209467b48Spatrick if (!Global && (!Expr || !Expr->isConstant()))
23309467b48Spatrick continue;
23409467b48Spatrick
23509467b48Spatrick if (Global && Global->isThreadLocal() &&
23609467b48Spatrick !Asm->getObjFileLowering().supportDebugThreadLocalLocation())
23709467b48Spatrick continue;
23809467b48Spatrick
23909467b48Spatrick if (!Loc) {
24009467b48Spatrick addToAccelTable = true;
24109467b48Spatrick Loc = new (DIEValueAllocator) DIELoc;
24209467b48Spatrick DwarfExpr = std::make_unique<DIEDwarfExpression>(*Asm, *this, *Loc);
24309467b48Spatrick }
24409467b48Spatrick
24509467b48Spatrick if (Expr) {
24609467b48Spatrick // According to
24709467b48Spatrick // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf
24809467b48Spatrick // cuda-gdb requires DW_AT_address_class for all variables to be able to
24909467b48Spatrick // correctly interpret address space of the variable address.
25009467b48Spatrick // Decode DW_OP_constu <DWARF Address Space> DW_OP_swap DW_OP_xderef
25109467b48Spatrick // sequence for the NVPTX + gdb target.
25209467b48Spatrick unsigned LocalNVPTXAddressSpace;
25309467b48Spatrick if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {
25409467b48Spatrick const DIExpression *NewExpr =
25509467b48Spatrick DIExpression::extractAddressClass(Expr, LocalNVPTXAddressSpace);
25609467b48Spatrick if (NewExpr != Expr) {
25709467b48Spatrick Expr = NewExpr;
25809467b48Spatrick NVPTXAddressSpace = LocalNVPTXAddressSpace;
25909467b48Spatrick }
26009467b48Spatrick }
26109467b48Spatrick DwarfExpr->addFragmentOffset(Expr);
26209467b48Spatrick }
26309467b48Spatrick
26409467b48Spatrick if (Global) {
26509467b48Spatrick const MCSymbol *Sym = Asm->getSymbol(Global);
266*d415bd75Srobert // 16-bit platforms like MSP430 and AVR take this path, so sink this
267*d415bd75Srobert // assert to platforms that use it.
268*d415bd75Srobert auto GetPointerSizedFormAndOp = [this]() {
269*d415bd75Srobert unsigned PointerSize = Asm->getDataLayout().getPointerSize();
270*d415bd75Srobert assert((PointerSize == 4 || PointerSize == 8) &&
271*d415bd75Srobert "Add support for other sizes if necessary");
272*d415bd75Srobert struct FormAndOp {
273*d415bd75Srobert dwarf::Form Form;
274*d415bd75Srobert dwarf::LocationAtom Op;
275*d415bd75Srobert };
276*d415bd75Srobert return PointerSize == 4
277*d415bd75Srobert ? FormAndOp{dwarf::DW_FORM_data4, dwarf::DW_OP_const4u}
278*d415bd75Srobert : FormAndOp{dwarf::DW_FORM_data8, dwarf::DW_OP_const8u};
279*d415bd75Srobert };
28009467b48Spatrick if (Global->isThreadLocal()) {
28109467b48Spatrick if (Asm->TM.useEmulatedTLS()) {
28209467b48Spatrick // TODO: add debug info for emulated thread local mode.
28309467b48Spatrick } else {
28409467b48Spatrick // FIXME: Make this work with -gsplit-dwarf.
28509467b48Spatrick // Based on GCC's support for TLS:
28609467b48Spatrick if (!DD->useSplitDwarf()) {
287*d415bd75Srobert auto FormAndOp = GetPointerSizedFormAndOp();
28809467b48Spatrick // 1) Start with a constNu of the appropriate pointer size
289*d415bd75Srobert addUInt(*Loc, dwarf::DW_FORM_data1, FormAndOp.Op);
29009467b48Spatrick // 2) containing the (relocated) offset of the TLS variable
29109467b48Spatrick // within the module's TLS block.
292*d415bd75Srobert addExpr(*Loc, FormAndOp.Form,
29309467b48Spatrick Asm->getObjFileLowering().getDebugThreadLocalSymbol(Sym));
29409467b48Spatrick } else {
29509467b48Spatrick addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index);
29609467b48Spatrick addUInt(*Loc, dwarf::DW_FORM_udata,
29709467b48Spatrick DD->getAddressPool().getIndex(Sym, /* TLS */ true));
29809467b48Spatrick }
29909467b48Spatrick // 3) followed by an OP to make the debugger do a TLS lookup.
30009467b48Spatrick addUInt(*Loc, dwarf::DW_FORM_data1,
30109467b48Spatrick DD->useGNUTLSOpcode() ? dwarf::DW_OP_GNU_push_tls_address
30209467b48Spatrick : dwarf::DW_OP_form_tls_address);
30309467b48Spatrick }
304*d415bd75Srobert } else if ((Asm->TM.getRelocationModel() == Reloc::RWPI ||
305*d415bd75Srobert Asm->TM.getRelocationModel() == Reloc::ROPI_RWPI) &&
306*d415bd75Srobert !Asm->getObjFileLowering()
307*d415bd75Srobert .getKindForGlobal(Global, Asm->TM)
308*d415bd75Srobert .isReadOnly()) {
309*d415bd75Srobert auto FormAndOp = GetPointerSizedFormAndOp();
310*d415bd75Srobert // Constant
311*d415bd75Srobert addUInt(*Loc, dwarf::DW_FORM_data1, FormAndOp.Op);
312*d415bd75Srobert // Relocation offset
313*d415bd75Srobert addExpr(*Loc, FormAndOp.Form,
314*d415bd75Srobert Asm->getObjFileLowering().getIndirectSymViaRWPI(Sym));
315*d415bd75Srobert // Base register
316*d415bd75Srobert Register BaseReg = Asm->getObjFileLowering().getStaticBase();
317*d415bd75Srobert BaseReg = Asm->TM.getMCRegisterInfo()->getDwarfRegNum(BaseReg, false);
318*d415bd75Srobert addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + BaseReg);
319*d415bd75Srobert // Offset from base register
320*d415bd75Srobert addSInt(*Loc, dwarf::DW_FORM_sdata, 0);
321*d415bd75Srobert // Operation
322*d415bd75Srobert addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
32309467b48Spatrick } else {
32409467b48Spatrick DD->addArangeLabel(SymbolCU(this, Sym));
32509467b48Spatrick addOpAddress(*Loc, Sym);
32609467b48Spatrick }
32709467b48Spatrick }
32809467b48Spatrick // Global variables attached to symbols are memory locations.
32909467b48Spatrick // It would be better if this were unconditional, but malformed input that
33009467b48Spatrick // mixes non-fragments and fragments for the same variable is too expensive
33109467b48Spatrick // to detect in the verifier.
33209467b48Spatrick if (DwarfExpr->isUnknownLocation())
33309467b48Spatrick DwarfExpr->setMemoryLocationKind();
33409467b48Spatrick DwarfExpr->addExpression(Expr);
33509467b48Spatrick }
33609467b48Spatrick if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {
33709467b48Spatrick // According to
33809467b48Spatrick // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf
33909467b48Spatrick // cuda-gdb requires DW_AT_address_class for all variables to be able to
34009467b48Spatrick // correctly interpret address space of the variable address.
34109467b48Spatrick const unsigned NVPTX_ADDR_global_space = 5;
34209467b48Spatrick addUInt(*VariableDIE, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1,
343*d415bd75Srobert NVPTXAddressSpace.value_or(NVPTX_ADDR_global_space));
34409467b48Spatrick }
34509467b48Spatrick if (Loc)
34609467b48Spatrick addBlock(*VariableDIE, dwarf::DW_AT_location, DwarfExpr->finalize());
34709467b48Spatrick
34809467b48Spatrick if (DD->useAllLinkageNames())
34909467b48Spatrick addLinkageName(*VariableDIE, GV->getLinkageName());
35009467b48Spatrick
35109467b48Spatrick if (addToAccelTable) {
35209467b48Spatrick DD->addAccelName(*CUNode, GV->getName(), *VariableDIE);
35309467b48Spatrick
35409467b48Spatrick // If the linkage name is different than the name, go ahead and output
35509467b48Spatrick // that as well into the name table.
35609467b48Spatrick if (GV->getLinkageName() != "" && GV->getName() != GV->getLinkageName() &&
35709467b48Spatrick DD->useAllLinkageNames())
35809467b48Spatrick DD->addAccelName(*CUNode, GV->getLinkageName(), *VariableDIE);
35909467b48Spatrick }
36009467b48Spatrick }
36109467b48Spatrick
getOrCreateCommonBlock(const DICommonBlock * CB,ArrayRef<GlobalExpr> GlobalExprs)36209467b48Spatrick DIE *DwarfCompileUnit::getOrCreateCommonBlock(
36309467b48Spatrick const DICommonBlock *CB, ArrayRef<GlobalExpr> GlobalExprs) {
364*d415bd75Srobert // Check for pre-existence.
36509467b48Spatrick if (DIE *NDie = getDIE(CB))
36609467b48Spatrick return NDie;
367*d415bd75Srobert DIE *ContextDIE = getOrCreateContextDIE(CB->getScope());
36809467b48Spatrick DIE &NDie = createAndAddDIE(dwarf::DW_TAG_common_block, *ContextDIE, CB);
36909467b48Spatrick StringRef Name = CB->getName().empty() ? "_BLNK_" : CB->getName();
37009467b48Spatrick addString(NDie, dwarf::DW_AT_name, Name);
37109467b48Spatrick addGlobalName(Name, NDie, CB->getScope());
37209467b48Spatrick if (CB->getFile())
37309467b48Spatrick addSourceLine(NDie, CB->getLineNo(), CB->getFile());
37409467b48Spatrick if (DIGlobalVariable *V = CB->getDecl())
37509467b48Spatrick getCU().addLocationAttribute(&NDie, V, GlobalExprs);
37609467b48Spatrick return &NDie;
37709467b48Spatrick }
37809467b48Spatrick
addRange(RangeSpan Range)37909467b48Spatrick void DwarfCompileUnit::addRange(RangeSpan Range) {
380097a140dSpatrick DD->insertSectionLabel(Range.Begin);
381097a140dSpatrick
382*d415bd75Srobert auto *PrevCU = DD->getPrevCU();
383*d415bd75Srobert bool SameAsPrevCU = this == PrevCU;
38409467b48Spatrick DD->setPrevCU(this);
38509467b48Spatrick // If we have no current ranges just add the range and return, otherwise,
38609467b48Spatrick // check the current section and CU against the previous section and CU we
38709467b48Spatrick // emitted into and the subprogram was contained within. If these are the
38809467b48Spatrick // same then extend our current range, otherwise add this as a new range.
38909467b48Spatrick if (CURanges.empty() || !SameAsPrevCU ||
39009467b48Spatrick (&CURanges.back().End->getSection() !=
39109467b48Spatrick &Range.End->getSection())) {
392*d415bd75Srobert // Before a new range is added, always terminate the prior line table.
393*d415bd75Srobert if (PrevCU)
394*d415bd75Srobert DD->terminateLineTable(PrevCU);
39509467b48Spatrick CURanges.push_back(Range);
39609467b48Spatrick return;
39709467b48Spatrick }
39809467b48Spatrick
39909467b48Spatrick CURanges.back().End = Range.End;
40009467b48Spatrick }
40109467b48Spatrick
initStmtList()40209467b48Spatrick void DwarfCompileUnit::initStmtList() {
40309467b48Spatrick if (CUNode->isDebugDirectivesOnly())
40409467b48Spatrick return;
40509467b48Spatrick
40609467b48Spatrick const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
40709467b48Spatrick if (DD->useSectionsAsReferences()) {
40809467b48Spatrick LineTableStartSym = TLOF.getDwarfLineSection()->getBeginSymbol();
40909467b48Spatrick } else {
41009467b48Spatrick LineTableStartSym =
41109467b48Spatrick Asm->OutStreamer->getDwarfLineTableSymbol(getUniqueID());
41209467b48Spatrick }
41309467b48Spatrick
41409467b48Spatrick // DW_AT_stmt_list is a offset of line number information for this
41509467b48Spatrick // compile unit in debug_line section. For split dwarf this is
41609467b48Spatrick // left in the skeleton CU and so not included.
41709467b48Spatrick // The line table entries are not always emitted in assembly, so it
41809467b48Spatrick // is not okay to use line_table_start here.
41909467b48Spatrick addSectionLabel(getUnitDie(), dwarf::DW_AT_stmt_list, LineTableStartSym,
42009467b48Spatrick TLOF.getDwarfLineSection()->getBeginSymbol());
42109467b48Spatrick }
42209467b48Spatrick
applyStmtList(DIE & D)42309467b48Spatrick void DwarfCompileUnit::applyStmtList(DIE &D) {
424097a140dSpatrick const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
425097a140dSpatrick addSectionLabel(D, dwarf::DW_AT_stmt_list, LineTableStartSym,
426097a140dSpatrick TLOF.getDwarfLineSection()->getBeginSymbol());
42709467b48Spatrick }
42809467b48Spatrick
attachLowHighPC(DIE & D,const MCSymbol * Begin,const MCSymbol * End)42909467b48Spatrick void DwarfCompileUnit::attachLowHighPC(DIE &D, const MCSymbol *Begin,
43009467b48Spatrick const MCSymbol *End) {
43109467b48Spatrick assert(Begin && "Begin label should not be null!");
43209467b48Spatrick assert(End && "End label should not be null!");
43309467b48Spatrick assert(Begin->isDefined() && "Invalid starting label");
43409467b48Spatrick assert(End->isDefined() && "Invalid end label");
43509467b48Spatrick
43609467b48Spatrick addLabelAddress(D, dwarf::DW_AT_low_pc, Begin);
43709467b48Spatrick if (DD->getDwarfVersion() < 4)
43809467b48Spatrick addLabelAddress(D, dwarf::DW_AT_high_pc, End);
43909467b48Spatrick else
44009467b48Spatrick addLabelDelta(D, dwarf::DW_AT_high_pc, End, Begin);
44109467b48Spatrick }
44209467b48Spatrick
44309467b48Spatrick // Find DIE for the given subprogram and attach appropriate DW_AT_low_pc
44409467b48Spatrick // and DW_AT_high_pc attributes. If there are global variables in this
44509467b48Spatrick // scope then create and insert DIEs for these variables.
updateSubprogramScopeDIE(const DISubprogram * SP)44609467b48Spatrick DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP) {
44709467b48Spatrick DIE *SPDie = getOrCreateSubprogramDIE(SP, includeMinimalInlineScopes());
448*d415bd75Srobert auto *ContextCU = static_cast<DwarfCompileUnit *>(SPDie->getUnit());
449*d415bd75Srobert return ContextCU->updateSubprogramScopeDIEImpl(SP, SPDie);
450*d415bd75Srobert }
45109467b48Spatrick
updateSubprogramScopeDIEImpl(const DISubprogram * SP,DIE * SPDie)452*d415bd75Srobert DIE &DwarfCompileUnit::updateSubprogramScopeDIEImpl(const DISubprogram *SP,
453*d415bd75Srobert DIE *SPDie) {
454097a140dSpatrick SmallVector<RangeSpan, 2> BB_List;
455097a140dSpatrick // If basic block sections are on, ranges for each basic block section has
456097a140dSpatrick // to be emitted separately.
457097a140dSpatrick for (const auto &R : Asm->MBBSectionRanges)
458097a140dSpatrick BB_List.push_back({R.second.BeginLabel, R.second.EndLabel});
459097a140dSpatrick
460097a140dSpatrick attachRangesOrLowHighPC(*SPDie, BB_List);
461097a140dSpatrick
46209467b48Spatrick if (DD->useAppleExtensionAttributes() &&
46309467b48Spatrick !DD->getCurrentFunction()->getTarget().Options.DisableFramePointerElim(
46409467b48Spatrick *DD->getCurrentFunction()))
46509467b48Spatrick addFlag(*SPDie, dwarf::DW_AT_APPLE_omit_frame_ptr);
46609467b48Spatrick
46709467b48Spatrick // Only include DW_AT_frame_base in full debug info
46809467b48Spatrick if (!includeMinimalInlineScopes()) {
469097a140dSpatrick const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();
470097a140dSpatrick TargetFrameLowering::DwarfFrameBase FrameBase =
471097a140dSpatrick TFI->getDwarfFrameBase(*Asm->MF);
472097a140dSpatrick switch (FrameBase.Kind) {
473097a140dSpatrick case TargetFrameLowering::DwarfFrameBase::Register: {
474097a140dSpatrick if (Register::isPhysicalRegister(FrameBase.Location.Reg)) {
475097a140dSpatrick MachineLocation Location(FrameBase.Location.Reg);
476097a140dSpatrick addAddress(*SPDie, dwarf::DW_AT_frame_base, Location);
477097a140dSpatrick }
478097a140dSpatrick break;
479097a140dSpatrick }
480097a140dSpatrick case TargetFrameLowering::DwarfFrameBase::CFA: {
48109467b48Spatrick DIELoc *Loc = new (DIEValueAllocator) DIELoc;
48209467b48Spatrick addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_call_frame_cfa);
48309467b48Spatrick addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc);
484097a140dSpatrick break;
485097a140dSpatrick }
486097a140dSpatrick case TargetFrameLowering::DwarfFrameBase::WasmFrameBase: {
487097a140dSpatrick // FIXME: duplicated from Target/WebAssembly/WebAssembly.h
488097a140dSpatrick // don't want to depend on target specific headers in this code?
489097a140dSpatrick const unsigned TI_GLOBAL_RELOC = 3;
490097a140dSpatrick if (FrameBase.Location.WasmLoc.Kind == TI_GLOBAL_RELOC) {
491097a140dSpatrick // These need to be relocatable.
492097a140dSpatrick assert(FrameBase.Location.WasmLoc.Index == 0); // Only SP so far.
493097a140dSpatrick auto SPSym = cast<MCSymbolWasm>(
494097a140dSpatrick Asm->GetExternalSymbolSymbol("__stack_pointer"));
495097a140dSpatrick // FIXME: this repeats what WebAssemblyMCInstLower::
496097a140dSpatrick // GetExternalSymbolSymbol does, since if there's no code that
497097a140dSpatrick // refers to this symbol, we have to set it here.
498097a140dSpatrick SPSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
499097a140dSpatrick SPSym->setGlobalType(wasm::WasmGlobalType{
500097a140dSpatrick uint8_t(Asm->getSubtargetInfo().getTargetTriple().getArch() ==
501097a140dSpatrick Triple::wasm64
502097a140dSpatrick ? wasm::WASM_TYPE_I64
503097a140dSpatrick : wasm::WASM_TYPE_I32),
504097a140dSpatrick true});
505097a140dSpatrick DIELoc *Loc = new (DIEValueAllocator) DIELoc;
506097a140dSpatrick addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_WASM_location);
50773471bf0Spatrick addSInt(*Loc, dwarf::DW_FORM_sdata, TI_GLOBAL_RELOC);
50873471bf0Spatrick if (!isDwoUnit()) {
50973471bf0Spatrick addLabel(*Loc, dwarf::DW_FORM_data4, SPSym);
51073471bf0Spatrick } else {
51173471bf0Spatrick // FIXME: when writing dwo, we need to avoid relocations. Probably
51273471bf0Spatrick // the "right" solution is to treat globals the way func and data
51373471bf0Spatrick // symbols are (with entries in .debug_addr).
51473471bf0Spatrick // For now, since we only ever use index 0, this should work as-is.
51573471bf0Spatrick addUInt(*Loc, dwarf::DW_FORM_data4, FrameBase.Location.WasmLoc.Index);
51673471bf0Spatrick }
517097a140dSpatrick addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value);
518097a140dSpatrick addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc);
51909467b48Spatrick } else {
520097a140dSpatrick DIELoc *Loc = new (DIEValueAllocator) DIELoc;
521097a140dSpatrick DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
522097a140dSpatrick DIExpressionCursor Cursor({});
523097a140dSpatrick DwarfExpr.addWasmLocation(FrameBase.Location.WasmLoc.Kind,
524097a140dSpatrick FrameBase.Location.WasmLoc.Index);
525097a140dSpatrick DwarfExpr.addExpression(std::move(Cursor));
526097a140dSpatrick addBlock(*SPDie, dwarf::DW_AT_frame_base, DwarfExpr.finalize());
527097a140dSpatrick }
528097a140dSpatrick break;
529097a140dSpatrick }
53009467b48Spatrick }
53109467b48Spatrick }
53209467b48Spatrick
53309467b48Spatrick // Add name to the name table, we do this here because we're guaranteed
53409467b48Spatrick // to have concrete versions of our DW_TAG_subprogram nodes.
53509467b48Spatrick DD->addSubprogramNames(*CUNode, SP, *SPDie);
53609467b48Spatrick
53709467b48Spatrick return *SPDie;
53809467b48Spatrick }
53909467b48Spatrick
54009467b48Spatrick // Construct a DIE for this scope.
constructScopeDIE(LexicalScope * Scope,DIE & ParentScopeDIE)541*d415bd75Srobert void DwarfCompileUnit::constructScopeDIE(LexicalScope *Scope,
542*d415bd75Srobert DIE &ParentScopeDIE) {
54309467b48Spatrick if (!Scope || !Scope->getScopeNode())
54409467b48Spatrick return;
54509467b48Spatrick
54609467b48Spatrick auto *DS = Scope->getScopeNode();
54709467b48Spatrick
54809467b48Spatrick assert((Scope->getInlinedAt() || !isa<DISubprogram>(DS)) &&
54909467b48Spatrick "Only handle inlined subprograms here, use "
55009467b48Spatrick "constructSubprogramScopeDIE for non-inlined "
55109467b48Spatrick "subprograms");
55209467b48Spatrick
553*d415bd75Srobert // Emit inlined subprograms.
55409467b48Spatrick if (Scope->getParent() && isa<DISubprogram>(DS)) {
555*d415bd75Srobert DIE *ScopeDIE = constructInlinedScopeDIE(Scope, ParentScopeDIE);
556*d415bd75Srobert assert(ScopeDIE && "Scope DIE should not be null.");
557*d415bd75Srobert createAndAddScopeChildren(Scope, *ScopeDIE);
55809467b48Spatrick return;
559*d415bd75Srobert }
560*d415bd75Srobert
56109467b48Spatrick // Early exit when we know the scope DIE is going to be null.
56209467b48Spatrick if (DD->isLexicalScopeDIENull(Scope))
56309467b48Spatrick return;
56409467b48Spatrick
565*d415bd75Srobert // Emit lexical blocks.
566*d415bd75Srobert DIE *ScopeDIE = constructLexicalScopeDIE(Scope);
56709467b48Spatrick assert(ScopeDIE && "Scope DIE should not be null.");
56809467b48Spatrick
569*d415bd75Srobert ParentScopeDIE.addChild(ScopeDIE);
570*d415bd75Srobert createAndAddScopeChildren(Scope, *ScopeDIE);
57109467b48Spatrick }
57209467b48Spatrick
addScopeRangeList(DIE & ScopeDIE,SmallVector<RangeSpan,2> Range)57309467b48Spatrick void DwarfCompileUnit::addScopeRangeList(DIE &ScopeDIE,
57409467b48Spatrick SmallVector<RangeSpan, 2> Range) {
57509467b48Spatrick
57609467b48Spatrick HasRangeLists = true;
57709467b48Spatrick
57809467b48Spatrick // Add the range list to the set of ranges to be emitted.
57909467b48Spatrick auto IndexAndList =
58009467b48Spatrick (DD->getDwarfVersion() < 5 && Skeleton ? Skeleton->DU : DU)
58109467b48Spatrick ->addRange(*(Skeleton ? Skeleton : this), std::move(Range));
58209467b48Spatrick
58309467b48Spatrick uint32_t Index = IndexAndList.first;
58409467b48Spatrick auto &List = *IndexAndList.second;
58509467b48Spatrick
58609467b48Spatrick // Under fission, ranges are specified by constant offsets relative to the
58709467b48Spatrick // CU's DW_AT_GNU_ranges_base.
58809467b48Spatrick // FIXME: For DWARF v5, do not generate the DW_AT_ranges attribute under
58909467b48Spatrick // fission until we support the forms using the .debug_addr section
59009467b48Spatrick // (DW_RLE_startx_endx etc.).
59109467b48Spatrick if (DD->getDwarfVersion() >= 5)
59209467b48Spatrick addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_rnglistx, Index);
59309467b48Spatrick else {
59409467b48Spatrick const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
59509467b48Spatrick const MCSymbol *RangeSectionSym =
59609467b48Spatrick TLOF.getDwarfRangesSection()->getBeginSymbol();
59709467b48Spatrick if (isDwoUnit())
59809467b48Spatrick addSectionDelta(ScopeDIE, dwarf::DW_AT_ranges, List.Label,
59909467b48Spatrick RangeSectionSym);
60009467b48Spatrick else
60109467b48Spatrick addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges, List.Label,
60209467b48Spatrick RangeSectionSym);
60309467b48Spatrick }
60409467b48Spatrick }
60509467b48Spatrick
attachRangesOrLowHighPC(DIE & Die,SmallVector<RangeSpan,2> Ranges)60609467b48Spatrick void DwarfCompileUnit::attachRangesOrLowHighPC(
60709467b48Spatrick DIE &Die, SmallVector<RangeSpan, 2> Ranges) {
60873471bf0Spatrick assert(!Ranges.empty());
60973471bf0Spatrick if (!DD->useRangesSection() ||
61073471bf0Spatrick (Ranges.size() == 1 &&
61173471bf0Spatrick (!DD->alwaysUseRanges() ||
61273471bf0Spatrick DD->getSectionLabel(&Ranges.front().Begin->getSection()) ==
61373471bf0Spatrick Ranges.front().Begin))) {
61409467b48Spatrick const RangeSpan &Front = Ranges.front();
61509467b48Spatrick const RangeSpan &Back = Ranges.back();
61609467b48Spatrick attachLowHighPC(Die, Front.Begin, Back.End);
61709467b48Spatrick } else
61809467b48Spatrick addScopeRangeList(Die, std::move(Ranges));
61909467b48Spatrick }
62009467b48Spatrick
attachRangesOrLowHighPC(DIE & Die,const SmallVectorImpl<InsnRange> & Ranges)62109467b48Spatrick void DwarfCompileUnit::attachRangesOrLowHighPC(
62209467b48Spatrick DIE &Die, const SmallVectorImpl<InsnRange> &Ranges) {
62309467b48Spatrick SmallVector<RangeSpan, 2> List;
62409467b48Spatrick List.reserve(Ranges.size());
625097a140dSpatrick for (const InsnRange &R : Ranges) {
626097a140dSpatrick auto *BeginLabel = DD->getLabelBeforeInsn(R.first);
627097a140dSpatrick auto *EndLabel = DD->getLabelAfterInsn(R.second);
628097a140dSpatrick
629097a140dSpatrick const auto *BeginMBB = R.first->getParent();
630097a140dSpatrick const auto *EndMBB = R.second->getParent();
631097a140dSpatrick
632097a140dSpatrick const auto *MBB = BeginMBB;
633097a140dSpatrick // Basic block sections allows basic block subsets to be placed in unique
634097a140dSpatrick // sections. For each section, the begin and end label must be added to the
635097a140dSpatrick // list. If there is more than one range, debug ranges must be used.
636097a140dSpatrick // Otherwise, low/high PC can be used.
637097a140dSpatrick // FIXME: Debug Info Emission depends on block order and this assumes that
638097a140dSpatrick // the order of blocks will be frozen beyond this point.
639097a140dSpatrick do {
640097a140dSpatrick if (MBB->sameSection(EndMBB) || MBB->isEndSection()) {
641097a140dSpatrick auto MBBSectionRange = Asm->MBBSectionRanges[MBB->getSectionIDNum()];
64209467b48Spatrick List.push_back(
643097a140dSpatrick {MBB->sameSection(BeginMBB) ? BeginLabel
644097a140dSpatrick : MBBSectionRange.BeginLabel,
645097a140dSpatrick MBB->sameSection(EndMBB) ? EndLabel : MBBSectionRange.EndLabel});
646097a140dSpatrick }
647097a140dSpatrick if (MBB->sameSection(EndMBB))
648097a140dSpatrick break;
649097a140dSpatrick MBB = MBB->getNextNode();
650097a140dSpatrick } while (true);
651097a140dSpatrick }
65209467b48Spatrick attachRangesOrLowHighPC(Die, std::move(List));
65309467b48Spatrick }
65409467b48Spatrick
constructInlinedScopeDIE(LexicalScope * Scope,DIE & ParentScopeDIE)655*d415bd75Srobert DIE *DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope,
656*d415bd75Srobert DIE &ParentScopeDIE) {
65709467b48Spatrick assert(Scope->getScopeNode());
65809467b48Spatrick auto *DS = Scope->getScopeNode();
65909467b48Spatrick auto *InlinedSP = getDISubprogram(DS);
66009467b48Spatrick // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram
66109467b48Spatrick // was inlined from another compile unit.
66209467b48Spatrick DIE *OriginDIE = getAbstractSPDies()[InlinedSP];
66309467b48Spatrick assert(OriginDIE && "Unable to find original DIE for an inlined subprogram.");
66409467b48Spatrick
66509467b48Spatrick auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_inlined_subroutine);
666*d415bd75Srobert ParentScopeDIE.addChild(ScopeDIE);
66709467b48Spatrick addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *OriginDIE);
66809467b48Spatrick
66909467b48Spatrick attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges());
67009467b48Spatrick
67109467b48Spatrick // Add the call site information to the DIE.
67209467b48Spatrick const DILocation *IA = Scope->getInlinedAt();
673*d415bd75Srobert addUInt(*ScopeDIE, dwarf::DW_AT_call_file, std::nullopt,
67409467b48Spatrick getOrCreateSourceID(IA->getFile()));
675*d415bd75Srobert addUInt(*ScopeDIE, dwarf::DW_AT_call_line, std::nullopt, IA->getLine());
67609467b48Spatrick if (IA->getColumn())
677*d415bd75Srobert addUInt(*ScopeDIE, dwarf::DW_AT_call_column, std::nullopt, IA->getColumn());
67809467b48Spatrick if (IA->getDiscriminator() && DD->getDwarfVersion() >= 4)
679*d415bd75Srobert addUInt(*ScopeDIE, dwarf::DW_AT_GNU_discriminator, std::nullopt,
68009467b48Spatrick IA->getDiscriminator());
68109467b48Spatrick
68209467b48Spatrick // Add name to the name table, we do this here because we're guaranteed
68309467b48Spatrick // to have concrete versions of our DW_TAG_inlined_subprogram nodes.
68409467b48Spatrick DD->addSubprogramNames(*CUNode, InlinedSP, *ScopeDIE);
68509467b48Spatrick
68609467b48Spatrick return ScopeDIE;
68709467b48Spatrick }
68809467b48Spatrick
68909467b48Spatrick // Construct new DW_TAG_lexical_block for this scope and attach
69009467b48Spatrick // DW_AT_low_pc/DW_AT_high_pc labels.
constructLexicalScopeDIE(LexicalScope * Scope)69109467b48Spatrick DIE *DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) {
69209467b48Spatrick if (DD->isLexicalScopeDIENull(Scope))
69309467b48Spatrick return nullptr;
69409467b48Spatrick
69509467b48Spatrick auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_lexical_block);
69609467b48Spatrick if (Scope->isAbstractScope())
69709467b48Spatrick return ScopeDIE;
69809467b48Spatrick
69909467b48Spatrick attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges());
70009467b48Spatrick
70109467b48Spatrick return ScopeDIE;
70209467b48Spatrick }
70309467b48Spatrick
70409467b48Spatrick /// constructVariableDIE - Construct a DIE for the given DbgVariable.
constructVariableDIE(DbgVariable & DV,bool Abstract)70509467b48Spatrick DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, bool Abstract) {
70609467b48Spatrick auto D = constructVariableDIEImpl(DV, Abstract);
70709467b48Spatrick DV.setDIE(*D);
70809467b48Spatrick return D;
70909467b48Spatrick }
71009467b48Spatrick
constructLabelDIE(DbgLabel & DL,const LexicalScope & Scope)71109467b48Spatrick DIE *DwarfCompileUnit::constructLabelDIE(DbgLabel &DL,
71209467b48Spatrick const LexicalScope &Scope) {
71309467b48Spatrick auto LabelDie = DIE::get(DIEValueAllocator, DL.getTag());
71409467b48Spatrick insertDIE(DL.getLabel(), LabelDie);
71509467b48Spatrick DL.setDIE(*LabelDie);
71609467b48Spatrick
71709467b48Spatrick if (Scope.isAbstractScope())
71809467b48Spatrick applyLabelAttributes(DL, *LabelDie);
71909467b48Spatrick
72009467b48Spatrick return LabelDie;
72109467b48Spatrick }
72209467b48Spatrick
constructVariableDIEImpl(const DbgVariable & DV,bool Abstract)72309467b48Spatrick DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
72409467b48Spatrick bool Abstract) {
72509467b48Spatrick // Define variable debug information entry.
72609467b48Spatrick auto VariableDie = DIE::get(DIEValueAllocator, DV.getTag());
72709467b48Spatrick insertDIE(DV.getVariable(), VariableDie);
72809467b48Spatrick
72909467b48Spatrick if (Abstract) {
73009467b48Spatrick applyVariableAttributes(DV, *VariableDie);
73109467b48Spatrick return VariableDie;
73209467b48Spatrick }
73309467b48Spatrick
73409467b48Spatrick // Add variable address.
73509467b48Spatrick
73673471bf0Spatrick unsigned Index = DV.getDebugLocListIndex();
73773471bf0Spatrick if (Index != ~0U) {
73873471bf0Spatrick addLocationList(*VariableDie, dwarf::DW_AT_location, Index);
73909467b48Spatrick auto TagOffset = DV.getDebugLocListTagOffset();
74009467b48Spatrick if (TagOffset)
74109467b48Spatrick addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
74209467b48Spatrick *TagOffset);
74309467b48Spatrick return VariableDie;
74409467b48Spatrick }
74509467b48Spatrick
74609467b48Spatrick // Check if variable has a single location description.
74709467b48Spatrick if (auto *DVal = DV.getValueLoc()) {
74873471bf0Spatrick if (!DVal->isVariadic()) {
74973471bf0Spatrick const DbgValueLocEntry *Entry = DVal->getLocEntries().begin();
75073471bf0Spatrick if (Entry->isLocation()) {
75173471bf0Spatrick addVariableAddress(DV, *VariableDie, Entry->getLoc());
75273471bf0Spatrick } else if (Entry->isInt()) {
75309467b48Spatrick auto *Expr = DV.getSingleExpression();
75409467b48Spatrick if (Expr && Expr->getNumElements()) {
75509467b48Spatrick DIELoc *Loc = new (DIEValueAllocator) DIELoc;
75609467b48Spatrick DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
75709467b48Spatrick // If there is an expression, emit raw unsigned bytes.
75809467b48Spatrick DwarfExpr.addFragmentOffset(Expr);
75973471bf0Spatrick DwarfExpr.addUnsignedConstant(Entry->getInt());
76009467b48Spatrick DwarfExpr.addExpression(Expr);
76109467b48Spatrick addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
76209467b48Spatrick if (DwarfExpr.TagOffset)
76309467b48Spatrick addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset,
76409467b48Spatrick dwarf::DW_FORM_data1, *DwarfExpr.TagOffset);
76509467b48Spatrick } else
76673471bf0Spatrick addConstantValue(*VariableDie, Entry->getInt(), DV.getType());
76773471bf0Spatrick } else if (Entry->isConstantFP()) {
76873471bf0Spatrick addConstantFPValue(*VariableDie, Entry->getConstantFP());
76973471bf0Spatrick } else if (Entry->isConstantInt()) {
77073471bf0Spatrick addConstantValue(*VariableDie, Entry->getConstantInt(), DV.getType());
77173471bf0Spatrick } else if (Entry->isTargetIndexLocation()) {
77273471bf0Spatrick DIELoc *Loc = new (DIEValueAllocator) DIELoc;
77373471bf0Spatrick DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
77473471bf0Spatrick const DIBasicType *BT = dyn_cast<DIBasicType>(
77573471bf0Spatrick static_cast<const Metadata *>(DV.getVariable()->getType()));
77673471bf0Spatrick DwarfDebug::emitDebugLocValue(*Asm, BT, *DVal, DwarfExpr);
77773471bf0Spatrick addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
77809467b48Spatrick }
77909467b48Spatrick return VariableDie;
78009467b48Spatrick }
78173471bf0Spatrick // If any of the location entries are registers with the value 0, then the
78273471bf0Spatrick // location is undefined.
78373471bf0Spatrick if (any_of(DVal->getLocEntries(), [](const DbgValueLocEntry &Entry) {
78473471bf0Spatrick return Entry.isLocation() && !Entry.getLoc().getReg();
78573471bf0Spatrick }))
78673471bf0Spatrick return VariableDie;
78773471bf0Spatrick const DIExpression *Expr = DV.getSingleExpression();
78873471bf0Spatrick assert(Expr && "Variadic Debug Value must have an Expression.");
78973471bf0Spatrick DIELoc *Loc = new (DIEValueAllocator) DIELoc;
79073471bf0Spatrick DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
79173471bf0Spatrick DwarfExpr.addFragmentOffset(Expr);
79273471bf0Spatrick DIExpressionCursor Cursor(Expr);
79373471bf0Spatrick const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
79473471bf0Spatrick
79573471bf0Spatrick auto AddEntry = [&](const DbgValueLocEntry &Entry,
79673471bf0Spatrick DIExpressionCursor &Cursor) {
79773471bf0Spatrick if (Entry.isLocation()) {
79873471bf0Spatrick if (!DwarfExpr.addMachineRegExpression(TRI, Cursor,
79973471bf0Spatrick Entry.getLoc().getReg()))
80073471bf0Spatrick return false;
80173471bf0Spatrick } else if (Entry.isInt()) {
80273471bf0Spatrick // If there is an expression, emit raw unsigned bytes.
80373471bf0Spatrick DwarfExpr.addUnsignedConstant(Entry.getInt());
80473471bf0Spatrick } else if (Entry.isConstantFP()) {
805*d415bd75Srobert // DwarfExpression does not support arguments wider than 64 bits
806*d415bd75Srobert // (see PR52584).
807*d415bd75Srobert // TODO: Consider chunking expressions containing overly wide
808*d415bd75Srobert // arguments into separate pointer-sized fragment expressions.
80973471bf0Spatrick APInt RawBytes = Entry.getConstantFP()->getValueAPF().bitcastToAPInt();
810*d415bd75Srobert if (RawBytes.getBitWidth() > 64)
811*d415bd75Srobert return false;
812*d415bd75Srobert DwarfExpr.addUnsignedConstant(RawBytes.getZExtValue());
81373471bf0Spatrick } else if (Entry.isConstantInt()) {
81473471bf0Spatrick APInt RawBytes = Entry.getConstantInt()->getValue();
815*d415bd75Srobert if (RawBytes.getBitWidth() > 64)
816*d415bd75Srobert return false;
817*d415bd75Srobert DwarfExpr.addUnsignedConstant(RawBytes.getZExtValue());
81873471bf0Spatrick } else if (Entry.isTargetIndexLocation()) {
81973471bf0Spatrick TargetIndexLocation Loc = Entry.getTargetIndexLocation();
82073471bf0Spatrick // TODO TargetIndexLocation is a target-independent. Currently only the
82173471bf0Spatrick // WebAssembly-specific encoding is supported.
82273471bf0Spatrick assert(Asm->TM.getTargetTriple().isWasm());
82373471bf0Spatrick DwarfExpr.addWasmLocation(Loc.Index, static_cast<uint64_t>(Loc.Offset));
82473471bf0Spatrick } else {
82573471bf0Spatrick llvm_unreachable("Unsupported Entry type.");
82673471bf0Spatrick }
82773471bf0Spatrick return true;
82873471bf0Spatrick };
82973471bf0Spatrick
830*d415bd75Srobert if (!DwarfExpr.addExpression(
83173471bf0Spatrick std::move(Cursor),
83273471bf0Spatrick [&](unsigned Idx, DIExpressionCursor &Cursor) -> bool {
83373471bf0Spatrick return AddEntry(DVal->getLocEntries()[Idx], Cursor);
834*d415bd75Srobert }))
835*d415bd75Srobert return VariableDie;
83673471bf0Spatrick
83773471bf0Spatrick // Now attach the location information to the DIE.
83873471bf0Spatrick addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
83973471bf0Spatrick if (DwarfExpr.TagOffset)
84073471bf0Spatrick addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
84173471bf0Spatrick *DwarfExpr.TagOffset);
84273471bf0Spatrick
84373471bf0Spatrick return VariableDie;
84473471bf0Spatrick }
84509467b48Spatrick
84609467b48Spatrick // .. else use frame index.
84709467b48Spatrick if (!DV.hasFrameIndexExprs())
84809467b48Spatrick return VariableDie;
84909467b48Spatrick
850*d415bd75Srobert std::optional<unsigned> NVPTXAddressSpace;
85109467b48Spatrick DIELoc *Loc = new (DIEValueAllocator) DIELoc;
85209467b48Spatrick DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
853*d415bd75Srobert for (const auto &Fragment : DV.getFrameIndexExprs()) {
854097a140dSpatrick Register FrameReg;
85509467b48Spatrick const DIExpression *Expr = Fragment.Expr;
85609467b48Spatrick const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();
85773471bf0Spatrick StackOffset Offset =
85873471bf0Spatrick TFI->getFrameIndexReference(*Asm->MF, Fragment.FI, FrameReg);
85909467b48Spatrick DwarfExpr.addFragmentOffset(Expr);
86073471bf0Spatrick
86173471bf0Spatrick auto *TRI = Asm->MF->getSubtarget().getRegisterInfo();
86209467b48Spatrick SmallVector<uint64_t, 8> Ops;
86373471bf0Spatrick TRI->getOffsetOpcodes(Offset, Ops);
86473471bf0Spatrick
86509467b48Spatrick // According to
86609467b48Spatrick // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf
86709467b48Spatrick // cuda-gdb requires DW_AT_address_class for all variables to be able to
86809467b48Spatrick // correctly interpret address space of the variable address.
86909467b48Spatrick // Decode DW_OP_constu <DWARF Address Space> DW_OP_swap DW_OP_xderef
87009467b48Spatrick // sequence for the NVPTX + gdb target.
87109467b48Spatrick unsigned LocalNVPTXAddressSpace;
87209467b48Spatrick if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {
87309467b48Spatrick const DIExpression *NewExpr =
87409467b48Spatrick DIExpression::extractAddressClass(Expr, LocalNVPTXAddressSpace);
87509467b48Spatrick if (NewExpr != Expr) {
87609467b48Spatrick Expr = NewExpr;
87709467b48Spatrick NVPTXAddressSpace = LocalNVPTXAddressSpace;
87809467b48Spatrick }
87909467b48Spatrick }
88009467b48Spatrick if (Expr)
88109467b48Spatrick Ops.append(Expr->elements_begin(), Expr->elements_end());
88209467b48Spatrick DIExpressionCursor Cursor(Ops);
88309467b48Spatrick DwarfExpr.setMemoryLocationKind();
88409467b48Spatrick if (const MCSymbol *FrameSymbol = Asm->getFunctionFrameSymbol())
88509467b48Spatrick addOpAddress(*Loc, FrameSymbol);
88609467b48Spatrick else
88709467b48Spatrick DwarfExpr.addMachineRegExpression(
88809467b48Spatrick *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, FrameReg);
88909467b48Spatrick DwarfExpr.addExpression(std::move(Cursor));
89009467b48Spatrick }
89109467b48Spatrick if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {
89209467b48Spatrick // According to
89309467b48Spatrick // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf
89409467b48Spatrick // cuda-gdb requires DW_AT_address_class for all variables to be able to
89509467b48Spatrick // correctly interpret address space of the variable address.
89609467b48Spatrick const unsigned NVPTX_ADDR_local_space = 6;
89709467b48Spatrick addUInt(*VariableDie, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1,
898*d415bd75Srobert NVPTXAddressSpace.value_or(NVPTX_ADDR_local_space));
89909467b48Spatrick }
90009467b48Spatrick addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
90109467b48Spatrick if (DwarfExpr.TagOffset)
90209467b48Spatrick addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
90309467b48Spatrick *DwarfExpr.TagOffset);
90409467b48Spatrick
90509467b48Spatrick return VariableDie;
90609467b48Spatrick }
90709467b48Spatrick
constructVariableDIE(DbgVariable & DV,const LexicalScope & Scope,DIE * & ObjectPointer)90809467b48Spatrick DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV,
90909467b48Spatrick const LexicalScope &Scope,
91009467b48Spatrick DIE *&ObjectPointer) {
91109467b48Spatrick auto Var = constructVariableDIE(DV, Scope.isAbstractScope());
91209467b48Spatrick if (DV.isObjectPointer())
91309467b48Spatrick ObjectPointer = Var;
91409467b48Spatrick return Var;
91509467b48Spatrick }
91609467b48Spatrick
91709467b48Spatrick /// Return all DIVariables that appear in count: expressions.
dependencies(DbgVariable * Var)91809467b48Spatrick static SmallVector<const DIVariable *, 2> dependencies(DbgVariable *Var) {
91909467b48Spatrick SmallVector<const DIVariable *, 2> Result;
92009467b48Spatrick auto *Array = dyn_cast<DICompositeType>(Var->getType());
92109467b48Spatrick if (!Array || Array->getTag() != dwarf::DW_TAG_array_type)
92209467b48Spatrick return Result;
923097a140dSpatrick if (auto *DLVar = Array->getDataLocation())
924097a140dSpatrick Result.push_back(DLVar);
92573471bf0Spatrick if (auto *AsVar = Array->getAssociated())
92673471bf0Spatrick Result.push_back(AsVar);
92773471bf0Spatrick if (auto *AlVar = Array->getAllocated())
92873471bf0Spatrick Result.push_back(AlVar);
92909467b48Spatrick for (auto *El : Array->getElements()) {
93009467b48Spatrick if (auto *Subrange = dyn_cast<DISubrange>(El)) {
931097a140dSpatrick if (auto Count = Subrange->getCount())
93209467b48Spatrick if (auto *Dependency = Count.dyn_cast<DIVariable *>())
93309467b48Spatrick Result.push_back(Dependency);
934097a140dSpatrick if (auto LB = Subrange->getLowerBound())
935097a140dSpatrick if (auto *Dependency = LB.dyn_cast<DIVariable *>())
936097a140dSpatrick Result.push_back(Dependency);
937097a140dSpatrick if (auto UB = Subrange->getUpperBound())
938097a140dSpatrick if (auto *Dependency = UB.dyn_cast<DIVariable *>())
939097a140dSpatrick Result.push_back(Dependency);
940097a140dSpatrick if (auto ST = Subrange->getStride())
941097a140dSpatrick if (auto *Dependency = ST.dyn_cast<DIVariable *>())
942097a140dSpatrick Result.push_back(Dependency);
94373471bf0Spatrick } else if (auto *GenericSubrange = dyn_cast<DIGenericSubrange>(El)) {
94473471bf0Spatrick if (auto Count = GenericSubrange->getCount())
94573471bf0Spatrick if (auto *Dependency = Count.dyn_cast<DIVariable *>())
94673471bf0Spatrick Result.push_back(Dependency);
94773471bf0Spatrick if (auto LB = GenericSubrange->getLowerBound())
94873471bf0Spatrick if (auto *Dependency = LB.dyn_cast<DIVariable *>())
94973471bf0Spatrick Result.push_back(Dependency);
95073471bf0Spatrick if (auto UB = GenericSubrange->getUpperBound())
95173471bf0Spatrick if (auto *Dependency = UB.dyn_cast<DIVariable *>())
95273471bf0Spatrick Result.push_back(Dependency);
95373471bf0Spatrick if (auto ST = GenericSubrange->getStride())
95473471bf0Spatrick if (auto *Dependency = ST.dyn_cast<DIVariable *>())
95573471bf0Spatrick Result.push_back(Dependency);
95609467b48Spatrick }
95709467b48Spatrick }
95809467b48Spatrick return Result;
95909467b48Spatrick }
96009467b48Spatrick
96109467b48Spatrick /// Sort local variables so that variables appearing inside of helper
96209467b48Spatrick /// expressions come first.
96309467b48Spatrick static SmallVector<DbgVariable *, 8>
sortLocalVars(SmallVectorImpl<DbgVariable * > & Input)96409467b48Spatrick sortLocalVars(SmallVectorImpl<DbgVariable *> &Input) {
96509467b48Spatrick SmallVector<DbgVariable *, 8> Result;
96609467b48Spatrick SmallVector<PointerIntPair<DbgVariable *, 1>, 8> WorkList;
96709467b48Spatrick // Map back from a DIVariable to its containing DbgVariable.
96809467b48Spatrick SmallDenseMap<const DILocalVariable *, DbgVariable *> DbgVar;
96909467b48Spatrick // Set of DbgVariables in Result.
97009467b48Spatrick SmallDenseSet<DbgVariable *, 8> Visited;
97109467b48Spatrick // For cycle detection.
97209467b48Spatrick SmallDenseSet<DbgVariable *, 8> Visiting;
97309467b48Spatrick
97409467b48Spatrick // Initialize the worklist and the DIVariable lookup table.
975*d415bd75Srobert for (auto *Var : reverse(Input)) {
97609467b48Spatrick DbgVar.insert({Var->getVariable(), Var});
97709467b48Spatrick WorkList.push_back({Var, 0});
97809467b48Spatrick }
97909467b48Spatrick
98009467b48Spatrick // Perform a stable topological sort by doing a DFS.
98109467b48Spatrick while (!WorkList.empty()) {
98209467b48Spatrick auto Item = WorkList.back();
98309467b48Spatrick DbgVariable *Var = Item.getPointer();
98409467b48Spatrick bool visitedAllDependencies = Item.getInt();
98509467b48Spatrick WorkList.pop_back();
98609467b48Spatrick
987*d415bd75Srobert assert(Var);
98809467b48Spatrick
98909467b48Spatrick // Already handled.
99009467b48Spatrick if (Visited.count(Var))
99109467b48Spatrick continue;
99209467b48Spatrick
99309467b48Spatrick // Add to Result if all dependencies are visited.
99409467b48Spatrick if (visitedAllDependencies) {
99509467b48Spatrick Visited.insert(Var);
99609467b48Spatrick Result.push_back(Var);
99709467b48Spatrick continue;
99809467b48Spatrick }
99909467b48Spatrick
100009467b48Spatrick // Detect cycles.
100109467b48Spatrick auto Res = Visiting.insert(Var);
100209467b48Spatrick if (!Res.second) {
100309467b48Spatrick assert(false && "dependency cycle in local variables");
100409467b48Spatrick return Result;
100509467b48Spatrick }
100609467b48Spatrick
100709467b48Spatrick // Push dependencies and this node onto the worklist, so that this node is
100809467b48Spatrick // visited again after all of its dependencies are handled.
100909467b48Spatrick WorkList.push_back({Var, 1});
1010*d415bd75Srobert for (const auto *Dependency : dependencies(Var)) {
1011*d415bd75Srobert // Don't add dependency if it is in a different lexical scope or a global.
1012*d415bd75Srobert if (const auto *Dep = dyn_cast<const DILocalVariable>(Dependency))
1013*d415bd75Srobert if (DbgVariable *Var = DbgVar.lookup(Dep))
1014*d415bd75Srobert WorkList.push_back({Var, 0});
101509467b48Spatrick }
101609467b48Spatrick }
101709467b48Spatrick return Result;
101809467b48Spatrick }
101909467b48Spatrick
constructSubprogramScopeDIE(const DISubprogram * Sub,LexicalScope * Scope)102009467b48Spatrick DIE &DwarfCompileUnit::constructSubprogramScopeDIE(const DISubprogram *Sub,
102109467b48Spatrick LexicalScope *Scope) {
102209467b48Spatrick DIE &ScopeDIE = updateSubprogramScopeDIE(Sub);
1023*d415bd75Srobert auto *ContextCU = static_cast<DwarfCompileUnit *>(ScopeDIE.getUnit());
102409467b48Spatrick
102509467b48Spatrick if (Scope) {
102609467b48Spatrick assert(!Scope->getInlinedAt());
102709467b48Spatrick assert(!Scope->isAbstractScope());
102809467b48Spatrick // Collect lexical scope children first.
102909467b48Spatrick // ObjectPointer might be a local (non-argument) local variable if it's a
103009467b48Spatrick // block's synthetic this pointer.
1031*d415bd75Srobert if (DIE *ObjectPointer =
1032*d415bd75Srobert ContextCU->createAndAddScopeChildren(Scope, ScopeDIE))
1033*d415bd75Srobert ContextCU->addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer,
1034*d415bd75Srobert *ObjectPointer);
103509467b48Spatrick }
103609467b48Spatrick
103709467b48Spatrick // If this is a variadic function, add an unspecified parameter.
103809467b48Spatrick DITypeRefArray FnArgs = Sub->getType()->getTypeArray();
103909467b48Spatrick
104009467b48Spatrick // If we have a single element of null, it is a function that returns void.
104109467b48Spatrick // If we have more than one elements and the last one is null, it is a
104209467b48Spatrick // variadic function.
104309467b48Spatrick if (FnArgs.size() > 1 && !FnArgs[FnArgs.size() - 1] &&
104409467b48Spatrick !includeMinimalInlineScopes())
104509467b48Spatrick ScopeDIE.addChild(
104609467b48Spatrick DIE::get(DIEValueAllocator, dwarf::DW_TAG_unspecified_parameters));
104709467b48Spatrick
104809467b48Spatrick return ScopeDIE;
104909467b48Spatrick }
105009467b48Spatrick
createAndAddScopeChildren(LexicalScope * Scope,DIE & ScopeDIE)105109467b48Spatrick DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope,
105209467b48Spatrick DIE &ScopeDIE) {
1053*d415bd75Srobert DIE *ObjectPointer = nullptr;
105409467b48Spatrick
1055*d415bd75Srobert // Emit function arguments (order is significant).
1056*d415bd75Srobert auto Vars = DU->getScopeVariables().lookup(Scope);
1057*d415bd75Srobert for (auto &DV : Vars.Args)
1058*d415bd75Srobert ScopeDIE.addChild(constructVariableDIE(*DV.second, *Scope, ObjectPointer));
1059*d415bd75Srobert
1060*d415bd75Srobert // Emit local variables.
1061*d415bd75Srobert auto Locals = sortLocalVars(Vars.Locals);
1062*d415bd75Srobert for (DbgVariable *DV : Locals)
1063*d415bd75Srobert ScopeDIE.addChild(constructVariableDIE(*DV, *Scope, ObjectPointer));
1064*d415bd75Srobert
1065*d415bd75Srobert // Emit imported entities (skipped in gmlt-like data).
1066*d415bd75Srobert if (!includeMinimalInlineScopes()) {
1067*d415bd75Srobert for (const auto *IE : ImportedEntities[Scope->getScopeNode()])
1068*d415bd75Srobert ScopeDIE.addChild(constructImportedEntityDIE(cast<DIImportedEntity>(IE)));
1069*d415bd75Srobert }
1070*d415bd75Srobert
1071*d415bd75Srobert // Emit labels.
1072*d415bd75Srobert for (DbgLabel *DL : DU->getScopeLabels().lookup(Scope))
1073*d415bd75Srobert ScopeDIE.addChild(constructLabelDIE(*DL, *Scope));
1074*d415bd75Srobert
1075*d415bd75Srobert // Emit inner lexical scopes.
1076*d415bd75Srobert auto needToEmitLexicalScope = [this](LexicalScope *LS) {
1077*d415bd75Srobert if (isa<DISubprogram>(LS->getScopeNode()))
1078*d415bd75Srobert return true;
1079*d415bd75Srobert auto Vars = DU->getScopeVariables().lookup(LS);
1080*d415bd75Srobert if (!Vars.Args.empty() || !Vars.Locals.empty())
1081*d415bd75Srobert return true;
1082*d415bd75Srobert if (!includeMinimalInlineScopes() &&
1083*d415bd75Srobert !ImportedEntities[LS->getScopeNode()].empty())
1084*d415bd75Srobert return true;
1085*d415bd75Srobert return false;
1086*d415bd75Srobert };
1087*d415bd75Srobert for (LexicalScope *LS : Scope->getChildren()) {
1088*d415bd75Srobert // If the lexical block doesn't have non-scope children, skip
1089*d415bd75Srobert // its emission and put its children directly to the parent scope.
1090*d415bd75Srobert if (needToEmitLexicalScope(LS))
1091*d415bd75Srobert constructScopeDIE(LS, ScopeDIE);
1092*d415bd75Srobert else
1093*d415bd75Srobert createAndAddScopeChildren(LS, ScopeDIE);
1094*d415bd75Srobert }
109509467b48Spatrick
109609467b48Spatrick return ObjectPointer;
109709467b48Spatrick }
109809467b48Spatrick
constructAbstractSubprogramScopeDIE(LexicalScope * Scope)109909467b48Spatrick void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(
110009467b48Spatrick LexicalScope *Scope) {
110109467b48Spatrick DIE *&AbsDef = getAbstractSPDies()[Scope->getScopeNode()];
110209467b48Spatrick if (AbsDef)
110309467b48Spatrick return;
110409467b48Spatrick
110509467b48Spatrick auto *SP = cast<DISubprogram>(Scope->getScopeNode());
110609467b48Spatrick
110709467b48Spatrick DIE *ContextDIE;
110809467b48Spatrick DwarfCompileUnit *ContextCU = this;
110909467b48Spatrick
111009467b48Spatrick if (includeMinimalInlineScopes())
111109467b48Spatrick ContextDIE = &getUnitDie();
111209467b48Spatrick // Some of this is duplicated from DwarfUnit::getOrCreateSubprogramDIE, with
111309467b48Spatrick // the important distinction that the debug node is not associated with the
111409467b48Spatrick // DIE (since the debug node will be associated with the concrete DIE, if
111509467b48Spatrick // any). It could be refactored to some common utility function.
111609467b48Spatrick else if (auto *SPDecl = SP->getDeclaration()) {
111709467b48Spatrick ContextDIE = &getUnitDie();
111809467b48Spatrick getOrCreateSubprogramDIE(SPDecl);
111909467b48Spatrick } else {
112009467b48Spatrick ContextDIE = getOrCreateContextDIE(SP->getScope());
112109467b48Spatrick // The scope may be shared with a subprogram that has already been
112209467b48Spatrick // constructed in another CU, in which case we need to construct this
112309467b48Spatrick // subprogram in the same CU.
112409467b48Spatrick ContextCU = DD->lookupCU(ContextDIE->getUnitDie());
112509467b48Spatrick }
112609467b48Spatrick
112709467b48Spatrick // Passing null as the associated node because the abstract definition
112809467b48Spatrick // shouldn't be found by lookup.
112909467b48Spatrick AbsDef = &ContextCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, nullptr);
113009467b48Spatrick ContextCU->applySubprogramAttributesToDefinition(SP, *AbsDef);
1131*d415bd75Srobert ContextCU->addSInt(*AbsDef, dwarf::DW_AT_inline,
1132*d415bd75Srobert DD->getDwarfVersion() <= 4 ? std::optional<dwarf::Form>()
1133*d415bd75Srobert : dwarf::DW_FORM_implicit_const,
1134*d415bd75Srobert dwarf::DW_INL_inlined);
113509467b48Spatrick if (DIE *ObjectPointer = ContextCU->createAndAddScopeChildren(Scope, *AbsDef))
113609467b48Spatrick ContextCU->addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
113709467b48Spatrick }
113809467b48Spatrick
useGNUAnalogForDwarf5Feature() const1139097a140dSpatrick bool DwarfCompileUnit::useGNUAnalogForDwarf5Feature() const {
114073471bf0Spatrick return DD->getDwarfVersion() == 4 && !DD->tuneForLLDB();
114109467b48Spatrick }
114209467b48Spatrick
getDwarf5OrGNUTag(dwarf::Tag Tag) const114309467b48Spatrick dwarf::Tag DwarfCompileUnit::getDwarf5OrGNUTag(dwarf::Tag Tag) const {
1144097a140dSpatrick if (!useGNUAnalogForDwarf5Feature())
114509467b48Spatrick return Tag;
114609467b48Spatrick switch (Tag) {
114709467b48Spatrick case dwarf::DW_TAG_call_site:
114809467b48Spatrick return dwarf::DW_TAG_GNU_call_site;
114909467b48Spatrick case dwarf::DW_TAG_call_site_parameter:
115009467b48Spatrick return dwarf::DW_TAG_GNU_call_site_parameter;
115109467b48Spatrick default:
115209467b48Spatrick llvm_unreachable("DWARF5 tag with no GNU analog");
115309467b48Spatrick }
115409467b48Spatrick }
115509467b48Spatrick
115609467b48Spatrick dwarf::Attribute
getDwarf5OrGNUAttr(dwarf::Attribute Attr) const115709467b48Spatrick DwarfCompileUnit::getDwarf5OrGNUAttr(dwarf::Attribute Attr) const {
1158097a140dSpatrick if (!useGNUAnalogForDwarf5Feature())
115909467b48Spatrick return Attr;
116009467b48Spatrick switch (Attr) {
116109467b48Spatrick case dwarf::DW_AT_call_all_calls:
116209467b48Spatrick return dwarf::DW_AT_GNU_all_call_sites;
116309467b48Spatrick case dwarf::DW_AT_call_target:
116409467b48Spatrick return dwarf::DW_AT_GNU_call_site_target;
116509467b48Spatrick case dwarf::DW_AT_call_origin:
116609467b48Spatrick return dwarf::DW_AT_abstract_origin;
1167097a140dSpatrick case dwarf::DW_AT_call_return_pc:
116809467b48Spatrick return dwarf::DW_AT_low_pc;
116909467b48Spatrick case dwarf::DW_AT_call_value:
117009467b48Spatrick return dwarf::DW_AT_GNU_call_site_value;
117109467b48Spatrick case dwarf::DW_AT_call_tail_call:
117209467b48Spatrick return dwarf::DW_AT_GNU_tail_call;
117309467b48Spatrick default:
117409467b48Spatrick llvm_unreachable("DWARF5 attribute with no GNU analog");
117509467b48Spatrick }
117609467b48Spatrick }
117709467b48Spatrick
117809467b48Spatrick dwarf::LocationAtom
getDwarf5OrGNULocationAtom(dwarf::LocationAtom Loc) const117909467b48Spatrick DwarfCompileUnit::getDwarf5OrGNULocationAtom(dwarf::LocationAtom Loc) const {
1180097a140dSpatrick if (!useGNUAnalogForDwarf5Feature())
118109467b48Spatrick return Loc;
118209467b48Spatrick switch (Loc) {
118309467b48Spatrick case dwarf::DW_OP_entry_value:
118409467b48Spatrick return dwarf::DW_OP_GNU_entry_value;
118509467b48Spatrick default:
118609467b48Spatrick llvm_unreachable("DWARF5 location atom with no GNU analog");
118709467b48Spatrick }
118809467b48Spatrick }
118909467b48Spatrick
constructCallSiteEntryDIE(DIE & ScopeDIE,const DISubprogram * CalleeSP,bool IsTail,const MCSymbol * PCAddr,const MCSymbol * CallAddr,unsigned CallReg)1190097a140dSpatrick DIE &DwarfCompileUnit::constructCallSiteEntryDIE(DIE &ScopeDIE,
119173471bf0Spatrick const DISubprogram *CalleeSP,
1192097a140dSpatrick bool IsTail,
1193097a140dSpatrick const MCSymbol *PCAddr,
1194097a140dSpatrick const MCSymbol *CallAddr,
1195097a140dSpatrick unsigned CallReg) {
119609467b48Spatrick // Insert a call site entry DIE within ScopeDIE.
119709467b48Spatrick DIE &CallSiteDIE = createAndAddDIE(getDwarf5OrGNUTag(dwarf::DW_TAG_call_site),
119809467b48Spatrick ScopeDIE, nullptr);
119909467b48Spatrick
120009467b48Spatrick if (CallReg) {
120109467b48Spatrick // Indirect call.
120209467b48Spatrick addAddress(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_target),
120309467b48Spatrick MachineLocation(CallReg));
120409467b48Spatrick } else {
120573471bf0Spatrick DIE *CalleeDIE = getOrCreateSubprogramDIE(CalleeSP);
120673471bf0Spatrick assert(CalleeDIE && "Could not create DIE for call site entry origin");
120709467b48Spatrick addDIEEntry(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_origin),
120809467b48Spatrick *CalleeDIE);
120909467b48Spatrick }
121009467b48Spatrick
1211097a140dSpatrick if (IsTail) {
121209467b48Spatrick // Attach DW_AT_call_tail_call to tail calls for standards compliance.
121309467b48Spatrick addFlag(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_tail_call));
121409467b48Spatrick
1215097a140dSpatrick // Attach the address of the branch instruction to allow the debugger to
1216097a140dSpatrick // show where the tail call occurred. This attribute has no GNU analog.
1217097a140dSpatrick //
1218097a140dSpatrick // GDB works backwards from non-standard usage of DW_AT_low_pc (in DWARF4
1219097a140dSpatrick // mode -- equivalently, in DWARF5 mode, DW_AT_call_return_pc) at tail-call
1220097a140dSpatrick // site entries to figure out the PC of tail-calling branch instructions.
1221097a140dSpatrick // This means it doesn't need the compiler to emit DW_AT_call_pc, so we
1222097a140dSpatrick // don't emit it here.
1223097a140dSpatrick //
1224097a140dSpatrick // There's no need to tie non-GDB debuggers to this non-standardness, as it
1225097a140dSpatrick // adds unnecessary complexity to the debugger. For non-GDB debuggers, emit
1226097a140dSpatrick // the standard DW_AT_call_pc info.
1227097a140dSpatrick if (!useGNUAnalogForDwarf5Feature())
1228097a140dSpatrick addLabelAddress(CallSiteDIE, dwarf::DW_AT_call_pc, CallAddr);
1229097a140dSpatrick }
1230097a140dSpatrick
123109467b48Spatrick // Attach the return PC to allow the debugger to disambiguate call paths
123209467b48Spatrick // from one function to another.
1233097a140dSpatrick //
1234097a140dSpatrick // The return PC is only really needed when the call /isn't/ a tail call, but
1235097a140dSpatrick // GDB expects it in DWARF4 mode, even for tail calls (see the comment above
1236097a140dSpatrick // the DW_AT_call_pc emission logic for an explanation).
1237097a140dSpatrick if (!IsTail || useGNUAnalogForDwarf5Feature()) {
1238097a140dSpatrick assert(PCAddr && "Missing return PC information for a call");
1239097a140dSpatrick addLabelAddress(CallSiteDIE,
1240097a140dSpatrick getDwarf5OrGNUAttr(dwarf::DW_AT_call_return_pc), PCAddr);
124109467b48Spatrick }
124209467b48Spatrick
124309467b48Spatrick return CallSiteDIE;
124409467b48Spatrick }
124509467b48Spatrick
constructCallSiteParmEntryDIEs(DIE & CallSiteDIE,SmallVector<DbgCallSiteParam,4> & Params)124609467b48Spatrick void DwarfCompileUnit::constructCallSiteParmEntryDIEs(
124709467b48Spatrick DIE &CallSiteDIE, SmallVector<DbgCallSiteParam, 4> &Params) {
124809467b48Spatrick for (const auto &Param : Params) {
124909467b48Spatrick unsigned Register = Param.getRegister();
125009467b48Spatrick auto CallSiteDieParam =
125109467b48Spatrick DIE::get(DIEValueAllocator,
125209467b48Spatrick getDwarf5OrGNUTag(dwarf::DW_TAG_call_site_parameter));
125309467b48Spatrick insertDIE(CallSiteDieParam);
125409467b48Spatrick addAddress(*CallSiteDieParam, dwarf::DW_AT_location,
125509467b48Spatrick MachineLocation(Register));
125609467b48Spatrick
125709467b48Spatrick DIELoc *Loc = new (DIEValueAllocator) DIELoc;
125809467b48Spatrick DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
125909467b48Spatrick DwarfExpr.setCallSiteParamValueFlag();
126009467b48Spatrick
126109467b48Spatrick DwarfDebug::emitDebugLocValue(*Asm, nullptr, Param.getValue(), DwarfExpr);
126209467b48Spatrick
126309467b48Spatrick addBlock(*CallSiteDieParam, getDwarf5OrGNUAttr(dwarf::DW_AT_call_value),
126409467b48Spatrick DwarfExpr.finalize());
126509467b48Spatrick
126609467b48Spatrick CallSiteDIE.addChild(CallSiteDieParam);
126709467b48Spatrick }
126809467b48Spatrick }
126909467b48Spatrick
constructImportedEntityDIE(const DIImportedEntity * Module)127009467b48Spatrick DIE *DwarfCompileUnit::constructImportedEntityDIE(
127109467b48Spatrick const DIImportedEntity *Module) {
127209467b48Spatrick DIE *IMDie = DIE::get(DIEValueAllocator, (dwarf::Tag)Module->getTag());
127309467b48Spatrick insertDIE(Module, IMDie);
127409467b48Spatrick DIE *EntityDie;
127509467b48Spatrick auto *Entity = Module->getEntity();
127609467b48Spatrick if (auto *NS = dyn_cast<DINamespace>(Entity))
127709467b48Spatrick EntityDie = getOrCreateNameSpace(NS);
127809467b48Spatrick else if (auto *M = dyn_cast<DIModule>(Entity))
127909467b48Spatrick EntityDie = getOrCreateModule(M);
128009467b48Spatrick else if (auto *SP = dyn_cast<DISubprogram>(Entity))
128109467b48Spatrick EntityDie = getOrCreateSubprogramDIE(SP);
128209467b48Spatrick else if (auto *T = dyn_cast<DIType>(Entity))
128309467b48Spatrick EntityDie = getOrCreateTypeDIE(T);
128409467b48Spatrick else if (auto *GV = dyn_cast<DIGlobalVariable>(Entity))
128509467b48Spatrick EntityDie = getOrCreateGlobalVariableDIE(GV, {});
128609467b48Spatrick else
128709467b48Spatrick EntityDie = getDIE(Entity);
128809467b48Spatrick assert(EntityDie);
128909467b48Spatrick addSourceLine(*IMDie, Module->getLine(), Module->getFile());
129009467b48Spatrick addDIEEntry(*IMDie, dwarf::DW_AT_import, *EntityDie);
129109467b48Spatrick StringRef Name = Module->getName();
129209467b48Spatrick if (!Name.empty())
129309467b48Spatrick addString(*IMDie, dwarf::DW_AT_name, Name);
129409467b48Spatrick
1295*d415bd75Srobert // This is for imported module with renamed entities (such as variables and
1296*d415bd75Srobert // subprograms).
1297*d415bd75Srobert DINodeArray Elements = Module->getElements();
1298*d415bd75Srobert for (const auto *Element : Elements) {
1299*d415bd75Srobert if (!Element)
1300*d415bd75Srobert continue;
1301*d415bd75Srobert IMDie->addChild(
1302*d415bd75Srobert constructImportedEntityDIE(cast<DIImportedEntity>(Element)));
1303*d415bd75Srobert }
1304*d415bd75Srobert
130509467b48Spatrick return IMDie;
130609467b48Spatrick }
130709467b48Spatrick
finishSubprogramDefinition(const DISubprogram * SP)130809467b48Spatrick void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP) {
130909467b48Spatrick DIE *D = getDIE(SP);
131009467b48Spatrick if (DIE *AbsSPDIE = getAbstractSPDies().lookup(SP)) {
131109467b48Spatrick if (D)
131209467b48Spatrick // If this subprogram has an abstract definition, reference that
131309467b48Spatrick addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE);
131409467b48Spatrick } else {
131509467b48Spatrick assert(D || includeMinimalInlineScopes());
131609467b48Spatrick if (D)
131709467b48Spatrick // And attach the attributes
131809467b48Spatrick applySubprogramAttributesToDefinition(SP, *D);
131909467b48Spatrick }
132009467b48Spatrick }
132109467b48Spatrick
finishEntityDefinition(const DbgEntity * Entity)132209467b48Spatrick void DwarfCompileUnit::finishEntityDefinition(const DbgEntity *Entity) {
132309467b48Spatrick DbgEntity *AbsEntity = getExistingAbstractEntity(Entity->getEntity());
132409467b48Spatrick
132509467b48Spatrick auto *Die = Entity->getDIE();
132609467b48Spatrick /// Label may be used to generate DW_AT_low_pc, so put it outside
132709467b48Spatrick /// if/else block.
132809467b48Spatrick const DbgLabel *Label = nullptr;
132909467b48Spatrick if (AbsEntity && AbsEntity->getDIE()) {
133009467b48Spatrick addDIEEntry(*Die, dwarf::DW_AT_abstract_origin, *AbsEntity->getDIE());
133109467b48Spatrick Label = dyn_cast<const DbgLabel>(Entity);
133209467b48Spatrick } else {
133309467b48Spatrick if (const DbgVariable *Var = dyn_cast<const DbgVariable>(Entity))
133409467b48Spatrick applyVariableAttributes(*Var, *Die);
133509467b48Spatrick else if ((Label = dyn_cast<const DbgLabel>(Entity)))
133609467b48Spatrick applyLabelAttributes(*Label, *Die);
133709467b48Spatrick else
133809467b48Spatrick llvm_unreachable("DbgEntity must be DbgVariable or DbgLabel.");
133909467b48Spatrick }
134009467b48Spatrick
134109467b48Spatrick if (Label)
134209467b48Spatrick if (const auto *Sym = Label->getSymbol())
134309467b48Spatrick addLabelAddress(*Die, dwarf::DW_AT_low_pc, Sym);
134409467b48Spatrick }
134509467b48Spatrick
getExistingAbstractEntity(const DINode * Node)134609467b48Spatrick DbgEntity *DwarfCompileUnit::getExistingAbstractEntity(const DINode *Node) {
134709467b48Spatrick auto &AbstractEntities = getAbstractEntities();
134809467b48Spatrick auto I = AbstractEntities.find(Node);
134909467b48Spatrick if (I != AbstractEntities.end())
135009467b48Spatrick return I->second.get();
135109467b48Spatrick return nullptr;
135209467b48Spatrick }
135309467b48Spatrick
createAbstractEntity(const DINode * Node,LexicalScope * Scope)135409467b48Spatrick void DwarfCompileUnit::createAbstractEntity(const DINode *Node,
135509467b48Spatrick LexicalScope *Scope) {
135609467b48Spatrick assert(Scope && Scope->isAbstractScope());
135709467b48Spatrick auto &Entity = getAbstractEntities()[Node];
135809467b48Spatrick if (isa<const DILocalVariable>(Node)) {
135909467b48Spatrick Entity = std::make_unique<DbgVariable>(
136009467b48Spatrick cast<const DILocalVariable>(Node), nullptr /* IA */);;
136109467b48Spatrick DU->addScopeVariable(Scope, cast<DbgVariable>(Entity.get()));
136209467b48Spatrick } else if (isa<const DILabel>(Node)) {
136309467b48Spatrick Entity = std::make_unique<DbgLabel>(
136409467b48Spatrick cast<const DILabel>(Node), nullptr /* IA */);
136509467b48Spatrick DU->addScopeLabel(Scope, cast<DbgLabel>(Entity.get()));
136609467b48Spatrick }
136709467b48Spatrick }
136809467b48Spatrick
emitHeader(bool UseOffsets)136909467b48Spatrick void DwarfCompileUnit::emitHeader(bool UseOffsets) {
137009467b48Spatrick // Don't bother labeling the .dwo unit, as its offset isn't used.
137109467b48Spatrick if (!Skeleton && !DD->useSectionsAsReferences()) {
137209467b48Spatrick LabelBegin = Asm->createTempSymbol("cu_begin");
1373097a140dSpatrick Asm->OutStreamer->emitLabel(LabelBegin);
137409467b48Spatrick }
137509467b48Spatrick
137609467b48Spatrick dwarf::UnitType UT = Skeleton ? dwarf::DW_UT_split_compile
137709467b48Spatrick : DD->useSplitDwarf() ? dwarf::DW_UT_skeleton
137809467b48Spatrick : dwarf::DW_UT_compile;
137909467b48Spatrick DwarfUnit::emitCommonHeader(UseOffsets, UT);
138009467b48Spatrick if (DD->getDwarfVersion() >= 5 && UT != dwarf::DW_UT_compile)
138109467b48Spatrick Asm->emitInt64(getDWOId());
138209467b48Spatrick }
138309467b48Spatrick
hasDwarfPubSections() const138409467b48Spatrick bool DwarfCompileUnit::hasDwarfPubSections() const {
138509467b48Spatrick switch (CUNode->getNameTableKind()) {
138609467b48Spatrick case DICompileUnit::DebugNameTableKind::None:
138709467b48Spatrick return false;
138809467b48Spatrick // Opting in to GNU Pubnames/types overrides the default to ensure these are
138909467b48Spatrick // generated for things like Gold's gdb_index generation.
139009467b48Spatrick case DICompileUnit::DebugNameTableKind::GNU:
139109467b48Spatrick return true;
139209467b48Spatrick case DICompileUnit::DebugNameTableKind::Default:
139309467b48Spatrick return DD->tuneForGDB() && !includeMinimalInlineScopes() &&
139409467b48Spatrick !CUNode->isDebugDirectivesOnly() &&
139509467b48Spatrick DD->getAccelTableKind() != AccelTableKind::Apple &&
139609467b48Spatrick DD->getDwarfVersion() < 5;
139709467b48Spatrick }
139809467b48Spatrick llvm_unreachable("Unhandled DICompileUnit::DebugNameTableKind enum");
139909467b48Spatrick }
140009467b48Spatrick
140109467b48Spatrick /// addGlobalName - Add a new global name to the compile unit.
addGlobalName(StringRef Name,const DIE & Die,const DIScope * Context)140209467b48Spatrick void DwarfCompileUnit::addGlobalName(StringRef Name, const DIE &Die,
140309467b48Spatrick const DIScope *Context) {
140409467b48Spatrick if (!hasDwarfPubSections())
140509467b48Spatrick return;
140609467b48Spatrick std::string FullName = getParentContextString(Context) + Name.str();
140709467b48Spatrick GlobalNames[FullName] = &Die;
140809467b48Spatrick }
140909467b48Spatrick
addGlobalNameForTypeUnit(StringRef Name,const DIScope * Context)141009467b48Spatrick void DwarfCompileUnit::addGlobalNameForTypeUnit(StringRef Name,
141109467b48Spatrick const DIScope *Context) {
141209467b48Spatrick if (!hasDwarfPubSections())
141309467b48Spatrick return;
141409467b48Spatrick std::string FullName = getParentContextString(Context) + Name.str();
141509467b48Spatrick // Insert, allowing the entry to remain as-is if it's already present
141609467b48Spatrick // This way the CU-level type DIE is preferred over the "can't describe this
141709467b48Spatrick // type as a unit offset because it's not really in the CU at all, it's only
141809467b48Spatrick // in a type unit"
141909467b48Spatrick GlobalNames.insert(std::make_pair(std::move(FullName), &getUnitDie()));
142009467b48Spatrick }
142109467b48Spatrick
142209467b48Spatrick /// Add a new global type to the unit.
addGlobalType(const DIType * Ty,const DIE & Die,const DIScope * Context)142309467b48Spatrick void DwarfCompileUnit::addGlobalType(const DIType *Ty, const DIE &Die,
142409467b48Spatrick const DIScope *Context) {
142509467b48Spatrick if (!hasDwarfPubSections())
142609467b48Spatrick return;
142709467b48Spatrick std::string FullName = getParentContextString(Context) + Ty->getName().str();
142809467b48Spatrick GlobalTypes[FullName] = &Die;
142909467b48Spatrick }
143009467b48Spatrick
addGlobalTypeUnitType(const DIType * Ty,const DIScope * Context)143109467b48Spatrick void DwarfCompileUnit::addGlobalTypeUnitType(const DIType *Ty,
143209467b48Spatrick const DIScope *Context) {
143309467b48Spatrick if (!hasDwarfPubSections())
143409467b48Spatrick return;
143509467b48Spatrick std::string FullName = getParentContextString(Context) + Ty->getName().str();
143609467b48Spatrick // Insert, allowing the entry to remain as-is if it's already present
143709467b48Spatrick // This way the CU-level type DIE is preferred over the "can't describe this
143809467b48Spatrick // type as a unit offset because it's not really in the CU at all, it's only
143909467b48Spatrick // in a type unit"
144009467b48Spatrick GlobalTypes.insert(std::make_pair(std::move(FullName), &getUnitDie()));
144109467b48Spatrick }
144209467b48Spatrick
addVariableAddress(const DbgVariable & DV,DIE & Die,MachineLocation Location)144309467b48Spatrick void DwarfCompileUnit::addVariableAddress(const DbgVariable &DV, DIE &Die,
144409467b48Spatrick MachineLocation Location) {
144509467b48Spatrick if (DV.hasComplexAddress())
144609467b48Spatrick addComplexAddress(DV, Die, dwarf::DW_AT_location, Location);
144709467b48Spatrick else
144809467b48Spatrick addAddress(Die, dwarf::DW_AT_location, Location);
144909467b48Spatrick }
145009467b48Spatrick
145109467b48Spatrick /// Add an address attribute to a die based on the location provided.
addAddress(DIE & Die,dwarf::Attribute Attribute,const MachineLocation & Location)145209467b48Spatrick void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute,
145309467b48Spatrick const MachineLocation &Location) {
145409467b48Spatrick DIELoc *Loc = new (DIEValueAllocator) DIELoc;
145509467b48Spatrick DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
145609467b48Spatrick if (Location.isIndirect())
145709467b48Spatrick DwarfExpr.setMemoryLocationKind();
145809467b48Spatrick
145909467b48Spatrick DIExpressionCursor Cursor({});
146009467b48Spatrick const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
146109467b48Spatrick if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
146209467b48Spatrick return;
146309467b48Spatrick DwarfExpr.addExpression(std::move(Cursor));
146409467b48Spatrick
146509467b48Spatrick // Now attach the location information to the DIE.
146609467b48Spatrick addBlock(Die, Attribute, DwarfExpr.finalize());
146709467b48Spatrick
146809467b48Spatrick if (DwarfExpr.TagOffset)
146909467b48Spatrick addUInt(Die, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
147009467b48Spatrick *DwarfExpr.TagOffset);
147109467b48Spatrick }
147209467b48Spatrick
147309467b48Spatrick /// Start with the address based on the location provided, and generate the
147409467b48Spatrick /// DWARF information necessary to find the actual variable given the extra
147509467b48Spatrick /// address information encoded in the DbgVariable, starting from the starting
147609467b48Spatrick /// location. Add the DWARF information to the die.
addComplexAddress(const DbgVariable & DV,DIE & Die,dwarf::Attribute Attribute,const MachineLocation & Location)147709467b48Spatrick void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die,
147809467b48Spatrick dwarf::Attribute Attribute,
147909467b48Spatrick const MachineLocation &Location) {
148009467b48Spatrick DIELoc *Loc = new (DIEValueAllocator) DIELoc;
148109467b48Spatrick DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
148209467b48Spatrick const DIExpression *DIExpr = DV.getSingleExpression();
148309467b48Spatrick DwarfExpr.addFragmentOffset(DIExpr);
1484097a140dSpatrick DwarfExpr.setLocation(Location, DIExpr);
148509467b48Spatrick
148609467b48Spatrick DIExpressionCursor Cursor(DIExpr);
148709467b48Spatrick
1488097a140dSpatrick if (DIExpr->isEntryValue())
148909467b48Spatrick DwarfExpr.beginEntryValueExpression(Cursor);
149009467b48Spatrick
149109467b48Spatrick const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
149209467b48Spatrick if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
149309467b48Spatrick return;
149409467b48Spatrick DwarfExpr.addExpression(std::move(Cursor));
149509467b48Spatrick
149609467b48Spatrick // Now attach the location information to the DIE.
149709467b48Spatrick addBlock(Die, Attribute, DwarfExpr.finalize());
149809467b48Spatrick
149909467b48Spatrick if (DwarfExpr.TagOffset)
150009467b48Spatrick addUInt(Die, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
150109467b48Spatrick *DwarfExpr.TagOffset);
150209467b48Spatrick }
150309467b48Spatrick
150409467b48Spatrick /// Add a Dwarf loclistptr attribute data and value.
addLocationList(DIE & Die,dwarf::Attribute Attribute,unsigned Index)150509467b48Spatrick void DwarfCompileUnit::addLocationList(DIE &Die, dwarf::Attribute Attribute,
150609467b48Spatrick unsigned Index) {
150773471bf0Spatrick dwarf::Form Form = (DD->getDwarfVersion() >= 5)
150873471bf0Spatrick ? dwarf::DW_FORM_loclistx
150973471bf0Spatrick : DD->getDwarfSectionOffsetForm();
151073471bf0Spatrick addAttribute(Die, Attribute, Form, DIELocList(Index));
151109467b48Spatrick }
151209467b48Spatrick
applyVariableAttributes(const DbgVariable & Var,DIE & VariableDie)151309467b48Spatrick void DwarfCompileUnit::applyVariableAttributes(const DbgVariable &Var,
151409467b48Spatrick DIE &VariableDie) {
151509467b48Spatrick StringRef Name = Var.getName();
151609467b48Spatrick if (!Name.empty())
151709467b48Spatrick addString(VariableDie, dwarf::DW_AT_name, Name);
151809467b48Spatrick const auto *DIVar = Var.getVariable();
1519*d415bd75Srobert if (DIVar) {
152009467b48Spatrick if (uint32_t AlignInBytes = DIVar->getAlignInBytes())
152109467b48Spatrick addUInt(VariableDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
152209467b48Spatrick AlignInBytes);
1523*d415bd75Srobert addAnnotation(VariableDie, DIVar->getAnnotations());
1524*d415bd75Srobert }
152509467b48Spatrick
152609467b48Spatrick addSourceLine(VariableDie, DIVar);
152709467b48Spatrick addType(VariableDie, Var.getType());
152809467b48Spatrick if (Var.isArtificial())
152909467b48Spatrick addFlag(VariableDie, dwarf::DW_AT_artificial);
153009467b48Spatrick }
153109467b48Spatrick
applyLabelAttributes(const DbgLabel & Label,DIE & LabelDie)153209467b48Spatrick void DwarfCompileUnit::applyLabelAttributes(const DbgLabel &Label,
153309467b48Spatrick DIE &LabelDie) {
153409467b48Spatrick StringRef Name = Label.getName();
153509467b48Spatrick if (!Name.empty())
153609467b48Spatrick addString(LabelDie, dwarf::DW_AT_name, Name);
153709467b48Spatrick const auto *DILabel = Label.getLabel();
153809467b48Spatrick addSourceLine(LabelDie, DILabel);
153909467b48Spatrick }
154009467b48Spatrick
154109467b48Spatrick /// Add a Dwarf expression attribute data and value.
addExpr(DIELoc & Die,dwarf::Form Form,const MCExpr * Expr)154209467b48Spatrick void DwarfCompileUnit::addExpr(DIELoc &Die, dwarf::Form Form,
154309467b48Spatrick const MCExpr *Expr) {
154473471bf0Spatrick addAttribute(Die, (dwarf::Attribute)0, Form, DIEExpr(Expr));
154509467b48Spatrick }
154609467b48Spatrick
applySubprogramAttributesToDefinition(const DISubprogram * SP,DIE & SPDie)154709467b48Spatrick void DwarfCompileUnit::applySubprogramAttributesToDefinition(
154809467b48Spatrick const DISubprogram *SP, DIE &SPDie) {
154909467b48Spatrick auto *SPDecl = SP->getDeclaration();
155009467b48Spatrick auto *Context = SPDecl ? SPDecl->getScope() : SP->getScope();
155109467b48Spatrick applySubprogramAttributes(SP, SPDie, includeMinimalInlineScopes());
155209467b48Spatrick addGlobalName(SP->getName(), SPDie, Context);
155309467b48Spatrick }
155409467b48Spatrick
isDwoUnit() const155509467b48Spatrick bool DwarfCompileUnit::isDwoUnit() const {
155609467b48Spatrick return DD->useSplitDwarf() && Skeleton;
155709467b48Spatrick }
155809467b48Spatrick
finishNonUnitTypeDIE(DIE & D,const DICompositeType * CTy)155909467b48Spatrick void DwarfCompileUnit::finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) {
156009467b48Spatrick constructTypeDIE(D, CTy);
156109467b48Spatrick }
156209467b48Spatrick
includeMinimalInlineScopes() const156309467b48Spatrick bool DwarfCompileUnit::includeMinimalInlineScopes() const {
156409467b48Spatrick return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly ||
156509467b48Spatrick (DD->useSplitDwarf() && !Skeleton);
156609467b48Spatrick }
156709467b48Spatrick
addAddrTableBase()156809467b48Spatrick void DwarfCompileUnit::addAddrTableBase() {
156909467b48Spatrick const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
157009467b48Spatrick MCSymbol *Label = DD->getAddressPool().getLabel();
157109467b48Spatrick addSectionLabel(getUnitDie(),
157273471bf0Spatrick DD->getDwarfVersion() >= 5 ? dwarf::DW_AT_addr_base
157309467b48Spatrick : dwarf::DW_AT_GNU_addr_base,
157409467b48Spatrick Label, TLOF.getDwarfAddrSection()->getBeginSymbol());
157509467b48Spatrick }
157609467b48Spatrick
addBaseTypeRef(DIEValueList & Die,int64_t Idx)157709467b48Spatrick void DwarfCompileUnit::addBaseTypeRef(DIEValueList &Die, int64_t Idx) {
157873471bf0Spatrick addAttribute(Die, (dwarf::Attribute)0, dwarf::DW_FORM_udata,
157909467b48Spatrick new (DIEValueAllocator) DIEBaseTypeRef(this, Idx));
158009467b48Spatrick }
158109467b48Spatrick
createBaseTypeDIEs()158209467b48Spatrick void DwarfCompileUnit::createBaseTypeDIEs() {
158309467b48Spatrick // Insert the base_type DIEs directly after the CU so that their offsets will
158409467b48Spatrick // fit in the fixed size ULEB128 used inside the location expressions.
158509467b48Spatrick // Maintain order by iterating backwards and inserting to the front of CU
158609467b48Spatrick // child list.
158709467b48Spatrick for (auto &Btr : reverse(ExprRefedBaseTypes)) {
158809467b48Spatrick DIE &Die = getUnitDie().addChildFront(
158909467b48Spatrick DIE::get(DIEValueAllocator, dwarf::DW_TAG_base_type));
159009467b48Spatrick SmallString<32> Str;
159109467b48Spatrick addString(Die, dwarf::DW_AT_name,
159209467b48Spatrick Twine(dwarf::AttributeEncodingString(Btr.Encoding) +
159309467b48Spatrick "_" + Twine(Btr.BitSize)).toStringRef(Str));
159409467b48Spatrick addUInt(Die, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Btr.Encoding);
1595*d415bd75Srobert // Round up to smallest number of bytes that contains this number of bits.
1596*d415bd75Srobert addUInt(Die, dwarf::DW_AT_byte_size, std::nullopt,
1597*d415bd75Srobert divideCeil(Btr.BitSize, 8));
159809467b48Spatrick
159909467b48Spatrick Btr.Die = &Die;
160009467b48Spatrick }
160109467b48Spatrick }
1602