LLVM: lib/DebugInfo/DWARF/DWARFContext.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

54#include

55#include

56#include

57#include

58#include

59#include

60

61using namespace llvm;

62using namespace dwarf;

63using namespace object;

64

65#define DEBUG_TYPE "dwarf"

66

70

71

75 EntryMap Map;

76 const auto &DObj = C.getDWARFObj();

77 if (DObj.getCUIndexSection().empty())

78 return;

79

82 DObj.forEachInfoDWOSections([&](const DWARFSection &S) {

83 if (!(C.getParseCUTUIndexManually() ||

84 S.Data.size() >= std::numeric_limits<uint32_t>::max()))

85 return;

86

90 if (Error ExtractionErr = Header.extract(

91 C, Data, &Offset, DWARFSectionKind::DW_SECT_INFO)) {

92 C.getWarningHandler()(

93 createError("Failed to parse CU header in DWP file: " +

94 toString(std::move(ExtractionErr))));

95 Map.clear();

96 break;

97 }

98

99 auto Iter = Map.insert({TruncOffset,

100 {Header.getOffset(), Header.getNextUnitOffset() -

101 Header.getOffset()}});

102 if (!Iter.second) {

104 createError("Collision occured between for truncated offset 0x" +

107 Map.clear();

108 return;

109 }

110

111 Offset = Header.getNextUnitOffset();

112 TruncOffset = Offset;

113 }

114 });

115

116 if (Map.empty())

117 return;

118

120 if (E.isValid())

121 continue;

123 auto Iter = Map.find(CUOff.getOffset());

124 if (Iter == Map.end()) {

127 " in the Map"),

129 break;

130 }

131 CUOff.setOffset(Iter->second.getOffset());

132 if (CUOff.getOffset() != Iter->second.getOffset())

134 "match calculated length at offset 0x" +

137 }

138}

139

142

143 const auto &DObj = C.getDWARFObj();

144 DObj.forEachInfoDWOSections([&](const DWARFSection &S) {

145 if (!(C.getParseCUTUIndexManually() ||

146 S.Data.size() >= std::numeric_limits<uint32_t>::max()))

147 return;

152 if (Error ExtractionErr = Header.extract(

153 C, Data, &Offset, DWARFSectionKind::DW_SECT_INFO)) {

154 C.getWarningHandler()(

155 createError("Failed to parse CU header in DWP file: " +

156 toString(std::move(ExtractionErr))));

157 break;

158 }

159 bool CU = Header.getUnitType() == DW_UT_split_compile;

160 uint64_t Sig = CU ? *Header.getDWOId() : Header.getTypeHash();

161 Map[Sig] = Header.getOffset();

162 Offset = Header.getNextUnitOffset();

163 }

164 });

165 if (Map.empty())

166 return;

168 if (E.isValid())

169 continue;

171 auto Iter = Map.find(E.getSignature());

172 if (Iter == Map.end()) {

174 createError("Could not find unit with signature 0x" +

177 break;

178 }

180 }

181}

182

184 if (Index.getVersion() < 5)

186 else

188}

189

190template

193 bool IsLittleEndian) {

194 if (Cache)

195 return *Cache;

197 DataExtractor StrData(StringSection, IsLittleEndian, 0);

198 Cache = std::make_unique(AccelSection, StrData);

199 if (Error E = Cache->extract())

201 return *Cache;

202}

203

204

205std::unique_ptr

207 auto Macro = std::make_unique();

210 ? D.compile_units()

211 : D.dwo_compile_units(),

213 ? D.getStringExtractor()

214 : D.getStringDWOExtractor(),

217 D.getRecoverableErrorHandler()(std::move(Err));

219 }

220 };

222 switch (SectionType) {

225 ParseAndDump(Data, false);

226 break;

227 }

230 ParseAndDump(Data, false);

231 break;

232 }

235 0);

236 ParseAndDump(Data, true);

237 break;

238 }

241 ParseAndDump(Data, true);

242 break;

243 }

244 }

246}

247

248namespace {

250

252 std::optional<DenseMap<uint64_t, DWARFTypeUnit *>> NormalTypeUnits;

253 std::unique_ptr CUIndex;

254 std::unique_ptr GdbIndex;

255 std::unique_ptr TUIndex;

256 std::unique_ptr Abbrev;

257 std::unique_ptr Loc;

258 std::unique_ptr Aranges;

259 std::unique_ptr Line;

260 std::unique_ptr DebugFrame;

261 std::unique_ptr EHFrame;

262 std::unique_ptr Macro;

263 std::unique_ptr Macinfo;

264 std::unique_ptr Names;

265 std::unique_ptr AppleNames;

266 std::unique_ptr AppleTypes;

268 std::unique_ptr AppleObjC;

270 std::optional<DenseMap<uint64_t, DWARFTypeUnit *>> DWOTypeUnits;

271 std::unique_ptr AbbrevDWO;

272 std::unique_ptr MacinfoDWO;

273 std::unique_ptr MacroDWO;

274 struct DWOFile {

276 std::unique_ptr Context;

277 };

279 std::weak_ptr DWP;

280 bool CheckedForDWP = false;

281 std::string DWPName;

282

283public:

284 ThreadUnsafeDWARFContextState(DWARFContext &DC, std::string &DWP) :

286 DWPName(std::move(DWP)) {}

287

289 if (NormalUnits.empty()) {

293 });

297 });

298 }

299 return NormalUnits;

300 }

301

302 DWARFUnitVector &getDWOUnits(bool Lazy) override {

303 if (DWOUnits.empty()) {

304 const DWARFObject &DObj = D.getDWARFObj();

305

308 });

312 });

313 }

314 return DWOUnits;

315 }

316

317 const DWARFDebugAbbrev *getDebugAbbrevDWO() override {

318 if (AbbrevDWO)

319 return AbbrevDWO.get();

320 const DWARFObject &DObj = D.getDWARFObj();

322 AbbrevDWO = std::make_unique(abbrData);

323 return AbbrevDWO.get();

324 }

325

326 const DWARFUnitIndex &getCUIndex() override {

327 if (CUIndex)

328 return *CUIndex;

329

330 DataExtractor Data(D.getDWARFObj().getCUIndexSection(),

331 D.isLittleEndian(), 0);

332 CUIndex = std::make_unique(DW_SECT_INFO);

333 if (CUIndex->parse(Data))

335 return *CUIndex;

336 }

337 const DWARFUnitIndex &getTUIndex() override {

338 if (TUIndex)

339 return *TUIndex;

340

341 DataExtractor Data(D.getDWARFObj().getTUIndexSection(),

342 D.isLittleEndian(), 0);

344 bool isParseSuccessful = TUIndex->parse(Data);

345

346

347 if (isParseSuccessful && TUIndex->getVersion() != 2)

349 return *TUIndex;

350 }

351

352 DWARFGdbIndex &getGdbIndex() override {

353 if (GdbIndex)

354 return *GdbIndex;

355

356 DataExtractor Data(D.getDWARFObj().getGdbIndexSection(), true , 0);

357 GdbIndex = std::make_unique();

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(),

367 D.isLittleEndian(), 0);

368 Abbrev = std::make_unique(Data);

369 return Abbrev.get();

370 }

371

372 const DWARFDebugLoc *getDebugLoc() override {

373 if (Loc)

374 return Loc.get();

375

376 const DWARFObject &DObj = D.getDWARFObj();

377

379 D.getNumCompileUnits()

380 ? DWARFDataExtractor(DObj, DObj.getLocSection(), D.isLittleEndian(),

381 D.getUnitAtIndex(0)->getAddressByteSize())

382 : DWARFDataExtractor("", D.isLittleEndian(), 0);

383 Loc = std::make_unique(std::move(Data));

384 return Loc.get();

385 }

386

387 const DWARFDebugAranges *getDebugAranges() override {

388 if (Aranges)

389 return Aranges.get();

390

391 Aranges = std::make_unique();

392 Aranges->generate(&D);

393 return Aranges.get();

394 }

395

396 Expected<const DWARFDebugLine::LineTable *>

397 getLineTableForUnit(DWARFUnit *U, function_ref<void(Error)> RecoverableErrorHandler) override {

398 if (!Line)

399 Line = std::make_unique();

400

401 auto UnitDIE = U->getUnitDIE();

402 if (!UnitDIE)

403 return nullptr;

404

407 return nullptr;

408

409 uint64_t stmtOffset = *Offset + U->getLineTableOffset();

410

412 return lt;

413

414

415 if (stmtOffset >= U->getLineSection().Data.size())

416 return nullptr;

417

418

419 DWARFDataExtractor Data(U->getContext().getDWARFObj(), U->getLineSection(),

420 U->isLittleEndian(), U->getAddressByteSize());

421 return Line->getOrParseLineTable(Data, stmtOffset, U->getContext(), U,

422 RecoverableErrorHandler);

423

424 }

425

426 void clearLineTableForUnit(DWARFUnit *U) override {

427 if (!Line)

428 return;

429

430 auto UnitDIE = U->getUnitDIE();

431 if (!UnitDIE)

432 return;

433

436 return;

437

438 uint64_t stmtOffset = *Offset + U->getLineTableOffset();

439 Line->clearLineTable(stmtOffset);

440 }

441

442 Expected<const DWARFDebugFrame *> getDebugFrame() override {

445 const DWARFObject &DObj = D.getDWARFObj();

447

448

449

450

451

452

453

454

455

456

457 DWARFDataExtractor Data(DObj, DS, D.isLittleEndian(),

459 auto DF =

460 std::make_unique(D.getArch(), false,

461 DS.Address);

463 return std::move(E);

464

467 }

468

469 Expected<const DWARFDebugFrame *> getEHFrame() override {

470 if (EHFrame)

471 return EHFrame.get();

472 const DWARFObject &DObj = D.getDWARFObj();

473

475 DWARFDataExtractor Data(DObj, DS, D.isLittleEndian(),

477 auto DF =

478 std::make_unique(D.getArch(), true,

479 DS.Address);

481 return std::move(E);

482 EHFrame.swap(DF);

483 return EHFrame.get();

484 }

485

486 const DWARFDebugMacro *getDebugMacinfo() override {

487 if (!Macinfo)

488 Macinfo = parseMacroOrMacinfo(MacinfoSection);

489 return Macinfo.get();

490 }

491 const DWARFDebugMacro *getDebugMacinfoDWO() override {

492 if (!MacinfoDWO)

493 MacinfoDWO = parseMacroOrMacinfo(MacinfoDwoSection);

494 return MacinfoDWO.get();

495 }

496 const DWARFDebugMacro *getDebugMacro() override {

498 Macro = parseMacroOrMacinfo(MacroSection);

499 return Macro.get();

500 }

501 const DWARFDebugMacro *getDebugMacroDWO() override {

502 if (!MacroDWO)

503 MacroDWO = parseMacroOrMacinfo(MacroDwoSection);

504 return MacroDWO.get();

505 }

506 const DWARFDebugNames &getDebugNames() override {

507 const DWARFObject &DObj = D.getDWARFObj();

510 }

511 const AppleAcceleratorTable &getAppleNames() override {

512 const DWARFObject &DObj = D.getDWARFObj();

515

516 }

517 const AppleAcceleratorTable &getAppleTypes() override {

518 const DWARFObject &DObj = D.getDWARFObj();

521

522 }

523 const AppleAcceleratorTable &getAppleNamespaces() override {

524 const DWARFObject &DObj = D.getDWARFObj();

528

529 }

530 const AppleAcceleratorTable &getAppleObjC() override {

531 const DWARFObject &DObj = D.getDWARFObj();

534 }

535

536 std::shared_ptr

537 getDWOContext(StringRef AbsolutePath) override {

538 if (auto S = DWP.lock()) {

539 DWARFContext *Ctxt = S->Context.get();

540 return std::shared_ptr(std::move(S), Ctxt);

541 }

542

543 std::weak_ptr *Entry = &DWOFiles[AbsolutePath];

544

545 if (auto S = Entry->lock()) {

546 DWARFContext *Ctxt = S->Context.get();

547 return std::shared_ptr(std::move(S), Ctxt);

548 }

549

550 const DWARFObject &DObj = D.getDWARFObj();

551

552 Expected<OwningBinary> Obj = [&] {

553 if (!CheckedForDWP) {

554 SmallString<128> DWPName;

556 this->DWPName.empty()

557 ? (DObj.getFileName() + ".dwp").toStringRef(DWPName)

558 : StringRef(this->DWPName));

559 if (Obj) {

561 return Obj;

562 } else {

563 CheckedForDWP = true;

564

565

567 }

568 }

569

571 }();

572

573 if (!Obj) {

574

576 return nullptr;

577 }

578

579 auto S = std::make_shared();

580 S->File = std::move(Obj.get());

581

582

583 bool ThreadSafe = isThreadSafe();

585 *S->File.getBinary(), DWARFContext::ProcessDebugRelocations::Ignore,

589 auto *Ctxt = S->Context.get();

590 return std::shared_ptr(std::move(S), Ctxt);

591 }

592

593 bool isThreadSafe() const override { return false; }

594

595 const DenseMap<uint64_t, DWARFTypeUnit *> &getNormalTypeUnitMap() {

596 if (!NormalTypeUnits) {

597 NormalTypeUnits.emplace();

598 for (const auto &U :D.normal_units()) {

600 (*NormalTypeUnits)[TU->getTypeHash()] = TU;

601 }

602 }

603 return *NormalTypeUnits;

604 }

605

606 const DenseMap<uint64_t, DWARFTypeUnit *> &getDWOTypeUnitMap() {

607 if (!DWOTypeUnits) {

608 DWOTypeUnits.emplace();

609 for (const auto &U :D.dwo_units()) {

611 (*DWOTypeUnits)[TU->getTypeHash()] = TU;

612 }

613 }

614 return *DWOTypeUnits;

615 }

616

617 const DenseMap<uint64_t, DWARFTypeUnit *> &

618 getTypeUnitMap(bool IsDWO) override {

619 if (IsDWO)

620 return getDWOTypeUnitMap();

621 else

622 return getNormalTypeUnitMap();

623 }

624};

625

626class ThreadSafeState : public ThreadUnsafeDWARFContextState {

627 std::recursive_mutex Mutex;

628

629public:

630 ThreadSafeState(DWARFContext &DC, std::string &DWP) :

631 ThreadUnsafeDWARFContextState(DC, DWP) {}

632

633 DWARFUnitVector &getNormalUnits() override {

634 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);

635 return ThreadUnsafeDWARFContextState::getNormalUnits();

636 }

637 DWARFUnitVector &getDWOUnits(bool Lazy) override {

638 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);

639

640

641

642 return ThreadUnsafeDWARFContextState::getDWOUnits(false);

643 }

644 const DWARFUnitIndex &getCUIndex() override {

645 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);

646 return ThreadUnsafeDWARFContextState::getCUIndex();

647 }

648 const DWARFDebugAbbrev *getDebugAbbrevDWO() override {

649 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);

650 return ThreadUnsafeDWARFContextState::getDebugAbbrevDWO();

651 }

652

653 const DWARFUnitIndex &getTUIndex() override {

654 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);

655 return ThreadUnsafeDWARFContextState::getTUIndex();

656 }

657 DWARFGdbIndex &getGdbIndex() override {

658 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);

659 return ThreadUnsafeDWARFContextState::getGdbIndex();

660 }

661 const DWARFDebugAbbrev *getDebugAbbrev() override {

662 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);

663 return ThreadUnsafeDWARFContextState::getDebugAbbrev();

664 }

665 const DWARFDebugLoc *getDebugLoc() override {

666 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);

667 return ThreadUnsafeDWARFContextState::getDebugLoc();

668 }

669 const DWARFDebugAranges *getDebugAranges() override {

670 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);

671 return ThreadUnsafeDWARFContextState::getDebugAranges();

672 }

673 Expected<const DWARFDebugLine::LineTable *>

674 getLineTableForUnit(DWARFUnit *U, function_ref<void(Error)> RecoverableErrorHandler) override {

675 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);

676 return ThreadUnsafeDWARFContextState::getLineTableForUnit(U, RecoverableErrorHandler);

677 }

678 void clearLineTableForUnit(DWARFUnit *U) override {

679 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);

680 return ThreadUnsafeDWARFContextState::clearLineTableForUnit(U);

681 }

682 Expected<const DWARFDebugFrame *> getDebugFrame() override {

683 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);

684 return ThreadUnsafeDWARFContextState::getDebugFrame();

685 }

686 Expected<const DWARFDebugFrame *> getEHFrame() override {

687 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);

688 return ThreadUnsafeDWARFContextState::getEHFrame();

689 }

690 const DWARFDebugMacro *getDebugMacinfo() override {

691 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);

692 return ThreadUnsafeDWARFContextState::getDebugMacinfo();

693 }

694 const DWARFDebugMacro *getDebugMacinfoDWO() override {

695 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);

696 return ThreadUnsafeDWARFContextState::getDebugMacinfoDWO();

697 }

698 const DWARFDebugMacro *getDebugMacro() override {

699 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);

700 return ThreadUnsafeDWARFContextState::getDebugMacro();

701 }

702 const DWARFDebugMacro *getDebugMacroDWO() override {

703 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);

704 return ThreadUnsafeDWARFContextState::getDebugMacroDWO();

705 }

706 const DWARFDebugNames &getDebugNames() override {

707 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);

708 return ThreadUnsafeDWARFContextState::getDebugNames();

709 }

710 const AppleAcceleratorTable &getAppleNames() override {

711 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);

712 return ThreadUnsafeDWARFContextState::getAppleNames();

713 }

714 const AppleAcceleratorTable &getAppleTypes() override {

715 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);

716 return ThreadUnsafeDWARFContextState::getAppleTypes();

717 }

718 const AppleAcceleratorTable &getAppleNamespaces() override {

719 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);

720 return ThreadUnsafeDWARFContextState::getAppleNamespaces();

721 }

722 const AppleAcceleratorTable &getAppleObjC() override {

723 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);

724 return ThreadUnsafeDWARFContextState::getAppleObjC();

725 }

726 std::shared_ptr

727 getDWOContext(StringRef AbsolutePath) override {

728 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);

729 return ThreadUnsafeDWARFContextState::getDWOContext(AbsolutePath);

730 }

731

732 bool isThreadSafe() const override { return true; }

733

734 const DenseMap<uint64_t, DWARFTypeUnit *> &

735 getTypeUnitMap(bool IsDWO) override {

736 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);

737 return ThreadUnsafeDWARFContextState::getTypeUnitMap(IsDWO);

738 }

739};

740}

741

743 std::string DWPName,

744 std::function<void(Error)> RecoverableErrorHandler,

745 std::function<void(Error)> WarningHandler,

746 bool ThreadSafe)

748 RecoverableErrorHandler(RecoverableErrorHandler),

749 WarningHandler(WarningHandler), DObj(std::move(DObj)) {

750 if (ThreadSafe)

751 State = std::make_unique(*this, DWPName);

752 else

753 State = std::make_unique(*this, DWPName);

754 }

755

757

758

762 return;

763 for (auto LC : MachO->load_commands()) {

765 if (LC.C.cmd == MachO::LC_UUID) {

766 if (LC.C.cmdsize < sizeof(UUID) + sizeof(LC.C)) {

767 OS << "error: UUID load command is too short.\n";

768 return;

769 }

770 OS << "UUID: ";

771 memcpy(&UUID, LC.Ptr+sizeof(LC.C), sizeof(UUID));

774 OS << " (" << T.getArchName() << ')';

775 OS << ' ' << MachO->getFileName() << '\n';

776 }

777 }

778}

779

781 std::vector<std::optional>;

782

783

784

788 for (const auto &U : Units)

789 if (const auto &C = U->getStringOffsetsTableContribution())

790 Contributions.push_back(C);

791

792

793

795 [](const std::optional &L,

796 const std::optional &R) {

797 if (L && R)

798 return L->Base < R->Base;

799 return R.has_value();

800 });

801

802

803

804

805 Contributions.erase(

807 Contributions,

808 [](const std::optional &L,

809 const std::optional &R) {

810 if (L && R)

811 return L->Base == R->Base && L->Size == R->Size;

812 return false;

813 }),

814 Contributions.end());

815 return Contributions;

816}

817

818

819

820

821

822

823

824

825

832 bool LittleEndian) {

834 DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0);

835 DataExtractor StrData(StringSection, LittleEndian, 0);

838 for (auto &Contribution : Contributions) {

839

840 if (!Contribution) {

841 OS << "error: invalid contribution to string offsets table in section ."

843 return;

844 }

845

848 uint16_t Version = Contribution->getVersion();

849 uint64_t ContributionHeader = Contribution->Base;

850

851

852

853

854 if (Version >= 5)

855 ContributionHeader -= Format == DWARF32 ? 8 : 16;

856

857

858 if (Offset > ContributionHeader) {

861 "overlapping contributions to string offsets table in section .%s.",

863 }

864

865 if (Offset < ContributionHeader) {

866 OS << format("0x%8.8" PRIx64 ": Gap, length = ", Offset);

867 OS << (ContributionHeader - Offset) << "\n";

868 }

869 OS << format("0x%8.8" PRIx64 ": ", ContributionHeader);

870

871

872

873

874 OS << "Contribution size = " << (Contribution->Size + (Version < 5 ? 0 : 4))

876 << ", Version = " << Version << "\n";

877

878 Offset = Contribution->Base;

879 unsigned EntrySize = Contribution->getDwarfOffsetByteSize();

880 while (Offset - Contribution->Base < Contribution->Size) {

884 OS << format("%0*" PRIx64 " ", OffsetDumpWidth, StringOffset);

885 const char *S = StrData.getCStr(&StringOffset);

886 if (S)

887 OS << format("\"%s\"", S);

888 OS << "\n";

889 }

890 }

891

892 if (Offset < SectionSize) {

893 OS << format("0x%8.8" PRIx64 ": Gap, length = ", Offset);

894 OS << (SectionSize - Offset) << "\n";

895 }

896}

897

898

906 if (Error Err = AddrTable.extract(AddrData, &Offset, Version, AddrSize,

909

910

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

925 LookupPooledAddress,

934

935

937 break;

939 } else {

940 Rnglists.dump(rnglistData, OS, LookupPooledAddress, DumpOpts);

941 }

942 }

943}

944

945

948 std::optional<uint64_t> DumpOffset) {

950

955 return;

956 }

957

958 Header.dump(Data, OS, DumpOpts);

959

960 uint64_t EndOffset = Header.length() + Header.getHeaderOffset();

961 Data.setAddressSize(Header.getAddrSize());

963 if (DumpOffset) {

964 if (DumpOffset >= Offset && DumpOffset < EndOffset) {

965 Offset = *DumpOffset;

966 Loc.dumpLocationList(&Offset, OS, std::nullopt, Obj,

967 nullptr, DumpOpts, 0);

968 OS << "\n";

969 return;

970 }

971 } else {

972 Loc.dumpRange(Offset, EndOffset - Offset, OS, Obj, DumpOpts);

973 }

975 }

976}

977

984

987 std::array<std::optional<uint64_t>, DIDT_ID_Count> DumpOffsets) {

989

991 bool IsDWO = (Extension == ".dwo") || (Extension == ".dwp");

992

993

994 const auto *ObjFile = DObj->getFile();

997

998

999

1000

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

1014 if (shouldDump(Explicit, ".debug_abbrev", DIDT_ID_DebugAbbrev,

1015 DObj->getAbbrevSection()))

1017 if (shouldDump(ExplicitDWO, ".debug_abbrev.dwo", DIDT_ID_DebugAbbrev,

1018 DObj->getAbbrevDWOSection()))

1020

1022 OS << '\n' << Name << " contents:\n";

1023 if (auto DumpOffset = DumpOffsets[DIDT_ID_DebugInfo])

1024 for (const auto &U : Units) {

1025 U->getDIEForOffset(*DumpOffset)

1027 DWARFDie CUDie = U->getUnitDIE(false);

1028 DWARFDie CUNonSkeletonDie = U->getNonSkeletonUnitDIE(false);

1029 if (CUNonSkeletonDie && CUDie != CUNonSkeletonDie) {

1033 }

1034 }

1035 else

1036 for (const auto &U : Units)

1037 U->dump(OS, DumpOpts);

1038 };

1039 if ((DumpType & DIDT_DebugInfo)) {

1044 }

1045

1047 OS << '\n' << Name << " contents:\n";

1048 for (const auto &U : Units)

1049 if (auto DumpOffset = DumpOffsets[DIDT_ID_DebugTypes])

1050 U->getDIEForOffset(*DumpOffset)

1052 else

1053 U->dump(OS, DumpOpts);

1054 };

1055 if ((DumpType & DIDT_DebugTypes)) {

1060 }

1061

1065

1066 if (const auto *Off = shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc,

1067 DObj->getLocSection().Data)) {

1069 }

1070 if (const auto *Off =

1071 shouldDump(Explicit, ".debug_loclists", DIDT_ID_DebugLoclists,

1072 DObj->getLoclistsSection().Data)) {

1074 0);

1076 }

1077 if (const auto *Off =

1078 shouldDump(ExplicitDWO, ".debug_loclists.dwo", DIDT_ID_DebugLoclists,

1079 DObj->getLoclistsDWOSection().Data)) {

1083 }

1084

1085 if (const auto *Off =

1086 shouldDump(ExplicitDWO, ".debug_loc.dwo", DIDT_ID_DebugLoc,

1087 DObj->getLocDWOSection().Data)) {

1089 4);

1091 if (*Off) {

1093 Loc.dumpLocationList(&Offset, OS,

1094 std::nullopt, *DObj, nullptr,

1095 LLDumpOpts,

1096 0);

1097 OS << "\n";

1098 } else {

1099 Loc.dumpRange(0, Data.getData().size(), OS, *DObj, LLDumpOpts);

1100 }

1101 }

1102

1103 if (const std::optional<uint64_t> *Off =

1104 shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,

1105 DObj->getFrameSection().Data)) {

1107 (*DF)->dump(OS, DumpOpts, *Off);

1108 else

1109 RecoverableErrorHandler(DF.takeError());

1110 }

1111

1112 if (const std::optional<uint64_t> *Off =

1113 shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame,

1114 DObj->getEHFrameSection().Data)) {

1116 (*DF)->dump(OS, DumpOpts, *Off);

1117 else

1118 RecoverableErrorHandler(DF.takeError());

1119 }

1120

1121 if (shouldDump(Explicit, ".debug_macro", DIDT_ID_DebugMacro,

1122 DObj->getMacroSection().Data)) {

1124 Macro->dump(OS);

1125 }

1126

1127 if (shouldDump(Explicit, ".debug_macro.dwo", DIDT_ID_DebugMacro,

1128 DObj->getMacroDWOSection())) {

1130 MacroDWO->dump(OS);

1131 }

1132

1133 if (shouldDump(Explicit, ".debug_macinfo", DIDT_ID_DebugMacro,

1134 DObj->getMacinfoSection())) {

1136 Macinfo->dump(OS);

1137 }

1138

1139 if (shouldDump(Explicit, ".debug_macinfo.dwo", DIDT_ID_DebugMacro,

1140 DObj->getMacinfoDWOSection())) {

1142 MacinfoDWO->dump(OS);

1143 }

1144

1145 if (shouldDump(Explicit, ".debug_aranges", DIDT_ID_DebugAranges,

1146 DObj->getArangesSection())) {

1149 0);

1154 RecoverableErrorHandler(std::move(E));

1155 break;

1156 }

1157 set.dump(OS);

1158 }

1159 }

1160

1163 std::optional<uint64_t> DumpOffset) {

1164 while (Parser.done()) {

1165 if (DumpOffset && Parser.getOffset() != *DumpOffset) {

1167 continue;

1168 }

1169 OS << "debug_line[" << format("0x%8.8" PRIx64, Parser.getOffset())

1170 << "]\n";

1173 }

1174 };

1175

1176 auto DumpStrSection = [&](StringRef Section) {

1182 const char *CStr = StrData.getCStr(&Offset, &Err);

1183 if (Err) {

1185 return;

1186 }

1187 OS << format("0x%8.8" PRIx64 ": \"", StrOffset);

1189 OS << "\"\n";

1191 }

1192 };

1193

1194 if (const auto *Off = shouldDump(Explicit, ".debug_line", DIDT_ID_DebugLine,

1195 DObj->getLineSection().Data)) {

1197 0);

1199 DumpLineSection(Parser, DumpOpts, *Off);

1200 }

1201

1202 if (const auto *Off =

1203 shouldDump(ExplicitDWO, ".debug_line.dwo", DIDT_ID_DebugLine,

1204 DObj->getLineDWOSection().Data)) {

1208 DumpLineSection(Parser, DumpOpts, *Off);

1209 }

1210

1211 if (shouldDump(Explicit, ".debug_cu_index", DIDT_ID_DebugCUIndex,

1212 DObj->getCUIndexSection())) {

1214 }

1215

1216 if (shouldDump(Explicit, ".debug_tu_index", DIDT_ID_DebugTUIndex,

1217 DObj->getTUIndexSection())) {

1219 }

1220

1221 if (shouldDump(Explicit, ".debug_str", DIDT_ID_DebugStr,

1222 DObj->getStrSection()))

1223 DumpStrSection(DObj->getStrSection());

1224

1225 if (shouldDump(ExplicitDWO, ".debug_str.dwo", DIDT_ID_DebugStr,

1226 DObj->getStrDWOSection()))

1227 DumpStrSection(DObj->getStrDWOSection());

1228

1229 if (shouldDump(Explicit, ".debug_line_str", DIDT_ID_DebugLineStr,

1230 DObj->getLineStrSection()))

1231 DumpStrSection(DObj->getLineStrSection());

1232

1233 if (shouldDump(Explicit, ".debug_addr", DIDT_ID_DebugAddr,

1234 DObj->getAddrSection().Data)) {

1238 }

1239

1240 if (shouldDump(Explicit, ".debug_ranges", DIDT_ID_DebugRanges,

1241 DObj->getRangesSection().Data)) {

1248 if (Error E = rangeList.extract(rangesData, &offset)) {

1250 break;

1251 }

1252 rangeList.dump(OS);

1253 }

1254 }

1255

1256 auto LookupPooledAddress =

1257 [&](uint32_t Index) -> std::optional {

1259 auto I = CUs.begin();

1260 if (I == CUs.end())

1261 return std::nullopt;

1262 return (*I)->getAddrOffsetSectionItem(Index);

1263 };

1264

1265 if (shouldDump(Explicit, ".debug_rnglists", DIDT_ID_DebugRnglists,

1266 DObj->getRnglistsSection().Data)) {

1270 }

1271

1272 if (shouldDump(ExplicitDWO, ".debug_rnglists.dwo", DIDT_ID_DebugRnglists,

1273 DObj->getRnglistsDWOSection().Data)) {

1274 DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsDWOSection(),

1277 }

1278

1279 if (shouldDump(Explicit, ".debug_pubnames", DIDT_ID_DebugPubnames,

1280 DObj->getPubnamesSection().Data)) {

1284 }

1285

1286 if (shouldDump(Explicit, ".debug_pubtypes", DIDT_ID_DebugPubtypes,

1287 DObj->getPubtypesSection().Data)) {

1291 }

1292

1293 if (shouldDump(Explicit, ".debug_gnu_pubnames", DIDT_ID_DebugGnuPubnames,

1294 DObj->getGnuPubnamesSection().Data)) {

1295 DWARFDataExtractor PubTableData(*DObj, DObj->getGnuPubnamesSection(),

1298 }

1299

1300 if (shouldDump(Explicit, ".debug_gnu_pubtypes", DIDT_ID_DebugGnuPubtypes,

1301 DObj->getGnuPubtypesSection().Data)) {

1302 DWARFDataExtractor PubTableData(*DObj, DObj->getGnuPubtypesSection(),

1305 }

1306

1307 if (shouldDump(Explicit, ".debug_str_offsets", DIDT_ID_DebugStrOffsets,

1308 DObj->getStrOffsetsSection().Data))

1310 OS, DumpOpts, "debug_str_offsets", *DObj, DObj->getStrOffsetsSection(),

1312 if (shouldDump(ExplicitDWO, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets,

1313 DObj->getStrOffsetsDWOSection().Data))

1315 DObj->getStrOffsetsDWOSection(),

1316 DObj->getStrDWOSection(), dwo_units(),

1318

1319 if (shouldDump(Explicit, ".gdb_index", DIDT_ID_GdbIndex,

1320 DObj->getGdbIndexSection())) {

1322 }

1323

1324 if (shouldDump(Explicit, ".apple_names", DIDT_ID_AppleNames,

1325 DObj->getAppleNamesSection().Data))

1327

1328 if (shouldDump(Explicit, ".apple_types", DIDT_ID_AppleTypes,

1329 DObj->getAppleTypesSection().Data))

1331

1332 if (shouldDump(Explicit, ".apple_namespaces", DIDT_ID_AppleNamespaces,

1333 DObj->getAppleNamespacesSection().Data))

1335

1336 if (shouldDump(Explicit, ".apple_objc", DIDT_ID_AppleObjC,

1337 DObj->getAppleObjCSection().Data))

1339 if (shouldDump(Explicit, ".debug_names", DIDT_ID_DebugNames,

1340 DObj->getNamesSection().Data))

1342}

1343

1346 if (const auto &TUI = getTUIndex()) {

1347 if (const auto *R = TUI.getFromHash(Hash)) {

1348 if (TUI.getVersion() >= 5) {

1351 } else {

1354 if (!TypesUnit)

1355 TypesUnit =

1357 });

1359 }

1360 }

1361 return nullptr;

1362 }

1363 return State->getTypeUnitMap(IsDWO).lookup(Hash);

1364}

1365

1367 DWARFUnitVector &DWOUnits = State->getDWOUnits(LazyParse);

1368

1369 if (const auto &CUI = getCUIndex()) {

1370 if (const auto *R = CUI.getFromHash(Hash))

1373 return nullptr;

1374 }

1375

1376

1377

1378

1379

1381

1382 if (!DWOCU->getDWOId()) {

1383 if (std::optional<uint64_t> DWOId =

1384 toUnsigned(DWOCU->getUnitDIE().find(DW_AT_GNU_dwo_id)))

1385 DWOCU->setDWOId(*DWOId);

1386 else

1387

1388 continue;

1389 }

1390 if (DWOCU->getDWOId() == Hash)

1392 }

1393 return nullptr;

1394}

1395

1397 if (auto *CU = State->getNormalUnits().getUnitForOffset(Offset))

1398 return CU->getDIEForOffset(Offset);

1400}

1401

1405

1407 if (DumpOpts.DumpType & DIDT_DebugCUIndex)

1409 if (DumpOpts.DumpType & DIDT_DebugTUIndex)

1411 if (DumpOpts.DumpType & DIDT_DebugInfo)

1413 if (DumpOpts.DumpType & DIDT_DebugLine)

1415 if (DumpOpts.DumpType & DIDT_DebugStrOffsets)

1420}

1421

1423 return State->getCUIndex();

1424}

1425

1427 return State->getTUIndex();

1428}

1429

1431 return State->getGdbIndex();

1432}

1433

1435 return State->getDebugAbbrev();

1436}

1437

1439 return State->getDebugAbbrevDWO();

1440}

1441

1443 return State->getDebugLoc();

1444}

1445

1447 return State->getDebugAranges();

1448}

1449

1451 return State->getDebugFrame();

1452}

1453

1455 return State->getEHFrame();

1456}

1457

1459 return State->getDebugMacro();

1460}

1461

1463 return State->getDebugMacroDWO();

1464}

1465

1467 return State->getDebugMacinfo();

1468}

1469

1471 return State->getDebugMacinfoDWO();

1472}

1473

1474

1476 return State->getDebugNames();

1477}

1478

1480 return State->getAppleNames();

1481}

1482

1484 return State->getAppleTypes();

1485}

1486

1488 return State->getAppleNamespaces();

1489}

1490

1492 return State->getAppleObjC();

1493}

1494

1499 if (!ExpectedLineTable) {

1500 WarningHandler(ExpectedLineTable.takeError());

1501 return nullptr;

1502 }

1503 return *ExpectedLineTable;

1504}

1505

1508 return State->getLineTableForUnit(U, RecoverableErrorHandler);

1509}

1510

1512 return State->clearLineTableForUnit(U);

1513}

1514

1516 return State->getDWOUnits(Lazy);

1517}

1518

1520 return State->getNormalUnits().getUnitForOffset(Offset);

1521}

1522

1526

1531

1535 return OffsetCU;

1536

1537

1538

1539

1540

1541

1542

1543

1544

1545

1546

1547 for (std::unique_ptr &CU : compile_units()) {

1548 if (CU->getVariableForAddress(Address)) {

1550 }

1551 }

1552 return nullptr;

1553}

1554

1556 bool CheckDWO) {

1558

1560 if (CU)

1561 return Result;

1562

1563 if (CheckDWO) {

1564

1565

1566

1567 DWARFDie CUDie = CU->getUnitDIE(false);

1568 DWARFDie CUDwoDie = CU->getNonSkeletonUnitDIE(false);

1569 if (CheckDWO && CUDwoDie && CUDie != CUDwoDie) {

1570

1573 if (CUDwo) {

1575 if (Result.FunctionDIE)

1576 Result.CompileUnit = CUDwo;

1577 }

1578 }

1579 }

1580

1581

1582

1583 if (!Result) {

1584 Result.CompileUnit = CU;

1585 Result.FunctionDIE = CU->getSubroutineForAddress(Address);

1586 }

1587

1588 std::vector Worklist;

1589 Worklist.push_back(Result.FunctionDIE);

1590 while (!Worklist.empty()) {

1592 Worklist.pop_back();

1593

1594 if (DIE.isValid())

1595 continue;

1596

1597 if (DIE.getTag() == DW_TAG_lexical_block &&

1598 DIE.addressRangeContainsAddress(Address)) {

1599 Result.BlockDIE = DIE;

1600 break;

1601 }

1602

1604 }

1605

1606 return Result;

1607}

1608

1609

1610

1614 std::string &FunctionName, std::string &StartFile, uint32_t &StartLine,

1615 std::optional<uint64_t> &StartAddress) {

1616

1617

1618

1620 CU->getInlinedChainForAddress(Address, InlinedChain);

1621 if (InlinedChain.empty())

1622 return false;

1623

1625 bool FoundResult = false;

1626 const char *Name = nullptr;

1627 if (Kind != FunctionNameKind::None && (Name = DIE.getSubroutineName(Kind))) {

1628 FunctionName = Name;

1629 FoundResult = true;

1630 }

1631 std::string DeclFile = DIE.getDeclFile(FileNameKind);

1632 if (!DeclFile.empty()) {

1633 StartFile = DeclFile;

1634 FoundResult = true;

1635 }

1636 if (auto DeclLineResult = DIE.getDeclLine()) {

1637 StartLine = DeclLineResult;

1638 FoundResult = true;

1639 }

1641 StartAddress = LowPcAddr->Address;

1642 return FoundResult;

1643}

1644

1645static std::optional<int64_t>

1647 std::optional FrameBaseReg) {

1648 if (!Expr.empty() &&

1649 (Expr[0] == DW_OP_fbreg ||

1650 (FrameBaseReg && Expr[0] == DW_OP_breg0 + *FrameBaseReg))) {

1653

1656

1657 if (Expr.size() == Count + 2 && Expr[Count + 1] == DW_OP_deref)

1659

1660 }

1661 return std::nullopt;

1662}

1663

1665 DWARFDie Die, std::vector &Result) {

1666 if (Die.getTag() == DW_TAG_variable ||

1667 Die.getTag() == DW_TAG_formal_parameter) {

1671

1672 std::optional FrameBaseReg;

1673 if (auto FrameBase = Subprogram.find(DW_AT_frame_base))

1674 if (std::optional<ArrayRef<uint8_t>> Expr = FrameBase->getAsBlock())

1675 if (!Expr->empty() && (*Expr)[0] >= DW_OP_reg0 &&

1676 (*Expr)[0] <= DW_OP_reg31) {

1677 FrameBaseReg = (*Expr)[0] - DW_OP_reg0;

1678 }

1679

1680 if (Expected<std::vector> Loc =

1682 for (const auto &Entry : *Loc) {

1683 if (std::optional<int64_t> FrameOffset =

1685 Local.FrameOffset = *FrameOffset;

1686 break;

1687 }

1688 }

1689 } else {

1690

1691

1693 }

1694

1695 if (auto TagOffsetAttr = Die.find(DW_AT_LLVM_tag_offset))

1696 Local.TagOffset = TagOffsetAttr->getAsUnsignedConstant();

1697

1698 if (auto Origin =

1700 Die = Origin;

1701 if (auto NameAttr = Die.find(DW_AT_name))

1702 if (std::optional<const char *> Name = dwarf::toString(*NameAttr))

1706 if (auto DeclFileAttr = Die.find(DW_AT_decl_file)) {

1708 LT->getFileNameByIndex(

1709 *DeclFileAttr->getAsUnsignedConstant(), CU->getCompilationDir(),

1711 Local.DeclFile);

1712 }

1713 if (auto DeclLineAttr = Die.find(DW_AT_decl_line))

1714 Local.DeclLine = *DeclLineAttr->getAsUnsignedConstant();

1715

1717 return;

1718 }

1719

1720 if (Die.getTag() == DW_TAG_inlined_subroutine)

1721 if (auto Origin =

1723 Subprogram = Origin;

1724

1725 for (auto Child : Die)

1726 addLocalsForDie(CU, Subprogram, Child, Result);

1727}

1728

1729std::vector

1731 std::vector Result;

1733 if (CU)

1734 return Result;

1735

1736 DWARFDie Subprogram = CU->getSubroutineForAddress(Address.Address);

1737 if (Subprogram.isValid())

1738 addLocalsForDie(CU, Subprogram, Subprogram, Result);

1739 return Result;

1740}

1741

1742std::optional

1746 if (CU)

1747 return std::nullopt;

1748

1751 CU, Address.Address, Spec.FNKind, Spec.FLIKind, Result.FunctionName,

1752 Result.StartFileName, Result.StartLine, Result.StartAddress);

1753 if (Spec.FLIKind != FileLineInfoKind::None) {

1755 LineTable->getFileLineInfoForAddress(

1757 CU->getCompilationDir(), Spec.FLIKind, Result);

1758 }

1759 }

1760

1761 return Result;

1762}

1763

1764std::optional

1768 if (CU)

1769 return Result;

1770

1771 if (DWARFDie Die = CU->getVariableForAddress(Address.Address)) {

1772 Result.FileName = Die.getDeclFile(FileLineInfoKind::AbsoluteFilePath);

1774 }

1775

1776 return Result;

1777}

1778

1783 if (CU)

1784 return Lines;

1785

1787 std::string StartFileName;

1789 std::optional<uint64_t> StartAddress;

1791 Spec.FLIKind, FunctionName,

1792 StartFileName, StartLine, StartAddress);

1793

1794

1795

1796 if (Spec.FLIKind == FileLineInfoKind::None) {

1798 Result.FunctionName = FunctionName;

1799 Result.StartFileName = StartFileName;

1800 Result.StartLine = StartLine;

1801 Result.StartAddress = StartAddress;

1802 Lines.push_back(std::make_pair(Address.Address, Result));

1803 return Lines;

1804 }

1805

1807

1808

1809 std::vector<uint32_t> RowVector;

1810 if (!LineTable->lookupAddressRange({Address.Address, Address.SectionIndex},

1811 Size, RowVector)) {

1812 return Lines;

1813 }

1814

1815 for (uint32_t RowIndex : RowVector) {

1816

1820 Spec.FLIKind, Result.FileName);

1821 Result.FunctionName = FunctionName;

1822 Result.Line = Row.Line;

1823 Result.Column = Row.Column;

1824 Result.StartFileName = StartFileName;

1825 Result.StartLine = StartLine;

1826 Result.StartAddress = StartAddress;

1827 Lines.push_back(std::make_pair(Row.Address.Address, Result));

1828 }

1829

1830 return Lines;

1831}

1832

1837

1839 if (CU)

1840 return InliningInfo;

1841

1844 CU->getInlinedChainForAddress(Address.Address, InlinedChain);

1845 if (InlinedChain.size() == 0) {

1846

1847

1848 if (Spec.FLIKind != FileLineInfoKind::None) {

1851 if (LineTable &&

1853 {Address.Address, Address.SectionIndex}, Spec.ApproximateLine,

1854 CU->getCompilationDir(), Spec.FLIKind, Frame))

1855 InliningInfo.addFrame(Frame);

1856 }

1857 return InliningInfo;

1858 }

1859

1860 uint32_t CallFile = 0, CallLine = 0, CallColumn = 0, CallDiscriminator = 0;

1861 for (uint32_t i = 0, n = InlinedChain.size(); i != n; i++) {

1862 DWARFDie &FunctionDIE = InlinedChain[i];

1864

1867 if (auto DeclLineResult = FunctionDIE.getDeclLine())

1868 Frame.StartLine = DeclLineResult;

1872 if (Spec.FLIKind != FileLineInfoKind::None) {

1873 if (i == 0) {

1874

1875

1877

1878 if (LineTable)

1881 CU->getCompilationDir(), Spec.FLIKind, Frame);

1882 } else {

1883

1884

1885 if (LineTable)

1888 Frame.Line = CallLine;

1889 Frame.Column = CallColumn;

1891 }

1892

1893 if (i + 1 < n) {

1894 FunctionDIE.getCallerFrame(CallFile, CallLine, CallColumn,

1895 CallDiscriminator);

1896 }

1897 }

1898 InliningInfo.addFrame(Frame);

1899 }

1900 return InliningInfo;

1901}

1902

1903std::shared_ptr

1905 return State->getDWOContext(AbsolutePath);

1906}

1907

1912

1913

1914

1919

1920

1921

1925 std::map<SymbolRef, SymInfo> &Cache) {

1929

1930 std::map<SymbolRef, SymInfo>::iterator CacheIt = Cache.end();

1931

1932

1933 if (Sym != Obj.symbol_end()) {

1934 bool New;

1935 std::tie(CacheIt, New) = Cache.try_emplace(*Sym);

1936 if (!New)

1937 return CacheIt->second;

1938

1940 if (!SymAddrOrErr)

1941 return createError("failed to compute symbol address: ",

1943

1944

1946 if (!SectOrErr)

1947 return createError("failed to get symbol section: ",

1948 SectOrErr.takeError());

1949

1950 RSec = *SectOrErr;

1951 Ret.Address = *SymAddrOrErr;

1953 RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl());

1955 }

1956

1957 if (RSec != Obj.section_end())

1959

1960

1961

1962

1963

1964

1965

1966

1967 if (L && RSec != Obj.section_end())

1968 if (uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec))

1970

1971 if (CacheIt != Cache.end())

1972 CacheIt->second = Ret;

1973

1974 return Ret;

1975}

1976

1980 if (!MachObj)

1981 return false;

1982

1983

1986}

1987

1988namespace {

1989struct DWARFSectionMap final : public DWARFSection {

1991};

1992

1993class DWARFObjInMemory final : public DWARFObject {

1994 bool IsLittleEndian;

1995 uint8_t AddressSize;

1996 StringRef FileName;

1997 const object::ObjectFile *Obj = nullptr;

1999

2000 using InfoSectionMap = MapVector<object::SectionRef, DWARFSectionMap,

2001 std::map<object::SectionRef, unsigned>>;

2002

2003 InfoSectionMap InfoSections;

2004 InfoSectionMap TypesSections;

2005 InfoSectionMap InfoDWOSections;

2006 InfoSectionMap TypesDWOSections;

2007

2008 DWARFSectionMap LocSection;

2009 DWARFSectionMap LoclistsSection;

2010 DWARFSectionMap LoclistsDWOSection;

2011 DWARFSectionMap LineSection;

2012 DWARFSectionMap RangesSection;

2013 DWARFSectionMap RnglistsSection;

2014 DWARFSectionMap StrOffsetsSection;

2015 DWARFSectionMap LineDWOSection;

2016 DWARFSectionMap FrameSection;

2017 DWARFSectionMap EHFrameSection;

2018 DWARFSectionMap LocDWOSection;

2019 DWARFSectionMap StrOffsetsDWOSection;

2020 DWARFSectionMap RangesDWOSection;

2021 DWARFSectionMap RnglistsDWOSection;

2022 DWARFSectionMap AddrSection;

2023 DWARFSectionMap AppleNamesSection;

2024 DWARFSectionMap AppleTypesSection;

2025 DWARFSectionMap AppleNamespacesSection;

2026 DWARFSectionMap AppleObjCSection;

2027 DWARFSectionMap NamesSection;

2028 DWARFSectionMap PubnamesSection;

2029 DWARFSectionMap PubtypesSection;

2030 DWARFSectionMap GnuPubnamesSection;

2031 DWARFSectionMap GnuPubtypesSection;

2032 DWARFSectionMap MacroSection;

2033

2034 DWARFSectionMap *mapNameToDWARFSection(StringRef Name) {

2035 return StringSwitch<DWARFSectionMap *>(Name)

2036 .Case("debug_loc", &LocSection)

2037 .Case("debug_loclists", &LoclistsSection)

2038 .Case("debug_loclists.dwo", &LoclistsDWOSection)

2039 .Case("debug_line", &LineSection)

2040 .Case("debug_frame", &FrameSection)

2041 .Case("eh_frame", &EHFrameSection)

2042 .Case("debug_str_offsets", &StrOffsetsSection)

2043 .Case("debug_ranges", &RangesSection)

2044 .Case("debug_rnglists", &RnglistsSection)

2045 .Case("debug_loc.dwo", &LocDWOSection)

2046 .Case("debug_line.dwo", &LineDWOSection)

2047 .Case("debug_names", &NamesSection)

2048 .Case("debug_rnglists.dwo", &RnglistsDWOSection)

2049 .Case("debug_str_offsets.dwo", &StrOffsetsDWOSection)

2050 .Case("debug_addr", &AddrSection)

2051 .Case("apple_names", &AppleNamesSection)

2052 .Case("debug_pubnames", &PubnamesSection)

2053 .Case("debug_pubtypes", &PubtypesSection)

2054 .Case("debug_gnu_pubnames", &GnuPubnamesSection)

2055 .Case("debug_gnu_pubtypes", &GnuPubtypesSection)

2056 .Case("apple_types", &AppleTypesSection)

2057 .Case("apple_namespaces", &AppleNamespacesSection)

2058 .Case("apple_namespac", &AppleNamespacesSection)

2059 .Case("apple_objc", &AppleObjCSection)

2060 .Case("debug_macro", &MacroSection)

2061 .Default(nullptr);

2062 }

2063

2064 StringRef AbbrevSection;

2065 StringRef ArangesSection;

2066 StringRef StrSection;

2067 StringRef MacinfoSection;

2068 StringRef MacinfoDWOSection;

2069 StringRef MacroDWOSection;

2070 StringRef AbbrevDWOSection;

2071 StringRef StrDWOSection;

2072 StringRef CUIndexSection;

2073 StringRef GdbIndexSection;

2074 StringRef TUIndexSection;

2075 StringRef LineStrSection;

2076

2077

2078

2079 std::deque<SmallString<0>> UncompressedSections;

2080

2081 StringRef *mapSectionToMember(StringRef Name) {

2082 if (DWARFSection *Sec = mapNameToDWARFSection(Name))

2083 return &Sec->Data;

2084 return StringSwitch<StringRef *>(Name)

2085 .Case("debug_abbrev", &AbbrevSection)

2086 .Case("debug_aranges", &ArangesSection)

2087 .Case("debug_str", &StrSection)

2088 .Case("debug_macinfo", &MacinfoSection)

2089 .Case("debug_macinfo.dwo", &MacinfoDWOSection)

2090 .Case("debug_macro.dwo", &MacroDWOSection)

2091 .Case("debug_abbrev.dwo", &AbbrevDWOSection)

2092 .Case("debug_str.dwo", &StrDWOSection)

2093 .Case("debug_cu_index", &CUIndexSection)

2094 .Case("debug_tu_index", &TUIndexSection)

2095 .Case("gdb_index", &GdbIndexSection)

2096 .Case("debug_line_str", &LineStrSection)

2097

2098 .Default(nullptr);

2099 }

2100

2101

2102

2103 Error maybeDecompress(const object::SectionRef &Sec, StringRef Name,

2104 StringRef &Data) {

2107

2108 Expected Decompressor =

2110 if (!Decompressor)

2111 return Decompressor.takeError();

2112

2113 SmallString<0> Out;

2114 if (auto Err = Decompressor->resizeAndDecompress(Out))

2115 return Err;

2116

2117 UncompressedSections.push_back(std::move(Out));

2118 Data = UncompressedSections.back();

2119

2121 }

2122

2123public:

2124 DWARFObjInMemory(const StringMap<std::unique_ptr> &Sections,

2125 uint8_t AddrSize, bool IsLittleEndian)

2126 : IsLittleEndian(IsLittleEndian) {

2127 for (const auto &SecIt : Sections) {

2128 if (StringRef *SectionData = mapSectionToMember(SecIt.first()))

2129 *SectionData = SecIt.second->getBuffer();

2130 else if (SecIt.first() == "debug_info")

2131

2132

2133 InfoSections[SectionRef()].Data = SecIt.second->getBuffer();

2134 else if (SecIt.first() == "debug_info.dwo")

2135 InfoDWOSections[SectionRef()].Data = SecIt.second->getBuffer();

2136 else if (SecIt.first() == "debug_types")

2137 TypesSections[SectionRef()].Data = SecIt.second->getBuffer();

2138 else if (SecIt.first() == "debug_types.dwo")

2139 TypesDWOSections[SectionRef()].Data = SecIt.second->getBuffer();

2140 }

2141 }

2142 DWARFObjInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L,

2143 function_ref<void(Error)> HandleError,

2144 function_ref<void(Error)> HandleWarning,

2146 : IsLittleEndian(Obj.isLittleEndian()),

2147 AddressSize(Obj.getBytesInAddress()), FileName(Obj.getFileName()),

2149

2150 StringMap SectionAmountMap;

2151 for (const SectionRef &Section : Obj.sections()) {

2152 StringRef Name;

2153 if (auto NameOrErr = Section.getName())

2154 Name = *NameOrErr;

2155 else

2156 consumeError(NameOrErr.takeError());

2157

2158 ++SectionAmountMap[Name];

2159 SectionNames.push_back({ Name, true });

2160

2161

2163 continue;

2164

2165

2167 continue;

2168

2169 StringRef Data;

2170 Expected<section_iterator> SecOrErr = Section.getRelocatedSection();

2171 if (!SecOrErr) {

2172 HandleError(createError("failed to get relocated section: ",

2173 SecOrErr.takeError()));

2174 continue;

2175 }

2176

2177

2178

2179

2181 Obj.isRelocatableObject() ? *SecOrErr : Obj.section_end();

2182 if (!L || L->getLoadedSectionContents(*RelocatedSection, Data)) {

2183 Expected E = Section.getContents();

2184 if (E)

2185 Data = *E;

2186 else

2187

2188 consumeError(E.takeError());

2189 }

2190

2191 if (auto Err = maybeDecompress(Section, Name, Data)) {

2192 HandleError(createError("failed to decompress '" + Name + "', ",

2193 std::move(Err)));

2194 continue;

2195 }

2196

2197

2198

2199 Name = Name.substr(Name.find_first_not_of("._"));

2200 Name = Obj.mapDebugSectionName(Name);

2201

2202 if (StringRef *SectionData = mapSectionToMember(Name)) {

2203 *SectionData = Data;

2204 if (Name == "debug_ranges") {

2205

2206 RangesDWOSection.Data = Data;

2207 } else if (Name == "debug_frame" || Name == "eh_frame") {

2208 if (DWARFSection *S = mapNameToDWARFSection(Name))

2210 }

2211 } else if (InfoSectionMap *Sections =

2212 StringSwitch<InfoSectionMap *>(Name)

2213 .Case("debug_info", &InfoSections)

2214 .Case("debug_info.dwo", &InfoDWOSections)

2215 .Case("debug_types", &TypesSections)

2216 .Case("debug_types.dwo", &TypesDWOSections)

2218

2219

2220 DWARFSectionMap &S = (*Sections)[Section];

2221 S.Data = Data;

2222 }

2223

2224 if (RelocatedSection == Obj.section_end() ||

2225 (RelocAction == DWARFContext::ProcessDebugRelocations::Ignore))

2226 continue;

2227

2228 StringRef RelSecName;

2229 if (auto NameOrErr = RelocatedSection->getName())

2230 RelSecName = *NameOrErr;

2231 else

2233

2234

2235

2236

2237 StringRef RelSecData;

2238 if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData))

2239 continue;

2240

2241

2242

2243

2244

2245

2247 continue;

2248

2249 if (Section.relocations().empty() && Name.ends_with(".dwo") &&

2250 RelSecName.starts_with(".debug")) {

2251 HandleWarning(createError("unexpected relocations for dwo section '" +

2252 RelSecName + "'"));

2253 }

2254

2255

2256

2257 RelSecName = RelSecName.substr(RelSecName.find_first_not_of("._"));

2258 DWARFSectionMap *Sec = mapNameToDWARFSection(RelSecName);

2260 if (!Map) {

2261

2262

2263 if (RelSecName == "debug_info")

2264 Map = &static_cast<DWARFSectionMap &>(InfoSections[*RelocatedSection])

2265 .Relocs;

2266 else if (RelSecName == "debug_types")

2268 &static_cast<DWARFSectionMap &>(TypesSections[*RelocatedSection])

2269 .Relocs;

2270 else

2271 continue;

2272 }

2273

2274 if (Section.relocations().empty())

2275 continue;

2276

2277

2278 std::map<SymbolRef, SymInfo> AddrCache;

2282 for (const RelocationRef &Reloc : Section.relocations()) {

2283

2284

2285 if (isRelocScattered(Obj, Reloc))

2286 continue;

2287

2288 Expected SymInfoOrErr =

2289 getSymbolInfo(Obj, Reloc, L, AddrCache);

2290 if (!SymInfoOrErr) {

2291 HandleError(SymInfoOrErr.takeError());

2292 continue;

2293 }

2294

2295

2296

2297

2298

2299 if (Supports && Supports(Reloc.getType())) {

2300 auto I = Map->try_emplace(

2301 Reloc.getOffset(),

2302 RelocAddrEntry{

2303 SymInfoOrErr->SectionIndex, Reloc, SymInfoOrErr->Address,

2304 std::optionalobject::RelocationRef(), 0, Resolver});

2305

2306

2307

2308 if (I.second) {

2309 RelocAddrEntry &entry = I.first->getSecond();

2310 if (entry.Reloc2) {

2311 HandleError(createError(

2312 "At most two relocations per offset are supported"));

2313 }

2314 entry.Reloc2 = Reloc;

2315 entry.SymbolValue2 = SymInfoOrErr->Address;

2316 }

2317 } else {

2320

2321 HandleWarning(

2322 createError("failed to compute relocation: " + Type + ", ",

2324 }

2325 }

2326 }

2327

2329 if (SectionAmountMap[S.Name] > 1)

2330 S.IsNameUnique = false;

2331 }

2332

2334 uint64_t Pos) const override {

2335 auto &Sec = static_cast<const DWARFSectionMap &>(S);

2337 if (AI == Sec.Relocs.end())

2338 return std::nullopt;

2339 return AI->second;

2340 }

2341

2343

2346 }

2347

2348 bool isLittleEndian() const override { return IsLittleEndian; }

2349 StringRef getAbbrevDWOSection() const override { return AbbrevDWOSection; }

2350 const DWARFSection &getLineDWOSection() const override {

2351 return LineDWOSection;

2352 }

2353 const DWARFSection &getLocDWOSection() const override {

2354 return LocDWOSection;

2355 }

2356 StringRef getStrDWOSection() const override { return StrDWOSection; }

2357 const DWARFSection &getStrOffsetsDWOSection() const override {

2358 return StrOffsetsDWOSection;

2359 }

2360 const DWARFSection &getRangesDWOSection() const override {

2361 return RangesDWOSection;

2362 }

2363 const DWARFSection &getRnglistsDWOSection() const override {

2364 return RnglistsDWOSection;

2365 }

2366 const DWARFSection &getLoclistsDWOSection() const override {

2367 return LoclistsDWOSection;

2368 }

2369 const DWARFSection &getAddrSection() const override { return AddrSection; }

2370 StringRef getCUIndexSection() const override { return CUIndexSection; }

2371 StringRef getGdbIndexSection() const override { return GdbIndexSection; }

2372 StringRef getTUIndexSection() const override { return TUIndexSection; }

2373

2374

2375 const DWARFSection &getStrOffsetsSection() const override {

2376 return StrOffsetsSection;

2377 }

2378 StringRef getLineStrSection() const override { return LineStrSection; }

2379

2380

2381 void forEachInfoDWOSections(

2383 for (auto &P : InfoDWOSections)

2384 F(P.second);

2385 }

2386 void forEachTypesDWOSections(

2388 for (auto &P : TypesDWOSections)

2389 F(P.second);

2390 }

2391

2392 StringRef getAbbrevSection() const override { return AbbrevSection; }

2393 const DWARFSection &getLocSection() const override { return LocSection; }

2394 const DWARFSection &getLoclistsSection() const override { return LoclistsSection; }

2395 StringRef getArangesSection() const override { return ArangesSection; }

2396 const DWARFSection &getFrameSection() const override {

2397 return FrameSection;

2398 }

2400 return EHFrameSection;

2401 }

2402 const DWARFSection &getLineSection() const override { return LineSection; }

2403 StringRef getStrSection() const override { return StrSection; }

2404 const DWARFSection &getRangesSection() const override { return RangesSection; }

2405 const DWARFSection &getRnglistsSection() const override {

2406 return RnglistsSection;

2407 }

2408 const DWARFSection &getMacroSection() const override { return MacroSection; }

2409 StringRef getMacroDWOSection() const override { return MacroDWOSection; }

2410 StringRef getMacinfoSection() const override { return MacinfoSection; }

2411 StringRef getMacinfoDWOSection() const override { return MacinfoDWOSection; }

2412 const DWARFSection &getPubnamesSection() const override { return PubnamesSection; }

2413 const DWARFSection &getPubtypesSection() const override { return PubtypesSection; }

2414 const DWARFSection &getGnuPubnamesSection() const override {

2415 return GnuPubnamesSection;

2416 }

2417 const DWARFSection &getGnuPubtypesSection() const override {

2418 return GnuPubtypesSection;

2419 }

2420 const DWARFSection &getAppleNamesSection() const override {

2421 return AppleNamesSection;

2422 }

2423 const DWARFSection &getAppleTypesSection() const override {

2424 return AppleTypesSection;

2425 }

2426 const DWARFSection &getAppleNamespacesSection() const override {

2427 return AppleNamespacesSection;

2428 }

2429 const DWARFSection &getAppleObjCSection() const override {

2430 return AppleObjCSection;

2431 }

2432 const DWARFSection &getNamesSection() const override {

2433 return NamesSection;

2434 }

2435

2437 uint8_t getAddressSize() const override { return AddressSize; }

2438 void forEachInfoSections(

2440 for (auto &P : InfoSections)

2441 F(P.second);

2442 }

2443 void forEachTypesSections(

2445 for (auto &P : TypesSections)

2446 F(P.second);

2447 }

2448};

2449}

2450

2451std::unique_ptr

2455 std::function<void(Error)> RecoverableErrorHandler,

2456 std::function<void(Error)> WarningHandler,

2457 bool ThreadSafe) {

2458 auto DObj = std::make_unique(

2459 Obj, L, RecoverableErrorHandler, WarningHandler, RelocAction);

2460 return std::make_unique(std::move(DObj),

2461 std::move(DWPName),

2462 RecoverableErrorHandler,

2463 WarningHandler,

2464 ThreadSafe);

2465}

2466

2467std::unique_ptr

2470 std::function<void(Error)> RecoverableErrorHandler,

2471 std::function<void(Error)> WarningHandler,

2472 bool ThreadSafe) {

2473 auto DObj =

2474 std::make_unique(Sections, AddrSize, isLittleEndian);

2475 return std::make_unique(

2476 std::move(DObj), "", RecoverableErrorHandler, WarningHandler, ThreadSafe);

2477}

2478

2480

2481

2482

2483

2484

2486 return CUs.empty() ? 0 : (*CUs.begin())->getAddressByteSize();

2487}

2488

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)

Definition DWARFContext.cpp:946

static void dumpRnglistsSection(raw_ostream &OS, DWARFDataExtractor &rnglistData, llvm::function_ref< std::optional< object::SectionedAddress >(uint32_t)> LookupPooledAddress, DIDumpOptions DumpOpts)

Definition DWARFContext.cpp:922

static void dumpUUID(raw_ostream &OS, const ObjectFile &Obj)

Dump the UUID load command.

Definition DWARFContext.cpp:759

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".

Definition DWARFContext.cpp:1611

static void dumpPubTableSection(raw_ostream &OS, DIDumpOptions DumpOpts, DWARFDataExtractor Data, bool GnuStyle)

Definition DWARFContext.cpp:978

void fixupIndex(DWARFContext &C, DWARFUnitIndex &Index)

Definition DWARFContext.cpp:183

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.

Definition DWARFContext.cpp:1922

static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData, DIDumpOptions DumpOpts, uint16_t Version, uint8_t AddrSize)

Definition DWARFContext.cpp:899

static T & getAccelTable(std::unique_ptr< T > &Cache, const DWARFObject &Obj, const DWARFSection &Section, StringRef StringSection, bool IsLittleEndian)

Definition DWARFContext.cpp:191

void fixupIndexV4(DWARFContext &C, DWARFUnitIndex &Index)

Definition DWARFContext.cpp:72

static ContributionCollection collectContributionData(DWARFContext::unit_iterator_range Units)

Definition DWARFContext.cpp:786

std::vector< std::optional< StrOffsetsContributionDescriptor > > ContributionCollection

Definition DWARFContext.cpp:780

DWARFDebugLine::LineTable DWARFLineTable

Definition DWARFContext.cpp:67

static bool isRelocScattered(const object::ObjectFile &Obj, const RelocationRef &Reloc)

Definition DWARFContext.cpp:1977

static std::optional< int64_t > getExpressionFrameOffset(ArrayRef< uint8_t > Expr, std::optional< unsigned > FrameBaseReg)

Definition DWARFContext.cpp:1646

void fixupIndexV5(DWARFContext &C, DWARFUnitIndex &Index)

Definition DWARFContext.cpp:140

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)

Definition DWARFContext.cpp:826

static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")

This file contains constants used for implementing Dwarf debug support.

static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)

Return the first DebugLoc that has line number information, given a range of instructions.

This file implements a map that provides insertion order iteration.

This file defines the SmallString class.

This file defines the SmallVector class.

This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...

std::pair< llvm::MachO::Target, std::string > UUID

This implements the Apple accelerator table format, a precursor of the DWARF 5 accelerator table form...

void dump(raw_ostream &OS) const override

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

size_t size() const

size - Get the array size.

bool empty() const

empty - Check if the array is empty.

DIContext(DIContextKind K)

A structured debug information entry.

dwarf::Tag getTag() const

A format-neutral container for inlined code description.

void addFrame(const DILineInfo &Frame)

DWARFContextState This structure contains all member variables for DWARFContext that need to be prote...

MacroSecType

Helper enum to distinguish between macro[.dwo] and macinfo[.dwo] section.

LLVM_ABI std::unique_ptr< DWARFDebugMacro > parseMacroOrMacinfo(MacroSecType SectionType)

Parse a macro[.dwo] or macinfo[.dwo] section.

Definition DWARFContext.cpp:206

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.

Definition DWARFContext.cpp:1527

uint8_t getCUAddrSize()

Get address size from CUs.

Definition DWARFContext.cpp:2479

std::optional< DILineInfo > getLineInfoForDataAddress(object::SectionedAddress Address) override

Definition DWARFContext.cpp:1765

DIInliningInfo getInliningInfoForAddress(object::SectionedAddress Address, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override

Definition DWARFContext.cpp:1834

Expected< const DWARFDebugFrame * > getDebugFrame()

Get a pointer to the parsed frame information object.

Definition DWARFContext.cpp:1450

DWARFGdbIndex & getGdbIndex()

Definition DWARFContext.cpp:1430

unsigned getNumCompileUnits()

Get the number of compile units in this context.

DWARFContext(std::unique_ptr< const DWARFObject > DObj, std::string DWPName="", std::function< void(Error)> RecoverableErrorHandler=WithColor::defaultErrorHandler, std::function< void(Error)> WarningHandler=WithColor::defaultWarningHandler, bool ThreadSafe=false)

Definition DWARFContext.cpp:742

DWARFDie getDIEForOffset(uint64_t Offset)

Get a DIE given an exact offset.

Definition DWARFContext.cpp:1396

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.

Definition DWARFContext.cpp:1438

compile_unit_range compile_units()

Get compile units in this context.

const AppleAcceleratorTable & getAppleObjC()

Get a reference to the parsed accelerator table object.

Definition DWARFContext.cpp:1491

const DWARFUnitIndex & getTUIndex()

Definition DWARFContext.cpp:1426

DWARFCompileUnit * getCompileUnitForDataAddress(uint64_t Address)

Return the compile unit which contains data with the provided address.

Definition DWARFContext.cpp:1532

const DWARFDebugAbbrev * getDebugAbbrev()

Get a pointer to the parsed DebugAbbrev object.

Definition DWARFContext.cpp:1434

std::vector< DILocal > getLocalsForAddress(object::SectionedAddress Address) override

Definition DWARFContext.cpp:1730

DWARFCompileUnit * getCompileUnitForOffset(uint64_t Offset)

Return the compile unit that includes an offset (relative to .debug_info).

Definition DWARFContext.cpp:1523

const DWARFDebugNames & getDebugNames()

Get a reference to the parsed accelerator table object.

Definition DWARFContext.cpp:1475

unsigned getNumDWOTypeUnits()

Get the number of type units in the DWO context.

const DWARFDebugMacro * getDebugMacroDWO()

Get a pointer to the parsed DebugMacroDWO information object.

Definition DWARFContext.cpp:1462

DILineInfoTable getLineInfoForAddressRange(object::SectionedAddress Address, uint64_t Size, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override

Definition DWARFContext.cpp:1779

bool isDWP() const

Return true of this DWARF context is a DWP file.

Definition DWARFContext.cpp:2489

bool isLittleEndian() const

const DWARFDebugLine::LineTable * getLineTableForUnit(DWARFUnit *U)

Get a pointer to a parsed line table corresponding to a compile unit.

Definition DWARFContext.cpp:1496

void clearLineTableForUnit(DWARFUnit *U)

Definition DWARFContext.cpp:1511

const AppleAcceleratorTable & getAppleTypes()

Get a reference to the parsed accelerator table object.

Definition DWARFContext.cpp:1483

const AppleAcceleratorTable & getAppleNames()

Get a reference to the parsed accelerator table object.

Definition DWARFContext.cpp:1479

DWARFUnit * getUnitForOffset(uint64_t Offset)

Return the DWARF unit that includes an offset (relative to .debug_info).

Definition DWARFContext.cpp:1519

compile_unit_range dwo_compile_units()

Get compile units in the DWO context.

const DWARFDebugLoc * getDebugLoc()

Get a pointer to the parsed DebugLoc object.

Definition DWARFContext.cpp:1442

const DWARFDebugMacro * getDebugMacinfoDWO()

Get a pointer to the parsed DebugMacinfoDWO information object.

Definition DWARFContext.cpp:1470

bool verify(raw_ostream &OS, DIDumpOptions DumpOpts={}) override

Definition DWARFContext.cpp:1402

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.

Definition DWARFContext.cpp:985

DWARFTypeUnit * getTypeUnitForHash(uint64_t Hash, bool IsDWO)

Definition DWARFContext.cpp:1344

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)

Definition DWARFContext.cpp:1904

DWARFCompileUnit * getDWOCompileUnitForHash(uint64_t Hash)

Definition DWARFContext.cpp:1366

unsigned getNumDWOCompileUnits()

Get the number of compile units in the DWO context.

const DWARFDebugAranges * getDebugAranges()

Get a pointer to the parsed DebugAranges object.

Definition DWARFContext.cpp:1446

const DWARFUnitIndex & getCUIndex()

Definition DWARFContext.cpp:1422

Expected< const DWARFDebugFrame * > getEHFrame()

Get a pointer to the parsed eh frame information object.

Definition DWARFContext.cpp:1454

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...

Definition DWARFContext.cpp:1555

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.

Definition DWARFContext.cpp:1487

const DWARFDebugMacro * getDebugMacro()

Get a pointer to the parsed DebugMacro information object.

Definition DWARFContext.cpp:1458

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)

Definition DWARFContext.cpp:2452

const DWARFDebugMacro * getDebugMacinfo()

Get a pointer to the parsed DebugMacinfo information object.

Definition DWARFContext.cpp:1466

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

Definition DWARFContext.cpp:1743

LLVM_ABI void dump(raw_ostream &OS) const

A class representing an address table as specified in DWARF v5.

void dump(raw_ostream &OS, DIDumpOptions DumpOpts={}) const

Error extract(const DWARFDataExtractor &Data, uint64_t *OffsetPtr, uint16_t CUVersion, uint8_t CUAddrSize, std::function< void(Error)> WarnCallback)

Extract the entire table, including all addresses.

std::optional< uint64_t > getFullLength() const

Return the full length of this table, including the length field.

LLVM_ABI void dump(raw_ostream &OS) const

LLVM_ABI Error extract(DWARFDataExtractor data, uint64_t *offset_ptr, function_ref< void(Error)> WarningHandler=nullptr)

uint64_t findAddress(uint64_t Address) const

Helper to allow for parsing of an entire .debug_line section in sequence.

void dump(raw_ostream &OS, const DWARFObject &Obj, DIDumpOptions DumpOpts, std::optional< uint64_t > Offset) const

Print the location lists found within the debug_loc section.

.debug_names section consists of one or more units.

void dump(raw_ostream &OS) const override

Represents structure for holding and parsing .debug_pub* tables.

LLVM_ABI void extract(DWARFDataExtractor Data, bool GnuStyle, function_ref< void(Error)> RecoverableErrorHandler)

LLVM_ABI void dump(raw_ostream &OS) const

LLVM_ABI Error extract(const DWARFDataExtractor &data, uint64_t *offset_ptr)

LLVM_ABI void dump(raw_ostream &OS) const

Utility class that carries the DWARF compile/type unit and the debug info entry in an object.

LLVM_ABI DWARFDie getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const

Extract the specified attribute from this DIE as the referenced DIE.

LLVM_ABI std::optional< DWARFFormValue > find(dwarf::Attribute Attr) const

Extract the specified attribute from this DIE.

DWARFUnit * getDwarfUnit() const

LLVM_ABI const char * getSubroutineName(DINameKind Kind) const

If a DIE represents a subprogram (or inlined subroutine), returns its mangled name (or short name,...

LLVM_ABI void getCallerFrame(uint32_t &CallFile, uint32_t &CallLine, uint32_t &CallColumn, uint32_t &CallDiscriminator) const

Retrieves values of DW_AT_call_file, DW_AT_call_line and DW_AT_call_column from DIE (or zeroes if the...

LLVM_ABI std::string getDeclFile(DILineInfoSpecifier::FileLineInfoKind Kind) const

LLVM_ABI uint64_t getDeclLine() const

Returns the declaration line (start line) for a DIE, assuming it specifies a subprogram.

dwarf::Tag getTag() const

LLVM_ABI Expected< DWARFLocationExpressionsVector > getLocations(dwarf::Attribute Attr) const

LLVM_ABI void dump(raw_ostream &OS, unsigned indent=0, DIDumpOptions DumpOpts=DIDumpOptions()) const

Dump the DIE and all of its attributes to the supplied stream.

void dump(raw_ostream &OS)

Error extract(DWARFDataExtractor Data, uint64_t *OffsetPtr)

Extract an entire table, including all list entries.

void dump(DWARFDataExtractor Data, raw_ostream &OS, llvm::function_ref< std::optional< object::SectionedAddress >(uint32_t)> LookupPooledAddress, DIDumpOptions DumpOpts={}) const

virtual StringRef getFileName() const

virtual StringRef getAbbrevDWOSection() const

virtual const DWARFSection & getFrameSection() const

virtual const DWARFSection & getNamesSection() const

virtual const DWARFSection & getAppleNamespacesSection() const

virtual void forEachInfoDWOSections(function_ref< void(const DWARFSection &)> F) const

virtual const DWARFSection & getAppleTypesSection() const

virtual void forEachInfoSections(function_ref< void(const DWARFSection &)> F) const

virtual const DWARFSection & getAppleNamesSection() const

virtual const DWARFSection & getEHFrameSection() const

virtual void forEachTypesSections(function_ref< void(const DWARFSection &)> F) const

virtual const DWARFSection & getLocSection() const

virtual const DWARFSection & getAppleObjCSection() const

virtual void forEachTypesDWOSections(function_ref< void(const DWARFSection &)> F) const

virtual StringRef getStrSection() const

virtual uint8_t getAddressSize() const

void setOffset(uint64_t Value)

uint64_t getOffset() const

LLVM_ABI void dump(raw_ostream &OS) const

Describe a collection of units.

void finishedInfoUnits()

Indicate that parsing .debug_info[.dwo] is done, and remaining units will be from ....

LLVM_ABI DWARFUnit * getUnitForIndexEntry(const DWARFUnitIndex::Entry &E, DWARFSectionKind Sec, const DWARFSection *Section=nullptr)

Returns the Unit from the .debug_info or .debug_types section by the index entry.

LLVM_ABI void addUnitsForSection(DWARFContext &C, const DWARFSection &Section, DWARFSectionKind SectionKind)

Read units from a .debug_info or .debug_types section.

LLVM_ABI void addUnitsForDWOSection(DWARFContext &C, const DWARFSection &DWOSection, DWARFSectionKind SectionKind, bool Lazy=false)

Read units from a .debug_info.dwo or .debug_types.dwo section.

DWARFContext & getContext() const

DWARFDie getDIEForOffset(uint64_t Offset)

Return the DIE object for a given offset Offset inside the unit's DIE vector.

const char * getCompilationDir()

DWARFDie getSubroutineForAddress(uint64_t Address)

Returns subprogram DIE with address range encompassing the provided address.

A class that verifies DWARF debug information given a DWARF Context.

LLVM_ABI bool handleAccelTables()

Verify the information in accelerator tables, if they exist.

LLVM_ABI bool handleDebugTUIndex()

Verify the information in the .debug_tu_index section.

LLVM_ABI bool handleDebugStrOffsets()

Verify the information in the .debug_str_offsets[.dwo].

LLVM_ABI bool handleDebugCUIndex()

Verify the information in the .debug_cu_index section.

LLVM_ABI bool handleDebugInfo()

Verify the information in the .debug_info and .debug_types sections.

LLVM_ABI bool handleDebugLine()

Verify the information in the .debug_line section.

LLVM_ABI void summarize()

Emits any aggregate information collected, depending on the dump options.

LLVM_ABI bool handleDebugAbbrev()

Verify the information in any of the following sections, if available: .debug_abbrev,...

LLVM_ABI DILocation * get() const

Get the underlying DILocation.

DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT, true > const_iterator

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Tagged union holding either a T or a Error.

Error takeError()

Take ownership of the stored error.

An inferface for inquiring the load address of a loaded object file to be used by the DIContext imple...

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...

StringRef - Represent a constant reference to a string, i.e.

constexpr size_t size() const

size - Get the string size.

Triple - Helper class for working with autoconf configuration names.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

static Twine utohexstr(uint64_t Val)

The instances of the Type class are immutable: once they are created, they are never changed.

static LLVM_ABI void defaultWarningHandler(Error Warning)

Implement default handling for Warning.

static LLVM_ABI void defaultErrorHandler(Error Err)

Implement default handling for Error.

An efficient, type-erasing, non-owning reference to a callable.

static LLVM_ABI Expected< Decompressor > create(StringRef Name, StringRef Data, bool IsLE, bool Is64Bit)

Create decompressor object.

MachO::any_relocation_info getRelocation(DataRefImpl Rel) const

bool isRelocationScattered(const MachO::any_relocation_info &RE) const

This class is the base class for all object file types.

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...

uint64_t getIndex() const

bool isCompressed() const

uint64_t getAddress() const

Expected< StringRef > getName() const

Expected< uint64_t > getAddress() const

Returns the symbol virtual address (i.e.

Expected< section_iterator > getSection() const

Get section this symbol is defined in reference to.

This class implements an extremely fast bulk output stream that can only output to a stream.

raw_ostream & write_uuid(const uuid_t UUID)

raw_ostream & write_escaped(StringRef Str, bool UseHexEscapes=false)

Output Str, turning '\', '\t', ' ', '"', and anything that doesn't satisfy llvm::isPrint into an esca...

uint8_t[16] uuid_t

Output a formatted UUID with dash separators.

LLVM_ABI StringRef FormatString(DwarfFormat Format)

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

@ C

The default llvm calling convention, compatible with C.

static constexpr StringLiteral SectionNames[SectionKindsNum]

Calculates the starting offsets for various sections within the .debug_names section.

std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)

Take an optional DWARFFormValue and try to extract a string value from it.

std::optional< object::SectionedAddress > toSectionedAddress(const std::optional< DWARFFormValue > &V)

DwarfFormat

Constants that define the DWARF format as 32 or 64 bit.

std::optional< uint64_t > toSectionOffset(const std::optional< DWARFFormValue > &V)

Take an optional DWARFFormValue and try to extract an section offset.

uint8_t getDwarfOffsetByteSize(DwarfFormat Format)

The size of a reference determined by the DWARF 32/64-bit format.

std::optional< uint64_t > toUnsigned(const std::optional< DWARFFormValue > &V)

Take an optional DWARFFormValue and try to extract an unsigned constant.

LLVM_ABI Section * getEHFrameSection(LinkGraph &G)

Returns a pointer to the DWARF eh-frame section if the graph contains a non-empty one,...

content_iterator< SectionRef > section_iterator

Error createError(const Twine &Err)

uint64_t(*)(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t Addend) RelocationResolver

LLVM_ABI std::pair< SupportsRelocation, RelocationResolver > getRelocationResolver(const ObjectFile &Obj)

bool(*)(uint64_t) SupportsRelocation

LLVM_ABI StringRef extension(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)

Get extension.

SmartMutex< false > Mutex

Mutex - A standard, always enforced mutex.

This is an optimization pass for GlobalISel generic memory operations.

LLVM_ABI void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})

Log all errors (if any) in E to OS.

auto find(R &&Range, const T &Val)

Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

LLVM_ABI std::error_code inconvertibleErrorCode()

The value returned by this function can be returned from convertToErrorCode for Error values where no...

SmallVector< std::pair< uint64_t, DILineInfo >, 16 > DILineInfoTable

void append_range(Container &C, Range &&R)

Wrapper function to append range R to container C.

int64_t decodeSLEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)

Utility function to decode a SLEB128 value.

auto unique(Range &&R, Predicate P)

Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)

Create formatted StringError object.

auto dyn_cast_or_null(const Y &Val)

void sort(IteratorTy Start, IteratorTy End)

static Error createError(const Twine &Err)

FunctionAddr VTableAddr Count

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

format_object< Ts... > format(const char *Fmt, const Ts &... Vals)

These are helper functions used to produce formatted output.

@ Success

The lock was released successfully.

Error make_error(ArgTs &&... Args)

Make a Error instance representing failure using the given error info type.

LLVM_ABI raw_fd_ostream & errs()

This returns a reference to a raw_ostream for standard error.

FunctionAddr VTableAddr uintptr_t uintptr_t Data

std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)

OutputIt move(R &&Range, OutputIt Out)

Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.

LLVM_ABI Error errorCodeToError(std::error_code EC)

Helper for converting an std::error_code to a Error.

DenseMap< uint64_t, RelocAddrEntry > RelocAddrMap

In place of applying the relocations to the data we've read from disk we use a separate mapping table...

void consumeError(Error Err)

Consume a Error without doing anything.

Implement std::hash so that hash_code can be used in STL containers.

SymInfo contains information about symbol: it's address and section index which is -1LL for absolute ...

Definition DWARFContext.cpp:1915

uint64_t Address

Definition DWARFContext.cpp:1916

uint64_t SectionIndex

Definition DWARFContext.cpp:1917

Container for dump options that control which debug information will be dumped.

std::function< void(Error)> WarningHandler

std::function< void(Error)> RecoverableErrorHandler

DIDumpOptions noImplicitRecursion() const

Return the options with RecurseDepth set to 0 unless explicitly required.

Controls which fields of DILineInfo container should be filled with data.

DINameKind FunctionNameKind

A format-neutral container for source line information.

static constexpr const char *const BadString

std::optional< uint64_t > StartAddress

std::string StartFileName

Wraps the returned DIEs for a given address.

LLVM_ABI bool getFileLineInfoForAddress(object::SectionedAddress Address, bool Approximate, const char *CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, DILineInfo &Result) const

Fills the Result argument with the file and line information corresponding to Address.

bool getFileNameByIndex(uint64_t FileIndex, StringRef CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, std::string &Result) const

Extracts filename by its index in filename table in prologue.

LLVM_ABI bool lookupAddressRange(object::SectionedAddress Address, uint64_t Size, std::vector< uint32_t > &Result, std::optional< uint64_t > StmtSequenceOffset=std::nullopt) const

Fills the Result argument with the indices of the rows that correspond to the address range specified...

Standard .debug_line state machine structure.