16e07bfd0SEugene Zelenko //===- llvm/CodeGen/DwarfCompileUnit.cpp - Dwarf Compile Units ------------===//
23443575cSPaul Robinson //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63443575cSPaul Robinson //
73443575cSPaul Robinson //===----------------------------------------------------------------------===//
83443575cSPaul Robinson //
93443575cSPaul Robinson // This file contains support for constructing a dwarf compile unit.
103443575cSPaul Robinson //
113443575cSPaul Robinson //===----------------------------------------------------------------------===//
123443575cSPaul Robinson
1337c52310SDavid Blaikie #include "DwarfCompileUnit.h"
146e07bfd0SEugene Zelenko #include "AddressPool.h"
157813d9c9SAdrian Prantl #include "DwarfExpression.h"
166e07bfd0SEugene Zelenko #include "llvm/ADT/None.h"
176e07bfd0SEugene Zelenko #include "llvm/ADT/STLExtras.h"
18b86ce219SMarkus Lavin #include "llvm/ADT/SmallString.h"
194318028cSDavid Blaikie #include "llvm/BinaryFormat/Dwarf.h"
206e07bfd0SEugene Zelenko #include "llvm/CodeGen/AsmPrinter.h"
216e07bfd0SEugene Zelenko #include "llvm/CodeGen/DIE.h"
22cda2aa82SDavid Blaikie #include "llvm/CodeGen/MachineFunction.h"
236e07bfd0SEugene Zelenko #include "llvm/CodeGen/MachineInstr.h"
24b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetFrameLowering.h"
25b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetRegisterInfo.h"
26b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetSubtargetInfo.h"
2737c52310SDavid Blaikie #include "llvm/IR/DataLayout.h"
286e07bfd0SEugene Zelenko #include "llvm/IR/DebugInfo.h"
2937c52310SDavid Blaikie #include "llvm/IR/GlobalVariable.h"
306e07bfd0SEugene Zelenko #include "llvm/MC/MCSection.h"
3137c52310SDavid Blaikie #include "llvm/MC/MCStreamer.h"
326e07bfd0SEugene Zelenko #include "llvm/MC/MCSymbol.h"
3348139ebcSWouter van Oortmerssen #include "llvm/MC/MCSymbolWasm.h"
34b3bde2eaSDavid Blaikie #include "llvm/MC/MachineLocation.h"
356054e650SDavid Blaikie #include "llvm/Target/TargetLoweringObjectFile.h"
36cda2aa82SDavid Blaikie #include "llvm/Target/TargetMachine.h"
376e07bfd0SEugene Zelenko #include "llvm/Target/TargetOptions.h"
386e07bfd0SEugene Zelenko #include <iterator>
396e07bfd0SEugene Zelenko #include <string>
406e07bfd0SEugene Zelenko #include <utility>
4137c52310SDavid Blaikie
426e07bfd0SEugene Zelenko using namespace llvm;
4337c52310SDavid Blaikie
GetCompileUnitType(UnitKind Kind,DwarfDebug * DW)44789e257cSAlexey Lapshin static dwarf::Tag GetCompileUnitType(UnitKind Kind, DwarfDebug *DW) {
45789e257cSAlexey Lapshin
46789e257cSAlexey Lapshin // According to DWARF Debugging Information Format Version 5,
47789e257cSAlexey Lapshin // 3.1.2 Skeleton Compilation Unit Entries:
48789e257cSAlexey Lapshin // "When generating a split DWARF object file (see Section 7.3.2
49789e257cSAlexey Lapshin // on page 187), the compilation unit in the .debug_info section
50789e257cSAlexey Lapshin // is a "skeleton" compilation unit with the tag DW_TAG_skeleton_unit"
51789e257cSAlexey Lapshin if (DW->getDwarfVersion() >= 5 && Kind == UnitKind::Skeleton)
52789e257cSAlexey Lapshin return dwarf::DW_TAG_skeleton_unit;
53789e257cSAlexey Lapshin
54789e257cSAlexey Lapshin return dwarf::DW_TAG_compile_unit;
55789e257cSAlexey Lapshin }
56789e257cSAlexey Lapshin
DwarfCompileUnit(unsigned UID,const DICompileUnit * Node,AsmPrinter * A,DwarfDebug * DW,DwarfFile * DWU,UnitKind Kind)57a9308c49SDuncan P. N. Exon Smith DwarfCompileUnit::DwarfCompileUnit(unsigned UID, const DICompileUnit *Node,
5837c52310SDavid Blaikie AsmPrinter *A, DwarfDebug *DW,
59789e257cSAlexey Lapshin DwarfFile *DWU, UnitKind Kind)
60789e257cSAlexey Lapshin : DwarfUnit(GetCompileUnitType(Kind, DW), Node, A, DW, DWU), UniqueID(UID) {
6137c52310SDavid Blaikie insertDIE(Node, &getUnitDie());
628bbce8adSAmjad Aboud MacroLabelBegin = Asm->createTempSymbol("cu_macro_begin");
6337c52310SDavid Blaikie }
6437c52310SDavid Blaikie
6537c52310SDavid Blaikie /// addLabelAddress - Add a dwarf label attribute data and value using
6637c52310SDavid Blaikie /// DW_FORM_addr or DW_FORM_GNU_addr_index.
addLabelAddress(DIE & Die,dwarf::Attribute Attribute,const MCSymbol * Label)6737c52310SDavid Blaikie void DwarfCompileUnit::addLabelAddress(DIE &Die, dwarf::Attribute Attribute,
6837c52310SDavid Blaikie const MCSymbol *Label) {
691be6ccfcSAlexander Yermolovich if ((Skeleton || !DD->useSplitDwarf()) && Label)
701be6ccfcSAlexander Yermolovich DD->addArangeLabel(SymbolCU(this, Label));
711be6ccfcSAlexander Yermolovich
7237c52310SDavid Blaikie // Don't use the address pool in non-fission or in the skeleton unit itself.
73161dd3c1SDavid Blaikie if ((!DD->useSplitDwarf() || !Skeleton) && DD->getDwarfVersion() < 5)
7437c52310SDavid Blaikie return addLocalLabelAddress(Die, Attribute, Label);
7537c52310SDavid Blaikie
764318028cSDavid Blaikie bool UseAddrOffsetFormOrExpressions =
774318028cSDavid Blaikie DD->useAddrOffsetForm() || DD->useAddrOffsetExpressions();
784318028cSDavid Blaikie
794318028cSDavid Blaikie const MCSymbol *Base = nullptr;
804318028cSDavid Blaikie if (Label->isInSection() && UseAddrOffsetFormOrExpressions)
814318028cSDavid Blaikie Base = DD->getSectionLabel(&Label->getSection());
824318028cSDavid Blaikie
834318028cSDavid Blaikie if (!Base || Base == Label) {
8437c52310SDavid Blaikie unsigned idx = DD->getAddressPool().getIndex(Label);
859deb7eeaSChen Zheng addAttribute(Die, Attribute,
86161dd3c1SDavid Blaikie DD->getDwarfVersion() >= 5 ? dwarf::DW_FORM_addrx
87161dd3c1SDavid Blaikie : dwarf::DW_FORM_GNU_addr_index,
884fb1f9cdSDuncan P. N. Exon Smith DIEInteger(idx));
897e6c87eeSDavid Blaikie return;
907e6c87eeSDavid Blaikie }
917e6c87eeSDavid Blaikie
927e6c87eeSDavid Blaikie // Could be extended to work with DWARFv4 Split DWARF if that's important for
937e6c87eeSDavid Blaikie // someone. In that case DW_FORM_data would be used.
947e6c87eeSDavid Blaikie assert(DD->getDwarfVersion() >= 5 &&
957e6c87eeSDavid Blaikie "Addr+offset expressions are only valuable when using debug_addr (to "
967e6c87eeSDavid Blaikie "reduce relocations) available in DWARFv5 or higher");
974318028cSDavid Blaikie if (DD->useAddrOffsetExpressions()) {
987e6c87eeSDavid Blaikie auto *Loc = new (DIEValueAllocator) DIEBlock();
997e6c87eeSDavid Blaikie addPoolOpAddress(*Loc, Label);
1007e6c87eeSDavid Blaikie addBlock(Die, Attribute, dwarf::DW_FORM_exprloc, Loc);
1014318028cSDavid Blaikie } else
1029deb7eeaSChen Zheng addAttribute(Die, Attribute, dwarf::DW_FORM_LLVM_addrx_offset,
10385b7b562SDavid Blaikie new (DIEValueAllocator) DIEAddrOffset(
10485b7b562SDavid Blaikie DD->getAddressPool().getIndex(Base), Label, Base));
10537c52310SDavid Blaikie }
10637c52310SDavid Blaikie
addLocalLabelAddress(DIE & Die,dwarf::Attribute Attribute,const MCSymbol * Label)10737c52310SDavid Blaikie void DwarfCompileUnit::addLocalLabelAddress(DIE &Die,
10837c52310SDavid Blaikie dwarf::Attribute Attribute,
10937c52310SDavid Blaikie const MCSymbol *Label) {
11037c52310SDavid Blaikie if (Label)
1119deb7eeaSChen Zheng addAttribute(Die, Attribute, dwarf::DW_FORM_addr, DIELabel(Label));
112815a6eb5SDuncan P. N. Exon Smith else
1139deb7eeaSChen Zheng addAttribute(Die, Attribute, dwarf::DW_FORM_addr, DIEInteger(0));
11437c52310SDavid Blaikie }
11537c52310SDavid Blaikie
getOrCreateSourceID(const DIFile * File)116612e89d7SPaul Robinson unsigned DwarfCompileUnit::getOrCreateSourceID(const DIFile *File) {
11737c52310SDavid Blaikie // If we print assembly, we can't separate .file entries according to
11837c52310SDavid Blaikie // compile units. Thus all files will belong to the default compile unit.
11937c52310SDavid Blaikie
12037c52310SDavid Blaikie // FIXME: add a better feature test than hasRawTextSupport. Even better,
12137c52310SDavid Blaikie // extend .file to support this.
122612e89d7SPaul Robinson unsigned CUID = Asm->OutStreamer->hasRawTextSupport() ? 0 : getUniqueID();
123612e89d7SPaul Robinson if (!File)
1240bc77a0fSFangrui Song return Asm->OutStreamer->emitDwarfFileDirective(0, "", "", None, None,
1250bc77a0fSFangrui Song CUID);
1269554aaa2SNikita Popov
1279554aaa2SNikita Popov if (LastFile != File) {
1289554aaa2SNikita Popov LastFile = File;
1299554aaa2SNikita Popov LastFileID = Asm->OutStreamer->emitDwarfFileDirective(
13038fbba4cSDavid Blaikie 0, File->getDirectory(), File->getFilename(), DD->getMD5AsBytes(File),
13116c7bdafSScott Linder File->getSource(), CUID);
13237c52310SDavid Blaikie }
1339554aaa2SNikita Popov return LastFileID;
1349554aaa2SNikita Popov }
13537c52310SDavid Blaikie
getOrCreateGlobalVariableDIE(const DIGlobalVariable * GV,ArrayRef<GlobalExpr> GlobalExprs)13660635e39SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(
137bceaaa96SAdrian Prantl const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) {
13837c52310SDavid Blaikie // Check for pre-existence.
13937c52310SDavid Blaikie if (DIE *Die = getDIE(GV))
14037c52310SDavid Blaikie return Die;
14137c52310SDavid Blaikie
142e686f159SDuncan P. N. Exon Smith assert(GV);
14337c52310SDavid Blaikie
144be9e4fe7SDuncan P. N. Exon Smith auto *GVContext = GV->getScope();
145da82ce99SFangrui Song const DIType *GTy = GV->getType();
14637c52310SDavid Blaikie
1476ed5706aSAdrian Prantl auto *CB = GVContext ? dyn_cast<DICommonBlock>(GVContext) : nullptr;
1486ed5706aSAdrian Prantl DIE *ContextDIE = CB ? getOrCreateCommonBlock(CB, GlobalExprs)
1496ed5706aSAdrian Prantl : getOrCreateContextDIE(GVContext);
15037c52310SDavid Blaikie
15172da9391SAmjad Aboud // Add to map.
15272da9391SAmjad Aboud DIE *VariableDIE = &createAndAddDIE(GV->getTag(), *ContextDIE, GV);
153a9308c49SDuncan P. N. Exon Smith DIScope *DeclContext;
154b1055640SDuncan P. N. Exon Smith if (auto *SDMDecl = GV->getStaticDataMemberDeclaration()) {
155da82ce99SFangrui Song DeclContext = SDMDecl->getScope();
156b1055640SDuncan P. N. Exon Smith assert(SDMDecl->isStaticMember() && "Expected static member decl");
1577348ddaaSDuncan P. N. Exon Smith assert(GV->isDefinition());
15849cfc8caSDavid Blaikie // We need the declaration DIE that is in the static member's class.
15949cfc8caSDavid Blaikie DIE *VariableSpecDIE = getOrCreateStaticMemberDIE(SDMDecl);
16049cfc8caSDavid Blaikie addDIEEntry(*VariableDIE, dwarf::DW_AT_specification, *VariableSpecDIE);
1613502f208SAdrian Prantl // If the global variable's type is different from the one in the class
1623502f208SAdrian Prantl // member type, assume that it's more specific and also emit it.
163da82ce99SFangrui Song if (GTy != SDMDecl->getBaseType())
1643502f208SAdrian Prantl addType(*VariableDIE, GTy);
16549cfc8caSDavid Blaikie } else {
1667348ddaaSDuncan P. N. Exon Smith DeclContext = GV->getScope();
16737c52310SDavid Blaikie // Add name and type.
1687aa1fa0aSMitch Phillips StringRef DisplayName = GV->getDisplayName();
1697aa1fa0aSMitch Phillips if (!DisplayName.empty())
1707348ddaaSDuncan P. N. Exon Smith addString(*VariableDIE, dwarf::DW_AT_name, GV->getDisplayName());
1713eb465a3SYonghong Song if (GTy)
17237c52310SDavid Blaikie addType(*VariableDIE, GTy);
17337c52310SDavid Blaikie
17437c52310SDavid Blaikie // Add scoping info.
1757348ddaaSDuncan P. N. Exon Smith if (!GV->isLocalToUnit())
17637c52310SDavid Blaikie addFlag(*VariableDIE, dwarf::DW_AT_external);
17737c52310SDavid Blaikie
17837c52310SDavid Blaikie // Add line number info.
17937c52310SDavid Blaikie addSourceLine(*VariableDIE, GV);
18037c52310SDavid Blaikie }
18137c52310SDavid Blaikie
1827348ddaaSDuncan P. N. Exon Smith if (!GV->isDefinition())
18349cfc8caSDavid Blaikie addFlag(*VariableDIE, dwarf::DW_AT_declaration);
184877354a2SDavid Blaikie else
185877354a2SDavid Blaikie addGlobalName(GV->getName(), *VariableDIE, DeclContext);
18649cfc8caSDavid Blaikie
18789424a82SYonghong Song addAnnotation(*VariableDIE, GV->getAnnotations());
18889424a82SYonghong Song
1893c989984SVictor Leschuk if (uint32_t AlignInBytes = GV->getAlignInBytes())
1903c989984SVictor Leschuk addUInt(*VariableDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
1913c989984SVictor Leschuk AlignInBytes);
1923c989984SVictor Leschuk
193f8ab35a4SMatthew Voss if (MDTuple *TP = GV->getTemplateParams())
194f8ab35a4SMatthew Voss addTemplateParams(*VariableDIE, DINodeArray(TP));
195f8ab35a4SMatthew Voss
19637c52310SDavid Blaikie // Add location.
1976ed5706aSAdrian Prantl addLocationAttribute(VariableDIE, GV, GlobalExprs);
1986ed5706aSAdrian Prantl
1996ed5706aSAdrian Prantl return VariableDIE;
2006ed5706aSAdrian Prantl }
2016ed5706aSAdrian Prantl
addLocationAttribute(DIE * VariableDIE,const DIGlobalVariable * GV,ArrayRef<GlobalExpr> GlobalExprs)2026ed5706aSAdrian Prantl void DwarfCompileUnit::addLocationAttribute(
2036ed5706aSAdrian Prantl DIE *VariableDIE, const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) {
20437c52310SDavid Blaikie bool addToAccelTable = false;
205bceaaa96SAdrian Prantl DIELoc *Loc = nullptr;
206f3a91503SAlexey Bataev Optional<unsigned> NVPTXAddressSpace;
207bceaaa96SAdrian Prantl std::unique_ptr<DIEDwarfExpression> DwarfExpr;
208bceaaa96SAdrian Prantl for (const auto &GE : GlobalExprs) {
209bceaaa96SAdrian Prantl const GlobalVariable *Global = GE.Var;
210bceaaa96SAdrian Prantl const DIExpression *Expr = GE.Expr;
211b216e3e9SAdrian Prantl
212d4135bbcSPeter Collingbourne // For compatibility with DWARF 3 and earlier,
213f13f0505SSourabh Singh Tomar // DW_AT_location(DW_OP_constu, X, DW_OP_stack_value) or
214f13f0505SSourabh Singh Tomar // DW_AT_location(DW_OP_consts, X, DW_OP_stack_value) becomes
215d4135bbcSPeter Collingbourne // DW_AT_const_value(X).
216bceaaa96SAdrian Prantl if (GlobalExprs.size() == 1 && Expr && Expr->isConstant()) {
217b216e3e9SAdrian Prantl addToAccelTable = true;
218f13f0505SSourabh Singh Tomar addConstantValue(
219f13f0505SSourabh Singh Tomar *VariableDIE,
220f13f0505SSourabh Singh Tomar DIExpression::SignedOrUnsignedConstant::UnsignedConstant ==
221f13f0505SSourabh Singh Tomar *Expr->isConstant(),
222f13f0505SSourabh Singh Tomar Expr->getElement(1));
223b216e3e9SAdrian Prantl break;
224b216e3e9SAdrian Prantl }
225b216e3e9SAdrian Prantl
226bceaaa96SAdrian Prantl // We cannot describe the location of dllimport'd variables: the
227bceaaa96SAdrian Prantl // computation of their address requires loads from the IAT.
228b216e3e9SAdrian Prantl if (Global && Global->hasDLLImportStorageClass())
229b216e3e9SAdrian Prantl continue;
230b216e3e9SAdrian Prantl
231b216e3e9SAdrian Prantl // Nothing to describe without address or constant.
232b216e3e9SAdrian Prantl if (!Global && (!Expr || !Expr->isConstant()))
233b216e3e9SAdrian Prantl continue;
234b216e3e9SAdrian Prantl
2358e422b84SLei Liu if (Global && Global->isThreadLocal() &&
2368e422b84SLei Liu !Asm->getObjFileLowering().supportDebugThreadLocalLocation())
2378e422b84SLei Liu continue;
2388e422b84SLei Liu
239bceaaa96SAdrian Prantl if (!Loc) {
240b216e3e9SAdrian Prantl addToAccelTable = true;
241bceaaa96SAdrian Prantl Loc = new (DIEValueAllocator) DIELoc;
2420eaee545SJonas Devlieghere DwarfExpr = std::make_unique<DIEDwarfExpression>(*Asm, *this, *Loc);
243bceaaa96SAdrian Prantl }
244b216e3e9SAdrian Prantl
245f3a91503SAlexey Bataev if (Expr) {
246f3a91503SAlexey Bataev // According to
247f3a91503SAlexey Bataev // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf
248f3a91503SAlexey Bataev // cuda-gdb requires DW_AT_address_class for all variables to be able to
249f3a91503SAlexey Bataev // correctly interpret address space of the variable address.
250f3a91503SAlexey Bataev // Decode DW_OP_constu <DWARF Address Space> DW_OP_swap DW_OP_xderef
251f3a91503SAlexey Bataev // sequence for the NVPTX + gdb target.
252f3a91503SAlexey Bataev unsigned LocalNVPTXAddressSpace;
253f3a91503SAlexey Bataev if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {
254f3a91503SAlexey Bataev const DIExpression *NewExpr =
255f3a91503SAlexey Bataev DIExpression::extractAddressClass(Expr, LocalNVPTXAddressSpace);
256f3a91503SAlexey Bataev if (NewExpr != Expr) {
257f3a91503SAlexey Bataev Expr = NewExpr;
258f3a91503SAlexey Bataev NVPTXAddressSpace = LocalNVPTXAddressSpace;
259f3a91503SAlexey Bataev }
260f3a91503SAlexey Bataev }
261a9e31537SMikael Holmen DwarfExpr->addFragmentOffset(Expr);
262f3a91503SAlexey Bataev }
263a9e31537SMikael Holmen
264bceaaa96SAdrian Prantl if (Global) {
265cca5f68eSDuncan P. N. Exon Smith const MCSymbol *Sym = Asm->getSymbol(Global);
2665b133718SJack Andersen // 16-bit platforms like MSP430 and AVR take this path, so sink this
2675b133718SJack Andersen // assert to platforms that use it.
2685b133718SJack Andersen auto GetPointerSizedFormAndOp = [this]() {
26904dc6871SAlexandros Lamprineas unsigned PointerSize = Asm->getDataLayout().getPointerSize();
27004dc6871SAlexandros Lamprineas assert((PointerSize == 4 || PointerSize == 8) &&
27104dc6871SAlexandros Lamprineas "Add support for other sizes if necessary");
2725b133718SJack Andersen struct FormAndOp {
2735b133718SJack Andersen dwarf::Form Form;
2745b133718SJack Andersen dwarf::LocationAtom Op;
2755b133718SJack Andersen };
2765b133718SJack Andersen return PointerSize == 4
2775b133718SJack Andersen ? FormAndOp{dwarf::DW_FORM_data4, dwarf::DW_OP_const4u}
2785b133718SJack Andersen : FormAndOp{dwarf::DW_FORM_data8, dwarf::DW_OP_const8u};
2795b133718SJack Andersen };
280cca5f68eSDuncan P. N. Exon Smith if (Global->isThreadLocal()) {
2819f9e4681SChih-Hung Hsieh if (Asm->TM.useEmulatedTLS()) {
2821e859582SChih-Hung Hsieh // TODO: add debug info for emulated thread local mode.
2831e859582SChih-Hung Hsieh } else {
28437c52310SDavid Blaikie // FIXME: Make this work with -gsplit-dwarf.
28537c52310SDavid Blaikie // Based on GCC's support for TLS:
28637c52310SDavid Blaikie if (!DD->useSplitDwarf()) {
2875b133718SJack Andersen auto FormAndOp = GetPointerSizedFormAndOp();
28837c52310SDavid Blaikie // 1) Start with a constNu of the appropriate pointer size
2895b133718SJack Andersen addUInt(*Loc, dwarf::DW_FORM_data1, FormAndOp.Op);
29037c52310SDavid Blaikie // 2) containing the (relocated) offset of the TLS variable
29137c52310SDavid Blaikie // within the module's TLS block.
2925b133718SJack Andersen addExpr(*Loc, FormAndOp.Form,
29337c52310SDavid Blaikie Asm->getObjFileLowering().getDebugThreadLocalSymbol(Sym));
29437c52310SDavid Blaikie } else {
29537c52310SDavid Blaikie addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index);
29637c52310SDavid Blaikie addUInt(*Loc, dwarf::DW_FORM_udata,
29737c52310SDavid Blaikie DD->getAddressPool().getIndex(Sym, /* TLS */ true));
29837c52310SDavid Blaikie }
29978cc0821SPaul Robinson // 3) followed by an OP to make the debugger do a TLS lookup.
30078cc0821SPaul Robinson addUInt(*Loc, dwarf::DW_FORM_data1,
30178cc0821SPaul Robinson DD->useGNUTLSOpcode() ? dwarf::DW_OP_GNU_push_tls_address
30278cc0821SPaul Robinson : dwarf::DW_OP_form_tls_address);
3031e859582SChih-Hung Hsieh }
30494fac097SKeith Walker } else if ((Asm->TM.getRelocationModel() == Reloc::RWPI ||
30594fac097SKeith Walker Asm->TM.getRelocationModel() == Reloc::ROPI_RWPI) &&
30694fac097SKeith Walker !Asm->getObjFileLowering()
30794fac097SKeith Walker .getKindForGlobal(Global, Asm->TM)
30894fac097SKeith Walker .isReadOnly()) {
3095b133718SJack Andersen auto FormAndOp = GetPointerSizedFormAndOp();
31004dc6871SAlexandros Lamprineas // Constant
3115b133718SJack Andersen addUInt(*Loc, dwarf::DW_FORM_data1, FormAndOp.Op);
31204dc6871SAlexandros Lamprineas // Relocation offset
3135b133718SJack Andersen addExpr(*Loc, FormAndOp.Form,
31404dc6871SAlexandros Lamprineas Asm->getObjFileLowering().getIndirectSymViaRWPI(Sym));
31504dc6871SAlexandros Lamprineas // Base register
31604dc6871SAlexandros Lamprineas Register BaseReg = Asm->getObjFileLowering().getStaticBase();
31704dc6871SAlexandros Lamprineas BaseReg = Asm->TM.getMCRegisterInfo()->getDwarfRegNum(BaseReg, false);
31804dc6871SAlexandros Lamprineas addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + BaseReg);
31904dc6871SAlexandros Lamprineas // Offset from base register
32004dc6871SAlexandros Lamprineas addSInt(*Loc, dwarf::DW_FORM_sdata, 0);
32104dc6871SAlexandros Lamprineas // Operation
32204dc6871SAlexandros Lamprineas addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
32337c52310SDavid Blaikie } else {
32437c52310SDavid Blaikie DD->addArangeLabel(SymbolCU(this, Sym));
32537c52310SDavid Blaikie addOpAddress(*Loc, Sym);
32637c52310SDavid Blaikie }
327bceaaa96SAdrian Prantl }
3284b542c6eSAdrian Prantl // Global variables attached to symbols are memory locations.
3294b542c6eSAdrian Prantl // It would be better if this were unconditional, but malformed input that
3304b542c6eSAdrian Prantl // mixes non-fragments and fragments for the same variable is too expensive
3314b542c6eSAdrian Prantl // to detect in the verifier.
3323edc63a5SAdrian Prantl if (DwarfExpr->isUnknownLocation())
3334b542c6eSAdrian Prantl DwarfExpr->setMemoryLocationKind();
334a63b8e82SAdrian Prantl DwarfExpr->addExpression(Expr);
335d4135bbcSPeter Collingbourne }
336f3a91503SAlexey Bataev if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {
337f3a91503SAlexey Bataev // According to
338f3a91503SAlexey Bataev // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf
339f3a91503SAlexey Bataev // cuda-gdb requires DW_AT_address_class for all variables to be able to
340f3a91503SAlexey Bataev // correctly interpret address space of the variable address.
341f3a91503SAlexey Bataev const unsigned NVPTX_ADDR_global_space = 5;
342f3a91503SAlexey Bataev addUInt(*VariableDIE, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1,
343f3a91503SAlexey Bataev NVPTXAddressSpace ? *NVPTXAddressSpace : NVPTX_ADDR_global_space);
344f3a91503SAlexey Bataev }
345bceaaa96SAdrian Prantl if (Loc)
346bceaaa96SAdrian Prantl addBlock(*VariableDIE, dwarf::DW_AT_location, DwarfExpr->finalize());
347d4135bbcSPeter Collingbourne
34843d1e453SPaul Robinson if (DD->useAllLinkageNames())
3497348ddaaSDuncan P. N. Exon Smith addLinkageName(*VariableDIE, GV->getLinkageName());
35037c52310SDavid Blaikie
35137c52310SDavid Blaikie if (addToAccelTable) {
35266cf14d0SDavid Blaikie DD->addAccelName(*CUNode, GV->getName(), *VariableDIE);
35337c52310SDavid Blaikie
35437c52310SDavid Blaikie // If the linkage name is different than the name, go ahead and output
35537c52310SDavid Blaikie // that as well into the name table.
3562a6afe5fSPavel Labath if (GV->getLinkageName() != "" && GV->getName() != GV->getLinkageName() &&
3572a6afe5fSPavel Labath DD->useAllLinkageNames())
35866cf14d0SDavid Blaikie DD->addAccelName(*CUNode, GV->getLinkageName(), *VariableDIE);
35937c52310SDavid Blaikie }
3606ed5706aSAdrian Prantl }
36137c52310SDavid Blaikie
getOrCreateCommonBlock(const DICommonBlock * CB,ArrayRef<GlobalExpr> GlobalExprs)3626ed5706aSAdrian Prantl DIE *DwarfCompileUnit::getOrCreateCommonBlock(
3636ed5706aSAdrian Prantl const DICommonBlock *CB, ArrayRef<GlobalExpr> GlobalExprs) {
3645b4bfd8cSKristina Bessonova // Check for pre-existence.
3656ed5706aSAdrian Prantl if (DIE *NDie = getDIE(CB))
3666ed5706aSAdrian Prantl return NDie;
3675b4bfd8cSKristina Bessonova DIE *ContextDIE = getOrCreateContextDIE(CB->getScope());
3686ed5706aSAdrian Prantl DIE &NDie = createAndAddDIE(dwarf::DW_TAG_common_block, *ContextDIE, CB);
3696ed5706aSAdrian Prantl StringRef Name = CB->getName().empty() ? "_BLNK_" : CB->getName();
3706ed5706aSAdrian Prantl addString(NDie, dwarf::DW_AT_name, Name);
3716ed5706aSAdrian Prantl addGlobalName(Name, NDie, CB->getScope());
3726ed5706aSAdrian Prantl if (CB->getFile())
3736ed5706aSAdrian Prantl addSourceLine(NDie, CB->getLineNo(), CB->getFile());
3746ed5706aSAdrian Prantl if (DIGlobalVariable *V = CB->getDecl())
3756ed5706aSAdrian Prantl getCU().addLocationAttribute(&NDie, V, GlobalExprs);
3766ed5706aSAdrian Prantl return &NDie;
37737c52310SDavid Blaikie }
37837c52310SDavid Blaikie
addRange(RangeSpan Range)37937c52310SDavid Blaikie void DwarfCompileUnit::addRange(RangeSpan Range) {
38058b10df5SDavid Blaikie DD->insertSectionLabel(Range.Begin);
38158b10df5SDavid Blaikie
3826747d44bSKyungwoo Lee auto *PrevCU = DD->getPrevCU();
3836747d44bSKyungwoo Lee bool SameAsPrevCU = this == PrevCU;
38437c52310SDavid Blaikie DD->setPrevCU(this);
38537c52310SDavid Blaikie // If we have no current ranges just add the range and return, otherwise,
38637c52310SDavid Blaikie // check the current section and CU against the previous section and CU we
38737c52310SDavid Blaikie // emitted into and the subprogram was contained within. If these are the
38837c52310SDavid Blaikie // same then extend our current range, otherwise add this as a new range.
38937c52310SDavid Blaikie if (CURanges.empty() || !SameAsPrevCU ||
390b677cb8dSDavid Blaikie (&CURanges.back().End->getSection() !=
391b677cb8dSDavid Blaikie &Range.End->getSection())) {
3926747d44bSKyungwoo Lee // Before a new range is added, always terminate the prior line table.
3936747d44bSKyungwoo Lee if (PrevCU)
3946747d44bSKyungwoo Lee DD->terminateLineTable(PrevCU);
39537c52310SDavid Blaikie CURanges.push_back(Range);
39637c52310SDavid Blaikie return;
39737c52310SDavid Blaikie }
39837c52310SDavid Blaikie
399b677cb8dSDavid Blaikie CURanges.back().End = Range.End;
40037c52310SDavid Blaikie }
40137c52310SDavid Blaikie
initStmtList()402063d725fSRafael Espindola void DwarfCompileUnit::initStmtList() {
403d4dd7215SAlexey Bataev if (CUNode->isDebugDirectivesOnly())
404d4dd7215SAlexey Bataev return;
405d4dd7215SAlexey Bataev
406bff36086SAlexey Bataev const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
407bff36086SAlexey Bataev if (DD->useSectionsAsReferences()) {
408bff36086SAlexey Bataev LineTableStartSym = TLOF.getDwarfLineSection()->getBeginSymbol();
409bff36086SAlexey Bataev } else {
410bff36086SAlexey Bataev LineTableStartSym =
4119ff69c8fSLang Hames Asm->OutStreamer->getDwarfLineTableSymbol(getUniqueID());
412bff36086SAlexey Bataev }
41337c52310SDavid Blaikie
41437c52310SDavid Blaikie // DW_AT_stmt_list is a offset of line number information for this
41537c52310SDavid Blaikie // compile unit in debug_line section. For split dwarf this is
41637c52310SDavid Blaikie // left in the skeleton CU and so not included.
41737c52310SDavid Blaikie // The line table entries are not always emitted in assembly, so it
41837c52310SDavid Blaikie // is not okay to use line_table_start here.
41935630c33SGreg Clayton addSectionLabel(getUnitDie(), dwarf::DW_AT_stmt_list, LineTableStartSym,
420063d725fSRafael Espindola TLOF.getDwarfLineSection()->getBeginSymbol());
42137c52310SDavid Blaikie }
42237c52310SDavid Blaikie
applyStmtList(DIE & D)42337c52310SDavid Blaikie void DwarfCompileUnit::applyStmtList(DIE &D) {
4240d71782fSSourabh Singh Tomar const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
4250d71782fSSourabh Singh Tomar addSectionLabel(D, dwarf::DW_AT_stmt_list, LineTableStartSym,
4260d71782fSSourabh Singh Tomar TLOF.getDwarfLineSection()->getBeginSymbol());
42737c52310SDavid Blaikie }
42837c52310SDavid Blaikie
attachLowHighPC(DIE & D,const MCSymbol * Begin,const MCSymbol * End)42914499a7dSDavid Blaikie void DwarfCompileUnit::attachLowHighPC(DIE &D, const MCSymbol *Begin,
43014499a7dSDavid Blaikie const MCSymbol *End) {
43114499a7dSDavid Blaikie assert(Begin && "Begin label should not be null!");
43214499a7dSDavid Blaikie assert(End && "End label should not be null!");
43314499a7dSDavid Blaikie assert(Begin->isDefined() && "Invalid starting label");
43414499a7dSDavid Blaikie assert(End->isDefined() && "Invalid end label");
43514499a7dSDavid Blaikie
43614499a7dSDavid Blaikie addLabelAddress(D, dwarf::DW_AT_low_pc, Begin);
43714499a7dSDavid Blaikie if (DD->getDwarfVersion() < 4)
43814499a7dSDavid Blaikie addLabelAddress(D, dwarf::DW_AT_high_pc, End);
43914499a7dSDavid Blaikie else
44014499a7dSDavid Blaikie addLabelDelta(D, dwarf::DW_AT_high_pc, End, Begin);
44114499a7dSDavid Blaikie }
44214499a7dSDavid Blaikie
443cda2aa82SDavid Blaikie // Find DIE for the given subprogram and attach appropriate DW_AT_low_pc
444cda2aa82SDavid Blaikie // and DW_AT_high_pc attributes. If there are global variables in this
445cda2aa82SDavid Blaikie // scope then create and insert DIEs for these variables.
updateSubprogramScopeDIE(const DISubprogram * SP)446a9308c49SDuncan P. N. Exon Smith DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP) {
4473a443c29SDavid Blaikie DIE *SPDie = getOrCreateSubprogramDIE(SP, includeMinimalInlineScopes());
448cda2aa82SDavid Blaikie
449e4b3c138SKrzysztof Pszeniczny SmallVector<RangeSpan, 2> BB_List;
450e4b3c138SKrzysztof Pszeniczny // If basic block sections are on, ranges for each basic block section has
451e4b3c138SKrzysztof Pszeniczny // to be emitted separately.
452e4b3c138SKrzysztof Pszeniczny for (const auto &R : Asm->MBBSectionRanges)
453e4b3c138SKrzysztof Pszeniczny BB_List.push_back({R.second.BeginLabel, R.second.EndLabel});
454e4b3c138SKrzysztof Pszeniczny
455e4b3c138SKrzysztof Pszeniczny attachRangesOrLowHighPC(*SPDie, BB_List);
456e4b3c138SKrzysztof Pszeniczny
457c53e18d9SDavid Blaikie if (DD->useAppleExtensionAttributes() &&
458c53e18d9SDavid Blaikie !DD->getCurrentFunction()->getTarget().Options.DisableFramePointerElim(
459cda2aa82SDavid Blaikie *DD->getCurrentFunction()))
460cda2aa82SDavid Blaikie addFlag(*SPDie, dwarf::DW_AT_APPLE_omit_frame_ptr);
461cda2aa82SDavid Blaikie
462cda2aa82SDavid Blaikie // Only include DW_AT_frame_base in full debug info
4633a443c29SDavid Blaikie if (!includeMinimalInlineScopes()) {
464ff171acfSDerek Schuff const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();
465ff171acfSDerek Schuff TargetFrameLowering::DwarfFrameBase FrameBase =
466ff171acfSDerek Schuff TFI->getDwarfFrameBase(*Asm->MF);
467ff171acfSDerek Schuff switch (FrameBase.Kind) {
468ff171acfSDerek Schuff case TargetFrameLowering::DwarfFrameBase::Register: {
469ff171acfSDerek Schuff if (Register::isPhysicalRegister(FrameBase.Location.Reg)) {
470ff171acfSDerek Schuff MachineLocation Location(FrameBase.Location.Reg);
471ff171acfSDerek Schuff addAddress(*SPDie, dwarf::DW_AT_frame_base, Location);
472ff171acfSDerek Schuff }
473ff171acfSDerek Schuff break;
474ff171acfSDerek Schuff }
475ff171acfSDerek Schuff case TargetFrameLowering::DwarfFrameBase::CFA: {
4767ae86fe7SAlexey Bataev DIELoc *Loc = new (DIEValueAllocator) DIELoc;
4777ae86fe7SAlexey Bataev addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_call_frame_cfa);
4787ae86fe7SAlexey Bataev addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc);
479ff171acfSDerek Schuff break;
480ff171acfSDerek Schuff }
481ff171acfSDerek Schuff case TargetFrameLowering::DwarfFrameBase::WasmFrameBase: {
48248139ebcSWouter van Oortmerssen // FIXME: duplicated from Target/WebAssembly/WebAssembly.h
48348139ebcSWouter van Oortmerssen // don't want to depend on target specific headers in this code?
48448139ebcSWouter van Oortmerssen const unsigned TI_GLOBAL_RELOC = 3;
485a0f45268SWouter van Oortmerssen if (FrameBase.Location.WasmLoc.Kind == TI_GLOBAL_RELOC) {
48648139ebcSWouter van Oortmerssen // These need to be relocatable.
48748139ebcSWouter van Oortmerssen assert(FrameBase.Location.WasmLoc.Index == 0); // Only SP so far.
48848139ebcSWouter van Oortmerssen auto SPSym = cast<MCSymbolWasm>(
48948139ebcSWouter van Oortmerssen Asm->GetExternalSymbolSymbol("__stack_pointer"));
49048139ebcSWouter van Oortmerssen // FIXME: this repeats what WebAssemblyMCInstLower::
49148139ebcSWouter van Oortmerssen // GetExternalSymbolSymbol does, since if there's no code that
49248139ebcSWouter van Oortmerssen // refers to this symbol, we have to set it here.
49348139ebcSWouter van Oortmerssen SPSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
494b9a539c0SWouter van Oortmerssen SPSym->setGlobalType(wasm::WasmGlobalType{
495b9a539c0SWouter van Oortmerssen uint8_t(Asm->getSubtargetInfo().getTargetTriple().getArch() ==
496b9a539c0SWouter van Oortmerssen Triple::wasm64
497b9a539c0SWouter van Oortmerssen ? wasm::WASM_TYPE_I64
498b9a539c0SWouter van Oortmerssen : wasm::WASM_TYPE_I32),
499b9a539c0SWouter van Oortmerssen true});
50048139ebcSWouter van Oortmerssen DIELoc *Loc = new (DIEValueAllocator) DIELoc;
50148139ebcSWouter van Oortmerssen addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_WASM_location);
502f98e03a3SIgor Kudrin addSInt(*Loc, dwarf::DW_FORM_sdata, TI_GLOBAL_RELOC);
503a0f45268SWouter van Oortmerssen if (!isDwoUnit()) {
504f98e03a3SIgor Kudrin addLabel(*Loc, dwarf::DW_FORM_data4, SPSym);
505a0f45268SWouter van Oortmerssen } else {
506a0f45268SWouter van Oortmerssen // FIXME: when writing dwo, we need to avoid relocations. Probably
507a0f45268SWouter van Oortmerssen // the "right" solution is to treat globals the way func and data
508a0f45268SWouter van Oortmerssen // symbols are (with entries in .debug_addr).
509a0f45268SWouter van Oortmerssen // For now, since we only ever use index 0, this should work as-is.
510a0f45268SWouter van Oortmerssen addUInt(*Loc, dwarf::DW_FORM_data4, FrameBase.Location.WasmLoc.Index);
511a0f45268SWouter van Oortmerssen }
51248139ebcSWouter van Oortmerssen addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value);
51348139ebcSWouter van Oortmerssen addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc);
51448139ebcSWouter van Oortmerssen } else {
515ff171acfSDerek Schuff DIELoc *Loc = new (DIEValueAllocator) DIELoc;
516ff171acfSDerek Schuff DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
517ff171acfSDerek Schuff DIExpressionCursor Cursor({});
518ff171acfSDerek Schuff DwarfExpr.addWasmLocation(FrameBase.Location.WasmLoc.Kind,
519ff171acfSDerek Schuff FrameBase.Location.WasmLoc.Index);
520ff171acfSDerek Schuff DwarfExpr.addExpression(std::move(Cursor));
521ff171acfSDerek Schuff addBlock(*SPDie, dwarf::DW_AT_frame_base, DwarfExpr.finalize());
52248139ebcSWouter van Oortmerssen }
523ff171acfSDerek Schuff break;
524ff171acfSDerek Schuff }
525cda2aa82SDavid Blaikie }
5267ae86fe7SAlexey Bataev }
527cda2aa82SDavid Blaikie
528cda2aa82SDavid Blaikie // Add name to the name table, we do this here because we're guaranteed
529cda2aa82SDavid Blaikie // to have concrete versions of our DW_TAG_subprogram nodes.
53066cf14d0SDavid Blaikie DD->addSubprogramNames(*CUNode, SP, *SPDie);
531cda2aa82SDavid Blaikie
532cda2aa82SDavid Blaikie return *SPDie;
533cda2aa82SDavid Blaikie }
534cda2aa82SDavid Blaikie
5359c65b135SDavid Blaikie // Construct a DIE for this scope.
constructScopeDIE(LexicalScope * Scope,DIE & ParentScopeDIE)53690432893SKristina Bessonova void DwarfCompileUnit::constructScopeDIE(LexicalScope *Scope,
53790432893SKristina Bessonova DIE &ParentScopeDIE) {
5389c65b135SDavid Blaikie if (!Scope || !Scope->getScopeNode())
5399c65b135SDavid Blaikie return;
5409c65b135SDavid Blaikie
541be9e4fe7SDuncan P. N. Exon Smith auto *DS = Scope->getScopeNode();
5429c65b135SDavid Blaikie
543a9308c49SDuncan P. N. Exon Smith assert((Scope->getInlinedAt() || !isa<DISubprogram>(DS)) &&
5449c65b135SDavid Blaikie "Only handle inlined subprograms here, use "
5459c65b135SDavid Blaikie "constructSubprogramScopeDIE for non-inlined "
5469c65b135SDavid Blaikie "subprograms");
5479c65b135SDavid Blaikie
54890432893SKristina Bessonova // Emit inlined subprograms.
549a9308c49SDuncan P. N. Exon Smith if (Scope->getParent() && isa<DISubprogram>(DS)) {
55090432893SKristina Bessonova DIE *ScopeDIE = constructInlinedScopeDIE(Scope);
5519c65b135SDavid Blaikie if (!ScopeDIE)
5529c65b135SDavid Blaikie return;
55390432893SKristina Bessonova
55490432893SKristina Bessonova ParentScopeDIE.addChild(ScopeDIE);
55590432893SKristina Bessonova createAndAddScopeChildren(Scope, *ScopeDIE);
55690432893SKristina Bessonova return;
55790432893SKristina Bessonova }
55890432893SKristina Bessonova
5599c65b135SDavid Blaikie // Early exit when we know the scope DIE is going to be null.
5609c65b135SDavid Blaikie if (DD->isLexicalScopeDIENull(Scope))
5619c65b135SDavid Blaikie return;
5629c65b135SDavid Blaikie
56390432893SKristina Bessonova // Emit lexical blocks.
56490432893SKristina Bessonova DIE *ScopeDIE = constructLexicalScopeDIE(Scope);
5659c65b135SDavid Blaikie assert(ScopeDIE && "Scope DIE should not be null.");
56681378f7eSKristina Bessonova
56790432893SKristina Bessonova ParentScopeDIE.addChild(ScopeDIE);
56890432893SKristina Bessonova createAndAddScopeChildren(Scope, *ScopeDIE);
5699c65b135SDavid Blaikie }
5709c65b135SDavid Blaikie
addScopeRangeList(DIE & ScopeDIE,SmallVector<RangeSpan,2> Range)5715b02a19fSDavid Blaikie void DwarfCompileUnit::addScopeRangeList(DIE &ScopeDIE,
5725b02a19fSDavid Blaikie SmallVector<RangeSpan, 2> Range) {
57352400200SDavid Blaikie
574c4af8bf2SDavid Blaikie HasRangeLists = true;
575c4af8bf2SDavid Blaikie
576c4af8bf2SDavid Blaikie // Add the range list to the set of ranges to be emitted.
577c4af8bf2SDavid Blaikie auto IndexAndList =
578c4af8bf2SDavid Blaikie (DD->getDwarfVersion() < 5 && Skeleton ? Skeleton->DU : DU)
579c8f7e6c1SDavid Blaikie ->addRange(*(Skeleton ? Skeleton : this), std::move(Range));
580c4af8bf2SDavid Blaikie
581c4af8bf2SDavid Blaikie uint32_t Index = IndexAndList.first;
582c4af8bf2SDavid Blaikie auto &List = *IndexAndList.second;
5835b02a19fSDavid Blaikie
58452400200SDavid Blaikie // Under fission, ranges are specified by constant offsets relative to the
58552400200SDavid Blaikie // CU's DW_AT_GNU_ranges_base.
586fcf3810cSWolfgang Pieb // FIXME: For DWARF v5, do not generate the DW_AT_ranges attribute under
587fcf3810cSWolfgang Pieb // fission until we support the forms using the .debug_addr section
588fcf3810cSWolfgang Pieb // (DW_RLE_startx_endx etc.).
58932e09de9SDavid Blaikie if (DD->getDwarfVersion() >= 5)
59032e09de9SDavid Blaikie addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_rnglistx, Index);
591de9aa37bSDavid Blaikie else {
592de9aa37bSDavid Blaikie const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
593de9aa37bSDavid Blaikie const MCSymbol *RangeSectionSym =
594de9aa37bSDavid Blaikie TLOF.getDwarfRangesSection()->getBeginSymbol();
595de9aa37bSDavid Blaikie if (isDwoUnit())
59664fa76efSDavid Blaikie addSectionDelta(ScopeDIE, dwarf::DW_AT_ranges, List.Label,
5975b02a19fSDavid Blaikie RangeSectionSym);
598c4af8bf2SDavid Blaikie else
59964fa76efSDavid Blaikie addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges, List.Label,
6005b02a19fSDavid Blaikie RangeSectionSym);
601fcf3810cSWolfgang Pieb }
602de9aa37bSDavid Blaikie }
60352400200SDavid Blaikie
attachRangesOrLowHighPC(DIE & Die,SmallVector<RangeSpan,2> Ranges)604de12375cSDavid Blaikie void DwarfCompileUnit::attachRangesOrLowHighPC(
6055b02a19fSDavid Blaikie DIE &Die, SmallVector<RangeSpan, 2> Ranges) {
606ad18b075SDavid Blaikie assert(!Ranges.empty());
607ad18b075SDavid Blaikie if (!DD->useRangesSection() ||
608ad18b075SDavid Blaikie (Ranges.size() == 1 &&
609ad18b075SDavid Blaikie (!DD->alwaysUseRanges() ||
610ad18b075SDavid Blaikie DD->getSectionLabel(&Ranges.front().Begin->getSection()) ==
611ad18b075SDavid Blaikie Ranges.front().Begin))) {
612858a7dd6SAlexey Bataev const RangeSpan &Front = Ranges.front();
613858a7dd6SAlexey Bataev const RangeSpan &Back = Ranges.back();
614b677cb8dSDavid Blaikie attachLowHighPC(Die, Front.Begin, Back.End);
6155b02a19fSDavid Blaikie } else
6165b02a19fSDavid Blaikie addScopeRangeList(Die, std::move(Ranges));
6175b02a19fSDavid Blaikie }
6185b02a19fSDavid Blaikie
attachRangesOrLowHighPC(DIE & Die,const SmallVectorImpl<InsnRange> & Ranges)6195b02a19fSDavid Blaikie void DwarfCompileUnit::attachRangesOrLowHighPC(
620de12375cSDavid Blaikie DIE &Die, const SmallVectorImpl<InsnRange> &Ranges) {
6215b02a19fSDavid Blaikie SmallVector<RangeSpan, 2> List;
6225b02a19fSDavid Blaikie List.reserve(Ranges.size());
623e4b3c138SKrzysztof Pszeniczny for (const InsnRange &R : Ranges) {
624e4b3c138SKrzysztof Pszeniczny auto *BeginLabel = DD->getLabelBeforeInsn(R.first);
625e4b3c138SKrzysztof Pszeniczny auto *EndLabel = DD->getLabelAfterInsn(R.second);
626e4b3c138SKrzysztof Pszeniczny
627e4b3c138SKrzysztof Pszeniczny const auto *BeginMBB = R.first->getParent();
628e4b3c138SKrzysztof Pszeniczny const auto *EndMBB = R.second->getParent();
629e4b3c138SKrzysztof Pszeniczny
630e4b3c138SKrzysztof Pszeniczny const auto *MBB = BeginMBB;
631e4b3c138SKrzysztof Pszeniczny // Basic block sections allows basic block subsets to be placed in unique
632e4b3c138SKrzysztof Pszeniczny // sections. For each section, the begin and end label must be added to the
633e4b3c138SKrzysztof Pszeniczny // list. If there is more than one range, debug ranges must be used.
634e4b3c138SKrzysztof Pszeniczny // Otherwise, low/high PC can be used.
635e4b3c138SKrzysztof Pszeniczny // FIXME: Debug Info Emission depends on block order and this assumes that
636e4b3c138SKrzysztof Pszeniczny // the order of blocks will be frozen beyond this point.
637e4b3c138SKrzysztof Pszeniczny do {
638e4b3c138SKrzysztof Pszeniczny if (MBB->sameSection(EndMBB) || MBB->isEndSection()) {
639e4b3c138SKrzysztof Pszeniczny auto MBBSectionRange = Asm->MBBSectionRanges[MBB->getSectionIDNum()];
640b677cb8dSDavid Blaikie List.push_back(
641e4b3c138SKrzysztof Pszeniczny {MBB->sameSection(BeginMBB) ? BeginLabel
642e4b3c138SKrzysztof Pszeniczny : MBBSectionRange.BeginLabel,
643e4b3c138SKrzysztof Pszeniczny MBB->sameSection(EndMBB) ? EndLabel : MBBSectionRange.EndLabel});
644e4b3c138SKrzysztof Pszeniczny }
645e4b3c138SKrzysztof Pszeniczny if (MBB->sameSection(EndMBB))
646e4b3c138SKrzysztof Pszeniczny break;
647e4b3c138SKrzysztof Pszeniczny MBB = MBB->getNextNode();
648e4b3c138SKrzysztof Pszeniczny } while (true);
649e4b3c138SKrzysztof Pszeniczny }
6505b02a19fSDavid Blaikie attachRangesOrLowHighPC(Die, std::move(List));
651de12375cSDavid Blaikie }
652de12375cSDavid Blaikie
65301b48a84SDavid Blaikie // This scope represents inlined body of a function. Construct DIE to
65401b48a84SDavid Blaikie // represent this concrete inlined copy of the function.
constructInlinedScopeDIE(LexicalScope * Scope)655827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope) {
65601b48a84SDavid Blaikie assert(Scope->getScopeNode());
657be9e4fe7SDuncan P. N. Exon Smith auto *DS = Scope->getScopeNode();
658be9e4fe7SDuncan P. N. Exon Smith auto *InlinedSP = getDISubprogram(DS);
65901b48a84SDavid Blaikie // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram
66001b48a84SDavid Blaikie // was inlined from another compile unit.
66181378f7eSKristina Bessonova DIE *OriginDIE = getAbstractSPDies()[InlinedSP];
66201b48a84SDavid Blaikie assert(OriginDIE && "Unable to find original DIE for an inlined subprogram.");
66301b48a84SDavid Blaikie
664827200c8SDuncan P. N. Exon Smith auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_inlined_subroutine);
66501b48a84SDavid Blaikie addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *OriginDIE);
66601b48a84SDavid Blaikie
66701b48a84SDavid Blaikie attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges());
66801b48a84SDavid Blaikie
66901b48a84SDavid Blaikie // Add the call site information to the DIE.
670a9308c49SDuncan P. N. Exon Smith const DILocation *IA = Scope->getInlinedAt();
67101b48a84SDavid Blaikie addUInt(*ScopeDIE, dwarf::DW_AT_call_file, None,
672612e89d7SPaul Robinson getOrCreateSourceID(IA->getFile()));
673b7e221baSDuncan P. N. Exon Smith addUInt(*ScopeDIE, dwarf::DW_AT_call_line, None, IA->getLine());
67440580d36SDavid Blaikie if (IA->getColumn())
67583264b35SJonas Devlieghere addUInt(*ScopeDIE, dwarf::DW_AT_call_column, None, IA->getColumn());
6766e0c8446SDehao Chen if (IA->getDiscriminator() && DD->getDwarfVersion() >= 4)
67754511353SDehao Chen addUInt(*ScopeDIE, dwarf::DW_AT_GNU_discriminator, None,
67854511353SDehao Chen IA->getDiscriminator());
67901b48a84SDavid Blaikie
68001b48a84SDavid Blaikie // Add name to the name table, we do this here because we're guaranteed
68101b48a84SDavid Blaikie // to have concrete versions of our DW_TAG_inlined_subprogram nodes.
68266cf14d0SDavid Blaikie DD->addSubprogramNames(*CUNode, InlinedSP, *ScopeDIE);
68301b48a84SDavid Blaikie
68401b48a84SDavid Blaikie return ScopeDIE;
68501b48a84SDavid Blaikie }
68601b48a84SDavid Blaikie
6870fbf8bdbSDavid Blaikie // Construct new DW_TAG_lexical_block for this scope and attach
6880fbf8bdbSDavid Blaikie // DW_AT_low_pc/DW_AT_high_pc labels.
constructLexicalScopeDIE(LexicalScope * Scope)689827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) {
6900fbf8bdbSDavid Blaikie if (DD->isLexicalScopeDIENull(Scope))
6910fbf8bdbSDavid Blaikie return nullptr;
6920fbf8bdbSDavid Blaikie
693827200c8SDuncan P. N. Exon Smith auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_lexical_block);
6940fbf8bdbSDavid Blaikie if (Scope->isAbstractScope())
6950fbf8bdbSDavid Blaikie return ScopeDIE;
6960fbf8bdbSDavid Blaikie
6970fbf8bdbSDavid Blaikie attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges());
6980fbf8bdbSDavid Blaikie
6990fbf8bdbSDavid Blaikie return ScopeDIE;
7000fbf8bdbSDavid Blaikie }
7010fbf8bdbSDavid Blaikie
702ee7df553SDavid Blaikie /// constructVariableDIE - Construct a DIE for the given DbgVariable.
constructVariableDIE(DbgVariable & DV,bool Abstract)703827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, bool Abstract) {
704ee7df553SDavid Blaikie auto D = constructVariableDIEImpl(DV, Abstract);
705ee7df553SDavid Blaikie DV.setDIE(*D);
706ee7df553SDavid Blaikie return D;
707ee7df553SDavid Blaikie }
708ee7df553SDavid Blaikie
constructLabelDIE(DbgLabel & DL,const LexicalScope & Scope)7092532ac88SHsiangkai Wang DIE *DwarfCompileUnit::constructLabelDIE(DbgLabel &DL,
7102532ac88SHsiangkai Wang const LexicalScope &Scope) {
7112532ac88SHsiangkai Wang auto LabelDie = DIE::get(DIEValueAllocator, DL.getTag());
7122532ac88SHsiangkai Wang insertDIE(DL.getLabel(), LabelDie);
7132532ac88SHsiangkai Wang DL.setDIE(*LabelDie);
7142532ac88SHsiangkai Wang
7152532ac88SHsiangkai Wang if (Scope.isAbstractScope())
7162532ac88SHsiangkai Wang applyLabelAttributes(DL, *LabelDie);
7172532ac88SHsiangkai Wang
7182532ac88SHsiangkai Wang return LabelDie;
7192532ac88SHsiangkai Wang }
7202532ac88SHsiangkai Wang
constructVariableDIEImpl(const DbgVariable & DV,bool Abstract)721827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
722ee7df553SDavid Blaikie bool Abstract) {
723ee7df553SDavid Blaikie // Define variable debug information entry.
724827200c8SDuncan P. N. Exon Smith auto VariableDie = DIE::get(DIEValueAllocator, DV.getTag());
725dc00becdSSander de Smalen insertDIE(DV.getVariable(), VariableDie);
726ee7df553SDavid Blaikie
727ee7df553SDavid Blaikie if (Abstract) {
728ee7df553SDavid Blaikie applyVariableAttributes(DV, *VariableDie);
729ee7df553SDavid Blaikie return VariableDie;
730ee7df553SDavid Blaikie }
731ee7df553SDavid Blaikie
732ee7df553SDavid Blaikie // Add variable address.
733ee7df553SDavid Blaikie
7348feff8d1SIgor Kudrin unsigned Index = DV.getDebugLocListIndex();
7358feff8d1SIgor Kudrin if (Index != ~0U) {
7368feff8d1SIgor Kudrin addLocationList(*VariableDie, dwarf::DW_AT_location, Index);
737dabd2622SEvgenii Stepanov auto TagOffset = DV.getDebugLocListTagOffset();
738dabd2622SEvgenii Stepanov if (TagOffset)
739dabd2622SEvgenii Stepanov addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
740dabd2622SEvgenii Stepanov *TagOffset);
741ee7df553SDavid Blaikie return VariableDie;
742ee7df553SDavid Blaikie }
743ee7df553SDavid Blaikie
744abc1dff7SNikola Prica // Check if variable has a single location description.
745abc1dff7SNikola Prica if (auto *DVal = DV.getValueLoc()) {
746e64f3cccSStephen Tozer if (!DVal->isVariadic()) {
747e64f3cccSStephen Tozer const DbgValueLocEntry *Entry = DVal->getLocEntries().begin();
748e64f3cccSStephen Tozer if (Entry->isLocation()) {
749e64f3cccSStephen Tozer addVariableAddress(DV, *VariableDie, Entry->getLoc());
750e64f3cccSStephen Tozer } else if (Entry->isInt()) {
7513b89e663SAdrian Prantl auto *Expr = DV.getSingleExpression();
7523b89e663SAdrian Prantl if (Expr && Expr->getNumElements()) {
7533b89e663SAdrian Prantl DIELoc *Loc = new (DIEValueAllocator) DIELoc;
7543b89e663SAdrian Prantl DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
7553b89e663SAdrian Prantl // If there is an expression, emit raw unsigned bytes.
7568fafb8d3SAdrian Prantl DwarfExpr.addFragmentOffset(Expr);
757e64f3cccSStephen Tozer DwarfExpr.addUnsignedConstant(Entry->getInt());
758a63b8e82SAdrian Prantl DwarfExpr.addExpression(Expr);
759bceaaa96SAdrian Prantl addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
760dabd2622SEvgenii Stepanov if (DwarfExpr.TagOffset)
761dabd2622SEvgenii Stepanov addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset,
762dabd2622SEvgenii Stepanov dwarf::DW_FORM_data1, *DwarfExpr.TagOffset);
7633b89e663SAdrian Prantl } else
764e64f3cccSStephen Tozer addConstantValue(*VariableDie, Entry->getInt(), DV.getType());
765e64f3cccSStephen Tozer } else if (Entry->isConstantFP()) {
766e64f3cccSStephen Tozer addConstantFPValue(*VariableDie, Entry->getConstantFP());
767e64f3cccSStephen Tozer } else if (Entry->isConstantInt()) {
768e64f3cccSStephen Tozer addConstantValue(*VariableDie, Entry->getConstantInt(), DV.getType());
769e64f3cccSStephen Tozer } else if (Entry->isTargetIndexLocation()) {
7705c38ae36SWouter van Oortmerssen DIELoc *Loc = new (DIEValueAllocator) DIELoc;
7715c38ae36SWouter van Oortmerssen DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
7725c38ae36SWouter van Oortmerssen const DIBasicType *BT = dyn_cast<DIBasicType>(
7735c38ae36SWouter van Oortmerssen static_cast<const Metadata *>(DV.getVariable()->getType()));
7745c38ae36SWouter van Oortmerssen DwarfDebug::emitDebugLocValue(*Asm, BT, *DVal, DwarfExpr);
7755c38ae36SWouter van Oortmerssen addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
776abc1dff7SNikola Prica }
777ee7df553SDavid Blaikie return VariableDie;
778ee7df553SDavid Blaikie }
779e64f3cccSStephen Tozer // If any of the location entries are registers with the value 0, then the
780e64f3cccSStephen Tozer // location is undefined.
781e64f3cccSStephen Tozer if (any_of(DVal->getLocEntries(), [](const DbgValueLocEntry &Entry) {
782e64f3cccSStephen Tozer return Entry.isLocation() && !Entry.getLoc().getReg();
783e64f3cccSStephen Tozer }))
784e64f3cccSStephen Tozer return VariableDie;
785e64f3cccSStephen Tozer const DIExpression *Expr = DV.getSingleExpression();
786e64f3cccSStephen Tozer assert(Expr && "Variadic Debug Value must have an Expression.");
787e64f3cccSStephen Tozer DIELoc *Loc = new (DIEValueAllocator) DIELoc;
788e64f3cccSStephen Tozer DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
789e64f3cccSStephen Tozer DwarfExpr.addFragmentOffset(Expr);
790e64f3cccSStephen Tozer DIExpressionCursor Cursor(Expr);
791e64f3cccSStephen Tozer const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
792e64f3cccSStephen Tozer
79380d1f657SDavid Blaikie auto AddEntry = [&](const DbgValueLocEntry &Entry,
794e64f3cccSStephen Tozer DIExpressionCursor &Cursor) {
795e64f3cccSStephen Tozer if (Entry.isLocation()) {
796e64f3cccSStephen Tozer if (!DwarfExpr.addMachineRegExpression(TRI, Cursor,
797e64f3cccSStephen Tozer Entry.getLoc().getReg()))
798e64f3cccSStephen Tozer return false;
799e64f3cccSStephen Tozer } else if (Entry.isInt()) {
800e64f3cccSStephen Tozer // If there is an expression, emit raw unsigned bytes.
801e64f3cccSStephen Tozer DwarfExpr.addUnsignedConstant(Entry.getInt());
802e64f3cccSStephen Tozer } else if (Entry.isConstantFP()) {
803c7c84b90SAdrian Prantl // DwarfExpression does not support arguments wider than 64 bits
804c7c84b90SAdrian Prantl // (see PR52584).
805c7c84b90SAdrian Prantl // TODO: Consider chunking expressions containing overly wide
806c7c84b90SAdrian Prantl // arguments into separate pointer-sized fragment expressions.
807e64f3cccSStephen Tozer APInt RawBytes = Entry.getConstantFP()->getValueAPF().bitcastToAPInt();
808c7c84b90SAdrian Prantl if (RawBytes.getBitWidth() > 64)
809c7c84b90SAdrian Prantl return false;
810c7c84b90SAdrian Prantl DwarfExpr.addUnsignedConstant(RawBytes.getZExtValue());
811e64f3cccSStephen Tozer } else if (Entry.isConstantInt()) {
812e64f3cccSStephen Tozer APInt RawBytes = Entry.getConstantInt()->getValue();
813c7c84b90SAdrian Prantl if (RawBytes.getBitWidth() > 64)
814c7c84b90SAdrian Prantl return false;
815c7c84b90SAdrian Prantl DwarfExpr.addUnsignedConstant(RawBytes.getZExtValue());
816e64f3cccSStephen Tozer } else if (Entry.isTargetIndexLocation()) {
817e64f3cccSStephen Tozer TargetIndexLocation Loc = Entry.getTargetIndexLocation();
818e64f3cccSStephen Tozer // TODO TargetIndexLocation is a target-independent. Currently only the
819e64f3cccSStephen Tozer // WebAssembly-specific encoding is supported.
82080d1f657SDavid Blaikie assert(Asm->TM.getTargetTriple().isWasm());
821e64f3cccSStephen Tozer DwarfExpr.addWasmLocation(Loc.Index, static_cast<uint64_t>(Loc.Offset));
822e64f3cccSStephen Tozer } else {
823e64f3cccSStephen Tozer llvm_unreachable("Unsupported Entry type.");
824e64f3cccSStephen Tozer }
825e64f3cccSStephen Tozer return true;
826e64f3cccSStephen Tozer };
827e64f3cccSStephen Tozer
828c7c84b90SAdrian Prantl if (!DwarfExpr.addExpression(
829e64f3cccSStephen Tozer std::move(Cursor),
83080d1f657SDavid Blaikie [&](unsigned Idx, DIExpressionCursor &Cursor) -> bool {
831e64f3cccSStephen Tozer return AddEntry(DVal->getLocEntries()[Idx], Cursor);
832c7c84b90SAdrian Prantl }))
833c7c84b90SAdrian Prantl return VariableDie;
834e64f3cccSStephen Tozer
835e64f3cccSStephen Tozer // Now attach the location information to the DIE.
836e64f3cccSStephen Tozer addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
837e64f3cccSStephen Tozer if (DwarfExpr.TagOffset)
838e64f3cccSStephen Tozer addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
839e64f3cccSStephen Tozer *DwarfExpr.TagOffset);
840e64f3cccSStephen Tozer
841e64f3cccSStephen Tozer return VariableDie;
842e64f3cccSStephen Tozer }
843ee7df553SDavid Blaikie
844ee7df553SDavid Blaikie // .. else use frame index.
84567c24422SAdrian Prantl if (!DV.hasFrameIndexExprs())
846ca7e4702SAdrian Prantl return VariableDie;
847ca7e4702SAdrian Prantl
848f3a91503SAlexey Bataev Optional<unsigned> NVPTXAddressSpace;
849e7e1d0c7SDuncan P. N. Exon Smith DIELoc *Loc = new (DIEValueAllocator) DIELoc;
850ca7e4702SAdrian Prantl DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
851*9e6d1f4bSKazu Hirata for (const auto &Fragment : DV.getFrameIndexExprs()) {
8522481f26aSMatt Arsenault Register FrameReg;
8536825fb64SAdrian Prantl const DIExpression *Expr = Fragment.Expr;
854d4e723f2SEric Christopher const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();
855d57bba7cSSander de Smalen StackOffset Offset =
856d57bba7cSSander de Smalen TFI->getFrameIndexReference(*Asm->MF, Fragment.FI, FrameReg);
8576825fb64SAdrian Prantl DwarfExpr.addFragmentOffset(Expr);
858d57bba7cSSander de Smalen
859aa280c99SSander de Smalen auto *TRI = Asm->MF->getSubtarget().getRegisterInfo();
860956484b7SAdrian Prantl SmallVector<uint64_t, 8> Ops;
861aa280c99SSander de Smalen TRI->getOffsetOpcodes(Offset, Ops);
862aa280c99SSander de Smalen
863f3a91503SAlexey Bataev // According to
864f3a91503SAlexey Bataev // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf
865f3a91503SAlexey Bataev // cuda-gdb requires DW_AT_address_class for all variables to be able to
866f3a91503SAlexey Bataev // correctly interpret address space of the variable address.
867f3a91503SAlexey Bataev // Decode DW_OP_constu <DWARF Address Space> DW_OP_swap DW_OP_xderef
868f3a91503SAlexey Bataev // sequence for the NVPTX + gdb target.
869f3a91503SAlexey Bataev unsigned LocalNVPTXAddressSpace;
870f3a91503SAlexey Bataev if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {
871f3a91503SAlexey Bataev const DIExpression *NewExpr =
872f3a91503SAlexey Bataev DIExpression::extractAddressClass(Expr, LocalNVPTXAddressSpace);
873f3a91503SAlexey Bataev if (NewExpr != Expr) {
874f3a91503SAlexey Bataev Expr = NewExpr;
875f3a91503SAlexey Bataev NVPTXAddressSpace = LocalNVPTXAddressSpace;
876f3a91503SAlexey Bataev }
877f3a91503SAlexey Bataev }
878f3a91503SAlexey Bataev if (Expr)
8796825fb64SAdrian Prantl Ops.append(Expr->elements_begin(), Expr->elements_end());
8806825fb64SAdrian Prantl DIExpressionCursor Cursor(Ops);
881c12cee36SAdrian Prantl DwarfExpr.setMemoryLocationKind();
8824dd7558fSAlexey Bataev if (const MCSymbol *FrameSymbol = Asm->getFunctionFrameSymbol())
8834dd7558fSAlexey Bataev addOpAddress(*Loc, FrameSymbol);
8844dd7558fSAlexey Bataev else
885c12cee36SAdrian Prantl DwarfExpr.addMachineRegExpression(
886c12cee36SAdrian Prantl *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, FrameReg);
8876825fb64SAdrian Prantl DwarfExpr.addExpression(std::move(Cursor));
888ee7df553SDavid Blaikie }
889f3a91503SAlexey Bataev if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {
890f3a91503SAlexey Bataev // According to
891f3a91503SAlexey Bataev // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf
892f3a91503SAlexey Bataev // cuda-gdb requires DW_AT_address_class for all variables to be able to
893f3a91503SAlexey Bataev // correctly interpret address space of the variable address.
894f3a91503SAlexey Bataev const unsigned NVPTX_ADDR_local_space = 6;
895f3a91503SAlexey Bataev addUInt(*VariableDie, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1,
896f3a91503SAlexey Bataev NVPTXAddressSpace ? *NVPTXAddressSpace : NVPTX_ADDR_local_space);
897f3a91503SAlexey Bataev }
898bceaaa96SAdrian Prantl addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
899fb9ce100SPeter Collingbourne if (DwarfExpr.TagOffset)
900fb9ce100SPeter Collingbourne addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
901fb9ce100SPeter Collingbourne *DwarfExpr.TagOffset);
902ee7df553SDavid Blaikie
903ee7df553SDavid Blaikie return VariableDie;
904ee7df553SDavid Blaikie }
905ee7df553SDavid Blaikie
constructVariableDIE(DbgVariable & DV,const LexicalScope & Scope,DIE * & ObjectPointer)906827200c8SDuncan P. N. Exon Smith DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV,
907827200c8SDuncan P. N. Exon Smith const LexicalScope &Scope,
908827200c8SDuncan P. N. Exon Smith DIE *&ObjectPointer) {
9094a1a44e3SDavid Blaikie auto Var = constructVariableDIE(DV, Scope.isAbstractScope());
9104a1a44e3SDavid Blaikie if (DV.isObjectPointer())
911827200c8SDuncan P. N. Exon Smith ObjectPointer = Var;
9124a1a44e3SDavid Blaikie return Var;
9134a1a44e3SDavid Blaikie }
9144a1a44e3SDavid Blaikie
91503dd6f57SAdrian Prantl /// Return all DIVariables that appear in count: expressions.
dependencies(DbgVariable * Var)91603dd6f57SAdrian Prantl static SmallVector<const DIVariable *, 2> dependencies(DbgVariable *Var) {
91703dd6f57SAdrian Prantl SmallVector<const DIVariable *, 2> Result;
91803dd6f57SAdrian Prantl auto *Array = dyn_cast<DICompositeType>(Var->getType());
919c929f7adSAdrian Prantl if (!Array || Array->getTag() != dwarf::DW_TAG_array_type)
92003dd6f57SAdrian Prantl return Result;
9214042ada1SAlok Kumar Sharma if (auto *DLVar = Array->getDataLocation())
9224042ada1SAlok Kumar Sharma Result.push_back(DLVar);
9232d10258aSAlok Kumar Sharma if (auto *AsVar = Array->getAssociated())
9242d10258aSAlok Kumar Sharma Result.push_back(AsVar);
9252d10258aSAlok Kumar Sharma if (auto *AlVar = Array->getAllocated())
9262d10258aSAlok Kumar Sharma Result.push_back(AlVar);
92703dd6f57SAdrian Prantl for (auto *El : Array->getElements()) {
928c929f7adSAdrian Prantl if (auto *Subrange = dyn_cast<DISubrange>(El)) {
929d20bf5a7SAlok Kumar Sharma if (auto Count = Subrange->getCount())
93003dd6f57SAdrian Prantl if (auto *Dependency = Count.dyn_cast<DIVariable *>())
93103dd6f57SAdrian Prantl Result.push_back(Dependency);
932d20bf5a7SAlok Kumar Sharma if (auto LB = Subrange->getLowerBound())
933d20bf5a7SAlok Kumar Sharma if (auto *Dependency = LB.dyn_cast<DIVariable *>())
934d20bf5a7SAlok Kumar Sharma Result.push_back(Dependency);
935d20bf5a7SAlok Kumar Sharma if (auto UB = Subrange->getUpperBound())
936d20bf5a7SAlok Kumar Sharma if (auto *Dependency = UB.dyn_cast<DIVariable *>())
937d20bf5a7SAlok Kumar Sharma Result.push_back(Dependency);
938d20bf5a7SAlok Kumar Sharma if (auto ST = Subrange->getStride())
939d20bf5a7SAlok Kumar Sharma if (auto *Dependency = ST.dyn_cast<DIVariable *>())
940d20bf5a7SAlok Kumar Sharma Result.push_back(Dependency);
941a6dd01afSAlok Kumar Sharma } else if (auto *GenericSubrange = dyn_cast<DIGenericSubrange>(El)) {
942a6dd01afSAlok Kumar Sharma if (auto Count = GenericSubrange->getCount())
943a6dd01afSAlok Kumar Sharma if (auto *Dependency = Count.dyn_cast<DIVariable *>())
944a6dd01afSAlok Kumar Sharma Result.push_back(Dependency);
945a6dd01afSAlok Kumar Sharma if (auto LB = GenericSubrange->getLowerBound())
946a6dd01afSAlok Kumar Sharma if (auto *Dependency = LB.dyn_cast<DIVariable *>())
947a6dd01afSAlok Kumar Sharma Result.push_back(Dependency);
948a6dd01afSAlok Kumar Sharma if (auto UB = GenericSubrange->getUpperBound())
949a6dd01afSAlok Kumar Sharma if (auto *Dependency = UB.dyn_cast<DIVariable *>())
950a6dd01afSAlok Kumar Sharma Result.push_back(Dependency);
951a6dd01afSAlok Kumar Sharma if (auto ST = GenericSubrange->getStride())
952a6dd01afSAlok Kumar Sharma if (auto *Dependency = ST.dyn_cast<DIVariable *>())
953a6dd01afSAlok Kumar Sharma Result.push_back(Dependency);
954c929f7adSAdrian Prantl }
95503dd6f57SAdrian Prantl }
95603dd6f57SAdrian Prantl return Result;
957c929f7adSAdrian Prantl }
958c929f7adSAdrian Prantl
959c929f7adSAdrian Prantl /// Sort local variables so that variables appearing inside of helper
960c929f7adSAdrian Prantl /// expressions come first.
96103dd6f57SAdrian Prantl static SmallVector<DbgVariable *, 8>
sortLocalVars(SmallVectorImpl<DbgVariable * > & Input)96203dd6f57SAdrian Prantl sortLocalVars(SmallVectorImpl<DbgVariable *> &Input) {
96303dd6f57SAdrian Prantl SmallVector<DbgVariable *, 8> Result;
96403dd6f57SAdrian Prantl SmallVector<PointerIntPair<DbgVariable *, 1>, 8> WorkList;
96503dd6f57SAdrian Prantl // Map back from a DIVariable to its containing DbgVariable.
96603dd6f57SAdrian Prantl SmallDenseMap<const DILocalVariable *, DbgVariable *> DbgVar;
96703dd6f57SAdrian Prantl // Set of DbgVariables in Result.
96803dd6f57SAdrian Prantl SmallDenseSet<DbgVariable *, 8> Visited;
96903dd6f57SAdrian Prantl // For cycle detection.
97003dd6f57SAdrian Prantl SmallDenseSet<DbgVariable *, 8> Visiting;
97103dd6f57SAdrian Prantl
97203dd6f57SAdrian Prantl // Initialize the worklist and the DIVariable lookup table.
973*9e6d1f4bSKazu Hirata for (auto *Var : reverse(Input)) {
97403dd6f57SAdrian Prantl DbgVar.insert({Var->getVariable(), Var});
97503dd6f57SAdrian Prantl WorkList.push_back({Var, 0});
97603dd6f57SAdrian Prantl }
97703dd6f57SAdrian Prantl
97803dd6f57SAdrian Prantl // Perform a stable topological sort by doing a DFS.
97903dd6f57SAdrian Prantl while (!WorkList.empty()) {
98003dd6f57SAdrian Prantl auto Item = WorkList.back();
98103dd6f57SAdrian Prantl DbgVariable *Var = Item.getPointer();
98203dd6f57SAdrian Prantl bool visitedAllDependencies = Item.getInt();
98303dd6f57SAdrian Prantl WorkList.pop_back();
98403dd6f57SAdrian Prantl
985b20da511SAaron Puchert assert(Var);
98603dd6f57SAdrian Prantl
98703dd6f57SAdrian Prantl // Already handled.
98803dd6f57SAdrian Prantl if (Visited.count(Var))
98903dd6f57SAdrian Prantl continue;
99003dd6f57SAdrian Prantl
99103dd6f57SAdrian Prantl // Add to Result if all dependencies are visited.
99203dd6f57SAdrian Prantl if (visitedAllDependencies) {
99303dd6f57SAdrian Prantl Visited.insert(Var);
99403dd6f57SAdrian Prantl Result.push_back(Var);
99503dd6f57SAdrian Prantl continue;
99603dd6f57SAdrian Prantl }
99703dd6f57SAdrian Prantl
99803dd6f57SAdrian Prantl // Detect cycles.
99903dd6f57SAdrian Prantl auto Res = Visiting.insert(Var);
100003dd6f57SAdrian Prantl if (!Res.second) {
100103dd6f57SAdrian Prantl assert(false && "dependency cycle in local variables");
100203dd6f57SAdrian Prantl return Result;
100303dd6f57SAdrian Prantl }
100403dd6f57SAdrian Prantl
100503dd6f57SAdrian Prantl // Push dependencies and this node onto the worklist, so that this node is
100603dd6f57SAdrian Prantl // visited again after all of its dependencies are handled.
100703dd6f57SAdrian Prantl WorkList.push_back({Var, 1});
1008*9e6d1f4bSKazu Hirata for (const auto *Dependency : dependencies(Var)) {
1009b20da511SAaron Puchert // Don't add dependency if it is in a different lexical scope or a global.
1010b20da511SAaron Puchert if (const auto *Dep = dyn_cast<const DILocalVariable>(Dependency))
1011b20da511SAaron Puchert if (DbgVariable *Var = DbgVar.lookup(Dep))
1012b20da511SAaron Puchert WorkList.push_back({Var, 0});
101303dd6f57SAdrian Prantl }
101403dd6f57SAdrian Prantl }
101503dd6f57SAdrian Prantl return Result;
1016c929f7adSAdrian Prantl }
1017c929f7adSAdrian Prantl
constructSubprogramScopeDIE(const DISubprogram * Sub,LexicalScope * Scope)10185931b4e5SVedant Kumar DIE &DwarfCompileUnit::constructSubprogramScopeDIE(const DISubprogram *Sub,
10195931b4e5SVedant Kumar LexicalScope *Scope) {
10201d072348SDavid Blaikie DIE &ScopeDIE = updateSubprogramScopeDIE(Sub);
10211d072348SDavid Blaikie
10223e3eb33eSDavid Blaikie if (Scope) {
10233e3eb33eSDavid Blaikie assert(!Scope->getInlinedAt());
10243e3eb33eSDavid Blaikie assert(!Scope->isAbstractScope());
10251dd573dbSDavid Blaikie // Collect lexical scope children first.
10261dd573dbSDavid Blaikie // ObjectPointer might be a local (non-argument) local variable if it's a
10271dd573dbSDavid Blaikie // block's synthetic this pointer.
10281dd573dbSDavid Blaikie if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, ScopeDIE))
10291dd573dbSDavid Blaikie addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer);
10303e3eb33eSDavid Blaikie }
10313e3eb33eSDavid Blaikie
10323e3eb33eSDavid Blaikie // If this is a variadic function, add an unspecified parameter.
10333e3eb33eSDavid Blaikie DITypeRefArray FnArgs = Sub->getType()->getTypeArray();
10341dd573dbSDavid Blaikie
10351d072348SDavid Blaikie // If we have a single element of null, it is a function that returns void.
10361d072348SDavid Blaikie // If we have more than one elements and the last one is null, it is a
10371d072348SDavid Blaikie // variadic function.
1038000fa2c6SDuncan P. N. Exon Smith if (FnArgs.size() > 1 && !FnArgs[FnArgs.size() - 1] &&
10393a443c29SDavid Blaikie !includeMinimalInlineScopes())
1040827200c8SDuncan P. N. Exon Smith ScopeDIE.addChild(
1041827200c8SDuncan P. N. Exon Smith DIE::get(DIEValueAllocator, dwarf::DW_TAG_unspecified_parameters));
10425931b4e5SVedant Kumar
10435931b4e5SVedant Kumar return ScopeDIE;
10441d072348SDavid Blaikie }
10451d072348SDavid Blaikie
createAndAddScopeChildren(LexicalScope * Scope,DIE & ScopeDIE)104678b65b6fSDavid Blaikie DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope,
104778b65b6fSDavid Blaikie DIE &ScopeDIE) {
104890432893SKristina Bessonova DIE *ObjectPointer = nullptr;
104978b65b6fSDavid Blaikie
105090432893SKristina Bessonova // Emit function arguments (order is significant).
105190432893SKristina Bessonova auto Vars = DU->getScopeVariables().lookup(Scope);
105290432893SKristina Bessonova for (auto &DV : Vars.Args)
105390432893SKristina Bessonova ScopeDIE.addChild(constructVariableDIE(*DV.second, *Scope, ObjectPointer));
105490432893SKristina Bessonova
105590432893SKristina Bessonova // Emit local variables.
105690432893SKristina Bessonova auto Locals = sortLocalVars(Vars.Locals);
105790432893SKristina Bessonova for (DbgVariable *DV : Locals)
105890432893SKristina Bessonova ScopeDIE.addChild(constructVariableDIE(*DV, *Scope, ObjectPointer));
105990432893SKristina Bessonova
106081378f7eSKristina Bessonova // Emit imported entities (skipped in gmlt-like data).
106181378f7eSKristina Bessonova if (!includeMinimalInlineScopes()) {
106281378f7eSKristina Bessonova for (const auto *IE : ImportedEntities[Scope->getScopeNode()])
106381378f7eSKristina Bessonova ScopeDIE.addChild(constructImportedEntityDIE(cast<DIImportedEntity>(IE)));
106481378f7eSKristina Bessonova }
106581378f7eSKristina Bessonova
106690432893SKristina Bessonova // Emit labels.
106790432893SKristina Bessonova for (DbgLabel *DL : DU->getScopeLabels().lookup(Scope))
106890432893SKristina Bessonova ScopeDIE.addChild(constructLabelDIE(*DL, *Scope));
106990432893SKristina Bessonova
107090432893SKristina Bessonova // Emit inner lexical scopes.
107181378f7eSKristina Bessonova auto needToEmitLexicalScope = [this](LexicalScope *LS) {
107290432893SKristina Bessonova if (isa<DISubprogram>(LS->getScopeNode()))
107390432893SKristina Bessonova return true;
107490432893SKristina Bessonova auto Vars = DU->getScopeVariables().lookup(LS);
107590432893SKristina Bessonova if (!Vars.Args.empty() || !Vars.Locals.empty())
107690432893SKristina Bessonova return true;
107781378f7eSKristina Bessonova if (!includeMinimalInlineScopes() &&
107881378f7eSKristina Bessonova !ImportedEntities[LS->getScopeNode()].empty())
107981378f7eSKristina Bessonova return true;
108081378f7eSKristina Bessonova return false;
108190432893SKristina Bessonova };
108290432893SKristina Bessonova for (LexicalScope *LS : Scope->getChildren()) {
108390432893SKristina Bessonova // If the lexical block doesn't have non-scope children, skip
108490432893SKristina Bessonova // its emission and put its children directly to the parent scope.
108590432893SKristina Bessonova if (needToEmitLexicalScope(LS))
108690432893SKristina Bessonova constructScopeDIE(LS, ScopeDIE);
108790432893SKristina Bessonova else
108890432893SKristina Bessonova createAndAddScopeChildren(LS, ScopeDIE);
108990432893SKristina Bessonova }
109078b65b6fSDavid Blaikie
109178b65b6fSDavid Blaikie return ObjectPointer;
109278b65b6fSDavid Blaikie }
109378b65b6fSDavid Blaikie
constructAbstractSubprogramScopeDIE(LexicalScope * Scope)109454511353SDehao Chen void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(
109554511353SDehao Chen LexicalScope *Scope) {
109681378f7eSKristina Bessonova DIE *&AbsDef = getAbstractSPDies()[Scope->getScopeNode()];
109781378f7eSKristina Bessonova if (AbsDef)
109881378f7eSKristina Bessonova return;
109949be5b35SDavid Blaikie
1100a9308c49SDuncan P. N. Exon Smith auto *SP = cast<DISubprogram>(Scope->getScopeNode());
110158410f24SDavid Blaikie
110258410f24SDavid Blaikie DIE *ContextDIE;
1103294e6895SJonas Devlieghere DwarfCompileUnit *ContextCU = this;
110458410f24SDavid Blaikie
11053a443c29SDavid Blaikie if (includeMinimalInlineScopes())
11063a443c29SDavid Blaikie ContextDIE = &getUnitDie();
110758410f24SDavid Blaikie // Some of this is duplicated from DwarfUnit::getOrCreateSubprogramDIE, with
11087c60f20eSDuncan P. N. Exon Smith // the important distinction that the debug node is not associated with the
11097c60f20eSDuncan P. N. Exon Smith // DIE (since the debug node will be associated with the concrete DIE, if
111058410f24SDavid Blaikie // any). It could be refactored to some common utility function.
1111537b4a81SDuncan P. N. Exon Smith else if (auto *SPDecl = SP->getDeclaration()) {
111258410f24SDavid Blaikie ContextDIE = &getUnitDie();
111358410f24SDavid Blaikie getOrCreateSubprogramDIE(SPDecl);
1114294e6895SJonas Devlieghere } else {
1115da82ce99SFangrui Song ContextDIE = getOrCreateContextDIE(SP->getScope());
1116294e6895SJonas Devlieghere // The scope may be shared with a subprogram that has already been
1117294e6895SJonas Devlieghere // constructed in another CU, in which case we need to construct this
1118294e6895SJonas Devlieghere // subprogram in the same CU.
1119294e6895SJonas Devlieghere ContextCU = DD->lookupCU(ContextDIE->getUnitDie());
1120294e6895SJonas Devlieghere }
112158410f24SDavid Blaikie
1122f0d997c4SAdrian Kuegel // Passing null as the associated node because the abstract definition
1123f0d997c4SAdrian Kuegel // shouldn't be found by lookup.
112481378f7eSKristina Bessonova AbsDef = &ContextCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, nullptr);
112581378f7eSKristina Bessonova ContextCU->applySubprogramAttributesToDefinition(SP, *AbsDef);
112681378f7eSKristina Bessonova ContextCU->addSInt(*AbsDef, dwarf::DW_AT_inline,
112712f80c0bSZequan Wu DD->getDwarfVersion() <= 4 ? Optional<dwarf::Form>()
112812f80c0bSZequan Wu : dwarf::DW_FORM_implicit_const,
112912f80c0bSZequan Wu dwarf::DW_INL_inlined);
113081378f7eSKristina Bessonova if (DIE *ObjectPointer = ContextCU->createAndAddScopeChildren(Scope, *AbsDef))
113181378f7eSKristina Bessonova ContextCU->addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
113258410f24SDavid Blaikie }
113358410f24SDavid Blaikie
useGNUAnalogForDwarf5Feature() const1134f7052da6SVedant Kumar bool DwarfCompileUnit::useGNUAnalogForDwarf5Feature() const {
11356371a0a0SDjordje Todorovic return DD->getDwarfVersion() == 4 && !DD->tuneForLLDB();
1136533dd021SVedant Kumar }
1137533dd021SVedant Kumar
getDwarf5OrGNUTag(dwarf::Tag Tag) const113858a07148SVedant Kumar dwarf::Tag DwarfCompileUnit::getDwarf5OrGNUTag(dwarf::Tag Tag) const {
1139f7052da6SVedant Kumar if (!useGNUAnalogForDwarf5Feature())
1140b9973f87SDjordje Todorovic return Tag;
1141b9973f87SDjordje Todorovic switch (Tag) {
1142b9973f87SDjordje Todorovic case dwarf::DW_TAG_call_site:
1143b9973f87SDjordje Todorovic return dwarf::DW_TAG_GNU_call_site;
1144b9973f87SDjordje Todorovic case dwarf::DW_TAG_call_site_parameter:
1145b9973f87SDjordje Todorovic return dwarf::DW_TAG_GNU_call_site_parameter;
1146b9973f87SDjordje Todorovic default:
114758a07148SVedant Kumar llvm_unreachable("DWARF5 tag with no GNU analog");
1148b9973f87SDjordje Todorovic }
1149b9973f87SDjordje Todorovic }
1150b9973f87SDjordje Todorovic
1151b9973f87SDjordje Todorovic dwarf::Attribute
getDwarf5OrGNUAttr(dwarf::Attribute Attr) const115258a07148SVedant Kumar DwarfCompileUnit::getDwarf5OrGNUAttr(dwarf::Attribute Attr) const {
1153f7052da6SVedant Kumar if (!useGNUAnalogForDwarf5Feature())
1154b9973f87SDjordje Todorovic return Attr;
1155b9973f87SDjordje Todorovic switch (Attr) {
1156b9973f87SDjordje Todorovic case dwarf::DW_AT_call_all_calls:
1157b9973f87SDjordje Todorovic return dwarf::DW_AT_GNU_all_call_sites;
1158b9973f87SDjordje Todorovic case dwarf::DW_AT_call_target:
1159b9973f87SDjordje Todorovic return dwarf::DW_AT_GNU_call_site_target;
1160b9973f87SDjordje Todorovic case dwarf::DW_AT_call_origin:
1161b9973f87SDjordje Todorovic return dwarf::DW_AT_abstract_origin;
116243464509SVedant Kumar case dwarf::DW_AT_call_return_pc:
1163b9973f87SDjordje Todorovic return dwarf::DW_AT_low_pc;
1164b9973f87SDjordje Todorovic case dwarf::DW_AT_call_value:
1165b9973f87SDjordje Todorovic return dwarf::DW_AT_GNU_call_site_value;
1166b9973f87SDjordje Todorovic case dwarf::DW_AT_call_tail_call:
1167b9973f87SDjordje Todorovic return dwarf::DW_AT_GNU_tail_call;
1168b9973f87SDjordje Todorovic default:
116958a07148SVedant Kumar llvm_unreachable("DWARF5 attribute with no GNU analog");
1170b9973f87SDjordje Todorovic }
1171b9973f87SDjordje Todorovic }
1172b9973f87SDjordje Todorovic
1173533dd021SVedant Kumar dwarf::LocationAtom
getDwarf5OrGNULocationAtom(dwarf::LocationAtom Loc) const1174533dd021SVedant Kumar DwarfCompileUnit::getDwarf5OrGNULocationAtom(dwarf::LocationAtom Loc) const {
1175f7052da6SVedant Kumar if (!useGNUAnalogForDwarf5Feature())
1176533dd021SVedant Kumar return Loc;
1177533dd021SVedant Kumar switch (Loc) {
1178533dd021SVedant Kumar case dwarf::DW_OP_entry_value:
1179533dd021SVedant Kumar return dwarf::DW_OP_GNU_entry_value;
1180533dd021SVedant Kumar default:
1181533dd021SVedant Kumar llvm_unreachable("DWARF5 location atom with no GNU analog");
1182533dd021SVedant Kumar }
1183533dd021SVedant Kumar }
1184533dd021SVedant Kumar
constructCallSiteEntryDIE(DIE & ScopeDIE,const DISubprogram * CalleeSP,bool IsTail,const MCSymbol * PCAddr,const MCSymbol * CallAddr,unsigned CallReg)1185f0120556SVedant Kumar DIE &DwarfCompileUnit::constructCallSiteEntryDIE(DIE &ScopeDIE,
1186d4ce9e46SJeremy Morse const DISubprogram *CalleeSP,
1187f0120556SVedant Kumar bool IsTail,
1188f0120556SVedant Kumar const MCSymbol *PCAddr,
1189f7052da6SVedant Kumar const MCSymbol *CallAddr,
1190f0120556SVedant Kumar unsigned CallReg) {
11915931b4e5SVedant Kumar // Insert a call site entry DIE within ScopeDIE.
119258a07148SVedant Kumar DIE &CallSiteDIE = createAndAddDIE(getDwarf5OrGNUTag(dwarf::DW_TAG_call_site),
119358a07148SVedant Kumar ScopeDIE, nullptr);
11945931b4e5SVedant Kumar
1195b9973f87SDjordje Todorovic if (CallReg) {
1196b9973f87SDjordje Todorovic // Indirect call.
119758a07148SVedant Kumar addAddress(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_target),
1198b9973f87SDjordje Todorovic MachineLocation(CallReg));
11990739ccd3SDjordje Todorovic } else {
1200d4ce9e46SJeremy Morse DIE *CalleeDIE = getOrCreateSubprogramDIE(CalleeSP);
1201d4ce9e46SJeremy Morse assert(CalleeDIE && "Could not create DIE for call site entry origin");
120258a07148SVedant Kumar addDIEEntry(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_origin),
1203b9973f87SDjordje Todorovic *CalleeDIE);
1204b9973f87SDjordje Todorovic }
1205b9973f87SDjordje Todorovic
1206f7052da6SVedant Kumar if (IsTail) {
1207b9973f87SDjordje Todorovic // Attach DW_AT_call_tail_call to tail calls for standards compliance.
120858a07148SVedant Kumar addFlag(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_tail_call));
1209b9973f87SDjordje Todorovic
1210f7052da6SVedant Kumar // Attach the address of the branch instruction to allow the debugger to
1211f7052da6SVedant Kumar // show where the tail call occurred. This attribute has no GNU analog.
1212f7052da6SVedant Kumar //
1213f7052da6SVedant Kumar // GDB works backwards from non-standard usage of DW_AT_low_pc (in DWARF4
1214f7052da6SVedant Kumar // mode -- equivalently, in DWARF5 mode, DW_AT_call_return_pc) at tail-call
1215f7052da6SVedant Kumar // site entries to figure out the PC of tail-calling branch instructions.
1216f7052da6SVedant Kumar // This means it doesn't need the compiler to emit DW_AT_call_pc, so we
1217f7052da6SVedant Kumar // don't emit it here.
1218f7052da6SVedant Kumar //
1219f7052da6SVedant Kumar // There's no need to tie non-GDB debuggers to this non-standardness, as it
1220f7052da6SVedant Kumar // adds unnecessary complexity to the debugger. For non-GDB debuggers, emit
1221f7052da6SVedant Kumar // the standard DW_AT_call_pc info.
1222f7052da6SVedant Kumar if (!useGNUAnalogForDwarf5Feature())
1223f7052da6SVedant Kumar addLabelAddress(CallSiteDIE, dwarf::DW_AT_call_pc, CallAddr);
1224f7052da6SVedant Kumar }
1225f7052da6SVedant Kumar
12265931b4e5SVedant Kumar // Attach the return PC to allow the debugger to disambiguate call paths
12275931b4e5SVedant Kumar // from one function to another.
122843464509SVedant Kumar //
122943464509SVedant Kumar // The return PC is only really needed when the call /isn't/ a tail call, but
1230f7052da6SVedant Kumar // GDB expects it in DWARF4 mode, even for tail calls (see the comment above
1231f7052da6SVedant Kumar // the DW_AT_call_pc emission logic for an explanation).
1232f7052da6SVedant Kumar if (!IsTail || useGNUAnalogForDwarf5Feature()) {
1233f0120556SVedant Kumar assert(PCAddr && "Missing return PC information for a call");
123443464509SVedant Kumar addLabelAddress(CallSiteDIE,
123543464509SVedant Kumar getDwarf5OrGNUAttr(dwarf::DW_AT_call_return_pc), PCAddr);
12365931b4e5SVedant Kumar }
1237b9973f87SDjordje Todorovic
12385931b4e5SVedant Kumar return CallSiteDIE;
12395931b4e5SVedant Kumar }
12405931b4e5SVedant Kumar
constructCallSiteParmEntryDIEs(DIE & CallSiteDIE,SmallVector<DbgCallSiteParam,4> & Params)1241b9973f87SDjordje Todorovic void DwarfCompileUnit::constructCallSiteParmEntryDIEs(
1242b9973f87SDjordje Todorovic DIE &CallSiteDIE, SmallVector<DbgCallSiteParam, 4> &Params) {
1243b9973f87SDjordje Todorovic for (const auto &Param : Params) {
1244b9973f87SDjordje Todorovic unsigned Register = Param.getRegister();
1245b9973f87SDjordje Todorovic auto CallSiteDieParam =
1246b9973f87SDjordje Todorovic DIE::get(DIEValueAllocator,
124758a07148SVedant Kumar getDwarf5OrGNUTag(dwarf::DW_TAG_call_site_parameter));
1248b9973f87SDjordje Todorovic insertDIE(CallSiteDieParam);
1249b9973f87SDjordje Todorovic addAddress(*CallSiteDieParam, dwarf::DW_AT_location,
1250b9973f87SDjordje Todorovic MachineLocation(Register));
1251b9973f87SDjordje Todorovic
1252b9973f87SDjordje Todorovic DIELoc *Loc = new (DIEValueAllocator) DIELoc;
1253b9973f87SDjordje Todorovic DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
1254b9973f87SDjordje Todorovic DwarfExpr.setCallSiteParamValueFlag();
1255b9973f87SDjordje Todorovic
1256b9973f87SDjordje Todorovic DwarfDebug::emitDebugLocValue(*Asm, nullptr, Param.getValue(), DwarfExpr);
1257b9973f87SDjordje Todorovic
125858a07148SVedant Kumar addBlock(*CallSiteDieParam, getDwarf5OrGNUAttr(dwarf::DW_AT_call_value),
1259b9973f87SDjordje Todorovic DwarfExpr.finalize());
1260b9973f87SDjordje Todorovic
1261b9973f87SDjordje Todorovic CallSiteDIE.addChild(CallSiteDieParam);
1262b9973f87SDjordje Todorovic }
1263b9973f87SDjordje Todorovic }
1264b9973f87SDjordje Todorovic
constructImportedEntityDIE(const DIImportedEntity * Module)126581378f7eSKristina Bessonova DIE *DwarfCompileUnit::constructImportedEntityDIE(
126681378f7eSKristina Bessonova const DIImportedEntity *Module) {
126781378f7eSKristina Bessonova DIE *IMDie = DIE::get(DIEValueAllocator, (dwarf::Tag)Module->getTag());
126881378f7eSKristina Bessonova insertDIE(Module, IMDie);
1269987fe227SFrederic Riss DIE *EntityDie;
127081378f7eSKristina Bessonova auto *Entity = Module->getEntity();
1271a9308c49SDuncan P. N. Exon Smith if (auto *NS = dyn_cast<DINamespace>(Entity))
1272e686f159SDuncan P. N. Exon Smith EntityDie = getOrCreateNameSpace(NS);
127308a388baSAdrian Prantl else if (auto *M = dyn_cast<DIModule>(Entity))
127408a388baSAdrian Prantl EntityDie = getOrCreateModule(M);
127581378f7eSKristina Bessonova else if (auto *SP = dyn_cast<DISubprogram>(Entity))
1276e686f159SDuncan P. N. Exon Smith EntityDie = getOrCreateSubprogramDIE(SP);
127781378f7eSKristina Bessonova else if (auto *T = dyn_cast<DIType>(Entity))
1278e686f159SDuncan P. N. Exon Smith EntityDie = getOrCreateTypeDIE(T);
1279a9308c49SDuncan P. N. Exon Smith else if (auto *GV = dyn_cast<DIGlobalVariable>(Entity))
1280bceaaa96SAdrian Prantl EntityDie = getOrCreateGlobalVariableDIE(GV, {});
1281987fe227SFrederic Riss else
1282987fe227SFrederic Riss EntityDie = getDIE(Entity);
1283987fe227SFrederic Riss assert(EntityDie);
128481378f7eSKristina Bessonova addSourceLine(*IMDie, Module->getLine(), Module->getFile());
1285987fe227SFrederic Riss addDIEEntry(*IMDie, dwarf::DW_AT_import, *EntityDie);
128681378f7eSKristina Bessonova StringRef Name = Module->getName();
1287987fe227SFrederic Riss if (!Name.empty())
1288987fe227SFrederic Riss addString(*IMDie, dwarf::DW_AT_name, Name);
1289987fe227SFrederic Riss
1290a5b72abcSAlok Kumar Sharma // This is for imported module with renamed entities (such as variables and
1291a5b72abcSAlok Kumar Sharma // subprograms).
129281378f7eSKristina Bessonova DINodeArray Elements = Module->getElements();
1293a5b72abcSAlok Kumar Sharma for (const auto *Element : Elements) {
1294a5b72abcSAlok Kumar Sharma if (!Element)
1295a5b72abcSAlok Kumar Sharma continue;
129681378f7eSKristina Bessonova IMDie->addChild(
129781378f7eSKristina Bessonova constructImportedEntityDIE(cast<DIImportedEntity>(Element)));
1298f9607d45SMuhammad Omair Javaid }
129981378f7eSKristina Bessonova
1300f9607d45SMuhammad Omair Javaid return IMDie;
130175b622a7SKristina Bessonova }
130262a6b9e9SDavid Blaikie
finishSubprogramDefinition(const DISubprogram * SP)1303a9308c49SDuncan P. N. Exon Smith void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP) {
130472da9391SAmjad Aboud DIE *D = getDIE(SP);
130581378f7eSKristina Bessonova if (DIE *AbsSPDIE = getAbstractSPDies().lookup(SP)) {
1306f0d997c4SAdrian Kuegel if (D)
13074191cbceSDavid Blaikie // If this subprogram has an abstract definition, reference that
13084191cbceSDavid Blaikie addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE);
130972da9391SAmjad Aboud } else {
13103e3eb33eSDavid Blaikie assert(D || includeMinimalInlineScopes());
131172da9391SAmjad Aboud if (D)
13124191cbceSDavid Blaikie // And attach the attributes
13134191cbceSDavid Blaikie applySubprogramAttributesToDefinition(SP, *D);
13144191cbceSDavid Blaikie }
13154191cbceSDavid Blaikie }
13164191cbceSDavid Blaikie
finishEntityDefinition(const DbgEntity * Entity)13172532ac88SHsiangkai Wang void DwarfCompileUnit::finishEntityDefinition(const DbgEntity *Entity) {
13182532ac88SHsiangkai Wang DbgEntity *AbsEntity = getExistingAbstractEntity(Entity->getEntity());
13192532ac88SHsiangkai Wang
13202532ac88SHsiangkai Wang auto *Die = Entity->getDIE();
13212532ac88SHsiangkai Wang /// Label may be used to generate DW_AT_low_pc, so put it outside
13222532ac88SHsiangkai Wang /// if/else block.
13232532ac88SHsiangkai Wang const DbgLabel *Label = nullptr;
13242532ac88SHsiangkai Wang if (AbsEntity && AbsEntity->getDIE()) {
13252532ac88SHsiangkai Wang addDIEEntry(*Die, dwarf::DW_AT_abstract_origin, *AbsEntity->getDIE());
13262532ac88SHsiangkai Wang Label = dyn_cast<const DbgLabel>(Entity);
13272532ac88SHsiangkai Wang } else {
13282532ac88SHsiangkai Wang if (const DbgVariable *Var = dyn_cast<const DbgVariable>(Entity))
13292532ac88SHsiangkai Wang applyVariableAttributes(*Var, *Die);
13302532ac88SHsiangkai Wang else if ((Label = dyn_cast<const DbgLabel>(Entity)))
13312532ac88SHsiangkai Wang applyLabelAttributes(*Label, *Die);
13322532ac88SHsiangkai Wang else
13332532ac88SHsiangkai Wang llvm_unreachable("DbgEntity must be DbgVariable or DbgLabel.");
1334488393f8SDavid Blaikie }
1335488393f8SDavid Blaikie
133655321d82SHsiangkai Wang if (Label)
133755321d82SHsiangkai Wang if (const auto *Sym = Label->getSymbol())
13382532ac88SHsiangkai Wang addLabelAddress(*Die, dwarf::DW_AT_low_pc, Sym);
13392532ac88SHsiangkai Wang }
1340488393f8SDavid Blaikie
getExistingAbstractEntity(const DINode * Node)13412532ac88SHsiangkai Wang DbgEntity *DwarfCompileUnit::getExistingAbstractEntity(const DINode *Node) {
13422532ac88SHsiangkai Wang auto &AbstractEntities = getAbstractEntities();
13432532ac88SHsiangkai Wang auto I = AbstractEntities.find(Node);
13442532ac88SHsiangkai Wang if (I != AbstractEntities.end())
1345488393f8SDavid Blaikie return I->second.get();
1346488393f8SDavid Blaikie return nullptr;
1347488393f8SDavid Blaikie }
1348488393f8SDavid Blaikie
createAbstractEntity(const DINode * Node,LexicalScope * Scope)13492532ac88SHsiangkai Wang void DwarfCompileUnit::createAbstractEntity(const DINode *Node,
1350488393f8SDavid Blaikie LexicalScope *Scope) {
1351488393f8SDavid Blaikie assert(Scope && Scope->isAbstractScope());
13522532ac88SHsiangkai Wang auto &Entity = getAbstractEntities()[Node];
13532532ac88SHsiangkai Wang if (isa<const DILocalVariable>(Node)) {
13540eaee545SJonas Devlieghere Entity = std::make_unique<DbgVariable>(
13552532ac88SHsiangkai Wang cast<const DILocalVariable>(Node), nullptr /* IA */);;
13562532ac88SHsiangkai Wang DU->addScopeVariable(Scope, cast<DbgVariable>(Entity.get()));
13572532ac88SHsiangkai Wang } else if (isa<const DILabel>(Node)) {
13580eaee545SJonas Devlieghere Entity = std::make_unique<DbgLabel>(
13592532ac88SHsiangkai Wang cast<const DILabel>(Node), nullptr /* IA */);
13602532ac88SHsiangkai Wang DU->addScopeLabel(Scope, cast<DbgLabel>(Entity.get()));
13612532ac88SHsiangkai Wang }
1362488393f8SDavid Blaikie }
1363488393f8SDavid Blaikie
emitHeader(bool UseOffsets)1364063d725fSRafael Espindola void DwarfCompileUnit::emitHeader(bool UseOffsets) {
1365b6726a9eSDavid Blaikie // Don't bother labeling the .dwo unit, as its offset isn't used.
1366bff36086SAlexey Bataev if (!Skeleton && !DD->useSectionsAsReferences()) {
13679ab09237SRafael Espindola LabelBegin = Asm->createTempSymbol("cu_begin");
13686d2d589bSFangrui Song Asm->OutStreamer->emitLabel(LabelBegin);
13693c311148SRafael Espindola }
1370ae57e66eSDavid Blaikie
1371cddd6044SPaul Robinson dwarf::UnitType UT = Skeleton ? dwarf::DW_UT_split_compile
1372cddd6044SPaul Robinson : DD->useSplitDwarf() ? dwarf::DW_UT_skeleton
1373cddd6044SPaul Robinson : dwarf::DW_UT_compile;
1374cddd6044SPaul Robinson DwarfUnit::emitCommonHeader(UseOffsets, UT);
1375543c0e1dSPaul Robinson if (DD->getDwarfVersion() >= 5 && UT != dwarf::DW_UT_compile)
1376543c0e1dSPaul Robinson Asm->emitInt64(getDWOId());
1377ae57e66eSDavid Blaikie }
1378ae57e66eSDavid Blaikie
hasDwarfPubSections() const1379b52e2366SPeter Collingbourne bool DwarfCompileUnit::hasDwarfPubSections() const {
138066cf14d0SDavid Blaikie switch (CUNode->getNameTableKind()) {
138166cf14d0SDavid Blaikie case DICompileUnit::DebugNameTableKind::None:
138266cf14d0SDavid Blaikie return false;
1383b52e2366SPeter Collingbourne // Opting in to GNU Pubnames/types overrides the default to ensure these are
1384b52e2366SPeter Collingbourne // generated for things like Gold's gdb_index generation.
138566cf14d0SDavid Blaikie case DICompileUnit::DebugNameTableKind::GNU:
1386b52e2366SPeter Collingbourne return true;
138766cf14d0SDavid Blaikie case DICompileUnit::DebugNameTableKind::Default:
13880e03047eSDavid Blaikie return DD->tuneForGDB() && !includeMinimalInlineScopes() &&
13892f511762SDavid Blaikie !CUNode->isDebugDirectivesOnly() &&
13902f511762SDavid Blaikie DD->getAccelTableKind() != AccelTableKind::Apple &&
13912f511762SDavid Blaikie DD->getDwarfVersion() < 5;
1392b52e2366SPeter Collingbourne }
139322d580f2SSimon Pilgrim llvm_unreachable("Unhandled DICompileUnit::DebugNameTableKind enum");
139466cf14d0SDavid Blaikie }
1395b52e2366SPeter Collingbourne
1396192b45c1SDavid Blaikie /// addGlobalName - Add a new global name to the compile unit.
addGlobalName(StringRef Name,const DIE & Die,const DIScope * Context)1397a0e3c751SDavid Blaikie void DwarfCompileUnit::addGlobalName(StringRef Name, const DIE &Die,
1398a9308c49SDuncan P. N. Exon Smith const DIScope *Context) {
1399b52e2366SPeter Collingbourne if (!hasDwarfPubSections())
1400192b45c1SDavid Blaikie return;
1401192b45c1SDavid Blaikie std::string FullName = getParentContextString(Context) + Name.str();
1402192b45c1SDavid Blaikie GlobalNames[FullName] = &Die;
1403192b45c1SDavid Blaikie }
1404192b45c1SDavid Blaikie
addGlobalNameForTypeUnit(StringRef Name,const DIScope * Context)1405a0e3c751SDavid Blaikie void DwarfCompileUnit::addGlobalNameForTypeUnit(StringRef Name,
1406a0e3c751SDavid Blaikie const DIScope *Context) {
1407b52e2366SPeter Collingbourne if (!hasDwarfPubSections())
1408a0e3c751SDavid Blaikie return;
1409a0e3c751SDavid Blaikie std::string FullName = getParentContextString(Context) + Name.str();
1410a0e3c751SDavid Blaikie // Insert, allowing the entry to remain as-is if it's already present
1411a0e3c751SDavid Blaikie // This way the CU-level type DIE is preferred over the "can't describe this
1412a0e3c751SDavid Blaikie // type as a unit offset because it's not really in the CU at all, it's only
1413a0e3c751SDavid Blaikie // in a type unit"
1414a0e3c751SDavid Blaikie GlobalNames.insert(std::make_pair(std::move(FullName), &getUnitDie()));
1415a0e3c751SDavid Blaikie }
1416a0e3c751SDavid Blaikie
1417192b45c1SDavid Blaikie /// Add a new global type to the unit.
addGlobalType(const DIType * Ty,const DIE & Die,const DIScope * Context)1418a9308c49SDuncan P. N. Exon Smith void DwarfCompileUnit::addGlobalType(const DIType *Ty, const DIE &Die,
1419a9308c49SDuncan P. N. Exon Smith const DIScope *Context) {
1420b52e2366SPeter Collingbourne if (!hasDwarfPubSections())
1421192b45c1SDavid Blaikie return;
1422b1055640SDuncan P. N. Exon Smith std::string FullName = getParentContextString(Context) + Ty->getName().str();
1423192b45c1SDavid Blaikie GlobalTypes[FullName] = &Die;
1424192b45c1SDavid Blaikie }
1425ae57e66eSDavid Blaikie
addGlobalTypeUnitType(const DIType * Ty,const DIScope * Context)1426a0e3c751SDavid Blaikie void DwarfCompileUnit::addGlobalTypeUnitType(const DIType *Ty,
1427a0e3c751SDavid Blaikie const DIScope *Context) {
1428b52e2366SPeter Collingbourne if (!hasDwarfPubSections())
1429a0e3c751SDavid Blaikie return;
1430a0e3c751SDavid Blaikie std::string FullName = getParentContextString(Context) + Ty->getName().str();
1431a0e3c751SDavid Blaikie // Insert, allowing the entry to remain as-is if it's already present
1432a0e3c751SDavid Blaikie // This way the CU-level type DIE is preferred over the "can't describe this
1433a0e3c751SDavid Blaikie // type as a unit offset because it's not really in the CU at all, it's only
1434a0e3c751SDavid Blaikie // in a type unit"
1435a0e3c751SDavid Blaikie GlobalTypes.insert(std::make_pair(std::move(FullName), &getUnitDie()));
1436a0e3c751SDavid Blaikie }
1437a0e3c751SDavid Blaikie
addVariableAddress(const DbgVariable & DV,DIE & Die,MachineLocation Location)14387d48be2bSDavid Blaikie void DwarfCompileUnit::addVariableAddress(const DbgVariable &DV, DIE &Die,
14397d48be2bSDavid Blaikie MachineLocation Location) {
1440e6cc531bSDuncan P. N. Exon Smith if (DV.hasComplexAddress())
14417d48be2bSDavid Blaikie addComplexAddress(DV, Die, dwarf::DW_AT_location, Location);
14427d48be2bSDavid Blaikie else
14435883af3fSAdrian Prantl addAddress(Die, dwarf::DW_AT_location, Location);
14447d48be2bSDavid Blaikie }
1445f7435ee6SDavid Blaikie
1446f7435ee6SDavid Blaikie /// Add an address attribute to a die based on the location provided.
addAddress(DIE & Die,dwarf::Attribute Attribute,const MachineLocation & Location)1447f7435ee6SDavid Blaikie void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute,
14485883af3fSAdrian Prantl const MachineLocation &Location) {
1449e7e1d0c7SDuncan P. N. Exon Smith DIELoc *Loc = new (DIEValueAllocator) DIELoc;
1450956484b7SAdrian Prantl DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
1451c12cee36SAdrian Prantl if (Location.isIndirect())
1452c12cee36SAdrian Prantl DwarfExpr.setMemoryLocationKind();
1453f7435ee6SDavid Blaikie
14542049c0d7SAdrian Prantl DIExpressionCursor Cursor({});
1455956484b7SAdrian Prantl const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
1456c12cee36SAdrian Prantl if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
1457ab255fcdSAdrian Prantl return;
1458956484b7SAdrian Prantl DwarfExpr.addExpression(std::move(Cursor));
1459ab255fcdSAdrian Prantl
1460f7435ee6SDavid Blaikie // Now attach the location information to the DIE.
1461956484b7SAdrian Prantl addBlock(Die, Attribute, DwarfExpr.finalize());
1462dabd2622SEvgenii Stepanov
1463dabd2622SEvgenii Stepanov if (DwarfExpr.TagOffset)
1464dabd2622SEvgenii Stepanov addUInt(Die, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
1465dabd2622SEvgenii Stepanov *DwarfExpr.TagOffset);
1466f7435ee6SDavid Blaikie }
146777895fb2SDavid Blaikie
146877895fb2SDavid Blaikie /// Start with the address based on the location provided, and generate the
146977895fb2SDavid Blaikie /// DWARF information necessary to find the actual variable given the extra
147077895fb2SDavid Blaikie /// address information encoded in the DbgVariable, starting from the starting
147177895fb2SDavid Blaikie /// location. Add the DWARF information to the die.
addComplexAddress(const DbgVariable & DV,DIE & Die,dwarf::Attribute Attribute,const MachineLocation & Location)147277895fb2SDavid Blaikie void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die,
147377895fb2SDavid Blaikie dwarf::Attribute Attribute,
147477895fb2SDavid Blaikie const MachineLocation &Location) {
1475e7e1d0c7SDuncan P. N. Exon Smith DIELoc *Loc = new (DIEValueAllocator) DIELoc;
14767813d9c9SAdrian Prantl DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
1477956484b7SAdrian Prantl const DIExpression *DIExpr = DV.getSingleExpression();
1478956484b7SAdrian Prantl DwarfExpr.addFragmentOffset(DIExpr);
14796e39379bSVedant Kumar DwarfExpr.setLocation(Location, DIExpr);
1480956484b7SAdrian Prantl
14812049c0d7SAdrian Prantl DIExpressionCursor Cursor(DIExpr);
148212aca5deSDjordje Todorovic
14836e39379bSVedant Kumar if (DIExpr->isEntryValue())
14841ae2d9a2SDavid Stenberg DwarfExpr.beginEntryValueExpression(Cursor);
148512aca5deSDjordje Todorovic
148696c9ae6aSPeter Collingbourne const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
1487c12cee36SAdrian Prantl if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
148854286bdaSAdrian Prantl return;
1489956484b7SAdrian Prantl DwarfExpr.addExpression(std::move(Cursor));
149077895fb2SDavid Blaikie
149177895fb2SDavid Blaikie // Now attach the location information to the DIE.
1492956484b7SAdrian Prantl addBlock(Die, Attribute, DwarfExpr.finalize());
1493dabd2622SEvgenii Stepanov
1494dabd2622SEvgenii Stepanov if (DwarfExpr.TagOffset)
1495dabd2622SEvgenii Stepanov addUInt(Die, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
1496dabd2622SEvgenii Stepanov *DwarfExpr.TagOffset);
149777895fb2SDavid Blaikie }
14984bc0881aSDavid Blaikie
14994bc0881aSDavid Blaikie /// Add a Dwarf loclistptr attribute data and value.
addLocationList(DIE & Die,dwarf::Attribute Attribute,unsigned Index)15004bc0881aSDavid Blaikie void DwarfCompileUnit::addLocationList(DIE &Die, dwarf::Attribute Attribute,
15014bc0881aSDavid Blaikie unsigned Index) {
150226f1f188SIgor Kudrin dwarf::Form Form = (DD->getDwarfVersion() >= 5)
150326f1f188SIgor Kudrin ? dwarf::DW_FORM_loclistx
150426f1f188SIgor Kudrin : DD->getDwarfSectionOffsetForm();
15059deb7eeaSChen Zheng addAttribute(Die, Attribute, Form, DIELocList(Index));
15064bc0881aSDavid Blaikie }
150702a6333bSDavid Blaikie
applyVariableAttributes(const DbgVariable & Var,DIE & VariableDie)15088c485b5dSDavid Blaikie void DwarfCompileUnit::applyVariableAttributes(const DbgVariable &Var,
150902a6333bSDavid Blaikie DIE &VariableDie) {
151002a6333bSDavid Blaikie StringRef Name = Var.getName();
151102a6333bSDavid Blaikie if (!Name.empty())
151202a6333bSDavid Blaikie addString(VariableDie, dwarf::DW_AT_name, Name);
15133c989984SVictor Leschuk const auto *DIVar = Var.getVariable();
151489424a82SYonghong Song if (DIVar) {
15153c989984SVictor Leschuk if (uint32_t AlignInBytes = DIVar->getAlignInBytes())
15163c989984SVictor Leschuk addUInt(VariableDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
15173c989984SVictor Leschuk AlignInBytes);
151889424a82SYonghong Song addAnnotation(VariableDie, DIVar->getAnnotations());
151989424a82SYonghong Song }
15203c989984SVictor Leschuk
15213c989984SVictor Leschuk addSourceLine(VariableDie, DIVar);
152202a6333bSDavid Blaikie addType(VariableDie, Var.getType());
152302a6333bSDavid Blaikie if (Var.isArtificial())
152402a6333bSDavid Blaikie addFlag(VariableDie, dwarf::DW_AT_artificial);
152502a6333bSDavid Blaikie }
152697802080SDavid Blaikie
applyLabelAttributes(const DbgLabel & Label,DIE & LabelDie)15272532ac88SHsiangkai Wang void DwarfCompileUnit::applyLabelAttributes(const DbgLabel &Label,
15282532ac88SHsiangkai Wang DIE &LabelDie) {
15292532ac88SHsiangkai Wang StringRef Name = Label.getName();
15302532ac88SHsiangkai Wang if (!Name.empty())
15312532ac88SHsiangkai Wang addString(LabelDie, dwarf::DW_AT_name, Name);
15322532ac88SHsiangkai Wang const auto *DILabel = Label.getLabel();
15332532ac88SHsiangkai Wang addSourceLine(LabelDie, DILabel);
15342532ac88SHsiangkai Wang }
15352532ac88SHsiangkai Wang
153697802080SDavid Blaikie /// Add a Dwarf expression attribute data and value.
addExpr(DIELoc & Die,dwarf::Form Form,const MCExpr * Expr)153797802080SDavid Blaikie void DwarfCompileUnit::addExpr(DIELoc &Die, dwarf::Form Form,
153897802080SDavid Blaikie const MCExpr *Expr) {
15399deb7eeaSChen Zheng addAttribute(Die, (dwarf::Attribute)0, Form, DIEExpr(Expr));
154097802080SDavid Blaikie }
15413363a57cSDavid Blaikie
applySubprogramAttributesToDefinition(const DISubprogram * SP,DIE & SPDie)15422fbe1354SDuncan P. N. Exon Smith void DwarfCompileUnit::applySubprogramAttributesToDefinition(
1543a9308c49SDuncan P. N. Exon Smith const DISubprogram *SP, DIE &SPDie) {
1544537b4a81SDuncan P. N. Exon Smith auto *SPDecl = SP->getDeclaration();
1545da82ce99SFangrui Song auto *Context = SPDecl ? SPDecl->getScope() : SP->getScope();
15463a443c29SDavid Blaikie applySubprogramAttributes(SP, SPDie, includeMinimalInlineScopes());
1547537b4a81SDuncan P. N. Exon Smith addGlobalName(SP->getName(), SPDie, Context);
15483363a57cSDavid Blaikie }
1549cafd962dSDavid Blaikie
isDwoUnit() const1550cafd962dSDavid Blaikie bool DwarfCompileUnit::isDwoUnit() const {
1551cafd962dSDavid Blaikie return DD->useSplitDwarf() && Skeleton;
1552cafd962dSDavid Blaikie }
15533a443c29SDavid Blaikie
finishNonUnitTypeDIE(DIE & D,const DICompositeType * CTy)1554832c7d9fSDavid Blaikie void DwarfCompileUnit::finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) {
1555832c7d9fSDavid Blaikie constructTypeDIE(D, CTy);
1556832c7d9fSDavid Blaikie }
1557832c7d9fSDavid Blaikie
includeMinimalInlineScopes() const15583a443c29SDavid Blaikie bool DwarfCompileUnit::includeMinimalInlineScopes() const {
1559b939a257SAdrian Prantl return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly ||
15603a443c29SDavid Blaikie (DD->useSplitDwarf() && !Skeleton);
15613a443c29SDavid Blaikie }
156261c127c1SDavid Blaikie
addAddrTableBase()156361c127c1SDavid Blaikie void DwarfCompileUnit::addAddrTableBase() {
156461c127c1SDavid Blaikie const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
156561c127c1SDavid Blaikie MCSymbol *Label = DD->getAddressPool().getLabel();
156661c127c1SDavid Blaikie addSectionLabel(getUnitDie(),
15671eade73dSIgor Kudrin DD->getDwarfVersion() >= 5 ? dwarf::DW_AT_addr_base
156861c127c1SDavid Blaikie : dwarf::DW_AT_GNU_addr_base,
156961c127c1SDavid Blaikie Label, TLOF.getDwarfAddrSection()->getBeginSymbol());
157061c127c1SDavid Blaikie }
1571b86ce219SMarkus Lavin
addBaseTypeRef(DIEValueList & Die,int64_t Idx)1572b86ce219SMarkus Lavin void DwarfCompileUnit::addBaseTypeRef(DIEValueList &Die, int64_t Idx) {
15739deb7eeaSChen Zheng addAttribute(Die, (dwarf::Attribute)0, dwarf::DW_FORM_udata,
1574b86ce219SMarkus Lavin new (DIEValueAllocator) DIEBaseTypeRef(this, Idx));
1575b86ce219SMarkus Lavin }
1576b86ce219SMarkus Lavin
createBaseTypeDIEs()1577b86ce219SMarkus Lavin void DwarfCompileUnit::createBaseTypeDIEs() {
1578b86ce219SMarkus Lavin // Insert the base_type DIEs directly after the CU so that their offsets will
1579b86ce219SMarkus Lavin // fit in the fixed size ULEB128 used inside the location expressions.
1580b86ce219SMarkus Lavin // Maintain order by iterating backwards and inserting to the front of CU
1581b86ce219SMarkus Lavin // child list.
1582b86ce219SMarkus Lavin for (auto &Btr : reverse(ExprRefedBaseTypes)) {
1583b86ce219SMarkus Lavin DIE &Die = getUnitDie().addChildFront(
1584b86ce219SMarkus Lavin DIE::get(DIEValueAllocator, dwarf::DW_TAG_base_type));
1585b86ce219SMarkus Lavin SmallString<32> Str;
1586b86ce219SMarkus Lavin addString(Die, dwarf::DW_AT_name,
1587b86ce219SMarkus Lavin Twine(dwarf::AttributeEncodingString(Btr.Encoding) +
1588b86ce219SMarkus Lavin "_" + Twine(Btr.BitSize)).toStringRef(Str));
1589b86ce219SMarkus Lavin addUInt(Die, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Btr.Encoding);
1590b6a41fddSOCHyams // Round up to smallest number of bytes that contains this number of bits.
1591b6a41fddSOCHyams addUInt(Die, dwarf::DW_AT_byte_size, None, divideCeil(Btr.BitSize, 8));
1592b86ce219SMarkus Lavin
1593b86ce219SMarkus Lavin Btr.Die = &Die;
1594b86ce219SMarkus Lavin }
1595b86ce219SMarkus Lavin }
1596