LLVM 24.0.0git
DWARFContext.cpp
Go to the documentation of this file.
1//===- DWARFContext.cpp ---------------------------------------------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
10#include "llvm/ADT/MapVector.h"
11#include "llvm/ADT/STLExtras.h"
14#include "llvm/ADT/StringRef.h"
43#include "llvm/Object/MachO.h"
48#include "llvm/Support/Error.h"
51#include "llvm/Support/LEB128.h"
53#include "llvm/Support/Path.h"
55#include <cstdint>
56#include <deque>
57#include <map>
58#include <string>
59#include <utility>
60#include <vector>
61
62using namespace llvm;
63using namespace dwarf;
64using namespace object;
65
66#define DEBUG_TYPE "dwarf"
67
69using FileLineInfoKind = DILineInfoSpecifier::FileLineInfoKind;
70using FunctionNameKind = DILineInfoSpecifier::FunctionNameKind;
71
72
75 using EntryMap = DenseMap<uint32_t, EntryType>;
76 EntryMap Map;
77 const auto &DObj = C.getDWARFObj();
78 if (DObj.getCUIndexSection().empty())
79 return;
80
81 uint64_t Offset = 0;
82 uint32_t TruncOffset = 0;
83 DObj.forEachInfoDWOSections([&](const DWARFSection &S) {
84 if (!(C.getParseCUTUIndexManually() ||
85 S.Data.size() >= std::numeric_limits<uint32_t>::max()))
86 return;
87
88 DWARFDataExtractor Data(DObj, S, C.isLittleEndian(), 0);
89 while (Data.isValidOffset(Offset)) {
90 DWARFUnitHeader Header;
91 if (Error ExtractionErr = Header.extract(
92 C, Data, &Offset, DWARFSectionKind::DW_SECT_INFO)) {
93 C.getWarningHandler()(
94 createError("Failed to parse CU header in DWP file: " +
95 toString(std::move(ExtractionErr))));
96 Map.clear();
97 break;
98 }
99
100 auto Iter = Map.insert({TruncOffset,
101 {Header.getOffset(), Header.getNextUnitOffset() -
102 Header.getOffset()}});
103 if (!Iter.second) {
105 createError("Collision occurred between for truncated offset 0x" +
106 Twine::utohexstr(TruncOffset)),
107 errs());
108 Map.clear();
109 return;
110 }
111
112 Offset = Header.getNextUnitOffset();
113 TruncOffset = Offset;
114 }
115 });
116
117 if (Map.empty())
118 return;
119
120 for (DWARFUnitIndex::Entry &E : Index.getMutableRows()) {
121 if (!E.isValid())
122 continue;
123 DWARFUnitIndex::Entry::SectionContribution &CUOff = E.getContribution();
124 auto Iter = Map.find(CUOff.getOffset());
125 if (Iter == Map.end()) {
126 logAllUnhandledErrors(createError("Could not find CU offset 0x" +
127 Twine::utohexstr(CUOff.getOffset()) +
128 " in the Map"),
129 errs());
130 break;
131 }
132 CUOff.setOffset(Iter->second.getOffset());
133 if (CUOff.getOffset() != Iter->second.getOffset())
134 logAllUnhandledErrors(createError("Length of CU in CU index doesn't "
135 "match calculated length at offset 0x" +
136 Twine::utohexstr(CUOff.getOffset())),
137 errs());
138 }
139}
140
143
144 const auto &DObj = C.getDWARFObj();
145 DObj.forEachInfoDWOSections([&](const DWARFSection &S) {
146 if (!(C.getParseCUTUIndexManually() ||
147 S.Data.size() >= std::numeric_limits<uint32_t>::max()))
148 return;
149 DWARFDataExtractor Data(DObj, S, C.isLittleEndian(), 0);
150 uint64_t Offset = 0;
151 while (Data.isValidOffset(Offset)) {
152 DWARFUnitHeader Header;
153 if (Error ExtractionErr = Header.extract(
154 C, Data, &Offset, DWARFSectionKind::DW_SECT_INFO)) {
155 C.getWarningHandler()(
156 createError("Failed to parse CU header in DWP file: " +
157 toString(std::move(ExtractionErr))));
158 break;
159 }
160 bool CU = Header.getUnitType() == DW_UT_split_compile;
161 uint64_t Sig = CU ? *Header.getDWOId() : Header.getTypeHash();
162 Map[Sig] = Header.getOffset();
163 Offset = Header.getNextUnitOffset();
164 }
165 });
166 if (Map.empty())
167 return;
168 for (DWARFUnitIndex::Entry &E : Index.getMutableRows()) {
169 if (!E.isValid())
170 continue;
171 DWARFUnitIndex::Entry::SectionContribution &CUOff = E.getContribution();
172 auto Iter = Map.find(E.getSignature());
173 if (Iter == Map.end()) {
175 createError("Could not find unit with signature 0x" +
176 Twine::utohexstr(E.getSignature()) + " in the Map"),
177 errs());
178 break;
179 }
180 CUOff.setOffset(Iter->second);
181 }
182}
183
185 if (Index.getVersion() < 5)
187 else
189}
190
191template <typename T>
192static T &getAccelTable(std::unique_ptr<T> &Cache, const DWARFObject &Obj,
193 const DWARFSection &Section, StringRef StringSection,
194 bool IsLittleEndian) {
195 if (Cache)
196 return *Cache;
197 DWARFDataExtractor AccelSection(Obj, Section, IsLittleEndian, 0);
198 DataExtractor StrData(StringSection, IsLittleEndian);
199 Cache = std::make_unique<T>(AccelSection, StrData);
200 if (Error E = Cache->extract())
201 llvm::consumeError(std::move(E));
202 return *Cache;
203}
204
205
206std::unique_ptr<DWARFDebugMacro>
208 auto Macro = std::make_unique<DWARFDebugMacro>();
209 auto ParseAndDump = [&](DWARFDataExtractor &Data, bool IsMacro) {
210 if (Error Err = IsMacro ? Macro->parseMacro(SectionType == MacroSection
211 ? D.compile_units()
212 : D.dwo_compile_units(),
213 SectionType == MacroSection
214 ? D.getStringExtractor()
215 : D.getStringDWOExtractor(),
216 Data)
217 : Macro->parseMacinfo(Data)) {
218 D.getRecoverableErrorHandler()(std::move(Err));
219 Macro = nullptr;
220 }
221 };
222 const DWARFObject &DObj = D.getDWARFObj();
223 switch (SectionType) {
224 case MacinfoSection: {
225 DWARFDataExtractor Data(DObj.getMacinfoSection(), D.isLittleEndian(), 0);
226 ParseAndDump(Data, /*IsMacro=*/false);
227 break;
228 }
229 case MacinfoDwoSection: {
230 DWARFDataExtractor Data(DObj.getMacinfoDWOSection(), D.isLittleEndian(), 0);
231 ParseAndDump(Data, /*IsMacro=*/false);
232 break;
233 }
234 case MacroSection: {
235 DWARFDataExtractor Data(DObj, DObj.getMacroSection(), D.isLittleEndian(),
236 0);
237 ParseAndDump(Data, /*IsMacro=*/true);
238 break;
239 }
240 case MacroDwoSection: {
241 DWARFDataExtractor Data(DObj.getMacroDWOSection(), D.isLittleEndian(), 0);
242 ParseAndDump(Data, /*IsMacro=*/true);
243 break;
244 }
245 }
246 return Macro;
247}
248
249namespace {
250class ThreadUnsafeDWARFContextState : public DWARFContext::DWARFContextState {
251
252 DWARFUnitVector NormalUnits;
253 std::optional<DenseMap<uint64_t, DWARFTypeUnit *>> NormalTypeUnits;
254 std::unique_ptr<DWARFUnitIndex> CUIndex;
255 std::unique_ptr<DWARFGdbIndex> GdbIndex;
256 std::unique_ptr<DWARFUnitIndex> TUIndex;
257 std::unique_ptr<DWARFDebugAbbrev> Abbrev;
258 std::unique_ptr<DWARFDebugLoc> Loc;
259 std::unique_ptr<DWARFDebugAranges> Aranges;
260 std::unique_ptr<DWARFDebugLine> Line;
261 std::unique_ptr<DWARFDebugFrame> DebugFrame;
262 std::unique_ptr<DWARFDebugFrame> EHFrame;
263 std::unique_ptr<DWARFDebugMacro> Macro;
264 std::unique_ptr<DWARFDebugMacro> Macinfo;
265 std::unique_ptr<DWARFDebugNames> Names;
266 std::unique_ptr<AppleAcceleratorTable> AppleNames;
267 std::unique_ptr<AppleAcceleratorTable> AppleTypes;
268 std::unique_ptr<AppleAcceleratorTable> AppleNamespaces;
269 std::unique_ptr<AppleAcceleratorTable> AppleObjC;
270 DWARFUnitVector DWOUnits;
271 std::optional<DenseMap<uint64_t, DWARFTypeUnit *>> DWOTypeUnits;
272 std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
273 std::unique_ptr<DWARFDebugMacro> MacinfoDWO;
274 std::unique_ptr<DWARFDebugMacro> MacroDWO;
275 struct DWOFile {
277 std::unique_ptr<DWARFContext> Context;
278 };
280 std::weak_ptr<DWOFile> DWP;
281 bool CheckedForDWP = false;
282 std::string DWPName;
283
284public:
285 ThreadUnsafeDWARFContextState(DWARFContext &DC, std::string &DWP) :
286 DWARFContext::DWARFContextState(DC),
287 DWPName(std::move(DWP)) {}
288
289 DWARFUnitVector &getNormalUnits() override {
290 if (NormalUnits.empty()) {
291 const DWARFObject &DObj = D.getDWARFObj();
292 DObj.forEachInfoSections([&](const DWARFSection &S) {
293 NormalUnits.addUnitsForSection(D, S, DW_SECT_INFO);
294 });
295 NormalUnits.finishedInfoUnits();
296 DObj.forEachTypesSections([&](const DWARFSection &S) {
297 NormalUnits.addUnitsForSection(D, S, DW_SECT_EXT_TYPES);
298 });
299 }
300 return NormalUnits;
301 }
302
303 DWARFUnitVector &getDWOUnits(bool Lazy) override {
304 if (DWOUnits.empty()) {
305 const DWARFObject &DObj = D.getDWARFObj();
306
307 DObj.forEachInfoDWOSections([&](const DWARFSection &S) {
308 DWOUnits.addUnitsForDWOSection(D, S, DW_SECT_INFO, Lazy);
309 });
310 DWOUnits.finishedInfoUnits();
311 DObj.forEachTypesDWOSections([&](const DWARFSection &S) {
312 DWOUnits.addUnitsForDWOSection(D, S, DW_SECT_EXT_TYPES, Lazy);
313 });
314 }
315 return DWOUnits;
316 }
317
318 const DWARFDebugAbbrev *getDebugAbbrevDWO() override {
319 if (AbbrevDWO)
320 return AbbrevDWO.get();
321 const DWARFObject &DObj = D.getDWARFObj();
322 DataExtractor abbrData(DObj.getAbbrevDWOSection(), D.isLittleEndian());
323 AbbrevDWO = std::make_unique<DWARFDebugAbbrev>(abbrData);
324 return AbbrevDWO.get();
325 }
326
327 const DWARFUnitIndex &getCUIndex() override {
328 if (CUIndex)
329 return *CUIndex;
330
331 DataExtractor Data(D.getDWARFObj().getCUIndexSection(), D.isLittleEndian());
332 CUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_INFO);
333 if (CUIndex->parse(Data))
334 fixupIndex(D, *CUIndex);
335 return *CUIndex;
336 }
337 const DWARFUnitIndex &getTUIndex() override {
338 if (TUIndex)
339 return *TUIndex;
340
341 DataExtractor Data(D.getDWARFObj().getTUIndexSection(), D.isLittleEndian());
342 TUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_EXT_TYPES);
343 bool isParseSuccessful = TUIndex->parse(Data);
344 // If we are parsing TU-index and for .debug_types section we don't need
345 // to do anything.
346 if (isParseSuccessful && TUIndex->getVersion() != 2)
347 fixupIndex(D, *TUIndex);
348 return *TUIndex;
349 }
350
351 DWARFGdbIndex &getGdbIndex() override {
352 if (GdbIndex)
353 return *GdbIndex;
354
355 DataExtractor Data(D.getDWARFObj().getGdbIndexSection(),
356 /*IsLittleEndian=*/true);
357 GdbIndex = std::make_unique<DWARFGdbIndex>();
358 GdbIndex->parse(Data);
359 return *GdbIndex;
360 }
361
362 const DWARFDebugAbbrev *getDebugAbbrev() override {
363 if (Abbrev)
364 return Abbrev.get();
365
366 DataExtractor Data(D.getDWARFObj().getAbbrevSection(), D.isLittleEndian());
367 Abbrev = std::make_unique<DWARFDebugAbbrev>(Data);
368 return Abbrev.get();
369 }
370
371 const DWARFDebugLoc *getDebugLoc() override {
372 if (Loc)
373 return Loc.get();
374
375 const DWARFObject &DObj = D.getDWARFObj();
376 // Assume all units have the same address byte size.
377 auto Data =
378 D.getNumCompileUnits()
379 ? DWARFDataExtractor(DObj, DObj.getLocSection(), D.isLittleEndian(),
380 D.getUnitAtIndex(0)->getAddressByteSize())
381 : DWARFDataExtractor("", D.isLittleEndian(), 0);
382 Loc = std::make_unique<DWARFDebugLoc>(std::move(Data));
383 return Loc.get();
384 }
385
386 const DWARFDebugAranges *getDebugAranges() override {
387 if (Aranges)
388 return Aranges.get();
389
390 Aranges = std::make_unique<DWARFDebugAranges>();
391 Aranges->generate(&D);
392 return Aranges.get();
393 }
394
395 Expected<const DWARFDebugLine::LineTable *>
396 getLineTableForUnit(DWARFUnit *U, function_ref<void(Error)> RecoverableErrorHandler) override {
397 if (!Line)
398 Line = std::make_unique<DWARFDebugLine>();
399
400 auto UnitDIE = U->getUnitDIE();
401 if (!UnitDIE)
402 return nullptr;
403
404 auto Offset = toSectionOffset(UnitDIE.find(DW_AT_stmt_list));
405 if (!Offset)
406 return nullptr; // No line table for this compile unit.
407
408 uint64_t stmtOffset = *Offset + U->getLineTableOffset();
409 // See if the line table is cached.
410 if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
411 return lt;
412
413 // Make sure the offset is good before we try to parse.
414 if (stmtOffset >= U->getLineSection().Data.size())
415 return nullptr;
416
417 // We have to parse it first.
418 DWARFDataExtractor Data(U->getContext().getDWARFObj(), U->getLineSection(),
419 U->isLittleEndian(), U->getAddressByteSize());
420 return Line->getOrParseLineTable(Data, stmtOffset, U->getContext(), U,
421 RecoverableErrorHandler);
422
423 }
424
425 void clearLineTableForUnit(DWARFUnit *U) override {
426 if (!Line)
427 return;
428
429 auto UnitDIE = U->getUnitDIE();
430 if (!UnitDIE)
431 return;
432
433 auto Offset = toSectionOffset(UnitDIE.find(DW_AT_stmt_list));
434 if (!Offset)
435 return;
436
437 uint64_t stmtOffset = *Offset + U->getLineTableOffset();
438 Line->clearLineTable(stmtOffset);
439 }
440
441 Expected<const DWARFDebugFrame *> getDebugFrame() override {
442 if (DebugFrame)
443 return DebugFrame.get();
444 const DWARFObject &DObj = D.getDWARFObj();
445 const DWARFSection &DS = DObj.getFrameSection();
446
447 // There's a "bug" in the DWARFv3 standard with respect to the target address
448 // size within debug frame sections. While DWARF is supposed to be independent
449 // of its container, FDEs have fields with size being "target address size",
450 // which isn't specified in DWARF in general. It's only specified for CUs, but
451 // .eh_frame can appear without a .debug_info section. Follow the example of
452 // other tools (libdwarf) and extract this from the container (ObjectFile
453 // provides this information). This problem is fixed in DWARFv4
454 // See this dwarf-discuss discussion for more details:
455 // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
456 DWARFDataExtractor Data(DObj, DS, D.isLittleEndian(),
457 DObj.getAddressSize());
458 auto DF =
459 std::make_unique<DWARFDebugFrame>(D.getArch(), /*IsEH=*/false,
460 DS.Address);
461 if (Error E = DF->parse(Data))
462 return std::move(E);
463
464 DebugFrame.swap(DF);
465 return DebugFrame.get();
466 }
467
468 Expected<const DWARFDebugFrame *> getEHFrame() override {
469 if (EHFrame)
470 return EHFrame.get();
471 const DWARFObject &DObj = D.getDWARFObj();
472
473 const DWARFSection &DS = DObj.getEHFrameSection();
474 DWARFDataExtractor Data(DObj, DS, D.isLittleEndian(),
475 DObj.getAddressSize());
476 auto DF =
477 std::make_unique<DWARFDebugFrame>(D.getArch(), /*IsEH=*/true,
478 DS.Address);
479 if (Error E = DF->parse(Data))
480 return std::move(E);
481 EHFrame.swap(DF);
482 return EHFrame.get();
483 }
484
485 const DWARFDebugMacro *getDebugMacinfo() override {
486 if (!Macinfo)
487 Macinfo = parseMacroOrMacinfo(MacinfoSection);
488 return Macinfo.get();
489 }
490 const DWARFDebugMacro *getDebugMacinfoDWO() override {
491 if (!MacinfoDWO)
492 MacinfoDWO = parseMacroOrMacinfo(MacinfoDwoSection);
493 return MacinfoDWO.get();
494 }
495 const DWARFDebugMacro *getDebugMacro() override {
496 if (!Macro)
497 Macro = parseMacroOrMacinfo(MacroSection);
498 return Macro.get();
499 }
500 const DWARFDebugMacro *getDebugMacroDWO() override {
501 if (!MacroDWO)
502 MacroDWO = parseMacroOrMacinfo(MacroDwoSection);
503 return MacroDWO.get();
504 }
505 const DWARFDebugNames &getDebugNames() override {
506 const DWARFObject &DObj = D.getDWARFObj();
507 return getAccelTable(Names, DObj, DObj.getNamesSection(),
508 DObj.getStrSection(), D.isLittleEndian());
509 }
510 const AppleAcceleratorTable &getAppleNames() override {
511 const DWARFObject &DObj = D.getDWARFObj();
512 return getAccelTable(AppleNames, DObj, DObj.getAppleNamesSection(),
513 DObj.getStrSection(), D.isLittleEndian());
514
515 }
516 const AppleAcceleratorTable &getAppleTypes() override {
517 const DWARFObject &DObj = D.getDWARFObj();
518 return getAccelTable(AppleTypes, DObj, DObj.getAppleTypesSection(),
519 DObj.getStrSection(), D.isLittleEndian());
520
521 }
522 const AppleAcceleratorTable &getAppleNamespaces() override {
523 const DWARFObject &DObj = D.getDWARFObj();
524 return getAccelTable(AppleNamespaces, DObj,
526 DObj.getStrSection(), D.isLittleEndian());
527
528 }
529 const AppleAcceleratorTable &getAppleObjC() override {
530 const DWARFObject &DObj = D.getDWARFObj();
531 return getAccelTable(AppleObjC, DObj, DObj.getAppleObjCSection(),
532 DObj.getStrSection(), D.isLittleEndian());
533 }
534
535 std::shared_ptr<DWARFContext>
536 getDWOContext(StringRef AbsolutePath) override {
537 if (auto S = DWP.lock()) {
538 DWARFContext *Ctxt = S->Context.get();
539 return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
540 }
541
542 std::weak_ptr<DWOFile> *Entry = &DWOFiles[AbsolutePath];
543
544 if (auto S = Entry->lock()) {
545 DWARFContext *Ctxt = S->Context.get();
546 return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
547 }
548
549 const DWARFObject &DObj = D.getDWARFObj();
550
551 Expected<OwningBinary<ObjectFile>> Obj = [&] {
552 if (!CheckedForDWP) {
553 SmallString<128> DWPName;
555 this->DWPName.empty()
556 ? (DObj.getFileName() + ".dwp").toStringRef(DWPName)
557 : StringRef(this->DWPName));
558 if (Obj) {
559 Entry = &DWP;
560 return Obj;
561 } else {
562 CheckedForDWP = true;
563 // TODO: Should this error be handled (maybe in a high verbosity mode)
564 // before falling back to .dwo files?
565 consumeError(Obj.takeError());
566 }
567 }
568
569 return object::ObjectFile::createObjectFile(AbsolutePath);
570 }();
571
572 if (!Obj) {
573 // TODO: Actually report errors helpfully.
574 consumeError(Obj.takeError());
575 return nullptr;
576 }
577
578 auto S = std::make_shared<DWOFile>();
579 S->File = std::move(Obj.get());
580 // Allow multi-threaded access if there is a .dwp file as the CU index and
581 // TU index might be accessed from multiple threads.
582 bool ThreadSafe = isThreadSafe();
583 S->Context = DWARFContext::create(
584 *S->File.getBinary(), DWARFContext::ProcessDebugRelocations::Ignore,
587 *Entry = S;
588 auto *Ctxt = S->Context.get();
589 return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
590 }
591
592 bool isThreadSafe() const override { return false; }
593
594 const DenseMap<uint64_t, DWARFTypeUnit *> &getNormalTypeUnitMap() {
595 if (!NormalTypeUnits) {
596 NormalTypeUnits.emplace();
597 for (const auto &U :D.normal_units()) {
598 if (DWARFTypeUnit *TU = dyn_cast<DWARFTypeUnit>(U.get()))
599 (*NormalTypeUnits)[TU->getTypeHash()] = TU;
600 }
601 }
602 return *NormalTypeUnits;
603 }
604
605 const DenseMap<uint64_t, DWARFTypeUnit *> &getDWOTypeUnitMap() {
606 if (!DWOTypeUnits) {
607 DWOTypeUnits.emplace();
608 for (const auto &U :D.dwo_units()) {
609 if (DWARFTypeUnit *TU = dyn_cast<DWARFTypeUnit>(U.get()))
610 (*DWOTypeUnits)[TU->getTypeHash()] = TU;
611 }
612 }
613 return *DWOTypeUnits;
614 }
615
616 const DenseMap<uint64_t, DWARFTypeUnit *> &
617 getTypeUnitMap(bool IsDWO) override {
618 if (IsDWO)
619 return getDWOTypeUnitMap();
620 else
621 return getNormalTypeUnitMap();
622 }
623};
624
625class ThreadSafeState : public ThreadUnsafeDWARFContextState {
626 std::recursive_mutex Mutex;
627
628public:
629 ThreadSafeState(DWARFContext &DC, std::string &DWP) :
630 ThreadUnsafeDWARFContextState(DC, DWP) {}
631
632 DWARFUnitVector &getNormalUnits() override {
633 std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
634 return ThreadUnsafeDWARFContextState::getNormalUnits();
635 }
636 DWARFUnitVector &getDWOUnits(bool Lazy) override {
637 std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
638 // We need to not do lazy parsing when we need thread safety as
639 // DWARFUnitVector, in lazy mode, will slowly add things to itself and
640 // will cause problems in a multi-threaded environment.
641 return ThreadUnsafeDWARFContextState::getDWOUnits(false);
642 }
643 const DWARFUnitIndex &getCUIndex() override {
644 std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
645 return ThreadUnsafeDWARFContextState::getCUIndex();
646 }
647 const DWARFDebugAbbrev *getDebugAbbrevDWO() override {
648 std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
649 return ThreadUnsafeDWARFContextState::getDebugAbbrevDWO();
650 }
651
652 const DWARFUnitIndex &getTUIndex() override {
653 std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
654 return ThreadUnsafeDWARFContextState::getTUIndex();
655 }
656 DWARFGdbIndex &getGdbIndex() override {
657 std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
658 return ThreadUnsafeDWARFContextState::getGdbIndex();
659 }
660 const DWARFDebugAbbrev *getDebugAbbrev() override {
661 std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
662 return ThreadUnsafeDWARFContextState::getDebugAbbrev();
663 }
664 const DWARFDebugLoc *getDebugLoc() override {
665 std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
666 return ThreadUnsafeDWARFContextState::getDebugLoc();
667 }
668 const DWARFDebugAranges *getDebugAranges() override {
669 std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
670 return ThreadUnsafeDWARFContextState::getDebugAranges();
671 }
672 Expected<const DWARFDebugLine::LineTable *>
673 getLineTableForUnit(DWARFUnit *U, function_ref<void(Error)> RecoverableErrorHandler) override {
674 std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
675 return ThreadUnsafeDWARFContextState::getLineTableForUnit(U, RecoverableErrorHandler);
676 }
677 void clearLineTableForUnit(DWARFUnit *U) override {
678 std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
679 return ThreadUnsafeDWARFContextState::clearLineTableForUnit(U);
680 }
681 Expected<const DWARFDebugFrame *> getDebugFrame() override {
682 std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
683 return ThreadUnsafeDWARFContextState::getDebugFrame();
684 }
685 Expected<const DWARFDebugFrame *> getEHFrame() override {
686 std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
687 return ThreadUnsafeDWARFContextState::getEHFrame();
688 }
689 const DWARFDebugMacro *getDebugMacinfo() override {
690 std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
691 return ThreadUnsafeDWARFContextState::getDebugMacinfo();
692 }
693 const DWARFDebugMacro *getDebugMacinfoDWO() override {
694 std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
695 return ThreadUnsafeDWARFContextState::getDebugMacinfoDWO();
696 }
697 const DWARFDebugMacro *getDebugMacro() override {
698 std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
699 return ThreadUnsafeDWARFContextState::getDebugMacro();
700 }
701 const DWARFDebugMacro *getDebugMacroDWO() override {
702 std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
703 return ThreadUnsafeDWARFContextState::getDebugMacroDWO();
704 }
705 const DWARFDebugNames &getDebugNames() override {
706 std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
707 return ThreadUnsafeDWARFContextState::getDebugNames();
708 }
709 const AppleAcceleratorTable &getAppleNames() override {
710 std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
711 return ThreadUnsafeDWARFContextState::getAppleNames();
712 }
713 const AppleAcceleratorTable &getAppleTypes() override {
714 std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
715 return ThreadUnsafeDWARFContextState::getAppleTypes();
716 }
717 const AppleAcceleratorTable &getAppleNamespaces() override {
718 std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
719 return ThreadUnsafeDWARFContextState::getAppleNamespaces();
720 }
721 const AppleAcceleratorTable &getAppleObjC() override {
722 std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
723 return ThreadUnsafeDWARFContextState::getAppleObjC();
724 }
725 std::shared_ptr<DWARFContext>
726 getDWOContext(StringRef AbsolutePath) override {
727 std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
728 return ThreadUnsafeDWARFContextState::getDWOContext(AbsolutePath);
729 }
730
731 bool isThreadSafe() const override { return true; }
732
733 const DenseMap<uint64_t, DWARFTypeUnit *> &
734 getTypeUnitMap(bool IsDWO) override {
735 std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
736 return ThreadUnsafeDWARFContextState::getTypeUnitMap(IsDWO);
737 }
738};
739} // namespace
740
741DWARFContext::DWARFContext(std::unique_ptr<const DWARFObject> DObj,
742 std::string DWPName,
743 std::function<void(Error)> RecoverableErrorHandler,
744 std::function<void(Error)> WarningHandler,
745 bool ThreadSafe)
747 RecoverableErrorHandler(RecoverableErrorHandler),
748 WarningHandler(WarningHandler), DObj(std::move(DObj)) {
749 if (ThreadSafe)
750 State = std::make_unique<ThreadSafeState>(*this, DWPName);
751 else
752 State = std::make_unique<ThreadUnsafeDWARFContextState>(*this, DWPName);
753 }
754
756
757/// Dump the UUID load command.
758static void dumpUUID(raw_ostream &OS, const ObjectFile &Obj) {
759 auto *MachO = dyn_cast<MachOObjectFile>(&Obj);
760 if (!MachO)
761 return;
762 for (auto LC : MachO->load_commands()) {
764 if (LC.C.cmd == MachO::LC_UUID) {
765 if (LC.C.cmdsize < sizeof(UUID) + sizeof(LC.C)) {
766 OS << "error: UUID load command is too short.\n";
767 return;
768 }
769 OS << "UUID: ";
770 memcpy(&UUID, LC.Ptr+sizeof(LC.C), sizeof(UUID));
771 OS.write_uuid(UUID);
772 Triple T = MachO->getArchTriple();
773 OS << " (" << T.getArchName() << ')';
774 OS << ' ' << MachO->getFileName() << '\n';
775 }
776 }
777}
778
780 std::vector<std::optional<StrOffsetsContributionDescriptor>>;
781
782// Collect all the contributions to the string offsets table from all units,
783// sort them by their starting offsets and remove duplicates.
786 ContributionCollection Contributions;
787 for (const auto &U : Units)
788 if (const auto &C = U->getStringOffsetsTableContribution())
789 Contributions.push_back(C);
790 // Sort the contributions so that any invalid ones are placed at
791 // the start of the contributions vector. This way they are reported
792 // first.
793 llvm::sort(Contributions,
794 [](const std::optional<StrOffsetsContributionDescriptor> &L,
795 const std::optional<StrOffsetsContributionDescriptor> &R) {
796 if (L && R)
797 return L->Base < R->Base;
798 return R.has_value();
799 });
800
801 // Uniquify contributions, as it is possible that units (specifically
802 // type units in dwo or dwp files) share contributions. We don't want
803 // to report them more than once.
804 Contributions.erase(
806 Contributions,
807 [](const std::optional<StrOffsetsContributionDescriptor> &L,
808 const std::optional<StrOffsetsContributionDescriptor> &R) {
809 if (L && R)
810 return L->Base == R->Base && L->Size == R->Size;
811 return false;
812 }),
813 Contributions.end());
814 return Contributions;
815}
816
817// Dump a DWARF string offsets section. This may be a DWARF v5 formatted
818// string offsets section, where each compile or type unit contributes a
819// number of entries (string offsets), with each contribution preceded by
820// a header containing size and version number. Alternatively, it may be a
821// monolithic series of string offsets, as generated by the pre-DWARF v5
822// implementation of split DWARF; however, in that case we still need to
823// collect contributions of units because the size of the offsets (4 or 8
824// bytes) depends on the format of the referencing unit (DWARF32 or DWARF64).
827 const DWARFObject &Obj,
828 const DWARFSection &StringOffsetsSection,
829 StringRef StringSection,
831 bool LittleEndian) {
832 auto Contributions = collectContributionData(Units);
833 DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0);
834 DataExtractor StrData(StringSection, LittleEndian);
835 uint64_t SectionSize = StringOffsetsSection.Data.size();
836 uint64_t Offset = 0;
837 for (auto &Contribution : Contributions) {
838 // Report an ill-formed contribution.
839 if (!Contribution) {
840 OS << "error: invalid contribution to string offsets table in section ."
841 << SectionName << ".\n";
842 return;
843 }
844
845 dwarf::DwarfFormat Format = Contribution->getFormat();
846 int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(Format);
847 uint16_t Version = Contribution->getVersion();
848 uint64_t ContributionHeader = Contribution->Base;
849 // In DWARF v5 there is a contribution header that immediately precedes
850 // the string offsets base (the location we have previously retrieved from
851 // the CU DIE's DW_AT_str_offsets attribute). The header is located either
852 // 8 or 16 bytes before the base, depending on the contribution's format.
853 if (Version >= 5)
854 ContributionHeader -= Format == DWARF32 ? 8 : 16;
855
856 // Detect overlapping contributions.
857 if (Offset > ContributionHeader) {
860 "overlapping contributions to string offsets table in section .%s.",
861 SectionName.data()));
862 }
863 // Report a gap in the table.
864 if (Offset < ContributionHeader) {
865 OS << formatv("{0:x8}: Gap, length = ", Offset);
866 OS << (ContributionHeader - Offset) << "\n";
867 }
868 OS << formatv("{0:x8}: ", ContributionHeader);
869 // In DWARF v5 the contribution size in the descriptor does not equal
870 // the originally encoded length (it does not contain the length of the
871 // version field and the padding, a total of 4 bytes). Add them back in
872 // for reporting.
873 OS << "Contribution size = " << (Contribution->Size + (Version < 5 ? 0 : 4))
874 << ", Format = " << dwarf::FormatString(Format)
875 << ", Version = " << Version << "\n";
876
877 Offset = Contribution->Base;
878 unsigned EntrySize = Contribution->getDwarfOffsetByteSize();
879 while (Offset - Contribution->Base < Contribution->Size) {
880 OS << formatv("{0:x8}: ", Offset);
881 uint64_t StringOffset =
882 StrOffsetExt.getRelocatedValue(EntrySize, &Offset);
883 OS << formatv("{0:x-} ", fmt_align(StringOffset, AlignStyle::Right,
884 OffsetDumpWidth, '0'));
885 const char *S = StrData.getCStr(&StringOffset);
886 if (S)
887 OS << formatv("\"{0}\"", S);
888 OS << "\n";
889 }
890 }
891 // Report a gap at the end of the table.
892 if (Offset < SectionSize) {
893 OS << formatv("{0:x8}: Gap, length = ", Offset);
894 OS << (SectionSize - Offset) << "\n";
895 }
896}
897
898// Dump the .debug_addr section.
900 DIDumpOptions DumpOpts, uint16_t Version,
901 uint8_t AddrSize) {
902 uint64_t Offset = 0;
903 while (AddrData.isValidOffset(Offset)) {
904 DWARFDebugAddrTable AddrTable;
905 uint64_t TableOffset = Offset;
906 if (Error Err = AddrTable.extract(AddrData, &Offset, Version, AddrSize,
907 DumpOpts.WarningHandler)) {
908 DumpOpts.RecoverableErrorHandler(std::move(Err));
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.
911 if (auto TableLength = AddrTable.getFullLength()) {
912 Offset = TableOffset + *TableLength;
913 continue;
914 }
915 break;
916 }
917 AddrTable.dump(OS, DumpOpts);
918 }
919}
920
921// Dump the .debug_rnglists or .debug_rnglists.dwo section (DWARF v5).
923 raw_ostream &OS, DWARFDataExtractor &rnglistData,
924 llvm::function_ref<std::optional<object::SectionedAddress>(uint32_t)>
925 LookupPooledAddress,
926 DIDumpOptions DumpOpts) {
927 uint64_t Offset = 0;
928 while (rnglistData.isValidOffset(Offset)) {
930 uint64_t TableOffset = Offset;
931 if (Error Err = Rnglists.extract(rnglistData, &Offset)) {
932 DumpOpts.RecoverableErrorHandler(std::move(Err));
933 uint64_t Length = Rnglists.length();
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.
936 if (Length == 0)
937 break;
938 Offset = TableOffset + Length;
939 } else {
940 Rnglists.dump(rnglistData, OS, LookupPooledAddress, DumpOpts);
941 }
942 }
943}
944
945
948 std::optional<uint64_t> DumpOffset) {
949 uint64_t Offset = 0;
950
951 while (Data.isValidOffset(Offset)) {
952 DWARFListTableHeader Header(".debug_loclists", "locations");
953 if (Error E = Header.extract(Data, &Offset)) {
954 DumpOpts.RecoverableErrorHandler(std::move(E));
955 return;
956 }
957
958 Header.dump(Data, OS, DumpOpts);
959
960 uint64_t EndOffset = Header.length() + Header.getHeaderOffset();
961 Data.setAddressSize(Header.getAddrSize());
962 DWARFDebugLoclists Loc(Data, Header.getVersion());
963 if (DumpOffset) {
964 if (DumpOffset >= Offset && DumpOffset < EndOffset) {
965 Offset = *DumpOffset;
966 Loc.dumpLocationList(&Offset, OS, /*BaseAddr=*/std::nullopt, Obj,
967 nullptr, DumpOpts, /*Indent=*/0);
968 OS << "\n";
969 return;
970 }
971 } else {
972 Loc.dumpRange(Offset, EndOffset - Offset, OS, Obj, DumpOpts);
973 }
974 Offset = EndOffset;
975 }
976}
977
979 DWARFDataExtractor Data, bool GnuStyle) {
981 Table.extract(Data, GnuStyle, DumpOpts.RecoverableErrorHandler);
982 Table.dump(OS);
983}
984
986 raw_ostream &OS, DIDumpOptions DumpOpts,
987 std::array<std::optional<uint64_t>, DIDT_ID_Count> DumpOffsets) {
988 uint64_t DumpType = DumpOpts.DumpType;
989
990 StringRef Extension = sys::path::extension(DObj->getFileName());
991 bool IsDWO = (Extension == ".dwo") || (Extension == ".dwp");
992
993 // Print UUID header.
994 const auto *ObjFile = DObj->getFile();
995 if (DumpType & DIDT_UUID)
996 dumpUUID(OS, *ObjFile);
997
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());
1007 if (!Should)
1008 return nullptr;
1009 OS << "\n" << Name << " contents:\n";
1010 return &DumpOffsets[ID];
1011 };
1012
1013 // Dump individual sections.
1014 if (shouldDump(Explicit, ".debug_abbrev", DIDT_ID_DebugAbbrev,
1015 DObj->getAbbrevSection()))
1016 getDebugAbbrev()->dump(OS);
1017 if (shouldDump(ExplicitDWO, ".debug_abbrev.dwo", DIDT_ID_DebugAbbrev,
1018 DObj->getAbbrevDWOSection()))
1019 getDebugAbbrevDWO()->dump(OS);
1020
1021 auto dumpDebugInfo = [&](const char *Name, unit_iterator_range Units) {
1022 OS << '\n' << Name << " contents:\n";
1023 std::optional<uint64_t> DumpOffset = DumpOffsets[DIDT_ID_DebugInfo];
1024 for (const auto &U : Units) {
1025 // For dumping of DWOs, remember if unit is already holding its context in
1026 // memory
1027 bool HadDWO = U->getDWO();
1028 if (DumpOffset) {
1029 U->getDIEForOffset(*DumpOffset)
1030 .dump(OS, 0, DumpOpts.noImplicitRecursion());
1031 DWARFDie CUDie = U->getUnitDIE(false);
1032 DWARFDie CUNonSkeletonDie = U->getNonSkeletonUnitDIE(false);
1033 if (CUNonSkeletonDie && CUDie != CUNonSkeletonDie) {
1034 CUNonSkeletonDie.getDwarfUnit()
1035 ->getDIEForOffset(*DumpOffset)
1036 .dump(OS, 0, DumpOpts.noImplicitRecursion());
1037 }
1038 } else {
1039 U->dump(OS, DumpOpts);
1040 }
1041 // If our dump caused a new context for the non-skeleton unit in a DWO to
1042 // be freshly opened, release it now. We won't re-use it. This avoids
1043 // holding a lot of unnecessary anon memory while streaming through
1044 // multiple DWOs (OTOH DWP is shared ctx, so better not to drop it
1045 // otherwise it will be immediately reopened by the next non-skeleton CU).
1046 const DWARFUnit *DWO = U->getDWO();
1047 if (!HadDWO && DWO && !DWO->getContext().isDWP())
1048 U->clearDWO();
1049 }
1050 };
1051 if ((DumpType & DIDT_DebugInfo)) {
1052 if (Explicit || getNumCompileUnits())
1053 dumpDebugInfo(".debug_info", info_section_units());
1054 if (ExplicitDWO || getNumDWOCompileUnits())
1055 dumpDebugInfo(".debug_info.dwo", dwo_info_section_units());
1056 }
1057
1058 auto dumpDebugType = [&](const char *Name, unit_iterator_range Units) {
1059 OS << '\n' << Name << " contents:\n";
1060 for (const auto &U : Units)
1061 if (auto DumpOffset = DumpOffsets[DIDT_ID_DebugTypes])
1062 U->getDIEForOffset(*DumpOffset)
1063 .dump(OS, 0, DumpOpts.noImplicitRecursion());
1064 else
1065 U->dump(OS, DumpOpts);
1066 };
1067 if ((DumpType & DIDT_DebugTypes)) {
1068 if (Explicit || getNumTypeUnits())
1069 dumpDebugType(".debug_types", types_section_units());
1070 if (ExplicitDWO || getNumDWOTypeUnits())
1071 dumpDebugType(".debug_types.dwo", dwo_types_section_units());
1072 }
1073
1074 DIDumpOptions LLDumpOpts = DumpOpts;
1075 if (LLDumpOpts.Verbose)
1076 LLDumpOpts.DisplayRawContents = true;
1077
1078 if (const auto *Off = shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc,
1079 DObj->getLocSection().Data)) {
1080 getDebugLoc()->dump(OS, *DObj, LLDumpOpts, *Off);
1081 }
1082 if (const auto *Off =
1083 shouldDump(Explicit, ".debug_loclists", DIDT_ID_DebugLoclists,
1084 DObj->getLoclistsSection().Data)) {
1085 DWARFDataExtractor Data(*DObj, DObj->getLoclistsSection(), isLittleEndian(),
1086 0);
1087 dumpLoclistsSection(OS, LLDumpOpts, Data, *DObj, *Off);
1088 }
1089 if (const auto *Off =
1090 shouldDump(ExplicitDWO, ".debug_loclists.dwo", DIDT_ID_DebugLoclists,
1091 DObj->getLoclistsDWOSection().Data)) {
1092 DWARFDataExtractor Data(*DObj, DObj->getLoclistsDWOSection(),
1093 isLittleEndian(), 0);
1094 dumpLoclistsSection(OS, LLDumpOpts, Data, *DObj, *Off);
1095 }
1096
1097 if (const auto *Off =
1098 shouldDump(ExplicitDWO, ".debug_loc.dwo", DIDT_ID_DebugLoc,
1099 DObj->getLocDWOSection().Data)) {
1100 DWARFDataExtractor Data(*DObj, DObj->getLocDWOSection(), isLittleEndian(),
1101 4);
1102 DWARFDebugLoclists Loc(Data, /*Version=*/4);
1103 if (*Off) {
1104 uint64_t Offset = **Off;
1105 Loc.dumpLocationList(&Offset, OS,
1106 /*BaseAddr=*/std::nullopt, *DObj, nullptr,
1107 LLDumpOpts,
1108 /*Indent=*/0);
1109 OS << "\n";
1110 } else {
1111 Loc.dumpRange(0, Data.getData().size(), OS, *DObj, LLDumpOpts);
1112 }
1113 }
1114
1115 if (const std::optional<uint64_t> *Off =
1116 shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,
1117 DObj->getFrameSection().Data)) {
1119 (*DF)->dump(OS, DumpOpts, *Off);
1120 else
1121 RecoverableErrorHandler(DF.takeError());
1122 }
1123
1124 if (const std::optional<uint64_t> *Off =
1125 shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame,
1126 DObj->getEHFrameSection().Data)) {
1128 (*DF)->dump(OS, DumpOpts, *Off);
1129 else
1130 RecoverableErrorHandler(DF.takeError());
1131 }
1132
1133 if (shouldDump(Explicit, ".debug_macro", DIDT_ID_DebugMacro,
1134 DObj->getMacroSection().Data)) {
1135 if (auto Macro = getDebugMacro())
1136 Macro->dump(OS);
1137 }
1138
1139 if (shouldDump(Explicit, ".debug_macro.dwo", DIDT_ID_DebugMacro,
1140 DObj->getMacroDWOSection())) {
1141 if (auto MacroDWO = getDebugMacroDWO())
1142 MacroDWO->dump(OS);
1143 }
1144
1145 if (shouldDump(Explicit, ".debug_macinfo", DIDT_ID_DebugMacro,
1146 DObj->getMacinfoSection())) {
1147 if (auto Macinfo = getDebugMacinfo())
1148 Macinfo->dump(OS);
1149 }
1150
1151 if (shouldDump(Explicit, ".debug_macinfo.dwo", DIDT_ID_DebugMacro,
1152 DObj->getMacinfoDWOSection())) {
1153 if (auto MacinfoDWO = getDebugMacinfoDWO())
1154 MacinfoDWO->dump(OS);
1155 }
1156
1157 if (shouldDump(Explicit, ".debug_aranges", DIDT_ID_DebugAranges,
1158 DObj->getArangesSection())) {
1159 uint64_t offset = 0;
1160 DWARFDataExtractor arangesData(DObj->getArangesSection(), isLittleEndian(),
1161 0);
1163 while (arangesData.isValidOffset(offset)) {
1164 if (Error E =
1165 set.extract(arangesData, &offset, DumpOpts.WarningHandler)) {
1166 RecoverableErrorHandler(std::move(E));
1167 break;
1168 }
1169 set.dump(OS);
1170 }
1171 }
1172
1173 auto DumpLineSection = [&](DWARFDebugLine::SectionParser Parser,
1174 DIDumpOptions DumpOpts,
1175 std::optional<uint64_t> DumpOffset) {
1176 while (!Parser.done()) {
1177 if (DumpOffset && Parser.getOffset() != *DumpOffset) {
1178 Parser.skip(DumpOpts.WarningHandler, DumpOpts.WarningHandler);
1179 continue;
1180 }
1181 OS << "debug_line[" << formatv("{0:x8}", Parser.getOffset()) << "]\n";
1182 Parser.parseNext(DumpOpts.WarningHandler, DumpOpts.WarningHandler, &OS,
1183 DumpOpts.Verbose);
1184 }
1185 };
1186
1187 auto DumpStrSection = [&](StringRef Section) {
1188 DataExtractor StrData(Section, isLittleEndian());
1189 uint64_t Offset = 0;
1190 uint64_t StrOffset = 0;
1191 while (StrData.isValidOffset(Offset)) {
1192 Error Err = Error::success();
1193 const char *CStr = StrData.getCStr(&Offset, &Err);
1194 if (Err) {
1195 DumpOpts.WarningHandler(std::move(Err));
1196 return;
1197 }
1198 OS << formatv("{0:x8}: \"", StrOffset);
1199 OS.write_escaped(CStr);
1200 OS << "\"\n";
1201 StrOffset = Offset;
1202 }
1203 };
1204
1205 if (const auto *Off = shouldDump(Explicit, ".debug_line", DIDT_ID_DebugLine,
1206 DObj->getLineSection().Data)) {
1207 DWARFDataExtractor LineData(*DObj, DObj->getLineSection(), isLittleEndian(),
1208 0);
1210 DumpLineSection(Parser, DumpOpts, *Off);
1211 }
1212
1213 if (const auto *Off =
1214 shouldDump(ExplicitDWO, ".debug_line.dwo", DIDT_ID_DebugLine,
1215 DObj->getLineDWOSection().Data)) {
1216 DWARFDataExtractor LineData(*DObj, DObj->getLineDWOSection(),
1217 isLittleEndian(), 0);
1219 DumpLineSection(Parser, DumpOpts, *Off);
1220 }
1221
1222 if (shouldDump(Explicit, ".debug_cu_index", DIDT_ID_DebugCUIndex,
1223 DObj->getCUIndexSection())) {
1224 getCUIndex().dump(OS);
1225 }
1226
1227 if (shouldDump(Explicit, ".debug_tu_index", DIDT_ID_DebugTUIndex,
1228 DObj->getTUIndexSection())) {
1229 getTUIndex().dump(OS);
1230 }
1231
1232 if (shouldDump(Explicit, ".debug_str", DIDT_ID_DebugStr,
1233 DObj->getStrSection()))
1234 DumpStrSection(DObj->getStrSection());
1235
1236 if (shouldDump(ExplicitDWO, ".debug_str.dwo", DIDT_ID_DebugStr,
1237 DObj->getStrDWOSection()))
1238 DumpStrSection(DObj->getStrDWOSection());
1239
1240 if (shouldDump(Explicit, ".debug_line_str", DIDT_ID_DebugLineStr,
1241 DObj->getLineStrSection()))
1242 DumpStrSection(DObj->getLineStrSection());
1243
1244 if (shouldDump(Explicit, ".debug_addr", DIDT_ID_DebugAddr,
1245 DObj->getAddrSection().Data)) {
1246 DWARFDataExtractor AddrData(*DObj, DObj->getAddrSection(),
1247 isLittleEndian(), 0);
1248 dumpAddrSection(OS, AddrData, DumpOpts, getMaxVersion(), getCUAddrSize());
1249 }
1250
1251 if (shouldDump(Explicit, ".debug_ranges", DIDT_ID_DebugRanges,
1252 DObj->getRangesSection().Data)) {
1253 uint8_t savedAddressByteSize = getCUAddrSize();
1254 DWARFDataExtractor rangesData(*DObj, DObj->getRangesSection(),
1255 isLittleEndian(), savedAddressByteSize);
1256 uint64_t offset = 0;
1257 DWARFDebugRangeList rangeList;
1258 while (rangesData.isValidOffset(offset)) {
1259 if (Error E = rangeList.extract(rangesData, &offset)) {
1260 DumpOpts.RecoverableErrorHandler(std::move(E));
1261 break;
1262 }
1263 rangeList.dump(OS);
1264 }
1265 }
1266
1267 auto LookupPooledAddress =
1268 [&](uint32_t Index) -> std::optional<SectionedAddress> {
1269 const auto &CUs = compile_units();
1270 auto I = CUs.begin();
1271 if (I == CUs.end())
1272 return std::nullopt;
1273 return (*I)->getAddrOffsetSectionItem(Index);
1274 };
1275
1276 if (shouldDump(Explicit, ".debug_rnglists", DIDT_ID_DebugRnglists,
1277 DObj->getRnglistsSection().Data)) {
1278 DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsSection(),
1279 isLittleEndian(), 0);
1280 dumpRnglistsSection(OS, RnglistData, LookupPooledAddress, DumpOpts);
1281 }
1282
1283 if (shouldDump(ExplicitDWO, ".debug_rnglists.dwo", DIDT_ID_DebugRnglists,
1284 DObj->getRnglistsDWOSection().Data)) {
1285 DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsDWOSection(),
1286 isLittleEndian(), 0);
1287 dumpRnglistsSection(OS, RnglistData, LookupPooledAddress, DumpOpts);
1288 }
1289
1290 if (shouldDump(Explicit, ".debug_pubnames", DIDT_ID_DebugPubnames,
1291 DObj->getPubnamesSection().Data)) {
1292 DWARFDataExtractor PubTableData(*DObj, DObj->getPubnamesSection(),
1293 isLittleEndian(), 0);
1294 dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/false);
1295 }
1296
1297 if (shouldDump(Explicit, ".debug_pubtypes", DIDT_ID_DebugPubtypes,
1298 DObj->getPubtypesSection().Data)) {
1299 DWARFDataExtractor PubTableData(*DObj, DObj->getPubtypesSection(),
1300 isLittleEndian(), 0);
1301 dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/false);
1302 }
1303
1304 if (shouldDump(Explicit, ".debug_gnu_pubnames", DIDT_ID_DebugGnuPubnames,
1305 DObj->getGnuPubnamesSection().Data)) {
1306 DWARFDataExtractor PubTableData(*DObj, DObj->getGnuPubnamesSection(),
1307 isLittleEndian(), 0);
1308 dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/true);
1309 }
1310
1311 if (shouldDump(Explicit, ".debug_gnu_pubtypes", DIDT_ID_DebugGnuPubtypes,
1312 DObj->getGnuPubtypesSection().Data)) {
1313 DWARFDataExtractor PubTableData(*DObj, DObj->getGnuPubtypesSection(),
1314 isLittleEndian(), 0);
1315 dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/true);
1316 }
1317
1318 if (shouldDump(Explicit, ".debug_str_offsets", DIDT_ID_DebugStrOffsets,
1319 DObj->getStrOffsetsSection().Data))
1321 OS, DumpOpts, "debug_str_offsets", *DObj, DObj->getStrOffsetsSection(),
1322 DObj->getStrSection(), normal_units(), isLittleEndian());
1323 if (shouldDump(ExplicitDWO, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets,
1324 DObj->getStrOffsetsDWOSection().Data))
1325 dumpStringOffsetsSection(OS, DumpOpts, "debug_str_offsets.dwo", *DObj,
1326 DObj->getStrOffsetsDWOSection(),
1327 DObj->getStrDWOSection(), dwo_units(),
1328 isLittleEndian());
1329
1330 if (shouldDump(Explicit, ".gdb_index", DIDT_ID_GdbIndex,
1331 DObj->getGdbIndexSection())) {
1332 getGdbIndex().dump(OS);
1333 }
1334
1335 if (shouldDump(Explicit, ".apple_names", DIDT_ID_AppleNames,
1336 DObj->getAppleNamesSection().Data))
1337 getAppleNames().dump(OS);
1338
1339 if (shouldDump(Explicit, ".apple_types", DIDT_ID_AppleTypes,
1340 DObj->getAppleTypesSection().Data))
1341 getAppleTypes().dump(OS);
1342
1343 if (shouldDump(Explicit, ".apple_namespaces", DIDT_ID_AppleNamespaces,
1344 DObj->getAppleNamespacesSection().Data))
1346
1347 if (shouldDump(Explicit, ".apple_objc", DIDT_ID_AppleObjC,
1348 DObj->getAppleObjCSection().Data))
1349 getAppleObjC().dump(OS);
1350 if (shouldDump(Explicit, ".debug_names", DIDT_ID_DebugNames,
1351 DObj->getNamesSection().Data))
1352 getDebugNames().dump(OS);
1353}
1354
1356 DWARFUnitVector &DWOUnits = State->getDWOUnits();
1357 if (const auto &TUI = getTUIndex()) {
1358 if (const auto *R = TUI.getFromHash(Hash)) {
1359 if (TUI.getVersion() >= 5) {
1361 DWOUnits.getUnitForIndexEntry(*R, DW_SECT_INFO));
1362 } else {
1363 DWARFUnit *TypesUnit = nullptr;
1365 if (!TypesUnit)
1366 TypesUnit =
1367 DWOUnits.getUnitForIndexEntry(*R, DW_SECT_EXT_TYPES, &S);
1368 });
1369 return dyn_cast_or_null<DWARFTypeUnit>(TypesUnit);
1370 }
1371 }
1372 return nullptr;
1373 }
1374 return State->getTypeUnitMap(IsDWO).lookup(Hash);
1375}
1376
1378 DWARFUnitVector &DWOUnits = State->getDWOUnits(LazyParse);
1379
1380 if (const auto &CUI = getCUIndex()) {
1381 if (const auto *R = CUI.getFromHash(Hash))
1383 DWOUnits.getUnitForIndexEntry(*R, DW_SECT_INFO));
1384 return nullptr;
1385 }
1386
1387 // If there's no index, just search through the CUs in the DWO - there's
1388 // probably only one unless this is something like LTO - though an in-process
1389 // built/cached lookup table could be used in that case to improve repeated
1390 // lookups of different CUs in the DWO.
1391 for (const auto &DWOCU : dwo_compile_units()) {
1392 // Might not have parsed DWO ID yet.
1393 if (!DWOCU->getDWOId()) {
1394 if (std::optional<uint64_t> DWOId =
1395 toUnsigned(DWOCU->getUnitDIE().find(DW_AT_GNU_dwo_id)))
1396 DWOCU->setDWOId(*DWOId);
1397 else
1398 // No DWO ID?
1399 continue;
1400 }
1401 if (DWOCU->getDWOId() == Hash)
1402 return dyn_cast<DWARFCompileUnit>(DWOCU.get());
1403 }
1404 return nullptr;
1405}
1406
1408 if (auto *CU = State->getNormalUnits().getUnitForOffset(Offset))
1409 return CU->getDIEForOffset(Offset);
1410 return DWARFDie();
1411}
1412
1414 bool Success = true;
1415 DWARFVerifier verifier(OS, *this, DumpOpts);
1416
1417 Success &= verifier.handleDebugAbbrev();
1418 if (DumpOpts.DumpType & DIDT_DebugCUIndex)
1419 Success &= verifier.handleDebugCUIndex();
1420 if (DumpOpts.DumpType & DIDT_DebugTUIndex)
1421 Success &= verifier.handleDebugTUIndex();
1422 if (DumpOpts.DumpType & DIDT_DebugInfo)
1423 Success &= verifier.handleDebugInfo();
1424 if (DumpOpts.DumpType & DIDT_DebugLine)
1425 Success &= verifier.handleDebugLine();
1426 if (DumpOpts.DumpType & DIDT_DebugStrOffsets)
1427 Success &= verifier.handleDebugStrOffsets();
1428 Success &= verifier.handleAccelTables();
1429 verifier.summarize();
1430 return Success;
1431}
1432
1434 return State->getCUIndex();
1435}
1436
1438 return State->getTUIndex();
1439}
1440
1442 return State->getGdbIndex();
1443}
1444
1446 return State->getDebugAbbrev();
1447}
1448
1450 return State->getDebugAbbrevDWO();
1451}
1452
1454 return State->getDebugLoc();
1455}
1456
1458 return State->getDebugAranges();
1459}
1460
1462 return State->getDebugFrame();
1463}
1464
1466 return State->getEHFrame();
1467}
1468
1470 return State->getDebugMacro();
1471}
1472
1474 return State->getDebugMacroDWO();
1475}
1476
1478 return State->getDebugMacinfo();
1479}
1480
1482 return State->getDebugMacinfoDWO();
1483}
1484
1485
1487 return State->getDebugNames();
1488}
1489
1491 return State->getAppleNames();
1492}
1493
1495 return State->getAppleTypes();
1496}
1497
1499 return State->getAppleNamespaces();
1500}
1501
1503 return State->getAppleObjC();
1504}
1505
1509 getLineTableForUnit(U, WarningHandler);
1510 if (!ExpectedLineTable) {
1511 WarningHandler(ExpectedLineTable.takeError());
1512 return nullptr;
1513 }
1514 return *ExpectedLineTable;
1515}
1516
1518 DWARFUnit *U, function_ref<void(Error)> RecoverableErrorHandler) {
1519 return State->getLineTableForUnit(U, RecoverableErrorHandler);
1520}
1521
1523 return State->clearLineTableForUnit(U);
1524}
1525
1526DWARFUnitVector &DWARFContext::getDWOUnits(bool Lazy) {
1527 return State->getDWOUnits(Lazy);
1528}
1529
1531 return State->getNormalUnits().getUnitForOffset(Offset);
1532}
1533
1537
1542
1544 uint64_t CUOffset = getDebugAranges()->findAddress(Address);
1545 if (DWARFCompileUnit *OffsetCU = getCompileUnitForOffset(CUOffset))
1546 return OffsetCU;
1547
1548 // Global variables are often missed by the above search, for one of two
1549 // reasons:
1550 // 1. .debug_aranges may not include global variables. On clang, it seems we
1551 // put the globals in the aranges, but this isn't true for gcc.
1552 // 2. Even if the global variable is in a .debug_arange, global variables
1553 // may not be captured in the [start, end) addresses described by the
1554 // parent compile unit.
1555 //
1556 // So, we walk the CU's and their child DI's manually, looking for the
1557 // specific global variable.
1558 for (std::unique_ptr<DWARFUnit> &CU : compile_units()) {
1559 if (CU->getVariableForAddress(Address)) {
1560 return static_cast<DWARFCompileUnit *>(CU.get());
1561 }
1562 }
1563 return nullptr;
1564}
1565
1567 bool CheckDWO) {
1568 DIEsForAddress Result;
1569
1571 if (!CU)
1572 return Result;
1573
1574 if (CheckDWO) {
1575 // We were asked to check the DWO file and this debug information is more
1576 // complete that any information in the skeleton compile unit, so search the
1577 // DWO first to see if we have a match.
1578 DWARFDie CUDie = CU->getUnitDIE(false);
1579 DWARFDie CUDwoDie = CU->getNonSkeletonUnitDIE(false);
1580 if (CheckDWO && CUDwoDie && CUDie != CUDwoDie) {
1581 // We have a DWO file, lets search it.
1582 DWARFCompileUnit *CUDwo =
1584 if (CUDwo) {
1585 Result.FunctionDIE = CUDwo->getSubroutineForAddress(Address);
1586 if (Result.FunctionDIE)
1587 Result.CompileUnit = CUDwo;
1588 }
1589 }
1590 }
1591
1592 // Search the normal DWARF if we didn't find a match in the DWO file or if
1593 // we didn't check the DWO file above.
1594 if (!Result) {
1595 Result.CompileUnit = CU;
1596 Result.FunctionDIE = CU->getSubroutineForAddress(Address);
1597 }
1598
1599 std::vector<DWARFDie> Worklist;
1600 Worklist.push_back(Result.FunctionDIE);
1601 while (!Worklist.empty()) {
1602 DWARFDie DIE = Worklist.back();
1603 Worklist.pop_back();
1604
1605 if (!DIE.isValid())
1606 continue;
1607
1608 if (DIE.getTag() == DW_TAG_lexical_block &&
1609 DIE.addressRangeContainsAddress(Address)) {
1610 Result.BlockDIE = DIE;
1611 break;
1612 }
1613
1614 append_range(Worklist, DIE);
1615 }
1616
1617 return Result;
1618}
1619
1620/// TODO: change input parameter from "uint64_t Address"
1621/// into "SectionedAddress Address"
1623 DWARFCompileUnit *CU, uint64_t Address, FunctionNameKind Kind,
1625 std::string &FunctionName, std::string &StartFile, uint32_t &StartLine,
1626 std::optional<uint64_t> &StartAddress) {
1627 // The address may correspond to instruction in some inlined function,
1628 // so we have to build the chain of inlined functions and take the
1629 // name of the topmost function in it.
1630 SmallVector<DWARFDie, 4> InlinedChain;
1631 CU->getInlinedChainForAddress(Address, InlinedChain);
1632 if (InlinedChain.empty())
1633 return false;
1634
1635 const DWARFDie &DIE = InlinedChain[0];
1636 bool FoundResult = false;
1637 const char *Name = nullptr;
1638 if (Kind != FunctionNameKind::None && (Name = DIE.getSubroutineName(Kind))) {
1639 FunctionName = Name;
1640 FoundResult = true;
1641 }
1642 std::string DeclFile = DIE.getDeclFile(FileNameKind);
1643 if (!DeclFile.empty()) {
1644 StartFile = DeclFile;
1645 FoundResult = true;
1646 }
1647 if (auto DeclLineResult = DIE.getDeclLine()) {
1648 StartLine = DeclLineResult;
1649 FoundResult = true;
1650 }
1651 if (auto LowPcAddr = toSectionedAddress(DIE.find(DW_AT_low_pc)))
1652 StartAddress = LowPcAddr->Address;
1653 return FoundResult;
1654}
1655
1656static std::optional<int64_t>
1658 std::optional<unsigned> FrameBaseReg) {
1659 if (!Expr.empty() &&
1660 (Expr[0] == DW_OP_fbreg ||
1661 (FrameBaseReg && Expr[0] == DW_OP_breg0 + *FrameBaseReg))) {
1662 unsigned Count;
1663 int64_t Offset = decodeSLEB128(Expr.data() + 1, &Count, Expr.end());
1664 // A single DW_OP_fbreg or DW_OP_breg.
1665 if (Expr.size() == Count + 1)
1666 return Offset;
1667 // Same + DW_OP_deref (Fortran arrays look like this).
1668 if (Expr.size() == Count + 2 && Expr[Count + 1] == DW_OP_deref)
1669 return Offset;
1670 // Fallthrough. Do not accept ex. (DW_OP_breg W29, DW_OP_stack_value)
1671 }
1672 return std::nullopt;
1673}
1674
1675void DWARFContext::addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram,
1676 DWARFDie Die, std::vector<DILocal> &Result) {
1677 if (Die.getTag() == DW_TAG_variable ||
1678 Die.getTag() == DW_TAG_formal_parameter) {
1679 DILocal Local;
1680 if (const char *Name = Subprogram.getSubroutineName(DINameKind::ShortName))
1681 Local.FunctionName = Name;
1682
1683 std::optional<unsigned> FrameBaseReg;
1684 if (auto FrameBase = Subprogram.find(DW_AT_frame_base))
1685 if (std::optional<ArrayRef<uint8_t>> Expr = FrameBase->getAsBlock())
1686 if (!Expr->empty() && (*Expr)[0] >= DW_OP_reg0 &&
1687 (*Expr)[0] <= DW_OP_reg31) {
1688 FrameBaseReg = (*Expr)[0] - DW_OP_reg0;
1689 }
1690
1691 if (Expected<std::vector<DWARFLocationExpression>> Loc =
1692 Die.getLocations(DW_AT_location)) {
1693 for (const auto &Entry : *Loc) {
1694 if (std::optional<int64_t> FrameOffset =
1695 getExpressionFrameOffset(Entry.Expr, FrameBaseReg)) {
1696 Local.FrameOffset = *FrameOffset;
1697 break;
1698 }
1699 }
1700 } else {
1701 // FIXME: missing DW_AT_location is OK here, but other errors should be
1702 // reported to the user.
1703 consumeError(Loc.takeError());
1704 }
1705
1706 if (auto TagOffsetAttr = Die.find(DW_AT_LLVM_tag_offset))
1707 Local.TagOffset = TagOffsetAttr->getAsUnsignedConstant();
1708
1709 if (auto Origin =
1710 Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin))
1711 Die = Origin;
1712 if (auto NameAttr = Die.find(DW_AT_name))
1713 if (std::optional<const char *> Name = dwarf::toString(*NameAttr))
1714 Local.Name = *Name;
1715 if (auto Type = Die.getAttributeValueAsReferencedDie(DW_AT_type))
1716 Local.Size = Type.getTypeSize(getCUAddrSize());
1717 if (auto DeclFileAttr = Die.find(DW_AT_decl_file)) {
1718 if (const auto *LT = CU->getContext().getLineTableForUnit(CU))
1719 LT->getFileNameByIndex(
1720 *DeclFileAttr->getAsUnsignedConstant(), CU->getCompilationDir(),
1722 Local.DeclFile);
1723 }
1724 if (auto DeclLineAttr = Die.find(DW_AT_decl_line))
1725 Local.DeclLine = *DeclLineAttr->getAsUnsignedConstant();
1726
1727 Result.push_back(Local);
1728 return;
1729 }
1730
1731 if (Die.getTag() == DW_TAG_inlined_subroutine)
1732 if (auto Origin =
1733 Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin))
1734 Subprogram = Origin;
1735
1736 for (auto Child : Die)
1737 addLocalsForDie(CU, Subprogram, Child, Result);
1738}
1739
1740std::vector<DILocal>
1742 std::vector<DILocal> Result;
1744 if (!CU)
1745 return Result;
1746
1747 DWARFDie Subprogram = CU->getSubroutineForAddress(Address.Address);
1748 if (Subprogram.isValid())
1749 addLocalsForDie(CU, Subprogram, Subprogram, Result);
1750 return Result;
1751}
1752
1753std::optional<DILineInfo>
1757 if (!CU)
1758 return std::nullopt;
1759
1760 DILineInfo Result;
1762 CU, Address.Address, Spec.FNKind, Spec.FLIKind, Result.FunctionName,
1763 Result.StartFileName, Result.StartLine, Result.StartAddress);
1764 if (Spec.FLIKind != FileLineInfoKind::None) {
1765 if (const DWARFLineTable *LineTable = getLineTableForUnit(CU)) {
1766 LineTable->getFileLineInfoForAddress(
1767 {Address.Address, Address.SectionIndex}, Spec.ApproximateLine,
1768 CU->getCompilationDir(), Spec.FLIKind, Result);
1769 }
1770 }
1771
1772 return Result;
1773}
1774
1775std::optional<DILineInfo>
1777 DILineInfo Result;
1779 if (!CU)
1780 return Result;
1781
1782 if (DWARFDie Die = CU->getVariableForAddress(Address.Address)) {
1783 Result.FileName = Die.getDeclFile(FileLineInfoKind::AbsoluteFilePath);
1784 Result.Line = Die.getDeclLine();
1785 }
1786
1787 return Result;
1788}
1789
1792 DILineInfoTable Lines;
1794 if (!CU)
1795 return Lines;
1796
1797 uint32_t StartLine = 0;
1798 std::string StartFileName;
1799 std::string FunctionName(DILineInfo::BadString);
1800 std::optional<uint64_t> StartAddress;
1802 Spec.FLIKind, FunctionName,
1803 StartFileName, StartLine, StartAddress);
1804
1805 // If the Specifier says we don't need FileLineInfo, just
1806 // return the top-most function at the starting address.
1807 if (Spec.FLIKind == FileLineInfoKind::None) {
1808 DILineInfo Result;
1809 Result.FunctionName = FunctionName;
1810 Result.StartFileName = StartFileName;
1811 Result.StartLine = StartLine;
1812 Result.StartAddress = StartAddress;
1813 Lines.push_back(std::make_pair(Address.Address, Result));
1814 return Lines;
1815 }
1816
1817 const DWARFLineTable *LineTable = getLineTableForUnit(CU);
1818
1819 // Get the index of row we're looking for in the line table.
1820 std::vector<uint32_t> RowVector;
1821 if (!LineTable->lookupAddressRange({Address.Address, Address.SectionIndex},
1822 Size, RowVector)) {
1823 return Lines;
1824 }
1825
1826 for (uint32_t RowIndex : RowVector) {
1827 // Take file number and line/column from the row.
1828 const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
1829 DILineInfo Result;
1830 LineTable->getFileNameByIndex(Row.File, CU->getCompilationDir(),
1831 Spec.FLIKind, Result.FileName);
1832 Result.FunctionName = FunctionName;
1833 Result.Line = Row.Line;
1834 Result.Column = Row.Column;
1835 Result.StartFileName = StartFileName;
1836 Result.StartLine = StartLine;
1837 Result.StartAddress = StartAddress;
1838 Lines.push_back(std::make_pair(Row.Address.Address, Result));
1839 }
1840
1841 return Lines;
1842}
1843
1847 DIInliningInfo InliningInfo;
1848
1850 if (!CU)
1851 return InliningInfo;
1852
1853 const DWARFLineTable *LineTable = nullptr;
1854 SmallVector<DWARFDie, 4> InlinedChain;
1855 CU->getInlinedChainForAddress(Address.Address, InlinedChain);
1856 if (InlinedChain.size() == 0) {
1857 // If there is no DIE for address (e.g. it is in unavailable .dwo file),
1858 // try to at least get file/line info from symbol table.
1859 if (Spec.FLIKind != FileLineInfoKind::None) {
1860 DILineInfo Frame;
1861 LineTable = getLineTableForUnit(CU);
1862 if (LineTable &&
1863 LineTable->getFileLineInfoForAddress(
1864 {Address.Address, Address.SectionIndex}, Spec.ApproximateLine,
1865 CU->getCompilationDir(), Spec.FLIKind, Frame))
1866 InliningInfo.addFrame(Frame);
1867 }
1868 return InliningInfo;
1869 }
1870
1871 uint32_t CallFile = 0, CallLine = 0, CallColumn = 0, CallDiscriminator = 0;
1872 for (uint32_t i = 0, n = InlinedChain.size(); i != n; i++) {
1873 DWARFDie &FunctionDIE = InlinedChain[i];
1874 DILineInfo Frame;
1875 // Get function name if necessary.
1876 if (const char *Name = FunctionDIE.getSubroutineName(Spec.FNKind))
1877 Frame.FunctionName = Name;
1878 if (auto DeclLineResult = FunctionDIE.getDeclLine())
1879 Frame.StartLine = DeclLineResult;
1880 Frame.StartFileName = FunctionDIE.getDeclFile(Spec.FLIKind);
1881 if (auto LowPcAddr = toSectionedAddress(FunctionDIE.find(DW_AT_low_pc)))
1882 Frame.StartAddress = LowPcAddr->Address;
1883 if (Spec.FLIKind != FileLineInfoKind::None) {
1884 if (i == 0) {
1885 // For the topmost frame, initialize the line table of this
1886 // compile unit and fetch file/line info from it.
1887 LineTable = getLineTableForUnit(CU);
1888 // For the topmost routine, get file/line info from line table.
1889 if (LineTable)
1890 LineTable->getFileLineInfoForAddress(
1891 {Address.Address, Address.SectionIndex}, Spec.ApproximateLine,
1892 CU->getCompilationDir(), Spec.FLIKind, Frame);
1893 } else {
1894 // Otherwise, use call file, call line and call column from
1895 // previous DIE in inlined chain.
1896 if (LineTable)
1897 LineTable->getFileNameByIndex(CallFile, CU->getCompilationDir(),
1898 Spec.FLIKind, Frame.FileName);
1899 Frame.Line = CallLine;
1900 Frame.Column = CallColumn;
1901 Frame.Discriminator = CallDiscriminator;
1902 }
1903 // Get call file/line/column of a current DIE.
1904 if (i + 1 < n) {
1905 FunctionDIE.getCallerFrame(CallFile, CallLine, CallColumn,
1906 CallDiscriminator);
1907 }
1908 }
1909 InliningInfo.addFrame(Frame);
1910 }
1911 return InliningInfo;
1912}
1913
1914std::shared_ptr<DWARFContext>
1916 return State->getDWOContext(AbsolutePath);
1917}
1918
1919static Error createError(const Twine &Reason, llvm::Error E) {
1920 return make_error<StringError>(Reason + toString(std::move(E)),
1922}
1923
1924/// SymInfo contains information about symbol: it's address
1925/// and section index which is -1LL for absolute symbols.
1926struct SymInfo {
1927 uint64_t Address = 0;
1928 uint64_t SectionIndex = 0;
1929};
1930
1931/// Returns the address of symbol relocation used against and a section index.
1932/// Used for futher relocations computation. Symbol's section load address is
1934 const RelocationRef &Reloc,
1935 const LoadedObjectInfo *L,
1936 std::map<SymbolRef, SymInfo> &Cache) {
1937 SymInfo Ret = {0, (uint64_t)-1LL};
1938 object::section_iterator RSec = Obj.section_end();
1939 object::symbol_iterator Sym = Reloc.getSymbol();
1940
1941 std::map<SymbolRef, SymInfo>::iterator CacheIt = Cache.end();
1942 // First calculate the address of the symbol or section as it appears
1943 // in the object file
1944 if (Sym != Obj.symbol_end()) {
1945 bool New;
1946 std::tie(CacheIt, New) = Cache.try_emplace(*Sym);
1947 if (!New)
1948 return CacheIt->second;
1949
1950 Expected<uint64_t> SymAddrOrErr = Sym->getAddress();
1951 if (!SymAddrOrErr)
1952 return createError("failed to compute symbol address: ",
1953 SymAddrOrErr.takeError());
1954
1955 // Also remember what section this symbol is in for later
1956 auto SectOrErr = Sym->getSection();
1957 if (!SectOrErr)
1958 return createError("failed to get symbol section: ",
1959 SectOrErr.takeError());
1960
1961 RSec = *SectOrErr;
1962 Ret.Address = *SymAddrOrErr;
1963 } else if (auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) {
1964 RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl());
1965 Ret.Address = RSec->getAddress();
1966 }
1967
1968 if (RSec != Obj.section_end())
1969 Ret.SectionIndex = RSec->getIndex();
1970
1971 // If we are given load addresses for the sections, we need to adjust:
1972 // SymAddr = (Address of Symbol Or Section in File) -
1973 // (Address of Section in File) +
1974 // (Load Address of Section)
1975 // RSec is now either the section being targeted or the section
1976 // containing the symbol being targeted. In either case,
1977 // we need to perform the same computation.
1978 if (L && RSec != Obj.section_end())
1979 if (uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec))
1980 Ret.Address += SectionLoadAddress - RSec->getAddress();
1981
1982 if (CacheIt != Cache.end())
1983 CacheIt->second = Ret;
1984
1985 return Ret;
1986}
1987
1989 const RelocationRef &Reloc) {
1990 const MachOObjectFile *MachObj = dyn_cast<MachOObjectFile>(&Obj);
1991 if (!MachObj)
1992 return false;
1993 // MachO also has relocations that point to sections and
1994 // scattered relocations.
1995 auto RelocInfo = MachObj->getRelocation(Reloc.getRawDataRefImpl());
1996 return MachObj->isRelocationScattered(RelocInfo);
1997}
1998
1999namespace {
2000struct DWARFSectionMap final : public DWARFSection {
2001 RelocAddrMap Relocs;
2002};
2003
2004class DWARFObjInMemory final : public DWARFObject {
2005 bool IsLittleEndian;
2006 uint8_t AddressSize;
2007 StringRef FileName;
2008 const object::ObjectFile *Obj = nullptr;
2009 std::vector<SectionName> SectionNames;
2010
2011 using InfoSectionMap = MapVector<object::SectionRef, DWARFSectionMap,
2012 std::map<object::SectionRef, unsigned>>;
2013
2014 InfoSectionMap InfoSections;
2015 InfoSectionMap TypesSections;
2016 InfoSectionMap InfoDWOSections;
2017 InfoSectionMap TypesDWOSections;
2018
2019 DWARFSectionMap LocSection;
2020 DWARFSectionMap LoclistsSection;
2021 DWARFSectionMap LoclistsDWOSection;
2022 DWARFSectionMap LineSection;
2023 DWARFSectionMap RangesSection;
2024 DWARFSectionMap RnglistsSection;
2025 DWARFSectionMap StrOffsetsSection;
2026 DWARFSectionMap LineDWOSection;
2027 DWARFSectionMap FrameSection;
2028 DWARFSectionMap EHFrameSection;
2029 DWARFSectionMap LocDWOSection;
2030 DWARFSectionMap StrOffsetsDWOSection;
2031 DWARFSectionMap RangesDWOSection;
2032 DWARFSectionMap RnglistsDWOSection;
2033 DWARFSectionMap AddrSection;
2034 DWARFSectionMap AppleNamesSection;
2035 DWARFSectionMap AppleTypesSection;
2036 DWARFSectionMap AppleNamespacesSection;
2037 DWARFSectionMap AppleObjCSection;
2038 DWARFSectionMap NamesSection;
2039 DWARFSectionMap PubnamesSection;
2040 DWARFSectionMap PubtypesSection;
2041 DWARFSectionMap GnuPubnamesSection;
2042 DWARFSectionMap GnuPubtypesSection;
2043 DWARFSectionMap MacroSection;
2044
2045 DWARFSectionMap *mapNameToDWARFSection(StringRef Name) {
2046 return StringSwitch<DWARFSectionMap *>(Name)
2047 .Case("debug_loc", &LocSection)
2048 .Case("debug_loclists", &LoclistsSection)
2049 .Case("debug_loclists.dwo", &LoclistsDWOSection)
2050 .Case("debug_line", &LineSection)
2051 .Case("debug_frame", &FrameSection)
2052 .Case("eh_frame", &EHFrameSection)
2053 .Case("debug_str_offsets", &StrOffsetsSection)
2054 .Case("debug_ranges", &RangesSection)
2055 .Case("debug_rnglists", &RnglistsSection)
2056 .Case("debug_loc.dwo", &LocDWOSection)
2057 .Case("debug_line.dwo", &LineDWOSection)
2058 .Case("debug_names", &NamesSection)
2059 .Case("debug_rnglists.dwo", &RnglistsDWOSection)
2060 .Case("debug_str_offsets.dwo", &StrOffsetsDWOSection)
2061 .Case("debug_addr", &AddrSection)
2062 .Case("apple_names", &AppleNamesSection)
2063 .Case("debug_pubnames", &PubnamesSection)
2064 .Case("debug_pubtypes", &PubtypesSection)
2065 .Case("debug_gnu_pubnames", &GnuPubnamesSection)
2066 .Case("debug_gnu_pubtypes", &GnuPubtypesSection)
2067 .Case("apple_types", &AppleTypesSection)
2068 .Case("apple_namespaces", &AppleNamespacesSection)
2069 .Case("apple_namespac", &AppleNamespacesSection)
2070 .Case("apple_objc", &AppleObjCSection)
2071 .Case("debug_macro", &MacroSection)
2072 .Default(nullptr);
2073 }
2074
2075 StringRef AbbrevSection;
2076 StringRef ArangesSection;
2077 StringRef StrSection;
2078 StringRef MacinfoSection;
2079 StringRef MacinfoDWOSection;
2080 StringRef MacroDWOSection;
2081 StringRef AbbrevDWOSection;
2082 StringRef StrDWOSection;
2083 StringRef CUIndexSection;
2084 StringRef GdbIndexSection;
2085 StringRef TUIndexSection;
2086 StringRef LineStrSection;
2087
2088 // A deque holding section data whose iterators are not invalidated when
2089 // new decompressed sections are inserted at the end.
2090 std::deque<SmallString<0>> UncompressedSections;
2091
2092 StringRef *mapSectionToMember(StringRef Name) {
2093 if (DWARFSection *Sec = mapNameToDWARFSection(Name))
2094 return &Sec->Data;
2095 return StringSwitch<StringRef *>(Name)
2096 .Case("debug_abbrev", &AbbrevSection)
2097 .Case("debug_aranges", &ArangesSection)
2098 .Case("debug_str", &StrSection)
2099 .Case("debug_macinfo", &MacinfoSection)
2100 .Case("debug_macinfo.dwo", &MacinfoDWOSection)
2101 .Case("debug_macro.dwo", &MacroDWOSection)
2102 .Case("debug_abbrev.dwo", &AbbrevDWOSection)
2103 .Case("debug_str.dwo", &StrDWOSection)
2104 .Case("debug_cu_index", &CUIndexSection)
2105 .Case("debug_tu_index", &TUIndexSection)
2106 .Case("gdb_index", &GdbIndexSection)
2107 .Case("debug_line_str", &LineStrSection)
2108 // Any more debug info sections go here.
2109 .Default(nullptr);
2110 }
2111
2112 /// If Sec is compressed section, decompresses and updates its contents
2113 /// provided by Data. Otherwise leaves it unchanged.
2114 Error maybeDecompress(const object::SectionRef &Sec, StringRef Name,
2115 StringRef &Data) {
2116 if (!Sec.isCompressed())
2117 return Error::success();
2118
2119 Expected<Decompressor> Decompressor =
2120 Decompressor::create(Name, Data, IsLittleEndian, AddressSize == 8);
2121 if (!Decompressor)
2122 return Decompressor.takeError();
2123
2124 SmallString<0> Out;
2125 if (auto Err = Decompressor->resizeAndDecompress(Out))
2126 return Err;
2127
2128 UncompressedSections.push_back(std::move(Out));
2129 Data = UncompressedSections.back();
2130
2131 return Error::success();
2132 }
2133
2134public:
2135 DWARFObjInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
2136 uint8_t AddrSize, bool IsLittleEndian)
2137 : IsLittleEndian(IsLittleEndian) {
2138 for (const auto &SecIt : Sections) {
2139 if (StringRef *SectionData = mapSectionToMember(SecIt.first()))
2140 *SectionData = SecIt.second->getBuffer();
2141 else if (SecIt.first() == "debug_info")
2142 // Find debug_info and debug_types data by section rather than name as
2143 // there are multiple, comdat grouped, of these sections.
2144 InfoSections[SectionRef()].Data = SecIt.second->getBuffer();
2145 else if (SecIt.first() == "debug_info.dwo")
2146 InfoDWOSections[SectionRef()].Data = SecIt.second->getBuffer();
2147 else if (SecIt.first() == "debug_types")
2148 TypesSections[SectionRef()].Data = SecIt.second->getBuffer();
2149 else if (SecIt.first() == "debug_types.dwo")
2150 TypesDWOSections[SectionRef()].Data = SecIt.second->getBuffer();
2151 }
2152 }
2153 DWARFObjInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
2154 function_ref<void(Error)> HandleError,
2155 function_ref<void(Error)> HandleWarning,
2157 : IsLittleEndian(Obj.isLittleEndian()),
2158 AddressSize(Obj.getBytesInAddress()), FileName(Obj.getFileName()),
2159 Obj(&Obj) {
2160
2161 StringMap<unsigned> SectionAmountMap;
2162 for (const SectionRef &Section : Obj.sections()) {
2163 StringRef Name;
2164 if (auto NameOrErr = Section.getName())
2165 Name = *NameOrErr;
2166 else
2167 consumeError(NameOrErr.takeError());
2168
2169 ++SectionAmountMap[Name];
2170 SectionNames.push_back({ Name, true });
2171
2172 // Skip BSS and Virtual sections, they aren't interesting.
2173 if (Section.isBSS() || Section.isVirtual())
2174 continue;
2175
2176 // Skip sections stripped by dsymutil.
2177 if (Section.isStripped())
2178 continue;
2179
2180 StringRef Data;
2181 Expected<section_iterator> SecOrErr = Section.getRelocatedSection();
2182 if (!SecOrErr) {
2183 HandleError(createError("failed to get relocated section: ",
2184 SecOrErr.takeError()));
2185 continue;
2186 }
2187
2188 // Try to obtain an already relocated version of this section.
2189 // Else use the unrelocated section from the object file. We'll have to
2190 // apply relocations ourselves later.
2191 section_iterator RelocatedSection =
2192 Obj.isRelocatableObject() ? *SecOrErr : Obj.section_end();
2193 if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data)) {
2194 Expected<StringRef> E = Section.getContents();
2195 if (E)
2196 Data = *E;
2197 else
2198 // maybeDecompress below will error.
2199 consumeError(E.takeError());
2200 }
2201
2202 if (auto Err = maybeDecompress(Section, Name, Data)) {
2203 HandleError(createError("failed to decompress '" + Name + "', ",
2204 std::move(Err)));
2205 continue;
2206 }
2207
2208 // Map platform specific debug section names to DWARF standard section
2209 // names.
2210 Name = Name.substr(Name.find_first_not_of("._"));
2211 Name = Obj.mapDebugSectionName(Name);
2212
2213 if (StringRef *SectionData = mapSectionToMember(Name)) {
2214 *SectionData = Data;
2215 if (Name == "debug_ranges") {
2216 // FIXME: Use the other dwo range section when we emit it.
2217 RangesDWOSection.Data = Data;
2218 } else if (Name == "debug_frame" || Name == "eh_frame") {
2219 if (DWARFSection *S = mapNameToDWARFSection(Name))
2220 S->Address = Section.getAddress();
2221 }
2222 } else if (InfoSectionMap *Sections =
2223 StringSwitch<InfoSectionMap *>(Name)
2224 .Case("debug_info", &InfoSections)
2225 .Case("debug_info.dwo", &InfoDWOSections)
2226 .Case("debug_types", &TypesSections)
2227 .Case("debug_types.dwo", &TypesDWOSections)
2228 .Default(nullptr)) {
2229 // Find debug_info and debug_types data by section rather than name as
2230 // there are multiple, comdat grouped, of these sections.
2231 DWARFSectionMap &S = (*Sections)[Section];
2232 S.Data = Data;
2233 }
2234
2235 if (RelocatedSection == Obj.section_end() ||
2236 (RelocAction == DWARFContext::ProcessDebugRelocations::Ignore))
2237 continue;
2238
2239 StringRef RelSecName;
2240 if (auto NameOrErr = RelocatedSection->getName())
2241 RelSecName = *NameOrErr;
2242 else
2243 consumeError(NameOrErr.takeError());
2244
2245 // If the section we're relocating was relocated already by the JIT,
2246 // then we used the relocated version above, so we do not need to process
2247 // relocations for it now.
2248 StringRef RelSecData;
2249 if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData))
2250 continue;
2251
2252 // In Mach-o files, the relocations do not need to be applied if
2253 // there is no load offset to apply. The value read at the
2254 // relocation point already factors in the section address
2255 // (actually applying the relocations will produce wrong results
2256 // as the section address will be added twice).
2257 if (!L && isa<MachOObjectFile>(&Obj))
2258 continue;
2259
2260 if (!Section.relocations().empty() && Name.ends_with(".dwo") &&
2261 RelSecName.starts_with(".debug")) {
2262 HandleWarning(createError("unexpected relocations for dwo section '" +
2263 RelSecName + "'"));
2264 }
2265
2266 // TODO: Add support for relocations in other sections as needed.
2267 // Record relocations for the debug_info and debug_line sections.
2268 RelSecName = RelSecName.substr(RelSecName.find_first_not_of("._"));
2269 DWARFSectionMap *Sec = mapNameToDWARFSection(RelSecName);
2270 RelocAddrMap *Map = Sec ? &Sec->Relocs : nullptr;
2271 if (!Map) {
2272 // Find debug_info and debug_types relocs by section rather than name
2273 // as there are multiple, comdat grouped, of these sections.
2274 if (RelSecName == "debug_info")
2275 Map = &static_cast<DWARFSectionMap &>(InfoSections[*RelocatedSection])
2276 .Relocs;
2277 else if (RelSecName == "debug_types")
2278 Map =
2279 &static_cast<DWARFSectionMap &>(TypesSections[*RelocatedSection])
2280 .Relocs;
2281 else
2282 continue;
2283 }
2284
2285 if (Section.relocations().empty())
2286 continue;
2287
2288 // Symbol to [address, section index] cache mapping.
2289 std::map<SymbolRef, SymInfo> AddrCache;
2290 SupportsRelocation Supports;
2291 RelocationResolver Resolver;
2292 std::tie(Supports, Resolver) = getRelocationResolver(Obj);
2293 for (const RelocationRef &Reloc : Section.relocations()) {
2294 // FIXME: it's not clear how to correctly handle scattered
2295 // relocations.
2296 if (isRelocScattered(Obj, Reloc))
2297 continue;
2298
2299 Expected<SymInfo> SymInfoOrErr =
2300 getSymbolInfo(Obj, Reloc, L, AddrCache);
2301 if (!SymInfoOrErr) {
2302 HandleError(SymInfoOrErr.takeError());
2303 continue;
2304 }
2305
2306 // Check if Resolver can handle this relocation type early so as not to
2307 // handle invalid cases in DWARFDataExtractor.
2308 //
2309 // TODO Don't store Resolver in every RelocAddrEntry.
2310 if (Supports && Supports(Reloc.getType())) {
2311 auto I = Map->try_emplace(
2312 Reloc.getOffset(),
2313 RelocAddrEntry{
2314 SymInfoOrErr->SectionIndex, Reloc, SymInfoOrErr->Address,
2315 std::optional<object::RelocationRef>(), 0, Resolver});
2316 // If we didn't successfully insert that's because we already had a
2317 // relocation for that offset. Store it as a second relocation in the
2318 // same RelocAddrEntry instead.
2319 if (!I.second) {
2320 RelocAddrEntry &entry = I.first->getSecond();
2321 if (entry.Reloc2) {
2322 HandleError(createError(
2323 "At most two relocations per offset are supported"));
2324 }
2325 entry.Reloc2 = Reloc;
2326 entry.SymbolValue2 = SymInfoOrErr->Address;
2327 }
2328 } else {
2330 Reloc.getTypeName(Type);
2331 // FIXME: Support more relocations & change this to an error
2332 HandleWarning(
2333 createError("failed to compute relocation: " + Type + ", ",
2334 errorCodeToError(object_error::parse_failed)));
2335 }
2336 }
2337 }
2338
2339 for (SectionName &S : SectionNames)
2340 if (SectionAmountMap[S.Name] > 1)
2341 S.IsNameUnique = false;
2342 }
2343
2344 std::optional<RelocAddrEntry> find(const DWARFSection &S,
2345 uint64_t Pos) const override {
2346 auto &Sec = static_cast<const DWARFSectionMap &>(S);
2347 RelocAddrMap::const_iterator AI = Sec.Relocs.find(Pos);
2348 if (AI == Sec.Relocs.end())
2349 return std::nullopt;
2350 return AI->second;
2351 }
2352
2353 const object::ObjectFile *getFile() const override { return Obj; }
2354
2355 ArrayRef<SectionName> getSectionNames() const override {
2356 return SectionNames;
2357 }
2358
2359 bool isLittleEndian() const override { return IsLittleEndian; }
2360 StringRef getAbbrevDWOSection() const override { return AbbrevDWOSection; }
2361 const DWARFSection &getLineDWOSection() const override {
2362 return LineDWOSection;
2363 }
2364 const DWARFSection &getLocDWOSection() const override {
2365 return LocDWOSection;
2366 }
2367 StringRef getStrDWOSection() const override { return StrDWOSection; }
2368 const DWARFSection &getStrOffsetsDWOSection() const override {
2369 return StrOffsetsDWOSection;
2370 }
2371 const DWARFSection &getRangesDWOSection() const override {
2372 return RangesDWOSection;
2373 }
2374 const DWARFSection &getRnglistsDWOSection() const override {
2375 return RnglistsDWOSection;
2376 }
2377 const DWARFSection &getLoclistsDWOSection() const override {
2378 return LoclistsDWOSection;
2379 }
2380 const DWARFSection &getAddrSection() const override { return AddrSection; }
2381 StringRef getCUIndexSection() const override { return CUIndexSection; }
2382 StringRef getGdbIndexSection() const override { return GdbIndexSection; }
2383 StringRef getTUIndexSection() const override { return TUIndexSection; }
2384
2385 // DWARF v5
2386 const DWARFSection &getStrOffsetsSection() const override {
2387 return StrOffsetsSection;
2388 }
2389 StringRef getLineStrSection() const override { return LineStrSection; }
2390
2391 // Sections for DWARF5 split dwarf proposal.
2392 void forEachInfoDWOSections(
2393 function_ref<void(const DWARFSection &)> F) const override {
2394 for (auto &P : InfoDWOSections)
2395 F(P.second);
2396 }
2397 void forEachTypesDWOSections(
2398 function_ref<void(const DWARFSection &)> F) const override {
2399 for (auto &P : TypesDWOSections)
2400 F(P.second);
2401 }
2402
2403 StringRef getAbbrevSection() const override { return AbbrevSection; }
2404 const DWARFSection &getLocSection() const override { return LocSection; }
2405 const DWARFSection &getLoclistsSection() const override { return LoclistsSection; }
2406 StringRef getArangesSection() const override { return ArangesSection; }
2407 const DWARFSection &getFrameSection() const override {
2408 return FrameSection;
2409 }
2410 const DWARFSection &getEHFrameSection() const override {
2411 return EHFrameSection;
2412 }
2413 const DWARFSection &getLineSection() const override { return LineSection; }
2414 StringRef getStrSection() const override { return StrSection; }
2415 const DWARFSection &getRangesSection() const override { return RangesSection; }
2416 const DWARFSection &getRnglistsSection() const override {
2417 return RnglistsSection;
2418 }
2419 const DWARFSection &getMacroSection() const override { return MacroSection; }
2420 StringRef getMacroDWOSection() const override { return MacroDWOSection; }
2421 StringRef getMacinfoSection() const override { return MacinfoSection; }
2422 StringRef getMacinfoDWOSection() const override { return MacinfoDWOSection; }
2423 const DWARFSection &getPubnamesSection() const override { return PubnamesSection; }
2424 const DWARFSection &getPubtypesSection() const override { return PubtypesSection; }
2425 const DWARFSection &getGnuPubnamesSection() const override {
2426 return GnuPubnamesSection;
2427 }
2428 const DWARFSection &getGnuPubtypesSection() const override {
2429 return GnuPubtypesSection;
2430 }
2431 const DWARFSection &getAppleNamesSection() const override {
2432 return AppleNamesSection;
2433 }
2434 const DWARFSection &getAppleTypesSection() const override {
2435 return AppleTypesSection;
2436 }
2437 const DWARFSection &getAppleNamespacesSection() const override {
2438 return AppleNamespacesSection;
2439 }
2440 const DWARFSection &getAppleObjCSection() const override {
2441 return AppleObjCSection;
2442 }
2443 const DWARFSection &getNamesSection() const override {
2444 return NamesSection;
2445 }
2446
2447 StringRef getFileName() const override { return FileName; }
2448 uint8_t getAddressSize() const override { return AddressSize; }
2449 void forEachInfoSections(
2450 function_ref<void(const DWARFSection &)> F) const override {
2451 for (auto &P : InfoSections)
2452 F(P.second);
2453 }
2454 void forEachTypesSections(
2455 function_ref<void(const DWARFSection &)> F) const override {
2456 for (auto &P : TypesSections)
2457 F(P.second);
2458 }
2459};
2460} // namespace
2461
2462std::unique_ptr<DWARFContext>
2464 ProcessDebugRelocations RelocAction,
2465 const LoadedObjectInfo *L, std::string DWPName,
2466 std::function<void(Error)> RecoverableErrorHandler,
2467 std::function<void(Error)> WarningHandler,
2468 bool ThreadSafe) {
2469 auto DObj = std::make_unique<DWARFObjInMemory>(
2470 Obj, L, RecoverableErrorHandler, WarningHandler, RelocAction);
2471 return std::make_unique<DWARFContext>(std::move(DObj),
2472 std::move(DWPName),
2473 RecoverableErrorHandler,
2474 WarningHandler,
2475 ThreadSafe);
2476}
2477
2478std::unique_ptr<DWARFContext>
2479DWARFContext::create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
2480 uint8_t AddrSize, bool isLittleEndian,
2481 std::function<void(Error)> RecoverableErrorHandler,
2482 std::function<void(Error)> WarningHandler,
2483 bool ThreadSafe) {
2484 auto DObj =
2485 std::make_unique<DWARFObjInMemory>(Sections, AddrSize, isLittleEndian);
2486 return std::make_unique<DWARFContext>(
2487 std::move(DObj), "", RecoverableErrorHandler, WarningHandler, ThreadSafe);
2488}
2489
2491 // In theory, different compile units may have different address byte
2492 // sizes, but for simplicity we just use the address byte size of the
2493 // first compile unit. In practice the address size field is repeated across
2494 // various DWARF headers (at least in version 5) to make it easier to dump
2495 // them independently, not to enable varying the address size.
2496 auto CUs = compile_units();
2497 return CUs.empty() ? 0 : (*CUs.begin())->getAddressByteSize();
2498}
2499
2500bool DWARFContext::isDWP() const { return !DObj->getCUIndexSection().empty(); }
unsigned uint64_t
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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")
@ Default
This file contains constants used for implementing Dwarf debug support.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
This file implements a map that provides insertion order iteration.
#define T
#define P(N)
if(PassOpts->AAPipeline)
Func MI getDebugLoc()))
This file contains some templates that are useful if you are working with the STL at all.
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
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
iterator end() const
Definition ArrayRef.h:130
size_t size() const
Get the array size.
Definition ArrayRef.h:141
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
const T * data() const
Definition ArrayRef.h:138
DIContext(DIContextKind K)
Definition DIContext.h:246
A structured debug information entry.
Definition DIE.h:842
dwarf::Tag getTag() const
Definition DIE.h:878
A format-neutral container for inlined code description.
Definition DIContext.h:94
void addFrame(const DILineInfo &Frame)
Definition DIContext.h:114
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() override
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()
unsigned getMaxVersion()
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
uint64_t getRelocatedValue(uint32_t Size, uint64_t *Off, uint64_t *SectionIndex=nullptr, Error *Err=nullptr) const
Extracts a value and returns it as adjusted by the Relocator.
A DWARFDataExtractor (typically for an in-memory copy of an object-file section) plus a relocation ma...
LLVM_ABI void dump(raw_ostream &OS) const
A class representing an address table as specified in DWARF v5.
LLVM_ABI void dump(raw_ostream &OS, DIDumpOptions DumpOpts={}) const
LLVM_ABI 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.
LLVM_ABI 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)
LLVM_ABI 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 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.
Definition DWARFDie.h:43
LLVM_ABI DWARFDie getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE as the referenced DIE.
Definition DWARFDie.cpp:376
LLVM_ABI std::optional< DWARFFormValue > find(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE.
Definition DWARFDie.cpp:320
DWARFUnit * getDwarfUnit() const
Definition DWARFDie.h:55
LLVM_ABI const char * getSubroutineName(DINameKind Kind) const
If a DIE represents a subprogram (or inlined subroutine), returns its mangled name (or short name,...
Definition DWARFDie.cpp:539
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...
Definition DWARFDie.cpp:584
LLVM_ABI std::string getDeclFile(DILineInfoSpecifier::FileLineInfoKind Kind) const
Definition DWARFDie.cpp:577
LLVM_ABI uint64_t getDeclLine() const
Returns the declaration line (start line) for a DIE, assuming it specifies a subprogram.
Definition DWARFDie.cpp:572
dwarf::Tag getTag() const
Definition DWARFDie.h:73
LLVM_ABI Expected< DWARFLocationExpressionsVector > getLocations(dwarf::Attribute Attr) const
Definition DWARFDie.cpp:509
bool isValid() const
Definition DWARFDie.h:52
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.
Definition DWARFDie.cpp:677
LLVM_ABI 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
A class representing the header of a list table such as the range list table in the ....
virtual StringRef getFileName() const
Definition DWARFObject.h:31
virtual StringRef getAbbrevDWOSection() const
Definition DWARFObject.h:64
virtual const DWARFSection & getFrameSection() const
Definition DWARFObject.h:44
virtual const DWARFSection & getNamesSection() const
Definition DWARFObject.h:80
virtual const DWARFSection & getAppleNamespacesSection() const
Definition DWARFObject.h:77
virtual void forEachInfoDWOSections(function_ref< void(const DWARFSection &)> F) const
Definition DWARFObject.h:61
virtual const DWARFSection & getAppleTypesSection() const
Definition DWARFObject.h:76
virtual void forEachInfoSections(function_ref< void(const DWARFSection &)> F) const
Definition DWARFObject.h:37
virtual const DWARFSection & getAppleNamesSection() const
Definition DWARFObject.h:75
virtual const DWARFSection & getEHFrameSection() const
Definition DWARFObject.h:45
virtual void forEachTypesSections(function_ref< void(const DWARFSection &)> F) const
Definition DWARFObject.h:39
virtual const DWARFSection & getLocSection() const
Definition DWARFObject.h:41
virtual const DWARFSection & getAppleObjCSection() const
Definition DWARFObject.h:81
virtual void forEachTypesDWOSections(function_ref< void(const DWARFSection &)> F) const
Definition DWARFObject.h:63
virtual StringRef getStrSection() const
Definition DWARFObject.h:48
virtual uint8_t getAddressSize() const
Definition DWARFObject.h:35
Base class describing the header of any kind of "unit." Some information is specific to certain unit ...
Definition DWARFUnit.h:55
LLVM_ABI void dump(raw_ostream &OS) const
Describe a collection of units.
Definition DWARFUnit.h:129
void finishedInfoUnits()
Indicate that parsing .debug_info[.dwo] is done, and remaining units will be from ....
Definition DWARFUnit.h:181
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.
Definition DWARFUnit.cpp:42
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.
Definition DWARFUnit.cpp:53
DWARFContext & getContext() const
Definition DWARFUnit.h:326
void clearDWO()
Release the DWO context owned by this skeleton unit, freeing the memory held by its DWARFContext and ...
Definition DWARFUnit.h:472
DWARFDie getDIEForOffset(uint64_t Offset)
Return the DIE object for a given offset Offset inside the unit's DIE vector.
Definition DWARFUnit.h:550
const char * getCompilationDir()
DWARFUnit * getDWO() const
Return the split unit this skeleton unit currently owns, or null if its DWO context is not open.
Definition DWARFUnit.h:466
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,...
const char * getCStr(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a C string from *offset_ptr.
bool isValidOffset(uint64_t offset) const
Test the validity of offset.
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT, true > const_iterator
Definition DenseMap.h:134
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
Error takeError()
Take ownership of the stored error.
Definition Error.h:612
An inferface for inquiring the load address of a loaded object file to be used by the DIContext imple...
Definition DIContext.h:282
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
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",...
Definition StringMap.h:128
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr size_t size() const
Get the string size.
Definition StringRef.h:144
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
static Twine utohexstr(uint64_t Val)
Definition Twine.h:385
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
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.
Definition ObjectFile.h:231
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
This is a value type class that represents a single relocation in the list of relocations in the obje...
Definition ObjectFile.h:54
uint64_t getIndex() const
Definition ObjectFile.h:530
bool isCompressed() const
Definition ObjectFile.h:551
uint64_t getAddress() const
Definition ObjectFile.h:526
Expected< StringRef > getName() const
Definition ObjectFile.h:522
Expected< uint64_t > getAddress() const
Returns the symbol virtual address (i.e.
Definition ObjectFile.h:469
Expected< section_iterator > getSection() const
Get section this symbol is defined in reference to.
Definition ObjectFile.h:485
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
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)
Definition Dwarf.cpp:1062
@ Entry
Definition COFF.h:862
static constexpr StringLiteral SectionNames[SectionKindsNum]
Calculates the starting offsets for various sections within the .debug_names section.
Definition Dwarf.h:35
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.
Definition Dwarf.h:93
@ DWARF32
Definition Dwarf.h:93
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.
Definition Dwarf.h:1186
std::optional< uint64_t > toUnsigned(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an unsigned constant.
content_iterator< SectionRef > section_iterator
Definition ObjectFile.h:49
Error createError(const Twine &Err)
Definition Error.h:86
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.
Definition Path.cpp:607
SmartMutex< false > Mutex
Mutex - A standard, always enforced mutex.
Definition Mutex.h:66
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
@ Length
Definition DWP.cpp:577
LLVM_ABI void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
Definition Error.cpp:61
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1765
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition Error.cpp:94
SmallVector< std::pair< uint64_t, DILineInfo >, 16 > DILineInfoTable
Definition DIContext.h:91
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2208
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.
Definition LEB128.h:169
auto unique(Range &&R, Predicate P)
Definition STLExtras.h:2134
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1321
@ DW_SECT_EXT_TYPES
@ invalid_argument
Definition Errc.h:56
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1636
static Error createError(const Twine &Err)
Definition APFloat.cpp:409
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...
Definition Casting.h:547
@ Success
The lock was released successfully.
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
Definition Error.h:340
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
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.
Definition STLExtras.h:1917
support::detail::AlignAdapter< T > fmt_align(T &&Item, AlignStyle Where, size_t Amount, char Fill=' ')
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition Error.cpp:107
@ DIDT_ID_Count
Definition DIContext.h:179
@ DIDT_All
Definition DIContext.h:186
@ DIDT_UUID
Definition DIContext.h:191
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.
Definition Error.h:1106
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
SymInfo contains information about symbol: it's address and section index which is -1LL for absolute ...
uint64_t Address
uint64_t SectionIndex
Container for dump options that control which debug information will be dumped.
Definition DIContext.h:196
std::function< void(Error)> WarningHandler
Definition DIContext.h:239
std::function< void(Error)> RecoverableErrorHandler
Definition DIContext.h:237
DIDumpOptions noImplicitRecursion() const
Return the options with RecurseDepth set to 0 unless explicitly required.
Definition DIContext.h:228
Controls which fields of DILineInfo container should be filled with data.
Definition DIContext.h:146
A format-neutral container for source line information.
Definition DIContext.h:32
static constexpr const char *const BadString
Definition DIContext.h:35
std::optional< uint64_t > StartAddress
Definition DIContext.h:49
uint32_t Discriminator
Definition DIContext.h:52
uint32_t Line
Definition DIContext.h:46
std::string FileName
Definition DIContext.h:38
std::string FunctionName
Definition DIContext.h:39
uint32_t Column
Definition DIContext.h:47
uint32_t StartLine
Definition DIContext.h:48
std::string StartFileName
Definition DIContext.h:40
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.