64using namespace object;
66#define DEBUG_TYPE "dwarf"
74 std::function<
void(
Error)> RecoverableErrorHandler,
75 std::function<
void(
Error)> WarningHandler)
77 RecoverableErrorHandler(RecoverableErrorHandler),
78 WarningHandler(WarningHandler), DObj(
std::
move(DObj)) {}
84 auto *MachO = dyn_cast<MachOObjectFile>(&Obj);
87 for (
auto LC : MachO->load_commands()) {
89 if (LC.C.cmd == MachO::LC_UUID) {
90 if (LC.C.cmdsize <
sizeof(
UUID) +
sizeof(LC.C)) {
91 OS <<
"error: UUID load command is too short.\n";
95 memcpy(&
UUID, LC.Ptr+
sizeof(LC.C),
sizeof(
UUID));
97 Triple T = MachO->getArchTriple();
98 OS <<
" (" <<
T.getArchName() <<
')';
99 OS <<
' ' << MachO->getFileName() <<
'\n';
105 std::vector<std::optional<StrOffsetsContributionDescriptor>>;
112 for (
const auto &U : Units)
113 if (
const auto &
C = U->getStringOffsetsTableContribution())
114 Contributions.push_back(
C);
119 [](
const std::optional<StrOffsetsContributionDescriptor> &L,
120 const std::optional<StrOffsetsContributionDescriptor> &R) {
122 return L->Base < R->Base;
123 return R.has_value();
130 std::unique(Contributions.begin(), Contributions.end(),
131 [](
const std::optional<StrOffsetsContributionDescriptor> &L,
132 const std::optional<StrOffsetsContributionDescriptor> &R) {
134 return L->Base == R->Base && L->Size == R->Size;
137 Contributions.end());
138 return Contributions;
161 for (
auto &Contribution : Contributions) {
164 OS <<
"error: invalid contribution to string offsets table in section ."
171 uint16_t Version = Contribution->getVersion();
172 uint64_t ContributionHeader = Contribution->Base;
181 if (
Offset > ContributionHeader) {
184 "overlapping contributions to string offsets table in section .%s.",
188 if (
Offset < ContributionHeader) {
190 OS << (ContributionHeader -
Offset) <<
"\n";
192 OS <<
format(
"0x%8.8" PRIx64
": ", ContributionHeader);
197 OS <<
"Contribution size = " << (Contribution->Size + (Version < 5 ? 0 : 4))
199 <<
", Version = " << Version <<
"\n";
201 Offset = Contribution->Base;
202 unsigned EntrySize = Contribution->getDwarfOffsetByteSize();
203 while (
Offset - Contribution->Base < Contribution->Size) {
207 OS <<
format(
"%0*" PRIx64
" ", OffsetDumpWidth, StringOffset);
208 const char *S = StrData.
getCStr(&StringOffset);
215 if (
Offset < SectionSize) {
217 OS << (SectionSize -
Offset) <<
"\n";
235 Offset = TableOffset + *TableLength;
240 AddrTable.
dump(
OS, DumpOpts);
263 Rnglists.
dump(rnglistData,
OS, LookupPooledAddress, DumpOpts);
268std::unique_ptr<DWARFDebugMacro>
269DWARFContext::parseMacroOrMacinfo(MacroSecType SectionType) {
270 auto Macro = std::make_unique<DWARFDebugMacro>();
272 if (
Error Err = IsMacro ? Macro->parseMacro(SectionType == MacroSection
275 SectionType == MacroSection
279 : Macro->parseMacinfo(
Data)) {
280 RecoverableErrorHandler(std::move(Err));
284 switch (SectionType) {
285 case MacinfoSection: {
287 ParseAndDump(
Data,
false);
290 case MacinfoDwoSection: {
292 ParseAndDump(
Data,
false);
298 ParseAndDump(
Data,
true);
301 case MacroDwoSection: {
303 ParseAndDump(
Data,
true);
312 std::optional<uint64_t> DumpOffset) {
322 Header.dump(
Data,
OS, DumpOpts);
324 uint64_t EndOffset = Header.length() + Header.getHeaderOffset();
325 Data.setAddressSize(Header.getAddrSize());
328 if (DumpOffset >=
Offset && DumpOffset < EndOffset) {
331 nullptr, DumpOpts, 0);
351 std::array<std::optional<uint64_t>,
DIDT_ID_Count> DumpOffsets) {
355 bool IsDWO = (Extension ==
".dwo") || (Extension ==
".dwp");
358 const auto *ObjFile = DObj->getFile();
365 bool Explicit = DumpType !=
DIDT_All && !IsDWO;
366 bool ExplicitDWO = Explicit && IsDWO;
367 auto shouldDump = [&](
bool Explicit,
const char *
Name,
unsigned ID,
368 StringRef Section) -> std::optional<uint64_t> * {
369 unsigned Mask = 1U <<
ID;
370 bool Should = (DumpType & Mask) && (Explicit || !Section.empty());
373 OS <<
"\n" <<
Name <<
" contents:\n";
374 return &DumpOffsets[
ID];
378 if (shouldDump(Explicit,
".debug_abbrev", DIDT_ID_DebugAbbrev,
379 DObj->getAbbrevSection()))
381 if (shouldDump(ExplicitDWO,
".debug_abbrev.dwo", DIDT_ID_DebugAbbrev,
382 DObj->getAbbrevDWOSection()))
386 OS <<
'\n' <<
Name <<
" contents:\n";
387 if (
auto DumpOffset = DumpOffsets[DIDT_ID_DebugInfo])
388 for (
const auto &U : Units)
389 U->getDIEForOffset(*DumpOffset)
392 for (
const auto &U : Units)
393 U->dump(
OS, DumpOpts);
395 if ((DumpType & DIDT_DebugInfo)) {
403 OS <<
'\n' <<
Name <<
" contents:\n";
404 for (
const auto &U : Units)
405 if (
auto DumpOffset = DumpOffsets[DIDT_ID_DebugTypes])
406 U->getDIEForOffset(*DumpOffset)
409 U->dump(
OS, DumpOpts);
411 if ((DumpType & DIDT_DebugTypes)) {
422 if (
const auto *Off = shouldDump(Explicit,
".debug_loc", DIDT_ID_DebugLoc,
423 DObj->getLocSection().Data)) {
426 if (
const auto *Off =
427 shouldDump(Explicit,
".debug_loclists", DIDT_ID_DebugLoclists,
428 DObj->getLoclistsSection().Data)) {
433 if (
const auto *Off =
434 shouldDump(ExplicitDWO,
".debug_loclists.dwo", DIDT_ID_DebugLoclists,
435 DObj->getLoclistsDWOSection().Data)) {
441 if (
const auto *Off =
442 shouldDump(ExplicitDWO,
".debug_loc.dwo", DIDT_ID_DebugLoc,
443 DObj->getLocDWOSection().Data)) {
450 std::nullopt, *DObj,
nullptr,
459 if (
const std::optional<uint64_t> *Off =
460 shouldDump(Explicit,
".debug_frame", DIDT_ID_DebugFrame,
461 DObj->getFrameSection().Data)) {
463 (*DF)->dump(
OS, DumpOpts, *Off);
465 RecoverableErrorHandler(
DF.takeError());
468 if (
const std::optional<uint64_t> *Off =
469 shouldDump(Explicit,
".eh_frame", DIDT_ID_DebugFrame,
470 DObj->getEHFrameSection().Data)) {
472 (*DF)->dump(
OS, DumpOpts, *Off);
474 RecoverableErrorHandler(
DF.takeError());
477 if (shouldDump(Explicit,
".debug_macro", DIDT_ID_DebugMacro,
478 DObj->getMacroSection().Data)) {
483 if (shouldDump(Explicit,
".debug_macro.dwo", DIDT_ID_DebugMacro,
484 DObj->getMacroDWOSection())) {
489 if (shouldDump(Explicit,
".debug_macinfo", DIDT_ID_DebugMacro,
490 DObj->getMacinfoSection())) {
495 if (shouldDump(Explicit,
".debug_macinfo.dwo", DIDT_ID_DebugMacro,
496 DObj->getMacinfoDWOSection())) {
498 MacinfoDWO->dump(
OS);
501 if (shouldDump(Explicit,
".debug_aranges", DIDT_ID_DebugAranges,
502 DObj->getArangesSection())) {
510 RecoverableErrorHandler(std::move(
E));
519 std::optional<uint64_t> DumpOffset) {
521 if (DumpOffset &&
Parser.getOffset() != *DumpOffset) {
525 OS <<
"debug_line[" <<
format(
"0x%8.8" PRIx64,
Parser.getOffset())
532 auto DumpStrSection = [&](
StringRef Section) {
543 OS <<
format(
"0x%8.8" PRIx64
": \"", StrOffset);
550 if (
const auto *Off = shouldDump(Explicit,
".debug_line", DIDT_ID_DebugLine,
551 DObj->getLineSection().Data)) {
555 DumpLineSection(
Parser, DumpOpts, *Off);
558 if (
const auto *Off =
559 shouldDump(ExplicitDWO,
".debug_line.dwo", DIDT_ID_DebugLine,
560 DObj->getLineDWOSection().Data)) {
564 DumpLineSection(
Parser, DumpOpts, *Off);
567 if (shouldDump(Explicit,
".debug_cu_index", DIDT_ID_DebugCUIndex,
568 DObj->getCUIndexSection())) {
572 if (shouldDump(Explicit,
".debug_tu_index", DIDT_ID_DebugTUIndex,
573 DObj->getTUIndexSection())) {
577 if (shouldDump(Explicit,
".debug_str", DIDT_ID_DebugStr,
578 DObj->getStrSection()))
579 DumpStrSection(DObj->getStrSection());
581 if (shouldDump(ExplicitDWO,
".debug_str.dwo", DIDT_ID_DebugStr,
582 DObj->getStrDWOSection()))
583 DumpStrSection(DObj->getStrDWOSection());
585 if (shouldDump(Explicit,
".debug_line_str", DIDT_ID_DebugLineStr,
586 DObj->getLineStrSection()))
587 DumpStrSection(DObj->getLineStrSection());
589 if (shouldDump(Explicit,
".debug_addr", DIDT_ID_DebugAddr,
590 DObj->getAddrSection().Data)) {
596 if (shouldDump(Explicit,
".debug_ranges", DIDT_ID_DebugRanges,
597 DObj->getRangesSection().Data)) {
612 auto LookupPooledAddress =
615 auto I = CUs.begin();
618 return (*I)->getAddrOffsetSectionItem(
Index);
621 if (shouldDump(Explicit,
".debug_rnglists", DIDT_ID_DebugRnglists,
622 DObj->getRnglistsSection().Data)) {
628 if (shouldDump(ExplicitDWO,
".debug_rnglists.dwo", DIDT_ID_DebugRnglists,
629 DObj->getRnglistsDWOSection().Data)) {
635 if (shouldDump(Explicit,
".debug_pubnames", DIDT_ID_DebugPubnames,
636 DObj->getPubnamesSection().Data)) {
642 if (shouldDump(Explicit,
".debug_pubtypes", DIDT_ID_DebugPubtypes,
643 DObj->getPubtypesSection().Data)) {
649 if (shouldDump(Explicit,
".debug_gnu_pubnames", DIDT_ID_DebugGnuPubnames,
650 DObj->getGnuPubnamesSection().Data)) {
656 if (shouldDump(Explicit,
".debug_gnu_pubtypes", DIDT_ID_DebugGnuPubtypes,
657 DObj->getGnuPubtypesSection().Data)) {
663 if (shouldDump(Explicit,
".debug_str_offsets", DIDT_ID_DebugStrOffsets,
664 DObj->getStrOffsetsSection().Data))
666 OS, DumpOpts,
"debug_str_offsets", *DObj, DObj->getStrOffsetsSection(),
668 if (shouldDump(ExplicitDWO,
".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets,
669 DObj->getStrOffsetsDWOSection().Data))
671 DObj->getStrOffsetsDWOSection(),
675 if (shouldDump(Explicit,
".gdb_index", DIDT_ID_GdbIndex,
676 DObj->getGdbIndexSection())) {
680 if (shouldDump(Explicit,
".apple_names", DIDT_ID_AppleNames,
681 DObj->getAppleNamesSection().Data))
684 if (shouldDump(Explicit,
".apple_types", DIDT_ID_AppleTypes,
685 DObj->getAppleTypesSection().Data))
688 if (shouldDump(Explicit,
".apple_namespaces", DIDT_ID_AppleNamespaces,
689 DObj->getAppleNamespacesSection().Data))
692 if (shouldDump(Explicit,
".apple_objc", DIDT_ID_AppleObjC,
693 DObj->getAppleObjCSection().Data))
695 if (shouldDump(Explicit,
".debug_names", DIDT_ID_DebugNames,
696 DObj->getNamesSection().Data))
702 parseDWOUnits(LazyParse);
705 if (
const auto *R = TUI.getFromHash(Hash))
706 return dyn_cast_or_null<DWARFTypeUnit>(
711 struct UnitContainers {
713 std::optional<DenseMap<uint64_t, DWARFTypeUnit *>> ⤅
715 UnitContainers Units = IsDWO ? UnitContainers{DWOUnits, DWOTypeUnits}
716 : UnitContainers{NormalUnits, NormalTypeUnits};
721 (*Units.Map)[TU->getTypeHash()] = TU;
725 return (*Units.Map)[Hash];
729 parseDWOUnits(LazyParse);
732 if (
const auto *R = CUI.getFromHash(Hash))
733 return dyn_cast_or_null<DWARFCompileUnit>(
744 if (!DWOCU->getDWOId()) {
745 if (std::optional<uint64_t> DWOId =
746 toUnsigned(DWOCU->getUnitDIE().find(DW_AT_GNU_dwo_id)))
747 DWOCU->setDWOId(*DWOId);
752 if (DWOCU->getDWOId() == Hash)
753 return dyn_cast<DWARFCompileUnit>(DWOCU.get());
770 if (DumpOpts.
DumpType & DIDT_DebugCUIndex)
772 if (DumpOpts.
DumpType & DIDT_DebugTUIndex)
774 if (DumpOpts.
DumpType & DIDT_DebugInfo)
776 if (DumpOpts.
DumpType & DIDT_DebugLine)
793 if (!(
C.getParseCUTUIndexManually() ||
794 S.
Data.
size() >= std::numeric_limits<uint32_t>::max()))
799 DWARFUnitHeader Header;
800 if (!Header.extract(C, Data, &Offset, DWARFSectionKind::DW_SECT_INFO)) {
801 logAllUnhandledErrors(
802 createError(
"Failed to parse CU header in DWP file"), errs());
807 auto Iter = Map.insert({TruncOffset,
808 {Header.getOffset(), Header.getNextUnitOffset() -
809 Header.getOffset()}});
811 logAllUnhandledErrors(
812 createError(
"Collision occured between for truncated offset 0x" +
813 Twine::utohexstr(TruncOffset)),
819 Offset = Header.getNextUnitOffset();
832 if (Iter ==
Map.end()) {
839 CUOff.
setOffset(Iter->second.getOffset());
840 if (CUOff.
getOffset() != Iter->second.getOffset())
842 "match calculated length at offset 0x" +
855 CUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_INFO);
856 CUIndex->parse(CUIndexData);
867 bool isParseSuccessful = TUIndex->parse(TUIndexData);
870 if (isParseSuccessful && TUIndex->getVersion() != 2)
879 DataExtractor GdbIndexData(DObj->getGdbIndexSection(),
true , 0);
880 GdbIndex = std::make_unique<DWARFGdbIndex>();
881 GdbIndex->parse(GdbIndexData);
892 Abbrev->extract(abbrData);
898 return AbbrevDWO.get();
902 AbbrevDWO->extract(abbrData);
903 return AbbrevDWO.get();
922 return Aranges.get();
925 Aranges->generate(
this);
926 return Aranges.get();
931 return DebugFrame.get();
945 DObj->getAddressSize());
947 std::make_unique<DWARFDebugFrame>(
getArch(),
false, DS.Address);
948 if (
Error E =
DF->parse(DebugFrameData))
952 return DebugFrame.get();
957 return EHFrame.get();
961 DObj->getAddressSize());
964 std::make_unique<DWARFDebugFrame>(
getArch(),
true, DS.Address);
965 if (
Error E =
DF->parse(DebugFrameData))
968 return DebugFrame.get();
973 Macro = parseMacroOrMacinfo(MacroSection);
979 MacroDWO = parseMacroOrMacinfo(MacroDwoSection);
980 return MacroDWO.get();
985 Macinfo = parseMacroOrMacinfo(MacinfoSection);
986 return Macinfo.get();
991 MacinfoDWO = parseMacroOrMacinfo(MacinfoDwoSection);
992 return MacinfoDWO.get();
998 bool IsLittleEndian) {
1003 Cache.reset(
new T(AccelSection, StrData));
1004 if (
Error E = Cache->extract())
1015 return getAccelTable(AppleNames, *DObj, DObj->getAppleNamesSection(),
1020 return getAccelTable(AppleTypes, *DObj, DObj->getAppleTypesSection(),
1026 DObj->getAppleNamespacesSection(),
1031 return getAccelTable(AppleObjC, *DObj, DObj->getAppleObjCSection(),
1039 if (!ExpectedLineTable) {
1040 WarningHandler(ExpectedLineTable.
takeError());
1043 return *ExpectedLineTable;
1051 auto UnitDIE = U->getUnitDIE();
1065 if (stmtOffset >= U->getLineSection().Data.size())
1070 U->getAddressByteSize());
1071 return Line->getOrParseLineTable(lineData, stmtOffset, *
this, U,
1072 RecoverableErrorHandler);
1079 auto UnitDIE = U->getUnitDIE();
1088 Line->clearLineTable(stmtOffset);
1091void DWARFContext::parseNormalUnits() {
1092 if (!NormalUnits.
empty())
1098 DObj->forEachTypesSections([&](
const DWARFSection &S) {
1103void DWARFContext::parseDWOUnits(
bool Lazy) {
1104 if (!DWOUnits.
empty())
1106 DObj->forEachInfoDWOSections([&](
const DWARFSection &S) {
1110 DObj->forEachTypesDWOSections([&](
const DWARFSection &S) {
1117 return dyn_cast_or_null<DWARFCompileUnit>(
1156 Result.CompileUnit =
CU;
1157 Result.FunctionDIE =
CU->getSubroutineForAddress(
Address);
1159 std::vector<DWARFDie> Worklist;
1160 Worklist.push_back(Result.FunctionDIE);
1161 while (!Worklist.empty()) {
1163 Worklist.pop_back();
1168 if (
DIE.
getTag() == DW_TAG_lexical_block &&
1170 Result.BlockDIE =
DIE;
1185 std::string &FunctionName, std::string &StartFile,
uint32_t &StartLine,
1186 std::optional<uint64_t> &StartAddress) {
1191 CU->getInlinedChainForAddress(
Address, InlinedChain);
1192 if (InlinedChain.
empty())
1196 bool FoundResult =
false;
1197 const char *
Name =
nullptr;
1198 if (
Kind != FunctionNameKind::None && (
Name =
DIE.getSubroutineName(
Kind))) {
1199 FunctionName =
Name;
1202 std::string DeclFile =
DIE.getDeclFile(FileNameKind);
1203 if (!DeclFile.empty()) {
1204 StartFile = DeclFile;
1207 if (
auto DeclLineResult =
DIE.getDeclLine()) {
1208 StartLine = DeclLineResult;
1212 StartAddress = LowPcAddr->Address;
1216static std::optional<int64_t>
1218 std::optional<unsigned> FrameBaseReg) {
1219 if (!Expr.
empty() &&
1220 (Expr[0] == DW_OP_fbreg ||
1221 (FrameBaseReg && Expr[0] == DW_OP_breg0 + *FrameBaseReg))) {
1225 if (Expr.
size() == Count + 1)
1228 if (Expr.
size() == Count + 2 && Expr[Count + 1] == DW_OP_deref)
1232 return std::nullopt;
1236 DWARFDie Die, std::vector<DILocal> &Result) {
1237 if (Die.
getTag() == DW_TAG_variable ||
1238 Die.
getTag() == DW_TAG_formal_parameter) {
1243 std::optional<unsigned> FrameBaseReg;
1244 if (
auto FrameBase = Subprogram.
find(DW_AT_frame_base))
1246 if (!Expr->empty() && (*Expr)[0] >= DW_OP_reg0 &&
1247 (*Expr)[0] <= DW_OP_reg31) {
1248 FrameBaseReg = (*Expr)[0] - DW_OP_reg0;
1251 if (
Expected<std::vector<DWARFLocationExpression>> Loc =
1253 for (
const auto &Entry : *Loc) {
1254 if (std::optional<int64_t> FrameOffset =
1256 Local.FrameOffset = *FrameOffset;
1266 if (
auto TagOffsetAttr = Die.
find(DW_AT_LLVM_tag_offset))
1267 Local.TagOffset = TagOffsetAttr->getAsUnsignedConstant();
1272 if (
auto NameAttr = Die.
find(DW_AT_name))
1277 if (
auto DeclFileAttr = Die.
find(DW_AT_decl_file)) {
1278 if (
const auto *LT =
CU->getContext().getLineTableForUnit(
CU))
1279 LT->getFileNameByIndex(
1280 *DeclFileAttr->getAsUnsignedConstant(),
CU->getCompilationDir(),
1281 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
1284 if (
auto DeclLineAttr = Die.
find(DW_AT_decl_line))
1285 Local.DeclLine = *DeclLineAttr->getAsUnsignedConstant();
1291 if (Die.
getTag() == DW_TAG_inlined_subroutine)
1294 Subprogram = Origin;
1296 for (
auto Child : Die)
1297 addLocalsForDie(
CU, Subprogram, Child, Result);
1302 std::vector<DILocal> Result;
1309 addLocalsForDie(
CU, Subprogram, Subprogram, Result);
1322 Result.StartFileName, Result.StartLine, Result.StartAddress);
1323 if (
Spec.FLIKind != FileLineInfoKind::None) {
1325 LineTable->getFileLineInfoForAddress(
1327 Spec.FLIKind, Result);
1342 Result.FileName = Die.
getDeclFile(FileLineInfoKind::AbsoluteFilePath);
1357 std::string StartFileName;
1359 std::optional<uint64_t> StartAddress;
1361 Spec.FLIKind, FunctionName,
1362 StartFileName, StartLine, StartAddress);
1366 if (
Spec.FLIKind == FileLineInfoKind::None) {
1368 Result.FunctionName = FunctionName;
1369 Result.StartFileName = StartFileName;
1370 Result.StartLine = StartLine;
1371 Result.StartAddress = StartAddress;
1372 Lines.push_back(std::make_pair(
Address.Address, Result));
1379 std::vector<uint32_t> RowVector;
1385 for (
uint32_t RowIndex : RowVector) {
1390 Spec.FLIKind, Result.FileName);
1391 Result.FunctionName = FunctionName;
1392 Result.Line = Row.Line;
1393 Result.Column = Row.Column;
1394 Result.StartFileName = StartFileName;
1395 Result.StartLine = StartLine;
1396 Result.StartAddress = StartAddress;
1397 Lines.push_back(std::make_pair(Row.Address.Address, Result));
1410 return InliningInfo;
1414 CU->getInlinedChainForAddress(
Address.Address, InlinedChain);
1415 if (InlinedChain.
size() == 0) {
1418 if (
Spec.FLIKind != FileLineInfoKind::None) {
1422 {Address.Address, Address.SectionIndex},
1423 CU->getCompilationDir(),
Spec.FLIKind, Frame))
1426 return InliningInfo;
1429 uint32_t CallFile = 0, CallLine = 0, CallColumn = 0, CallDiscriminator = 0;
1430 for (
uint32_t i = 0, n = InlinedChain.
size(); i != n; i++) {
1431 DWARFDie &FunctionDIE = InlinedChain[i];
1436 if (
auto DeclLineResult = FunctionDIE.
getDeclLine())
1441 if (
Spec.FLIKind != FileLineInfoKind::None) {
1450 Spec.FLIKind, Frame);
1457 Frame.
Line = CallLine;
1458 Frame.
Column = CallColumn;
1469 return InliningInfo;
1472std::shared_ptr<DWARFContext>
1474 if (
auto S = DWP.lock()) {
1476 return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
1479 std::weak_ptr<DWOFile> *Entry = &DWOFiles[AbsolutePath];
1481 if (
auto S = Entry->lock()) {
1483 return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
1487 if (!CheckedForDWP) {
1490 this->DWPName.
empty()
1491 ? (DObj->getFileName() +
".dwp").toStringRef(DWPName)
1497 CheckedForDWP =
true;
1513 auto S = std::make_shared<DWOFile>();
1514 S->File = std::move(Obj.
get());
1518 auto *Ctxt = S->Context.get();
1519 return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
1523 return make_error<StringError>(Reason +
toString(std::move(
E)),
1539 std::map<SymbolRef, SymInfo> &Cache) {
1544 std::map<SymbolRef, SymInfo>::iterator CacheIt = Cache.end();
1549 std::tie(CacheIt, New) = Cache.insert({*Sym, {0, 0}});
1551 return CacheIt->second;
1555 return createError(
"failed to compute symbol address: ",
1561 return createError(
"failed to get symbol section: ",
1562 SectOrErr.takeError());
1565 Ret.Address = *SymAddrOrErr;
1566 }
else if (
auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) {
1568 Ret.Address = RSec->getAddress();
1572 Ret.SectionIndex = RSec->getIndex();
1582 if (
uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec))
1583 Ret.Address += SectionLoadAddress - RSec->getAddress();
1585 if (CacheIt != Cache.end())
1586 CacheIt->second = Ret;
1607class DWARFObjInMemory final :
public DWARFObject {
1608 bool IsLittleEndian;
1609 uint8_t AddressSize;
1612 std::vector<SectionName> SectionNames;
1615 std::map<object::SectionRef, unsigned>>;
1617 InfoSectionMap InfoSections;
1618 InfoSectionMap TypesSections;
1619 InfoSectionMap InfoDWOSections;
1620 InfoSectionMap TypesDWOSections;
1622 DWARFSectionMap LocSection;
1623 DWARFSectionMap LoclistsSection;
1624 DWARFSectionMap LoclistsDWOSection;
1625 DWARFSectionMap LineSection;
1626 DWARFSectionMap RangesSection;
1627 DWARFSectionMap RnglistsSection;
1628 DWARFSectionMap StrOffsetsSection;
1629 DWARFSectionMap LineDWOSection;
1630 DWARFSectionMap FrameSection;
1631 DWARFSectionMap EHFrameSection;
1632 DWARFSectionMap LocDWOSection;
1633 DWARFSectionMap StrOffsetsDWOSection;
1634 DWARFSectionMap RangesDWOSection;
1635 DWARFSectionMap RnglistsDWOSection;
1636 DWARFSectionMap AddrSection;
1637 DWARFSectionMap AppleNamesSection;
1638 DWARFSectionMap AppleTypesSection;
1639 DWARFSectionMap AppleNamespacesSection;
1640 DWARFSectionMap AppleObjCSection;
1641 DWARFSectionMap NamesSection;
1642 DWARFSectionMap PubnamesSection;
1643 DWARFSectionMap PubtypesSection;
1644 DWARFSectionMap GnuPubnamesSection;
1645 DWARFSectionMap GnuPubtypesSection;
1646 DWARFSectionMap MacroSection;
1650 .
Case(
"debug_loc", &LocSection)
1651 .
Case(
"debug_loclists", &LoclistsSection)
1652 .
Case(
"debug_loclists.dwo", &LoclistsDWOSection)
1653 .
Case(
"debug_line", &LineSection)
1654 .
Case(
"debug_frame", &FrameSection)
1655 .
Case(
"eh_frame", &EHFrameSection)
1656 .
Case(
"debug_str_offsets", &StrOffsetsSection)
1657 .
Case(
"debug_ranges", &RangesSection)
1658 .
Case(
"debug_rnglists", &RnglistsSection)
1659 .
Case(
"debug_loc.dwo", &LocDWOSection)
1660 .
Case(
"debug_line.dwo", &LineDWOSection)
1661 .
Case(
"debug_names", &NamesSection)
1662 .
Case(
"debug_rnglists.dwo", &RnglistsDWOSection)
1663 .
Case(
"debug_str_offsets.dwo", &StrOffsetsDWOSection)
1664 .
Case(
"debug_addr", &AddrSection)
1665 .
Case(
"apple_names", &AppleNamesSection)
1666 .
Case(
"debug_pubnames", &PubnamesSection)
1667 .
Case(
"debug_pubtypes", &PubtypesSection)
1668 .
Case(
"debug_gnu_pubnames", &GnuPubnamesSection)
1669 .
Case(
"debug_gnu_pubtypes", &GnuPubtypesSection)
1670 .
Case(
"apple_types", &AppleTypesSection)
1671 .
Case(
"apple_namespaces", &AppleNamespacesSection)
1672 .
Case(
"apple_namespac", &AppleNamespacesSection)
1673 .
Case(
"apple_objc", &AppleObjCSection)
1674 .
Case(
"debug_macro", &MacroSection)
1693 std::deque<SmallString<0>> UncompressedSections;
1699 .
Case(
"debug_abbrev", &AbbrevSection)
1700 .
Case(
"debug_aranges", &ArangesSection)
1701 .
Case(
"debug_str", &StrSection)
1702 .
Case(
"debug_macinfo", &MacinfoSection)
1703 .
Case(
"debug_macinfo.dwo", &MacinfoDWOSection)
1704 .
Case(
"debug_macro.dwo", &MacroDWOSection)
1705 .
Case(
"debug_abbrev.dwo", &AbbrevDWOSection)
1706 .
Case(
"debug_str.dwo", &StrDWOSection)
1707 .
Case(
"debug_cu_index", &CUIndexSection)
1708 .
Case(
"debug_tu_index", &TUIndexSection)
1709 .
Case(
"gdb_index", &GdbIndexSection)
1710 .
Case(
"debug_line_str", &LineStrSection)
1731 UncompressedSections.push_back(std::move(Out));
1732 Data = UncompressedSections.back();
1738 DWARFObjInMemory(
const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
1739 uint8_t AddrSize,
bool IsLittleEndian)
1740 : IsLittleEndian(IsLittleEndian) {
1741 for (
const auto &SecIt : Sections) {
1742 if (
StringRef *SectionData = mapSectionToMember(SecIt.first()))
1743 *SectionData = SecIt.second->getBuffer();
1744 else if (SecIt.first() ==
"debug_info")
1747 InfoSections[
SectionRef()].Data = SecIt.second->getBuffer();
1748 else if (SecIt.first() ==
"debug_info.dwo")
1749 InfoDWOSections[
SectionRef()].Data = SecIt.second->getBuffer();
1750 else if (SecIt.first() ==
"debug_types")
1751 TypesSections[
SectionRef()].Data = SecIt.second->getBuffer();
1752 else if (SecIt.first() ==
"debug_types.dwo")
1753 TypesDWOSections[
SectionRef()].Data = SecIt.second->getBuffer();
1760 : IsLittleEndian(Obj.isLittleEndian()),
1761 AddressSize(Obj.getBytesInAddress()), FileName(Obj.
getFileName()),
1767 if (
auto NameOrErr =
Section.getName())
1772 ++SectionAmountMap[
Name];
1773 SectionNames.push_back({
Name,
true });
1786 HandleError(
createError(
"failed to get relocated section: ",
1796 if (!L || !
L->getLoadedSectionContents(*RelocatedSection,
Data)) {
1805 if (
auto Err = maybeDecompress(Section,
Name,
Data)) {
1814 Name.find_first_not_of(
"._z"));
1821 *SectionData =
Data;
1822 if (
Name ==
"debug_ranges") {
1824 RangesDWOSection.Data =
Data;
1825 }
else if (
Name ==
"debug_frame" ||
Name ==
"eh_frame") {
1829 }
else if (InfoSectionMap *Sections =
1831 .Case(
"debug_info", &InfoSections)
1832 .Case(
"debug_info.dwo", &InfoDWOSections)
1833 .Case(
"debug_types", &TypesSections)
1834 .Case(
"debug_types.dwo", &TypesDWOSections)
1838 DWARFSectionMap &S = (*Sections)[
Section];
1847 (RelocAction == DWARFContext::ProcessDebugRelocations::Ignore))
1851 if (
auto NameOrErr = RelocatedSection->getName())
1852 RelSecName = *NameOrErr;
1860 if (L &&
L->getLoadedSectionContents(*RelocatedSection, RelSecData))
1868 if (!L && isa<MachOObjectFile>(&Obj))
1871 RelSecName = RelSecName.
substr(
1876 DWARFSectionMap *Sec = mapNameToDWARFSection(RelSecName);
1881 if (RelSecName ==
"debug_info")
1882 Map = &
static_cast<DWARFSectionMap &
>(InfoSections[*RelocatedSection])
1884 else if (RelSecName ==
"debug_types")
1886 &
static_cast<DWARFSectionMap &
>(TypesSections[*RelocatedSection])
1896 std::map<SymbolRef, SymInfo> AddrCache;
1908 if (!SymInfoOrErr) {
1917 if (Supports && Supports(Reloc.getType())) {
1918 auto I =
Map->try_emplace(
1921 SymInfoOrErr->SectionIndex, Reloc, SymInfoOrErr->Address,
1922 std::optional<object::RelocationRef>(), 0, Resolver});
1930 "At most two relocations per offset are supported"));
1932 entry.Reloc2 = Reloc;
1933 entry.SymbolValue2 = SymInfoOrErr->Address;
1937 Reloc.getTypeName(
Type);
1947 if (SectionAmountMap[S.Name] > 1)
1948 S.IsNameUnique =
false;
1953 auto &Sec =
static_cast<const DWARFSectionMap &
>(S);
1955 if (AI == Sec.Relocs.end())
1956 return std::nullopt;
1963 return SectionNames;
1966 bool isLittleEndian()
const override {
return IsLittleEndian; }
1967 StringRef getAbbrevDWOSection()
const override {
return AbbrevDWOSection; }
1968 const DWARFSection &getLineDWOSection()
const override {
1969 return LineDWOSection;
1971 const DWARFSection &getLocDWOSection()
const override {
1972 return LocDWOSection;
1974 StringRef getStrDWOSection()
const override {
return StrDWOSection; }
1975 const DWARFSection &getStrOffsetsDWOSection()
const override {
1976 return StrOffsetsDWOSection;
1978 const DWARFSection &getRangesDWOSection()
const override {
1979 return RangesDWOSection;
1981 const DWARFSection &getRnglistsDWOSection()
const override {
1982 return RnglistsDWOSection;
1984 const DWARFSection &getLoclistsDWOSection()
const override {
1985 return LoclistsDWOSection;
1987 const DWARFSection &getAddrSection()
const override {
return AddrSection; }
1988 StringRef getCUIndexSection()
const override {
return CUIndexSection; }
1989 StringRef getGdbIndexSection()
const override {
return GdbIndexSection; }
1990 StringRef getTUIndexSection()
const override {
return TUIndexSection; }
1993 const DWARFSection &getStrOffsetsSection()
const override {
1994 return StrOffsetsSection;
1996 StringRef getLineStrSection()
const override {
return LineStrSection; }
1999 void forEachInfoDWOSections(
2001 for (
auto &
P : InfoDWOSections)
2004 void forEachTypesDWOSections(
2006 for (
auto &
P : TypesDWOSections)
2010 StringRef getAbbrevSection()
const override {
return AbbrevSection; }
2011 const DWARFSection &getLocSection()
const override {
return LocSection; }
2012 const DWARFSection &getLoclistsSection()
const override {
return LoclistsSection; }
2013 StringRef getArangesSection()
const override {
return ArangesSection; }
2015 return FrameSection;
2017 const DWARFSection &getEHFrameSection()
const override {
2018 return EHFrameSection;
2020 const DWARFSection &getLineSection()
const override {
return LineSection; }
2021 StringRef getStrSection()
const override {
return StrSection; }
2022 const DWARFSection &getRangesSection()
const override {
return RangesSection; }
2023 const DWARFSection &getRnglistsSection()
const override {
2024 return RnglistsSection;
2026 const DWARFSection &getMacroSection()
const override {
return MacroSection; }
2027 StringRef getMacroDWOSection()
const override {
return MacroDWOSection; }
2028 StringRef getMacinfoSection()
const override {
return MacinfoSection; }
2029 StringRef getMacinfoDWOSection()
const override {
return MacinfoDWOSection; }
2030 const DWARFSection &getPubnamesSection()
const override {
return PubnamesSection; }
2031 const DWARFSection &getPubtypesSection()
const override {
return PubtypesSection; }
2032 const DWARFSection &getGnuPubnamesSection()
const override {
2033 return GnuPubnamesSection;
2035 const DWARFSection &getGnuPubtypesSection()
const override {
2036 return GnuPubtypesSection;
2038 const DWARFSection &getAppleNamesSection()
const override {
2039 return AppleNamesSection;
2041 const DWARFSection &getAppleTypesSection()
const override {
2042 return AppleTypesSection;
2044 const DWARFSection &getAppleNamespacesSection()
const override {
2045 return AppleNamespacesSection;
2047 const DWARFSection &getAppleObjCSection()
const override {
2048 return AppleObjCSection;
2051 return NamesSection;
2055 uint8_t getAddressSize()
const override {
return AddressSize; }
2056 void forEachInfoSections(
2058 for (
auto &
P : InfoSections)
2061 void forEachTypesSections(
2063 for (
auto &
P : TypesSections)
2069std::unique_ptr<DWARFContext>
2073 std::function<
void(
Error)> RecoverableErrorHandler,
2074 std::function<
void(
Error)> WarningHandler) {
2075 auto DObj = std::make_unique<DWARFObjInMemory>(
2076 Obj, L, RecoverableErrorHandler, WarningHandler, RelocAction);
2077 return std::make_unique<DWARFContext>(std::move(DObj), std::move(DWPName),
2078 RecoverableErrorHandler,
2082std::unique_ptr<DWARFContext>
2084 uint8_t AddrSize,
bool isLittleEndian,
2085 std::function<
void(
Error)> RecoverableErrorHandler,
2086 std::function<
void(
Error)> WarningHandler) {
2088 std::make_unique<DWARFObjInMemory>(Sections, AddrSize,
isLittleEndian);
2089 return std::make_unique<DWARFContext>(
2090 std::move(DObj),
"", RecoverableErrorHandler, WarningHandler);
2100 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)
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 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
Expected< uint64_t > getAddress() const
Returns the symbol virtual address (i.e.
Expected< section_iterator > getSection() const
Get section this symbol is defined in reference to.
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.