58 #define DEBUG_TYPE "dwarfdebug"
62 cl::desc(
"Disable debug info printing"));
66 cl::desc(
"Make an absence of debug location information explicit."),
71 cl::desc(
"Generate GNU-style pubnames and pubtypes"),
85 cl::desc(
"Output prototype dwarf accelerator tables."),
93 cl::desc(
"Output DWARF5 split debug info."),
101 cl::desc(
"Generate DWARF pubnames and pubtypes sections"),
138 assert(Var &&
"Invalid complex DbgVariable!");
141 ->isBlockByrefStruct();
174 uint16_t tag = Ty->
getTag();
176 if (tag == dwarf::DW_TAG_pointer_type)
177 subType = resolve(cast<DIDerivedType>(Ty)->getBaseType());
179 auto Elements = cast<DICompositeTypeBase>(subType)->getElements();
180 for (
unsigned i = 0,
N = Elements.size(); i <
N; ++i) {
181 auto *DT = cast<DIDerivedTypeBase>(Elements[i]);
182 if (
getName() == DT->getName())
183 return resolve(DT->getBaseType());
195 :
Asm(A), MMI(
Asm->MMI), DebugLocs(A->OutStreamer->isVerboseAsm()),
196 PrevLabel(nullptr), InfoHolder(A,
"info_string", DIEValueAllocator),
197 UsedNonDefaultText(
false),
198 SkeletonHolder(A,
"skel_string", DIEValueAllocator),
199 IsDarwin(
Triple(A->getTargetTriple()).isOSDarwin()),
200 IsPS4(
Triple(A->getTargetTriple()).isPS4()),
215 HasDwarfAccelTables = IsDarwin;
220 HasSplitDwarf =
false;
225 HasDwarfPubSections = !IsDarwin && !IsPS4;
230 DwarfVersion = DwarfVersionNumber ? DwarfVersionNumber
235 UseGNUTLSOpcode = !(IsDarwin || IsPS4) || DwarfVersion < 3;
237 Asm->
OutStreamer->getContext().setDwarfVersion(DwarfVersion);
281 if (!SP->isDefinition())
287 if (SP->getLinkageName() !=
"" && SP->
getName() != SP->getLinkageName())
308 if (isa<DISubprogram>(Context))
310 if (
auto *
T = dyn_cast<DIType>(Context))
326 if (Ranges.
size() > 1)
340 void DwarfDebug::constructAbstractSubprogramScopeDIE(
LexicalScope *Scope) {
347 ProcessedSPNodes.insert(SP);
351 auto &CU = SPMap[
SP];
357 void DwarfDebug::addGnuPubAttributes(
DwarfUnit &U,
DIE &D)
const {
367 DwarfDebug::constructDwarfCompileUnit(
const DICompileUnit *DIUnit) {
371 auto OwnedUnit = make_unique<DwarfCompileUnit>(
372 InfoHolder.
getUnits().size(), DIUnit, Asm,
this, &InfoHolder);
374 DIE &Die = NewCU.getUnitDie();
375 InfoHolder.
addUnit(std::move(OwnedUnit));
377 NewCU.setSkeleton(constructSkeletonCU(NewCU));
383 if (!Asm->OutStreamer->hasRawTextSupport() || SingleCU)
384 Asm->OutStreamer->getContext().setMCLineTableCompilationDir(
385 NewCU.getUniqueID(), CompilationDir);
393 NewCU.initStmtList();
397 if (!CompilationDir.
empty())
400 addGnuPubAttributes(NewCU, Die);
415 NewCU.initSection(Asm->getObjFileLowering().getDwarfInfoDWOSection());
417 NewCU.initSection(Asm->getObjFileLowering().getDwarfInfoSection());
419 CUMap.insert(std::make_pair(DIUnit, &NewCU));
420 CUDieMap.insert(std::make_pair(&Die, &NewCU));
449 auto *CUNode = cast<DICompileUnit>(
N);
451 for (
auto *
IE : CUNode->getImportedEntities())
452 ScopesWithImportedEntities.
push_back(std::make_pair(
IE->getScope(),
IE));
456 std::stable_sort(ScopesWithImportedEntities.
begin(),
458 for (
auto *GV : CUNode->getGlobalVariables())
459 CU.getOrCreateGlobalVariableDIE(GV);
460 for (
auto *SP : CUNode->getSubprograms())
461 SPMap.insert(std::make_pair(SP, &CU));
462 for (
auto *Ty : CUNode->getEnumTypes()) {
465 CU.getOrCreateTypeDIE(cast<DIType>(
resolve(Ty->getRef())));
467 for (
auto *Ty : CUNode->getRetainedTypes()) {
470 CU.getOrCreateTypeDIE(cast<DIType>(
resolve(Ty->getRef())));
474 for (
auto *
IE : CUNode->getImportedEntities())
475 constructAndAddImportedEntityDIE(CU,
IE);
482 void DwarfDebug::finishVariableDefinitions() {
483 for (
const auto &Var : ConcreteVariables) {
484 DIE *VariableDie = Var->getDIE();
492 InlinedVariable(Var->getVariable(), Var->getInlinedAt()));
493 if (AbsVar && AbsVar->
getDIE()) {
501 void DwarfDebug::finishSubprogramDefinitions() {
502 for (
const auto &
P : SPMap)
510 void DwarfDebug::collectDeadVariables() {
515 auto *TheCU = cast<DICompileUnit>(
N);
519 assert(SPCU &&
"Unable to find Compile Unit!");
520 for (
auto *SP : TheCU->getSubprograms()) {
521 if (ProcessedSPNodes.count(SP) != 0)
523 SPCU->collectDeadVariables(SP);
529 void DwarfDebug::finalizeModuleInfo() {
532 finishSubprogramDefinitions();
534 finishVariableDefinitions();
537 collectDeadVariables();
541 for (
const auto &
P : CUMap) {
542 auto &TheCU = *
P.second;
566 if (!SkCU->getRangeLists().empty()) {
580 if (
unsigned NumRanges = TheCU.
getRanges().size()) {
601 assert(CurFn ==
nullptr);
602 assert(CurMI ==
nullptr);
611 finalizeModuleInfo();
637 emitDebugAbbrevDWO();
640 AddrPool.
emit(*Asm, Asm->getObjFileLowering().getDwarfAddrSection());
647 emitAccelNamespaces();
652 if (HasDwarfPubSections) {
659 AbstractVariables.clear();
664 DwarfDebug::getExistingAbstractVariable(InlinedVariable IV,
668 auto I = AbstractVariables.find(Cleansed);
669 if (
I != AbstractVariables.end())
670 return I->second.get();
674 DbgVariable *DwarfDebug::getExistingAbstractVariable(InlinedVariable IV) {
676 return getExistingAbstractVariable(IV, Cleansed);
681 auto AbsDbgVariable = make_unique<DbgVariable>(Var,
nullptr,
this);
683 AbstractVariables[Var] = std::move(AbsDbgVariable);
686 void DwarfDebug::ensureAbstractVariableIsCreated(InlinedVariable IV,
687 const MDNode *ScopeNode) {
689 if (getExistingAbstractVariable(IV, Cleansed))
693 cast<DILocalScope>(ScopeNode)));
696 void DwarfDebug::ensureAbstractVariableIsCreatedIfScoped(
697 InlinedVariable IV,
const MDNode *ScopeNode) {
699 if (getExistingAbstractVariable(IV, Cleansed))
704 createAbstractVariable(Cleansed, Scope);
708 void DwarfDebug::collectVariableInfoFromMMITable(
713 assert(
VI.Var->isValidLocationForIntrinsic(
VI.Loc) &&
714 "Expected inlined-at fields to agree");
716 InlinedVariable Var(
VI.Var,
VI.Loc->getInlinedAt());
724 ensureAbstractVariableIsCreatedIfScoped(Var, Scope->
getScopeNode());
725 auto RegVar = make_unique<DbgVariable>(Var.first, Var.second,
this);
726 RegVar->initializeMMI(
VI.Expr,
VI.Slot);
728 ConcreteVariables.push_back(std::move(RegVar));
766 return (l1 < r2) && (l2 < r1);
797 for (
auto I = Ranges.
begin(), E = Ranges.
end();
I != E; ++
I) {
800 assert(Begin->
isDebugValue() &&
"Invalid History entry");
811 auto Last = std::remove_if(OpenRanges.
begin(), OpenRanges.
end(),
815 OpenRanges.
erase(Last, OpenRanges.
end());
818 assert(StartLabel &&
"Forgot label before DBG_VALUE starting a range!");
823 else if (std::next(
I) == Ranges.
end())
824 EndLabel = Asm->getFunctionEnd();
827 assert(EndLabel &&
"Forgot label after instruction ending a range!");
829 DEBUG(
dbgs() <<
"DotDebugLoc: " << *Begin <<
"\n");
833 bool couldMerge =
false;
841 if (!DebugLoc.
empty())
849 if (OpenRanges.
size())
850 Loc.addValues(OpenRanges);
857 auto CurEntry = DebugLoc.
rbegin();
859 dbgs() << CurEntry->getValues().size() <<
" Values:\n";
860 for (
auto &
Value : CurEntry->getValues())
865 auto PrevEntry = std::next(CurEntry);
866 if (PrevEntry != DebugLoc.
rend() && PrevEntry->MergeRanges(*CurEntry))
872 InlinedVariable IV) {
873 ensureAbstractVariableIsCreatedIfScoped(IV, Scope.
getScopeNode());
874 ConcreteVariables.push_back(
875 make_unique<DbgVariable>(IV.first, IV.second,
this));
877 return ConcreteVariables.back().get();
885 collectVariableInfoFromMMITable(Processed);
887 for (
const auto &
I : DbgValues) {
888 InlinedVariable IV =
I.first;
889 if (Processed.
count(IV))
893 const auto &Ranges =
I.second;
907 DbgVariable *RegVar = createConcreteVariable(*Scope, IV);
910 assert(MInsn->
isDebugValue() &&
"History must begin with debug value");
913 if (Ranges.
size() == 1 && Ranges.
front().second ==
nullptr) {
923 buildLocationList(Entries, Ranges);
929 static_cast<const Metadata *
>(IV.first->getType()));
932 for (
auto &Entry : Entries)
933 Entry.finalize(*Asm,
List, BT);
938 if (Processed.
insert(InlinedVariable(DV,
nullptr)).second)
940 createConcreteVariable(*Scope, InlinedVariable(DV,
nullptr));
947 assert(Label &&
"Didn't insert label before instruction");
953 return LabelsAfterInsn.lookup(MI);
958 assert(CurMI ==
nullptr);
963 if (DL != PrevInstLoc) {
967 if (DL == PrologEndLoc) {
969 PrologEndLoc = DebugLoc();
973 Asm->OutStreamer->getContext().getCurrentDwarfLoc().getLine())
980 recordSourceLine(0, 0,
nullptr, 0);
987 LabelsBeforeInsn.find(MI);
990 if (I == LabelsBeforeInsn.end())
999 Asm->OutStreamer->EmitLabel(PrevLabel);
1001 I->second = PrevLabel;
1006 assert(CurMI !=
nullptr);
1010 PrevLabel =
nullptr;
1013 LabelsAfterInsn.find(CurMI);
1017 if (I == LabelsAfterInsn.end())
1027 Asm->OutStreamer->EmitLabel(PrevLabel);
1029 I->second = PrevLabel;
1036 void DwarfDebug::identifyScopeMarkers() {
1039 while (!WorkList.
empty()) {
1043 if (!Children.
empty())
1050 assert(R.first &&
"InsnRange does not have first instruction!");
1051 assert(R.second &&
"InsnRange does not have second instruction!");
1052 requestLabelBeforeInsn(R.first);
1053 requestLabelAfterInsn(R.second);
1061 for (
const auto &MBB : *MF)
1062 for (
const auto &
MI : MBB)
1066 assert(!
MI.isCFIInstruction() &&
1067 "First non-frame-setup instruction is a CFI instruction.");
1068 return MI.getDebugLoc();
1083 if (
DI == FunctionDIs.end())
1089 if (LScopes.
empty())
1092 assert(DbgValues.empty() &&
"DbgValues map wasn't cleaned!");
1095 identifyScopeMarkers();
1110 assert(TheCU &&
"Unable to find compile unit!");
1111 if (Asm->OutStreamer->hasRawTextSupport())
1113 Asm->OutStreamer->getContext().setDwarfCompileUnitID(0);
1115 Asm->OutStreamer->getContext().setDwarfCompileUnitID(TheCU->
getUniqueID());
1122 for (
const auto &
I : DbgValues) {
1123 const auto &Ranges =
I.second;
1130 if (DIVar->
getTag() == dwarf::DW_TAG_arg_variable &&
1132 LabelsBeforeInsn[Ranges.
front().first] = Asm->getFunctionBegin();
1133 if (Ranges.
front().first->getDebugExpression()->isBitPiece()) {
1135 for (
auto I = Ranges.
begin();
I != Ranges.
end(); ++
I) {
1139 return !
piecesOverlap(Piece, Pred.first->getDebugExpression());
1141 LabelsBeforeInsn[
I->first] = Asm->getFunctionBegin();
1148 for (
const auto &Range : Ranges) {
1149 requestLabelBeforeInsn(Range.first);
1151 requestLabelAfterInsn(Range.second);
1155 PrevInstLoc = DebugLoc();
1156 PrevLabel = Asm->getFunctionBegin();
1170 assert(CurFn == MF &&
1171 "endFunction should be called with the same function as beginFunction");
1187 auto *SP = cast<DISubprogram>(FnScope->
getScopeNode());
1191 collectVariableInfo(TheCU, SP, ProcessedVars);
1194 TheCU.addRange(
RangeSpan(Asm->getFunctionBegin(), Asm->getFunctionEnd()));
1201 assert(DbgValues.empty());
1204 assert(AbstractVariables.empty());
1205 LabelsBeforeInsn.clear();
1206 LabelsAfterInsn.clear();
1207 PrevLabel =
nullptr;
1217 auto *SP = cast<DISubprogram>(AScope->getScopeNode());
1220 if (!ProcessedVars.
insert(InlinedVariable(DV,
nullptr)).second)
1222 ensureAbstractVariableIsCreated(InlinedVariable(DV,
nullptr),
1225 &&
"ensureAbstractVariableIsCreated inserted abstract scopes");
1227 constructAbstractSubprogramScopeDIE(AScope);
1230 TheCU.constructSubprogramScopeDIE(FnScope);
1231 if (
auto *SkelCU = TheCU.getSkeleton())
1233 SkelCU->constructSubprogramScopeDIE(FnScope);
1241 LabelsBeforeInsn.clear();
1242 LabelsAfterInsn.clear();
1243 PrevLabel =
nullptr;
1249 void DwarfDebug::recordSourceLine(
unsigned Line,
unsigned Col,
const MDNode *S,
1254 unsigned Discriminator = 0;
1255 if (
auto *Scope = cast_or_null<DIScope>(S)) {
1256 Fn = Scope->getFilename();
1257 Dir = Scope->getDirectory();
1258 if (
auto *LBF = dyn_cast<DILexicalBlockFile>(Scope))
1259 Discriminator = LBF->getDiscriminator();
1261 unsigned CUID = Asm->OutStreamer->getContext().getDwarfCompileUnitID();
1263 .getOrCreateSourceID(Fn, Dir);
1265 Asm->OutStreamer->EmitDwarfLocDirective(Src, Line, Col, Flags, 0,
1274 void DwarfDebug::emitDebugInfo() {
1280 void DwarfDebug::emitAbbreviations() {
1283 Holder.
emitAbbrevs(Asm->getObjFileLowering().getDwarfAbbrevSection());
1289 Asm->OutStreamer->SwitchSection(Section);
1296 void DwarfDebug::emitAccelNames() {
1297 emitAccel(AccelNames, Asm->getObjFileLowering().getDwarfAccelNamesSection(),
1303 void DwarfDebug::emitAccelObjC() {
1304 emitAccel(AccelObjC, Asm->getObjFileLowering().getDwarfAccelObjCSection(),
1309 void DwarfDebug::emitAccelNamespaces() {
1310 emitAccel(AccelNamespace,
1311 Asm->getObjFileLowering().getDwarfAccelNamespaceSection(),
1316 void DwarfDebug::emitAccelTypes() {
1317 emitAccel(AccelTypes, Asm->getObjFileLowering().getDwarfAccelTypesSection(),
1343 DIE &SpecDIE = SpecVal.getDIEEntry().getEntry();
1350 case dwarf::DW_TAG_class_type:
1351 case dwarf::DW_TAG_structure_type:
1352 case dwarf::DW_TAG_union_type:
1353 case dwarf::DW_TAG_enumeration_type:
1358 case dwarf::DW_TAG_typedef:
1359 case dwarf::DW_TAG_base_type:
1360 case dwarf::DW_TAG_subrange_type:
1362 case dwarf::DW_TAG_namespace:
1364 case dwarf::DW_TAG_subprogram:
1366 case dwarf::DW_TAG_variable:
1368 case dwarf::DW_TAG_enumerator:
1378 void DwarfDebug::emitDebugPubNames(
bool GnuStyle) {
1380 ? Asm->getObjFileLowering().getDwarfGnuPubNamesSection()
1381 : Asm->getObjFileLowering().getDwarfPubNamesSection();
1383 emitDebugPubSection(GnuStyle, PSec,
"Names",
1387 void DwarfDebug::emitDebugPubSection(
1390 for (
const auto &NU : CUMap) {
1393 const auto &Globals = (TheU->*Accessor)();
1395 if (Globals.empty())
1402 Asm->OutStreamer->SwitchSection(PSec);
1405 Asm->OutStreamer->AddComment(
"Length of Public " + Name +
" Info");
1406 MCSymbol *BeginLabel = Asm->createTempSymbol(
"pub" + Name +
"_begin");
1407 MCSymbol *EndLabel = Asm->createTempSymbol(
"pub" + Name +
"_end");
1408 Asm->EmitLabelDifference(EndLabel, BeginLabel, 4);
1410 Asm->OutStreamer->EmitLabel(BeginLabel);
1412 Asm->OutStreamer->AddComment(
"DWARF Version");
1415 Asm->OutStreamer->AddComment(
"Offset of Compilation Unit Info");
1418 Asm->OutStreamer->AddComment(
"Compilation Unit Length");
1422 for (
const auto &GI : Globals) {
1423 const char *Name = GI.getKeyData();
1424 const DIE *Entity = GI.second;
1426 Asm->OutStreamer->AddComment(
"DIE offset");
1431 Asm->OutStreamer->AddComment(
1434 Asm->EmitInt8(Desc.
toBits());
1437 Asm->OutStreamer->AddComment(
"External Name");
1438 Asm->OutStreamer->EmitBytes(
StringRef(Name, GI.getKeyLength() + 1));
1441 Asm->OutStreamer->AddComment(
"End Mark");
1443 Asm->OutStreamer->EmitLabel(EndLabel);
1447 void DwarfDebug::emitDebugPubTypes(
bool GnuStyle) {
1449 ? Asm->getObjFileLowering().getDwarfGnuPubTypesSection()
1450 : Asm->getObjFileLowering().getDwarfPubTypesSection();
1452 emitDebugPubSection(GnuStyle, PSec,
"Types",
1457 void DwarfDebug::emitDebugStr() {
1459 Holder.
emitStrings(Asm->getObjFileLowering().getDwarfStrSection());
1465 auto Comment = Comments.begin();
1466 auto End = Comments.end();
1467 for (uint8_t Byte : DebugLocs.
getBytes(Entry))
1468 Streamer.
EmitInt8(Byte, Comment != End ? *(Comment++) :
"");
1474 unsigned PieceOffsetInBits) {
1479 if (Value.
isInt()) {
1480 if (BT && (BT->
getEncoding() == dwarf::DW_ATE_signed ||
1484 DwarfExpr.AddUnsignedConstant(Value.
getInt());
1498 DwarfExpr.AddMachineRegExpression(Expr, Loc.
getReg(),
1516 return P.isBitPiece();
1517 }) &&
"all values are expected to be pieces");
1518 assert(std::is_sorted(Values.begin(), Values.end()) &&
1519 "pieces are expected to be sorted");
1521 unsigned Offset = 0;
1522 for (
auto Piece : Values) {
1526 assert(Offset <= PieceOffset &&
"overlapping or duplicate pieces");
1527 if (Offset < PieceOffset) {
1532 Expr.AddOpPiece(PieceOffset-Offset, 0);
1533 Offset += PieceOffset-Offset;
1535 Offset += PieceSize;
1540 assert(Values.size() == 1 &&
"only pieces may have >1 value");
1547 Asm->OutStreamer->AddComment(
"Loc expr size");
1548 Asm->EmitInt16(DebugLocs.
getBytes(Entry).size());
1556 void DwarfDebug::emitDebugLoc() {
1558 Asm->OutStreamer->SwitchSection(
1559 Asm->getObjFileLowering().getDwarfLocSection());
1560 unsigned char Size = Asm->getDataLayout().getPointerSize();
1562 Asm->OutStreamer->EmitLabel(
List.Label);
1569 Asm->EmitLabelDifference(Entry.BeginSym, Base, Size);
1570 Asm->EmitLabelDifference(Entry.EndSym, Base, Size);
1572 Asm->OutStreamer->EmitSymbolValue(Entry.BeginSym, Size);
1573 Asm->OutStreamer->EmitSymbolValue(Entry.EndSym, Size);
1578 Asm->OutStreamer->EmitIntValue(0, Size);
1579 Asm->OutStreamer->EmitIntValue(0, Size);
1583 void DwarfDebug::emitDebugLocDWO() {
1584 Asm->OutStreamer->SwitchSection(
1585 Asm->getObjFileLowering().getDwarfLocDWOSection());
1587 Asm->OutStreamer->EmitLabel(
List.Label);
1594 unsigned idx = AddrPool.
getIndex(Entry.BeginSym);
1595 Asm->EmitULEB128(idx);
1596 Asm->EmitLabelDifference(Entry.EndSym, Entry.BeginSym, 4);
1610 void DwarfDebug::emitDebugARanges() {
1615 for (
const SymbolCU &SCU : ArangeLabels) {
1616 if (SCU.Sym->isInSection()) {
1618 MCSection *Section = &SCU.Sym->getSection();
1620 SectionMap[Section].push_back(SCU);
1625 SectionMap[
nullptr].push_back(SCU);
1630 for (
const auto &
I : SectionMap) {
1635 Sym = Asm->OutStreamer->endSection(Section);
1643 for (
auto &
I : SectionMap) {
1646 if (List.
size() < 2)
1654 Span.
Start = Cur.Sym;
1657 Spans[Cur.CU].push_back(Span);
1663 std::sort(List.begin(), List.end(),
1665 unsigned IA = A.
Sym ? Asm->OutStreamer->GetSymbolOrder(A.
Sym) : 0;
1666 unsigned IB = B.Sym ? Asm->OutStreamer->GetSymbolOrder(B.Sym) : 0;
1678 const MCSymbol *StartSym = List[0].Sym;
1679 for (
size_t n = 1, e = List.size(); n < e; n++) {
1680 const SymbolCU &Prev = List[n - 1];
1684 if (Cur.
CU != Prev.
CU) {
1686 Span.
Start = StartSym;
1688 Spans[Prev.
CU].push_back(Span);
1695 Asm->OutStreamer->SwitchSection(
1696 Asm->getObjFileLowering().getDwarfARangesSection());
1698 unsigned PtrSize = Asm->getDataLayout().getPointerSize();
1701 std::vector<DwarfCompileUnit *> CUs;
1702 for (
const auto &it : Spans) {
1714 std::vector<ArangeSpan> &List = Spans[CU];
1721 unsigned ContentSize =
1727 unsigned TupleSize = PtrSize * 2;
1733 ContentSize += Padding;
1734 ContentSize += (List.size() + 1) * TupleSize;
1737 Asm->OutStreamer->AddComment(
"Length of ARange Set");
1738 Asm->EmitInt32(ContentSize);
1739 Asm->OutStreamer->AddComment(
"DWARF Arange version number");
1741 Asm->OutStreamer->AddComment(
"Offset Into Debug Info Section");
1743 Asm->OutStreamer->AddComment(
"Address Size (in bytes)");
1744 Asm->EmitInt8(PtrSize);
1745 Asm->OutStreamer->AddComment(
"Segment Size (in bytes)");
1748 Asm->OutStreamer->EmitFill(Padding, 0xff);
1751 Asm->EmitLabelReference(Span.
Start, PtrSize);
1755 Asm->EmitLabelDifference(Span.
End, Span.
Start, PtrSize);
1759 uint64_t Size = SymSize[Span.
Start];
1763 Asm->OutStreamer->EmitIntValue(Size, PtrSize);
1767 Asm->OutStreamer->AddComment(
"ARange terminator");
1768 Asm->OutStreamer->EmitIntValue(0, PtrSize);
1769 Asm->OutStreamer->EmitIntValue(0, PtrSize);
1774 void DwarfDebug::emitDebugRanges() {
1776 Asm->OutStreamer->SwitchSection(
1777 Asm->getObjFileLowering().getDwarfRangesSection());
1780 unsigned char Size = Asm->getDataLayout().getPointerSize();
1783 for (
const auto &
I : CUMap) {
1792 Asm->OutStreamer->EmitLabel(List.getSym());
1794 for (
const RangeSpan &Range : List.getRanges()) {
1795 const MCSymbol *Begin = Range.getStart();
1796 const MCSymbol *End = Range.getEnd();
1797 assert(Begin &&
"Range without a begin symbol?");
1798 assert(End &&
"Range without an end symbol?");
1800 Asm->EmitLabelDifference(Begin, Base, Size);
1801 Asm->EmitLabelDifference(End, Base, Size);
1803 Asm->OutStreamer->EmitSymbolValue(Begin, Size);
1804 Asm->OutStreamer->EmitSymbolValue(End, Size);
1809 Asm->OutStreamer->EmitIntValue(0, Size);
1810 Asm->OutStreamer->EmitIntValue(0, Size);
1817 void DwarfDebug::initSkeletonUnit(
const DwarfUnit &U,
DIE &Die,
1818 std::unique_ptr<DwarfUnit> NewU) {
1822 if (!CompilationDir.
empty())
1825 addGnuPubAttributes(*NewU, Die);
1827 SkeletonHolder.
addUnit(std::move(NewU));
1835 auto OwnedUnit = make_unique<DwarfCompileUnit>(
1838 NewCU.
initSection(Asm->getObjFileLowering().getDwarfInfoSection());
1840 NewCU.initStmtList();
1842 initSkeletonUnit(CU, NewCU.
getUnitDie(), std::move(OwnedUnit));
1849 void DwarfDebug::emitDebugInfoDWO() {
1857 void DwarfDebug::emitDebugAbbrevDWO() {
1859 InfoHolder.
emitAbbrevs(Asm->getObjFileLowering().getDwarfAbbrevDWOSection());
1862 void DwarfDebug::emitDebugLineDWO() {
1864 Asm->OutStreamer->SwitchSection(
1865 Asm->getObjFileLowering().getDwarfLineDWOSection());
1866 SplitTypeUnitFileTable.
Emit(*Asm->OutStreamer);
1872 void DwarfDebug::emitDebugStrDWO() {
1874 MCSection *OffSec = Asm->getObjFileLowering().getDwarfStrOffDWOSection();
1875 InfoHolder.
emitStrings(Asm->getObjFileLowering().getDwarfStrDWOSection(),
1884 return &SplitTypeUnitFileTable;
1904 if (!TypeUnitsUnderConstruction.empty() && AddrPool.
hasBeenUsed())
1913 bool TopLevelType = TypeUnitsUnderConstruction.empty();
1916 auto OwnedUnit = make_unique<DwarfTypeUnit>(
1917 InfoHolder.
getUnits().size() + TypeUnitsUnderConstruction.size(), CU, Asm,
1918 this, &InfoHolder, getDwoLineTable(CU));
1920 DIE &UnitDie = NewTU.getUnitDie();
1922 TypeUnitsUnderConstruction.push_back(
1923 std::make_pair(std::move(OwnedUnit), CTy));
1929 NewTU.setTypeSignature(Signature);
1932 NewTU.initSection(Asm->getObjFileLowering().getDwarfTypesDWOSection());
1936 Asm->getObjFileLowering().getDwarfTypesSection(Signature));
1939 NewTU.setType(NewTU.createTypeDIE(CTy));
1942 auto TypeUnitsToAdd = std::move(TypeUnitsUnderConstruction);
1943 TypeUnitsUnderConstruction.clear();
1952 for (
const auto &TU : TypeUnitsToAdd)
1953 DwarfTypeUnits.erase(TU.second);
1965 for (
auto &TU : TypeUnitsToAdd)
1966 InfoHolder.addUnit(std::move(TU.first));
MachineLocation getLoc() const
void emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry)
Emit the location for a debug loc entry, including the size header.
ArrayRef< Entry > getEntries(const List &L) const
ValuesClass< DataType > LLVM_END_WITH_NULL values(const char *Arg, DataType Val, const char *Desc,...)
Instances of this class represent a uniqued identifier for a section in the current translation unit...
void push_back(const T &Elt)
An object containing the capability of hashing and adding hash attributes onto a DIE.
uint64_t computeCUSignature(const DIE &Die)
Computes the CU signature.
Builder for DebugLocStream lists.
void calculateDbgValueHistory(const MachineFunction *MF, const TargetRegisterInfo *TRI, DbgValueHistoryMap &Result)
void addFlag(DIE &Die, dwarf::Attribute Attribute)
Add a flag that is true to the DIE.
unsigned getUniqueID() const
const DILocalScope * getScopeNode() const
static dwarf::PubIndexEntryDescriptor computeIndexValue(DwarfUnit *CU, const DIE *Die)
computeIndexValue - Compute the gdb index value for the DIE and CU.
static cl::opt< bool > GenerateGnuPubSections("generate-gnu-dwarf-pub-sections", cl::Hidden, cl::desc("Generate GNU-style pubnames and pubtypes"), cl::init(false))
static cl::opt< bool > DisableDebugInfoPrinting("disable-debug-info-print", cl::Hidden, cl::desc("Disable debug info printing"))
This struct describes location entries emitted in the .debug_loc section.
const DICompileUnit * getCUNode() const
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
MCSection * getDwarfAddrSection() const
#define DWARF2_FLAG_PROLOGUE_END
MCTargetOptions MCOptions
Machine level options.
MDNode * getScope() const
static uint64_t makeTypeSignature(StringRef Identifier)
virtual void EmitDwarfRegOp(ByteStreamer &BS, const MachineLocation &MLoc) const
EmitDwarfRegOp - Emit a dwarf register operation.
const ConstantFP * getFPImm() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
A Module instance is used to store all the information related to an LLVM module. ...
StringRef getFlags() const
const DIExpression * getDebugExpression() const
Return the complex address expression referenced by this DBG_VALUE instruction.
BufferByteStreamer getStreamer()
static cl::opt< DefaultOnOff > DwarfAccelTables("dwarf-accel-tables", cl::Hidden, cl::desc("Output prototype dwarf accelerator tables."), cl::values(clEnumVal(Default,"Default for platform"), clEnumVal(Enable,"Enabled"), clEnumVal(Disable,"Disabled"), clEnumValEnd), cl::init(Default))
DILocalScope * getScope() const
Get the local scope for this variable.
DenseSet - This implements a dense probed hash-table based set.
void Emit(MCStreamer &MCOS) const
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
ArrayRef< std::string > getComments(const Entry &E) const
bool useDwarfAccelTables() const
Returns whether or not to emit tables that dwarf consumers can use to accelerate lookup.
const MachineFunction * MF
The current machine function.
SmallVectorImpl< InsnRange > & getRanges()
void forBothCUs(DwarfCompileUnit &CU, Func F)
void emit(AsmPrinter *, const MCSymbol *, DwarfDebug *)
DenseMap< LexicalScope *, SmallVector< DbgVariable *, 8 > > & getScopeVariables()
This class implements a map that also provides access to all stored values in a deterministic order...
static const char *const DbgTimerName
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
StringRef getName() const
void initSection(MCSection *Section)
std::pair< const MachineInstr *, const MachineInstr * > InstrRange
LexicalScope - This class is used to track scope information.
bool isFrameRegister(unsigned MachineReg) override
Return whether the given machine register is the frame register in the current function.
const DILocation * getInlinedAt() const
void addAccelNamespace(StringRef Name, const DIE &Die)
void constructTypeDIE(DIE &Buffer, const DICompositeType *CTy)
void initializeDbgValue(const MachineInstr *DbgValue)
Initialize from a DBG_VALUE instruction.
static cl::opt< bool > GenerateARangeSection("generate-arange-section", cl::Hidden, cl::desc("Generate dwarf aranges"), cl::init(false))
const StringMap< const DIE * > & getGlobalTypes() const
virtual void EmitULEB128(uint64_t DWord, const Twine &Comment="")=0
const DIExpression * getExpression() const
ArrayRef< LexicalScope * > getAbstractScopesList() const
getAbstractScopesList - Return a reference to list of abstract scopes.
#define DWARF2_FLAG_IS_STMT
const char * GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage)
const char * OperationEncodingString(unsigned Encoding)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
LexicalScope * getOrCreateAbstractScope(const DILocalScope *Scope)
getOrCreateAbstractScope - Find or create an abstract lexical scope.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
SmallVectorImpl< LexicalScope * > & getChildren()
void applyVariableAttributes(const DbgVariable &Var, DIE &VariableDie)
T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val()
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
NamedRegionTimer - This class is basically a combination of TimeRegion and Timer. ...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static bool piecesOverlap(const DIExpression *P1, const DIExpression *P2)
Determine whether two variable pieces overlap.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void attachRangesOrLowHighPC(DIE &D, SmallVector< RangeSpan, 2 > Ranges)
const Module * getModule() const
DwarfCompileUnit * getSkeleton() const
bool isLexicalScopeDIENull(LexicalScope *Scope)
A helper function to check whether the DIE for a given Scope is going to be null. ...
StringRef getFilename() const
void constructContainingTypeDIEs()
Construct DIEs for types that contain vtables.
Pointer union between a subclass of DINode and MDString.
bool hasDebugInfo() const
hasDebugInfo - Returns true if valid debug info is present.
virtual void EmitInt8(uint8_t Byte, const Twine &Comment="")=0
DISubprogram * getDISubprogram(const MDNode *Scope)
Find subprogram that is enclosing this scope.
uint64_t read64le(const void *p)
#define clEnumVal(ENUMVAL, DESC)
T * resolve(const MapTy &Map) const
bool MergeValues(const DebugLocEntry &Next)
If this and Next are describing different pieces of the same variable, merge them by appending Next's...
DwarfExpression implementation for .debug_loc entries.
MCSymbol * getLabelAfterInsn(const MachineInstr *MI)
Return Label immediately following the instruction.
LexicalScope * getCurrentFunctionScope() const
getCurrentFunctionScope - Return lexical scope for the current function.
unsigned getNumOperands() const
Access to explicit operands of the instruction.
static cl::opt< DefaultOnOff > SplitDwarf("split-dwarf", cl::Hidden, cl::desc("Output DWARF5 split debug info."), cl::values(clEnumVal(Default,"Default for platform"), clEnumVal(Enable,"Enabled"), clEnumVal(Disable,"Disabled"), clEnumValEnd), cl::init(Default))
Decsribes an entry of the various gnu_pub* debug sections.
void EmitSigned(int64_t Value) override
Emit a raw signed value.
void setDwarfCompileUnitID(unsigned CUIndex)
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
This class is used to track local variable information.
void initialize(const MachineFunction &)
initialize - Scan machine function and constuct lexical scope nest, resets the instance if necessary...
void setBaseAddress(const MCSymbol *Base)
void FinalizeTable(AsmPrinter *, StringRef)
expr_op_iterator expr_op_begin() const
Visit the elements via ExprOperand wrappers.
void AddName(DwarfStringPoolEntryRef Name, const DIE *Die, char Flags=0)
void EmitOp(uint8_t Op, const char *Comment=nullptr) override
Output a dwarf operand and an optional assembler comment.
LexicalScope * findLexicalScope(const DILocation *DL)
findLexicalScope - Find lexical scope, either regular or inlined, for the given DebugLoc.
MCSymbol * getLabelBegin() const
void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
MCContext & getContext() const
DIE & addChild(DIE *Child)
Add a child to the DIE.
dwarf::Tag getTag() const
iterator_range< op_iterator > operands()
DIScope * getScope() const
ArrayRef< char > getBytes(const Entry &E) const
LexicalScope * findAbstractScope(const DILocalScope *N)
findAbstractScope - Find an abstract scope or return null.
bool isDebugValue() const
unsigned getRuntimeVersion() const
void AddSignedConstant(int Value)
Emit a signed constant.
bool useSplitDwarf() const
Returns whether or not to change the current debug info for the split dwarf proposal support...
This dwarf writer support class manages information associated with a source file.
DwarfStringPool & getStringPool()
Returns the string pool.
initializer< Ty > init(const Ty &Val)
void endModule() override
Emit all Dwarf sections that should come after the content.
const DIType * getType() const
MCSymbol * createTempSymbol(bool CanBeUnnamed=true)
Create and return a new assembler temporary symbol with a unique but unspecified name.
unsigned getNumElements() const
void applyStmtList(DIE &D)
Apply the DW_AT_stmt_list from this compile unit to the specified DIE.
StringRef getName() const
static void getObjCClassCategory(StringRef In, StringRef &Class, StringRef &Category)
const SmallVectorImpl< RangeSpanList > & getRangeLists() const
getRangeLists - Get the vector of range lists.
VariableDbgInfoMapTy & getVariableDbgInfo()
void emit(AsmPrinter &Asm, MCSection *AddrSection)
size_type count(const ValueT &V) const
Return 1 if the specified key is in the set, 0 otherwise.
static DebugLocEntry::Value getDebugLocValue(const MachineInstr *MI)
DIEValue findAttribute(dwarf::Attribute Attribute) const
Find a value in the DIE with the attribute given.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
const MachineOperand & getOperand(unsigned i) const
DIE - A structured debug information entry.
const MCSymbol * getBaseAddress() const
unsigned getSourceLanguage() const
TargetMachine & TM
Target machine description.
bool isCImm() const
isCImm - Test if this is a MO_CImmediate operand.
This class is intended to be used as a driving class for all asm writers.
void addDwarfTypeUnitType(DwarfCompileUnit &CU, StringRef Identifier, DIE &Die, const DICompositeType *CTy)
Add a DIE to the set of types that we're going to pull into type units.
void emitUnits(bool UseOffsets)
Emit all of the units to the section listed with the given abbreviation section.
DwarfDebug * getDwarfDebug()
void setCompilationDir(StringRef CompilationDir)
T * resolve(TypedDINodeRef< T > Ref) const
Find the MDNode for the given reference.
MCSymbol * getLabelBeforeInsn(const MachineInstr *MI)
Return Label preceding the instruction.
void addAccelType(StringRef Name, const DIE &Die, char Flags)
DwarfDebug(AsmPrinter *A, Module *M)
void endFunction(const MachineFunction *MF) override
Gather and emit post-function debug information.
void constructAbstractSubprogramScopeDIE(LexicalScope *Scope)
unsigned getEncoding() const
bool isAbstractScope() const
GDBIndexEntryLinkage Linkage
DIE * constructImportedEntityDIE(const DIImportedEntity *Module)
Construct import_module DIE.
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Helper used to pair up a symbol and its DWARF compile unit.
iterator erase(iterator I)
unsigned getDwarfVersion() const
Returns the Dwarf Version by checking module flags.
ArrayRef< List > getLists() const
Triple - Helper class for working with autoconf configuration names.
DITypeRef getType() const
An imported module (C++ using directive or similar).
void dump() const
Support for debugging, callable in GDB: V->dump()
StringRef getDirectory() const
SmallVector< RangeSpan, 2 > takeRanges()
static DebugLoc findPrologueEndLoc(const MachineFunction *MF)
LexicalScope * findInlinedScope(const DILocalScope *N, const DILocation *IA)
findInlinedScope - Find an inlined scope for the given scope/inlined-at.
std::pair< iterator, bool > insert(const ValueT &V)
static bool hasObjCCategory(StringRef Name)
void beginInstruction(const MachineInstr *MI) override
Process beginning of an instruction.
bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
void beginFunction(const MachineFunction *MF) override
Gather pre-function debug information.
void setDebugInfoAvailability(bool avail)
SectionKind getKind() const
const MCContext & getContext() const
uint16_t getLanguage() const
static LLVM_CONSTEXPR DwarfAccelTable::Atom TypeAtoms[]
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
virtual void EmitSLEB128(uint64_t DWord, const Twine &Comment="")=0
Module.h This file contains the declarations for the Module class.
void computeSizeAndOffsets()
Compute the size and offset of all the DIEs.
void beginModule()
Emit all Dwarf sections that should come prior to the content.
const SmallVectorImpl< RangeSpan > & getRanges() const
getRanges - Get the list of ranges for this unit.
bool isSubprogramContext(const MDNode *Context)
isSubprogramContext - Return true if Context is either a subprogram or another context nested inside ...
unsigned getOffset() const
MCSymbol * getBeginSymbol()
DwarfCompileUnit * lookupUnit(const DIE *CU) const
Find the DwarfCompileUnit for the given CU Die.
void addAccelName(StringRef Name, const DIE &Die)
void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
const StringMap< const DIE * > & getGlobalNames() const
void emitDebugLocEntry(ByteStreamer &Streamer, const DebugLocStream::Entry &Entry)
Emit an entry for the debug loc section.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isFPImm() const
isFPImm - Tests if this is a MO_FPImmediate operand.
const ConstantInt * getCImm() const
bool isBlockByrefStruct() const
StringMap - This is an unconventional map that is specialized for handling keys that are "strings"...
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
void addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DIE &Entry)
Add a DIE attribute data and value.
void emitAbbrevs(MCSection *)
Emit a set of abbreviations to the specific section.
void endInstruction() override
Process end of an instruction.
static cl::opt< bool > UnknownLocations("use-unknown-locations", cl::Hidden, cl::desc("Make an absence of debug location information explicit."), cl::init(false))
bool addScopeVariable(LexicalScope *LS, DbgVariable *Var)
A single location or constant.
void finalize(const AsmPrinter &AP, DebugLocStream::ListBuilder &List, const DIBasicType *BT)
Lower this entry into a DWARF expression.
DIE * getOrCreateContextDIE(const DIScope *Context)
Get context owner's DIE.
const char * GDBIndexEntryKindString(GDBIndexEntryKind Kind)
void EmitUnsigned(uint64_t Value) override
Emit a raw unsigned value.
Representation of each machine instruction.
static StringRef getObjCMethodName(StringRef In)
NamedMDNode * getNamedMetadata(const Twine &Name) const
Return the first NamedMDNode in the module with the specified name.
EntryRef getEntry(AsmPrinter &Asm, StringRef Str)
Get a reference to an entry in the string pool.
static cl::opt< DefaultOnOff > DwarfPubSections("generate-dwarf-pub-sections", cl::Hidden, cl::desc("Generate DWARF pubnames and pubtypes sections"), cl::values(clEnumVal(Default,"Default for platform"), clEnumVal(Enable,"Enabled"), clEnumVal(Disable,"Disabled"), clEnumValEnd), cl::init(Default))
const SmallVectorImpl< std::unique_ptr< DwarfUnit > > & getUnits()
std::pair< const MachineInstr *, const MachineInstr * > InsnRange
InsnRange - This is used to track range of instructions with identical lexical scope.
op_range operands() const
void emitStrings(MCSection *StrSection, MCSection *OffsetSection=nullptr)
Emit all of the strings to the section given.
bool isBitPiece() const
Return whether this is a piece of an aggregate variable.
bool all_of(R &&Range, UnaryPredicate &&P)
Provide wrappers to std::all_of which take ranges instead of having to pass being/end explicitly...
const DITypeIdentifierMap & getTypeIdentifierMap() const
Return the TypeIdentifierMap.
void set(unsigned R)
Make this location a direct register location.
void addSubprogramNames(const DISubprogram *SP, DIE &Die)
std::vector< uint8_t > Unit
unsigned getReg() const
getReg - Returns the register number.
reverse_iterator rbegin()
void addDIETypeSignature(DIE &Die, const DwarfTypeUnit &Type)
DenseMap< const Function *, DISubprogram * > makeSubprogramMap(const Module &M)
static const char *const DWARFGroupName
bool isBlockByrefVariable() const
LLVM Value Representation.
MCSection * getDwarfRangesSection() const
uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
uint64_t getBitPieceSize() const
Return the size of this piece in bits.
uint64_t getBitPieceOffset() const
Return the offset of this piece in bits.
unsigned getNumOperands() const
std::string Hash(const Unit &U)
void addUnit(std::unique_ptr< DwarfUnit > U)
Add a unit to the list of CUs.
void addAccelObjC(StringRef Name, const DIE &Die)
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
StringRef - Represent a constant reference to a string, i.e.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
const DIE * getUnit() const
Climb up the parent chain to get the compile or type unit DIE this DIE belongs to.
bool TimePassesIsEnabled
If the user specifies the -time-passes argument on an LLVM tool command line then the value of this b...
DITypeIdentifierMap generateDITypeIdentifierMap(const NamedMDNode *CU_Nodes)
Generate map by visiting all retained types.
static bool isObjCClass(StringRef Name)
Builder for DebugLocStream entries.
DISubprogram * getSubprogram() const
Get the subprogram for this scope.
static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT, ByteStreamer &Streamer, const DebugLocEntry::Value &Value, unsigned PieceOffsetInBits)
expr_op_iterator expr_op_end() const
StringRef getProducer() const
void finishSubprogramDefinition(const DISubprogram *SP)
unsigned getDwarfVersion() const
Returns the Dwarf Version.
void addUInt(DIE &Die, dwarf::Attribute Attribute, Optional< dwarf::Form > Form, uint64_t Integer)
Add an unsigned integer attribute data and value.
Function object to check whether the first component of a std::pair compares less than the first comp...
bool empty()
empty - Return true if there is any lexical scope information available.
bool empty() const
empty - Check if the string is empty.
Basic type, like 'int' or 'float'.
unsigned getIndex(const MCSymbol *Sym, bool TLS=false)
Returns the index into the address pool with the given label/symbol.
StringRef getSplitDebugFilename() const