12cab237bSDimitry Andric //===- llvm/CodeGen/DwarfDebug.cpp - Dwarf Debug Framework ----------------===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky // The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
10f22ef01cSRoman Divacky // This file contains support for writing dwarf debug info into asm files.
11f22ef01cSRoman Divacky //
12f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
13f22ef01cSRoman Divacky
14f22ef01cSRoman Divacky #include "DwarfDebug.h"
1539d628a0SDimitry Andric #include "ByteStreamer.h"
16f785676fSDimitry Andric #include "DIEHash.h"
17ff0cc061SDimitry Andric #include "DebugLocEntry.h"
182cab237bSDimitry Andric #include "DebugLocStream.h"
1939d628a0SDimitry Andric #include "DwarfCompileUnit.h"
2039d628a0SDimitry Andric #include "DwarfExpression.h"
212cab237bSDimitry Andric #include "DwarfFile.h"
2291bc56edSDimitry Andric #include "DwarfUnit.h"
232cab237bSDimitry Andric #include "llvm/ADT/APInt.h"
242cab237bSDimitry Andric #include "llvm/ADT/DenseMap.h"
252cab237bSDimitry Andric #include "llvm/ADT/DenseSet.h"
262cab237bSDimitry Andric #include "llvm/ADT/MapVector.h"
27139f7f9bSDimitry Andric #include "llvm/ADT/STLExtras.h"
282cab237bSDimitry Andric #include "llvm/ADT/SmallVector.h"
292cab237bSDimitry Andric #include "llvm/ADT/StringRef.h"
30139f7f9bSDimitry Andric #include "llvm/ADT/Triple.h"
312cab237bSDimitry Andric #include "llvm/ADT/Twine.h"
32db17bf38SDimitry Andric #include "llvm/BinaryFormat/Dwarf.h"
334ba319b5SDimitry Andric #include "llvm/CodeGen/AccelTable.h"
342cab237bSDimitry Andric #include "llvm/CodeGen/AsmPrinter.h"
3539d628a0SDimitry Andric #include "llvm/CodeGen/DIE.h"
362cab237bSDimitry Andric #include "llvm/CodeGen/LexicalScopes.h"
372cab237bSDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
38f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineFunction.h"
392cab237bSDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
40f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineModuleInfo.h"
412cab237bSDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
42*b5893f02SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
432cab237bSDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
442cab237bSDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
45139f7f9bSDimitry Andric #include "llvm/IR/Constants.h"
462cab237bSDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
472cab237bSDimitry Andric #include "llvm/IR/DebugLoc.h"
482cab237bSDimitry Andric #include "llvm/IR/Function.h"
492cab237bSDimitry Andric #include "llvm/IR/GlobalVariable.h"
50139f7f9bSDimitry Andric #include "llvm/IR/Module.h"
51f22ef01cSRoman Divacky #include "llvm/MC/MCAsmInfo.h"
522cab237bSDimitry Andric #include "llvm/MC/MCContext.h"
537d523365SDimitry Andric #include "llvm/MC/MCDwarf.h"
54f22ef01cSRoman Divacky #include "llvm/MC/MCSection.h"
55f22ef01cSRoman Divacky #include "llvm/MC/MCStreamer.h"
56f22ef01cSRoman Divacky #include "llvm/MC/MCSymbol.h"
572cab237bSDimitry Andric #include "llvm/MC/MCTargetOptions.h"
582cab237bSDimitry Andric #include "llvm/MC/MachineLocation.h"
592cab237bSDimitry Andric #include "llvm/MC/SectionKind.h"
602cab237bSDimitry Andric #include "llvm/Pass.h"
612cab237bSDimitry Andric #include "llvm/Support/Casting.h"
62f22ef01cSRoman Divacky #include "llvm/Support/CommandLine.h"
63f22ef01cSRoman Divacky #include "llvm/Support/Debug.h"
64f22ef01cSRoman Divacky #include "llvm/Support/ErrorHandling.h"
65f785676fSDimitry Andric #include "llvm/Support/MD5.h"
662cab237bSDimitry Andric #include "llvm/Support/MathExtras.h"
67139f7f9bSDimitry Andric #include "llvm/Support/Timer.h"
68ff0cc061SDimitry Andric #include "llvm/Support/raw_ostream.h"
694ba319b5SDimitry Andric #include "llvm/Target/TargetLoweringObjectFile.h"
70139f7f9bSDimitry Andric #include "llvm/Target/TargetMachine.h"
71139f7f9bSDimitry Andric #include "llvm/Target/TargetOptions.h"
722cab237bSDimitry Andric #include <algorithm>
732cab237bSDimitry Andric #include <cassert>
742cab237bSDimitry Andric #include <cstddef>
752cab237bSDimitry Andric #include <cstdint>
762cab237bSDimitry Andric #include <iterator>
772cab237bSDimitry Andric #include <string>
782cab237bSDimitry Andric #include <utility>
792cab237bSDimitry Andric #include <vector>
803ca95b02SDimitry Andric
81f22ef01cSRoman Divacky using namespace llvm;
82f22ef01cSRoman Divacky
8391bc56edSDimitry Andric #define DEBUG_TYPE "dwarfdebug"
8491bc56edSDimitry Andric
85f785676fSDimitry Andric static cl::opt<bool>
86f785676fSDimitry Andric DisableDebugInfoPrinting("disable-debug-info-print", cl::Hidden,
87f22ef01cSRoman Divacky cl::desc("Disable debug info printing"));
88f22ef01cSRoman Divacky
892cab237bSDimitry Andric static cl::opt<bool> UseDwarfRangesBaseAddressSpecifier(
902cab237bSDimitry Andric "use-dwarf-ranges-base-address-specifier", cl::Hidden,
912cab237bSDimitry Andric cl::desc("Use base address specifiers in debug_ranges"), cl::init(false));
92139f7f9bSDimitry Andric
9391bc56edSDimitry Andric static cl::opt<bool> GenerateARangeSection("generate-arange-section",
9491bc56edSDimitry Andric cl::Hidden,
9591bc56edSDimitry Andric cl::desc("Generate dwarf aranges"),
9691bc56edSDimitry Andric cl::init(false));
9791bc56edSDimitry Andric
984ba319b5SDimitry Andric static cl::opt<bool>
994ba319b5SDimitry Andric GenerateDwarfTypeUnits("generate-type-units", cl::Hidden,
1004ba319b5SDimitry Andric cl::desc("Generate DWARF4 type units."),
1014ba319b5SDimitry Andric cl::init(false));
1024ba319b5SDimitry Andric
1035517e702SDimitry Andric static cl::opt<bool> SplitDwarfCrossCuReferences(
1045517e702SDimitry Andric "split-dwarf-cross-cu-references", cl::Hidden,
1055517e702SDimitry Andric cl::desc("Enable cross-cu references in DWO files"), cl::init(false));
1065517e702SDimitry Andric
10791bc56edSDimitry Andric enum DefaultOnOff { Default, Enable, Disable };
1083861d79fSDimitry Andric
109d88c1a5aSDimitry Andric static cl::opt<DefaultOnOff> UnknownLocations(
110d88c1a5aSDimitry Andric "use-unknown-locations", cl::Hidden,
111d88c1a5aSDimitry Andric cl::desc("Make an absence of debug location information explicit."),
112d88c1a5aSDimitry Andric cl::values(clEnumVal(Default, "At top of block or after label"),
113d88c1a5aSDimitry Andric clEnumVal(Enable, "In all cases"), clEnumVal(Disable, "Never")),
114d88c1a5aSDimitry Andric cl::init(Default));
115d88c1a5aSDimitry Andric
1164ba319b5SDimitry Andric static cl::opt<AccelTableKind> AccelTables(
1174ba319b5SDimitry Andric "accel-tables", cl::Hidden, cl::desc("Output dwarf accelerator tables."),
1184ba319b5SDimitry Andric cl::values(clEnumValN(AccelTableKind::Default, "Default",
1194ba319b5SDimitry Andric "Default for platform"),
1204ba319b5SDimitry Andric clEnumValN(AccelTableKind::None, "Disable", "Disabled."),
1214ba319b5SDimitry Andric clEnumValN(AccelTableKind::Apple, "Apple", "Apple"),
1224ba319b5SDimitry Andric clEnumValN(AccelTableKind::Dwarf, "Dwarf", "DWARF")),
1234ba319b5SDimitry Andric cl::init(AccelTableKind::Default));
1244ba319b5SDimitry Andric
125f785676fSDimitry Andric static cl::opt<DefaultOnOff>
1264ba319b5SDimitry Andric DwarfInlinedStrings("dwarf-inlined-strings", cl::Hidden,
1274ba319b5SDimitry Andric cl::desc("Use inlined strings rather than string section."),
128f785676fSDimitry Andric cl::values(clEnumVal(Default, "Default for platform"),
1293861d79fSDimitry Andric clEnumVal(Enable, "Enabled"),
130d88c1a5aSDimitry Andric clEnumVal(Disable, "Disabled")),
1313861d79fSDimitry Andric cl::init(Default));
1323861d79fSDimitry Andric
1334ba319b5SDimitry Andric static cl::opt<bool>
1344ba319b5SDimitry Andric NoDwarfRangesSection("no-dwarf-ranges-section", cl::Hidden,
1354ba319b5SDimitry Andric cl::desc("Disable emission .debug_ranges section."),
1364ba319b5SDimitry Andric cl::init(false));
1374ba319b5SDimitry Andric
1384ba319b5SDimitry Andric static cl::opt<DefaultOnOff> DwarfSectionsAsReferences(
1394ba319b5SDimitry Andric "dwarf-sections-as-references", cl::Hidden,
1404ba319b5SDimitry Andric cl::desc("Use sections+offset as references rather than labels."),
1414ba319b5SDimitry Andric cl::values(clEnumVal(Default, "Default for platform"),
1424ba319b5SDimitry Andric clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")),
1434ba319b5SDimitry Andric cl::init(Default));
1444ba319b5SDimitry Andric
1453ca95b02SDimitry Andric enum LinkageNameOption {
1463ca95b02SDimitry Andric DefaultLinkageNames,
1473ca95b02SDimitry Andric AllLinkageNames,
1483ca95b02SDimitry Andric AbstractLinkageNames
1493ca95b02SDimitry Andric };
1502cab237bSDimitry Andric
1513ca95b02SDimitry Andric static cl::opt<LinkageNameOption>
1527d523365SDimitry Andric DwarfLinkageNames("dwarf-linkage-names", cl::Hidden,
1533ca95b02SDimitry Andric cl::desc("Which DWARF linkage-name attributes to emit."),
1543ca95b02SDimitry Andric cl::values(clEnumValN(DefaultLinkageNames, "Default",
1553ca95b02SDimitry Andric "Default for platform"),
1563ca95b02SDimitry Andric clEnumValN(AllLinkageNames, "All", "All"),
1573ca95b02SDimitry Andric clEnumValN(AbstractLinkageNames, "Abstract",
158d88c1a5aSDimitry Andric "Abstract subprograms")),
1593ca95b02SDimitry Andric cl::init(DefaultLinkageNames));
1607d523365SDimitry Andric
161d88c1a5aSDimitry Andric static const char *const DWARFGroupName = "dwarf";
162d88c1a5aSDimitry Andric static const char *const DWARFGroupDescription = "DWARF Emission";
163d88c1a5aSDimitry Andric static const char *const DbgTimerName = "writer";
164d88c1a5aSDimitry Andric static const char *const DbgTimerDescription = "DWARF Debug Writer";
165f22ef01cSRoman Divacky
emitOp(uint8_t Op,const char * Comment)1667a7e6055SDimitry Andric void DebugLocDwarfExpression::emitOp(uint8_t Op, const char *Comment) {
167ff0cc061SDimitry Andric BS.EmitInt8(
168ff0cc061SDimitry Andric Op, Comment ? Twine(Comment) + " " + dwarf::OperationEncodingString(Op)
169ff0cc061SDimitry Andric : dwarf::OperationEncodingString(Op));
170ff0cc061SDimitry Andric }
171ff0cc061SDimitry Andric
emitSigned(int64_t Value)1727a7e6055SDimitry Andric void DebugLocDwarfExpression::emitSigned(int64_t Value) {
173ff0cc061SDimitry Andric BS.EmitSLEB128(Value, Twine(Value));
174ff0cc061SDimitry Andric }
175ff0cc061SDimitry Andric
emitUnsigned(uint64_t Value)1767a7e6055SDimitry Andric void DebugLocDwarfExpression::emitUnsigned(uint64_t Value) {
177ff0cc061SDimitry Andric BS.EmitULEB128(Value, Twine(Value));
178ff0cc061SDimitry Andric }
179ff0cc061SDimitry Andric
isFrameRegister(const TargetRegisterInfo & TRI,unsigned MachineReg)1803ca95b02SDimitry Andric bool DebugLocDwarfExpression::isFrameRegister(const TargetRegisterInfo &TRI,
1813ca95b02SDimitry Andric unsigned MachineReg) {
182ff0cc061SDimitry Andric // This information is not available while emitting .debug_loc entries.
183ff0cc061SDimitry Andric return false;
184ff0cc061SDimitry Andric }
185ff0cc061SDimitry Andric
isBlockByrefVariable() const18691bc56edSDimitry Andric bool DbgVariable::isBlockByrefVariable() const {
187*b5893f02SDimitry Andric assert(getVariable() && "Invalid complex DbgVariable!");
188*b5893f02SDimitry Andric return getVariable()->getType().resolve()->isBlockByrefStruct();
18991bc56edSDimitry Andric }
19091bc56edSDimitry Andric
getType() const191ff0cc061SDimitry Andric const DIType *DbgVariable::getType() const {
192*b5893f02SDimitry Andric DIType *Ty = getVariable()->getType().resolve();
193e580952dSDimitry Andric // FIXME: isBlockByrefVariable should be reformulated in terms of complex
194e580952dSDimitry Andric // addresses instead.
195ff0cc061SDimitry Andric if (Ty->isBlockByrefStruct()) {
196e580952dSDimitry Andric /* Byref variables, in Blocks, are declared by the programmer as
197e580952dSDimitry Andric "SomeType VarName;", but the compiler creates a
198e580952dSDimitry Andric __Block_byref_x_VarName struct, and gives the variable VarName
199e580952dSDimitry Andric either the struct, or a pointer to the struct, as its type. This
200e580952dSDimitry Andric is necessary for various behind-the-scenes things the compiler
201e580952dSDimitry Andric needs to do with by-reference variables in blocks.
202e580952dSDimitry Andric
203e580952dSDimitry Andric However, as far as the original *programmer* is concerned, the
204e580952dSDimitry Andric variable should still have type 'SomeType', as originally declared.
205e580952dSDimitry Andric
206e580952dSDimitry Andric The following function dives into the __Block_byref_x_VarName
207e580952dSDimitry Andric struct to find the original type of the variable. This will be
208e580952dSDimitry Andric passed back to the code generating the type for the Debug
209e580952dSDimitry Andric Information Entry for the variable 'VarName'. 'VarName' will then
210e580952dSDimitry Andric have the original type 'SomeType' in its debug information.
211e580952dSDimitry Andric
212e580952dSDimitry Andric The original type 'SomeType' will be the type of the field named
213e580952dSDimitry Andric 'VarName' inside the __Block_byref_x_VarName struct.
214e580952dSDimitry Andric
215e580952dSDimitry Andric NOTE: In order for this to not completely fail on the debugger
216e580952dSDimitry Andric side, the Debug Information Entry for the variable VarName needs to
217e580952dSDimitry Andric have a DW_AT_location that tells the debugger how to unwind through
218e580952dSDimitry Andric the pointers and __Block_byref_x_VarName struct to find the actual
219e580952dSDimitry Andric value of the variable. The function addBlockByrefType does this. */
220ff0cc061SDimitry Andric DIType *subType = Ty;
221ff0cc061SDimitry Andric uint16_t tag = Ty->getTag();
222e580952dSDimitry Andric
223f785676fSDimitry Andric if (tag == dwarf::DW_TAG_pointer_type)
224ff0cc061SDimitry Andric subType = resolve(cast<DIDerivedType>(Ty)->getBaseType());
225e580952dSDimitry Andric
2267d523365SDimitry Andric auto Elements = cast<DICompositeType>(subType)->getElements();
227ff0cc061SDimitry Andric for (unsigned i = 0, N = Elements.size(); i < N; ++i) {
2287d523365SDimitry Andric auto *DT = cast<DIDerivedType>(Elements[i]);
229ff0cc061SDimitry Andric if (getName() == DT->getName())
230ff0cc061SDimitry Andric return resolve(DT->getBaseType());
231e580952dSDimitry Andric }
232e580952dSDimitry Andric }
233e580952dSDimitry Andric return Ty;
234e580952dSDimitry Andric }
235f22ef01cSRoman Divacky
getFrameIndexExprs() const2365d193882SDimitry Andric ArrayRef<DbgVariable::FrameIndexExpr> DbgVariable::getFrameIndexExprs() const {
2377a7e6055SDimitry Andric if (FrameIndexExprs.size() == 1)
2387a7e6055SDimitry Andric return FrameIndexExprs;
2397a7e6055SDimitry Andric
2402cab237bSDimitry Andric assert(llvm::all_of(FrameIndexExprs,
2412cab237bSDimitry Andric [](const FrameIndexExpr &A) {
2422cab237bSDimitry Andric return A.Expr->isFragment();
2432cab237bSDimitry Andric }) &&
2447a7e6055SDimitry Andric "multiple FI expressions without DW_OP_LLVM_fragment");
245*b5893f02SDimitry Andric llvm::sort(FrameIndexExprs,
2465d193882SDimitry Andric [](const FrameIndexExpr &A, const FrameIndexExpr &B) -> bool {
2475d193882SDimitry Andric return A.Expr->getFragmentInfo()->OffsetInBits <
2485d193882SDimitry Andric B.Expr->getFragmentInfo()->OffsetInBits;
2495d193882SDimitry Andric });
2502cab237bSDimitry Andric
2515d193882SDimitry Andric return FrameIndexExprs;
2525d193882SDimitry Andric }
2535d193882SDimitry Andric
addMMIEntry(const DbgVariable & V)2542cab237bSDimitry Andric void DbgVariable::addMMIEntry(const DbgVariable &V) {
2552cab237bSDimitry Andric assert(DebugLocListIndex == ~0U && !MInsn && "not an MMI entry");
2562cab237bSDimitry Andric assert(V.DebugLocListIndex == ~0U && !V.MInsn && "not an MMI entry");
257*b5893f02SDimitry Andric assert(V.getVariable() == getVariable() && "conflicting variable");
258*b5893f02SDimitry Andric assert(V.getInlinedAt() == getInlinedAt() && "conflicting inlined-at location");
2592cab237bSDimitry Andric
2602cab237bSDimitry Andric assert(!FrameIndexExprs.empty() && "Expected an MMI entry");
2612cab237bSDimitry Andric assert(!V.FrameIndexExprs.empty() && "Expected an MMI entry");
2622cab237bSDimitry Andric
2632cab237bSDimitry Andric // FIXME: This logic should not be necessary anymore, as we now have proper
2642cab237bSDimitry Andric // deduplication. However, without it, we currently run into the assertion
2652cab237bSDimitry Andric // below, which means that we are likely dealing with broken input, i.e. two
2662cab237bSDimitry Andric // non-fragment entries for the same variable at different frame indices.
2672cab237bSDimitry Andric if (FrameIndexExprs.size()) {
2682cab237bSDimitry Andric auto *Expr = FrameIndexExprs.back().Expr;
2692cab237bSDimitry Andric if (!Expr || !Expr->isFragment())
2702cab237bSDimitry Andric return;
2712cab237bSDimitry Andric }
2722cab237bSDimitry Andric
2732cab237bSDimitry Andric for (const auto &FIE : V.FrameIndexExprs)
2742cab237bSDimitry Andric // Ignore duplicate entries.
2752cab237bSDimitry Andric if (llvm::none_of(FrameIndexExprs, [&](const FrameIndexExpr &Other) {
2762cab237bSDimitry Andric return FIE.FI == Other.FI && FIE.Expr == Other.Expr;
2772cab237bSDimitry Andric }))
2782cab237bSDimitry Andric FrameIndexExprs.push_back(FIE);
2792cab237bSDimitry Andric
2802cab237bSDimitry Andric assert((FrameIndexExprs.size() == 1 ||
2812cab237bSDimitry Andric llvm::all_of(FrameIndexExprs,
2822cab237bSDimitry Andric [](FrameIndexExpr &FIE) {
2832cab237bSDimitry Andric return FIE.Expr && FIE.Expr->isFragment();
2842cab237bSDimitry Andric })) &&
2852cab237bSDimitry Andric "conflicting locations for variable");
2862cab237bSDimitry Andric }
2872cab237bSDimitry Andric
computeAccelTableKind(unsigned DwarfVersion,bool GenerateTypeUnits,DebuggerKind Tuning,const Triple & TT)2884ba319b5SDimitry Andric static AccelTableKind computeAccelTableKind(unsigned DwarfVersion,
2894ba319b5SDimitry Andric bool GenerateTypeUnits,
2904ba319b5SDimitry Andric DebuggerKind Tuning,
2914ba319b5SDimitry Andric const Triple &TT) {
2924ba319b5SDimitry Andric // Honor an explicit request.
2934ba319b5SDimitry Andric if (AccelTables != AccelTableKind::Default)
2944ba319b5SDimitry Andric return AccelTables;
2954ba319b5SDimitry Andric
2964ba319b5SDimitry Andric // Accelerator tables with type units are currently not supported.
2974ba319b5SDimitry Andric if (GenerateTypeUnits)
2984ba319b5SDimitry Andric return AccelTableKind::None;
2994ba319b5SDimitry Andric
3004ba319b5SDimitry Andric // Accelerator tables get emitted if targetting DWARF v5 or LLDB. DWARF v5
3014ba319b5SDimitry Andric // always implies debug_names. For lower standard versions we use apple
3024ba319b5SDimitry Andric // accelerator tables on apple platforms and debug_names elsewhere.
3034ba319b5SDimitry Andric if (DwarfVersion >= 5)
3044ba319b5SDimitry Andric return AccelTableKind::Dwarf;
3054ba319b5SDimitry Andric if (Tuning == DebuggerKind::LLDB)
3064ba319b5SDimitry Andric return TT.isOSBinFormatMachO() ? AccelTableKind::Apple
3074ba319b5SDimitry Andric : AccelTableKind::Dwarf;
3084ba319b5SDimitry Andric return AccelTableKind::None;
3094ba319b5SDimitry Andric }
310f785676fSDimitry Andric
DwarfDebug(AsmPrinter * A,Module * M)311f22ef01cSRoman Divacky DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
3123ca95b02SDimitry Andric : DebugHandlerBase(A), DebugLocs(A->OutStreamer->isVerboseAsm()),
3133ca95b02SDimitry Andric InfoHolder(A, "info_string", DIEValueAllocator),
314ff0cc061SDimitry Andric SkeletonHolder(A, "skel_string", DIEValueAllocator),
3154ba319b5SDimitry Andric IsDarwin(A->TM.getTargetTriple().isOSDarwin()) {
316d88c1a5aSDimitry Andric const Triple &TT = Asm->TM.getTargetTriple();
317dff0c46cSDimitry Andric
3187d523365SDimitry Andric // Make sure we know our "debugger tuning." The target option takes
3197d523365SDimitry Andric // precedence; fall back to triple-based defaults.
3207d523365SDimitry Andric if (Asm->TM.Options.DebuggerTuning != DebuggerKind::Default)
3217d523365SDimitry Andric DebuggerTuning = Asm->TM.Options.DebuggerTuning;
3227d043514SDimitry Andric else if (IsDarwin)
3237d523365SDimitry Andric DebuggerTuning = DebuggerKind::LLDB;
3247d523365SDimitry Andric else if (TT.isPS4CPU())
3257d523365SDimitry Andric DebuggerTuning = DebuggerKind::SCE;
3267d523365SDimitry Andric else
3277d523365SDimitry Andric DebuggerTuning = DebuggerKind::GDB;
3287d523365SDimitry Andric
3294ba319b5SDimitry Andric if (DwarfInlinedStrings == Default)
3304ba319b5SDimitry Andric UseInlineStrings = TT.isNVPTX();
3313861d79fSDimitry Andric else
3324ba319b5SDimitry Andric UseInlineStrings = DwarfInlinedStrings == Enable;
3334ba319b5SDimitry Andric
3344ba319b5SDimitry Andric UseLocSection = !TT.isNVPTX();
335139f7f9bSDimitry Andric
3363ca95b02SDimitry Andric HasAppleExtensionAttributes = tuneForLLDB();
3373ca95b02SDimitry Andric
33851690af2SDimitry Andric // Handle split DWARF.
33951690af2SDimitry Andric HasSplitDwarf = !Asm->TM.Options.MCOptions.SplitDwarfFile.empty();
340f785676fSDimitry Andric
3413ca95b02SDimitry Andric // SCE defaults to linkage names only for abstract subprograms.
3423ca95b02SDimitry Andric if (DwarfLinkageNames == DefaultLinkageNames)
3433ca95b02SDimitry Andric UseAllLinkageNames = !tuneForSCE();
3447d523365SDimitry Andric else
3453ca95b02SDimitry Andric UseAllLinkageNames = DwarfLinkageNames == AllLinkageNames;
3467d523365SDimitry Andric
34791bc56edSDimitry Andric unsigned DwarfVersionNumber = Asm->TM.Options.MCOptions.DwarfVersion;
348d88c1a5aSDimitry Andric unsigned DwarfVersion = DwarfVersionNumber ? DwarfVersionNumber
34991bc56edSDimitry Andric : MMI->getModule()->getDwarfVersion();
3504ba319b5SDimitry Andric // Use dwarf 4 by default if nothing is requested. For NVPTX, use dwarf 2.
3514ba319b5SDimitry Andric DwarfVersion =
3524ba319b5SDimitry Andric TT.isNVPTX() ? 2 : (DwarfVersion ? DwarfVersion : dwarf::DWARF_VERSION);
3534ba319b5SDimitry Andric
3544ba319b5SDimitry Andric UseRangesSection = !NoDwarfRangesSection && !TT.isNVPTX();
3554ba319b5SDimitry Andric
3564ba319b5SDimitry Andric // Use sections as references. Force for NVPTX.
3574ba319b5SDimitry Andric if (DwarfSectionsAsReferences == Default)
3584ba319b5SDimitry Andric UseSectionsAsReferences = TT.isNVPTX();
3594ba319b5SDimitry Andric else
3604ba319b5SDimitry Andric UseSectionsAsReferences = DwarfSectionsAsReferences == Enable;
3614ba319b5SDimitry Andric
3624ba319b5SDimitry Andric // Don't generate type units for unsupported object file formats.
3634ba319b5SDimitry Andric GenerateTypeUnits =
3644ba319b5SDimitry Andric A->TM.getTargetTriple().isOSBinFormatELF() && GenerateDwarfTypeUnits;
3654ba319b5SDimitry Andric
3664ba319b5SDimitry Andric TheAccelTableKind = computeAccelTableKind(
3674ba319b5SDimitry Andric DwarfVersion, GenerateTypeUnits, DebuggerTuning, A->TM.getTargetTriple());
36891bc56edSDimitry Andric
3697d523365SDimitry Andric // Work around a GDB bug. GDB doesn't support the standard opcode;
3707d523365SDimitry Andric // SCE doesn't support GNU's; LLDB prefers the standard opcode, which
3717d523365SDimitry Andric // is defined as of DWARF 3.
3727d523365SDimitry Andric // See GDB bug 11616 - DW_OP_form_tls_address is unimplemented
3737d523365SDimitry Andric // https://sourceware.org/bugzilla/show_bug.cgi?id=11616
3747d523365SDimitry Andric UseGNUTLSOpcode = tuneForGDB() || DwarfVersion < 3;
375ff0cc061SDimitry Andric
3763ca95b02SDimitry Andric // GDB does not fully support the DWARF 4 representation for bitfields.
3773ca95b02SDimitry Andric UseDWARF2Bitfields = (DwarfVersion < 4) || tuneForGDB();
378dff0c46cSDimitry Andric
3794ba319b5SDimitry Andric // The DWARF v5 string offsets table has - possibly shared - contributions
3804ba319b5SDimitry Andric // from each compile and type unit each preceded by a header. The string
3814ba319b5SDimitry Andric // offsets table used by the pre-DWARF v5 split-DWARF implementation uses
3824ba319b5SDimitry Andric // a monolithic string offsets table without any header.
3834ba319b5SDimitry Andric UseSegmentedStringOffsetsTable = DwarfVersion >= 5;
3844ba319b5SDimitry Andric
3853ca95b02SDimitry Andric Asm->OutStreamer->getContext().setDwarfVersion(DwarfVersion);
386f22ef01cSRoman Divacky }
387f22ef01cSRoman Divacky
38891bc56edSDimitry Andric // Define out of line so we don't have to include DwarfUnit.h in DwarfDebug.h.
3892cab237bSDimitry Andric DwarfDebug::~DwarfDebug() = default;
39091bc56edSDimitry Andric
isObjCClass(StringRef Name)391dff0c46cSDimitry Andric static bool isObjCClass(StringRef Name) {
392dff0c46cSDimitry Andric return Name.startswith("+") || Name.startswith("-");
393dff0c46cSDimitry Andric }
394dff0c46cSDimitry Andric
hasObjCCategory(StringRef Name)395dff0c46cSDimitry Andric static bool hasObjCCategory(StringRef Name) {
39691bc56edSDimitry Andric if (!isObjCClass(Name))
39791bc56edSDimitry Andric return false;
398dff0c46cSDimitry Andric
399f785676fSDimitry Andric return Name.find(") ") != StringRef::npos;
400dff0c46cSDimitry Andric }
401dff0c46cSDimitry Andric
getObjCClassCategory(StringRef In,StringRef & Class,StringRef & Category)402dff0c46cSDimitry Andric static void getObjCClassCategory(StringRef In, StringRef &Class,
403dff0c46cSDimitry Andric StringRef &Category) {
404dff0c46cSDimitry Andric if (!hasObjCCategory(In)) {
405dff0c46cSDimitry Andric Class = In.slice(In.find('[') + 1, In.find(' '));
406dff0c46cSDimitry Andric Category = "";
407dff0c46cSDimitry Andric return;
408dff0c46cSDimitry Andric }
409dff0c46cSDimitry Andric
410dff0c46cSDimitry Andric Class = In.slice(In.find('[') + 1, In.find('('));
411dff0c46cSDimitry Andric Category = In.slice(In.find('[') + 1, In.find(' '));
412dff0c46cSDimitry Andric }
413dff0c46cSDimitry Andric
getObjCMethodName(StringRef In)414dff0c46cSDimitry Andric static StringRef getObjCMethodName(StringRef In) {
415dff0c46cSDimitry Andric return In.slice(In.find(' ') + 1, In.find(']'));
416dff0c46cSDimitry Andric }
417dff0c46cSDimitry Andric
418dff0c46cSDimitry Andric // Add the various names to the Dwarf accelerator table names.
addSubprogramNames(const DICompileUnit & CU,const DISubprogram * SP,DIE & Die)419*b5893f02SDimitry Andric void DwarfDebug::addSubprogramNames(const DICompileUnit &CU,
420*b5893f02SDimitry Andric const DISubprogram *SP, DIE &Die) {
421*b5893f02SDimitry Andric if (getAccelTableKind() != AccelTableKind::Apple &&
422*b5893f02SDimitry Andric CU.getNameTableKind() == DICompileUnit::DebugNameTableKind::None)
423*b5893f02SDimitry Andric return;
424*b5893f02SDimitry Andric
425ff0cc061SDimitry Andric if (!SP->isDefinition())
42691bc56edSDimitry Andric return;
4274ba319b5SDimitry Andric
4284ba319b5SDimitry Andric if (SP->getName() != "")
429*b5893f02SDimitry Andric addAccelName(CU, SP->getName(), Die);
430dff0c46cSDimitry Andric
4314ba319b5SDimitry Andric // If the linkage name is different than the name, go ahead and output that as
4324ba319b5SDimitry Andric // well into the name table. Only do that if we are going to actually emit
4334ba319b5SDimitry Andric // that name.
4344ba319b5SDimitry Andric if (SP->getLinkageName() != "" && SP->getName() != SP->getLinkageName() &&
4354ba319b5SDimitry Andric (useAllLinkageNames() || InfoHolder.getAbstractSPDies().lookup(SP)))
436*b5893f02SDimitry Andric addAccelName(CU, SP->getLinkageName(), Die);
437dff0c46cSDimitry Andric
438dff0c46cSDimitry Andric // If this is an Objective-C selector name add it to the ObjC accelerator
439dff0c46cSDimitry Andric // too.
440ff0cc061SDimitry Andric if (isObjCClass(SP->getName())) {
441dff0c46cSDimitry Andric StringRef Class, Category;
442ff0cc061SDimitry Andric getObjCClassCategory(SP->getName(), Class, Category);
443*b5893f02SDimitry Andric addAccelObjC(CU, Class, Die);
444dff0c46cSDimitry Andric if (Category != "")
445*b5893f02SDimitry Andric addAccelObjC(CU, Category, Die);
446dff0c46cSDimitry Andric // Also add the base method name to the name table.
447*b5893f02SDimitry Andric addAccelName(CU, getObjCMethodName(SP->getName()), Die);
448dff0c46cSDimitry Andric }
449dff0c46cSDimitry Andric }
450dff0c46cSDimitry Andric
451f785676fSDimitry Andric /// Check whether we should create a DIE for the given Scope, return true
452f785676fSDimitry Andric /// if we don't create a DIE (the corresponding DIE is null).
isLexicalScopeDIENull(LexicalScope * Scope)453f785676fSDimitry Andric bool DwarfDebug::isLexicalScopeDIENull(LexicalScope *Scope) {
454f785676fSDimitry Andric if (Scope->isAbstractScope())
455f785676fSDimitry Andric return false;
456f785676fSDimitry Andric
457f785676fSDimitry Andric // We don't create a DIE if there is no Range.
458f785676fSDimitry Andric const SmallVectorImpl<InsnRange> &Ranges = Scope->getRanges();
459f785676fSDimitry Andric if (Ranges.empty())
460f785676fSDimitry Andric return true;
461f785676fSDimitry Andric
462f785676fSDimitry Andric if (Ranges.size() > 1)
463f785676fSDimitry Andric return false;
464f785676fSDimitry Andric
465f785676fSDimitry Andric // We don't create a DIE if we have a single Range and the end label
466f785676fSDimitry Andric // is null.
46739d628a0SDimitry Andric return !getLabelAfterInsn(Ranges.front().second);
468f785676fSDimitry Andric }
469f785676fSDimitry Andric
forBothCUs(DwarfCompileUnit & CU,Func F)470d88c1a5aSDimitry Andric template <typename Func> static void forBothCUs(DwarfCompileUnit &CU, Func F) {
47139d628a0SDimitry Andric F(CU);
47239d628a0SDimitry Andric if (auto *SkelCU = CU.getSkeleton())
473d88c1a5aSDimitry Andric if (CU.getCUNode()->getSplitDebugInlining())
47439d628a0SDimitry Andric F(*SkelCU);
47591bc56edSDimitry Andric }
47691bc56edSDimitry Andric
shareAcrossDWOCUs() const4775517e702SDimitry Andric bool DwarfDebug::shareAcrossDWOCUs() const {
4785517e702SDimitry Andric return SplitDwarfCrossCuReferences;
4795517e702SDimitry Andric }
4805517e702SDimitry Andric
constructAbstractSubprogramScopeDIE(DwarfCompileUnit & SrcCU,LexicalScope * Scope)4815517e702SDimitry Andric void DwarfDebug::constructAbstractSubprogramScopeDIE(DwarfCompileUnit &SrcCU,
4825517e702SDimitry Andric LexicalScope *Scope) {
48391bc56edSDimitry Andric assert(Scope && Scope->getScopeNode());
48491bc56edSDimitry Andric assert(Scope->isAbstractScope());
48591bc56edSDimitry Andric assert(!Scope->getInlinedAt());
4863861d79fSDimitry Andric
487d88c1a5aSDimitry Andric auto *SP = cast<DISubprogram>(Scope->getScopeNode());
48891bc56edSDimitry Andric
48991bc56edSDimitry Andric // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram
49091bc56edSDimitry Andric // was inlined from another compile unit.
491302affcbSDimitry Andric if (useSplitDwarf() && !shareAcrossDWOCUs() && !SP->getUnit()->getSplitDebugInlining())
492302affcbSDimitry Andric // Avoid building the original CU if it won't be used
493302affcbSDimitry Andric SrcCU.constructAbstractSubprogramScopeDIE(Scope);
494302affcbSDimitry Andric else {
495302affcbSDimitry Andric auto &CU = getOrCreateDwarfCompileUnit(SP->getUnit());
4965517e702SDimitry Andric if (auto *SkelCU = CU.getSkeleton()) {
4975517e702SDimitry Andric (shareAcrossDWOCUs() ? CU : SrcCU)
4985517e702SDimitry Andric .constructAbstractSubprogramScopeDIE(Scope);
4995517e702SDimitry Andric if (CU.getCUNode()->getSplitDebugInlining())
5005517e702SDimitry Andric SkelCU->constructAbstractSubprogramScopeDIE(Scope);
501302affcbSDimitry Andric } else
50239d628a0SDimitry Andric CU.constructAbstractSubprogramScopeDIE(Scope);
5035517e702SDimitry Andric }
50491bc56edSDimitry Andric }
50591bc56edSDimitry Andric
constructCallSiteEntryDIEs(const DISubprogram & SP,DwarfCompileUnit & CU,DIE & ScopeDIE,const MachineFunction & MF)506*b5893f02SDimitry Andric void DwarfDebug::constructCallSiteEntryDIEs(const DISubprogram &SP,
507*b5893f02SDimitry Andric DwarfCompileUnit &CU, DIE &ScopeDIE,
508*b5893f02SDimitry Andric const MachineFunction &MF) {
509*b5893f02SDimitry Andric // Add a call site-related attribute (DWARF5, Sec. 3.3.1.3). Do this only if
510*b5893f02SDimitry Andric // the subprogram is required to have one.
511*b5893f02SDimitry Andric if (!SP.areAllCallsDescribed() || !SP.isDefinition())
512*b5893f02SDimitry Andric return;
513*b5893f02SDimitry Andric
514*b5893f02SDimitry Andric // Use DW_AT_call_all_calls to express that call site entries are present
515*b5893f02SDimitry Andric // for both tail and non-tail calls. Don't use DW_AT_call_all_source_calls
516*b5893f02SDimitry Andric // because one of its requirements is not met: call site entries for
517*b5893f02SDimitry Andric // optimized-out calls are elided.
518*b5893f02SDimitry Andric CU.addFlag(ScopeDIE, dwarf::DW_AT_call_all_calls);
519*b5893f02SDimitry Andric
520*b5893f02SDimitry Andric const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
521*b5893f02SDimitry Andric assert(TII && "TargetInstrInfo not found: cannot label tail calls");
522*b5893f02SDimitry Andric
523*b5893f02SDimitry Andric // Emit call site entries for each call or tail call in the function.
524*b5893f02SDimitry Andric for (const MachineBasicBlock &MBB : MF) {
525*b5893f02SDimitry Andric for (const MachineInstr &MI : MBB.instrs()) {
526*b5893f02SDimitry Andric // Skip instructions which aren't calls. Both calls and tail-calling jump
527*b5893f02SDimitry Andric // instructions (e.g TAILJMPd64) are classified correctly here.
528*b5893f02SDimitry Andric if (!MI.isCall())
529*b5893f02SDimitry Andric continue;
530*b5893f02SDimitry Andric
531*b5893f02SDimitry Andric // TODO: Add support for targets with delay slots (see: beginInstruction).
532*b5893f02SDimitry Andric if (MI.hasDelaySlot())
533*b5893f02SDimitry Andric return;
534*b5893f02SDimitry Andric
535*b5893f02SDimitry Andric // If this is a direct call, find the callee's subprogram.
536*b5893f02SDimitry Andric const MachineOperand &CalleeOp = MI.getOperand(0);
537*b5893f02SDimitry Andric if (!CalleeOp.isGlobal())
538*b5893f02SDimitry Andric continue;
539*b5893f02SDimitry Andric const Function *CalleeDecl = dyn_cast<Function>(CalleeOp.getGlobal());
540*b5893f02SDimitry Andric if (!CalleeDecl || !CalleeDecl->getSubprogram())
541*b5893f02SDimitry Andric continue;
542*b5893f02SDimitry Andric
543*b5893f02SDimitry Andric // TODO: Omit call site entries for runtime calls (objc_msgSend, etc).
544*b5893f02SDimitry Andric // TODO: Add support for indirect calls.
545*b5893f02SDimitry Andric
546*b5893f02SDimitry Andric bool IsTail = TII->isTailCall(MI);
547*b5893f02SDimitry Andric
548*b5893f02SDimitry Andric // For tail calls, no return PC information is needed. For regular calls,
549*b5893f02SDimitry Andric // the return PC is needed to disambiguate paths in the call graph which
550*b5893f02SDimitry Andric // could lead to some target function.
551*b5893f02SDimitry Andric const MCExpr *PCOffset =
552*b5893f02SDimitry Andric IsTail ? nullptr : getFunctionLocalOffsetAfterInsn(&MI);
553*b5893f02SDimitry Andric
554*b5893f02SDimitry Andric assert((IsTail || PCOffset) && "Call without return PC information");
555*b5893f02SDimitry Andric LLVM_DEBUG(dbgs() << "CallSiteEntry: " << MF.getName() << " -> "
556*b5893f02SDimitry Andric << CalleeDecl->getName() << (IsTail ? " [tail]" : "")
557*b5893f02SDimitry Andric << "\n");
558*b5893f02SDimitry Andric CU.constructCallSiteEntryDIE(ScopeDIE, *CalleeDecl->getSubprogram(),
559*b5893f02SDimitry Andric IsTail, PCOffset);
560*b5893f02SDimitry Andric }
561*b5893f02SDimitry Andric }
562*b5893f02SDimitry Andric }
563*b5893f02SDimitry Andric
addGnuPubAttributes(DwarfCompileUnit & U,DIE & D) const564302affcbSDimitry Andric void DwarfDebug::addGnuPubAttributes(DwarfCompileUnit &U, DIE &D) const {
5652cab237bSDimitry Andric if (!U.hasDwarfPubSections())
56691bc56edSDimitry Andric return;
56791bc56edSDimitry Andric
56891bc56edSDimitry Andric U.addFlag(D, dwarf::DW_AT_GNU_pubnames);
56991bc56edSDimitry Andric }
57091bc56edSDimitry Andric
finishUnitAttributes(const DICompileUnit * DIUnit,DwarfCompileUnit & NewCU)571*b5893f02SDimitry Andric void DwarfDebug::finishUnitAttributes(const DICompileUnit *DIUnit,
572*b5893f02SDimitry Andric DwarfCompileUnit &NewCU) {
57391bc56edSDimitry Andric DIE &Die = NewCU.getUnitDie();
574*b5893f02SDimitry Andric StringRef FN = DIUnit->getFilename();
575139f7f9bSDimitry Andric
5767a7e6055SDimitry Andric StringRef Producer = DIUnit->getProducer();
5777a7e6055SDimitry Andric StringRef Flags = DIUnit->getFlags();
578*b5893f02SDimitry Andric if (!Flags.empty() && !useAppleExtensionAttributes()) {
5797a7e6055SDimitry Andric std::string ProducerWithFlags = Producer.str() + " " + Flags.str();
5807a7e6055SDimitry Andric NewCU.addString(Die, dwarf::DW_AT_producer, ProducerWithFlags);
5817a7e6055SDimitry Andric } else
5827a7e6055SDimitry Andric NewCU.addString(Die, dwarf::DW_AT_producer, Producer);
5837a7e6055SDimitry Andric
58491bc56edSDimitry Andric NewCU.addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
585ff0cc061SDimitry Andric DIUnit->getSourceLanguage());
58691bc56edSDimitry Andric NewCU.addString(Die, dwarf::DW_AT_name, FN);
587284c1978SDimitry Andric
5884ba319b5SDimitry Andric // Add DW_str_offsets_base to the unit DIE, except for split units.
5894ba319b5SDimitry Andric if (useSegmentedStringOffsetsTable() && !useSplitDwarf())
5904ba319b5SDimitry Andric NewCU.addStringOffsetsStart();
5914ba319b5SDimitry Andric
592f785676fSDimitry Andric if (!useSplitDwarf()) {
593ff0cc061SDimitry Andric NewCU.initStmtList();
594f22ef01cSRoman Divacky
595284c1978SDimitry Andric // If we're using split dwarf the compilation dir is going to be in the
596284c1978SDimitry Andric // skeleton CU and so we don't need to duplicate it here.
597f785676fSDimitry Andric if (!CompilationDir.empty())
59891bc56edSDimitry Andric NewCU.addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
599f785676fSDimitry Andric
60091bc56edSDimitry Andric addGnuPubAttributes(NewCU, Die);
601f785676fSDimitry Andric }
602f785676fSDimitry Andric
6033ca95b02SDimitry Andric if (useAppleExtensionAttributes()) {
604ff0cc061SDimitry Andric if (DIUnit->isOptimized())
60591bc56edSDimitry Andric NewCU.addFlag(Die, dwarf::DW_AT_APPLE_optimized);
606f22ef01cSRoman Divacky
607ff0cc061SDimitry Andric StringRef Flags = DIUnit->getFlags();
608f22ef01cSRoman Divacky if (!Flags.empty())
60991bc56edSDimitry Andric NewCU.addString(Die, dwarf::DW_AT_APPLE_flags, Flags);
610f22ef01cSRoman Divacky
611ff0cc061SDimitry Andric if (unsigned RVer = DIUnit->getRuntimeVersion())
61291bc56edSDimitry Andric NewCU.addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
613f22ef01cSRoman Divacky dwarf::DW_FORM_data1, RVer);
6143ca95b02SDimitry Andric }
615f22ef01cSRoman Divacky
6167d523365SDimitry Andric if (DIUnit->getDWOId()) {
6177d523365SDimitry Andric // This CU is either a clang module DWO or a skeleton CU.
6187d523365SDimitry Andric NewCU.addUInt(Die, dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8,
6197d523365SDimitry Andric DIUnit->getDWOId());
6207d523365SDimitry Andric if (!DIUnit->getSplitDebugFilename().empty())
6217d523365SDimitry Andric // This is a prefabricated skeleton CU.
6227d523365SDimitry Andric NewCU.addString(Die, dwarf::DW_AT_GNU_dwo_name,
6237d523365SDimitry Andric DIUnit->getSplitDebugFilename());
6247d523365SDimitry Andric }
625*b5893f02SDimitry Andric }
626*b5893f02SDimitry Andric // Create new DwarfCompileUnit for the given metadata node with tag
627*b5893f02SDimitry Andric // DW_TAG_compile_unit.
628*b5893f02SDimitry Andric DwarfCompileUnit &
getOrCreateDwarfCompileUnit(const DICompileUnit * DIUnit)629*b5893f02SDimitry Andric DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) {
630*b5893f02SDimitry Andric if (auto *CU = CUMap.lookup(DIUnit))
631*b5893f02SDimitry Andric return *CU;
632*b5893f02SDimitry Andric
633*b5893f02SDimitry Andric CompilationDir = DIUnit->getDirectory();
634*b5893f02SDimitry Andric
635*b5893f02SDimitry Andric auto OwnedUnit = llvm::make_unique<DwarfCompileUnit>(
636*b5893f02SDimitry Andric InfoHolder.getUnits().size(), DIUnit, Asm, this, &InfoHolder);
637*b5893f02SDimitry Andric DwarfCompileUnit &NewCU = *OwnedUnit;
638*b5893f02SDimitry Andric InfoHolder.addUnit(std::move(OwnedUnit));
639*b5893f02SDimitry Andric
640*b5893f02SDimitry Andric for (auto *IE : DIUnit->getImportedEntities())
641*b5893f02SDimitry Andric NewCU.addImportedEntity(IE);
642*b5893f02SDimitry Andric
643*b5893f02SDimitry Andric // LTO with assembly output shares a single line table amongst multiple CUs.
644*b5893f02SDimitry Andric // To avoid the compilation directory being ambiguous, let the line table
645*b5893f02SDimitry Andric // explicitly describe the directory of all files, never relying on the
646*b5893f02SDimitry Andric // compilation directory.
647*b5893f02SDimitry Andric if (!Asm->OutStreamer->hasRawTextSupport() || SingleCU)
648*b5893f02SDimitry Andric Asm->OutStreamer->emitDwarfFile0Directive(
649*b5893f02SDimitry Andric CompilationDir, DIUnit->getFilename(),
650*b5893f02SDimitry Andric NewCU.getMD5AsBytes(DIUnit->getFile()), DIUnit->getSource(),
651*b5893f02SDimitry Andric NewCU.getUniqueID());
652*b5893f02SDimitry Andric
653*b5893f02SDimitry Andric if (useSplitDwarf()) {
654*b5893f02SDimitry Andric NewCU.setSkeleton(constructSkeletonCU(NewCU));
655*b5893f02SDimitry Andric NewCU.setSection(Asm->getObjFileLowering().getDwarfInfoDWOSection());
656*b5893f02SDimitry Andric } else {
657*b5893f02SDimitry Andric finishUnitAttributes(DIUnit, NewCU);
658*b5893f02SDimitry Andric NewCU.setSection(Asm->getObjFileLowering().getDwarfInfoSection());
659*b5893f02SDimitry Andric }
6607d523365SDimitry Andric
661d88c1a5aSDimitry Andric CUMap.insert({DIUnit, &NewCU});
662*b5893f02SDimitry Andric CUDieMap.insert({&NewCU.getUnitDie(), &NewCU});
6636122f3e6SDimitry Andric return NewCU;
664f22ef01cSRoman Divacky }
665f22ef01cSRoman Divacky
constructAndAddImportedEntityDIE(DwarfCompileUnit & TheCU,const DIImportedEntity * N)66639d628a0SDimitry Andric void DwarfDebug::constructAndAddImportedEntityDIE(DwarfCompileUnit &TheCU,
667ff0cc061SDimitry Andric const DIImportedEntity *N) {
6682cab237bSDimitry Andric if (isa<DILocalScope>(N->getScope()))
6692cab237bSDimitry Andric return;
670ff0cc061SDimitry Andric if (DIE *D = TheCU.getOrCreateContextDIE(N->getScope()))
671ff0cc061SDimitry Andric D->addChild(TheCU.constructImportedEntityDIE(N));
672284c1978SDimitry Andric }
673284c1978SDimitry Andric
674d88c1a5aSDimitry Andric /// Sort and unique GVEs by comparing their fragment offset.
675d88c1a5aSDimitry Andric static SmallVectorImpl<DwarfCompileUnit::GlobalExpr> &
sortGlobalExprs(SmallVectorImpl<DwarfCompileUnit::GlobalExpr> & GVEs)676d88c1a5aSDimitry Andric sortGlobalExprs(SmallVectorImpl<DwarfCompileUnit::GlobalExpr> &GVEs) {
677*b5893f02SDimitry Andric llvm::sort(
678*b5893f02SDimitry Andric GVEs, [](DwarfCompileUnit::GlobalExpr A, DwarfCompileUnit::GlobalExpr B) {
6792cab237bSDimitry Andric // Sort order: first null exprs, then exprs without fragment
6802cab237bSDimitry Andric // info, then sort by fragment offset in bits.
6812cab237bSDimitry Andric // FIXME: Come up with a more comprehensive comparator so
6822cab237bSDimitry Andric // the sorting isn't non-deterministic, and so the following
6832cab237bSDimitry Andric // std::unique call works correctly.
6842cab237bSDimitry Andric if (!A.Expr || !B.Expr)
6852cab237bSDimitry Andric return !!B.Expr;
686d88c1a5aSDimitry Andric auto FragmentA = A.Expr->getFragmentInfo();
687d88c1a5aSDimitry Andric auto FragmentB = B.Expr->getFragmentInfo();
6882cab237bSDimitry Andric if (!FragmentA || !FragmentB)
6892cab237bSDimitry Andric return !!FragmentB;
690d88c1a5aSDimitry Andric return FragmentA->OffsetInBits < FragmentB->OffsetInBits;
691d88c1a5aSDimitry Andric });
692d88c1a5aSDimitry Andric GVEs.erase(std::unique(GVEs.begin(), GVEs.end(),
693d88c1a5aSDimitry Andric [](DwarfCompileUnit::GlobalExpr A,
694d88c1a5aSDimitry Andric DwarfCompileUnit::GlobalExpr B) {
695d88c1a5aSDimitry Andric return A.Expr == B.Expr;
696d88c1a5aSDimitry Andric }),
697d88c1a5aSDimitry Andric GVEs.end());
698d88c1a5aSDimitry Andric return GVEs;
699d88c1a5aSDimitry Andric }
700d88c1a5aSDimitry Andric
701139f7f9bSDimitry Andric // Emit all Dwarf sections that should come prior to the content. Create
702139f7f9bSDimitry Andric // global DIEs and emit initial debug info sections. This is invoked by
703139f7f9bSDimitry Andric // the target AsmPrinter.
beginModule()704139f7f9bSDimitry Andric void DwarfDebug::beginModule() {
705d88c1a5aSDimitry Andric NamedRegionTimer T(DbgTimerName, DbgTimerDescription, DWARFGroupName,
706d88c1a5aSDimitry Andric DWARFGroupDescription, TimePassesIsEnabled);
707*b5893f02SDimitry Andric if (DisableDebugInfoPrinting) {
708*b5893f02SDimitry Andric MMI->setDebugInfoAvailability(false);
7096122f3e6SDimitry Andric return;
710*b5893f02SDimitry Andric }
7116122f3e6SDimitry Andric
712139f7f9bSDimitry Andric const Module *M = MMI->getModule();
713139f7f9bSDimitry Andric
7143ca95b02SDimitry Andric unsigned NumDebugCUs = std::distance(M->debug_compile_units_begin(),
7153ca95b02SDimitry Andric M->debug_compile_units_end());
7163ca95b02SDimitry Andric // Tell MMI whether we have debug info.
717*b5893f02SDimitry Andric assert(MMI->hasDebugInfo() == (NumDebugCUs > 0) &&
718*b5893f02SDimitry Andric "DebugInfoAvailabilty initialized unexpectedly");
7193ca95b02SDimitry Andric SingleCU = NumDebugCUs == 1;
720d88c1a5aSDimitry Andric DenseMap<DIGlobalVariable *, SmallVector<DwarfCompileUnit::GlobalExpr, 1>>
721d88c1a5aSDimitry Andric GVMap;
722d88c1a5aSDimitry Andric for (const GlobalVariable &Global : M->globals()) {
723d88c1a5aSDimitry Andric SmallVector<DIGlobalVariableExpression *, 1> GVs;
724d88c1a5aSDimitry Andric Global.getDebugInfo(GVs);
725d88c1a5aSDimitry Andric for (auto *GVE : GVs)
726d88c1a5aSDimitry Andric GVMap[GVE->getVariable()].push_back({&Global, GVE->getExpression()});
727d88c1a5aSDimitry Andric }
728139f7f9bSDimitry Andric
7294ba319b5SDimitry Andric // Create the symbol that designates the start of the unit's contribution
7304ba319b5SDimitry Andric // to the string offsets table. In a split DWARF scenario, only the skeleton
7314ba319b5SDimitry Andric // unit has the DW_AT_str_offsets_base attribute (and hence needs the symbol).
7324ba319b5SDimitry Andric if (useSegmentedStringOffsetsTable())
7334ba319b5SDimitry Andric (useSplitDwarf() ? SkeletonHolder : InfoHolder)
7344ba319b5SDimitry Andric .setStringOffsetsStartSym(Asm->createTempSymbol("str_offsets_base"));
7354ba319b5SDimitry Andric
736*b5893f02SDimitry Andric
737*b5893f02SDimitry Andric // Create the symbols that designates the start of the DWARF v5 range list
738*b5893f02SDimitry Andric // and locations list tables. They are located past the table headers.
739*b5893f02SDimitry Andric if (getDwarfVersion() >= 5) {
740*b5893f02SDimitry Andric DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder;
741*b5893f02SDimitry Andric Holder.setRnglistsTableBaseSym(
742*b5893f02SDimitry Andric Asm->createTempSymbol("rnglists_table_base"));
743*b5893f02SDimitry Andric Holder.setLoclistsTableBaseSym(
744*b5893f02SDimitry Andric Asm->createTempSymbol("loclists_table_base"));
745*b5893f02SDimitry Andric
746*b5893f02SDimitry Andric if (useSplitDwarf())
747*b5893f02SDimitry Andric InfoHolder.setRnglistsTableBaseSym(
748*b5893f02SDimitry Andric Asm->createTempSymbol("rnglists_dwo_table_base"));
749*b5893f02SDimitry Andric }
750*b5893f02SDimitry Andric
751*b5893f02SDimitry Andric // Create the symbol that points to the first entry following the debug
752*b5893f02SDimitry Andric // address table (.debug_addr) header.
753*b5893f02SDimitry Andric AddrPool.setLabel(Asm->createTempSymbol("addr_table_base"));
7544ba319b5SDimitry Andric
7553ca95b02SDimitry Andric for (DICompileUnit *CUNode : M->debug_compile_units()) {
7562cab237bSDimitry Andric // FIXME: Move local imported entities into a list attached to the
7572cab237bSDimitry Andric // subprogram, then this search won't be needed and a
7582cab237bSDimitry Andric // getImportedEntities().empty() test should go below with the rest.
7592cab237bSDimitry Andric bool HasNonLocalImportedEntities = llvm::any_of(
7602cab237bSDimitry Andric CUNode->getImportedEntities(), [](const DIImportedEntity *IE) {
7612cab237bSDimitry Andric return !isa<DILocalScope>(IE->getScope());
7622cab237bSDimitry Andric });
7632cab237bSDimitry Andric
7642cab237bSDimitry Andric if (!HasNonLocalImportedEntities && CUNode->getEnumTypes().empty() &&
7652cab237bSDimitry Andric CUNode->getRetainedTypes().empty() &&
7662cab237bSDimitry Andric CUNode->getGlobalVariables().empty() && CUNode->getMacros().empty())
767302affcbSDimitry Andric continue;
768302affcbSDimitry Andric
769302affcbSDimitry Andric DwarfCompileUnit &CU = getOrCreateDwarfCompileUnit(CUNode);
770d88c1a5aSDimitry Andric
771d88c1a5aSDimitry Andric // Global Variables.
7722cab237bSDimitry Andric for (auto *GVE : CUNode->getGlobalVariables()) {
7732cab237bSDimitry Andric // Don't bother adding DIGlobalVariableExpressions listed in the CU if we
7742cab237bSDimitry Andric // already know about the variable and it isn't adding a constant
7752cab237bSDimitry Andric // expression.
7762cab237bSDimitry Andric auto &GVMapEntry = GVMap[GVE->getVariable()];
7772cab237bSDimitry Andric auto *Expr = GVE->getExpression();
7782cab237bSDimitry Andric if (!GVMapEntry.size() || (Expr && Expr->isConstant()))
7792cab237bSDimitry Andric GVMapEntry.push_back({nullptr, Expr});
7802cab237bSDimitry Andric }
781d88c1a5aSDimitry Andric DenseSet<DIGlobalVariable *> Processed;
782d88c1a5aSDimitry Andric for (auto *GVE : CUNode->getGlobalVariables()) {
783d88c1a5aSDimitry Andric DIGlobalVariable *GV = GVE->getVariable();
784d88c1a5aSDimitry Andric if (Processed.insert(GV).second)
785d88c1a5aSDimitry Andric CU.getOrCreateGlobalVariableDIE(GV, sortGlobalExprs(GVMap[GV]));
786d88c1a5aSDimitry Andric }
787d88c1a5aSDimitry Andric
788ff0cc061SDimitry Andric for (auto *Ty : CUNode->getEnumTypes()) {
78939d628a0SDimitry Andric // The enum types array by design contains pointers to
79039d628a0SDimitry Andric // MDNodes rather than DIRefs. Unique them here.
7913ca95b02SDimitry Andric CU.getOrCreateTypeDIE(cast<DIType>(Ty));
79239d628a0SDimitry Andric }
793ff0cc061SDimitry Andric for (auto *Ty : CUNode->getRetainedTypes()) {
79491bc56edSDimitry Andric // The retained types array by design contains pointers to
79591bc56edSDimitry Andric // MDNodes rather than DIRefs. Unique them here.
7963ca95b02SDimitry Andric if (DIType *RT = dyn_cast<DIType>(Ty))
7977d523365SDimitry Andric // There is no point in force-emitting a forward declaration.
7987d523365SDimitry Andric CU.getOrCreateTypeDIE(RT);
79991bc56edSDimitry Andric }
800284c1978SDimitry Andric // Emit imported_modules last so that the relevant context is already
801284c1978SDimitry Andric // available.
802ff0cc061SDimitry Andric for (auto *IE : CUNode->getImportedEntities())
803ff0cc061SDimitry Andric constructAndAddImportedEntityDIE(CU, IE);
804139f7f9bSDimitry Andric }
805f22ef01cSRoman Divacky }
806f22ef01cSRoman Divacky
finishEntityDefinitions()807*b5893f02SDimitry Andric void DwarfDebug::finishEntityDefinitions() {
808*b5893f02SDimitry Andric for (const auto &Entity : ConcreteEntities) {
809*b5893f02SDimitry Andric DIE *Die = Entity->getDIE();
810*b5893f02SDimitry Andric assert(Die);
81191bc56edSDimitry Andric // FIXME: Consider the time-space tradeoff of just storing the unit pointer
812*b5893f02SDimitry Andric // in the ConcreteEntities list, rather than looking it up again here.
81391bc56edSDimitry Andric // DIE::getUnit isn't simple - it walks parent pointers, etc.
814*b5893f02SDimitry Andric DwarfCompileUnit *Unit = CUDieMap.lookup(Die->getUnitDie());
81591bc56edSDimitry Andric assert(Unit);
816*b5893f02SDimitry Andric Unit->finishEntityDefinition(Entity.get());
817139f7f9bSDimitry Andric }
818139f7f9bSDimitry Andric }
819139f7f9bSDimitry Andric
finishSubprogramDefinitions()82091bc56edSDimitry Andric void DwarfDebug::finishSubprogramDefinitions() {
821302affcbSDimitry Andric for (const DISubprogram *SP : ProcessedSPNodes) {
822302affcbSDimitry Andric assert(SP->getUnit()->getEmissionKind() != DICompileUnit::NoDebug);
823302affcbSDimitry Andric forBothCUs(
824302affcbSDimitry Andric getOrCreateDwarfCompileUnit(SP->getUnit()),
825302affcbSDimitry Andric [&](DwarfCompileUnit &CU) { CU.finishSubprogramDefinition(SP); });
826302affcbSDimitry Andric }
82791bc56edSDimitry Andric }
82891bc56edSDimitry Andric
finalizeModuleInfo()829139f7f9bSDimitry Andric void DwarfDebug::finalizeModuleInfo() {
830ff0cc061SDimitry Andric const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
831ff0cc061SDimitry Andric
83291bc56edSDimitry Andric finishSubprogramDefinitions();
83391bc56edSDimitry Andric
834*b5893f02SDimitry Andric finishEntityDefinitions();
83591bc56edSDimitry Andric
836302affcbSDimitry Andric // Include the DWO file name in the hash if there's more than one CU.
837302affcbSDimitry Andric // This handles ThinLTO's situation where imported CUs may very easily be
838302affcbSDimitry Andric // duplicate with the same CU partially imported into another ThinLTO unit.
839302affcbSDimitry Andric StringRef DWOName;
840302affcbSDimitry Andric if (CUMap.size() > 1)
841302affcbSDimitry Andric DWOName = Asm->TM.Options.MCOptions.SplitDwarfFile;
842302affcbSDimitry Andric
84391bc56edSDimitry Andric // Handle anything that needs to be done on a per-unit basis after
84491bc56edSDimitry Andric // all other generation.
84539d628a0SDimitry Andric for (const auto &P : CUMap) {
84639d628a0SDimitry Andric auto &TheCU = *P.second;
847*b5893f02SDimitry Andric if (TheCU.getCUNode()->isDebugDirectivesOnly())
848*b5893f02SDimitry Andric continue;
8496122f3e6SDimitry Andric // Emit DW_AT_containing_type attribute to connect types with their
8506122f3e6SDimitry Andric // vtable holding type.
85139d628a0SDimitry Andric TheCU.constructContainingTypeDIEs();
852f785676fSDimitry Andric
85391bc56edSDimitry Andric // Add CU specific attributes if we need to add any.
854f785676fSDimitry Andric // If we're splitting the dwarf out now that we've got the entire
85591bc56edSDimitry Andric // CU then add the dwo id to it.
85639d628a0SDimitry Andric auto *SkCU = TheCU.getSkeleton();
857*b5893f02SDimitry Andric if (useSplitDwarf() && !empty(TheCU.getUnitDie().children())) {
858*b5893f02SDimitry Andric finishUnitAttributes(TheCU.getCUNode(), TheCU);
859*b5893f02SDimitry Andric TheCU.addString(TheCU.getUnitDie(), dwarf::DW_AT_GNU_dwo_name,
860*b5893f02SDimitry Andric Asm->TM.Options.MCOptions.SplitDwarfFile);
861*b5893f02SDimitry Andric SkCU->addString(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_name,
862*b5893f02SDimitry Andric Asm->TM.Options.MCOptions.SplitDwarfFile);
86391bc56edSDimitry Andric // Emit a unique identifier for this CU.
864302affcbSDimitry Andric uint64_t ID =
865302affcbSDimitry Andric DIEHash(Asm).computeCUSignature(DWOName, TheCU.getUnitDie());
8664ba319b5SDimitry Andric if (getDwarfVersion() >= 5) {
8674ba319b5SDimitry Andric TheCU.setDWOId(ID);
8684ba319b5SDimitry Andric SkCU->setDWOId(ID);
8694ba319b5SDimitry Andric } else {
87039d628a0SDimitry Andric TheCU.addUInt(TheCU.getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
87191bc56edSDimitry Andric dwarf::DW_FORM_data8, ID);
87291bc56edSDimitry Andric SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
87391bc56edSDimitry Andric dwarf::DW_FORM_data8, ID);
8744ba319b5SDimitry Andric }
875*b5893f02SDimitry Andric
876*b5893f02SDimitry Andric if (getDwarfVersion() < 5 && !SkeletonHolder.getRangeLists().empty()) {
877ff0cc061SDimitry Andric const MCSymbol *Sym = TLOF.getDwarfRangesSection()->getBeginSymbol();
87839d628a0SDimitry Andric SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_ranges_base,
879ff0cc061SDimitry Andric Sym, Sym);
880ff0cc061SDimitry Andric }
881*b5893f02SDimitry Andric } else if (SkCU) {
882*b5893f02SDimitry Andric finishUnitAttributes(SkCU->getCUNode(), *SkCU);
883f785676fSDimitry Andric }
88491bc56edSDimitry Andric
88591bc56edSDimitry Andric // If we have code split among multiple sections or non-contiguous
88691bc56edSDimitry Andric // ranges of code then emit a DW_AT_ranges attribute on the unit that will
88791bc56edSDimitry Andric // remain in the .o file, otherwise add a DW_AT_low_pc.
88891bc56edSDimitry Andric // FIXME: We should use ranges allow reordering of code ala
88991bc56edSDimitry Andric // .subsections_via_symbols in mach-o. This would mean turning on
89091bc56edSDimitry Andric // ranges for all subprogram DIEs for mach-o.
89139d628a0SDimitry Andric DwarfCompileUnit &U = SkCU ? *SkCU : TheCU;
892*b5893f02SDimitry Andric
893*b5893f02SDimitry Andric // We don't keep track of which addresses are used in which CU so this
894*b5893f02SDimitry Andric // is a bit pessimistic under LTO.
895*b5893f02SDimitry Andric if (!AddrPool.isEmpty() &&
896*b5893f02SDimitry Andric (getDwarfVersion() >= 5 ||
897*b5893f02SDimitry Andric (SkCU && !empty(TheCU.getUnitDie().children()))))
898*b5893f02SDimitry Andric U.addAddrTableBase();
899*b5893f02SDimitry Andric
90039d628a0SDimitry Andric if (unsigned NumRanges = TheCU.getRanges().size()) {
9014ba319b5SDimitry Andric if (NumRanges > 1 && useRangesSection())
90291bc56edSDimitry Andric // A DW_AT_low_pc attribute may also be specified in combination with
90391bc56edSDimitry Andric // DW_AT_ranges to specify the default base address for use in
90491bc56edSDimitry Andric // location lists (see Section 2.6.2) and range lists (see Section
90591bc56edSDimitry Andric // 2.17.3).
90639d628a0SDimitry Andric U.addUInt(U.getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, 0);
90739d628a0SDimitry Andric else
908ff0cc061SDimitry Andric U.setBaseAddress(TheCU.getRanges().front().getStart());
90939d628a0SDimitry Andric U.attachRangesOrLowHighPC(U.getUnitDie(), TheCU.takeRanges());
910f785676fSDimitry Andric }
911444ed5c5SDimitry Andric
912*b5893f02SDimitry Andric if (getDwarfVersion() >= 5) {
913*b5893f02SDimitry Andric if (U.hasRangeLists())
9144ba319b5SDimitry Andric U.addRnglistsBase();
9154ba319b5SDimitry Andric
916*b5893f02SDimitry Andric if (!DebugLocs.getLists().empty() && !useSplitDwarf())
917*b5893f02SDimitry Andric U.addLoclistsBase();
918*b5893f02SDimitry Andric }
919*b5893f02SDimitry Andric
920444ed5c5SDimitry Andric auto *CUNode = cast<DICompileUnit>(P.first);
9213ca95b02SDimitry Andric // If compile Unit has macros, emit "DW_AT_macro_info" attribute.
9223ca95b02SDimitry Andric if (CUNode->getMacros())
9233ca95b02SDimitry Andric U.addSectionLabel(U.getUnitDie(), dwarf::DW_AT_macro_info,
9243ca95b02SDimitry Andric U.getMacroLabelBegin(),
9253ca95b02SDimitry Andric TLOF.getDwarfMacinfoSection()->getBeginSymbol());
926f22ef01cSRoman Divacky }
927f22ef01cSRoman Divacky
9282cab237bSDimitry Andric // Emit all frontend-produced Skeleton CUs, i.e., Clang modules.
9292cab237bSDimitry Andric for (auto *CUNode : MMI->getModule()->debug_compile_units())
9302cab237bSDimitry Andric if (CUNode->getDWOId())
9312cab237bSDimitry Andric getOrCreateDwarfCompileUnit(CUNode);
9322cab237bSDimitry Andric
933139f7f9bSDimitry Andric // Compute DIE offsets and sizes.
934139f7f9bSDimitry Andric InfoHolder.computeSizeAndOffsets();
935139f7f9bSDimitry Andric if (useSplitDwarf())
936139f7f9bSDimitry Andric SkeletonHolder.computeSizeAndOffsets();
937139f7f9bSDimitry Andric }
938139f7f9bSDimitry Andric
939139f7f9bSDimitry Andric // Emit all Dwarf sections that should come after the content.
endModule()940139f7f9bSDimitry Andric void DwarfDebug::endModule() {
94191bc56edSDimitry Andric assert(CurFn == nullptr);
94291bc56edSDimitry Andric assert(CurMI == nullptr);
943f22ef01cSRoman Divacky
94439d628a0SDimitry Andric // If we aren't actually generating debug info (check beginModule -
94539d628a0SDimitry Andric // conditionalized on !DisableDebugInfoPrinting and the presence of the
94639d628a0SDimitry Andric // llvm.dbg.cu metadata node)
947ff0cc061SDimitry Andric if (!MMI->hasDebugInfo())
94891bc56edSDimitry Andric return;
949139f7f9bSDimitry Andric
950139f7f9bSDimitry Andric // Finalize the debug info for the module.
951139f7f9bSDimitry Andric finalizeModuleInfo();
952139f7f9bSDimitry Andric
953f785676fSDimitry Andric emitDebugStr();
954f785676fSDimitry Andric
955ff0cc061SDimitry Andric if (useSplitDwarf())
956ff0cc061SDimitry Andric emitDebugLocDWO();
957ff0cc061SDimitry Andric else
958ff0cc061SDimitry Andric // Emit info into a debug loc section.
959ff0cc061SDimitry Andric emitDebugLoc();
960f22ef01cSRoman Divacky
961f22ef01cSRoman Divacky // Corresponding abbreviations into a abbrev section.
962f22ef01cSRoman Divacky emitAbbreviations();
963f22ef01cSRoman Divacky
964ff0cc061SDimitry Andric // Emit all the DIEs into a debug info section.
965ff0cc061SDimitry Andric emitDebugInfo();
966ff0cc061SDimitry Andric
967f22ef01cSRoman Divacky // Emit info into a debug aranges section.
96891bc56edSDimitry Andric if (GenerateARangeSection)
969139f7f9bSDimitry Andric emitDebugARanges();
970f22ef01cSRoman Divacky
971f22ef01cSRoman Divacky // Emit info into a debug ranges section.
972f22ef01cSRoman Divacky emitDebugRanges();
973f22ef01cSRoman Divacky
974444ed5c5SDimitry Andric // Emit info into a debug macinfo section.
975444ed5c5SDimitry Andric emitDebugMacinfo();
976444ed5c5SDimitry Andric
97791bc56edSDimitry Andric if (useSplitDwarf()) {
978f785676fSDimitry Andric emitDebugStrDWO();
979139f7f9bSDimitry Andric emitDebugInfoDWO();
980139f7f9bSDimitry Andric emitDebugAbbrevDWO();
98191bc56edSDimitry Andric emitDebugLineDWO();
982*b5893f02SDimitry Andric emitDebugRangesDWO();
983ff0cc061SDimitry Andric }
984139f7f9bSDimitry Andric
985*b5893f02SDimitry Andric emitDebugAddr();
986*b5893f02SDimitry Andric
987139f7f9bSDimitry Andric // Emit info into the dwarf accelerator table sections.
9884ba319b5SDimitry Andric switch (getAccelTableKind()) {
9894ba319b5SDimitry Andric case AccelTableKind::Apple:
990139f7f9bSDimitry Andric emitAccelNames();
991139f7f9bSDimitry Andric emitAccelObjC();
992139f7f9bSDimitry Andric emitAccelNamespaces();
993139f7f9bSDimitry Andric emitAccelTypes();
9944ba319b5SDimitry Andric break;
9954ba319b5SDimitry Andric case AccelTableKind::Dwarf:
9964ba319b5SDimitry Andric emitAccelDebugNames();
9974ba319b5SDimitry Andric break;
9984ba319b5SDimitry Andric case AccelTableKind::None:
9994ba319b5SDimitry Andric break;
10004ba319b5SDimitry Andric case AccelTableKind::Default:
10014ba319b5SDimitry Andric llvm_unreachable("Default should have already been resolved.");
1002139f7f9bSDimitry Andric }
1003139f7f9bSDimitry Andric
1004f785676fSDimitry Andric // Emit the pubnames and pubtypes sections if requested.
10052cab237bSDimitry Andric emitDebugPubSections();
1006f22ef01cSRoman Divacky
1007e580952dSDimitry Andric // clean up.
10085517e702SDimitry Andric // FIXME: AbstractVariables.clear();
1009f22ef01cSRoman Divacky }
1010f22ef01cSRoman Divacky
ensureAbstractEntityIsCreated(DwarfCompileUnit & CU,const DINode * Node,const MDNode * ScopeNode)1011*b5893f02SDimitry Andric void DwarfDebug::ensureAbstractEntityIsCreated(DwarfCompileUnit &CU,
1012*b5893f02SDimitry Andric const DINode *Node,
101391bc56edSDimitry Andric const MDNode *ScopeNode) {
1014*b5893f02SDimitry Andric if (CU.getExistingAbstractEntity(Node))
101591bc56edSDimitry Andric return;
101691bc56edSDimitry Andric
1017*b5893f02SDimitry Andric CU.createAbstractEntity(Node, LScopes.getOrCreateAbstractScope(
1018ff0cc061SDimitry Andric cast<DILocalScope>(ScopeNode)));
101991bc56edSDimitry Andric }
102091bc56edSDimitry Andric
ensureAbstractEntityIsCreatedIfScoped(DwarfCompileUnit & CU,const DINode * Node,const MDNode * ScopeNode)1021*b5893f02SDimitry Andric void DwarfDebug::ensureAbstractEntityIsCreatedIfScoped(DwarfCompileUnit &CU,
1022*b5893f02SDimitry Andric const DINode *Node, const MDNode *ScopeNode) {
1023*b5893f02SDimitry Andric if (CU.getExistingAbstractEntity(Node))
102491bc56edSDimitry Andric return;
102591bc56edSDimitry Andric
1026ff0cc061SDimitry Andric if (LexicalScope *Scope =
1027ff0cc061SDimitry Andric LScopes.findAbstractScope(cast_or_null<DILocalScope>(ScopeNode)))
1028*b5893f02SDimitry Andric CU.createAbstractEntity(Node, Scope);
1029f22ef01cSRoman Divacky }
10302cab237bSDimitry Andric
1031d88c1a5aSDimitry Andric // Collect variable information from side table maintained by MF.
collectVariableInfoFromMFTable(DwarfCompileUnit & TheCU,DenseSet<InlinedEntity> & Processed)1032d88c1a5aSDimitry Andric void DwarfDebug::collectVariableInfoFromMFTable(
1033*b5893f02SDimitry Andric DwarfCompileUnit &TheCU, DenseSet<InlinedEntity> &Processed) {
1034*b5893f02SDimitry Andric SmallDenseMap<InlinedEntity, DbgVariable *> MFVars;
1035d88c1a5aSDimitry Andric for (const auto &VI : Asm->MF->getVariableDbgInfo()) {
103691bc56edSDimitry Andric if (!VI.Var)
103791bc56edSDimitry Andric continue;
1038ff0cc061SDimitry Andric assert(VI.Var->isValidLocationForIntrinsic(VI.Loc) &&
1039ff0cc061SDimitry Andric "Expected inlined-at fields to agree");
1040ff0cc061SDimitry Andric
1041*b5893f02SDimitry Andric InlinedEntity Var(VI.Var, VI.Loc->getInlinedAt());
1042ff0cc061SDimitry Andric Processed.insert(Var);
104391bc56edSDimitry Andric LexicalScope *Scope = LScopes.findLexicalScope(VI.Loc);
1044f22ef01cSRoman Divacky
1045f22ef01cSRoman Divacky // If variable scope is not found then skip this variable.
104691bc56edSDimitry Andric if (!Scope)
1047f22ef01cSRoman Divacky continue;
1048f22ef01cSRoman Divacky
1049*b5893f02SDimitry Andric ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first, Scope->getScopeNode());
1050*b5893f02SDimitry Andric auto RegVar = llvm::make_unique<DbgVariable>(
1051*b5893f02SDimitry Andric cast<DILocalVariable>(Var.first), Var.second);
10523dac3a9bSDimitry Andric RegVar->initializeMMI(VI.Expr, VI.Slot);
10532cab237bSDimitry Andric if (DbgVariable *DbgVar = MFVars.lookup(Var))
10542cab237bSDimitry Andric DbgVar->addMMIEntry(*RegVar);
10552cab237bSDimitry Andric else if (InfoHolder.addScopeVariable(Scope, RegVar.get())) {
10562cab237bSDimitry Andric MFVars.insert({Var, RegVar.get()});
1057*b5893f02SDimitry Andric ConcreteEntities.push_back(std::move(RegVar));
1058f22ef01cSRoman Divacky }
1059f22ef01cSRoman Divacky }
10602cab237bSDimitry Andric }
1061f22ef01cSRoman Divacky
1062139f7f9bSDimitry Andric // Get .debug_loc entry for the instruction range starting at MI.
getDebugLocValue(const MachineInstr * MI)106391bc56edSDimitry Andric static DebugLocEntry::Value getDebugLocValue(const MachineInstr *MI) {
1064ff0cc061SDimitry Andric const DIExpression *Expr = MI->getDebugExpression();
106539d628a0SDimitry Andric assert(MI->getNumOperands() == 4);
1066f785676fSDimitry Andric if (MI->getOperand(0).isReg()) {
10672cab237bSDimitry Andric auto RegOp = MI->getOperand(0);
10682cab237bSDimitry Andric auto Op1 = MI->getOperand(1);
1069f785676fSDimitry Andric // If the second operand is an immediate, this is a
1070f785676fSDimitry Andric // register-indirect address.
10712cab237bSDimitry Andric assert((!Op1.isImm() || (Op1.getImm() == 0)) && "unexpected offset");
10722cab237bSDimitry Andric MachineLocation MLoc(RegOp.getReg(), Op1.isImm());
1073ff0cc061SDimitry Andric return DebugLocEntry::Value(Expr, MLoc);
107417a519f9SDimitry Andric }
107517a519f9SDimitry Andric if (MI->getOperand(0).isImm())
1076ff0cc061SDimitry Andric return DebugLocEntry::Value(Expr, MI->getOperand(0).getImm());
107717a519f9SDimitry Andric if (MI->getOperand(0).isFPImm())
1078ff0cc061SDimitry Andric return DebugLocEntry::Value(Expr, MI->getOperand(0).getFPImm());
107917a519f9SDimitry Andric if (MI->getOperand(0).isCImm())
1080ff0cc061SDimitry Andric return DebugLocEntry::Value(Expr, MI->getOperand(0).getCImm());
108117a519f9SDimitry Andric
108239d628a0SDimitry Andric llvm_unreachable("Unexpected 4-operand DBG_VALUE instruction!");
108317a519f9SDimitry Andric }
108417a519f9SDimitry Andric
10854ba319b5SDimitry Andric /// If this and Next are describing different fragments of the same
108647d45e34SDimitry Andric /// variable, merge them by appending Next's values to the current
108747d45e34SDimitry Andric /// list of values.
108847d45e34SDimitry Andric /// Return true if the merge was successful.
MergeValues(const DebugLocEntry & Next)108947d45e34SDimitry Andric bool DebugLocEntry::MergeValues(const DebugLocEntry &Next) {
109047d45e34SDimitry Andric if (Begin == Next.Begin) {
1091a8bcc4d8SDimitry Andric auto *FirstExpr = cast<DIExpression>(Values[0].Expression);
1092a8bcc4d8SDimitry Andric auto *FirstNextExpr = cast<DIExpression>(Next.Values[0].Expression);
1093d88c1a5aSDimitry Andric if (!FirstExpr->isFragment() || !FirstNextExpr->isFragment())
1094a8bcc4d8SDimitry Andric return false;
1095a8bcc4d8SDimitry Andric
1096d88c1a5aSDimitry Andric // We can only merge entries if none of the fragments overlap any others.
1097a8bcc4d8SDimitry Andric // In doing so, we can take advantage of the fact that both lists are
1098a8bcc4d8SDimitry Andric // sorted.
1099a8bcc4d8SDimitry Andric for (unsigned i = 0, j = 0; i < Values.size(); ++i) {
1100a8bcc4d8SDimitry Andric for (; j < Next.Values.size(); ++j) {
11014ba319b5SDimitry Andric int res = cast<DIExpression>(Values[i].Expression)->fragmentCmp(
1102a8bcc4d8SDimitry Andric cast<DIExpression>(Next.Values[j].Expression));
1103a8bcc4d8SDimitry Andric if (res == 0) // The two expressions overlap, we can't merge.
1104a8bcc4d8SDimitry Andric return false;
1105a8bcc4d8SDimitry Andric // Values[i] is entirely before Next.Values[j],
1106a8bcc4d8SDimitry Andric // so go back to the next entry of Values.
1107a8bcc4d8SDimitry Andric else if (res == -1)
1108a8bcc4d8SDimitry Andric break;
1109a8bcc4d8SDimitry Andric // Next.Values[j] is entirely before Values[i], so go on to the
1110a8bcc4d8SDimitry Andric // next entry of Next.Values.
1111a8bcc4d8SDimitry Andric }
1112a8bcc4d8SDimitry Andric }
1113a8bcc4d8SDimitry Andric
111447d45e34SDimitry Andric addValues(Next.Values);
111547d45e34SDimitry Andric End = Next.End;
111647d45e34SDimitry Andric return true;
111747d45e34SDimitry Andric }
111847d45e34SDimitry Andric return false;
111947d45e34SDimitry Andric }
112047d45e34SDimitry Andric
112139d628a0SDimitry Andric /// Build the location list for all DBG_VALUEs in the function that
112239d628a0SDimitry Andric /// describe the same variable. If the ranges of several independent
1123d88c1a5aSDimitry Andric /// fragments of the same variable overlap partially, split them up and
112439d628a0SDimitry Andric /// combine the ranges. The resulting DebugLocEntries are will have
112539d628a0SDimitry Andric /// strict monotonically increasing begin addresses and will never
112639d628a0SDimitry Andric /// overlap.
112739d628a0SDimitry Andric //
112839d628a0SDimitry Andric // Input:
112939d628a0SDimitry Andric //
1130d88c1a5aSDimitry Andric // Ranges History [var, loc, fragment ofs size]
1131d88c1a5aSDimitry Andric // 0 | [x, (reg0, fragment 0, 32)]
1132d88c1a5aSDimitry Andric // 1 | | [x, (reg1, fragment 32, 32)] <- IsFragmentOfPrevEntry
113339d628a0SDimitry Andric // 2 | | ...
113439d628a0SDimitry Andric // 3 | [clobber reg0]
1135d88c1a5aSDimitry Andric // 4 [x, (mem, fragment 0, 64)] <- overlapping with both previous fragments of
1136ff0cc061SDimitry Andric // x.
113739d628a0SDimitry Andric //
113839d628a0SDimitry Andric // Output:
113939d628a0SDimitry Andric //
1140d88c1a5aSDimitry Andric // [0-1] [x, (reg0, fragment 0, 32)]
1141d88c1a5aSDimitry Andric // [1-3] [x, (reg0, fragment 0, 32), (reg1, fragment 32, 32)]
1142d88c1a5aSDimitry Andric // [3-4] [x, (reg1, fragment 32, 32)]
1143d88c1a5aSDimitry Andric // [4- ] [x, (mem, fragment 0, 64)]
114439d628a0SDimitry Andric void
buildLocationList(SmallVectorImpl<DebugLocEntry> & DebugLoc,const DbgValueHistoryMap::InstrRanges & Ranges)114539d628a0SDimitry Andric DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
114639d628a0SDimitry Andric const DbgValueHistoryMap::InstrRanges &Ranges) {
114739d628a0SDimitry Andric SmallVector<DebugLocEntry::Value, 4> OpenRanges;
114839d628a0SDimitry Andric
114939d628a0SDimitry Andric for (auto I = Ranges.begin(), E = Ranges.end(); I != E; ++I) {
115039d628a0SDimitry Andric const MachineInstr *Begin = I->first;
115139d628a0SDimitry Andric const MachineInstr *End = I->second;
115239d628a0SDimitry Andric assert(Begin->isDebugValue() && "Invalid History entry");
115339d628a0SDimitry Andric
115439d628a0SDimitry Andric // Check if a variable is inaccessible in this range.
115539d628a0SDimitry Andric if (Begin->getNumOperands() > 1 &&
115639d628a0SDimitry Andric Begin->getOperand(0).isReg() && !Begin->getOperand(0).getReg()) {
115739d628a0SDimitry Andric OpenRanges.clear();
115839d628a0SDimitry Andric continue;
115939d628a0SDimitry Andric }
116039d628a0SDimitry Andric
1161d88c1a5aSDimitry Andric // If this fragment overlaps with any open ranges, truncate them.
1162ff0cc061SDimitry Andric const DIExpression *DIExpr = Begin->getDebugExpression();
1163d88c1a5aSDimitry Andric auto Last = remove_if(OpenRanges, [&](DebugLocEntry::Value R) {
11644ba319b5SDimitry Andric return DIExpr->fragmentsOverlap(R.getExpression());
116539d628a0SDimitry Andric });
116639d628a0SDimitry Andric OpenRanges.erase(Last, OpenRanges.end());
116739d628a0SDimitry Andric
116839d628a0SDimitry Andric const MCSymbol *StartLabel = getLabelBeforeInsn(Begin);
116939d628a0SDimitry Andric assert(StartLabel && "Forgot label before DBG_VALUE starting a range!");
117039d628a0SDimitry Andric
117139d628a0SDimitry Andric const MCSymbol *EndLabel;
117239d628a0SDimitry Andric if (End != nullptr)
117339d628a0SDimitry Andric EndLabel = getLabelAfterInsn(End);
117439d628a0SDimitry Andric else if (std::next(I) == Ranges.end())
1175ff0cc061SDimitry Andric EndLabel = Asm->getFunctionEnd();
117639d628a0SDimitry Andric else
117739d628a0SDimitry Andric EndLabel = getLabelBeforeInsn(std::next(I)->first);
117839d628a0SDimitry Andric assert(EndLabel && "Forgot label after instruction ending a range!");
117939d628a0SDimitry Andric
11804ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "DotDebugLoc: " << *Begin << "\n");
118139d628a0SDimitry Andric
118239d628a0SDimitry Andric auto Value = getDebugLocValue(Begin);
1183*b5893f02SDimitry Andric
1184*b5893f02SDimitry Andric // Omit entries with empty ranges as they do not have any effect in DWARF.
1185*b5893f02SDimitry Andric if (StartLabel == EndLabel) {
1186*b5893f02SDimitry Andric // If this is a fragment, we must still add the value to the list of
1187*b5893f02SDimitry Andric // open ranges, since it may describe non-overlapping parts of the
1188*b5893f02SDimitry Andric // variable.
1189*b5893f02SDimitry Andric if (DIExpr->isFragment())
1190*b5893f02SDimitry Andric OpenRanges.push_back(Value);
1191*b5893f02SDimitry Andric LLVM_DEBUG(dbgs() << "Omitting location list entry with empty range.\n");
1192*b5893f02SDimitry Andric continue;
1193*b5893f02SDimitry Andric }
1194*b5893f02SDimitry Andric
119539d628a0SDimitry Andric DebugLocEntry Loc(StartLabel, EndLabel, Value);
119639d628a0SDimitry Andric bool couldMerge = false;
119739d628a0SDimitry Andric
1198d88c1a5aSDimitry Andric // If this is a fragment, it may belong to the current DebugLocEntry.
1199d88c1a5aSDimitry Andric if (DIExpr->isFragment()) {
120039d628a0SDimitry Andric // Add this value to the list of open ranges.
120139d628a0SDimitry Andric OpenRanges.push_back(Value);
120239d628a0SDimitry Andric
1203d88c1a5aSDimitry Andric // Attempt to add the fragment to the last entry.
120439d628a0SDimitry Andric if (!DebugLoc.empty())
120539d628a0SDimitry Andric if (DebugLoc.back().MergeValues(Loc))
120639d628a0SDimitry Andric couldMerge = true;
120739d628a0SDimitry Andric }
120839d628a0SDimitry Andric
120939d628a0SDimitry Andric if (!couldMerge) {
121039d628a0SDimitry Andric // Need to add a new DebugLocEntry. Add all values from still
1211d88c1a5aSDimitry Andric // valid non-overlapping fragments.
121239d628a0SDimitry Andric if (OpenRanges.size())
121339d628a0SDimitry Andric Loc.addValues(OpenRanges);
121439d628a0SDimitry Andric
121539d628a0SDimitry Andric DebugLoc.push_back(std::move(Loc));
121639d628a0SDimitry Andric }
121739d628a0SDimitry Andric
121839d628a0SDimitry Andric // Attempt to coalesce the ranges of two otherwise identical
121939d628a0SDimitry Andric // DebugLocEntries.
122039d628a0SDimitry Andric auto CurEntry = DebugLoc.rbegin();
12214ba319b5SDimitry Andric LLVM_DEBUG({
1222ff0cc061SDimitry Andric dbgs() << CurEntry->getValues().size() << " Values:\n";
1223ff0cc061SDimitry Andric for (auto &Value : CurEntry->getValues())
12243ca95b02SDimitry Andric Value.dump();
1225ff0cc061SDimitry Andric dbgs() << "-----\n";
1226ff0cc061SDimitry Andric });
1227ff0cc061SDimitry Andric
122839d628a0SDimitry Andric auto PrevEntry = std::next(CurEntry);
122939d628a0SDimitry Andric if (PrevEntry != DebugLoc.rend() && PrevEntry->MergeRanges(*CurEntry))
123039d628a0SDimitry Andric DebugLoc.pop_back();
123139d628a0SDimitry Andric }
123239d628a0SDimitry Andric }
123339d628a0SDimitry Andric
createConcreteEntity(DwarfCompileUnit & TheCU,LexicalScope & Scope,const DINode * Node,const DILocation * Location,const MCSymbol * Sym)1234*b5893f02SDimitry Andric DbgEntity *DwarfDebug::createConcreteEntity(DwarfCompileUnit &TheCU,
12355517e702SDimitry Andric LexicalScope &Scope,
1236*b5893f02SDimitry Andric const DINode *Node,
1237*b5893f02SDimitry Andric const DILocation *Location,
1238*b5893f02SDimitry Andric const MCSymbol *Sym) {
1239*b5893f02SDimitry Andric ensureAbstractEntityIsCreatedIfScoped(TheCU, Node, Scope.getScopeNode());
1240*b5893f02SDimitry Andric if (isa<const DILocalVariable>(Node)) {
1241*b5893f02SDimitry Andric ConcreteEntities.push_back(
1242*b5893f02SDimitry Andric llvm::make_unique<DbgVariable>(cast<const DILocalVariable>(Node),
1243*b5893f02SDimitry Andric Location));
1244*b5893f02SDimitry Andric InfoHolder.addScopeVariable(&Scope,
1245*b5893f02SDimitry Andric cast<DbgVariable>(ConcreteEntities.back().get()));
1246*b5893f02SDimitry Andric } else if (isa<const DILabel>(Node)) {
1247*b5893f02SDimitry Andric ConcreteEntities.push_back(
1248*b5893f02SDimitry Andric llvm::make_unique<DbgLabel>(cast<const DILabel>(Node),
1249*b5893f02SDimitry Andric Location, Sym));
1250*b5893f02SDimitry Andric InfoHolder.addScopeLabel(&Scope,
1251*b5893f02SDimitry Andric cast<DbgLabel>(ConcreteEntities.back().get()));
1252*b5893f02SDimitry Andric }
1253*b5893f02SDimitry Andric return ConcreteEntities.back().get();
12543dac3a9bSDimitry Andric }
125539d628a0SDimitry Andric
1256edd7eaddSDimitry Andric /// Determine whether a *singular* DBG_VALUE is valid for the entirety of its
1257edd7eaddSDimitry Andric /// enclosing lexical scope. The check ensures there are no other instructions
1258edd7eaddSDimitry Andric /// in the same lexical scope preceding the DBG_VALUE and that its range is
1259edd7eaddSDimitry Andric /// either open or otherwise rolls off the end of the scope.
validThroughout(LexicalScopes & LScopes,const MachineInstr * DbgValue,const MachineInstr * RangeEnd)1260edd7eaddSDimitry Andric static bool validThroughout(LexicalScopes &LScopes,
1261edd7eaddSDimitry Andric const MachineInstr *DbgValue,
1262edd7eaddSDimitry Andric const MachineInstr *RangeEnd) {
1263edd7eaddSDimitry Andric assert(DbgValue->getDebugLoc() && "DBG_VALUE without a debug location");
1264edd7eaddSDimitry Andric auto MBB = DbgValue->getParent();
1265edd7eaddSDimitry Andric auto DL = DbgValue->getDebugLoc();
1266edd7eaddSDimitry Andric auto *LScope = LScopes.findLexicalScope(DL);
1267edd7eaddSDimitry Andric // Scope doesn't exist; this is a dead DBG_VALUE.
1268edd7eaddSDimitry Andric if (!LScope)
12693ca95b02SDimitry Andric return false;
1270edd7eaddSDimitry Andric auto &LSRange = LScope->getRanges();
1271edd7eaddSDimitry Andric if (LSRange.size() == 0)
12723ca95b02SDimitry Andric return false;
1273edd7eaddSDimitry Andric
1274edd7eaddSDimitry Andric // Determine if the DBG_VALUE is valid at the beginning of its lexical block.
1275edd7eaddSDimitry Andric const MachineInstr *LScopeBegin = LSRange.front().first;
1276edd7eaddSDimitry Andric // Early exit if the lexical scope begins outside of the current block.
1277edd7eaddSDimitry Andric if (LScopeBegin->getParent() != MBB)
1278edd7eaddSDimitry Andric return false;
1279edd7eaddSDimitry Andric MachineBasicBlock::const_reverse_iterator Pred(DbgValue);
1280edd7eaddSDimitry Andric for (++Pred; Pred != MBB->rend(); ++Pred) {
1281edd7eaddSDimitry Andric if (Pred->getFlag(MachineInstr::FrameSetup))
1282edd7eaddSDimitry Andric break;
1283edd7eaddSDimitry Andric auto PredDL = Pred->getDebugLoc();
1284edd7eaddSDimitry Andric if (!PredDL || Pred->isMetaInstruction())
1285edd7eaddSDimitry Andric continue;
1286edd7eaddSDimitry Andric // Check whether the instruction preceding the DBG_VALUE is in the same
1287edd7eaddSDimitry Andric // (sub)scope as the DBG_VALUE.
1288edd7eaddSDimitry Andric if (DL->getScope() == PredDL->getScope())
1289edd7eaddSDimitry Andric return false;
1290edd7eaddSDimitry Andric auto *PredScope = LScopes.findLexicalScope(PredDL);
1291edd7eaddSDimitry Andric if (!PredScope || LScope->dominates(PredScope))
1292edd7eaddSDimitry Andric return false;
1293edd7eaddSDimitry Andric }
1294edd7eaddSDimitry Andric
1295edd7eaddSDimitry Andric // If the range of the DBG_VALUE is open-ended, report success.
1296edd7eaddSDimitry Andric if (!RangeEnd)
12973ca95b02SDimitry Andric return true;
1298edd7eaddSDimitry Andric
1299edd7eaddSDimitry Andric // Fail if there are instructions belonging to our scope in another block.
1300edd7eaddSDimitry Andric const MachineInstr *LScopeEnd = LSRange.back().second;
1301edd7eaddSDimitry Andric if (LScopeEnd->getParent() != MBB)
1302edd7eaddSDimitry Andric return false;
1303edd7eaddSDimitry Andric
1304edd7eaddSDimitry Andric // Single, constant DBG_VALUEs in the prologue are promoted to be live
1305edd7eaddSDimitry Andric // throughout the function. This is a hack, presumably for DWARF v2 and not
1306edd7eaddSDimitry Andric // necessarily correct. It would be much better to use a dbg.declare instead
1307edd7eaddSDimitry Andric // if we know the constant is live throughout the scope.
1308edd7eaddSDimitry Andric if (DbgValue->getOperand(0).isImm() && MBB->pred_empty())
1309edd7eaddSDimitry Andric return true;
1310edd7eaddSDimitry Andric
1311edd7eaddSDimitry Andric return false;
13123ca95b02SDimitry Andric }
13133ca95b02SDimitry Andric
1314139f7f9bSDimitry Andric // Find variables for each lexical scope.
collectEntityInfo(DwarfCompileUnit & TheCU,const DISubprogram * SP,DenseSet<InlinedEntity> & Processed)1315*b5893f02SDimitry Andric void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
1316ff0cc061SDimitry Andric const DISubprogram *SP,
1317*b5893f02SDimitry Andric DenseSet<InlinedEntity> &Processed) {
1318f785676fSDimitry Andric // Grab the variable info that was squirreled away in the MMI side-table.
13195517e702SDimitry Andric collectVariableInfoFromMFTable(TheCU, Processed);
1320f22ef01cSRoman Divacky
132191bc56edSDimitry Andric for (const auto &I : DbgValues) {
1322*b5893f02SDimitry Andric InlinedEntity IV = I.first;
1323ff0cc061SDimitry Andric if (Processed.count(IV))
1324f22ef01cSRoman Divacky continue;
1325f22ef01cSRoman Divacky
1326ff0cc061SDimitry Andric // Instruction ranges, specifying where IV is accessible.
132791bc56edSDimitry Andric const auto &Ranges = I.second;
132891bc56edSDimitry Andric if (Ranges.empty())
13293b0f4066SDimitry Andric continue;
1330f22ef01cSRoman Divacky
133191bc56edSDimitry Andric LexicalScope *Scope = nullptr;
1332*b5893f02SDimitry Andric const DILocalVariable *LocalVar = cast<DILocalVariable>(IV.first);
1333ff0cc061SDimitry Andric if (const DILocation *IA = IV.second)
1334*b5893f02SDimitry Andric Scope = LScopes.findInlinedScope(LocalVar->getScope(), IA);
1335ff0cc061SDimitry Andric else
1336*b5893f02SDimitry Andric Scope = LScopes.findLexicalScope(LocalVar->getScope());
1337f22ef01cSRoman Divacky // If variable scope is not found then skip this variable.
1338f22ef01cSRoman Divacky if (!Scope)
1339f22ef01cSRoman Divacky continue;
1340f22ef01cSRoman Divacky
1341ff0cc061SDimitry Andric Processed.insert(IV);
1342*b5893f02SDimitry Andric DbgVariable *RegVar = cast<DbgVariable>(createConcreteEntity(TheCU,
1343*b5893f02SDimitry Andric *Scope, LocalVar, IV.second));
13443dac3a9bSDimitry Andric
134591bc56edSDimitry Andric const MachineInstr *MInsn = Ranges.front().first;
13463b0f4066SDimitry Andric assert(MInsn->isDebugValue() && "History must begin with debug value");
13473b0f4066SDimitry Andric
1348edd7eaddSDimitry Andric // Check if there is a single DBG_VALUE, valid throughout the var's scope.
13493ca95b02SDimitry Andric if (Ranges.size() == 1 &&
1350edd7eaddSDimitry Andric validThroughout(LScopes, MInsn, Ranges.front().second)) {
13513dac3a9bSDimitry Andric RegVar->initializeDbgValue(MInsn);
1352f22ef01cSRoman Divacky continue;
13533dac3a9bSDimitry Andric }
13544ba319b5SDimitry Andric // Do not emit location lists if .debug_loc secton is disabled.
13554ba319b5SDimitry Andric if (!useLocSection())
13564ba319b5SDimitry Andric continue;
1357f22ef01cSRoman Divacky
1358139f7f9bSDimitry Andric // Handle multiple DBG_VALUE instructions describing one variable.
13593dac3a9bSDimitry Andric DebugLocStream::ListBuilder List(DebugLocs, TheCU, *Asm, *RegVar, *MInsn);
1360e580952dSDimitry Andric
136139d628a0SDimitry Andric // Build the location list for this variable.
1362ff0cc061SDimitry Andric SmallVector<DebugLocEntry, 8> Entries;
1363ff0cc061SDimitry Andric buildLocationList(Entries, Ranges);
1364ff0cc061SDimitry Andric
13653ca95b02SDimitry Andric // If the variable has a DIBasicType, extract it. Basic types cannot have
1366ff0cc061SDimitry Andric // unique identifiers, so don't bother resolving the type with the
1367ff0cc061SDimitry Andric // identifier map.
1368ff0cc061SDimitry Andric const DIBasicType *BT = dyn_cast<DIBasicType>(
1369*b5893f02SDimitry Andric static_cast<const Metadata *>(LocalVar->getType()));
1370ff0cc061SDimitry Andric
1371ff0cc061SDimitry Andric // Finalize the entry by lowering it into a DWARF bytestream.
1372ff0cc061SDimitry Andric for (auto &Entry : Entries)
13733dac3a9bSDimitry Andric Entry.finalize(*Asm, List, BT);
1374f22ef01cSRoman Divacky }
1375f22ef01cSRoman Divacky
1376*b5893f02SDimitry Andric // For each InlinedEntity collected from DBG_LABEL instructions, convert to
1377*b5893f02SDimitry Andric // DWARF-related DbgLabel.
1378*b5893f02SDimitry Andric for (const auto &I : DbgLabels) {
1379*b5893f02SDimitry Andric InlinedEntity IL = I.first;
1380*b5893f02SDimitry Andric const MachineInstr *MI = I.second;
1381*b5893f02SDimitry Andric if (MI == nullptr)
1382*b5893f02SDimitry Andric continue;
1383*b5893f02SDimitry Andric
1384*b5893f02SDimitry Andric LexicalScope *Scope = nullptr;
1385*b5893f02SDimitry Andric const DILabel *Label = cast<DILabel>(IL.first);
1386*b5893f02SDimitry Andric // Get inlined DILocation if it is inlined label.
1387*b5893f02SDimitry Andric if (const DILocation *IA = IL.second)
1388*b5893f02SDimitry Andric Scope = LScopes.findInlinedScope(Label->getScope(), IA);
1389*b5893f02SDimitry Andric else
1390*b5893f02SDimitry Andric Scope = LScopes.findLexicalScope(Label->getScope());
1391*b5893f02SDimitry Andric // If label scope is not found then skip this label.
1392*b5893f02SDimitry Andric if (!Scope)
1393*b5893f02SDimitry Andric continue;
1394*b5893f02SDimitry Andric
1395*b5893f02SDimitry Andric Processed.insert(IL);
1396*b5893f02SDimitry Andric /// At this point, the temporary label is created.
1397*b5893f02SDimitry Andric /// Save the temporary label to DbgLabel entity to get the
1398*b5893f02SDimitry Andric /// actually address when generating Dwarf DIE.
1399*b5893f02SDimitry Andric MCSymbol *Sym = getLabelBeforeInsn(MI);
1400*b5893f02SDimitry Andric createConcreteEntity(TheCU, *Scope, Label, IL.second, Sym);
1401f22ef01cSRoman Divacky }
1402*b5893f02SDimitry Andric
1403*b5893f02SDimitry Andric // Collect info for variables/labels that were optimized out.
1404*b5893f02SDimitry Andric for (const DINode *DN : SP->getRetainedNodes()) {
1405*b5893f02SDimitry Andric if (!Processed.insert(InlinedEntity(DN, nullptr)).second)
1406*b5893f02SDimitry Andric continue;
1407*b5893f02SDimitry Andric LexicalScope *Scope = nullptr;
1408*b5893f02SDimitry Andric if (auto *DV = dyn_cast<DILocalVariable>(DN)) {
1409*b5893f02SDimitry Andric Scope = LScopes.findLexicalScope(DV->getScope());
1410*b5893f02SDimitry Andric } else if (auto *DL = dyn_cast<DILabel>(DN)) {
1411*b5893f02SDimitry Andric Scope = LScopes.findLexicalScope(DL->getScope());
1412*b5893f02SDimitry Andric }
1413*b5893f02SDimitry Andric
1414*b5893f02SDimitry Andric if (Scope)
1415*b5893f02SDimitry Andric createConcreteEntity(TheCU, *Scope, DN, nullptr);
1416f22ef01cSRoman Divacky }
14174ba319b5SDimitry Andric }
1418f22ef01cSRoman Divacky
1419139f7f9bSDimitry Andric // Process beginning of an instruction.
beginInstruction(const MachineInstr * MI)14202754fe60SDimitry Andric void DwarfDebug::beginInstruction(const MachineInstr *MI) {
14213ca95b02SDimitry Andric DebugHandlerBase::beginInstruction(MI);
14223ca95b02SDimitry Andric assert(CurMI);
14233ca95b02SDimitry Andric
14242cab237bSDimitry Andric const auto *SP = MI->getMF()->getFunction().getSubprogram();
1425302affcbSDimitry Andric if (!SP || SP->getUnit()->getEmissionKind() == DICompileUnit::NoDebug)
1426302affcbSDimitry Andric return;
1427302affcbSDimitry Andric
1428d88c1a5aSDimitry Andric // Check if source location changes, but ignore DBG_VALUE and CFI locations.
14294ba319b5SDimitry Andric // If the instruction is part of the function frame setup code, do not emit
14304ba319b5SDimitry Andric // any line record, as there is no correspondence with any user code.
14314ba319b5SDimitry Andric if (MI->isMetaInstruction() || MI->getFlag(MachineInstr::FrameSetup))
1432d88c1a5aSDimitry Andric return;
14333ca95b02SDimitry Andric const DebugLoc &DL = MI->getDebugLoc();
1434d88c1a5aSDimitry Andric // When we emit a line-0 record, we don't update PrevInstLoc; so look at
1435d88c1a5aSDimitry Andric // the last line number actually emitted, to see if it was line 0.
1436d88c1a5aSDimitry Andric unsigned LastAsmLine =
1437d88c1a5aSDimitry Andric Asm->OutStreamer->getContext().getCurrentDwarfLoc().getLine();
1438d88c1a5aSDimitry Andric
1439*b5893f02SDimitry Andric // Request a label after the call in order to emit AT_return_pc information
1440*b5893f02SDimitry Andric // in call site entries. TODO: Add support for targets with delay slots.
1441*b5893f02SDimitry Andric if (SP->areAllCallsDescribed() && MI->isCall() && !MI->hasDelaySlot())
1442*b5893f02SDimitry Andric requestLabelAfterInsn(MI);
1443*b5893f02SDimitry Andric
1444d88c1a5aSDimitry Andric if (DL == PrevInstLoc) {
1445d88c1a5aSDimitry Andric // If we have an ongoing unspecified location, nothing to do here.
1446d88c1a5aSDimitry Andric if (!DL)
1447d88c1a5aSDimitry Andric return;
1448d88c1a5aSDimitry Andric // We have an explicit location, same as the previous location.
1449d88c1a5aSDimitry Andric // But we might be coming back to it after a line 0 record.
1450d88c1a5aSDimitry Andric if (LastAsmLine == 0 && DL.getLine() != 0) {
1451d88c1a5aSDimitry Andric // Reinstate the source location but not marked as a statement.
1452d88c1a5aSDimitry Andric const MDNode *Scope = DL.getScope();
1453d88c1a5aSDimitry Andric recordSourceLine(DL.getLine(), DL.getCol(), Scope, /*Flags=*/0);
1454bd5abe19SDimitry Andric }
1455d88c1a5aSDimitry Andric return;
1456d88c1a5aSDimitry Andric }
1457d88c1a5aSDimitry Andric
1458d88c1a5aSDimitry Andric if (!DL) {
1459d88c1a5aSDimitry Andric // We have an unspecified location, which might want to be line 0.
1460d88c1a5aSDimitry Andric // If we have already emitted a line-0 record, don't repeat it.
1461d88c1a5aSDimitry Andric if (LastAsmLine == 0)
1462d88c1a5aSDimitry Andric return;
1463d88c1a5aSDimitry Andric // If user said Don't Do That, don't do that.
1464d88c1a5aSDimitry Andric if (UnknownLocations == Disable)
1465d88c1a5aSDimitry Andric return;
1466d88c1a5aSDimitry Andric // See if we have a reason to emit a line-0 record now.
1467d88c1a5aSDimitry Andric // Reasons to emit a line-0 record include:
1468d88c1a5aSDimitry Andric // - User asked for it (UnknownLocations).
1469d88c1a5aSDimitry Andric // - Instruction has a label, so it's referenced from somewhere else,
1470d88c1a5aSDimitry Andric // possibly debug information; we want it to have a source location.
1471d88c1a5aSDimitry Andric // - Instruction is at the top of a block; we don't want to inherit the
1472d88c1a5aSDimitry Andric // location from the physically previous (maybe unrelated) block.
1473d88c1a5aSDimitry Andric if (UnknownLocations == Enable || PrevLabel ||
1474d88c1a5aSDimitry Andric (PrevInstBB && PrevInstBB != MI->getParent())) {
1475d88c1a5aSDimitry Andric // Preserve the file and column numbers, if we can, to save space in
1476d88c1a5aSDimitry Andric // the encoded line table.
1477d88c1a5aSDimitry Andric // Do not update PrevInstLoc, it remembers the last non-0 line.
1478d88c1a5aSDimitry Andric const MDNode *Scope = nullptr;
1479d88c1a5aSDimitry Andric unsigned Column = 0;
1480d88c1a5aSDimitry Andric if (PrevInstLoc) {
1481d88c1a5aSDimitry Andric Scope = PrevInstLoc.getScope();
1482d88c1a5aSDimitry Andric Column = PrevInstLoc.getCol();
1483d88c1a5aSDimitry Andric }
1484d88c1a5aSDimitry Andric recordSourceLine(/*Line=*/0, Column, Scope, /*Flags=*/0);
1485d88c1a5aSDimitry Andric }
1486d88c1a5aSDimitry Andric return;
1487d88c1a5aSDimitry Andric }
1488d88c1a5aSDimitry Andric
1489d88c1a5aSDimitry Andric // We have an explicit location, different from the previous location.
1490d88c1a5aSDimitry Andric // Don't repeat a line-0 record, but otherwise emit the new location.
1491d88c1a5aSDimitry Andric // (The new location might be an explicit line 0, which we do emit.)
1492d88c1a5aSDimitry Andric if (PrevInstLoc && DL.getLine() == 0 && LastAsmLine == 0)
1493d88c1a5aSDimitry Andric return;
1494d88c1a5aSDimitry Andric unsigned Flags = 0;
1495d88c1a5aSDimitry Andric if (DL == PrologEndLoc) {
1496d88c1a5aSDimitry Andric Flags |= DWARF2_FLAG_PROLOGUE_END | DWARF2_FLAG_IS_STMT;
1497d88c1a5aSDimitry Andric PrologEndLoc = DebugLoc();
1498d88c1a5aSDimitry Andric }
1499d88c1a5aSDimitry Andric // If the line changed, we call that a new statement; unless we went to
1500d88c1a5aSDimitry Andric // line 0 and came back, in which case it is not a new statement.
1501d88c1a5aSDimitry Andric unsigned OldLine = PrevInstLoc ? PrevInstLoc.getLine() : LastAsmLine;
1502d88c1a5aSDimitry Andric if (DL.getLine() && DL.getLine() != OldLine)
1503dff0c46cSDimitry Andric Flags |= DWARF2_FLAG_IS_STMT;
1504dff0c46cSDimitry Andric
1505ff0cc061SDimitry Andric const MDNode *Scope = DL.getScope();
1506bd5abe19SDimitry Andric recordSourceLine(DL.getLine(), DL.getCol(), Scope, Flags);
1507d88c1a5aSDimitry Andric
1508d88c1a5aSDimitry Andric // If we're not at line 0, remember this location.
1509d88c1a5aSDimitry Andric if (DL.getLine())
1510ff0cc061SDimitry Andric PrevInstLoc = DL;
1511f22ef01cSRoman Divacky }
1512f22ef01cSRoman Divacky
findPrologueEndLoc(const MachineFunction * MF)151391bc56edSDimitry Andric static DebugLoc findPrologueEndLoc(const MachineFunction *MF) {
151491bc56edSDimitry Andric // First known non-DBG_VALUE and non-frame setup location marks
151591bc56edSDimitry Andric // the beginning of the function body.
151691bc56edSDimitry Andric for (const auto &MBB : *MF)
151791bc56edSDimitry Andric for (const auto &MI : MBB)
1518302affcbSDimitry Andric if (!MI.isMetaInstruction() && !MI.getFlag(MachineInstr::FrameSetup) &&
15197d523365SDimitry Andric MI.getDebugLoc())
152091bc56edSDimitry Andric return MI.getDebugLoc();
1521bd5abe19SDimitry Andric return DebugLoc();
15222754fe60SDimitry Andric }
15232754fe60SDimitry Andric
1524139f7f9bSDimitry Andric // Gather pre-function debug information. Assumes being called immediately
1525139f7f9bSDimitry Andric // after the function entry point has been emitted.
beginFunctionImpl(const MachineFunction * MF)15267a7e6055SDimitry Andric void DwarfDebug::beginFunctionImpl(const MachineFunction *MF) {
152791bc56edSDimitry Andric CurFn = MF;
1528f785676fSDimitry Andric
15292cab237bSDimitry Andric auto *SP = MF->getFunction().getSubprogram();
1530302affcbSDimitry Andric assert(LScopes.empty() || SP == LScopes.getCurrentFunctionScope()->getScopeNode());
1531302affcbSDimitry Andric if (SP->getUnit()->getEmissionKind() == DICompileUnit::NoDebug)
1532f785676fSDimitry Andric return;
1533f785676fSDimitry Andric
1534302affcbSDimitry Andric DwarfCompileUnit &CU = getOrCreateDwarfCompileUnit(SP->getUnit());
1535302affcbSDimitry Andric
153691bc56edSDimitry Andric // Set DwarfDwarfCompileUnitID in MCContext to the Compile Unit this function
1537f785676fSDimitry Andric // belongs to so that we add to the correct per-cu line table in the
1538f785676fSDimitry Andric // non-asm case.
1539ff0cc061SDimitry Andric if (Asm->OutStreamer->hasRawTextSupport())
154091bc56edSDimitry Andric // Use a single line table if we are generating assembly.
1541ff0cc061SDimitry Andric Asm->OutStreamer->getContext().setDwarfCompileUnitID(0);
1542284c1978SDimitry Andric else
1543302affcbSDimitry Andric Asm->OutStreamer->getContext().setDwarfCompileUnitID(CU.getUniqueID());
1544f22ef01cSRoman Divacky
1545bd5abe19SDimitry Andric // Record beginning of function.
154691bc56edSDimitry Andric PrologEndLoc = findPrologueEndLoc(MF);
1547302affcbSDimitry Andric if (PrologEndLoc) {
1548139f7f9bSDimitry Andric // We'd like to list the prologue as "not statements" but GDB behaves
1549139f7f9bSDimitry Andric // poorly if we do that. Revisit this with caution/GDB (7.5+) testing.
1550302affcbSDimitry Andric auto *SP = PrologEndLoc->getInlinedAtScope()->getSubprogram();
1551ff0cc061SDimitry Andric recordSourceLine(SP->getScopeLine(), 0, SP, DWARF2_FLAG_IS_STMT);
1552bd5abe19SDimitry Andric }
1553f22ef01cSRoman Divacky }
1554f22ef01cSRoman Divacky
skippedNonDebugFunction()15557a7e6055SDimitry Andric void DwarfDebug::skippedNonDebugFunction() {
1556d88c1a5aSDimitry Andric // If we don't have a subprogram for this function then there will be a hole
15577a7e6055SDimitry Andric // in the range information. Keep note of this by setting the previously used
15587a7e6055SDimitry Andric // section to nullptr.
155991bc56edSDimitry Andric PrevCU = nullptr;
156091bc56edSDimitry Andric CurFn = nullptr;
156191bc56edSDimitry Andric }
1562f22ef01cSRoman Divacky
15637a7e6055SDimitry Andric // Gather and emit post-function debug information.
endFunctionImpl(const MachineFunction * MF)15647a7e6055SDimitry Andric void DwarfDebug::endFunctionImpl(const MachineFunction *MF) {
15652cab237bSDimitry Andric const DISubprogram *SP = MF->getFunction().getSubprogram();
15667a7e6055SDimitry Andric
15677a7e6055SDimitry Andric assert(CurFn == MF &&
15687a7e6055SDimitry Andric "endFunction should be called with the same function as beginFunction");
15697a7e6055SDimitry Andric
157091bc56edSDimitry Andric // Set DwarfDwarfCompileUnitID in MCContext to default value.
1571ff0cc061SDimitry Andric Asm->OutStreamer->getContext().setDwarfCompileUnitID(0);
1572f22ef01cSRoman Divacky
15736122f3e6SDimitry Andric LexicalScope *FnScope = LScopes.getCurrentFunctionScope();
1574d88c1a5aSDimitry Andric assert(!FnScope || SP == FnScope->getScopeNode());
15753ca95b02SDimitry Andric DwarfCompileUnit &TheCU = *CUMap.lookup(SP->getUnit());
1576*b5893f02SDimitry Andric if (TheCU.getCUNode()->isDebugDirectivesOnly()) {
1577*b5893f02SDimitry Andric PrevLabel = nullptr;
1578*b5893f02SDimitry Andric CurFn = nullptr;
1579*b5893f02SDimitry Andric return;
1580*b5893f02SDimitry Andric }
15816122f3e6SDimitry Andric
1582*b5893f02SDimitry Andric DenseSet<InlinedEntity> Processed;
1583*b5893f02SDimitry Andric collectEntityInfo(TheCU, SP, Processed);
158439d628a0SDimitry Andric
158539d628a0SDimitry Andric // Add the range of this function to the list of ranges for the CU.
1586ff0cc061SDimitry Andric TheCU.addRange(RangeSpan(Asm->getFunctionBegin(), Asm->getFunctionEnd()));
158739d628a0SDimitry Andric
158839d628a0SDimitry Andric // Under -gmlt, skip building the subprogram if there are no inlined
15897a7e6055SDimitry Andric // subroutines inside it. But with -fdebug-info-for-profiling, the subprogram
15907a7e6055SDimitry Andric // is still needed as we need its source location.
15917a7e6055SDimitry Andric if (!TheCU.getCUNode()->getDebugInfoForProfiling() &&
15927a7e6055SDimitry Andric TheCU.getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly &&
159339d628a0SDimitry Andric LScopes.getAbstractScopesList().empty() && !IsDarwin) {
159439d628a0SDimitry Andric assert(InfoHolder.getScopeVariables().empty());
159539d628a0SDimitry Andric PrevLabel = nullptr;
159639d628a0SDimitry Andric CurFn = nullptr;
159739d628a0SDimitry Andric return;
159839d628a0SDimitry Andric }
159939d628a0SDimitry Andric
160039d628a0SDimitry Andric #ifndef NDEBUG
160139d628a0SDimitry Andric size_t NumAbstractScopes = LScopes.getAbstractScopesList().size();
160239d628a0SDimitry Andric #endif
1603f22ef01cSRoman Divacky // Construct abstract scopes.
160491bc56edSDimitry Andric for (LexicalScope *AScope : LScopes.getAbstractScopesList()) {
1605ff0cc061SDimitry Andric auto *SP = cast<DISubprogram>(AScope->getScopeNode());
16064ba319b5SDimitry Andric for (const DINode *DN : SP->getRetainedNodes()) {
1607*b5893f02SDimitry Andric if (!Processed.insert(InlinedEntity(DN, nullptr)).second)
1608ffd1746dSEd Schouten continue;
1609*b5893f02SDimitry Andric
1610*b5893f02SDimitry Andric const MDNode *Scope = nullptr;
1611*b5893f02SDimitry Andric if (auto *DV = dyn_cast<DILocalVariable>(DN))
1612*b5893f02SDimitry Andric Scope = DV->getScope();
1613*b5893f02SDimitry Andric else if (auto *DL = dyn_cast<DILabel>(DN))
1614*b5893f02SDimitry Andric Scope = DL->getScope();
1615*b5893f02SDimitry Andric else
1616*b5893f02SDimitry Andric llvm_unreachable("Unexpected DI type!");
1617*b5893f02SDimitry Andric
1618*b5893f02SDimitry Andric // Collect info for variables/labels that were optimized out.
1619*b5893f02SDimitry Andric ensureAbstractEntityIsCreated(TheCU, DN, Scope);
162039d628a0SDimitry Andric assert(LScopes.getAbstractScopesList().size() == NumAbstractScopes
1621*b5893f02SDimitry Andric && "ensureAbstractEntityIsCreated inserted abstract scopes");
16224ba319b5SDimitry Andric }
16235517e702SDimitry Andric constructAbstractSubprogramScopeDIE(TheCU, AScope);
1624ffd1746dSEd Schouten }
1625f22ef01cSRoman Divacky
1626d88c1a5aSDimitry Andric ProcessedSPNodes.insert(SP);
1627*b5893f02SDimitry Andric DIE &ScopeDIE = TheCU.constructSubprogramScopeDIE(SP, FnScope);
162839d628a0SDimitry Andric if (auto *SkelCU = TheCU.getSkeleton())
1629d88c1a5aSDimitry Andric if (!LScopes.getAbstractScopesList().empty() &&
1630d88c1a5aSDimitry Andric TheCU.getCUNode()->getSplitDebugInlining())
1631d88c1a5aSDimitry Andric SkelCU->constructSubprogramScopeDIE(SP, FnScope);
1632f22ef01cSRoman Divacky
1633*b5893f02SDimitry Andric // Construct call site entries.
1634*b5893f02SDimitry Andric constructCallSiteEntryDIEs(*SP, TheCU, ScopeDIE, *MF);
1635*b5893f02SDimitry Andric
1636f22ef01cSRoman Divacky // Clear debug info
163791bc56edSDimitry Andric // Ownership of DbgVariables is a bit subtle - ScopeVariables owns all the
163891bc56edSDimitry Andric // DbgVariables except those that are also in AbstractVariables (since they
163991bc56edSDimitry Andric // can be used cross-function)
164039d628a0SDimitry Andric InfoHolder.getScopeVariables().clear();
1641*b5893f02SDimitry Andric InfoHolder.getScopeLabels().clear();
164291bc56edSDimitry Andric PrevLabel = nullptr;
164391bc56edSDimitry Andric CurFn = nullptr;
1644f22ef01cSRoman Divacky }
1645f22ef01cSRoman Divacky
1646139f7f9bSDimitry Andric // Register a source line with debug info. Returns the unique label that was
1647139f7f9bSDimitry Andric // emitted and which provides correspondence to the source line list.
recordSourceLine(unsigned Line,unsigned Col,const MDNode * S,unsigned Flags)1648bd5abe19SDimitry Andric void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S,
1649bd5abe19SDimitry Andric unsigned Flags) {
1650f22ef01cSRoman Divacky StringRef Fn;
16514ba319b5SDimitry Andric unsigned FileNo = 1;
165291bc56edSDimitry Andric unsigned Discriminator = 0;
1653ff0cc061SDimitry Andric if (auto *Scope = cast_or_null<DIScope>(S)) {
1654ff0cc061SDimitry Andric Fn = Scope->getFilename();
16552cab237bSDimitry Andric if (Line != 0 && getDwarfVersion() >= 4)
1656ff0cc061SDimitry Andric if (auto *LBF = dyn_cast<DILexicalBlockFile>(Scope))
1657ff0cc061SDimitry Andric Discriminator = LBF->getDiscriminator();
1658f22ef01cSRoman Divacky
1659ff0cc061SDimitry Andric unsigned CUID = Asm->OutStreamer->getContext().getDwarfCompileUnitID();
16604ba319b5SDimitry Andric FileNo = static_cast<DwarfCompileUnit &>(*InfoHolder.getUnits()[CUID])
16614ba319b5SDimitry Andric .getOrCreateSourceID(Scope->getFile());
1662f22ef01cSRoman Divacky }
16634ba319b5SDimitry Andric Asm->OutStreamer->EmitDwarfLocDirective(FileNo, Line, Col, Flags, 0,
166491bc56edSDimitry Andric Discriminator, Fn);
1665f22ef01cSRoman Divacky }
1666f22ef01cSRoman Divacky
1667f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
1668f22ef01cSRoman Divacky // Emit Methods
1669f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
1670f22ef01cSRoman Divacky
1671139f7f9bSDimitry Andric // Emit the debug info section.
emitDebugInfo()1672139f7f9bSDimitry Andric void DwarfDebug::emitDebugInfo() {
167391bc56edSDimitry Andric DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder;
1674ff0cc061SDimitry Andric Holder.emitUnits(/* UseOffsets */ false);
1675139f7f9bSDimitry Andric }
1676139f7f9bSDimitry Andric
1677139f7f9bSDimitry Andric // Emit the abbreviation section.
emitAbbreviations()1678139f7f9bSDimitry Andric void DwarfDebug::emitAbbreviations() {
167991bc56edSDimitry Andric DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder;
1680139f7f9bSDimitry Andric
168191bc56edSDimitry Andric Holder.emitAbbrevs(Asm->getObjFileLowering().getDwarfAbbrevSection());
1682f22ef01cSRoman Divacky }
1683f22ef01cSRoman Divacky
emitStringOffsetsTableHeader()16844ba319b5SDimitry Andric void DwarfDebug::emitStringOffsetsTableHeader() {
16854ba319b5SDimitry Andric DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder;
16864ba319b5SDimitry Andric Holder.getStringPool().emitStringOffsetsTableHeader(
16874ba319b5SDimitry Andric *Asm, Asm->getObjFileLowering().getDwarfStrOffSection(),
16884ba319b5SDimitry Andric Holder.getStringOffsetsStartSym());
16894ba319b5SDimitry Andric }
16904ba319b5SDimitry Andric
16914ba319b5SDimitry Andric template <typename AccelTableT>
emitAccel(AccelTableT & Accel,MCSection * Section,StringRef TableName)16924ba319b5SDimitry Andric void DwarfDebug::emitAccel(AccelTableT &Accel, MCSection *Section,
1693ff0cc061SDimitry Andric StringRef TableName) {
1694ff0cc061SDimitry Andric Asm->OutStreamer->SwitchSection(Section);
1695dff0c46cSDimitry Andric
1696dff0c46cSDimitry Andric // Emit the full data.
16974ba319b5SDimitry Andric emitAppleAccelTable(Asm, Accel, TableName, Section->getBeginSymbol());
16984ba319b5SDimitry Andric }
16994ba319b5SDimitry Andric
emitAccelDebugNames()17004ba319b5SDimitry Andric void DwarfDebug::emitAccelDebugNames() {
17014ba319b5SDimitry Andric // Don't emit anything if we have no compilation units to index.
17024ba319b5SDimitry Andric if (getUnits().empty())
17034ba319b5SDimitry Andric return;
17044ba319b5SDimitry Andric
17054ba319b5SDimitry Andric emitDWARF5AccelTable(Asm, AccelDebugNames, *this, getUnits());
170639d628a0SDimitry Andric }
170739d628a0SDimitry Andric
170839d628a0SDimitry Andric // Emit visible names into a hashed accelerator table section.
emitAccelNames()170939d628a0SDimitry Andric void DwarfDebug::emitAccelNames() {
171039d628a0SDimitry Andric emitAccel(AccelNames, Asm->getObjFileLowering().getDwarfAccelNamesSection(),
1711ff0cc061SDimitry Andric "Names");
1712f22ef01cSRoman Divacky }
1713dff0c46cSDimitry Andric
1714139f7f9bSDimitry Andric // Emit objective C classes and categories into a hashed accelerator table
1715139f7f9bSDimitry Andric // section.
emitAccelObjC()1716dff0c46cSDimitry Andric void DwarfDebug::emitAccelObjC() {
171739d628a0SDimitry Andric emitAccel(AccelObjC, Asm->getObjFileLowering().getDwarfAccelObjCSection(),
1718ff0cc061SDimitry Andric "ObjC");
1719dff0c46cSDimitry Andric }
1720dff0c46cSDimitry Andric
1721139f7f9bSDimitry Andric // Emit namespace dies into a hashed accelerator table.
emitAccelNamespaces()1722dff0c46cSDimitry Andric void DwarfDebug::emitAccelNamespaces() {
172339d628a0SDimitry Andric emitAccel(AccelNamespace,
172439d628a0SDimitry Andric Asm->getObjFileLowering().getDwarfAccelNamespaceSection(),
1725ff0cc061SDimitry Andric "namespac");
1726dff0c46cSDimitry Andric }
1727dff0c46cSDimitry Andric
1728139f7f9bSDimitry Andric // Emit type dies into a hashed accelerator table.
emitAccelTypes()1729dff0c46cSDimitry Andric void DwarfDebug::emitAccelTypes() {
173039d628a0SDimitry Andric emitAccel(AccelTypes, Asm->getObjFileLowering().getDwarfAccelTypesSection(),
1731ff0cc061SDimitry Andric "types");
1732139f7f9bSDimitry Andric }
1733139f7f9bSDimitry Andric
1734f785676fSDimitry Andric // Public name handling.
1735f785676fSDimitry Andric // The format for the various pubnames:
1736f785676fSDimitry Andric //
1737f785676fSDimitry Andric // dwarf pubnames - offset/name pairs where the offset is the offset into the CU
1738f785676fSDimitry Andric // for the DIE that is named.
1739f785676fSDimitry Andric //
1740f785676fSDimitry Andric // gnu pubnames - offset/index value/name tuples where the offset is the offset
1741f785676fSDimitry Andric // into the CU and the index value is computed according to the type of value
1742f785676fSDimitry Andric // for the DIE that is named.
1743f785676fSDimitry Andric //
1744f785676fSDimitry Andric // For type units the offset is the offset of the skeleton DIE. For split dwarf
1745f785676fSDimitry Andric // it's the offset within the debug_info/debug_types dwo section, however, the
1746f785676fSDimitry Andric // reference in the pubname header doesn't change.
1747f785676fSDimitry Andric
1748f785676fSDimitry Andric /// computeIndexValue - Compute the gdb index value for the DIE and CU.
computeIndexValue(DwarfUnit * CU,const DIE * Die)174991bc56edSDimitry Andric static dwarf::PubIndexEntryDescriptor computeIndexValue(DwarfUnit *CU,
175091bc56edSDimitry Andric const DIE *Die) {
17517a7e6055SDimitry Andric // Entities that ended up only in a Type Unit reference the CU instead (since
17527a7e6055SDimitry Andric // the pub entry has offsets within the CU there's no real offset that can be
17537a7e6055SDimitry Andric // provided anyway). As it happens all such entities (namespaces and types,
17547a7e6055SDimitry Andric // types only in C++ at that) are rendered as TYPE+EXTERNAL. If this turns out
17557a7e6055SDimitry Andric // not to be true it would be necessary to persist this information from the
17567a7e6055SDimitry Andric // point at which the entry is added to the index data structure - since by
17577a7e6055SDimitry Andric // the time the index is built from that, the original type/namespace DIE in a
17587a7e6055SDimitry Andric // type unit has already been destroyed so it can't be queried for properties
17597a7e6055SDimitry Andric // like tag, etc.
17607a7e6055SDimitry Andric if (Die->getTag() == dwarf::DW_TAG_compile_unit)
17617a7e6055SDimitry Andric return dwarf::PubIndexEntryDescriptor(dwarf::GIEK_TYPE,
17627a7e6055SDimitry Andric dwarf::GIEL_EXTERNAL);
1763f785676fSDimitry Andric dwarf::GDBIndexEntryLinkage Linkage = dwarf::GIEL_STATIC;
1764f785676fSDimitry Andric
1765f785676fSDimitry Andric // We could have a specification DIE that has our most of our knowledge,
1766f785676fSDimitry Andric // look for that now.
176797bc6c73SDimitry Andric if (DIEValue SpecVal = Die->findAttribute(dwarf::DW_AT_specification)) {
176897bc6c73SDimitry Andric DIE &SpecDIE = SpecVal.getDIEEntry().getEntry();
176991bc56edSDimitry Andric if (SpecDIE.findAttribute(dwarf::DW_AT_external))
1770f785676fSDimitry Andric Linkage = dwarf::GIEL_EXTERNAL;
1771f785676fSDimitry Andric } else if (Die->findAttribute(dwarf::DW_AT_external))
1772f785676fSDimitry Andric Linkage = dwarf::GIEL_EXTERNAL;
1773f785676fSDimitry Andric
1774f785676fSDimitry Andric switch (Die->getTag()) {
1775f785676fSDimitry Andric case dwarf::DW_TAG_class_type:
1776f785676fSDimitry Andric case dwarf::DW_TAG_structure_type:
1777f785676fSDimitry Andric case dwarf::DW_TAG_union_type:
1778f785676fSDimitry Andric case dwarf::DW_TAG_enumeration_type:
1779f785676fSDimitry Andric return dwarf::PubIndexEntryDescriptor(
1780f785676fSDimitry Andric dwarf::GIEK_TYPE, CU->getLanguage() != dwarf::DW_LANG_C_plus_plus
1781f785676fSDimitry Andric ? dwarf::GIEL_STATIC
1782f785676fSDimitry Andric : dwarf::GIEL_EXTERNAL);
1783f785676fSDimitry Andric case dwarf::DW_TAG_typedef:
1784f785676fSDimitry Andric case dwarf::DW_TAG_base_type:
1785f785676fSDimitry Andric case dwarf::DW_TAG_subrange_type:
1786f785676fSDimitry Andric return dwarf::PubIndexEntryDescriptor(dwarf::GIEK_TYPE, dwarf::GIEL_STATIC);
1787f785676fSDimitry Andric case dwarf::DW_TAG_namespace:
1788f785676fSDimitry Andric return dwarf::GIEK_TYPE;
1789f785676fSDimitry Andric case dwarf::DW_TAG_subprogram:
1790f785676fSDimitry Andric return dwarf::PubIndexEntryDescriptor(dwarf::GIEK_FUNCTION, Linkage);
1791f785676fSDimitry Andric case dwarf::DW_TAG_variable:
1792f785676fSDimitry Andric return dwarf::PubIndexEntryDescriptor(dwarf::GIEK_VARIABLE, Linkage);
1793f785676fSDimitry Andric case dwarf::DW_TAG_enumerator:
1794f785676fSDimitry Andric return dwarf::PubIndexEntryDescriptor(dwarf::GIEK_VARIABLE,
1795f785676fSDimitry Andric dwarf::GIEL_STATIC);
1796f785676fSDimitry Andric default:
1797f785676fSDimitry Andric return dwarf::GIEK_NONE;
1798f785676fSDimitry Andric }
1799f785676fSDimitry Andric }
1800f785676fSDimitry Andric
18012cab237bSDimitry Andric /// emitDebugPubSections - Emit visible names and types into debug pubnames and
18022cab237bSDimitry Andric /// pubtypes sections.
emitDebugPubSections()18032cab237bSDimitry Andric void DwarfDebug::emitDebugPubSections() {
180491bc56edSDimitry Andric for (const auto &NU : CUMap) {
180591bc56edSDimitry Andric DwarfCompileUnit *TheU = NU.second;
18062cab237bSDimitry Andric if (!TheU->hasDwarfPubSections())
180791bc56edSDimitry Andric continue;
180891bc56edSDimitry Andric
1809*b5893f02SDimitry Andric bool GnuStyle = TheU->getCUNode()->getNameTableKind() ==
1810*b5893f02SDimitry Andric DICompileUnit::DebugNameTableKind::GNU;
18112cab237bSDimitry Andric
18122cab237bSDimitry Andric Asm->OutStreamer->SwitchSection(
18132cab237bSDimitry Andric GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubNamesSection()
18142cab237bSDimitry Andric : Asm->getObjFileLowering().getDwarfPubNamesSection());
18152cab237bSDimitry Andric emitDebugPubSection(GnuStyle, "Names", TheU, TheU->getGlobalNames());
18162cab237bSDimitry Andric
18172cab237bSDimitry Andric Asm->OutStreamer->SwitchSection(
18182cab237bSDimitry Andric GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubTypesSection()
18192cab237bSDimitry Andric : Asm->getObjFileLowering().getDwarfPubTypesSection());
18202cab237bSDimitry Andric emitDebugPubSection(GnuStyle, "Types", TheU, TheU->getGlobalTypes());
18212cab237bSDimitry Andric }
18222cab237bSDimitry Andric }
18232cab237bSDimitry Andric
emitSectionReference(const DwarfCompileUnit & CU)18244ba319b5SDimitry Andric void DwarfDebug::emitSectionReference(const DwarfCompileUnit &CU) {
18254ba319b5SDimitry Andric if (useSectionsAsReferences())
18264ba319b5SDimitry Andric Asm->EmitDwarfOffset(CU.getSection()->getBeginSymbol(),
18274ba319b5SDimitry Andric CU.getDebugSectionOffset());
18284ba319b5SDimitry Andric else
18294ba319b5SDimitry Andric Asm->emitDwarfSymbolReference(CU.getLabelBegin());
18304ba319b5SDimitry Andric }
18314ba319b5SDimitry Andric
emitDebugPubSection(bool GnuStyle,StringRef Name,DwarfCompileUnit * TheU,const StringMap<const DIE * > & Globals)18322cab237bSDimitry Andric void DwarfDebug::emitDebugPubSection(bool GnuStyle, StringRef Name,
18332cab237bSDimitry Andric DwarfCompileUnit *TheU,
18342cab237bSDimitry Andric const StringMap<const DIE *> &Globals) {
183539d628a0SDimitry Andric if (auto *Skeleton = TheU->getSkeleton())
183691bc56edSDimitry Andric TheU = Skeleton;
1837139f7f9bSDimitry Andric
1838f785676fSDimitry Andric // Emit the header.
1839ff0cc061SDimitry Andric Asm->OutStreamer->AddComment("Length of Public " + Name + " Info");
1840ff0cc061SDimitry Andric MCSymbol *BeginLabel = Asm->createTempSymbol("pub" + Name + "_begin");
1841ff0cc061SDimitry Andric MCSymbol *EndLabel = Asm->createTempSymbol("pub" + Name + "_end");
184291bc56edSDimitry Andric Asm->EmitLabelDifference(EndLabel, BeginLabel, 4);
1843139f7f9bSDimitry Andric
1844ff0cc061SDimitry Andric Asm->OutStreamer->EmitLabel(BeginLabel);
1845139f7f9bSDimitry Andric
1846ff0cc061SDimitry Andric Asm->OutStreamer->AddComment("DWARF Version");
18474ba319b5SDimitry Andric Asm->emitInt16(dwarf::DW_PUBNAMES_VERSION);
1848139f7f9bSDimitry Andric
1849ff0cc061SDimitry Andric Asm->OutStreamer->AddComment("Offset of Compilation Unit Info");
18504ba319b5SDimitry Andric emitSectionReference(*TheU);
1851139f7f9bSDimitry Andric
1852ff0cc061SDimitry Andric Asm->OutStreamer->AddComment("Compilation Unit Length");
18534ba319b5SDimitry Andric Asm->emitInt32(TheU->getLength());
1854139f7f9bSDimitry Andric
1855f785676fSDimitry Andric // Emit the pubnames for this compilation unit.
185691bc56edSDimitry Andric for (const auto &GI : Globals) {
185791bc56edSDimitry Andric const char *Name = GI.getKeyData();
185891bc56edSDimitry Andric const DIE *Entity = GI.second;
1859139f7f9bSDimitry Andric
1860ff0cc061SDimitry Andric Asm->OutStreamer->AddComment("DIE offset");
18614ba319b5SDimitry Andric Asm->emitInt32(Entity->getOffset());
1862139f7f9bSDimitry Andric
1863f785676fSDimitry Andric if (GnuStyle) {
186491bc56edSDimitry Andric dwarf::PubIndexEntryDescriptor Desc = computeIndexValue(TheU, Entity);
1865ff0cc061SDimitry Andric Asm->OutStreamer->AddComment(
1866*b5893f02SDimitry Andric Twine("Attributes: ") + dwarf::GDBIndexEntryKindString(Desc.Kind) +
1867*b5893f02SDimitry Andric ", " + dwarf::GDBIndexEntryLinkageString(Desc.Linkage));
18684ba319b5SDimitry Andric Asm->emitInt8(Desc.toBits());
1869f785676fSDimitry Andric }
1870f785676fSDimitry Andric
1871ff0cc061SDimitry Andric Asm->OutStreamer->AddComment("External Name");
1872ff0cc061SDimitry Andric Asm->OutStreamer->EmitBytes(StringRef(Name, GI.getKeyLength() + 1));
1873139f7f9bSDimitry Andric }
1874139f7f9bSDimitry Andric
1875ff0cc061SDimitry Andric Asm->OutStreamer->AddComment("End Mark");
18764ba319b5SDimitry Andric Asm->emitInt32(0);
1877ff0cc061SDimitry Andric Asm->OutStreamer->EmitLabel(EndLabel);
1878139f7f9bSDimitry Andric }
1879139f7f9bSDimitry Andric
18803ca95b02SDimitry Andric /// Emit null-terminated strings into a debug str section.
emitDebugStr()1881139f7f9bSDimitry Andric void DwarfDebug::emitDebugStr() {
18824ba319b5SDimitry Andric MCSection *StringOffsetsSection = nullptr;
18834ba319b5SDimitry Andric if (useSegmentedStringOffsetsTable()) {
18844ba319b5SDimitry Andric emitStringOffsetsTableHeader();
18854ba319b5SDimitry Andric StringOffsetsSection = Asm->getObjFileLowering().getDwarfStrOffSection();
18864ba319b5SDimitry Andric }
188791bc56edSDimitry Andric DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder;
18884ba319b5SDimitry Andric Holder.emitStrings(Asm->getObjFileLowering().getDwarfStrSection(),
18894ba319b5SDimitry Andric StringOffsetsSection, /* UseRelativeOffsets = */ true);
1890139f7f9bSDimitry Andric }
1891139f7f9bSDimitry Andric
emitDebugLocEntry(ByteStreamer & Streamer,const DebugLocStream::Entry & Entry)189291bc56edSDimitry Andric void DwarfDebug::emitDebugLocEntry(ByteStreamer &Streamer,
1893ff0cc061SDimitry Andric const DebugLocStream::Entry &Entry) {
1894ff0cc061SDimitry Andric auto &&Comments = DebugLocs.getComments(Entry);
1895ff0cc061SDimitry Andric auto Comment = Comments.begin();
1896ff0cc061SDimitry Andric auto End = Comments.end();
1897ff0cc061SDimitry Andric for (uint8_t Byte : DebugLocs.getBytes(Entry))
1898ff0cc061SDimitry Andric Streamer.EmitInt8(Byte, Comment != End ? *(Comment++) : "");
189939d628a0SDimitry Andric }
190039d628a0SDimitry Andric
emitDebugLocValue(const AsmPrinter & AP,const DIBasicType * BT,const DebugLocEntry::Value & Value,DwarfExpression & DwarfExpr)1901ff0cc061SDimitry Andric static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
190239d628a0SDimitry Andric const DebugLocEntry::Value &Value,
1903d88c1a5aSDimitry Andric DwarfExpression &DwarfExpr) {
19047a7e6055SDimitry Andric auto *DIExpr = Value.getExpression();
19057a7e6055SDimitry Andric DIExpressionCursor ExprCursor(DIExpr);
19067a7e6055SDimitry Andric DwarfExpr.addFragmentOffset(DIExpr);
190739d628a0SDimitry Andric // Regular entry.
190891bc56edSDimitry Andric if (Value.isInt()) {
1909ff0cc061SDimitry Andric if (BT && (BT->getEncoding() == dwarf::DW_ATE_signed ||
1910ff0cc061SDimitry Andric BT->getEncoding() == dwarf::DW_ATE_signed_char))
19117a7e6055SDimitry Andric DwarfExpr.addSignedConstant(Value.getInt());
191239d628a0SDimitry Andric else
19137a7e6055SDimitry Andric DwarfExpr.addUnsignedConstant(Value.getInt());
191491bc56edSDimitry Andric } else if (Value.isLocation()) {
19157a7e6055SDimitry Andric MachineLocation Location = Value.getLoc();
19166bc11b14SDimitry Andric if (Location.isIndirect())
19176bc11b14SDimitry Andric DwarfExpr.setMemoryLocationKind();
19182cab237bSDimitry Andric DIExpressionCursor Cursor(DIExpr);
19193ca95b02SDimitry Andric const TargetRegisterInfo &TRI = *AP.MF->getSubtarget().getRegisterInfo();
19207a7e6055SDimitry Andric if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
19217a7e6055SDimitry Andric return;
19227a7e6055SDimitry Andric return DwarfExpr.addExpression(std::move(Cursor));
19233ca95b02SDimitry Andric } else if (Value.isConstantFP()) {
19243ca95b02SDimitry Andric APInt RawBytes = Value.getConstantFP()->getValueAPF().bitcastToAPInt();
19257a7e6055SDimitry Andric DwarfExpr.addUnsignedConstant(RawBytes);
192617a519f9SDimitry Andric }
19277a7e6055SDimitry Andric DwarfExpr.addExpression(std::move(ExprCursor));
192891bc56edSDimitry Andric }
192991bc56edSDimitry Andric
finalize(const AsmPrinter & AP,DebugLocStream::ListBuilder & List,const DIBasicType * BT)19303dac3a9bSDimitry Andric void DebugLocEntry::finalize(const AsmPrinter &AP,
19313dac3a9bSDimitry Andric DebugLocStream::ListBuilder &List,
1932ff0cc061SDimitry Andric const DIBasicType *BT) {
1933*b5893f02SDimitry Andric assert(Begin != End && "unexpected location list entry with empty range");
19343dac3a9bSDimitry Andric DebugLocStream::EntryBuilder Entry(List, Begin, End);
19353dac3a9bSDimitry Andric BufferByteStreamer Streamer = Entry.getStreamer();
1936d88c1a5aSDimitry Andric DebugLocDwarfExpression DwarfExpr(AP.getDwarfVersion(), Streamer);
1937ff0cc061SDimitry Andric const DebugLocEntry::Value &Value = Values[0];
1938d88c1a5aSDimitry Andric if (Value.isFragment()) {
1939d88c1a5aSDimitry Andric // Emit all fragments that belong to the same variable and range.
19402cab237bSDimitry Andric assert(llvm::all_of(Values, [](DebugLocEntry::Value P) {
1941d88c1a5aSDimitry Andric return P.isFragment();
1942d88c1a5aSDimitry Andric }) && "all values are expected to be fragments");
1943ff0cc061SDimitry Andric assert(std::is_sorted(Values.begin(), Values.end()) &&
1944d88c1a5aSDimitry Andric "fragments are expected to be sorted");
1945ff0cc061SDimitry Andric
1946d88c1a5aSDimitry Andric for (auto Fragment : Values)
19474ba319b5SDimitry Andric emitDebugLocValue(AP, BT, Fragment, DwarfExpr);
1948ff0cc061SDimitry Andric
1949ff0cc061SDimitry Andric } else {
1950d88c1a5aSDimitry Andric assert(Values.size() == 1 && "only fragments may have >1 value");
19514ba319b5SDimitry Andric emitDebugLocValue(AP, BT, Value, DwarfExpr);
1952ff0cc061SDimitry Andric }
1953d88c1a5aSDimitry Andric DwarfExpr.finalize();
1954ff0cc061SDimitry Andric }
1955ff0cc061SDimitry Andric
emitDebugLocEntryLocation(const DebugLocStream::Entry & Entry)1956ff0cc061SDimitry Andric void DwarfDebug::emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry) {
1957ff0cc061SDimitry Andric // Emit the size.
1958ff0cc061SDimitry Andric Asm->OutStreamer->AddComment("Loc expr size");
1959*b5893f02SDimitry Andric if (getDwarfVersion() >= 5)
1960*b5893f02SDimitry Andric Asm->EmitULEB128(DebugLocs.getBytes(Entry).size());
1961*b5893f02SDimitry Andric else
19624ba319b5SDimitry Andric Asm->emitInt16(DebugLocs.getBytes(Entry).size());
196391bc56edSDimitry Andric // Emit the entry.
196491bc56edSDimitry Andric APByteStreamer Streamer(*Asm);
196591bc56edSDimitry Andric emitDebugLocEntry(Streamer, Entry);
1966f22ef01cSRoman Divacky }
196791bc56edSDimitry Andric
1968*b5893f02SDimitry Andric // Emit the common part of the DWARF 5 range/locations list tables header.
emitListsTableHeaderStart(AsmPrinter * Asm,const DwarfFile & Holder,MCSymbol * TableStart,MCSymbol * TableEnd)1969*b5893f02SDimitry Andric static void emitListsTableHeaderStart(AsmPrinter *Asm, const DwarfFile &Holder,
1970*b5893f02SDimitry Andric MCSymbol *TableStart,
1971*b5893f02SDimitry Andric MCSymbol *TableEnd) {
1972*b5893f02SDimitry Andric // Build the table header, which starts with the length field.
1973*b5893f02SDimitry Andric Asm->OutStreamer->AddComment("Length");
1974*b5893f02SDimitry Andric Asm->EmitLabelDifference(TableEnd, TableStart, 4);
1975*b5893f02SDimitry Andric Asm->OutStreamer->EmitLabel(TableStart);
1976*b5893f02SDimitry Andric // Version number (DWARF v5 and later).
1977*b5893f02SDimitry Andric Asm->OutStreamer->AddComment("Version");
1978*b5893f02SDimitry Andric Asm->emitInt16(Asm->OutStreamer->getContext().getDwarfVersion());
1979*b5893f02SDimitry Andric // Address size.
1980*b5893f02SDimitry Andric Asm->OutStreamer->AddComment("Address size");
1981*b5893f02SDimitry Andric Asm->emitInt8(Asm->MAI->getCodePointerSize());
1982*b5893f02SDimitry Andric // Segment selector size.
1983*b5893f02SDimitry Andric Asm->OutStreamer->AddComment("Segment selector size");
1984*b5893f02SDimitry Andric Asm->emitInt8(0);
1985*b5893f02SDimitry Andric }
1986*b5893f02SDimitry Andric
1987*b5893f02SDimitry Andric // Emit the header of a DWARF 5 range list table list table. Returns the symbol
1988*b5893f02SDimitry Andric // that designates the end of the table for the caller to emit when the table is
1989*b5893f02SDimitry Andric // complete.
emitRnglistsTableHeader(AsmPrinter * Asm,const DwarfFile & Holder)1990*b5893f02SDimitry Andric static MCSymbol *emitRnglistsTableHeader(AsmPrinter *Asm,
1991*b5893f02SDimitry Andric const DwarfFile &Holder) {
1992*b5893f02SDimitry Andric MCSymbol *TableStart = Asm->createTempSymbol("debug_rnglist_table_start");
1993*b5893f02SDimitry Andric MCSymbol *TableEnd = Asm->createTempSymbol("debug_rnglist_table_end");
1994*b5893f02SDimitry Andric emitListsTableHeaderStart(Asm, Holder, TableStart, TableEnd);
1995*b5893f02SDimitry Andric
1996*b5893f02SDimitry Andric Asm->OutStreamer->AddComment("Offset entry count");
1997*b5893f02SDimitry Andric Asm->emitInt32(Holder.getRangeLists().size());
1998*b5893f02SDimitry Andric Asm->OutStreamer->EmitLabel(Holder.getRnglistsTableBaseSym());
1999*b5893f02SDimitry Andric
2000*b5893f02SDimitry Andric for (const RangeSpanList &List : Holder.getRangeLists())
2001*b5893f02SDimitry Andric Asm->EmitLabelDifference(List.getSym(), Holder.getRnglistsTableBaseSym(),
2002*b5893f02SDimitry Andric 4);
2003*b5893f02SDimitry Andric
2004*b5893f02SDimitry Andric return TableEnd;
2005*b5893f02SDimitry Andric }
2006*b5893f02SDimitry Andric
2007*b5893f02SDimitry Andric // Emit the header of a DWARF 5 locations list table. Returns the symbol that
2008*b5893f02SDimitry Andric // designates the end of the table for the caller to emit when the table is
2009*b5893f02SDimitry Andric // complete.
emitLoclistsTableHeader(AsmPrinter * Asm,const DwarfFile & Holder)2010*b5893f02SDimitry Andric static MCSymbol *emitLoclistsTableHeader(AsmPrinter *Asm,
2011*b5893f02SDimitry Andric const DwarfFile &Holder) {
2012*b5893f02SDimitry Andric MCSymbol *TableStart = Asm->createTempSymbol("debug_loclist_table_start");
2013*b5893f02SDimitry Andric MCSymbol *TableEnd = Asm->createTempSymbol("debug_loclist_table_end");
2014*b5893f02SDimitry Andric emitListsTableHeaderStart(Asm, Holder, TableStart, TableEnd);
2015*b5893f02SDimitry Andric
2016*b5893f02SDimitry Andric // FIXME: Generate the offsets table and use DW_FORM_loclistx with the
2017*b5893f02SDimitry Andric // DW_AT_loclists_base attribute. Until then set the number of offsets to 0.
2018*b5893f02SDimitry Andric Asm->OutStreamer->AddComment("Offset entry count");
2019*b5893f02SDimitry Andric Asm->emitInt32(0);
2020*b5893f02SDimitry Andric Asm->OutStreamer->EmitLabel(Holder.getLoclistsTableBaseSym());
2021*b5893f02SDimitry Andric
2022*b5893f02SDimitry Andric return TableEnd;
2023*b5893f02SDimitry Andric }
2024*b5893f02SDimitry Andric
2025*b5893f02SDimitry Andric // Emit locations into the .debug_loc/.debug_rnglists section.
emitDebugLoc()202691bc56edSDimitry Andric void DwarfDebug::emitDebugLoc() {
2027302affcbSDimitry Andric if (DebugLocs.getLists().empty())
2028302affcbSDimitry Andric return;
2029302affcbSDimitry Andric
2030*b5893f02SDimitry Andric bool IsLocLists = getDwarfVersion() >= 5;
2031*b5893f02SDimitry Andric MCSymbol *TableEnd = nullptr;
2032*b5893f02SDimitry Andric if (IsLocLists) {
2033*b5893f02SDimitry Andric Asm->OutStreamer->SwitchSection(
2034*b5893f02SDimitry Andric Asm->getObjFileLowering().getDwarfLoclistsSection());
2035*b5893f02SDimitry Andric TableEnd = emitLoclistsTableHeader(Asm, useSplitDwarf() ? SkeletonHolder
2036*b5893f02SDimitry Andric : InfoHolder);
2037*b5893f02SDimitry Andric } else {
2038ff0cc061SDimitry Andric Asm->OutStreamer->SwitchSection(
203991bc56edSDimitry Andric Asm->getObjFileLowering().getDwarfLocSection());
2040*b5893f02SDimitry Andric }
2041*b5893f02SDimitry Andric
20426bc11b14SDimitry Andric unsigned char Size = Asm->MAI->getCodePointerSize();
2043ff0cc061SDimitry Andric for (const auto &List : DebugLocs.getLists()) {
2044ff0cc061SDimitry Andric Asm->OutStreamer->EmitLabel(List.Label);
2045*b5893f02SDimitry Andric
2046ff0cc061SDimitry Andric const DwarfCompileUnit *CU = List.CU;
2047*b5893f02SDimitry Andric const MCSymbol *Base = CU->getBaseAddress();
2048ff0cc061SDimitry Andric for (const auto &Entry : DebugLocs.getEntries(List)) {
2049*b5893f02SDimitry Andric if (Base) {
205091bc56edSDimitry Andric // Set up the range. This range is relative to the entry point of the
205191bc56edSDimitry Andric // compile unit. This is a hard coded 0 for low_pc when we're emitting
205291bc56edSDimitry Andric // ranges, or the DW_AT_low_pc on the compile unit otherwise.
2053*b5893f02SDimitry Andric if (IsLocLists) {
2054*b5893f02SDimitry Andric Asm->OutStreamer->AddComment("DW_LLE_offset_pair");
2055*b5893f02SDimitry Andric Asm->OutStreamer->EmitIntValue(dwarf::DW_LLE_offset_pair, 1);
2056*b5893f02SDimitry Andric Asm->OutStreamer->AddComment(" starting offset");
2057*b5893f02SDimitry Andric Asm->EmitLabelDifferenceAsULEB128(Entry.BeginSym, Base);
2058*b5893f02SDimitry Andric Asm->OutStreamer->AddComment(" ending offset");
2059*b5893f02SDimitry Andric Asm->EmitLabelDifferenceAsULEB128(Entry.EndSym, Base);
2060*b5893f02SDimitry Andric } else {
2061ff0cc061SDimitry Andric Asm->EmitLabelDifference(Entry.BeginSym, Base, Size);
2062ff0cc061SDimitry Andric Asm->EmitLabelDifference(Entry.EndSym, Base, Size);
2063*b5893f02SDimitry Andric }
2064*b5893f02SDimitry Andric
2065*b5893f02SDimitry Andric emitDebugLocEntryLocation(Entry);
2066*b5893f02SDimitry Andric continue;
2067*b5893f02SDimitry Andric }
2068*b5893f02SDimitry Andric
2069*b5893f02SDimitry Andric // We have no base address.
2070*b5893f02SDimitry Andric if (IsLocLists) {
2071*b5893f02SDimitry Andric // TODO: Use DW_LLE_base_addressx + DW_LLE_offset_pair, or
2072*b5893f02SDimitry Andric // DW_LLE_startx_length in case if there is only a single range.
2073*b5893f02SDimitry Andric // That should reduce the size of the debug data emited.
2074*b5893f02SDimitry Andric // For now just use the DW_LLE_startx_length for all cases.
2075*b5893f02SDimitry Andric Asm->OutStreamer->AddComment("DW_LLE_startx_length");
2076*b5893f02SDimitry Andric Asm->emitInt8(dwarf::DW_LLE_startx_length);
2077*b5893f02SDimitry Andric Asm->OutStreamer->AddComment(" start idx");
2078*b5893f02SDimitry Andric Asm->EmitULEB128(AddrPool.getIndex(Entry.BeginSym));
2079*b5893f02SDimitry Andric Asm->OutStreamer->AddComment(" length");
2080*b5893f02SDimitry Andric Asm->EmitLabelDifferenceAsULEB128(Entry.EndSym, Entry.BeginSym);
208191bc56edSDimitry Andric } else {
2082ff0cc061SDimitry Andric Asm->OutStreamer->EmitSymbolValue(Entry.BeginSym, Size);
2083ff0cc061SDimitry Andric Asm->OutStreamer->EmitSymbolValue(Entry.EndSym, Size);
208491bc56edSDimitry Andric }
208591bc56edSDimitry Andric
208691bc56edSDimitry Andric emitDebugLocEntryLocation(Entry);
208791bc56edSDimitry Andric }
2088*b5893f02SDimitry Andric
2089*b5893f02SDimitry Andric if (IsLocLists) {
2090*b5893f02SDimitry Andric // .debug_loclists section ends with DW_LLE_end_of_list.
2091*b5893f02SDimitry Andric Asm->OutStreamer->AddComment("DW_LLE_end_of_list");
2092*b5893f02SDimitry Andric Asm->OutStreamer->EmitIntValue(dwarf::DW_LLE_end_of_list, 1);
2093*b5893f02SDimitry Andric } else {
2094*b5893f02SDimitry Andric // Terminate the .debug_loc list with two 0 values.
2095ff0cc061SDimitry Andric Asm->OutStreamer->EmitIntValue(0, Size);
2096ff0cc061SDimitry Andric Asm->OutStreamer->EmitIntValue(0, Size);
2097f22ef01cSRoman Divacky }
2098e580952dSDimitry Andric }
2099f22ef01cSRoman Divacky
2100*b5893f02SDimitry Andric if (TableEnd)
2101*b5893f02SDimitry Andric Asm->OutStreamer->EmitLabel(TableEnd);
2102*b5893f02SDimitry Andric }
2103*b5893f02SDimitry Andric
emitDebugLocDWO()210491bc56edSDimitry Andric void DwarfDebug::emitDebugLocDWO() {
2105ff0cc061SDimitry Andric Asm->OutStreamer->SwitchSection(
210691bc56edSDimitry Andric Asm->getObjFileLowering().getDwarfLocDWOSection());
2107ff0cc061SDimitry Andric for (const auto &List : DebugLocs.getLists()) {
2108ff0cc061SDimitry Andric Asm->OutStreamer->EmitLabel(List.Label);
2109ff0cc061SDimitry Andric for (const auto &Entry : DebugLocs.getEntries(List)) {
2110*b5893f02SDimitry Andric // GDB only supports startx_length in pre-standard split-DWARF.
2111*b5893f02SDimitry Andric // (in v5 standard loclists, it currently* /only/ supports base_address +
2112*b5893f02SDimitry Andric // offset_pair, so the implementations can't really share much since they
2113*b5893f02SDimitry Andric // need to use different representations)
2114*b5893f02SDimitry Andric // * as of October 2018, at least
2115*b5893f02SDimitry Andric // Ideally/in v5, this could use SectionLabels to reuse existing addresses
2116*b5893f02SDimitry Andric // in the address pool to minimize object size/relocations.
21174ba319b5SDimitry Andric Asm->emitInt8(dwarf::DW_LLE_startx_length);
2118ff0cc061SDimitry Andric unsigned idx = AddrPool.getIndex(Entry.BeginSym);
211991bc56edSDimitry Andric Asm->EmitULEB128(idx);
2120ff0cc061SDimitry Andric Asm->EmitLabelDifference(Entry.EndSym, Entry.BeginSym, 4);
2121f785676fSDimitry Andric
212291bc56edSDimitry Andric emitDebugLocEntryLocation(Entry);
2123f785676fSDimitry Andric }
21244ba319b5SDimitry Andric Asm->emitInt8(dwarf::DW_LLE_end_of_list);
212591bc56edSDimitry Andric }
2126f785676fSDimitry Andric }
2127f785676fSDimitry Andric
2128f785676fSDimitry Andric struct ArangeSpan {
2129f785676fSDimitry Andric const MCSymbol *Start, *End;
2130f785676fSDimitry Andric };
2131f785676fSDimitry Andric
2132f785676fSDimitry Andric // Emit a debug aranges section, containing a CU lookup for any
2133f785676fSDimitry Andric // address we can tie back to a CU.
emitDebugARanges()2134139f7f9bSDimitry Andric void DwarfDebug::emitDebugARanges() {
2135ff0cc061SDimitry Andric // Provides a unique id per text section.
2136ff0cc061SDimitry Andric MapVector<MCSection *, SmallVector<SymbolCU, 8>> SectionMap;
2137f785676fSDimitry Andric
2138ff0cc061SDimitry Andric // Filter labels by section.
2139ff0cc061SDimitry Andric for (const SymbolCU &SCU : ArangeLabels) {
2140ff0cc061SDimitry Andric if (SCU.Sym->isInSection()) {
2141ff0cc061SDimitry Andric // Make a note of this symbol and it's section.
2142ff0cc061SDimitry Andric MCSection *Section = &SCU.Sym->getSection();
2143ff0cc061SDimitry Andric if (!Section->getKind().isMetadata())
2144ff0cc061SDimitry Andric SectionMap[Section].push_back(SCU);
2145ff0cc061SDimitry Andric } else {
2146ff0cc061SDimitry Andric // Some symbols (e.g. common/bss on mach-o) can have no section but still
2147ff0cc061SDimitry Andric // appear in the output. This sucks as we rely on sections to build
2148ff0cc061SDimitry Andric // arange spans. We can do it without, but it's icky.
2149ff0cc061SDimitry Andric SectionMap[nullptr].push_back(SCU);
2150ff0cc061SDimitry Andric }
2151f785676fSDimitry Andric }
2152f785676fSDimitry Andric
2153ff0cc061SDimitry Andric DenseMap<DwarfCompileUnit *, std::vector<ArangeSpan>> Spans;
2154ff0cc061SDimitry Andric
2155ff0cc061SDimitry Andric for (auto &I : SectionMap) {
21563ca95b02SDimitry Andric MCSection *Section = I.first;
2157ff0cc061SDimitry Andric SmallVector<SymbolCU, 8> &List = I.second;
21583ca95b02SDimitry Andric if (List.size() < 1)
2159f785676fSDimitry Andric continue;
2160f785676fSDimitry Andric
2161f785676fSDimitry Andric // If we have no section (e.g. common), just write out
2162f785676fSDimitry Andric // individual spans for each symbol.
216391bc56edSDimitry Andric if (!Section) {
216491bc56edSDimitry Andric for (const SymbolCU &Cur : List) {
2165f785676fSDimitry Andric ArangeSpan Span;
2166f785676fSDimitry Andric Span.Start = Cur.Sym;
216791bc56edSDimitry Andric Span.End = nullptr;
21683ca95b02SDimitry Andric assert(Cur.CU);
2169f785676fSDimitry Andric Spans[Cur.CU].push_back(Span);
2170f785676fSDimitry Andric }
2171ff0cc061SDimitry Andric continue;
2172ff0cc061SDimitry Andric }
2173ff0cc061SDimitry Andric
2174ff0cc061SDimitry Andric // Sort the symbols by offset within the section.
21754ba319b5SDimitry Andric std::stable_sort(
21763ca95b02SDimitry Andric List.begin(), List.end(), [&](const SymbolCU &A, const SymbolCU &B) {
2177ff0cc061SDimitry Andric unsigned IA = A.Sym ? Asm->OutStreamer->GetSymbolOrder(A.Sym) : 0;
2178ff0cc061SDimitry Andric unsigned IB = B.Sym ? Asm->OutStreamer->GetSymbolOrder(B.Sym) : 0;
2179ff0cc061SDimitry Andric
2180ff0cc061SDimitry Andric // Symbols with no order assigned should be placed at the end.
2181ff0cc061SDimitry Andric // (e.g. section end labels)
2182ff0cc061SDimitry Andric if (IA == 0)
2183ff0cc061SDimitry Andric return false;
2184ff0cc061SDimitry Andric if (IB == 0)
2185ff0cc061SDimitry Andric return true;
2186ff0cc061SDimitry Andric return IA < IB;
2187ff0cc061SDimitry Andric });
2188ff0cc061SDimitry Andric
21893ca95b02SDimitry Andric // Insert a final terminator.
21903ca95b02SDimitry Andric List.push_back(SymbolCU(nullptr, Asm->OutStreamer->endSection(Section)));
21913ca95b02SDimitry Andric
2192f785676fSDimitry Andric // Build spans between each label.
2193f785676fSDimitry Andric const MCSymbol *StartSym = List[0].Sym;
219491bc56edSDimitry Andric for (size_t n = 1, e = List.size(); n < e; n++) {
2195f785676fSDimitry Andric const SymbolCU &Prev = List[n - 1];
2196f785676fSDimitry Andric const SymbolCU &Cur = List[n];
2197f785676fSDimitry Andric
2198f785676fSDimitry Andric // Try and build the longest span we can within the same CU.
2199f785676fSDimitry Andric if (Cur.CU != Prev.CU) {
2200f785676fSDimitry Andric ArangeSpan Span;
2201f785676fSDimitry Andric Span.Start = StartSym;
2202f785676fSDimitry Andric Span.End = Cur.Sym;
22033ca95b02SDimitry Andric assert(Prev.CU);
2204f785676fSDimitry Andric Spans[Prev.CU].push_back(Span);
2205f785676fSDimitry Andric StartSym = Cur.Sym;
2206f785676fSDimitry Andric }
2207f785676fSDimitry Andric }
2208f785676fSDimitry Andric }
2209ff0cc061SDimitry Andric
2210ff0cc061SDimitry Andric // Start the dwarf aranges section.
2211ff0cc061SDimitry Andric Asm->OutStreamer->SwitchSection(
2212ff0cc061SDimitry Andric Asm->getObjFileLowering().getDwarfARangesSection());
2213f785676fSDimitry Andric
22146bc11b14SDimitry Andric unsigned PtrSize = Asm->MAI->getCodePointerSize();
2215f785676fSDimitry Andric
2216f785676fSDimitry Andric // Build a list of CUs used.
221791bc56edSDimitry Andric std::vector<DwarfCompileUnit *> CUs;
221891bc56edSDimitry Andric for (const auto &it : Spans) {
221991bc56edSDimitry Andric DwarfCompileUnit *CU = it.first;
2220f785676fSDimitry Andric CUs.push_back(CU);
2221f785676fSDimitry Andric }
2222f785676fSDimitry Andric
2223f785676fSDimitry Andric // Sort the CU list (again, to ensure consistent output order).
2224*b5893f02SDimitry Andric llvm::sort(CUs, [](const DwarfCompileUnit *A, const DwarfCompileUnit *B) {
222591bc56edSDimitry Andric return A->getUniqueID() < B->getUniqueID();
222691bc56edSDimitry Andric });
2227f785676fSDimitry Andric
2228f785676fSDimitry Andric // Emit an arange table for each CU we used.
222991bc56edSDimitry Andric for (DwarfCompileUnit *CU : CUs) {
2230f785676fSDimitry Andric std::vector<ArangeSpan> &List = Spans[CU];
2231f785676fSDimitry Andric
223239d628a0SDimitry Andric // Describe the skeleton CU's offset and length, not the dwo file's.
223339d628a0SDimitry Andric if (auto *Skel = CU->getSkeleton())
223439d628a0SDimitry Andric CU = Skel;
223539d628a0SDimitry Andric
2236f785676fSDimitry Andric // Emit size of content not including length itself.
223791bc56edSDimitry Andric unsigned ContentSize =
223891bc56edSDimitry Andric sizeof(int16_t) + // DWARF ARange version number
223991bc56edSDimitry Andric sizeof(int32_t) + // Offset of CU in the .debug_info section
224091bc56edSDimitry Andric sizeof(int8_t) + // Pointer Size (in bytes)
224191bc56edSDimitry Andric sizeof(int8_t); // Segment Size (in bytes)
2242f785676fSDimitry Andric
2243f785676fSDimitry Andric unsigned TupleSize = PtrSize * 2;
2244f785676fSDimitry Andric
2245f785676fSDimitry Andric // 7.20 in the Dwarf specs requires the table to be aligned to a tuple.
224691bc56edSDimitry Andric unsigned Padding =
224791bc56edSDimitry Andric OffsetToAlignment(sizeof(int32_t) + ContentSize, TupleSize);
2248f785676fSDimitry Andric
2249f785676fSDimitry Andric ContentSize += Padding;
2250f785676fSDimitry Andric ContentSize += (List.size() + 1) * TupleSize;
2251f785676fSDimitry Andric
2252f785676fSDimitry Andric // For each compile unit, write the list of spans it covers.
2253ff0cc061SDimitry Andric Asm->OutStreamer->AddComment("Length of ARange Set");
22544ba319b5SDimitry Andric Asm->emitInt32(ContentSize);
2255ff0cc061SDimitry Andric Asm->OutStreamer->AddComment("DWARF Arange version number");
22564ba319b5SDimitry Andric Asm->emitInt16(dwarf::DW_ARANGES_VERSION);
2257ff0cc061SDimitry Andric Asm->OutStreamer->AddComment("Offset Into Debug Info Section");
22584ba319b5SDimitry Andric emitSectionReference(*CU);
2259ff0cc061SDimitry Andric Asm->OutStreamer->AddComment("Address Size (in bytes)");
22604ba319b5SDimitry Andric Asm->emitInt8(PtrSize);
2261ff0cc061SDimitry Andric Asm->OutStreamer->AddComment("Segment Size (in bytes)");
22624ba319b5SDimitry Andric Asm->emitInt8(0);
2263f785676fSDimitry Andric
22643ca95b02SDimitry Andric Asm->OutStreamer->emitFill(Padding, 0xff);
2265f785676fSDimitry Andric
226691bc56edSDimitry Andric for (const ArangeSpan &Span : List) {
2267f785676fSDimitry Andric Asm->EmitLabelReference(Span.Start, PtrSize);
2268f785676fSDimitry Andric
2269f785676fSDimitry Andric // Calculate the size as being from the span start to it's end.
2270f785676fSDimitry Andric if (Span.End) {
2271f785676fSDimitry Andric Asm->EmitLabelDifference(Span.End, Span.Start, PtrSize);
2272f785676fSDimitry Andric } else {
2273f785676fSDimitry Andric // For symbols without an end marker (e.g. common), we
2274f785676fSDimitry Andric // write a single arange entry containing just that one symbol.
2275f785676fSDimitry Andric uint64_t Size = SymSize[Span.Start];
2276f785676fSDimitry Andric if (Size == 0)
2277f785676fSDimitry Andric Size = 1;
2278f785676fSDimitry Andric
2279ff0cc061SDimitry Andric Asm->OutStreamer->EmitIntValue(Size, PtrSize);
2280f785676fSDimitry Andric }
2281f785676fSDimitry Andric }
2282f785676fSDimitry Andric
2283ff0cc061SDimitry Andric Asm->OutStreamer->AddComment("ARange terminator");
2284ff0cc061SDimitry Andric Asm->OutStreamer->EmitIntValue(0, PtrSize);
2285ff0cc061SDimitry Andric Asm->OutStreamer->EmitIntValue(0, PtrSize);
2286f785676fSDimitry Andric }
2287f22ef01cSRoman Divacky }
2288f22ef01cSRoman Divacky
22894ba319b5SDimitry Andric /// Emit a single range list. We handle both DWARF v5 and earlier.
emitRangeList(DwarfDebug & DD,AsmPrinter * Asm,const RangeSpanList & List)2290*b5893f02SDimitry Andric static void emitRangeList(DwarfDebug &DD, AsmPrinter *Asm,
22914ba319b5SDimitry Andric const RangeSpanList &List) {
2292302affcbSDimitry Andric
2293*b5893f02SDimitry Andric auto DwarfVersion = DD.getDwarfVersion();
229491bc56edSDimitry Andric // Emit our symbol so we can find the beginning of the range.
2295ff0cc061SDimitry Andric Asm->OutStreamer->EmitLabel(List.getSym());
22962cab237bSDimitry Andric // Gather all the ranges that apply to the same section so they can share
22972cab237bSDimitry Andric // a base address entry.
22984ba319b5SDimitry Andric MapVector<const MCSection *, std::vector<const RangeSpan *>> SectionRanges;
22994ba319b5SDimitry Andric // Size for our labels.
23004ba319b5SDimitry Andric auto Size = Asm->MAI->getCodePointerSize();
23012cab237bSDimitry Andric
23024ba319b5SDimitry Andric for (const RangeSpan &Range : List.getRanges())
23034ba319b5SDimitry Andric SectionRanges[&Range.getStart()->getSection()].push_back(&Range);
23044ba319b5SDimitry Andric
2305*b5893f02SDimitry Andric const DwarfCompileUnit &CU = List.getCU();
2306*b5893f02SDimitry Andric const MCSymbol *CUBase = CU.getBaseAddress();
23072cab237bSDimitry Andric bool BaseIsSet = false;
23084ba319b5SDimitry Andric for (const auto &P : SectionRanges) {
23092cab237bSDimitry Andric // Don't bother with a base address entry if there's only one range in
23102cab237bSDimitry Andric // this section in this range list - for example ranges for a CU will
23112cab237bSDimitry Andric // usually consist of single regions from each of many sections
23122cab237bSDimitry Andric // (-ffunction-sections, or just C++ inline functions) except under LTO
23132cab237bSDimitry Andric // or optnone where there may be holes in a single CU's section
23144ba319b5SDimitry Andric // contributions.
23152cab237bSDimitry Andric auto *Base = CUBase;
2316*b5893f02SDimitry Andric if (!Base && (P.second.size() > 1 || DwarfVersion < 5) &&
2317*b5893f02SDimitry Andric (CU.getCUNode()->getRangesBaseAddress() || DwarfVersion >= 5)) {
23182cab237bSDimitry Andric BaseIsSet = true;
23192cab237bSDimitry Andric // FIXME/use care: This may not be a useful base address if it's not
23202cab237bSDimitry Andric // the lowest address/range in this object.
23212cab237bSDimitry Andric Base = P.second.front()->getStart();
23224ba319b5SDimitry Andric if (DwarfVersion >= 5) {
2323*b5893f02SDimitry Andric Base = DD.getSectionLabel(&Base->getSection());
2324*b5893f02SDimitry Andric Asm->OutStreamer->AddComment("DW_RLE_base_addressx");
2325*b5893f02SDimitry Andric Asm->OutStreamer->EmitIntValue(dwarf::DW_RLE_base_addressx, 1);
2326*b5893f02SDimitry Andric Asm->OutStreamer->AddComment(" base address index");
2327*b5893f02SDimitry Andric Asm->EmitULEB128(DD.getAddressPool().getIndex(Base));
2328*b5893f02SDimitry Andric } else {
23292cab237bSDimitry Andric Asm->OutStreamer->EmitIntValue(-1, Size);
23304ba319b5SDimitry Andric Asm->OutStreamer->AddComment(" base address");
23312cab237bSDimitry Andric Asm->OutStreamer->EmitSymbolValue(Base, Size);
2332*b5893f02SDimitry Andric }
23334ba319b5SDimitry Andric } else if (BaseIsSet && DwarfVersion < 5) {
23342cab237bSDimitry Andric BaseIsSet = false;
23354ba319b5SDimitry Andric assert(!Base);
23362cab237bSDimitry Andric Asm->OutStreamer->EmitIntValue(-1, Size);
23372cab237bSDimitry Andric Asm->OutStreamer->EmitIntValue(0, Size);
23382cab237bSDimitry Andric }
23392cab237bSDimitry Andric
23402cab237bSDimitry Andric for (const auto *RS : P.second) {
23412cab237bSDimitry Andric const MCSymbol *Begin = RS->getStart();
23422cab237bSDimitry Andric const MCSymbol *End = RS->getEnd();
234391bc56edSDimitry Andric assert(Begin && "Range without a begin symbol?");
234491bc56edSDimitry Andric assert(End && "Range without an end symbol?");
23452cab237bSDimitry Andric if (Base) {
23464ba319b5SDimitry Andric if (DwarfVersion >= 5) {
23474ba319b5SDimitry Andric // Emit DW_RLE_offset_pair when we have a base.
23484ba319b5SDimitry Andric Asm->OutStreamer->AddComment("DW_RLE_offset_pair");
23494ba319b5SDimitry Andric Asm->OutStreamer->EmitIntValue(dwarf::DW_RLE_offset_pair, 1);
23504ba319b5SDimitry Andric Asm->OutStreamer->AddComment(" starting offset");
23514ba319b5SDimitry Andric Asm->EmitLabelDifferenceAsULEB128(Begin, Base);
23524ba319b5SDimitry Andric Asm->OutStreamer->AddComment(" ending offset");
23534ba319b5SDimitry Andric Asm->EmitLabelDifferenceAsULEB128(End, Base);
23544ba319b5SDimitry Andric } else {
235591bc56edSDimitry Andric Asm->EmitLabelDifference(Begin, Base, Size);
235691bc56edSDimitry Andric Asm->EmitLabelDifference(End, Base, Size);
23574ba319b5SDimitry Andric }
23584ba319b5SDimitry Andric } else if (DwarfVersion >= 5) {
2359*b5893f02SDimitry Andric Asm->OutStreamer->AddComment("DW_RLE_startx_length");
2360*b5893f02SDimitry Andric Asm->OutStreamer->EmitIntValue(dwarf::DW_RLE_startx_length, 1);
2361*b5893f02SDimitry Andric Asm->OutStreamer->AddComment(" start index");
2362*b5893f02SDimitry Andric Asm->EmitULEB128(DD.getAddressPool().getIndex(Begin));
23634ba319b5SDimitry Andric Asm->OutStreamer->AddComment(" length");
23644ba319b5SDimitry Andric Asm->EmitLabelDifferenceAsULEB128(End, Begin);
236591bc56edSDimitry Andric } else {
2366ff0cc061SDimitry Andric Asm->OutStreamer->EmitSymbolValue(Begin, Size);
2367ff0cc061SDimitry Andric Asm->OutStreamer->EmitSymbolValue(End, Size);
2368f22ef01cSRoman Divacky }
2369f22ef01cSRoman Divacky }
23702cab237bSDimitry Andric }
23714ba319b5SDimitry Andric if (DwarfVersion >= 5) {
23724ba319b5SDimitry Andric Asm->OutStreamer->AddComment("DW_RLE_end_of_list");
23734ba319b5SDimitry Andric Asm->OutStreamer->EmitIntValue(dwarf::DW_RLE_end_of_list, 1);
23744ba319b5SDimitry Andric } else {
23754ba319b5SDimitry Andric // Terminate the list with two 0 values.
23764ba319b5SDimitry Andric Asm->OutStreamer->EmitIntValue(0, Size);
23774ba319b5SDimitry Andric Asm->OutStreamer->EmitIntValue(0, Size);
23784ba319b5SDimitry Andric }
23794ba319b5SDimitry Andric }
2380f22ef01cSRoman Divacky
emitDebugRangesImpl(DwarfDebug & DD,AsmPrinter * Asm,const DwarfFile & Holder,MCSymbol * TableEnd)2381*b5893f02SDimitry Andric static void emitDebugRangesImpl(DwarfDebug &DD, AsmPrinter *Asm,
2382*b5893f02SDimitry Andric const DwarfFile &Holder, MCSymbol *TableEnd) {
2383*b5893f02SDimitry Andric for (const RangeSpanList &List : Holder.getRangeLists())
2384*b5893f02SDimitry Andric emitRangeList(DD, Asm, List);
23854ba319b5SDimitry Andric
2386*b5893f02SDimitry Andric if (TableEnd)
2387*b5893f02SDimitry Andric Asm->OutStreamer->EmitLabel(TableEnd);
238891bc56edSDimitry Andric }
23894ba319b5SDimitry Andric
23904ba319b5SDimitry Andric /// Emit address ranges into the .debug_ranges section or into the DWARF v5
23914ba319b5SDimitry Andric /// .debug_rnglists section.
emitDebugRanges()23924ba319b5SDimitry Andric void DwarfDebug::emitDebugRanges() {
23934ba319b5SDimitry Andric if (CUMap.empty())
23944ba319b5SDimitry Andric return;
23954ba319b5SDimitry Andric
2396*b5893f02SDimitry Andric const auto &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder;
23974ba319b5SDimitry Andric
2398*b5893f02SDimitry Andric if (Holder.getRangeLists().empty())
23994ba319b5SDimitry Andric return;
24004ba319b5SDimitry Andric
2401*b5893f02SDimitry Andric assert(useRangesSection());
2402*b5893f02SDimitry Andric assert(llvm::none_of(CUMap, [](const decltype(CUMap)::value_type &Pair) {
2403*b5893f02SDimitry Andric return Pair.second->getCUNode()->isDebugDirectivesOnly();
2404*b5893f02SDimitry Andric }));
24054ba319b5SDimitry Andric
24064ba319b5SDimitry Andric // Start the dwarf ranges section.
24074ba319b5SDimitry Andric MCSymbol *TableEnd = nullptr;
24084ba319b5SDimitry Andric if (getDwarfVersion() >= 5) {
24094ba319b5SDimitry Andric Asm->OutStreamer->SwitchSection(
24104ba319b5SDimitry Andric Asm->getObjFileLowering().getDwarfRnglistsSection());
2411*b5893f02SDimitry Andric TableEnd = emitRnglistsTableHeader(Asm, Holder);
24124ba319b5SDimitry Andric } else
24134ba319b5SDimitry Andric Asm->OutStreamer->SwitchSection(
24144ba319b5SDimitry Andric Asm->getObjFileLowering().getDwarfRangesSection());
24154ba319b5SDimitry Andric
2416*b5893f02SDimitry Andric emitDebugRangesImpl(*this, Asm, Holder, TableEnd);
24174ba319b5SDimitry Andric }
24184ba319b5SDimitry Andric
emitDebugRangesDWO()2419*b5893f02SDimitry Andric void DwarfDebug::emitDebugRangesDWO() {
2420*b5893f02SDimitry Andric assert(useSplitDwarf());
2421*b5893f02SDimitry Andric
2422*b5893f02SDimitry Andric if (CUMap.empty())
2423*b5893f02SDimitry Andric return;
2424*b5893f02SDimitry Andric
2425*b5893f02SDimitry Andric const auto &Holder = InfoHolder;
2426*b5893f02SDimitry Andric
2427*b5893f02SDimitry Andric if (Holder.getRangeLists().empty())
2428*b5893f02SDimitry Andric return;
2429*b5893f02SDimitry Andric
2430*b5893f02SDimitry Andric assert(getDwarfVersion() >= 5);
2431*b5893f02SDimitry Andric assert(useRangesSection());
2432*b5893f02SDimitry Andric assert(llvm::none_of(CUMap, [](const decltype(CUMap)::value_type &Pair) {
2433*b5893f02SDimitry Andric return Pair.second->getCUNode()->isDebugDirectivesOnly();
2434*b5893f02SDimitry Andric }));
2435*b5893f02SDimitry Andric
2436*b5893f02SDimitry Andric // Start the dwarf ranges section.
2437*b5893f02SDimitry Andric Asm->OutStreamer->SwitchSection(
2438*b5893f02SDimitry Andric Asm->getObjFileLowering().getDwarfRnglistsDWOSection());
2439*b5893f02SDimitry Andric MCSymbol *TableEnd = emitRnglistsTableHeader(Asm, Holder);
2440*b5893f02SDimitry Andric
2441*b5893f02SDimitry Andric emitDebugRangesImpl(*this, Asm, Holder, TableEnd);
2442f22ef01cSRoman Divacky }
2443f22ef01cSRoman Divacky
handleMacroNodes(DIMacroNodeArray Nodes,DwarfCompileUnit & U)24443ca95b02SDimitry Andric void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes, DwarfCompileUnit &U) {
2445444ed5c5SDimitry Andric for (auto *MN : Nodes) {
2446444ed5c5SDimitry Andric if (auto *M = dyn_cast<DIMacro>(MN))
24473ca95b02SDimitry Andric emitMacro(*M);
2448444ed5c5SDimitry Andric else if (auto *F = dyn_cast<DIMacroFile>(MN))
24493ca95b02SDimitry Andric emitMacroFile(*F, U);
2450444ed5c5SDimitry Andric else
2451444ed5c5SDimitry Andric llvm_unreachable("Unexpected DI type!");
2452444ed5c5SDimitry Andric }
2453444ed5c5SDimitry Andric }
2454444ed5c5SDimitry Andric
emitMacro(DIMacro & M)24553ca95b02SDimitry Andric void DwarfDebug::emitMacro(DIMacro &M) {
24563ca95b02SDimitry Andric Asm->EmitULEB128(M.getMacinfoType());
24573ca95b02SDimitry Andric Asm->EmitULEB128(M.getLine());
2458444ed5c5SDimitry Andric StringRef Name = M.getName();
2459444ed5c5SDimitry Andric StringRef Value = M.getValue();
24603ca95b02SDimitry Andric Asm->OutStreamer->EmitBytes(Name);
2461444ed5c5SDimitry Andric if (!Value.empty()) {
2462444ed5c5SDimitry Andric // There should be one space between macro name and macro value.
24634ba319b5SDimitry Andric Asm->emitInt8(' ');
24643ca95b02SDimitry Andric Asm->OutStreamer->EmitBytes(Value);
2465444ed5c5SDimitry Andric }
24664ba319b5SDimitry Andric Asm->emitInt8('\0');
2467444ed5c5SDimitry Andric }
2468444ed5c5SDimitry Andric
emitMacroFile(DIMacroFile & F,DwarfCompileUnit & U)24693ca95b02SDimitry Andric void DwarfDebug::emitMacroFile(DIMacroFile &F, DwarfCompileUnit &U) {
2470444ed5c5SDimitry Andric assert(F.getMacinfoType() == dwarf::DW_MACINFO_start_file);
24713ca95b02SDimitry Andric Asm->EmitULEB128(dwarf::DW_MACINFO_start_file);
24723ca95b02SDimitry Andric Asm->EmitULEB128(F.getLine());
24734ba319b5SDimitry Andric Asm->EmitULEB128(U.getOrCreateSourceID(F.getFile()));
24743ca95b02SDimitry Andric handleMacroNodes(F.getElements(), U);
24753ca95b02SDimitry Andric Asm->EmitULEB128(dwarf::DW_MACINFO_end_file);
2476444ed5c5SDimitry Andric }
2477444ed5c5SDimitry Andric
24783ca95b02SDimitry Andric /// Emit macros into a debug macinfo section.
emitDebugMacinfo()2479444ed5c5SDimitry Andric void DwarfDebug::emitDebugMacinfo() {
2480302affcbSDimitry Andric if (CUMap.empty())
2481302affcbSDimitry Andric return;
2482302affcbSDimitry Andric
2483*b5893f02SDimitry Andric if (llvm::all_of(CUMap, [](const decltype(CUMap)::value_type &Pair) {
2484*b5893f02SDimitry Andric return Pair.second->getCUNode()->isDebugDirectivesOnly();
2485*b5893f02SDimitry Andric }))
2486*b5893f02SDimitry Andric return;
2487*b5893f02SDimitry Andric
2488444ed5c5SDimitry Andric // Start the dwarf macinfo section.
24893ca95b02SDimitry Andric Asm->OutStreamer->SwitchSection(
24903ca95b02SDimitry Andric Asm->getObjFileLowering().getDwarfMacinfoSection());
24913ca95b02SDimitry Andric
2492444ed5c5SDimitry Andric for (const auto &P : CUMap) {
2493444ed5c5SDimitry Andric auto &TheCU = *P.second;
2494*b5893f02SDimitry Andric if (TheCU.getCUNode()->isDebugDirectivesOnly())
2495*b5893f02SDimitry Andric continue;
2496444ed5c5SDimitry Andric auto *SkCU = TheCU.getSkeleton();
2497444ed5c5SDimitry Andric DwarfCompileUnit &U = SkCU ? *SkCU : TheCU;
2498444ed5c5SDimitry Andric auto *CUNode = cast<DICompileUnit>(P.first);
24994ba319b5SDimitry Andric DIMacroNodeArray Macros = CUNode->getMacros();
25004ba319b5SDimitry Andric if (!Macros.empty()) {
25013ca95b02SDimitry Andric Asm->OutStreamer->EmitLabel(U.getMacroLabelBegin());
25024ba319b5SDimitry Andric handleMacroNodes(Macros, U);
25034ba319b5SDimitry Andric }
2504444ed5c5SDimitry Andric }
2505444ed5c5SDimitry Andric Asm->OutStreamer->AddComment("End Of Macro List Mark");
25064ba319b5SDimitry Andric Asm->emitInt8(0);
2507444ed5c5SDimitry Andric }
2508444ed5c5SDimitry Andric
2509139f7f9bSDimitry Andric // DWARF5 Experimental Separate Dwarf emitters.
2510139f7f9bSDimitry Andric
initSkeletonUnit(const DwarfUnit & U,DIE & Die,std::unique_ptr<DwarfCompileUnit> NewU)251191bc56edSDimitry Andric void DwarfDebug::initSkeletonUnit(const DwarfUnit &U, DIE &Die,
25123ca95b02SDimitry Andric std::unique_ptr<DwarfCompileUnit> NewU) {
2513139f7f9bSDimitry Andric
2514139f7f9bSDimitry Andric if (!CompilationDir.empty())
251539d628a0SDimitry Andric NewU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
2516139f7f9bSDimitry Andric
251791bc56edSDimitry Andric addGnuPubAttributes(*NewU, Die);
2518f785676fSDimitry Andric
251991bc56edSDimitry Andric SkeletonHolder.addUnit(std::move(NewU));
2520f785676fSDimitry Andric }
2521f785676fSDimitry Andric
constructSkeletonCU(const DwarfCompileUnit & CU)252291bc56edSDimitry Andric DwarfCompileUnit &DwarfDebug::constructSkeletonCU(const DwarfCompileUnit &CU) {
2523f785676fSDimitry Andric
25242cab237bSDimitry Andric auto OwnedUnit = llvm::make_unique<DwarfCompileUnit>(
252591bc56edSDimitry Andric CU.getUniqueID(), CU.getCUNode(), Asm, this, &SkeletonHolder);
252691bc56edSDimitry Andric DwarfCompileUnit &NewCU = *OwnedUnit;
2527d88c1a5aSDimitry Andric NewCU.setSection(Asm->getObjFileLowering().getDwarfInfoSection());
252891bc56edSDimitry Andric
2529ff0cc061SDimitry Andric NewCU.initStmtList();
253091bc56edSDimitry Andric
25314ba319b5SDimitry Andric if (useSegmentedStringOffsetsTable())
25324ba319b5SDimitry Andric NewCU.addStringOffsetsStart();
25334ba319b5SDimitry Andric
253491bc56edSDimitry Andric initSkeletonUnit(CU, NewCU.getUnitDie(), std::move(OwnedUnit));
2535139f7f9bSDimitry Andric
2536139f7f9bSDimitry Andric return NewCU;
2537139f7f9bSDimitry Andric }
2538139f7f9bSDimitry Andric
2539139f7f9bSDimitry Andric // Emit the .debug_info.dwo section for separated dwarf. This contains the
2540139f7f9bSDimitry Andric // compile units that would normally be in debug_info.
emitDebugInfoDWO()2541139f7f9bSDimitry Andric void DwarfDebug::emitDebugInfoDWO() {
2542139f7f9bSDimitry Andric assert(useSplitDwarf() && "No split dwarf debug info?");
2543ff0cc061SDimitry Andric // Don't emit relocations into the dwo file.
2544ff0cc061SDimitry Andric InfoHolder.emitUnits(/* UseOffsets */ true);
2545139f7f9bSDimitry Andric }
2546139f7f9bSDimitry Andric
2547139f7f9bSDimitry Andric // Emit the .debug_abbrev.dwo section for separated dwarf. This contains the
2548139f7f9bSDimitry Andric // abbreviations for the .debug_info.dwo section.
emitDebugAbbrevDWO()2549139f7f9bSDimitry Andric void DwarfDebug::emitDebugAbbrevDWO() {
2550139f7f9bSDimitry Andric assert(useSplitDwarf() && "No split dwarf?");
255191bc56edSDimitry Andric InfoHolder.emitAbbrevs(Asm->getObjFileLowering().getDwarfAbbrevDWOSection());
255291bc56edSDimitry Andric }
255391bc56edSDimitry Andric
emitDebugLineDWO()255491bc56edSDimitry Andric void DwarfDebug::emitDebugLineDWO() {
255591bc56edSDimitry Andric assert(useSplitDwarf() && "No split dwarf?");
25564ba319b5SDimitry Andric SplitTypeUnitFileTable.Emit(
25574ba319b5SDimitry Andric *Asm->OutStreamer, MCDwarfLineTableParams(),
255891bc56edSDimitry Andric Asm->getObjFileLowering().getDwarfLineDWOSection());
25594ba319b5SDimitry Andric }
25604ba319b5SDimitry Andric
emitStringOffsetsTableHeaderDWO()25614ba319b5SDimitry Andric void DwarfDebug::emitStringOffsetsTableHeaderDWO() {
25624ba319b5SDimitry Andric assert(useSplitDwarf() && "No split dwarf?");
25634ba319b5SDimitry Andric InfoHolder.getStringPool().emitStringOffsetsTableHeader(
25644ba319b5SDimitry Andric *Asm, Asm->getObjFileLowering().getDwarfStrOffDWOSection(),
25654ba319b5SDimitry Andric InfoHolder.getStringOffsetsStartSym());
2566139f7f9bSDimitry Andric }
2567139f7f9bSDimitry Andric
2568139f7f9bSDimitry Andric // Emit the .debug_str.dwo section for separated dwarf. This contains the
2569139f7f9bSDimitry Andric // string section and is identical in format to traditional .debug_str
2570139f7f9bSDimitry Andric // sections.
emitDebugStrDWO()2571139f7f9bSDimitry Andric void DwarfDebug::emitDebugStrDWO() {
25724ba319b5SDimitry Andric if (useSegmentedStringOffsetsTable())
25734ba319b5SDimitry Andric emitStringOffsetsTableHeaderDWO();
2574139f7f9bSDimitry Andric assert(useSplitDwarf() && "No split dwarf?");
2575ff0cc061SDimitry Andric MCSection *OffSec = Asm->getObjFileLowering().getDwarfStrOffDWOSection();
2576139f7f9bSDimitry Andric InfoHolder.emitStrings(Asm->getObjFileLowering().getDwarfStrDWOSection(),
25774ba319b5SDimitry Andric OffSec, /* UseRelativeOffsets = */ false);
25784ba319b5SDimitry Andric }
25794ba319b5SDimitry Andric
2580*b5893f02SDimitry Andric // Emit address pool.
emitDebugAddr()25814ba319b5SDimitry Andric void DwarfDebug::emitDebugAddr() {
25824ba319b5SDimitry Andric AddrPool.emit(*Asm, Asm->getObjFileLowering().getDwarfAddrSection());
2583139f7f9bSDimitry Andric }
258491bc56edSDimitry Andric
getDwoLineTable(const DwarfCompileUnit & CU)258591bc56edSDimitry Andric MCDwarfDwoLineTable *DwarfDebug::getDwoLineTable(const DwarfCompileUnit &CU) {
258691bc56edSDimitry Andric if (!useSplitDwarf())
258791bc56edSDimitry Andric return nullptr;
25884ba319b5SDimitry Andric const DICompileUnit *DIUnit = CU.getCUNode();
25894ba319b5SDimitry Andric SplitTypeUnitFileTable.maybeSetRootFile(
25904ba319b5SDimitry Andric DIUnit->getDirectory(), DIUnit->getFilename(),
25914ba319b5SDimitry Andric CU.getMD5AsBytes(DIUnit->getFile()), DIUnit->getSource());
259291bc56edSDimitry Andric return &SplitTypeUnitFileTable;
259391bc56edSDimitry Andric }
259491bc56edSDimitry Andric
makeTypeSignature(StringRef Identifier)25957d523365SDimitry Andric uint64_t DwarfDebug::makeTypeSignature(StringRef Identifier) {
259691bc56edSDimitry Andric MD5 Hash;
259791bc56edSDimitry Andric Hash.update(Identifier);
259891bc56edSDimitry Andric // ... take the least significant 8 bytes and return those. Our MD5
25997a7e6055SDimitry Andric // implementation always returns its results in little endian, so we actually
26007a7e6055SDimitry Andric // need the "high" word.
260191bc56edSDimitry Andric MD5::MD5Result Result;
260291bc56edSDimitry Andric Hash.final(Result);
26037a7e6055SDimitry Andric return Result.high();
260491bc56edSDimitry Andric }
260591bc56edSDimitry Andric
addDwarfTypeUnitType(DwarfCompileUnit & CU,StringRef Identifier,DIE & RefDie,const DICompositeType * CTy)260691bc56edSDimitry Andric void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU,
260791bc56edSDimitry Andric StringRef Identifier, DIE &RefDie,
2608ff0cc061SDimitry Andric const DICompositeType *CTy) {
260991bc56edSDimitry Andric // Fast path if we're building some type units and one has already used the
261091bc56edSDimitry Andric // address pool we know we're going to throw away all this work anyway, so
261191bc56edSDimitry Andric // don't bother building dependent types.
261291bc56edSDimitry Andric if (!TypeUnitsUnderConstruction.empty() && AddrPool.hasBeenUsed())
261391bc56edSDimitry Andric return;
261491bc56edSDimitry Andric
26153ca95b02SDimitry Andric auto Ins = TypeSignatures.insert(std::make_pair(CTy, 0));
26163ca95b02SDimitry Andric if (!Ins.second) {
26173ca95b02SDimitry Andric CU.addDIETypeSignature(RefDie, Ins.first->second);
261891bc56edSDimitry Andric return;
261991bc56edSDimitry Andric }
262091bc56edSDimitry Andric
262191bc56edSDimitry Andric bool TopLevelType = TypeUnitsUnderConstruction.empty();
262291bc56edSDimitry Andric AddrPool.resetUsedFlag();
262391bc56edSDimitry Andric
26242cab237bSDimitry Andric auto OwnedUnit = llvm::make_unique<DwarfTypeUnit>(CU, Asm, this, &InfoHolder,
26253ca95b02SDimitry Andric getDwoLineTable(CU));
262691bc56edSDimitry Andric DwarfTypeUnit &NewTU = *OwnedUnit;
262791bc56edSDimitry Andric DIE &UnitDie = NewTU.getUnitDie();
2628d88c1a5aSDimitry Andric TypeUnitsUnderConstruction.emplace_back(std::move(OwnedUnit), CTy);
262991bc56edSDimitry Andric
263091bc56edSDimitry Andric NewTU.addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
263191bc56edSDimitry Andric CU.getLanguage());
263291bc56edSDimitry Andric
263391bc56edSDimitry Andric uint64_t Signature = makeTypeSignature(Identifier);
263491bc56edSDimitry Andric NewTU.setTypeSignature(Signature);
26353ca95b02SDimitry Andric Ins.first->second = Signature;
263691bc56edSDimitry Andric
2637*b5893f02SDimitry Andric if (useSplitDwarf()) {
2638*b5893f02SDimitry Andric MCSection *Section =
2639*b5893f02SDimitry Andric getDwarfVersion() <= 4
2640*b5893f02SDimitry Andric ? Asm->getObjFileLowering().getDwarfTypesDWOSection()
2641*b5893f02SDimitry Andric : Asm->getObjFileLowering().getDwarfInfoDWOSection();
2642*b5893f02SDimitry Andric NewTU.setSection(Section);
2643*b5893f02SDimitry Andric } else {
2644*b5893f02SDimitry Andric MCSection *Section =
2645*b5893f02SDimitry Andric getDwarfVersion() <= 4
2646*b5893f02SDimitry Andric ? Asm->getObjFileLowering().getDwarfTypesSection(Signature)
2647*b5893f02SDimitry Andric : Asm->getObjFileLowering().getDwarfInfoSection(Signature);
2648*b5893f02SDimitry Andric NewTU.setSection(Section);
26494ba319b5SDimitry Andric // Non-split type units reuse the compile unit's line table.
26504ba319b5SDimitry Andric CU.applyStmtList(UnitDie);
265139d628a0SDimitry Andric }
265291bc56edSDimitry Andric
26534ba319b5SDimitry Andric // Add DW_AT_str_offsets_base to the type unit DIE, but not for split type
26544ba319b5SDimitry Andric // units.
26554ba319b5SDimitry Andric if (useSegmentedStringOffsetsTable() && !useSplitDwarf())
26564ba319b5SDimitry Andric NewTU.addStringOffsetsStart();
26574ba319b5SDimitry Andric
265891bc56edSDimitry Andric NewTU.setType(NewTU.createTypeDIE(CTy));
265991bc56edSDimitry Andric
266091bc56edSDimitry Andric if (TopLevelType) {
266191bc56edSDimitry Andric auto TypeUnitsToAdd = std::move(TypeUnitsUnderConstruction);
266291bc56edSDimitry Andric TypeUnitsUnderConstruction.clear();
266391bc56edSDimitry Andric
266491bc56edSDimitry Andric // Types referencing entries in the address table cannot be placed in type
266591bc56edSDimitry Andric // units.
266691bc56edSDimitry Andric if (AddrPool.hasBeenUsed()) {
266791bc56edSDimitry Andric
266891bc56edSDimitry Andric // Remove all the types built while building this type.
266991bc56edSDimitry Andric // This is pessimistic as some of these types might not be dependent on
267091bc56edSDimitry Andric // the type that used an address.
267191bc56edSDimitry Andric for (const auto &TU : TypeUnitsToAdd)
26723ca95b02SDimitry Andric TypeSignatures.erase(TU.second);
267391bc56edSDimitry Andric
267491bc56edSDimitry Andric // Construct this type in the CU directly.
267591bc56edSDimitry Andric // This is inefficient because all the dependent types will be rebuilt
267691bc56edSDimitry Andric // from scratch, including building them in type units, discovering that
267791bc56edSDimitry Andric // they depend on addresses, throwing them out and rebuilding them.
2678ff0cc061SDimitry Andric CU.constructTypeDIE(RefDie, cast<DICompositeType>(CTy));
267991bc56edSDimitry Andric return;
268091bc56edSDimitry Andric }
268191bc56edSDimitry Andric
268291bc56edSDimitry Andric // If the type wasn't dependent on fission addresses, finish adding the type
268391bc56edSDimitry Andric // and all its dependent types.
26843ca95b02SDimitry Andric for (auto &TU : TypeUnitsToAdd) {
26853ca95b02SDimitry Andric InfoHolder.computeSizeAndOffsetsForUnit(TU.first.get());
26863ca95b02SDimitry Andric InfoHolder.emitUnit(TU.first.get(), useSplitDwarf());
268791bc56edSDimitry Andric }
26883ca95b02SDimitry Andric }
26893ca95b02SDimitry Andric CU.addDIETypeSignature(RefDie, Signature);
269091bc56edSDimitry Andric }
269191bc56edSDimitry Andric
26924ba319b5SDimitry Andric // Add the Name along with its companion DIE to the appropriate accelerator
26934ba319b5SDimitry Andric // table (for AccelTableKind::Dwarf it's always AccelDebugNames, for
26944ba319b5SDimitry Andric // AccelTableKind::Apple, we use the table we got as an argument). If
26954ba319b5SDimitry Andric // accelerator tables are disabled, this function does nothing.
26964ba319b5SDimitry Andric template <typename DataT>
addAccelNameImpl(const DICompileUnit & CU,AccelTable<DataT> & AppleAccel,StringRef Name,const DIE & Die)2697*b5893f02SDimitry Andric void DwarfDebug::addAccelNameImpl(const DICompileUnit &CU,
2698*b5893f02SDimitry Andric AccelTable<DataT> &AppleAccel, StringRef Name,
26994ba319b5SDimitry Andric const DIE &Die) {
27004ba319b5SDimitry Andric if (getAccelTableKind() == AccelTableKind::None)
270191bc56edSDimitry Andric return;
27024ba319b5SDimitry Andric
2703*b5893f02SDimitry Andric if (getAccelTableKind() != AccelTableKind::Apple &&
2704*b5893f02SDimitry Andric CU.getNameTableKind() == DICompileUnit::DebugNameTableKind::None)
2705*b5893f02SDimitry Andric return;
2706*b5893f02SDimitry Andric
27074ba319b5SDimitry Andric DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder;
2708*b5893f02SDimitry Andric DwarfStringPoolEntryRef Ref = Holder.getStringPool().getEntry(*Asm, Name);
27094ba319b5SDimitry Andric
27104ba319b5SDimitry Andric switch (getAccelTableKind()) {
27114ba319b5SDimitry Andric case AccelTableKind::Apple:
27124ba319b5SDimitry Andric AppleAccel.addName(Ref, Die);
27134ba319b5SDimitry Andric break;
27144ba319b5SDimitry Andric case AccelTableKind::Dwarf:
27154ba319b5SDimitry Andric AccelDebugNames.addName(Ref, Die);
27164ba319b5SDimitry Andric break;
27174ba319b5SDimitry Andric case AccelTableKind::Default:
27184ba319b5SDimitry Andric llvm_unreachable("Default should have already been resolved.");
27194ba319b5SDimitry Andric case AccelTableKind::None:
27204ba319b5SDimitry Andric llvm_unreachable("None handled above");
27214ba319b5SDimitry Andric }
27224ba319b5SDimitry Andric }
27234ba319b5SDimitry Andric
addAccelName(const DICompileUnit & CU,StringRef Name,const DIE & Die)2724*b5893f02SDimitry Andric void DwarfDebug::addAccelName(const DICompileUnit &CU, StringRef Name,
2725*b5893f02SDimitry Andric const DIE &Die) {
2726*b5893f02SDimitry Andric addAccelNameImpl(CU, AccelNames, Name, Die);
272791bc56edSDimitry Andric }
272891bc56edSDimitry Andric
addAccelObjC(const DICompileUnit & CU,StringRef Name,const DIE & Die)2729*b5893f02SDimitry Andric void DwarfDebug::addAccelObjC(const DICompileUnit &CU, StringRef Name,
2730*b5893f02SDimitry Andric const DIE &Die) {
27314ba319b5SDimitry Andric // ObjC names go only into the Apple accelerator tables.
27324ba319b5SDimitry Andric if (getAccelTableKind() == AccelTableKind::Apple)
2733*b5893f02SDimitry Andric addAccelNameImpl(CU, AccelObjC, Name, Die);
273491bc56edSDimitry Andric }
273591bc56edSDimitry Andric
addAccelNamespace(const DICompileUnit & CU,StringRef Name,const DIE & Die)2736*b5893f02SDimitry Andric void DwarfDebug::addAccelNamespace(const DICompileUnit &CU, StringRef Name,
2737*b5893f02SDimitry Andric const DIE &Die) {
2738*b5893f02SDimitry Andric addAccelNameImpl(CU, AccelNamespace, Name, Die);
273991bc56edSDimitry Andric }
274091bc56edSDimitry Andric
addAccelType(const DICompileUnit & CU,StringRef Name,const DIE & Die,char Flags)2741*b5893f02SDimitry Andric void DwarfDebug::addAccelType(const DICompileUnit &CU, StringRef Name,
2742*b5893f02SDimitry Andric const DIE &Die, char Flags) {
2743*b5893f02SDimitry Andric addAccelNameImpl(CU, AccelTypes, Name, Die);
274491bc56edSDimitry Andric }
2745d88c1a5aSDimitry Andric
getDwarfVersion() const2746d88c1a5aSDimitry Andric uint16_t DwarfDebug::getDwarfVersion() const {
2747d88c1a5aSDimitry Andric return Asm->OutStreamer->getContext().getDwarfVersion();
2748d88c1a5aSDimitry Andric }
2749*b5893f02SDimitry Andric
addSectionLabel(const MCSymbol * Sym)2750*b5893f02SDimitry Andric void DwarfDebug::addSectionLabel(const MCSymbol *Sym) {
2751*b5893f02SDimitry Andric SectionLabels.insert(std::make_pair(&Sym->getSection(), Sym));
2752*b5893f02SDimitry Andric }
2753*b5893f02SDimitry Andric
getSectionLabel(const MCSection * S)2754*b5893f02SDimitry Andric const MCSymbol *DwarfDebug::getSectionLabel(const MCSection *S) {
2755*b5893f02SDimitry Andric return SectionLabels.find(S)->second;
2756*b5893f02SDimitry Andric }
2757