65using namespace object;
67#define DEBUG_TYPE "dwarf"
75 std::function<
void(
Error)> RecoverableErrorHandler,
76 std::function<
void(
Error)> WarningHandler)
78 RecoverableErrorHandler(RecoverableErrorHandler),
79 WarningHandler(WarningHandler), DObj(
std::
move(DObj)) {}
85 auto *MachO = dyn_cast<MachOObjectFile>(&Obj);
88 for (
auto LC : MachO->load_commands()) {
90 if (LC.C.cmd == MachO::LC_UUID) {
91 if (LC.C.cmdsize <
sizeof(
UUID) +
sizeof(LC.C)) {
92 OS <<
"error: UUID load command is too short.\n";
96 memcpy(&
UUID, LC.Ptr+
sizeof(LC.C),
sizeof(
UUID));
98 Triple T = MachO->getArchTriple();
99 OS <<
" (" <<
T.getArchName() <<
')';
100 OS <<
' ' << MachO->getFileName() <<
'\n';
106 std::vector<std::optional<StrOffsetsContributionDescriptor>>;
113 for (
const auto &U : Units)
114 if (
const auto &
C = U->getStringOffsetsTableContribution())
115 Contributions.push_back(
C);
120 [](
const std::optional<StrOffsetsContributionDescriptor> &L,
121 const std::optional<StrOffsetsContributionDescriptor> &R) {
123 return L->Base < R->Base;
124 return R.has_value();
131 std::unique(Contributions.begin(), Contributions.end(),
132 [](
const std::optional<StrOffsetsContributionDescriptor> &L,
133 const std::optional<StrOffsetsContributionDescriptor> &R) {
135 return L->Base == R->Base && L->Size == R->Size;
138 Contributions.end());
139 return Contributions;
162 for (
auto &Contribution : Contributions) {
165 OS <<
"error: invalid contribution to string offsets table in section ."
172 uint16_t Version = Contribution->getVersion();
173 uint64_t ContributionHeader = Contribution->Base;
182 if (
Offset > ContributionHeader) {
185 "overlapping contributions to string offsets table in section .%s.",
189 if (
Offset < ContributionHeader) {
191 OS << (ContributionHeader -
Offset) <<
"\n";
193 OS <<
format(
"0x%8.8" PRIx64
": ", ContributionHeader);
198 OS <<
"Contribution size = " << (Contribution->Size + (Version < 5 ? 0 : 4))
200 <<
", Version = " << Version <<
"\n";
202 Offset = Contribution->Base;
203 unsigned EntrySize = Contribution->getDwarfOffsetByteSize();
204 while (
Offset - Contribution->Base < Contribution->Size) {
208 OS <<
format(
"%0*" PRIx64
" ", OffsetDumpWidth, StringOffset);
209 const char *S = StrData.
getCStr(&StringOffset);
216 if (
Offset < SectionSize) {
218 OS << (SectionSize -
Offset) <<
"\n";
236 Offset = TableOffset + *TableLength;
241 AddrTable.
dump(
OS, DumpOpts);
264 Rnglists.
dump(rnglistData,
OS, LookupPooledAddress, DumpOpts);
269std::unique_ptr<DWARFDebugMacro>
270DWARFContext::parseMacroOrMacinfo(MacroSecType SectionType) {
271 auto Macro = std::make_unique<DWARFDebugMacro>();
273 if (
Error Err = IsMacro ? Macro->parseMacro(SectionType == MacroSection
276 SectionType == MacroSection
280 : Macro->parseMacinfo(
Data)) {
281 RecoverableErrorHandler(std::move(Err));
285 switch (SectionType) {
286 case MacinfoSection: {
288 ParseAndDump(
Data,
false);
291 case MacinfoDwoSection: {
293 ParseAndDump(
Data,
false);
299 ParseAndDump(
Data,
true);
302 case MacroDwoSection: {
304 ParseAndDump(
Data,
true);
313 std::optional<uint64_t> DumpOffset) {
323 Header.dump(
Data,
OS, DumpOpts);
325 uint64_t EndOffset = Header.length() + Header.getHeaderOffset();
326 Data.setAddressSize(Header.getAddrSize());
329 if (DumpOffset >=
Offset && DumpOffset < EndOffset) {
332 nullptr, DumpOpts, 0);
352 std::array<std::optional<uint64_t>,
DIDT_ID_Count> DumpOffsets) {
356 bool IsDWO = (Extension ==
".dwo") || (Extension ==
".dwp");
359 const auto *ObjFile = DObj->getFile();
366 bool Explicit = DumpType !=
DIDT_All && !IsDWO;
367 bool ExplicitDWO = Explicit && IsDWO;
368 auto shouldDump = [&](
bool Explicit,
const char *
Name,
unsigned ID,
369 StringRef Section) -> std::optional<uint64_t> * {
370 unsigned Mask = 1U <<
ID;
371 bool Should = (DumpType & Mask) && (Explicit || !Section.empty());
374 OS <<
"\n" <<
Name <<
" contents:\n";
375 return &DumpOffsets[
ID];
379 if (shouldDump(Explicit,
".debug_abbrev", DIDT_ID_DebugAbbrev,
380 DObj->getAbbrevSection()))
382 if (shouldDump(ExplicitDWO,
".debug_abbrev.dwo", DIDT_ID_DebugAbbrev,
383 DObj->getAbbrevDWOSection()))
387 OS <<
'\n' <<
Name <<
" contents:\n";
388 if (
auto DumpOffset = DumpOffsets[DIDT_ID_DebugInfo])
389 for (
const auto &U : Units)
390 U->getDIEForOffset(*DumpOffset)
393 for (
const auto &U : Units)
394 U->dump(
OS, DumpOpts);
396 if ((DumpType & DIDT_DebugInfo)) {
404 OS <<
'\n' <<
Name <<
" contents:\n";
405 for (
const auto &U : Units)
406 if (
auto DumpOffset = DumpOffsets[DIDT_ID_DebugTypes])
407 U->getDIEForOffset(*DumpOffset)
410 U->dump(
OS, DumpOpts);
412 if ((DumpType & DIDT_DebugTypes)) {
423 if (
const auto *Off = shouldDump(Explicit,
".debug_loc", DIDT_ID_DebugLoc,
424 DObj->getLocSection().Data)) {
427 if (
const auto *Off =
428 shouldDump(Explicit,
".debug_loclists", DIDT_ID_DebugLoclists,
429 DObj->getLoclistsSection().Data)) {
434 if (
const auto *Off =
435 shouldDump(ExplicitDWO,
".debug_loclists.dwo", DIDT_ID_DebugLoclists,
436 DObj->getLoclistsDWOSection().Data)) {
442 if (
const auto *Off =
443 shouldDump(ExplicitDWO,
".debug_loc.dwo", DIDT_ID_DebugLoc,
444 DObj->getLocDWOSection().Data)) {
451 std::nullopt, *DObj,
nullptr,
460 if (
const std::optional<uint64_t> *Off =
461 shouldDump(Explicit,
".debug_frame", DIDT_ID_DebugFrame,
462 DObj->getFrameSection().Data)) {
464 (*DF)->dump(
OS, DumpOpts, *Off);
466 RecoverableErrorHandler(
DF.takeError());
469 if (
const std::optional<uint64_t> *Off =
470 shouldDump(Explicit,
".eh_frame", DIDT_ID_DebugFrame,
471 DObj->getEHFrameSection().Data)) {
473 (*DF)->dump(
OS, DumpOpts, *Off);
475 RecoverableErrorHandler(
DF.takeError());
478 if (shouldDump(Explicit,
".debug_macro", DIDT_ID_DebugMacro,
479 DObj->getMacroSection().Data)) {
484 if (shouldDump(Explicit,
".debug_macro.dwo", DIDT_ID_DebugMacro,
485 DObj->getMacroDWOSection())) {
490 if (shouldDump(Explicit,
".debug_macinfo", DIDT_ID_DebugMacro,
491 DObj->getMacinfoSection())) {
496 if (shouldDump(Explicit,
".debug_macinfo.dwo", DIDT_ID_DebugMacro,
497 DObj->getMacinfoDWOSection())) {
499 MacinfoDWO->dump(
OS);
502 if (shouldDump(Explicit,
".debug_aranges", DIDT_ID_DebugAranges,
503 DObj->getArangesSection())) {
511 RecoverableErrorHandler(std::move(
E));
520 std::optional<uint64_t> DumpOffset) {
522 if (DumpOffset &&
Parser.getOffset() != *DumpOffset) {
526 OS <<
"debug_line[" <<
format(
"0x%8.8" PRIx64,
Parser.getOffset())
533 auto DumpStrSection = [&](
StringRef Section) {
544 OS <<
format(
"0x%8.8" PRIx64
": \"", StrOffset);
551 if (
const auto *Off = shouldDump(Explicit,
".debug_line", DIDT_ID_DebugLine,
552 DObj->getLineSection().Data)) {
556 DumpLineSection(
Parser, DumpOpts, *Off);
559 if (
const auto *Off =
560 shouldDump(ExplicitDWO,
".debug_line.dwo", DIDT_ID_DebugLine,
561 DObj->getLineDWOSection().Data)) {
565 DumpLineSection(
Parser, DumpOpts, *Off);
568 if (shouldDump(Explicit,
".debug_cu_index", DIDT_ID_DebugCUIndex,
569 DObj->getCUIndexSection())) {
573 if (shouldDump(Explicit,
".debug_tu_index", DIDT_ID_DebugTUIndex,
574 DObj->getTUIndexSection())) {
578 if (shouldDump(Explicit,
".debug_str", DIDT_ID_DebugStr,
579 DObj->getStrSection()))
580 DumpStrSection(DObj->getStrSection());
582 if (shouldDump(ExplicitDWO,
".debug_str.dwo", DIDT_ID_DebugStr,
583 DObj->getStrDWOSection()))
584 DumpStrSection(DObj->getStrDWOSection());
586 if (shouldDump(Explicit,
".debug_line_str", DIDT_ID_DebugLineStr,
587 DObj->getLineStrSection()))
588 DumpStrSection(DObj->getLineStrSection());
590 if (shouldDump(Explicit,
".debug_addr", DIDT_ID_DebugAddr,
591 DObj->getAddrSection().Data)) {
597 if (shouldDump(Explicit,
".debug_ranges", DIDT_ID_DebugRanges,
598 DObj->getRangesSection().Data)) {
613 auto LookupPooledAddress =
616 auto I = CUs.begin();
619 return (*I)->getAddrOffsetSectionItem(
Index);
622 if (shouldDump(Explicit,
".debug_rnglists", DIDT_ID_DebugRnglists,
623 DObj->getRnglistsSection().Data)) {
629 if (shouldDump(ExplicitDWO,
".debug_rnglists.dwo", DIDT_ID_DebugRnglists,
630 DObj->getRnglistsDWOSection().Data)) {
636 if (shouldDump(Explicit,
".debug_pubnames", DIDT_ID_DebugPubnames,
637 DObj->getPubnamesSection().Data)) {
643 if (shouldDump(Explicit,
".debug_pubtypes", DIDT_ID_DebugPubtypes,
644 DObj->getPubtypesSection().Data)) {
650 if (shouldDump(Explicit,
".debug_gnu_pubnames", DIDT_ID_DebugGnuPubnames,
651 DObj->getGnuPubnamesSection().Data)) {
657 if (shouldDump(Explicit,
".debug_gnu_pubtypes", DIDT_ID_DebugGnuPubtypes,
658 DObj->getGnuPubtypesSection().Data)) {
664 if (shouldDump(Explicit,
".debug_str_offsets", DIDT_ID_DebugStrOffsets,
665 DObj->getStrOffsetsSection().Data))
667 OS, DumpOpts,
"debug_str_offsets", *DObj, DObj->getStrOffsetsSection(),
669 if (shouldDump(ExplicitDWO,
".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets,
670 DObj->getStrOffsetsDWOSection().Data))
672 DObj->getStrOffsetsDWOSection(),
676 if (shouldDump(Explicit,
".gdb_index", DIDT_ID_GdbIndex,
677 DObj->getGdbIndexSection())) {
681 if (shouldDump(Explicit,
".apple_names", DIDT_ID_AppleNames,
682 DObj->getAppleNamesSection().Data))
685 if (shouldDump(Explicit,
".apple_types", DIDT_ID_AppleTypes,
686 DObj->getAppleTypesSection().Data))
689 if (shouldDump(Explicit,
".apple_namespaces", DIDT_ID_AppleNamespaces,
690 DObj->getAppleNamespacesSection().Data))
693 if (shouldDump(Explicit,
".apple_objc", DIDT_ID_AppleObjC,
694 DObj->getAppleObjCSection().Data))
696 if (shouldDump(Explicit,
".debug_names", DIDT_ID_DebugNames,
697 DObj->getNamesSection().Data))
703 parseDWOUnits(LazyParse);
706 if (
const auto *R = TUI.getFromHash(Hash))
707 return dyn_cast_or_null<DWARFTypeUnit>(
712 struct UnitContainers {
714 std::optional<DenseMap<uint64_t, DWARFTypeUnit *>> ⤅
716 UnitContainers Units = IsDWO ? UnitContainers{DWOUnits, DWOTypeUnits}
717 : UnitContainers{NormalUnits, NormalTypeUnits};
722 (*Units.Map)[TU->getTypeHash()] = TU;
726 return (*Units.Map)[Hash];
730 parseDWOUnits(LazyParse);
733 if (
const auto *R = CUI.getFromHash(Hash))
734 return dyn_cast_or_null<DWARFCompileUnit>(
745 if (!DWOCU->getDWOId()) {
746 if (std::optional<uint64_t> DWOId =
747 toUnsigned(DWOCU->getUnitDIE().find(DW_AT_GNU_dwo_id)))
748 DWOCU->setDWOId(*DWOId);
753 if (DWOCU->getDWOId() == Hash)
754 return dyn_cast<DWARFCompileUnit>(DWOCU.get());
771 if (DumpOpts.
DumpType & DIDT_DebugCUIndex)
773 if (DumpOpts.
DumpType & DIDT_DebugTUIndex)
775 if (DumpOpts.
DumpType & DIDT_DebugInfo)
777 if (DumpOpts.
DumpType & DIDT_DebugLine)
794 if (!(
C.getParseCUTUIndexManually() ||
795 S.
Data.
size() >= std::numeric_limits<uint32_t>::max()))
800 DWARFUnitHeader Header;
801 if (!Header.extract(C, Data, &Offset, DWARFSectionKind::DW_SECT_INFO)) {
802 logAllUnhandledErrors(
803 createError(
"Failed to parse CU header in DWP file"), errs());
808 auto Iter = Map.insert({TruncOffset,
809 {Header.getOffset(), Header.getNextUnitOffset() -
810 Header.getOffset()}});
812 logAllUnhandledErrors(
813 createError(
"Collision occured between for truncated offset 0x" +
814 Twine::utohexstr(TruncOffset)),
820 Offset = Header.getNextUnitOffset();
833 if (Iter ==
Map.end()) {
840 CUOff.
setOffset(Iter->second.getOffset());
841 if (CUOff.
getOffset() != Iter->second.getOffset())
843 "match calculated length at offset 0x" +
854 if (!(
C.getParseCUTUIndexManually() ||
855 S.
Data.
size() >= std::numeric_limits<uint32_t>::max()))
860 DWARFUnitHeader Header;
861 if (!Header.extract(C, Data, &Offset, DWARFSectionKind::DW_SECT_INFO)) {
862 logAllUnhandledErrors(
863 createError(
"Failed to parse unit header in DWP file"), errs());
866 bool CU = Header.getUnitType() == DW_UT_split_compile;
867 uint64_t Sig =
CU ? *Header.getDWOId() : Header.getTypeHash();
868 Map[Sig] = Header.getOffset();
869 Offset = Header.getNextUnitOffset();
878 auto Iter =
Map.find(
E.getSignature());
879 if (Iter ==
Map.end()) {
881 createError(
"Could not find unit with signature 0x" +
892 if (
Index.getVersion() < 5)
903 CUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_INFO);
904 bool IsParseSuccessful = CUIndex->parse(CUIndexData);
905 if (IsParseSuccessful)
916 bool isParseSuccessful = TUIndex->parse(TUIndexData);
919 if (isParseSuccessful && TUIndex->getVersion() != 2)
928 DataExtractor GdbIndexData(DObj->getGdbIndexSection(),
true , 0);
929 GdbIndex = std::make_unique<DWARFGdbIndex>();
930 GdbIndex->parse(GdbIndexData);
941 Abbrev->extract(abbrData);
947 return AbbrevDWO.get();
951 AbbrevDWO->extract(abbrData);
952 return AbbrevDWO.get();
971 return Aranges.get();
974 Aranges->generate(
this);
975 return Aranges.get();
980 return DebugFrame.get();
994 DObj->getAddressSize());
996 std::make_unique<DWARFDebugFrame>(
getArch(),
false, DS.Address);
997 if (
Error E =
DF->parse(DebugFrameData))
1000 DebugFrame.swap(
DF);
1001 return DebugFrame.get();
1006 return EHFrame.get();
1010 DObj->getAddressSize());
1013 std::make_unique<DWARFDebugFrame>(
getArch(),
true, DS.Address);
1014 if (
Error E =
DF->parse(DebugFrameData))
1015 return std::move(
E);
1016 DebugFrame.swap(
DF);
1017 return DebugFrame.get();
1022 Macro = parseMacroOrMacinfo(MacroSection);
1028 MacroDWO = parseMacroOrMacinfo(MacroDwoSection);
1029 return MacroDWO.get();
1034 Macinfo = parseMacroOrMacinfo(MacinfoSection);
1035 return Macinfo.get();
1040 MacinfoDWO = parseMacroOrMacinfo(MacinfoDwoSection);
1041 return MacinfoDWO.get();
1044template <
typename T>
1047 bool IsLittleEndian) {
1052 Cache.reset(
new T(AccelSection, StrData));
1053 if (
Error E = Cache->extract())
1064 return getAccelTable(AppleNames, *DObj, DObj->getAppleNamesSection(),
1069 return getAccelTable(AppleTypes, *DObj, DObj->getAppleTypesSection(),
1075 DObj->getAppleNamespacesSection(),
1080 return getAccelTable(AppleObjC, *DObj, DObj->getAppleObjCSection(),
1088 if (!ExpectedLineTable) {
1089 WarningHandler(ExpectedLineTable.
takeError());
1092 return *ExpectedLineTable;
1100 auto UnitDIE = U->getUnitDIE();
1114 if (stmtOffset >= U->getLineSection().Data.size())
1119 U->getAddressByteSize());
1120 return Line->getOrParseLineTable(lineData, stmtOffset, *
this, U,
1121 RecoverableErrorHandler);
1128 auto UnitDIE = U->getUnitDIE();
1137 Line->clearLineTable(stmtOffset);
1140void DWARFContext::parseNormalUnits() {
1141 if (!NormalUnits.
empty())
1147 DObj->forEachTypesSections([&](
const DWARFSection &S) {
1152void DWARFContext::parseDWOUnits(
bool Lazy) {
1153 if (!DWOUnits.
empty())
1155 DObj->forEachInfoDWOSections([&](
const DWARFSection &S) {
1159 DObj->forEachTypesDWOSections([&](
const DWARFSection &S) {
1166 return dyn_cast_or_null<DWARFCompileUnit>(
1205 Result.CompileUnit =
CU;
1206 Result.FunctionDIE =
CU->getSubroutineForAddress(
Address);
1208 std::vector<DWARFDie> Worklist;
1209 Worklist.push_back(Result.FunctionDIE);
1210 while (!Worklist.empty()) {
1212 Worklist.pop_back();
1217 if (
DIE.
getTag() == DW_TAG_lexical_block &&
1219 Result.BlockDIE =
DIE;
1234 std::string &FunctionName, std::string &StartFile,
uint32_t &StartLine,
1235 std::optional<uint64_t> &StartAddress) {
1240 CU->getInlinedChainForAddress(
Address, InlinedChain);
1241 if (InlinedChain.
empty())
1245 bool FoundResult =
false;
1246 const char *
Name =
nullptr;
1247 if (
Kind != FunctionNameKind::None && (
Name =
DIE.getSubroutineName(
Kind))) {
1248 FunctionName =
Name;
1251 std::string DeclFile =
DIE.getDeclFile(FileNameKind);
1252 if (!DeclFile.empty()) {
1253 StartFile = DeclFile;
1256 if (
auto DeclLineResult =
DIE.getDeclLine()) {
1257 StartLine = DeclLineResult;
1261 StartAddress = LowPcAddr->Address;
1265static std::optional<int64_t>
1267 std::optional<unsigned> FrameBaseReg) {
1268 if (!Expr.
empty() &&
1269 (Expr[0] == DW_OP_fbreg ||
1270 (FrameBaseReg && Expr[0] == DW_OP_breg0 + *FrameBaseReg))) {
1274 if (Expr.
size() == Count + 1)
1277 if (Expr.
size() == Count + 2 && Expr[Count + 1] == DW_OP_deref)
1281 return std::nullopt;
1285 DWARFDie Die, std::vector<DILocal> &Result) {
1286 if (Die.
getTag() == DW_TAG_variable ||
1287 Die.
getTag() == DW_TAG_formal_parameter) {
1292 std::optional<unsigned> FrameBaseReg;
1293 if (
auto FrameBase = Subprogram.
find(DW_AT_frame_base))
1295 if (!Expr->empty() && (*Expr)[0] >= DW_OP_reg0 &&
1296 (*Expr)[0] <= DW_OP_reg31) {
1297 FrameBaseReg = (*Expr)[0] - DW_OP_reg0;
1300 if (
Expected<std::vector<DWARFLocationExpression>> Loc =
1302 for (
const auto &Entry : *Loc) {
1303 if (std::optional<int64_t> FrameOffset =
1305 Local.FrameOffset = *FrameOffset;
1315 if (
auto TagOffsetAttr = Die.
find(DW_AT_LLVM_tag_offset))
1316 Local.TagOffset = TagOffsetAttr->getAsUnsignedConstant();
1321 if (
auto NameAttr = Die.
find(DW_AT_name))
1326 if (
auto DeclFileAttr = Die.
find(DW_AT_decl_file)) {
1327 if (
const auto *LT =
CU->getContext().getLineTableForUnit(
CU))
1328 LT->getFileNameByIndex(
1329 *DeclFileAttr->getAsUnsignedConstant(),
CU->getCompilationDir(),
1330 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
1333 if (
auto DeclLineAttr = Die.
find(DW_AT_decl_line))
1334 Local.DeclLine = *DeclLineAttr->getAsUnsignedConstant();
1340 if (Die.
getTag() == DW_TAG_inlined_subroutine)
1343 Subprogram = Origin;
1345 for (
auto Child : Die)
1346 addLocalsForDie(
CU, Subprogram, Child, Result);
1351 std::vector<DILocal> Result;
1358 addLocalsForDie(
CU, Subprogram, Subprogram, Result);
1371 Result.StartFileName, Result.StartLine, Result.StartAddress);
1372 if (
Spec.FLIKind != FileLineInfoKind::None) {
1374 LineTable->getFileLineInfoForAddress(
1376 Spec.FLIKind, Result);
1391 Result.FileName = Die.
getDeclFile(FileLineInfoKind::AbsoluteFilePath);
1406 std::string StartFileName;
1408 std::optional<uint64_t> StartAddress;
1410 Spec.FLIKind, FunctionName,
1411 StartFileName, StartLine, StartAddress);
1415 if (
Spec.FLIKind == FileLineInfoKind::None) {
1417 Result.FunctionName = FunctionName;
1418 Result.StartFileName = StartFileName;
1419 Result.StartLine = StartLine;
1420 Result.StartAddress = StartAddress;
1421 Lines.push_back(std::make_pair(
Address.Address, Result));
1428 std::vector<uint32_t> RowVector;
1434 for (
uint32_t RowIndex : RowVector) {
1439 Spec.FLIKind, Result.FileName);
1440 Result.FunctionName = FunctionName;
1441 Result.Line = Row.Line;
1442 Result.Column = Row.Column;
1443 Result.StartFileName = StartFileName;
1444 Result.StartLine = StartLine;
1445 Result.StartAddress = StartAddress;
1446 Lines.push_back(std::make_pair(Row.Address.Address, Result));
1459 return InliningInfo;
1463 CU->getInlinedChainForAddress(
Address.Address, InlinedChain);
1464 if (InlinedChain.
size() == 0) {
1467 if (
Spec.FLIKind != FileLineInfoKind::None) {
1471 {Address.Address, Address.SectionIndex},
1472 CU->getCompilationDir(),
Spec.FLIKind, Frame))
1475 return InliningInfo;
1478 uint32_t CallFile = 0, CallLine = 0, CallColumn = 0, CallDiscriminator = 0;
1479 for (
uint32_t i = 0, n = InlinedChain.
size(); i != n; i++) {
1480 DWARFDie &FunctionDIE = InlinedChain[i];
1485 if (
auto DeclLineResult = FunctionDIE.
getDeclLine())
1490 if (
Spec.FLIKind != FileLineInfoKind::None) {
1499 Spec.FLIKind, Frame);
1506 Frame.
Line = CallLine;
1507 Frame.
Column = CallColumn;
1518 return InliningInfo;
1521std::shared_ptr<DWARFContext>
1523 if (
auto S = DWP.lock()) {
1525 return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
1528 std::weak_ptr<DWOFile> *Entry = &DWOFiles[AbsolutePath];
1530 if (
auto S = Entry->lock()) {
1532 return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
1536 if (!CheckedForDWP) {
1539 this->DWPName.
empty()
1540 ? (DObj->getFileName() +
".dwp").toStringRef(DWPName)
1546 CheckedForDWP =
true;
1562 auto S = std::make_shared<DWOFile>();
1563 S->File = std::move(Obj.
get());
1567 auto *Ctxt = S->Context.get();
1568 return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
1572 return make_error<StringError>(Reason +
toString(std::move(
E)),
1588 std::map<SymbolRef, SymInfo> &Cache) {
1593 std::map<SymbolRef, SymInfo>::iterator CacheIt = Cache.end();
1598 std::tie(CacheIt, New) = Cache.insert({*
Sym, {0, 0}});
1600 return CacheIt->second;
1604 return createError(
"failed to compute symbol address: ",
1608 auto SectOrErr =
Sym->getSection();
1610 return createError(
"failed to get symbol section: ",
1611 SectOrErr.takeError());
1614 Ret.Address = *SymAddrOrErr;
1615 }
else if (
auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) {
1617 Ret.Address = RSec->getAddress();
1621 Ret.SectionIndex = RSec->getIndex();
1631 if (
uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec))
1632 Ret.Address += SectionLoadAddress - RSec->getAddress();
1634 if (CacheIt != Cache.end())
1635 CacheIt->second = Ret;
1656class DWARFObjInMemory final :
public DWARFObject {
1657 bool IsLittleEndian;
1658 uint8_t AddressSize;
1661 std::vector<SectionName> SectionNames;
1664 std::map<object::SectionRef, unsigned>>;
1666 InfoSectionMap InfoSections;
1667 InfoSectionMap TypesSections;
1668 InfoSectionMap InfoDWOSections;
1669 InfoSectionMap TypesDWOSections;
1671 DWARFSectionMap LocSection;
1672 DWARFSectionMap LoclistsSection;
1673 DWARFSectionMap LoclistsDWOSection;
1674 DWARFSectionMap LineSection;
1675 DWARFSectionMap RangesSection;
1676 DWARFSectionMap RnglistsSection;
1677 DWARFSectionMap StrOffsetsSection;
1678 DWARFSectionMap LineDWOSection;
1679 DWARFSectionMap FrameSection;
1680 DWARFSectionMap EHFrameSection;
1681 DWARFSectionMap LocDWOSection;
1682 DWARFSectionMap StrOffsetsDWOSection;
1683 DWARFSectionMap RangesDWOSection;
1684 DWARFSectionMap RnglistsDWOSection;
1685 DWARFSectionMap AddrSection;
1686 DWARFSectionMap AppleNamesSection;
1687 DWARFSectionMap AppleTypesSection;
1688 DWARFSectionMap AppleNamespacesSection;
1689 DWARFSectionMap AppleObjCSection;
1690 DWARFSectionMap NamesSection;
1691 DWARFSectionMap PubnamesSection;
1692 DWARFSectionMap PubtypesSection;
1693 DWARFSectionMap GnuPubnamesSection;
1694 DWARFSectionMap GnuPubtypesSection;
1695 DWARFSectionMap MacroSection;
1699 .
Case(
"debug_loc", &LocSection)
1700 .
Case(
"debug_loclists", &LoclistsSection)
1701 .
Case(
"debug_loclists.dwo", &LoclistsDWOSection)
1702 .
Case(
"debug_line", &LineSection)
1703 .
Case(
"debug_frame", &FrameSection)
1704 .
Case(
"eh_frame", &EHFrameSection)
1705 .
Case(
"debug_str_offsets", &StrOffsetsSection)
1706 .
Case(
"debug_ranges", &RangesSection)
1707 .
Case(
"debug_rnglists", &RnglistsSection)
1708 .
Case(
"debug_loc.dwo", &LocDWOSection)
1709 .
Case(
"debug_line.dwo", &LineDWOSection)
1710 .
Case(
"debug_names", &NamesSection)
1711 .
Case(
"debug_rnglists.dwo", &RnglistsDWOSection)
1712 .
Case(
"debug_str_offsets.dwo", &StrOffsetsDWOSection)
1713 .
Case(
"debug_addr", &AddrSection)
1714 .
Case(
"apple_names", &AppleNamesSection)
1715 .
Case(
"debug_pubnames", &PubnamesSection)
1716 .
Case(
"debug_pubtypes", &PubtypesSection)
1717 .
Case(
"debug_gnu_pubnames", &GnuPubnamesSection)
1718 .
Case(
"debug_gnu_pubtypes", &GnuPubtypesSection)
1719 .
Case(
"apple_types", &AppleTypesSection)
1720 .
Case(
"apple_namespaces", &AppleNamespacesSection)
1721 .
Case(
"apple_namespac", &AppleNamespacesSection)
1722 .
Case(
"apple_objc", &AppleObjCSection)
1723 .
Case(
"debug_macro", &MacroSection)
1742 std::deque<SmallString<0>> UncompressedSections;
1748 .
Case(
"debug_abbrev", &AbbrevSection)
1749 .
Case(
"debug_aranges", &ArangesSection)
1750 .
Case(
"debug_str", &StrSection)
1751 .
Case(
"debug_macinfo", &MacinfoSection)
1752 .
Case(
"debug_macinfo.dwo", &MacinfoDWOSection)
1753 .
Case(
"debug_macro.dwo", &MacroDWOSection)
1754 .
Case(
"debug_abbrev.dwo", &AbbrevDWOSection)
1755 .
Case(
"debug_str.dwo", &StrDWOSection)
1756 .
Case(
"debug_cu_index", &CUIndexSection)
1757 .
Case(
"debug_tu_index", &TUIndexSection)
1758 .
Case(
"gdb_index", &GdbIndexSection)
1759 .
Case(
"debug_line_str", &LineStrSection)
1780 UncompressedSections.push_back(std::move(Out));
1781 Data = UncompressedSections.back();
1787 DWARFObjInMemory(
const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
1788 uint8_t AddrSize,
bool IsLittleEndian)
1789 : IsLittleEndian(IsLittleEndian) {
1790 for (
const auto &SecIt : Sections) {
1791 if (
StringRef *SectionData = mapSectionToMember(SecIt.first()))
1792 *SectionData = SecIt.second->getBuffer();
1793 else if (SecIt.first() ==
"debug_info")
1796 InfoSections[
SectionRef()].Data = SecIt.second->getBuffer();
1797 else if (SecIt.first() ==
"debug_info.dwo")
1798 InfoDWOSections[
SectionRef()].Data = SecIt.second->getBuffer();
1799 else if (SecIt.first() ==
"debug_types")
1800 TypesSections[
SectionRef()].Data = SecIt.second->getBuffer();
1801 else if (SecIt.first() ==
"debug_types.dwo")
1802 TypesDWOSections[
SectionRef()].Data = SecIt.second->getBuffer();
1809 : IsLittleEndian(Obj.isLittleEndian()),
1810 AddressSize(Obj.getBytesInAddress()), FileName(Obj.
getFileName()),
1816 if (
auto NameOrErr =
Section.getName())
1821 ++SectionAmountMap[
Name];
1822 SectionNames.push_back({
Name,
true });
1835 HandleError(
createError(
"failed to get relocated section: ",
1845 if (!L || !
L->getLoadedSectionContents(*RelocatedSection,
Data)) {
1854 if (
auto Err = maybeDecompress(Section,
Name,
Data)) {
1863 Name.find_first_not_of(
"._z"));
1870 *SectionData =
Data;
1871 if (
Name ==
"debug_ranges") {
1873 RangesDWOSection.Data =
Data;
1874 }
else if (
Name ==
"debug_frame" ||
Name ==
"eh_frame") {
1878 }
else if (InfoSectionMap *Sections =
1880 .Case(
"debug_info", &InfoSections)
1881 .Case(
"debug_info.dwo", &InfoDWOSections)
1882 .Case(
"debug_types", &TypesSections)
1883 .Case(
"debug_types.dwo", &TypesDWOSections)
1887 DWARFSectionMap &S = (*Sections)[
Section];
1896 (RelocAction == DWARFContext::ProcessDebugRelocations::Ignore))
1900 if (
auto NameOrErr = RelocatedSection->getName())
1901 RelSecName = *NameOrErr;
1909 if (L &&
L->getLoadedSectionContents(*RelocatedSection, RelSecData))
1917 if (!L && isa<MachOObjectFile>(&Obj))
1920 RelSecName = RelSecName.
substr(
1925 DWARFSectionMap *Sec = mapNameToDWARFSection(RelSecName);
1930 if (RelSecName ==
"debug_info")
1931 Map = &
static_cast<DWARFSectionMap &
>(InfoSections[*RelocatedSection])
1933 else if (RelSecName ==
"debug_types")
1935 &
static_cast<DWARFSectionMap &
>(TypesSections[*RelocatedSection])
1945 std::map<SymbolRef, SymInfo> AddrCache;
1957 if (!SymInfoOrErr) {
1966 if (Supports && Supports(Reloc.getType())) {
1967 auto I =
Map->try_emplace(
1970 SymInfoOrErr->SectionIndex, Reloc, SymInfoOrErr->Address,
1971 std::optional<object::RelocationRef>(), 0, Resolver});
1979 "At most two relocations per offset are supported"));
1981 entry.Reloc2 = Reloc;
1982 entry.SymbolValue2 = SymInfoOrErr->Address;
1986 Reloc.getTypeName(
Type);
1996 if (SectionAmountMap[S.Name] > 1)
1997 S.IsNameUnique =
false;
2002 auto &Sec =
static_cast<const DWARFSectionMap &
>(S);
2004 if (AI == Sec.Relocs.end())
2005 return std::nullopt;
2012 return SectionNames;
2015 bool isLittleEndian()
const override {
return IsLittleEndian; }
2016 StringRef getAbbrevDWOSection()
const override {
return AbbrevDWOSection; }
2017 const DWARFSection &getLineDWOSection()
const override {
2018 return LineDWOSection;
2020 const DWARFSection &getLocDWOSection()
const override {
2021 return LocDWOSection;
2023 StringRef getStrDWOSection()
const override {
return StrDWOSection; }
2024 const DWARFSection &getStrOffsetsDWOSection()
const override {
2025 return StrOffsetsDWOSection;
2027 const DWARFSection &getRangesDWOSection()
const override {
2028 return RangesDWOSection;
2030 const DWARFSection &getRnglistsDWOSection()
const override {
2031 return RnglistsDWOSection;
2033 const DWARFSection &getLoclistsDWOSection()
const override {
2034 return LoclistsDWOSection;
2036 const DWARFSection &getAddrSection()
const override {
return AddrSection; }
2037 StringRef getCUIndexSection()
const override {
return CUIndexSection; }
2038 StringRef getGdbIndexSection()
const override {
return GdbIndexSection; }
2039 StringRef getTUIndexSection()
const override {
return TUIndexSection; }
2042 const DWARFSection &getStrOffsetsSection()
const override {
2043 return StrOffsetsSection;
2045 StringRef getLineStrSection()
const override {
return LineStrSection; }
2048 void forEachInfoDWOSections(
2050 for (
auto &
P : InfoDWOSections)
2053 void forEachTypesDWOSections(
2055 for (
auto &
P : TypesDWOSections)
2059 StringRef getAbbrevSection()
const override {
return AbbrevSection; }
2060 const DWARFSection &getLocSection()
const override {
return LocSection; }
2061 const DWARFSection &getLoclistsSection()
const override {
return LoclistsSection; }
2062 StringRef getArangesSection()
const override {
return ArangesSection; }
2064 return FrameSection;
2066 const DWARFSection &getEHFrameSection()
const override {
2067 return EHFrameSection;
2069 const DWARFSection &getLineSection()
const override {
return LineSection; }
2070 StringRef getStrSection()
const override {
return StrSection; }
2071 const DWARFSection &getRangesSection()
const override {
return RangesSection; }
2072 const DWARFSection &getRnglistsSection()
const override {
2073 return RnglistsSection;
2075 const DWARFSection &getMacroSection()
const override {
return MacroSection; }
2076 StringRef getMacroDWOSection()
const override {
return MacroDWOSection; }
2077 StringRef getMacinfoSection()
const override {
return MacinfoSection; }
2078 StringRef getMacinfoDWOSection()
const override {
return MacinfoDWOSection; }
2079 const DWARFSection &getPubnamesSection()
const override {
return PubnamesSection; }
2080 const DWARFSection &getPubtypesSection()
const override {
return PubtypesSection; }
2081 const DWARFSection &getGnuPubnamesSection()
const override {
2082 return GnuPubnamesSection;
2084 const DWARFSection &getGnuPubtypesSection()
const override {
2085 return GnuPubtypesSection;
2087 const DWARFSection &getAppleNamesSection()
const override {
2088 return AppleNamesSection;
2090 const DWARFSection &getAppleTypesSection()
const override {
2091 return AppleTypesSection;
2093 const DWARFSection &getAppleNamespacesSection()
const override {
2094 return AppleNamespacesSection;
2096 const DWARFSection &getAppleObjCSection()
const override {
2097 return AppleObjCSection;
2100 return NamesSection;
2104 uint8_t getAddressSize()
const override {
return AddressSize; }
2105 void forEachInfoSections(
2107 for (
auto &
P : InfoSections)
2110 void forEachTypesSections(
2112 for (
auto &
P : TypesSections)
2118std::unique_ptr<DWARFContext>
2122 std::function<
void(
Error)> RecoverableErrorHandler,
2123 std::function<
void(
Error)> WarningHandler) {
2124 auto DObj = std::make_unique<DWARFObjInMemory>(
2125 Obj, L, RecoverableErrorHandler, WarningHandler, RelocAction);
2126 return std::make_unique<DWARFContext>(std::move(DObj), std::move(DWPName),
2127 RecoverableErrorHandler,
2131std::unique_ptr<DWARFContext>
2133 uint8_t AddrSize,
bool isLittleEndian,
2134 std::function<
void(
Error)> RecoverableErrorHandler,
2135 std::function<
void(
Error)> WarningHandler) {
2137 std::make_unique<DWARFObjInMemory>(Sections, AddrSize,
isLittleEndian);
2138 return std::make_unique<DWARFContext>(
2139 std::move(DObj),
"", RecoverableErrorHandler, WarningHandler);
2149 return CUs.empty() ? 0 : (*CUs.begin())->getAddressByteSize();
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static Expected< StringRef > getFileName(const DebugStringTableSubsectionRef &Strings, const DebugChecksumsSubsectionRef &Checksums, uint32_t FileID)
static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts, DWARFDataExtractor Data, const DWARFObject &Obj, std::optional< uint64_t > DumpOffset)
void fixupIndexV4(const DWARFObject &DObj, DWARFContext &C, DWARFUnitIndex &Index)
static void dumpRnglistsSection(raw_ostream &OS, DWARFDataExtractor &rnglistData, llvm::function_ref< std::optional< object::SectionedAddress >(uint32_t)> LookupPooledAddress, DIDumpOptions DumpOpts)
static void dumpUUID(raw_ostream &OS, const ObjectFile &Obj)
Dump the UUID load command.
void fixupIndexV5(const DWARFObject &DObj, DWARFContext &C, DWARFUnitIndex &Index)
void fixupIndex(const DWARFObject &DObj, DWARFContext &C, DWARFUnitIndex &Index)
static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit *CU, uint64_t Address, FunctionNameKind Kind, DILineInfoSpecifier::FileLineInfoKind FileNameKind, std::string &FunctionName, std::string &StartFile, uint32_t &StartLine, std::optional< uint64_t > &StartAddress)
TODO: change input parameter from "uint64_t Address" into "SectionedAddress Address".
static void dumpPubTableSection(raw_ostream &OS, DIDumpOptions DumpOpts, DWARFDataExtractor Data, bool GnuStyle)
static Expected< SymInfo > getSymbolInfo(const object::ObjectFile &Obj, const RelocationRef &Reloc, const LoadedObjectInfo *L, std::map< SymbolRef, SymInfo > &Cache)
Returns the address of symbol relocation used against and a section index.
static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData, DIDumpOptions DumpOpts, uint16_t Version, uint8_t AddrSize)
static T & getAccelTable(std::unique_ptr< T > &Cache, const DWARFObject &Obj, const DWARFSection &Section, StringRef StringSection, bool IsLittleEndian)
std::vector< std::optional< StrOffsetsContributionDescriptor > > ContributionCollection
static ContributionCollection collectContributionData(DWARFContext::unit_iterator_range Units)
static bool isRelocScattered(const object::ObjectFile &Obj, const RelocationRef &Reloc)
static std::optional< int64_t > getExpressionFrameOffset(ArrayRef< uint8_t > Expr, std::optional< unsigned > FrameBaseReg)
static void dumpStringOffsetsSection(raw_ostream &OS, DIDumpOptions DumpOpts, StringRef SectionName, const DWARFObject &Obj, const DWARFSection &StringOffsetsSection, StringRef StringSection, DWARFContext::unit_iterator_range Units, bool LittleEndian)
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
This file contains constants used for implementing Dwarf debug support.
This file implements a map that provides insertion order iteration.
print Instructions which execute on loop entry
This file defines the SmallString class.
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
std::pair< llvm::MachO::Target, std::string > UUID
This implements the Apple accelerator table format, a precursor of the DWARF 5 accelerator table form...
void dump(raw_ostream &OS) const override
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
A structured debug information entry.
dwarf::Tag getTag() const
A format-neutral container for inlined code description.
void addFrame(const DILineInfo &Frame)
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
DWARFCompileUnit * getCompileUnitForCodeAddress(uint64_t Address)
Return the compile unit which contains instruction with provided address.
uint8_t getCUAddrSize()
Get address size from CUs.
DIInliningInfo getInliningInfoForAddress(object::SectionedAddress Address, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
Expected< const DWARFDebugFrame * > getDebugFrame()
Get a pointer to the parsed frame information object.
Triple::ArchType getArch() const
DWARFGdbIndex & getGdbIndex()
unsigned getNumCompileUnits()
Get the number of compile units in this context.
DWARFDie getDIEForOffset(uint64_t Offset)
Get a DIE given an exact offset.
unsigned getNumTypeUnits()
Get the number of type units in this context.
DIEsForAddress getDIEsForAddress(uint64_t Address)
Get the compilation unit, the function DIE and lexical block DIE for the given address where applicab...
DILineInfo getLineInfoForAddress(object::SectionedAddress Address, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
const DWARFDebugAbbrev * getDebugAbbrevDWO()
Get a pointer to the parsed dwo abbreviations object.
compile_unit_range compile_units()
Get compile units in this context.
const AppleAcceleratorTable & getAppleObjC()
Get a reference to the parsed accelerator table object.
const DWARFUnitIndex & getTUIndex()
DWARFContext(std::unique_ptr< const DWARFObject > DObj, std::string DWPName="", std::function< void(Error)> RecoverableErrorHandler=WithColor::defaultErrorHandler, std::function< void(Error)> WarningHandler=WithColor::defaultWarningHandler)
DWARFCompileUnit * getCompileUnitForDataAddress(uint64_t Address)
Return the compile unit which contains data with the provided address.
const DWARFDebugAbbrev * getDebugAbbrev()
Get a pointer to the parsed DebugAbbrev object.
std::vector< DILocal > getLocalsForAddress(object::SectionedAddress Address) override
DataExtractor getStringExtractor() const
static std::unique_ptr< DWARFContext > create(const object::ObjectFile &Obj, ProcessDebugRelocations RelocAction=ProcessDebugRelocations::Process, const LoadedObjectInfo *L=nullptr, std::string DWPName="", std::function< void(Error)> RecoverableErrorHandler=WithColor::defaultErrorHandler, std::function< void(Error)> WarningHandler=WithColor::defaultWarningHandler)
DWARFCompileUnit * getCompileUnitForOffset(uint64_t Offset)
Return the compile unit that includes an offset (relative to .debug_info).
const DWARFDebugNames & getDebugNames()
Get a reference to the parsed accelerator table object.
unsigned getNumDWOTypeUnits()
Get the number of type units in the DWO context.
const DWARFDebugMacro * getDebugMacroDWO()
Get a pointer to the parsed DebugMacroDWO information object.
DILineInfoTable getLineInfoForAddressRange(object::SectionedAddress Address, uint64_t Size, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
bool isLittleEndian() const
DWARFUnit * getUnitAtIndex(unsigned index)
Get the unit at the specified index.
const DWARFDebugLine::LineTable * getLineTableForUnit(DWARFUnit *U)
Get a pointer to a parsed line table corresponding to a compile unit.
void clearLineTableForUnit(DWARFUnit *U)
const AppleAcceleratorTable & getAppleTypes()
Get a reference to the parsed accelerator table object.
const AppleAcceleratorTable & getAppleNames()
Get a reference to the parsed accelerator table object.
compile_unit_range dwo_compile_units()
Get compile units in the DWO context.
const DWARFDebugLoc * getDebugLoc()
Get a pointer to the parsed DebugLoc object.
const DWARFDebugMacro * getDebugMacinfoDWO()
Get a pointer to the parsed DebugMacinfoDWO information object.
bool verify(raw_ostream &OS, DIDumpOptions DumpOpts={}) override
unit_iterator_range dwo_types_section_units()
Get units from .debug_types.dwo in the DWO context.
void dump(raw_ostream &OS, DIDumpOptions DumpOpts, std::array< std::optional< uint64_t >, DIDT_ID_Count > DumpOffsets)
Dump a textual representation to OS.
unit_iterator_range normal_units()
Get all normal compile/type units in this context.
unit_iterator_range types_section_units()
Get units from .debug_types in this context.
std::shared_ptr< DWARFContext > getDWOContext(StringRef AbsolutePath)
DWARFCompileUnit * getDWOCompileUnitForHash(uint64_t Hash)
unsigned getNumDWOCompileUnits()
Get the number of compile units in the DWO context.
DILineInfo getLineInfoForDataAddress(object::SectionedAddress Address) override
const DWARFDebugAranges * getDebugAranges()
Get a pointer to the parsed DebugAranges object.
const DWARFUnitIndex & getCUIndex()
Expected< const DWARFDebugFrame * > getEHFrame()
Get a pointer to the parsed eh frame information object.
unit_iterator_range info_section_units()
Get units from .debug_info in this context.
DWARFTypeUnit * getTypeUnitForHash(uint16_t Version, uint64_t Hash, bool IsDWO)
unit_iterator_range dwo_info_section_units()
Get units from .debug_info..dwo in the DWO context.
DataExtractor getStringDWOExtractor() const
const AppleAcceleratorTable & getAppleNamespaces()
Get a reference to the parsed accelerator table object.
const DWARFDebugMacro * getDebugMacro()
Get a pointer to the parsed DebugMacro information object.
const DWARFDebugMacro * getDebugMacinfo()
Get a pointer to the parsed DebugMacinfo information object.
unit_iterator_range dwo_units()
Get all units in the DWO context.
void dump(raw_ostream &OS) const
A class representing an address table as specified in DWARF v5.
void dump(raw_ostream &OS, DIDumpOptions DumpOpts={}) const
Error extract(const DWARFDataExtractor &Data, uint64_t *OffsetPtr, uint16_t CUVersion, uint8_t CUAddrSize, std::function< void(Error)> WarnCallback)
Extract the entire table, including all addresses.
std::optional< uint64_t > getFullLength() const
Return the full length of this table, including the length field.
Error extract(DWARFDataExtractor data, uint64_t *offset_ptr, function_ref< void(Error)> WarningHandler)
void dump(raw_ostream &OS) const
uint64_t findAddress(uint64_t Address) const
Helper to allow for parsing of an entire .debug_line section in sequence.
void dump(raw_ostream &OS, const DWARFObject &Obj, DIDumpOptions DumpOpts, std::optional< uint64_t > Offset) const
Print the location lists found within the debug_loc section.
void dumpRange(uint64_t StartOffset, uint64_t Size, raw_ostream &OS, const DWARFObject &Obj, DIDumpOptions DumpOpts)
Dump all location lists within the given range.
.debug_names section consists of one or more units.
void dump(raw_ostream &OS) const override
Represents structure for holding and parsing .debug_pub* tables.
void extract(DWARFDataExtractor Data, bool GnuStyle, function_ref< void(Error)> RecoverableErrorHandler)
void dump(raw_ostream &OS) const
Error extract(const DWARFDataExtractor &data, uint64_t *offset_ptr)
void dump(raw_ostream &OS) const
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
DWARFDie getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE as the referenced DIE.
std::optional< DWARFFormValue > find(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE.
const char * getSubroutineName(DINameKind Kind) const
If a DIE represents a subprogram (or inlined subroutine), returns its mangled name (or short name,...
void getCallerFrame(uint32_t &CallFile, uint32_t &CallLine, uint32_t &CallColumn, uint32_t &CallDiscriminator) const
Retrieves values of DW_AT_call_file, DW_AT_call_line and DW_AT_call_column from DIE (or zeroes if the...
std::string getDeclFile(DILineInfoSpecifier::FileLineInfoKind Kind) const
uint64_t getDeclLine() const
Returns the declaration line (start line) for a DIE, assuming it specifies a subprogram.
dwarf::Tag getTag() const
Expected< DWARFLocationExpressionsVector > getLocations(dwarf::Attribute Attr) const
void dump(raw_ostream &OS)
Error extract(DWARFDataExtractor Data, uint64_t *OffsetPtr)
Extract an entire table, including all list entries.
void dump(DWARFDataExtractor Data, raw_ostream &OS, llvm::function_ref< std::optional< object::SectionedAddress >(uint32_t)> LookupPooledAddress, DIDumpOptions DumpOpts={}) const
bool dumpLocationList(uint64_t *Offset, raw_ostream &OS, std::optional< object::SectionedAddress > BaseAddr, const DWARFObject &Obj, DWARFUnit *U, DIDumpOptions DumpOpts, unsigned Indent) const
Dump the location list at the given Offset.
virtual void forEachInfoDWOSections(function_ref< void(const DWARFSection &)> F) const
virtual StringRef getCUIndexSection() const
void setOffset(uint64_t Value)
uint64_t getOffset() const
void dump(raw_ostream &OS) const
Describe a collection of units.
void finishedInfoUnits()
Indicate that parsing .debug_info[.dwo] is done, and remaining units will be from ....
void addUnitsForSection(DWARFContext &C, const DWARFSection &Section, DWARFSectionKind SectionKind)
Read units from a .debug_info or .debug_types section.
DWARFUnit * getUnitForOffset(uint64_t Offset) const
void addUnitsForDWOSection(DWARFContext &C, const DWARFSection &DWOSection, DWARFSectionKind SectionKind, bool Lazy=false)
Read units from a .debug_info.dwo or .debug_types.dwo section.
DWARFUnit * getUnitForIndexEntry(const DWARFUnitIndex::Entry &E)
A class that verifies DWARF debug information given a DWARF Context.
bool handleAccelTables()
Verify the information in accelerator tables, if they exist.
bool handleDebugTUIndex()
Verify the information in the .debug_tu_index section.
bool handleDebugCUIndex()
Verify the information in the .debug_cu_index section.
bool handleDebugInfo()
Verify the information in the .debug_info and .debug_types sections.
bool handleDebugLine()
Verify the information in the .debug_line section.
bool handleDebugAbbrev()
Verify the information in any of the following sections, if available: .debug_abbrev,...
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
reference get()
Returns a reference to the stored T value.
An inferface for inquiring the load address of a loaded object file to be used by the DIContext imple...
This class implements a map that also provides access to all stored values in a deterministic order.
Interface for looking up the initializer for a variable name, used by Init::resolveReferences.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
StringRef - Represent a constant reference to a string, i.e.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
constexpr bool empty() const
empty - Check if the string is empty.
constexpr size_t size() const
size - Get the string size.
size_t find_first_not_of(char C, size_t From=0) const
Find the first character in the string that is not C or npos if not found.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Triple - Helper class for working with autoconf configuration names.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static Twine utohexstr(const uint64_t &Val)
The instances of the Type class are immutable: once they are created, they are never changed.
An efficient, type-erasing, non-owning reference to a callable.
A range adaptor for a pair of iterators.
Decompressor helps to handle decompression of compressed sections.
Error resizeAndDecompress(T &Out)
Resize the buffer and uncompress section data into it.
static Expected< Decompressor > create(StringRef Name, StringRef Data, bool IsLE, bool Is64Bit)
Create decompressor object.
MachO::any_relocation_info getRelocation(DataRefImpl Rel) const
bool isRelocationScattered(const MachO::any_relocation_info &RE) const
This class is the base class for all object file types.
virtual section_iterator section_end() const =0
section_iterator_range sections() const
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
virtual StringRef mapDebugSectionName(StringRef Name) const
Maps a debug section name to a standard DWARF section name.
virtual bool isRelocatableObject() const =0
True if this is a relocatable object (.o/.obj).
This is a value type class that represents a single relocation in the list of relocations in the obje...
symbol_iterator getSymbol() const
DataRefImpl getRawDataRefImpl() const
This is a value type class that represents a single section in the list of sections in the object fil...
bool isCompressed() const
virtual basic_symbol_iterator symbol_end() const =0
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream & write_uuid(const uuid_t UUID)
raw_ostream & write_escaped(StringRef Str, bool UseHexEscapes=false)
Output Str, turning '\', '\t', ' ', '"', and anything that doesn't satisfy llvm::isPrint into an esca...
uint8_t[16] uuid_t
Output a formatted UUID with dash separators.
StringRef FormatString(DwarfFormat Format)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
std::optional< object::SectionedAddress > toSectionedAddress(const std::optional< DWARFFormValue > &V)
DwarfFormat
Constants that define the DWARF format as 32 or 64 bit.
std::optional< uint64_t > toSectionOffset(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an section offset.
uint8_t getDwarfOffsetByteSize(DwarfFormat Format)
The size of a reference determined by the DWARF 32/64-bit format.
std::optional< uint64_t > toUnsigned(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an unsigned constant.
uint64_t(*)(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t Addend) RelocationResolver
Error createError(const Twine &Err)
bool(*)(uint64_t) SupportsRelocation
std::pair< SupportsRelocation, RelocationResolver > getRelocationResolver(const ObjectFile &Obj)
StringRef extension(StringRef path, Style style=Style::native)
Get extension.
This is an optimization pass for GlobalISel generic memory operations.
void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
void append_range(Container &C, Range &&R)
Wrapper function to append a range to a container.
int64_t decodeSLEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a SLEB128 value.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
void sort(IteratorTy Start, IteratorTy End)
static Error createError(const Twine &Err)
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
DINameKind
A DINameKind is passed to name search methods to specify a preference regarding the type of name reso...
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
void consumeError(Error Err)
Consume a Error without doing anything.
SymInfo contains information about symbol: it's address and section index which is -1LL for absolute ...
Container for dump options that control which debug information will be dumped.
std::function< void(Error)> WarningHandler
std::function< void(Error)> RecoverableErrorHandler
DIDumpOptions noImplicitRecursion() const
Return the options with RecurseDepth set to 0 unless explicitly required.
Controls which fields of DILineInfo container should be filled with data.
DINameKind FunctionNameKind
A format-neutral container for source line information.
static constexpr const char *const BadString
std::optional< uint64_t > StartAddress
std::string StartFileName
Wraps the returned DIEs for a given address.
bool getFileLineInfoForAddress(object::SectionedAddress Address, const char *CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, DILineInfo &Result) const
Fills the Result argument with the file and line information corresponding to Address.
bool getFileNameByIndex(uint64_t FileIndex, StringRef CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, std::string &Result) const
Extracts filename by its index in filename table in prologue.
bool lookupAddressRange(object::SectionedAddress Address, uint64_t Size, std::vector< uint32_t > &Result) const
Standard .debug_line state machine structure.
RelocAddrEntry contains relocated value and section index.