1//===- DWARFContext.cpp ---------------------------------------------------===// 
  3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
  4// See https://llvm.org/LICENSE.txt for license information. 
  5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
  7//===----------------------------------------------------------------------===// 
  65 #define DEBUG_TYPE "dwarf" 
  76 const auto &DObj = 
C.getDWARFObj();
 
  77 if (DObj.getCUIndexSection().empty())
 
  83 if (!(
C.getParseCUTUIndexManually() ||
 
  84 S.
Data.
size() >= std::numeric_limits<uint32_t>::max()))
 
  90 if (
Error ExtractionErr = Header.extract(
 
  91 C, 
Data, &
Offset, DWARFSectionKind::DW_SECT_INFO)) {
 
  92 C.getWarningHandler()(
 
  93 createError(
"Failed to parse CU header in DWP file: " +
 
  94 toString(std::move(ExtractionErr))));
 
  99 auto Iter = Map.insert({TruncOffset,
 
  100 {Header.getOffset(), Header.getNextUnitOffset() -
 
  101 Header.getOffset()}});
 
  104 createError(
"Collision occured between for truncated offset 0x" +
 
  111 Offset = Header.getNextUnitOffset();
 
  124 if (Iter == Map.end()) {
 
  131 CUOff.
setOffset(Iter->second.getOffset());
 
  132 if (CUOff.
getOffset() != Iter->second.getOffset())
 
  134 "match calculated length at offset 0x" +
 
 
  143 const auto &DObj = 
C.getDWARFObj();
 
  144 DObj.forEachInfoDWOSections([&](
const DWARFSection &S) {
 
  145 if (!(
C.getParseCUTUIndexManually() ||
 
  146 S.
Data.
size() >= std::numeric_limits<uint32_t>::max()))
 
  152 if (
Error ExtractionErr = Header.extract(
 
  153 C, 
Data, &
Offset, DWARFSectionKind::DW_SECT_INFO)) {
 
  154 C.getWarningHandler()(
 
  155 createError(
"Failed to parse CU header in DWP file: " +
 
  156 toString(std::move(ExtractionErr))));
 
  159 bool CU = Header.getUnitType() == DW_UT_split_compile;
 
  160 uint64_t Sig = 
CU ? *Header.getDWOId() : Header.getTypeHash();
 
  161 Map[Sig] = Header.getOffset();
 
  162 Offset = Header.getNextUnitOffset();
 
  171 auto Iter = Map.find(
E.getSignature());
 
  172 if (Iter == Map.end()) {
 
  174 createError(
"Could not find unit with signature 0x" +
 
 
  184 if (
Index.getVersion() < 5)
 
 
  193 bool IsLittleEndian) {
 
  198 Cache = std::make_unique<T>(AccelSection, StrData);
 
  199 if (
Error E = Cache->extract())
 
 
  205std::unique_ptr<DWARFDebugMacro>
 
  207 auto Macro = std::make_unique<DWARFDebugMacro>();
 
  211 : 
D.dwo_compile_units(),
 
  213 ? 
D.getStringExtractor()
 
  214 : 
D.getStringDWOExtractor(),
 
  217 D.getRecoverableErrorHandler()(std::move(Err));
 
  222 switch (SectionType) {
 
  225 ParseAndDump(
Data, 
/*IsMacro=*/false);
 
  230 ParseAndDump(
Data, 
/*IsMacro=*/false);
 
  236 ParseAndDump(
Data, 
/*IsMacro=*/true);
 
  241 ParseAndDump(
Data, 
/*IsMacro=*/true);
 
 
  252 std::optional<DenseMap<uint64_t, DWARFTypeUnit *>> NormalTypeUnits;
 
  253 std::unique_ptr<DWARFUnitIndex> CUIndex;
 
  254 std::unique_ptr<DWARFGdbIndex> GdbIndex;
 
  255 std::unique_ptr<DWARFUnitIndex> TUIndex;
 
  256 std::unique_ptr<DWARFDebugAbbrev> Abbrev;
 
  257 std::unique_ptr<DWARFDebugLoc> 
Loc;
 
  258 std::unique_ptr<DWARFDebugAranges> Aranges;
 
  259 std::unique_ptr<DWARFDebugLine> Line;
 
  261 std::unique_ptr<DWARFDebugFrame> EHFrame;
 
  262 std::unique_ptr<DWARFDebugMacro> 
Macro;
 
  263 std::unique_ptr<DWARFDebugMacro> Macinfo;
 
  264 std::unique_ptr<DWARFDebugNames> Names;
 
  265 std::unique_ptr<AppleAcceleratorTable> 
AppleNames;
 
  266 std::unique_ptr<AppleAcceleratorTable> 
AppleTypes;
 
  268 std::unique_ptr<AppleAcceleratorTable> 
AppleObjC;
 
  270 std::optional<DenseMap<uint64_t, DWARFTypeUnit *>> DWOTypeUnits;
 
  271 std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
 
  272 std::unique_ptr<DWARFDebugMacro> MacinfoDWO;
 
  273 std::unique_ptr<DWARFDebugMacro> MacroDWO;
 
  276 std::unique_ptr<DWARFContext> Context;
 
  279 std::weak_ptr<DWOFile> DWP;
 
  280 bool CheckedForDWP = 
false;
 
  284 ThreadUnsafeDWARFContextState(
DWARFContext &DC, std::string &DWP) :
 
  289 if (NormalUnits.
empty()) {
 
  302 DWARFUnitVector &getDWOUnits(
bool Lazy)
 override {
 
  303 if (DWOUnits.
empty()) {
 
  304 const DWARFObject &DObj = 
D.getDWARFObj();
 
  317 const DWARFDebugAbbrev *getDebugAbbrevDWO()
 override {
 
  319 return AbbrevDWO.get();
 
  320 const DWARFObject &DObj = 
D.getDWARFObj();
 
  322 AbbrevDWO = std::make_unique<DWARFDebugAbbrev>(abbrData);
 
  323 return AbbrevDWO.get();
 
  326 const DWARFUnitIndex &getCUIndex()
 override {
 
  330 DataExtractor 
Data(
D.getDWARFObj().getCUIndexSection(),
 
  331 D.isLittleEndian(), 0);
 
  332 CUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_INFO);
 
  333 if (CUIndex->parse(
Data))
 
  337 const DWARFUnitIndex &getTUIndex()
 override {
 
  341 DataExtractor 
Data(
D.getDWARFObj().getTUIndexSection(),
 
  342 D.isLittleEndian(), 0);
 
  344 bool isParseSuccessful = TUIndex->parse(
Data);
 
  345 // If we are parsing TU-index and for .debug_types section we don't need 
  347 if (isParseSuccessful && TUIndex->getVersion() != 2)
 
  352 DWARFGdbIndex &getGdbIndex()
 override {
 
  356 DataExtractor 
Data(
D.getDWARFObj().getGdbIndexSection(), 
true /*LE*/, 0);
 
  357 GdbIndex = std::make_unique<DWARFGdbIndex>();
 
  358 GdbIndex->parse(
Data);
 
  362 const DWARFDebugAbbrev *getDebugAbbrev()
 override {
 
  366 DataExtractor 
Data(
D.getDWARFObj().getAbbrevSection(),
 
  367 D.isLittleEndian(), 0);
 
  368 Abbrev = std::make_unique<DWARFDebugAbbrev>(
Data);
 
  376 const DWARFObject &DObj = 
D.getDWARFObj();
 
  377 // Assume all units have the same address byte size. 
  379 D.getNumCompileUnits()
 
  380 ? DWARFDataExtractor(DObj, DObj.
getLocSection(), 
D.isLittleEndian(),
 
  381 D.getUnitAtIndex(0)->getAddressByteSize())
 
  382 : DWARFDataExtractor(
"", 
D.isLittleEndian(), 0);
 
  383 Loc = std::make_unique<DWARFDebugLoc>(std::move(
Data));
 
  387 const DWARFDebugAranges *getDebugAranges()
 override {
 
  389 return Aranges.get();
 
  391 Aranges = std::make_unique<DWARFDebugAranges>();
 
  392 Aranges->generate(&
D);
 
  393 return Aranges.get();
 
  396 Expected<const DWARFDebugLine::LineTable *>
 
  397 getLineTableForUnit(DWARFUnit *U, function_ref<
void(
Error)> RecoverableErrorHandler)
 override {
 
  399 Line = std::make_unique<DWARFDebugLine>();
 
  401 auto UnitDIE = 
U->getUnitDIE();
 
  407 return nullptr; 
// No line table for this compile unit. 
  409 uint64_t stmtOffset = *
Offset + 
U->getLineTableOffset();
 
  410 // See if the line table is cached. 
  414 // Make sure the offset is good before we try to parse. 
  415 if (stmtOffset >= 
U->getLineSection().Data.size())
 
  418 // We have to parse it first. 
  419 DWARFDataExtractor 
Data(
U->getContext().getDWARFObj(), 
U->getLineSection(),
 
  420 U->isLittleEndian(), 
U->getAddressByteSize());
 
  421 return Line->getOrParseLineTable(
Data, stmtOffset, 
U->getContext(), U,
 
  422 RecoverableErrorHandler);
 
  426 void clearLineTableForUnit(DWARFUnit *U)
 override {
 
  430 auto UnitDIE = 
U->getUnitDIE();
 
  438 uint64_t stmtOffset = *
Offset + 
U->getLineTableOffset();
 
  439 Line->clearLineTable(stmtOffset);
 
  442 Expected<const DWARFDebugFrame *> getDebugFrame()
 override {
 
  445 const DWARFObject &DObj = 
D.getDWARFObj();
 
  448 // There's a "bug" in the DWARFv3 standard with respect to the target address 
  449 // size within debug frame sections. While DWARF is supposed to be independent 
  450 // of its container, FDEs have fields with size being "target address size", 
  451 // which isn't specified in DWARF in general. It's only specified for CUs, but 
  452 // .eh_frame can appear without a .debug_info section. Follow the example of 
  453 // other tools (libdwarf) and extract this from the container (ObjectFile 
  454 // provides this information). This problem is fixed in DWARFv4 
  455 // See this dwarf-discuss discussion for more details: 
  456 // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html 
  457 DWARFDataExtractor 
Data(DObj, DS, 
D.isLittleEndian(),
 
  460 std::make_unique<DWARFDebugFrame>(
D.getArch(), 
/*IsEH=*/false,
 
  469 Expected<const DWARFDebugFrame *> getEHFrame()
 override {
 
  471 return EHFrame.get();
 
  472 const DWARFObject &DObj = 
D.getDWARFObj();
 
  475 DWARFDataExtractor 
Data(DObj, DS, 
D.isLittleEndian(),
 
  478 std::make_unique<DWARFDebugFrame>(
D.getArch(), 
/*IsEH=*/true,
 
  483 return EHFrame.get();
 
  486 const DWARFDebugMacro *getDebugMacinfo()
 override {
 
  488 Macinfo = parseMacroOrMacinfo(MacinfoSection);
 
  489 return Macinfo.get();
 
  491 const DWARFDebugMacro *getDebugMacinfoDWO()
 override {
 
  493 MacinfoDWO = parseMacroOrMacinfo(MacinfoDwoSection);
 
  494 return MacinfoDWO.get();
 
  496 const DWARFDebugMacro *getDebugMacro()
 override {
 
  498 Macro = parseMacroOrMacinfo(MacroSection);
 
  501 const DWARFDebugMacro *getDebugMacroDWO()
 override {
 
  503 MacroDWO = parseMacroOrMacinfo(MacroDwoSection);
 
  504 return MacroDWO.get();
 
  506 const DWARFDebugNames &getDebugNames()
 override {
 
  507 const DWARFObject &DObj = 
D.getDWARFObj();
 
  511 const AppleAcceleratorTable &getAppleNames()
 override {
 
  512 const DWARFObject &DObj = 
D.getDWARFObj();
 
  517 const AppleAcceleratorTable &getAppleTypes()
 override {
 
  518 const DWARFObject &DObj = 
D.getDWARFObj();
 
  523 const AppleAcceleratorTable &getAppleNamespaces()
 override {
 
  524 const DWARFObject &DObj = 
D.getDWARFObj();
 
  530 const AppleAcceleratorTable &getAppleObjC()
 override {
 
  531 const DWARFObject &DObj = 
D.getDWARFObj();
 
  536 std::shared_ptr<DWARFContext>
 
  537 getDWOContext(StringRef AbsolutePath)
 override {
 
  538 if (
auto S = DWP.lock()) {
 
  539 DWARFContext *Ctxt = S->Context.get();
 
  540 return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
 
  543 std::weak_ptr<DWOFile> *
Entry = &DWOFiles[AbsolutePath];
 
  545 if (
auto S = 
Entry->lock()) {
 
  546 DWARFContext *Ctxt = S->Context.get();
 
  547 return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
 
  550 const DWARFObject &DObj = 
D.getDWARFObj();
 
  552 Expected<OwningBinary<ObjectFile>> Obj = [&] {
 
  553 if (!CheckedForDWP) {
 
  554 SmallString<128> DWPName;
 
  556 this->DWPName.
empty()
 
  557 ? (DObj.
getFileName() + 
".dwp").toStringRef(DWPName)
 
  558 : StringRef(this->DWPName));
 
  563 CheckedForDWP = 
true;
 
  564 // TODO: Should this error be handled (maybe in a high verbosity mode) 
  565 // before falling back to .dwo files? 
  574 // TODO: Actually report errors helpfully. 
  579 auto S = std::make_shared<DWOFile>();
 
  580 S->File = std::move(Obj.
get());
 
  581 // Allow multi-threaded access if there is a .dwp file as the CU index and 
  582 // TU index might be accessed from multiple threads. 
  583 bool ThreadSafe = isThreadSafe();
 
  585 *S->File.getBinary(), DWARFContext::ProcessDebugRelocations::Ignore,
 
  589 auto *Ctxt = S->Context.get();
 
  590 return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
 
  593 bool isThreadSafe()
 const override { 
return false; }
 
  595 const DenseMap<uint64_t, DWARFTypeUnit *> &getNormalTypeUnitMap() {
 
  596 if (!NormalTypeUnits) {
 
  597 NormalTypeUnits.emplace();
 
  598 for (
const auto &U :
D.normal_units()) {
 
  600 (*NormalTypeUnits)[TU->getTypeHash()] = TU;
 
  603 return *NormalTypeUnits;
 
  606 const DenseMap<uint64_t, DWARFTypeUnit *> &getDWOTypeUnitMap() {
 
  608 DWOTypeUnits.emplace();
 
  609 for (
const auto &U :
D.dwo_units()) {
 
  611 (*DWOTypeUnits)[TU->getTypeHash()] = TU;
 
  614 return *DWOTypeUnits;
 
  617 const DenseMap<uint64_t, DWARFTypeUnit *> &
 
  618 getTypeUnitMap(
bool IsDWO)
 override {
 
  620 return getDWOTypeUnitMap();
 
  622 return getNormalTypeUnitMap();
 
  626class ThreadSafeState : 
public ThreadUnsafeDWARFContextState {
 
  627 std::recursive_mutex 
Mutex;
 
  630 ThreadSafeState(DWARFContext &DC, std::string &DWP) :
 
  631 ThreadUnsafeDWARFContextState(DC, DWP) {}
 
  633 DWARFUnitVector &getNormalUnits()
 override {
 
  634 std::unique_lock<std::recursive_mutex> LockGuard(
Mutex);
 
  635 return ThreadUnsafeDWARFContextState::getNormalUnits();
 
  637 DWARFUnitVector &getDWOUnits(
bool Lazy)
 override {
 
  638 std::unique_lock<std::recursive_mutex> LockGuard(
Mutex);
 
  639 // We need to not do lazy parsing when we need thread safety as 
  640 // DWARFUnitVector, in lazy mode, will slowly add things to itself and 
  641 // will cause problems in a multi-threaded environment. 
  642 return ThreadUnsafeDWARFContextState::getDWOUnits(
false);
 
  644 const DWARFUnitIndex &getCUIndex()
 override {
 
  645 std::unique_lock<std::recursive_mutex> LockGuard(
Mutex);
 
  646 return ThreadUnsafeDWARFContextState::getCUIndex();
 
  648 const DWARFDebugAbbrev *getDebugAbbrevDWO()
 override {
 
  649 std::unique_lock<std::recursive_mutex> LockGuard(
Mutex);
 
  650 return ThreadUnsafeDWARFContextState::getDebugAbbrevDWO();
 
  653 const DWARFUnitIndex &getTUIndex()
 override {
 
  654 std::unique_lock<std::recursive_mutex> LockGuard(
Mutex);
 
  655 return ThreadUnsafeDWARFContextState::getTUIndex();
 
  657 DWARFGdbIndex &getGdbIndex()
 override {
 
  658 std::unique_lock<std::recursive_mutex> LockGuard(
Mutex);
 
  659 return ThreadUnsafeDWARFContextState::getGdbIndex();
 
  661 const DWARFDebugAbbrev *getDebugAbbrev()
 override {
 
  662 std::unique_lock<std::recursive_mutex> LockGuard(
Mutex);
 
  663 return ThreadUnsafeDWARFContextState::getDebugAbbrev();
 
  666 std::unique_lock<std::recursive_mutex> LockGuard(
Mutex);
 
  667 return ThreadUnsafeDWARFContextState::getDebugLoc();
 
  669 const DWARFDebugAranges *getDebugAranges()
 override {
 
  670 std::unique_lock<std::recursive_mutex> LockGuard(
Mutex);
 
  671 return ThreadUnsafeDWARFContextState::getDebugAranges();
 
  673 Expected<const DWARFDebugLine::LineTable *>
 
  674 getLineTableForUnit(DWARFUnit *U, function_ref<
void(
Error)> RecoverableErrorHandler)
 override {
 
  675 std::unique_lock<std::recursive_mutex> LockGuard(
Mutex);
 
  676 return ThreadUnsafeDWARFContextState::getLineTableForUnit(U, RecoverableErrorHandler);
 
  678 void clearLineTableForUnit(DWARFUnit *U)
 override {
 
  679 std::unique_lock<std::recursive_mutex> LockGuard(
Mutex);
 
  680 return ThreadUnsafeDWARFContextState::clearLineTableForUnit(U);
 
  682 Expected<const DWARFDebugFrame *> getDebugFrame()
 override {
 
  683 std::unique_lock<std::recursive_mutex> LockGuard(
Mutex);
 
  684 return ThreadUnsafeDWARFContextState::getDebugFrame();
 
  686 Expected<const DWARFDebugFrame *> getEHFrame()
 override {
 
  687 std::unique_lock<std::recursive_mutex> LockGuard(
Mutex);
 
  688 return ThreadUnsafeDWARFContextState::getEHFrame();
 
  690 const DWARFDebugMacro *getDebugMacinfo()
 override {
 
  691 std::unique_lock<std::recursive_mutex> LockGuard(
Mutex);
 
  692 return ThreadUnsafeDWARFContextState::getDebugMacinfo();
 
  694 const DWARFDebugMacro *getDebugMacinfoDWO()
 override {
 
  695 std::unique_lock<std::recursive_mutex> LockGuard(
Mutex);
 
  696 return ThreadUnsafeDWARFContextState::getDebugMacinfoDWO();
 
  698 const DWARFDebugMacro *getDebugMacro()
 override {
 
  699 std::unique_lock<std::recursive_mutex> LockGuard(
Mutex);
 
  700 return ThreadUnsafeDWARFContextState::getDebugMacro();
 
  702 const DWARFDebugMacro *getDebugMacroDWO()
 override {
 
  703 std::unique_lock<std::recursive_mutex> LockGuard(
Mutex);
 
  704 return ThreadUnsafeDWARFContextState::getDebugMacroDWO();
 
  706 const DWARFDebugNames &getDebugNames()
 override {
 
  707 std::unique_lock<std::recursive_mutex> LockGuard(
Mutex);
 
  708 return ThreadUnsafeDWARFContextState::getDebugNames();
 
  710 const AppleAcceleratorTable &getAppleNames()
 override {
 
  711 std::unique_lock<std::recursive_mutex> LockGuard(
Mutex);
 
  712 return ThreadUnsafeDWARFContextState::getAppleNames();
 
  714 const AppleAcceleratorTable &getAppleTypes()
 override {
 
  715 std::unique_lock<std::recursive_mutex> LockGuard(
Mutex);
 
  716 return ThreadUnsafeDWARFContextState::getAppleTypes();
 
  718 const AppleAcceleratorTable &getAppleNamespaces()
 override {
 
  719 std::unique_lock<std::recursive_mutex> LockGuard(
Mutex);
 
  720 return ThreadUnsafeDWARFContextState::getAppleNamespaces();
 
  722 const AppleAcceleratorTable &getAppleObjC()
 override {
 
  723 std::unique_lock<std::recursive_mutex> LockGuard(
Mutex);
 
  724 return ThreadUnsafeDWARFContextState::getAppleObjC();
 
  726 std::shared_ptr<DWARFContext>
 
  727 getDWOContext(StringRef AbsolutePath)
 override {
 
  728 std::unique_lock<std::recursive_mutex> LockGuard(
Mutex);
 
  729 return ThreadUnsafeDWARFContextState::getDWOContext(AbsolutePath);
 
  732 bool isThreadSafe()
 const override { 
return true; }
 
  734 const DenseMap<uint64_t, DWARFTypeUnit *> &
 
  735 getTypeUnitMap(
bool IsDWO)
 override {
 
  736 std::unique_lock<std::recursive_mutex> LockGuard(
Mutex);
 
  737 return ThreadUnsafeDWARFContextState::getTypeUnitMap(IsDWO);
 
  744 std::function<
void(
Error)> RecoverableErrorHandler,
 
  745 std::function<
void(
Error)> WarningHandler,
 
  748 RecoverableErrorHandler(RecoverableErrorHandler),
 
  749 WarningHandler(WarningHandler), DObj(
std::
move(DObj)) {
 
  751 State = std::make_unique<ThreadSafeState>(*
this, DWPName);
 
  753 State = std::make_unique<ThreadUnsafeDWARFContextState>(*
this, DWPName);
 
 
  758/// Dump the UUID load command. 
  763 for (
auto LC : 
MachO->load_commands()) {
 
  765 if (LC.C.cmd == MachO::LC_UUID) {
 
  766 if (LC.C.cmdsize < 
sizeof(
UUID) + 
sizeof(LC.C)) {
 
  767 OS << 
"error: UUID load command is too short.\n";
 
  771 memcpy(&
UUID, LC.Ptr+
sizeof(LC.C), 
sizeof(
UUID));
 
  774 OS << 
" (" << 
T.getArchName() << 
')';
 
  775 OS << 
' ' << 
MachO->getFileName() << 
'\n';
 
 
  781 std::vector<std::optional<StrOffsetsContributionDescriptor>>;
 
  783// Collect all the contributions to the string offsets table from all units, 
  784// sort them by their starting offsets and remove duplicates. 
  788 for (
const auto &U : Units)
 
  789 if (
const auto &
C = U->getStringOffsetsTableContribution())
 
  790 Contributions.push_back(
C);
 
  791 // Sort the contributions so that any invalid ones are placed at 
  792 // the start of the contributions vector. This way they are reported 
  795 [](
const std::optional<StrOffsetsContributionDescriptor> &L,
 
  796 const std::optional<StrOffsetsContributionDescriptor> &R) {
 
  798 return L->Base < R->Base;
 
  799 return R.has_value();
 
  802 // Uniquify contributions, as it is possible that units (specifically 
  803 // type units in dwo or dwp files) share contributions. We don't want 
  804 // to report them more than once. 
  808 [](
const std::optional<StrOffsetsContributionDescriptor> &L,
 
  809 const std::optional<StrOffsetsContributionDescriptor> &R) {
 
  811 return L->Base == R->Base && L->Size == R->Size;
 
  814 Contributions.end());
 
  815 return Contributions;
 
 
  818// Dump a DWARF string offsets section. This may be a DWARF v5 formatted 
  819// string offsets section, where each compile or type unit contributes a 
  820// number of entries (string offsets), with each contribution preceded by 
  821// a header containing size and version number. Alternatively, it may be a 
  822// monolithic series of string offsets, as generated by the pre-DWARF v5 
  823// implementation of split DWARF; however, in that case we still need to 
  824// collect contributions of units because the size of the offsets (4 or 8 
  825// bytes) depends on the format of the referencing unit (DWARF32 or DWARF64). 
  838 for (
auto &Contribution : Contributions) {
 
  839 // Report an ill-formed contribution. 
  841 OS << 
"error: invalid contribution to string offsets table in section ." 
  848 uint16_t Version = Contribution->getVersion();
 
  849 uint64_t ContributionHeader = Contribution->Base;
 
  850 // In DWARF v5 there is a contribution header that immediately precedes 
  851 // the string offsets base (the location we have previously retrieved from 
  852 // the CU DIE's DW_AT_str_offsets attribute). The header is located either 
  853 // 8 or 16 bytes before the base, depending on the contribution's format. 
  855 ContributionHeader -= Format == 
DWARF32 ? 8 : 16;
 
  857 // Detect overlapping contributions. 
  858 if (
Offset > ContributionHeader) {
 
  861 "overlapping contributions to string offsets table in section .%s.",
 
  864 // Report a gap in the table. 
  865 if (
Offset < ContributionHeader) {
 
  866 OS << 
format(
"0x%8.8" PRIx64 
": Gap, length = ", 
Offset);
 
  867 OS << (ContributionHeader - 
Offset) << 
"\n";
 
  869 OS << 
format(
"0x%8.8" PRIx64 
": ", ContributionHeader);
 
  870 // In DWARF v5 the contribution size in the descriptor does not equal 
  871 // the originally encoded length (it does not contain the length of the 
  872 // version field and the padding, a total of 4 bytes). Add them back in 
  874 OS << 
"Contribution size = " << (Contribution->Size + (Version < 5 ? 0 : 4))
 
  876 << 
", Version = " << Version << 
"\n";
 
  878 Offset = Contribution->Base;
 
  879 unsigned EntrySize = Contribution->getDwarfOffsetByteSize();
 
  880 while (
Offset - Contribution->Base < Contribution->Size) {
 
  884 OS << 
format(
"%0*" PRIx64 
" ", OffsetDumpWidth, StringOffset);
 
  885 const char *S = StrData.
getCStr(&StringOffset);
 
  887 OS << 
format(
"\"%s\"", S);
 
  891 // Report a gap at the end of the table. 
  892 if (
Offset < SectionSize) {
 
  893 OS << 
format(
"0x%8.8" PRIx64 
": Gap, length = ", 
Offset);
 
  894 OS << (SectionSize - 
Offset) << 
"\n";
 
 
  898// Dump the .debug_addr section. 
  909 // Keep going after an error, if we can, assuming that the length field 
  910 // could be read. If it couldn't, stop reading the section. 
  912 Offset = TableOffset + *TableLength;
 
  917 AddrTable.
dump(OS, DumpOpts);
 
 
  921// Dump the .debug_rnglists or .debug_rnglists.dwo section (DWARF v5). 
  934 // Keep going after an error, if we can, assuming that the length field 
  935 // could be read. If it couldn't, stop reading the section. 
  940 Rnglists.
dump(rnglistData, OS, LookupPooledAddress, DumpOpts);
 
 
  948 std::optional<uint64_t> DumpOffset) {
 
  958 Header.dump(
Data, OS, DumpOpts);
 
  960 uint64_t EndOffset = Header.length() + Header.getHeaderOffset();
 
  961 Data.setAddressSize(Header.getAddrSize());
 
  964 if (DumpOffset >= 
Offset && DumpOffset < EndOffset) {
 
  966 Loc.dumpLocationList(&
Offset, OS, 
/*BaseAddr=*/std::nullopt, Obj,
 
  967 nullptr, DumpOpts, 
/*Indent=*/0);
 
 
  987 std::array<std::optional<uint64_t>, 
DIDT_ID_Count> DumpOffsets) {
 
  991 bool IsDWO = (Extension == 
".dwo") || (Extension == 
".dwp");
 
  993 // Print UUID header. 
  994 const auto *ObjFile = DObj->getFile();
 
  998 // Print a header for each explicitly-requested section. 
  999 // Otherwise just print one for non-empty sections. 
  1000 // Only print empty .dwo section headers when dumping a .dwo file. 
  1001 bool Explicit = DumpType != 
DIDT_All && !IsDWO;
 
  1002 bool ExplicitDWO = Explicit && IsDWO;
 
  1003 auto shouldDump = [&](
bool Explicit, 
const char *Name, 
unsigned ID,
 
  1004 StringRef Section) -> std::optional<uint64_t> * {
 
  1005 unsigned Mask = 1U << 
ID;
 
  1006 bool Should = (DumpType & Mask) && (Explicit || !Section.empty());
 
  1009 OS << 
"\n" << Name << 
" contents:\n";
 
  1010 return &DumpOffsets[
ID];
 
  1013 // Dump individual sections. 
  1014 if (shouldDump(Explicit, 
".debug_abbrev", DIDT_ID_DebugAbbrev,
 
  1015 DObj->getAbbrevSection()))
 
  1017 if (shouldDump(ExplicitDWO, 
".debug_abbrev.dwo", DIDT_ID_DebugAbbrev,
 
  1018 DObj->getAbbrevDWOSection()))
 
  1022 OS << 
'\n' << Name << 
" contents:\n";
 
  1023 if (
auto DumpOffset = DumpOffsets[DIDT_ID_DebugInfo])
 
  1024 for (
const auto &U : Units) {
 
  1025 U->getDIEForOffset(*DumpOffset)
 
  1027 DWARFDie CUDie = U->getUnitDIE(
false);
 
  1028 DWARFDie CUNonSkeletonDie = U->getNonSkeletonUnitDIE(
false);
 
  1029 if (CUNonSkeletonDie && CUDie != CUNonSkeletonDie) {
 
  1036 for (
const auto &U : Units)
 
  1037 U->dump(OS, DumpOpts);
 
  1039 if ((DumpType & DIDT_DebugInfo)) {
 
  1047 OS << 
'\n' << Name << 
" contents:\n";
 
  1048 for (
const auto &U : Units)
 
  1049 if (
auto DumpOffset = DumpOffsets[DIDT_ID_DebugTypes])
 
  1050 U->getDIEForOffset(*DumpOffset)
 
  1053 U->dump(OS, DumpOpts);
 
  1055 if ((DumpType & DIDT_DebugTypes)) {
 
  1066 if (
const auto *Off = shouldDump(Explicit, 
".debug_loc", DIDT_ID_DebugLoc,
 
  1067 DObj->getLocSection().Data)) {
 
  1070 if (
const auto *Off =
 
  1071 shouldDump(Explicit, 
".debug_loclists", DIDT_ID_DebugLoclists,
 
  1072 DObj->getLoclistsSection().Data)) {
 
  1077 if (
const auto *Off =
 
  1078 shouldDump(ExplicitDWO, 
".debug_loclists.dwo", DIDT_ID_DebugLoclists,
 
  1079 DObj->getLoclistsDWOSection().Data)) {
 
  1085 if (
const auto *Off =
 
  1086 shouldDump(ExplicitDWO, 
".debug_loc.dwo", DIDT_ID_DebugLoc,
 
  1087 DObj->getLocDWOSection().Data)) {
 
  1094 /*BaseAddr=*/std::nullopt, *DObj, 
nullptr,
 
  1099 Loc.dumpRange(0, 
Data.getData().size(), OS, *DObj, LLDumpOpts);
 
  1103 if (
const std::optional<uint64_t> *Off =
 
  1104 shouldDump(Explicit, 
".debug_frame", DIDT_ID_DebugFrame,
 
  1105 DObj->getFrameSection().Data)) {
 
  1107 (*DF)->dump(OS, DumpOpts, *Off);
 
  1109 RecoverableErrorHandler(
DF.takeError());
 
  1112 if (
const std::optional<uint64_t> *Off =
 
  1113 shouldDump(Explicit, 
".eh_frame", DIDT_ID_DebugFrame,
 
  1114 DObj->getEHFrameSection().Data)) {
 
  1116 (*DF)->dump(OS, DumpOpts, *Off);
 
  1118 RecoverableErrorHandler(
DF.takeError());
 
  1121 if (shouldDump(Explicit, 
".debug_macro", DIDT_ID_DebugMacro,
 
  1122 DObj->getMacroSection().Data)) {
 
  1127 if (shouldDump(Explicit, 
".debug_macro.dwo", DIDT_ID_DebugMacro,
 
  1128 DObj->getMacroDWOSection())) {
 
  1133 if (shouldDump(Explicit, 
".debug_macinfo", DIDT_ID_DebugMacro,
 
  1134 DObj->getMacinfoSection())) {
 
  1139 if (shouldDump(Explicit, 
".debug_macinfo.dwo", DIDT_ID_DebugMacro,
 
  1140 DObj->getMacinfoDWOSection())) {
 
  1142 MacinfoDWO->dump(OS);
 
  1145 if (shouldDump(Explicit, 
".debug_aranges", DIDT_ID_DebugAranges,
 
  1146 DObj->getArangesSection())) {
 
  1154 RecoverableErrorHandler(std::move(E));
 
  1163 std::optional<uint64_t> DumpOffset) {
 
  1165 if (DumpOffset && 
Parser.getOffset() != *DumpOffset) {
 
  1169 OS << 
"debug_line[" << 
format(
"0x%8.8" PRIx64, 
Parser.getOffset())
 
  1176 auto DumpStrSection = [&](
StringRef Section) {
 
  1187 OS << 
format(
"0x%8.8" PRIx64 
": \"", StrOffset);
 
  1194 if (
const auto *Off = shouldDump(Explicit, 
".debug_line", DIDT_ID_DebugLine,
 
  1195 DObj->getLineSection().Data)) {
 
  1199 DumpLineSection(
Parser, DumpOpts, *Off);
 
  1202 if (
const auto *Off =
 
  1203 shouldDump(ExplicitDWO, 
".debug_line.dwo", DIDT_ID_DebugLine,
 
  1204 DObj->getLineDWOSection().Data)) {
 
  1208 DumpLineSection(
Parser, DumpOpts, *Off);
 
  1211 if (shouldDump(Explicit, 
".debug_cu_index", DIDT_ID_DebugCUIndex,
 
  1212 DObj->getCUIndexSection())) {
 
  1216 if (shouldDump(Explicit, 
".debug_tu_index", DIDT_ID_DebugTUIndex,
 
  1217 DObj->getTUIndexSection())) {
 
  1221 if (shouldDump(Explicit, 
".debug_str", DIDT_ID_DebugStr,
 
  1222 DObj->getStrSection()))
 
  1223 DumpStrSection(DObj->getStrSection());
 
  1225 if (shouldDump(ExplicitDWO, 
".debug_str.dwo", DIDT_ID_DebugStr,
 
  1226 DObj->getStrDWOSection()))
 
  1227 DumpStrSection(DObj->getStrDWOSection());
 
  1229 if (shouldDump(Explicit, 
".debug_line_str", DIDT_ID_DebugLineStr,
 
  1230 DObj->getLineStrSection()))
 
  1231 DumpStrSection(DObj->getLineStrSection());
 
  1233 if (shouldDump(Explicit, 
".debug_addr", DIDT_ID_DebugAddr,
 
  1234 DObj->getAddrSection().Data)) {
 
  1240 if (shouldDump(Explicit, 
".debug_ranges", DIDT_ID_DebugRanges,
 
  1241 DObj->getRangesSection().Data)) {
 
  1248 if (
Error E = rangeList.
extract(rangesData, &offset)) {
 
  1256 auto LookupPooledAddress =
 
  1259 auto I = CUs.begin();
 
  1261 return std::nullopt;
 
  1262 return (*I)->getAddrOffsetSectionItem(
Index);
 
  1265 if (shouldDump(Explicit, 
".debug_rnglists", DIDT_ID_DebugRnglists,
 
  1266 DObj->getRnglistsSection().Data)) {
 
  1272 if (shouldDump(ExplicitDWO, 
".debug_rnglists.dwo", DIDT_ID_DebugRnglists,
 
  1273 DObj->getRnglistsDWOSection().Data)) {
 
  1279 if (shouldDump(Explicit, 
".debug_pubnames", DIDT_ID_DebugPubnames,
 
  1280 DObj->getPubnamesSection().Data)) {
 
  1286 if (shouldDump(Explicit, 
".debug_pubtypes", DIDT_ID_DebugPubtypes,
 
  1287 DObj->getPubtypesSection().Data)) {
 
  1293 if (shouldDump(Explicit, 
".debug_gnu_pubnames", DIDT_ID_DebugGnuPubnames,
 
  1294 DObj->getGnuPubnamesSection().Data)) {
 
  1300 if (shouldDump(Explicit, 
".debug_gnu_pubtypes", DIDT_ID_DebugGnuPubtypes,
 
  1301 DObj->getGnuPubtypesSection().Data)) {
 
  1307 if (shouldDump(Explicit, 
".debug_str_offsets", DIDT_ID_DebugStrOffsets,
 
  1308 DObj->getStrOffsetsSection().Data))
 
  1310 OS, DumpOpts, 
"debug_str_offsets", *DObj, DObj->getStrOffsetsSection(),
 
  1312 if (shouldDump(ExplicitDWO, 
".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets,
 
  1313 DObj->getStrOffsetsDWOSection().Data))
 
  1315 DObj->getStrOffsetsDWOSection(),
 
  1319 if (shouldDump(Explicit, 
".gdb_index", DIDT_ID_GdbIndex,
 
  1320 DObj->getGdbIndexSection())) {
 
  1324 if (shouldDump(Explicit, 
".apple_names", DIDT_ID_AppleNames,
 
  1325 DObj->getAppleNamesSection().Data))
 
  1328 if (shouldDump(Explicit, 
".apple_types", DIDT_ID_AppleTypes,
 
  1329 DObj->getAppleTypesSection().Data))
 
  1332 if (shouldDump(Explicit, 
".apple_namespaces", DIDT_ID_AppleNamespaces,
 
  1333 DObj->getAppleNamespacesSection().Data))
 
  1336 if (shouldDump(Explicit, 
".apple_objc", DIDT_ID_AppleObjC,
 
  1337 DObj->getAppleObjCSection().Data))
 
  1339 if (shouldDump(Explicit, 
".debug_names", DIDT_ID_DebugNames,
 
  1340 DObj->getNamesSection().Data))
 
 
  1347 if (
const auto *R = TUI.getFromHash(Hash)) {
 
  1348 if (TUI.getVersion() >= 5) {
 
  1363 return State->getTypeUnitMap(IsDWO).lookup(Hash);
 
 
  1370 if (
const auto *R = CUI.getFromHash(Hash))
 
  1376 // If there's no index, just search through the CUs in the DWO - there's 
  1377 // probably only one unless this is something like LTO - though an in-process 
  1378 // built/cached lookup table could be used in that case to improve repeated 
  1379 // lookups of different CUs in the DWO. 
  1381 // Might not have parsed DWO ID yet. 
  1382 if (!DWOCU->getDWOId()) {
 
  1383 if (std::optional<uint64_t> DWOId =
 
  1384 toUnsigned(DWOCU->getUnitDIE().find(DW_AT_GNU_dwo_id)))
 
  1385 DWOCU->setDWOId(*DWOId);
 
  1390 if (DWOCU->getDWOId() == Hash)
 
 
  1397 if (
auto *
CU = State->getNormalUnits().getUnitForOffset(
Offset))
 
  1398 return CU->getDIEForOffset(
Offset);
 
 
  1407 if (DumpOpts.
DumpType & DIDT_DebugCUIndex)
 
  1409 if (DumpOpts.
DumpType & DIDT_DebugTUIndex)
 
  1411 if (DumpOpts.
DumpType & DIDT_DebugInfo)
 
  1413 if (DumpOpts.
DumpType & DIDT_DebugLine)
 
  1415 if (DumpOpts.
DumpType & DIDT_DebugStrOffsets)
 
 
  1423 return State->getCUIndex();
 
 
  1427 return State->getTUIndex();
 
 
  1431 return State->getGdbIndex();
 
 
  1435 return State->getDebugAbbrev();
 
 
  1439 return State->getDebugAbbrevDWO();
 
 
  1443 return State->getDebugLoc();
 
 
  1447 return State->getDebugAranges();
 
 
  1451 return State->getDebugFrame();
 
 
  1455 return State->getEHFrame();
 
 
  1459 return State->getDebugMacro();
 
 
  1463 return State->getDebugMacroDWO();
 
 
  1467 return State->getDebugMacinfo();
 
 
  1471 return State->getDebugMacinfoDWO();
 
 
  1476 return State->getDebugNames();
 
 
  1480 return State->getAppleNames();
 
 
  1484 return State->getAppleTypes();
 
 
  1488 return State->getAppleNamespaces();
 
 
  1492 return State->getAppleObjC();
 
 
  1499 if (!ExpectedLineTable) {
 
  1500 WarningHandler(ExpectedLineTable.
takeError());
 
  1503 return *ExpectedLineTable;
 
 
  1508 return State->getLineTableForUnit(U, RecoverableErrorHandler);
 
 
  1512 return State->clearLineTableForUnit(U);
 
 
  1516 return State->getDWOUnits(Lazy);
 
  1520 return State->getNormalUnits().getUnitForOffset(
Offset);
 
 
  1537 // Global variables are often missed by the above search, for one of two 
  1539 // 1. .debug_aranges may not include global variables. On clang, it seems we 
  1540 // put the globals in the aranges, but this isn't true for gcc. 
  1541 // 2. Even if the global variable is in a .debug_arange, global variables 
  1542 // may not be captured in the [start, end) addresses described by the 
  1543 // parent compile unit. 
  1545 // So, we walk the CU's and their child DI's manually, looking for the 
  1546 // specific global variable. 
  1548 if (
CU->getVariableForAddress(
Address)) {
 
 
  1564 // We were asked to check the DWO file and this debug information is more 
  1565 // complete that any information in the skeleton compile unit, so search the 
  1566 // DWO first to see if we have a match. 
  1568 DWARFDie CUDwoDie = 
CU->getNonSkeletonUnitDIE(
false);
 
  1569 if (CheckDWO && CUDwoDie && CUDie != CUDwoDie) {
 
  1570 // We have a DWO file, lets search it. 
  1575 if (Result.FunctionDIE)
 
  1576 Result.CompileUnit = CUDwo;
 
  1581 // Search the normal DWARF if we didn't find a match in the DWO file or if 
  1582 // we didn't check the DWO file above. 
  1584 Result.CompileUnit = 
CU;
 
  1585 Result.FunctionDIE = 
CU->getSubroutineForAddress(
Address);
 
  1588 std::vector<DWARFDie> Worklist;
 
  1589 Worklist.push_back(Result.FunctionDIE);
 
  1590 while (!Worklist.empty()) {
 
  1592 Worklist.pop_back();
 
  1597 if (
DIE.
getTag() == DW_TAG_lexical_block &&
 
  1599 Result.BlockDIE = 
DIE;
 
 
  1609/// TODO: change input parameter from "uint64_t Address" 
  1610/// into "SectionedAddress Address" 
  1614 std::string &FunctionName, std::string &StartFile, 
uint32_t &StartLine,
 
  1615 std::optional<uint64_t> &StartAddress) {
 
  1616 // The address may correspond to instruction in some inlined function, 
  1617 // so we have to build the chain of inlined functions and take the 
  1618 // name of the topmost function in it. 
  1620 CU->getInlinedChainForAddress(Address, InlinedChain);
 
  1621 if (InlinedChain.
empty())
 
  1625 bool FoundResult = 
false;
 
  1626 const char *Name = 
nullptr;
 
  1627 if (
Kind != FunctionNameKind::None && (Name = 
DIE.getSubroutineName(
Kind))) {
 
  1628 FunctionName = Name;
 
  1631 std::string DeclFile = 
DIE.getDeclFile(FileNameKind);
 
  1632 if (!DeclFile.empty()) {
 
  1633 StartFile = DeclFile;
 
  1636 if (
auto DeclLineResult = 
DIE.getDeclLine()) {
 
  1637 StartLine = DeclLineResult;
 
  1641 StartAddress = LowPcAddr->Address;
 
 
  1645static std::optional<int64_t>
 
  1647 std::optional<unsigned> FrameBaseReg) {
 
  1648 if (!Expr.
empty() &&
 
  1649 (Expr[0] == DW_OP_fbreg ||
 
  1650 (FrameBaseReg && Expr[0] == DW_OP_breg0 + *FrameBaseReg))) {
 
  1653 // A single DW_OP_fbreg or DW_OP_breg. 
  1656 // Same + DW_OP_deref (Fortran arrays look like this). 
  1659 // Fallthrough. Do not accept ex. (DW_OP_breg W29, DW_OP_stack_value) 
  1661 return std::nullopt;
 
 
  1665 DWARFDie Die, std::vector<DILocal> &Result) {
 
  1666 if (Die.
getTag() == DW_TAG_variable ||
 
  1667 Die.
getTag() == DW_TAG_formal_parameter) {
 
  1672 std::optional<unsigned> FrameBaseReg;
 
  1673 if (
auto FrameBase = Subprogram.
find(DW_AT_frame_base))
 
  1674 if (std::optional<ArrayRef<uint8_t>> Expr = FrameBase->getAsBlock())
 
  1675 if (!Expr->empty() && (*Expr)[0] >= DW_OP_reg0 &&
 
  1676 (*Expr)[0] <= DW_OP_reg31) {
 
  1677 FrameBaseReg = (*Expr)[0] - DW_OP_reg0;
 
  1680 if (Expected<std::vector<DWARFLocationExpression>> Loc =
 
  1682 for (
const auto &Entry : *Loc) {
 
  1683 if (std::optional<int64_t> FrameOffset =
 
  1685 Local.FrameOffset = *FrameOffset;
 
  1690 // FIXME: missing DW_AT_location is OK here, but other errors should be 
  1691 // reported to the user. 
  1695 if (
auto TagOffsetAttr = Die.
find(DW_AT_LLVM_tag_offset))
 
  1696 Local.TagOffset = TagOffsetAttr->getAsUnsignedConstant();
 
  1701 if (
auto NameAttr = Die.
find(DW_AT_name))
 
  1706 if (
auto DeclFileAttr = Die.
find(DW_AT_decl_file)) {
 
  1708 LT->getFileNameByIndex(
 
  1713 if (
auto DeclLineAttr = Die.
find(DW_AT_decl_line))
 
  1714 Local.DeclLine = *DeclLineAttr->getAsUnsignedConstant();
 
  1720 if (Die.
getTag() == DW_TAG_inlined_subroutine)
 
  1723 Subprogram = Origin;
 
  1725 for (
auto Child : Die)
 
  1726 addLocalsForDie(CU, Subprogram, Child, Result);
 
  1731 std::vector<DILocal> Result;
 
  1738 addLocalsForDie(
CU, Subprogram, Subprogram, Result);
 
 
  1742std::optional<DILineInfo>
 
  1747 return std::nullopt;
 
  1752 Result.StartFileName, Result.StartLine, Result.StartAddress);
 
  1753 if (
Spec.FLIKind != FileLineInfoKind::None) {
 
  1755 LineTable->getFileLineInfoForAddress(
 
  1757 CU->getCompilationDir(), 
Spec.FLIKind, Result);
 
 
  1764std::optional<DILineInfo>
 
  1772 Result.FileName = Die.
getDeclFile(FileLineInfoKind::AbsoluteFilePath);
 
 
  1787 std::string StartFileName;
 
  1789 std::optional<uint64_t> StartAddress;
 
  1791 Spec.FLIKind, FunctionName,
 
  1792 StartFileName, StartLine, StartAddress);
 
  1794 // If the Specifier says we don't need FileLineInfo, just 
  1795 // return the top-most function at the starting address. 
  1796 if (
Spec.FLIKind == FileLineInfoKind::None) {
 
  1798 Result.FunctionName = FunctionName;
 
  1799 Result.StartFileName = StartFileName;
 
  1800 Result.StartLine = StartLine;
 
  1801 Result.StartAddress = StartAddress;
 
  1802 Lines.push_back(std::make_pair(
Address.Address, Result));
 
  1808 // Get the index of row we're looking for in the line table. 
  1809 std::vector<uint32_t> RowVector;
 
  1815 for (
uint32_t RowIndex : RowVector) {
 
  1816 // Take file number and line/column from the row. 
  1820 Spec.FLIKind, Result.FileName);
 
  1821 Result.FunctionName = FunctionName;
 
  1822 Result.Line = Row.Line;
 
  1823 Result.Column = Row.Column;
 
  1824 Result.StartFileName = StartFileName;
 
  1825 Result.StartLine = StartLine;
 
  1826 Result.StartAddress = StartAddress;
 
  1827 Lines.push_back(std::make_pair(Row.Address.Address, Result));
 
 
  1840 return InliningInfo;
 
  1844 CU->getInlinedChainForAddress(
Address.Address, InlinedChain);
 
  1845 if (InlinedChain.
size() == 0) {
 
  1846 // If there is no DIE for address (e.g. it is in unavailable .dwo file), 
  1847 // try to at least get file/line info from symbol table. 
  1848 if (
Spec.FLIKind != FileLineInfoKind::None) {
 
  1853 {Address.Address, Address.SectionIndex}, 
Spec.ApproximateLine,
 
  1854 CU->getCompilationDir(), 
Spec.FLIKind, Frame))
 
  1857 return InliningInfo;
 
  1860 uint32_t CallFile = 0, CallLine = 0, CallColumn = 0, CallDiscriminator = 0;
 
  1861 for (
uint32_t i = 0, n = InlinedChain.
size(); i != n; i++) {
 
  1862 DWARFDie &FunctionDIE = InlinedChain[i];
 
  1864 // Get function name if necessary. 
  1867 if (
auto DeclLineResult = FunctionDIE.
getDeclLine())
 
  1872 if (
Spec.FLIKind != FileLineInfoKind::None) {
 
  1874 // For the topmost frame, initialize the line table of this 
  1875 // compile unit and fetch file/line info from it. 
  1877 // For the topmost routine, get file/line info from line table. 
  1881 CU->getCompilationDir(), 
Spec.FLIKind, Frame);
 
  1883 // Otherwise, use call file, call line and call column from 
  1884 // previous DIE in inlined chain. 
  1888 Frame.
Line = CallLine;
 
  1889 Frame.
Column = CallColumn;
 
  1892 // Get call file/line/column of a current DIE. 
  1900 return InliningInfo;
 
 
  1903std::shared_ptr<DWARFContext>
 
  1905 return State->getDWOContext(AbsolutePath);
 
 
  1913/// SymInfo contains information about symbol: it's address 
  1914/// and section index which is -1LL for absolute symbols. 
  1920/// Returns the address of symbol relocation used against and a section index. 
  1921/// Used for futher relocations computation. Symbol's section load address is 
  1925 std::map<SymbolRef, SymInfo> &Cache) {
 
  1930 std::map<SymbolRef, SymInfo>::iterator CacheIt = Cache.end();
 
  1931 // First calculate the address of the symbol or section as it appears 
  1932 // in the object file 
  1935 std::tie(CacheIt, New) = Cache.try_emplace(*Sym);
 
  1937 return CacheIt->second;
 
  1941 return createError(
"failed to compute symbol address: ",
 
  1944 // Also remember what section this symbol is in for later 
  1947 return createError(
"failed to get symbol section: ",
 
  1948 SectOrErr.takeError());
 
  1951 Ret.Address = *SymAddrOrErr;
 
  1953 RSec = MObj->getRelocationSection(
Reloc.getRawDataRefImpl());
 
  1958 Ret.SectionIndex = RSec->
getIndex();
 
  1960 // If we are given load addresses for the sections, we need to adjust: 
  1961 // SymAddr = (Address of Symbol Or Section in File) - 
  1962 // (Address of Section in File) + 
  1963 // (Load Address of Section) 
  1964 // RSec is now either the section being targeted or the section 
  1965 // containing the symbol being targeted. In either case, 
  1966 // we need to perform the same computation. 
  1968 if (
uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec))
 
  1969 Ret.Address += SectionLoadAddress - RSec->
getAddress();
 
  1971 if (CacheIt != Cache.end())
 
  1972 CacheIt->second = Ret;
 
 
  1982 // MachO also has relocations that point to sections and 
  1983 // scattered relocations. 
 
  1993class DWARFObjInMemory final : 
public DWARFObject {
 
  1994 bool IsLittleEndian;
 
  1995 uint8_t AddressSize;
 
  1997 const object::ObjectFile *Obj = 
nullptr;
 
  2000 using InfoSectionMap = MapVector<object::SectionRef, DWARFSectionMap,
 
  2001 std::map<object::SectionRef, unsigned>>;
 
  2003 InfoSectionMap InfoSections;
 
  2004 InfoSectionMap TypesSections;
 
  2005 InfoSectionMap InfoDWOSections;
 
  2006 InfoSectionMap TypesDWOSections;
 
  2008 DWARFSectionMap LocSection;
 
  2009 DWARFSectionMap LoclistsSection;
 
  2010 DWARFSectionMap LoclistsDWOSection;
 
  2011 DWARFSectionMap LineSection;
 
  2012 DWARFSectionMap RangesSection;
 
  2013 DWARFSectionMap RnglistsSection;
 
  2014 DWARFSectionMap StrOffsetsSection;
 
  2015 DWARFSectionMap LineDWOSection;
 
  2016 DWARFSectionMap FrameSection;
 
  2017 DWARFSectionMap EHFrameSection;
 
  2018 DWARFSectionMap LocDWOSection;
 
  2019 DWARFSectionMap StrOffsetsDWOSection;
 
  2020 DWARFSectionMap RangesDWOSection;
 
  2021 DWARFSectionMap RnglistsDWOSection;
 
  2022 DWARFSectionMap AddrSection;
 
  2023 DWARFSectionMap AppleNamesSection;
 
  2024 DWARFSectionMap AppleTypesSection;
 
  2025 DWARFSectionMap AppleNamespacesSection;
 
  2026 DWARFSectionMap AppleObjCSection;
 
  2027 DWARFSectionMap NamesSection;
 
  2028 DWARFSectionMap PubnamesSection;
 
  2029 DWARFSectionMap PubtypesSection;
 
  2030 DWARFSectionMap GnuPubnamesSection;
 
  2031 DWARFSectionMap GnuPubtypesSection;
 
  2032 DWARFSectionMap MacroSection;
 
  2034 DWARFSectionMap *mapNameToDWARFSection(StringRef Name) {
 
  2035 return StringSwitch<DWARFSectionMap *>(Name)
 
  2036 .Case(
"debug_loc", &LocSection)
 
  2037 .Case(
"debug_loclists", &LoclistsSection)
 
  2038 .Case(
"debug_loclists.dwo", &LoclistsDWOSection)
 
  2039 .Case(
"debug_line", &LineSection)
 
  2040 .Case(
"debug_frame", &FrameSection)
 
  2041 .Case(
"eh_frame", &EHFrameSection)
 
  2042 .Case(
"debug_str_offsets", &StrOffsetsSection)
 
  2043 .Case(
"debug_ranges", &RangesSection)
 
  2044 .Case(
"debug_rnglists", &RnglistsSection)
 
  2045 .Case(
"debug_loc.dwo", &LocDWOSection)
 
  2046 .Case(
"debug_line.dwo", &LineDWOSection)
 
  2047 .Case(
"debug_names", &NamesSection)
 
  2048 .Case(
"debug_rnglists.dwo", &RnglistsDWOSection)
 
  2049 .Case(
"debug_str_offsets.dwo", &StrOffsetsDWOSection)
 
  2050 .Case(
"debug_addr", &AddrSection)
 
  2051 .Case(
"apple_names", &AppleNamesSection)
 
  2052 .Case(
"debug_pubnames", &PubnamesSection)
 
  2053 .Case(
"debug_pubtypes", &PubtypesSection)
 
  2054 .Case(
"debug_gnu_pubnames", &GnuPubnamesSection)
 
  2055 .Case(
"debug_gnu_pubtypes", &GnuPubtypesSection)
 
  2056 .Case(
"apple_types", &AppleTypesSection)
 
  2057 .Case(
"apple_namespaces", &AppleNamespacesSection)
 
  2058 .Case(
"apple_namespac", &AppleNamespacesSection)
 
  2059 .Case(
"apple_objc", &AppleObjCSection)
 
  2060 .Case(
"debug_macro", &MacroSection)
 
  2064 StringRef AbbrevSection;
 
  2065 StringRef ArangesSection;
 
  2066 StringRef StrSection;
 
  2067 StringRef MacinfoSection;
 
  2068 StringRef MacinfoDWOSection;
 
  2069 StringRef MacroDWOSection;
 
  2070 StringRef AbbrevDWOSection;
 
  2071 StringRef StrDWOSection;
 
  2072 StringRef CUIndexSection;
 
  2073 StringRef GdbIndexSection;
 
  2074 StringRef TUIndexSection;
 
  2075 StringRef LineStrSection;
 
  2077 // A deque holding section data whose iterators are not invalidated when 
  2078 // new decompressed sections are inserted at the end. 
  2079 std::deque<SmallString<0>> UncompressedSections;
 
  2081 StringRef *mapSectionToMember(StringRef Name) {
 
  2082 if (DWARFSection *Sec = mapNameToDWARFSection(Name))
 
  2084 return StringSwitch<StringRef *>(Name)
 
  2085 .Case(
"debug_abbrev", &AbbrevSection)
 
  2086 .Case(
"debug_aranges", &ArangesSection)
 
  2087 .Case(
"debug_str", &StrSection)
 
  2088 .Case(
"debug_macinfo", &MacinfoSection)
 
  2089 .Case(
"debug_macinfo.dwo", &MacinfoDWOSection)
 
  2090 .Case(
"debug_macro.dwo", &MacroDWOSection)
 
  2091 .Case(
"debug_abbrev.dwo", &AbbrevDWOSection)
 
  2092 .Case(
"debug_str.dwo", &StrDWOSection)
 
  2093 .Case(
"debug_cu_index", &CUIndexSection)
 
  2094 .Case(
"debug_tu_index", &TUIndexSection)
 
  2095 .Case(
"gdb_index", &GdbIndexSection)
 
  2096 .Case(
"debug_line_str", &LineStrSection)
 
  2097 // Any more debug info sections go here. 
  2101 /// If Sec is compressed section, decompresses and updates its contents 
  2102 /// provided by Data. Otherwise leaves it unchanged. 
  2103 Error maybeDecompress(
const object::SectionRef &Sec, StringRef Name,
 
  2108 Expected<Decompressor> Decompressor =
 
  2114 if (
auto Err = Decompressor->resizeAndDecompress(Out))
 
  2117 UncompressedSections.push_back(std::move(Out));
 
  2118 Data = UncompressedSections.back();
 
  2124 DWARFObjInMemory(
const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
 
  2125 uint8_t AddrSize, 
bool IsLittleEndian)
 
  2126 : IsLittleEndian(IsLittleEndian) {
 
  2127 for (
const auto &SecIt : Sections) {
 
  2128 if (StringRef *SectionData = mapSectionToMember(SecIt.first()))
 
  2129 *SectionData = SecIt.second->getBuffer();
 
  2130 else if (SecIt.first() == 
"debug_info")
 
  2131 // Find debug_info and debug_types data by section rather than name as 
  2132 // there are multiple, comdat grouped, of these sections. 
  2133 InfoSections[SectionRef()].Data = SecIt.second->getBuffer();
 
  2134 else if (SecIt.first() == 
"debug_info.dwo")
 
  2135 InfoDWOSections[SectionRef()].Data = SecIt.second->getBuffer();
 
  2136 else if (SecIt.first() == 
"debug_types")
 
  2137 TypesSections[SectionRef()].Data = SecIt.second->getBuffer();
 
  2138 else if (SecIt.first() == 
"debug_types.dwo")
 
  2139 TypesDWOSections[SectionRef()].Data = SecIt.second->getBuffer();
 
  2142 DWARFObjInMemory(
const object::ObjectFile &Obj, 
const LoadedObjectInfo *L,
 
  2143 function_ref<
void(
Error)> HandleError,
 
  2144 function_ref<
void(
Error)> HandleWarning,
 
  2146 : IsLittleEndian(Obj.isLittleEndian()),
 
  2147 AddressSize(Obj.getBytesInAddress()), FileName(Obj.
getFileName()),
 
  2150 StringMap<unsigned> SectionAmountMap;
 
  2151 for (
const SectionRef &Section : Obj.
sections()) {
 
  2153 if (auto NameOrErr = Section.getName())
 
  2156 consumeError(NameOrErr.takeError());
 
  2158 ++SectionAmountMap[Name];
 
  2159 SectionNames.push_back({ Name, true });
 
  2161 // Skip BSS and Virtual sections, they aren't interesting. 
  2165 // Skip sections stripped by dsymutil. 
  2170 Expected<section_iterator> SecOrErr = 
Section.getRelocatedSection();
 
  2172 HandleError(
createError(
"failed to get relocated section: ",
 
  2173 SecOrErr.takeError()));
 
  2177 // Try to obtain an already relocated version of this section. 
  2178 // Else use the unrelocated section from the object file. We'll have to 
  2179 // apply relocations ourselves later. 
  2182 if (!L || !
L->getLoadedSectionContents(*RelocatedSection, 
Data)) {
 
  2183 Expected<StringRef> E = Section.getContents();
 
  2187 // maybeDecompress below will error. 
  2188 consumeError(E.takeError());
 
  2191 if (
auto Err = maybeDecompress(Section, Name, 
Data)) {
 
  2192 HandleError(
createError(
"failed to decompress '" + Name + 
"', ",
 
  2197 // Map platform specific debug section names to DWARF standard section 
  2202 if (StringRef *SectionData = mapSectionToMember(Name)) {
 
  2203 *SectionData = 
Data;
 
  2204 if (Name == 
"debug_ranges") {
 
  2205 // FIXME: Use the other dwo range section when we emit it. 
  2206 RangesDWOSection.Data = 
Data;
 
  2207 } 
else if (Name == 
"debug_frame" || Name == 
"eh_frame") {
 
  2208 if (DWARFSection *S = mapNameToDWARFSection(Name))
 
  2211 } 
else if (InfoSectionMap *Sections =
 
  2212 StringSwitch<InfoSectionMap *>(Name)
 
  2213 .Case(
"debug_info", &InfoSections)
 
  2214 .Case(
"debug_info.dwo", &InfoDWOSections)
 
  2215 .Case(
"debug_types", &TypesSections)
 
  2216 .Case(
"debug_types.dwo", &TypesDWOSections)
 
  2218 // Find debug_info and debug_types data by section rather than name as 
  2219 // there are multiple, comdat grouped, of these sections. 
  2220 DWARFSectionMap &S = (*Sections)[
Section];
 
  2225 (RelocAction == DWARFContext::ProcessDebugRelocations::Ignore))
 
  2228 StringRef RelSecName;
 
  2229 if (
auto NameOrErr = RelocatedSection->
getName())
 
  2230 RelSecName = *NameOrErr;
 
  2234 // If the section we're relocating was relocated already by the JIT, 
  2235 // then we used the relocated version above, so we do not need to process 
  2236 // relocations for it now. 
  2237 StringRef RelSecData;
 
  2238 if (L && 
L->getLoadedSectionContents(*RelocatedSection, RelSecData))
 
  2241 // In Mach-o files, the relocations do not need to be applied if 
  2242 // there is no load offset to apply. The value read at the 
  2243 // relocation point already factors in the section address 
  2244 // (actually applying the relocations will produce wrong results 
  2245 // as the section address will be added twice). 
  2249 if (!
Section.relocations().empty() && 
Name.ends_with(
".dwo") &&
 
  2250 RelSecName.starts_with(
".debug")) {
 
  2251 HandleWarning(createError(
"unexpected relocations for dwo section '" +
 
  2255 // TODO: Add support for relocations in other sections as needed. 
  2256 // Record relocations for the debug_info and debug_line sections. 
  2257 RelSecName = RelSecName.
substr(RelSecName.find_first_not_of(
"._"));
 
  2258 DWARFSectionMap *Sec = mapNameToDWARFSection(RelSecName);
 
  2261 // Find debug_info and debug_types relocs by section rather than name 
  2262 // as there are multiple, comdat grouped, of these sections. 
  2263 if (RelSecName == 
"debug_info")
 
  2264 Map = &
static_cast<DWARFSectionMap &
>(InfoSections[*RelocatedSection])
 
  2266 else if (RelSecName == 
"debug_types")
 
  2268 &
static_cast<DWARFSectionMap &
>(TypesSections[*RelocatedSection])
 
  2274 if (
Section.relocations().empty())
 
  2277 // Symbol to [address, section index] cache mapping. 
  2278 std::map<SymbolRef, SymInfo> AddrCache;
 
  2282 for (
const RelocationRef &Reloc : 
Section.relocations()) {
 
  2283 // FIXME: it's not clear how to correctly handle scattered 
  2285 if (isRelocScattered(Obj, Reloc))
 
  2288 Expected<SymInfo> SymInfoOrErr =
 
  2289 getSymbolInfo(Obj, Reloc, L, AddrCache);
 
  2290 if (!SymInfoOrErr) {
 
  2291 HandleError(SymInfoOrErr.takeError());
 
  2295 // Check if Resolver can handle this relocation type early so as not to 
  2296 // handle invalid cases in DWARFDataExtractor. 
  2298 // TODO Don't store Resolver in every RelocAddrEntry. 
  2299 if (Supports && Supports(Reloc.getType())) {
 
  2300 auto I = Map->try_emplace(
 
  2303 SymInfoOrErr->SectionIndex, Reloc, SymInfoOrErr->Address,
 
  2304 std::optional<object::RelocationRef>(), 0, Resolver});
 
  2305 // If we didn't successfully insert that's because we already had a 
  2306 // relocation for that offset. Store it as a second relocation in the 
  2307 // same RelocAddrEntry instead. 
  2309 RelocAddrEntry &entry = I.first->getSecond();
 
  2311 HandleError(createError(
 
  2312 "At most two relocations per offset are supported"));
 
  2314 entry.Reloc2 = Reloc;
 
  2315 entry.SymbolValue2 = SymInfoOrErr->Address;
 
  2320 // FIXME: Support more relocations & change this to an error 
  2329 if (SectionAmountMap[S.Name] > 1)
 
  2330 S.IsNameUnique = 
false;
 
  2334 uint64_t Pos)
 const override {
 
  2335 auto &Sec = 
static_cast<const DWARFSectionMap &
>(S);
 
  2337 if (AI == Sec.Relocs.end())
 
  2338 return std::nullopt;
 
  2348 bool isLittleEndian()
 const override { 
return IsLittleEndian; }
 
  2349 StringRef getAbbrevDWOSection()
 const override { 
return AbbrevDWOSection; }
 
  2350 const DWARFSection &getLineDWOSection()
 const override {
 
  2351 return LineDWOSection;
 
  2353 const DWARFSection &getLocDWOSection()
 const override {
 
  2354 return LocDWOSection;
 
  2356 StringRef getStrDWOSection()
 const override { 
return StrDWOSection; }
 
  2357 const DWARFSection &getStrOffsetsDWOSection()
 const override {
 
  2358 return StrOffsetsDWOSection;
 
  2360 const DWARFSection &getRangesDWOSection()
 const override {
 
  2361 return RangesDWOSection;
 
  2363 const DWARFSection &getRnglistsDWOSection()
 const override {
 
  2364 return RnglistsDWOSection;
 
  2366 const DWARFSection &getLoclistsDWOSection()
 const override {
 
  2367 return LoclistsDWOSection;
 
  2369 const DWARFSection &getAddrSection()
 const override { 
return AddrSection; }
 
  2370 StringRef getCUIndexSection()
 const override { 
return CUIndexSection; }
 
  2371 StringRef getGdbIndexSection()
 const override { 
return GdbIndexSection; }
 
  2372 StringRef getTUIndexSection()
 const override { 
return TUIndexSection; }
 
  2375 const DWARFSection &getStrOffsetsSection()
 const override {
 
  2376 return StrOffsetsSection;
 
  2378 StringRef getLineStrSection()
 const override { 
return LineStrSection; }
 
  2380 // Sections for DWARF5 split dwarf proposal. 
  2381 void forEachInfoDWOSections(
 
  2383 for (
auto &
P : InfoDWOSections)
 
  2386 void forEachTypesDWOSections(
 
  2388 for (
auto &
P : TypesDWOSections)
 
  2392 StringRef getAbbrevSection()
 const override { 
return AbbrevSection; }
 
  2393 const DWARFSection &getLocSection()
 const override { 
return LocSection; }
 
  2394 const DWARFSection &getLoclistsSection()
 const override { 
return LoclistsSection; }
 
  2395 StringRef getArangesSection()
 const override { 
return ArangesSection; }
 
  2397 return FrameSection;
 
  2400 return EHFrameSection;
 
  2402 const DWARFSection &getLineSection()
 const override { 
return LineSection; }
 
  2403 StringRef getStrSection()
 const override { 
return StrSection; }
 
  2404 const DWARFSection &getRangesSection()
 const override { 
return RangesSection; }
 
  2405 const DWARFSection &getRnglistsSection()
 const override {
 
  2406 return RnglistsSection;
 
  2408 const DWARFSection &getMacroSection()
 const override { 
return MacroSection; }
 
  2409 StringRef getMacroDWOSection()
 const override { 
return MacroDWOSection; }
 
  2410 StringRef getMacinfoSection()
 const override { 
return MacinfoSection; }
 
  2411 StringRef getMacinfoDWOSection()
 const override { 
return MacinfoDWOSection; }
 
  2412 const DWARFSection &getPubnamesSection()
 const override { 
return PubnamesSection; }
 
  2413 const DWARFSection &getPubtypesSection()
 const override { 
return PubtypesSection; }
 
  2414 const DWARFSection &getGnuPubnamesSection()
 const override {
 
  2415 return GnuPubnamesSection;
 
  2417 const DWARFSection &getGnuPubtypesSection()
 const override {
 
  2418 return GnuPubtypesSection;
 
  2420 const DWARFSection &getAppleNamesSection()
 const override {
 
  2421 return AppleNamesSection;
 
  2423 const DWARFSection &getAppleTypesSection()
 const override {
 
  2424 return AppleTypesSection;
 
  2426 const DWARFSection &getAppleNamespacesSection()
 const override {
 
  2427 return AppleNamespacesSection;
 
  2429 const DWARFSection &getAppleObjCSection()
 const override {
 
  2430 return AppleObjCSection;
 
  2433 return NamesSection;
 
  2437 uint8_t getAddressSize()
 const override { 
return AddressSize; }
 
  2438 void forEachInfoSections(
 
  2440 for (
auto &
P : InfoSections)
 
  2443 void forEachTypesSections(
 
  2445 for (
auto &
P : TypesSections)
 
  2451std::unique_ptr<DWARFContext>
 
  2455 std::function<
void(
Error)> RecoverableErrorHandler,
 
  2456 std::function<
void(
Error)> WarningHandler,
 
  2458 auto DObj = std::make_unique<DWARFObjInMemory>(
 
  2459 Obj, L, RecoverableErrorHandler, WarningHandler, RelocAction);
 
  2460 return std::make_unique<DWARFContext>(std::move(DObj),
 
  2462 RecoverableErrorHandler,
 
 
  2467std::unique_ptr<DWARFContext>
 
  2470 std::function<
void(
Error)> RecoverableErrorHandler,
 
  2471 std::function<
void(
Error)> WarningHandler,
 
  2474 std::make_unique<DWARFObjInMemory>(Sections, AddrSize, 
isLittleEndian);
 
  2475 return std::make_unique<DWARFContext>(
 
  2476 std::move(DObj), 
"", RecoverableErrorHandler, WarningHandler, ThreadSafe);
 
 
  2480 // In theory, different compile units may have different address byte 
  2481 // sizes, but for simplicity we just use the address byte size of the 
  2482 // first compile unit. In practice the address size field is repeated across 
  2483 // various DWARF headers (at least in version 5) to make it easier to dump 
  2484 // them independently, not to enable varying the address size. 
  2486 return CUs.empty() ? 0 : (*CUs.begin())->getAddressByteSize();
 
 
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
 
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.
 
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)
 
void fixupIndex(DWARFContext &C, DWARFUnitIndex &Index)
 
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)
 
void fixupIndexV4(DWARFContext &C, DWARFUnitIndex &Index)
 
static ContributionCollection collectContributionData(DWARFContext::unit_iterator_range Units)
 
std::vector< std::optional< StrOffsetsContributionDescriptor > > ContributionCollection
 
DWARFDebugLine::LineTable DWARFLineTable
 
static bool isRelocScattered(const object::ObjectFile &Obj, const RelocationRef &Reloc)
 
static std::optional< int64_t > getExpressionFrameOffset(ArrayRef< uint8_t > Expr, std::optional< unsigned > FrameBaseReg)
 
void fixupIndexV5(DWARFContext &C, DWARFUnitIndex &Index)
 
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.
 
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first found DebugLoc that has a DILocation, given a range of instructions.
 
This file implements a map that provides insertion order iteration.
 
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.
 
DIContext(DIContextKind K)
 
A structured debug information entry.
 
dwarf::Tag getTag() const
 
A format-neutral container for inlined code description.
 
void addFrame(const DILineInfo &Frame)
 
DWARFContextState This structure contains all member variables for DWARFContext that need to be prote...
 
MacroSecType
Helper enum to distinguish between macro[.dwo] and macinfo[.dwo] section.
 
LLVM_ABI std::unique_ptr< DWARFDebugMacro > parseMacroOrMacinfo(MacroSecType SectionType)
Parse a macro[.dwo] or macinfo[.dwo] section.
 
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.
 
std::optional< DILineInfo > getLineInfoForDataAddress(object::SectionedAddress Address) override
 
DIInliningInfo getInliningInfoForAddress(object::SectionedAddress Address, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
 
Expected< const DWARFDebugFrame * > getDebugFrame()
Get a pointer to the parsed frame information object.
 
DWARFGdbIndex & getGdbIndex()
 
unsigned getNumCompileUnits()
Get the number of compile units in this context.
 
DWARFContext(std::unique_ptr< const DWARFObject > DObj, std::string DWPName="", std::function< void(Error)> RecoverableErrorHandler=WithColor::defaultErrorHandler, std::function< void(Error)> WarningHandler=WithColor::defaultWarningHandler, bool ThreadSafe=false)
 
DWARFDie getDIEForOffset(uint64_t Offset)
Get a DIE given an exact offset.
 
unsigned getNumTypeUnits()
Get the number of type units in this context.
 
DWARFUnitVector::iterator_range unit_iterator_range
 
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()
 
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
 
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 isDWP() const
Return true of this DWARF context is a DWP file.
 
bool isLittleEndian() const
 
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.
 
DWARFUnit * getUnitForOffset(uint64_t Offset)
Return the DWARF unit that includes an offset (relative to .debug_info).
 
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.
 
DWARFTypeUnit * getTypeUnitForHash(uint64_t Hash, bool IsDWO)
 
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.
 
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.
 
DIEsForAddress getDIEsForAddress(uint64_t Address, bool CheckDWO=false)
Get the compilation unit, the function DIE and lexical block DIE for the given address where applicab...
 
unit_iterator_range info_section_units()
Get units from .debug_info in this context.
 
unit_iterator_range dwo_info_section_units()
Get units from .debug_info..dwo in the DWO context.
 
const AppleAcceleratorTable & getAppleNamespaces()
Get a reference to the parsed accelerator table object.
 
const DWARFDebugMacro * getDebugMacro()
Get a pointer to the parsed DebugMacro information object.
 
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, bool ThreadSafe=false)
 
const DWARFDebugMacro * getDebugMacinfo()
Get a pointer to the parsed DebugMacinfo information object.
 
unit_iterator_range dwo_units()
Get all units in the DWO context.
 
const DWARFObject & getDWARFObj() const
 
std::optional< DILineInfo > getLineInfoForAddress(object::SectionedAddress Address, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
 
LLVM_ABI 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.
 
LLVM_ABI void dump(raw_ostream &OS) const
 
LLVM_ABI Error extract(DWARFDataExtractor data, uint64_t *offset_ptr, function_ref< void(Error)> WarningHandler=nullptr)
 
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.
 
.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.
 
LLVM_ABI void extract(DWARFDataExtractor Data, bool GnuStyle, function_ref< void(Error)> RecoverableErrorHandler)
 
LLVM_ABI void dump(raw_ostream &OS) const
 
LLVM_ABI Error extract(const DWARFDataExtractor &data, uint64_t *offset_ptr)
 
LLVM_ABI void dump(raw_ostream &OS) const
 
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
 
LLVM_ABI DWARFDie getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE as the referenced DIE.
 
LLVM_ABI std::optional< DWARFFormValue > find(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE.
 
DWARFUnit * getDwarfUnit() const
 
LLVM_ABI const char * getSubroutineName(DINameKind Kind) const
If a DIE represents a subprogram (or inlined subroutine), returns its mangled name (or short name,...
 
LLVM_ABI 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...
 
LLVM_ABI std::string getDeclFile(DILineInfoSpecifier::FileLineInfoKind Kind) const
 
LLVM_ABI uint64_t getDeclLine() const
Returns the declaration line (start line) for a DIE, assuming it specifies a subprogram.
 
dwarf::Tag getTag() const
 
LLVM_ABI Expected< DWARFLocationExpressionsVector > getLocations(dwarf::Attribute Attr) const
 
LLVM_ABI void dump(raw_ostream &OS, unsigned indent=0, DIDumpOptions DumpOpts=DIDumpOptions()) const
Dump the DIE and all of its attributes to the supplied stream.
 
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
 
virtual StringRef getFileName() const
 
virtual StringRef getAbbrevDWOSection() const
 
virtual const DWARFSection & getFrameSection() const
 
virtual const DWARFSection & getNamesSection() const
 
virtual const DWARFSection & getAppleNamespacesSection() const
 
virtual void forEachInfoDWOSections(function_ref< void(const DWARFSection &)> F) const
 
virtual const DWARFSection & getAppleTypesSection() const
 
virtual void forEachInfoSections(function_ref< void(const DWARFSection &)> F) const
 
virtual const DWARFSection & getAppleNamesSection() const
 
virtual const DWARFSection & getEHFrameSection() const
 
virtual void forEachTypesSections(function_ref< void(const DWARFSection &)> F) const
 
virtual const DWARFSection & getLocSection() const
 
virtual const DWARFSection & getAppleObjCSection() const
 
virtual void forEachTypesDWOSections(function_ref< void(const DWARFSection &)> F) const
 
virtual StringRef getStrSection() const
 
virtual uint8_t getAddressSize() const
 
void setOffset(uint64_t Value)
 
uint64_t getOffset() const
 
LLVM_ABI 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 ....
 
LLVM_ABI DWARFUnit * getUnitForIndexEntry(const DWARFUnitIndex::Entry &E, DWARFSectionKind Sec, const DWARFSection *Section=nullptr)
Returns the Unit from the .debug_info or .debug_types section by the index entry.
 
LLVM_ABI void addUnitsForSection(DWARFContext &C, const DWARFSection &Section, DWARFSectionKind SectionKind)
Read units from a .debug_info or .debug_types section.
 
LLVM_ABI void addUnitsForDWOSection(DWARFContext &C, const DWARFSection &DWOSection, DWARFSectionKind SectionKind, bool Lazy=false)
Read units from a .debug_info.dwo or .debug_types.dwo section.
 
DWARFContext & getContext() const
 
DWARFDie getDIEForOffset(uint64_t Offset)
Return the DIE object for a given offset Offset inside the unit's DIE vector.
 
const char * getCompilationDir()
 
DWARFDie getSubroutineForAddress(uint64_t Address)
Returns subprogram DIE with address range encompassing the provided address.
 
A class that verifies DWARF debug information given a DWARF Context.
 
LLVM_ABI bool handleAccelTables()
Verify the information in accelerator tables, if they exist.
 
LLVM_ABI bool handleDebugTUIndex()
Verify the information in the .debug_tu_index section.
 
LLVM_ABI bool handleDebugStrOffsets()
Verify the information in the .debug_str_offsets[.dwo].
 
LLVM_ABI bool handleDebugCUIndex()
Verify the information in the .debug_cu_index section.
 
LLVM_ABI bool handleDebugInfo()
Verify the information in the .debug_info and .debug_types sections.
 
LLVM_ABI bool handleDebugLine()
Verify the information in the .debug_line section.
 
LLVM_ABI void summarize()
Emits any aggregate information collected, depending on the dump options.
 
LLVM_ABI bool handleDebugAbbrev()
Verify the information in any of the following sections, if available: .debug_abbrev,...
 
LLVM_ABI DILocation * get() const
Get the underlying DILocation.
 
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT, true > const_iterator
 
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...
 
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 size_t size() const
size - Get the string size.
 
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(uint64_t Val)
 
The instances of the Type class are immutable: once they are created, they are never changed.
 
static LLVM_ABI void defaultWarningHandler(Error Warning)
Implement default handling for Warning.
 
static LLVM_ABI void defaultErrorHandler(Error Err)
Implement default handling for Error.
 
An efficient, type-erasing, non-owning reference to a callable.
 
static LLVM_ABI 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...
 
uint64_t getIndex() const
 
bool isCompressed() const
 
uint64_t getAddress() const
 
Expected< StringRef > getName() 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.
 
LLVM_ABI 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.
 
static constexpr StringLiteral SectionNames[SectionKindsNum]
 
Calculates the starting offsets for various sections within the .debug_names section.
 
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.
 
LLVM_ABI Section * getEHFrameSection(LinkGraph &G)
Returns a pointer to the DWARF eh-frame section if the graph contains a non-empty one,...
 
content_iterator< SectionRef > section_iterator
 
Error createError(const Twine &Err)
 
uint64_t(*)(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t Addend) RelocationResolver
 
LLVM_ABI std::pair< SupportsRelocation, RelocationResolver > getRelocationResolver(const ObjectFile &Obj)
 
bool(*)(uint64_t) SupportsRelocation
 
LLVM_ABI StringRef extension(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get extension.
 
SmartMutex< false > Mutex
Mutex - A standard, always enforced mutex.
 
This is an optimization pass for GlobalISel generic memory operations.
 
LLVM_ABI 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.
 
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
 
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
 
SmallVector< std::pair< uint64_t, DILineInfo >, 16 > DILineInfoTable
 
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
 
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.
 
auto unique(Range &&R, Predicate P)
 
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
 
auto dyn_cast_or_null(const Y &Val)
 
void sort(IteratorTy Start, IteratorTy End)
 
static Error createError(const Twine &Err)
 
FunctionAddr VTableAddr Count
 
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
 
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
 
@ Success
The lock was released successfully.
 
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
 
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
 
FunctionAddr VTableAddr uintptr_t uintptr_t Data
 
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
 
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
 
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
 
DenseMap< uint64_t, RelocAddrEntry > RelocAddrMap
In place of applying the relocations to the data we've read from disk we use a separate mapping table...
 
void consumeError(Error Err)
Consume a Error without doing anything.
 
Implement std::hash so that hash_code can be used in STL containers.
 
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.
 
LLVM_ABI bool getFileLineInfoForAddress(object::SectionedAddress Address, bool Approximate, 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.
 
LLVM_ABI bool lookupAddressRange(object::SectionedAddress Address, uint64_t Size, std::vector< uint32_t > &Result, std::optional< uint64_t > StmtSequenceOffset=std::nullopt) const
Fills the Result argument with the indices of the rows that correspond to the address range specified...
 
Standard .debug_line state machine structure.