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

1

2

3

4

5

6

7

8

32#include

33#include

34#include

35#include

36#include

37#include

38

39using namespace llvm;

40using namespace dwarf;

41

46 addUnitsImpl(C, D, Section, C.getDebugAbbrev(), &D.getRangesSection(),

47 &D.getLocSection(), D.getStrSection(),

48 D.getStrOffsetsSection(), &D.getAddrSection(),

49 D.getLineSection(), D.isLittleEndian(), false, false,

51}

52

56 bool Lazy) {

58 addUnitsImpl(C, D, DWOSection, C.getDebugAbbrevDWO(), &D.getRangesDWOSection(),

59 &D.getLocDWOSection(), D.getStrDWOSection(),

60 D.getStrOffsetsDWOSection(), &D.getAddrSection(),

61 D.getLineDWOSection(), C.isLittleEndian(), true, Lazy,

63}

64

65void DWARFUnitVector::addUnitsImpl(

72

73 if (!Parser) {

74 Parser = [=, &Context, &Obj, &Section, &SOS,

78 -> std::unique_ptr {

79 const DWARFSection &InfoSection = CurSection ? *CurSection : Section;

82 return nullptr;

84 if (Error ExtractErr =

86 Context.getWarningHandler()(std::move(ExtractErr));

87 return nullptr;

88 }

89 if (!IndexEntry && IsDWO) {

93 if (Header.isTypeUnit())

94 IndexEntry = Index.getFromHash(Header.getTypeHash());

95 else if (auto DWOId = Header.getDWOId())

96 IndexEntry = Index.getFromHash(*DWOId);

97 }

98 if (!IndexEntry)

99 IndexEntry = Index.getFromOffset(Header.getOffset());

100 }

101 if (IndexEntry) {

102 if (Error ApplicationErr = Header.applyIndexEntry(IndexEntry)) {

103 Context.getWarningHandler()(std::move(ApplicationErr));

104 return nullptr;

105 }

106 }

107 std::unique_ptr U;

108 if (Header.isTypeUnit())

109 U = std::make_unique(Context, InfoSection, Header, DA,

110 RS, LocSection, SS, SOS, AOS, LS,

111 LE, IsDWO, *this);

112 else

113 U = std::make_unique(Context, InfoSection, Header,

114 DA, RS, LocSection, SS, SOS,

115 AOS, LS, LE, IsDWO, *this);

116 return U;

117 };

118 }

119 if (Lazy)

120 return;

121

122

123

124

125

126 auto I = this->begin();

129 if (I != this->end() &&

130 (&(*I)->getInfoSection() != &Section || (*I)->getOffset() == Offset)) {

131 ++I;

132 continue;

133 }

134 auto U = Parser(Offset, SectionKind, &Section, nullptr);

135

136 if (!U)

137 break;

138 Offset = U->getNextUnitOffset();

139 I = std::next(this->insert(I, std::move(U)));

140 }

141}

142

145 [](const std::unique_ptr &LHS,

146 const std::unique_ptr &RHS) {

147 return LHS->getOffset() < RHS->getOffset();

148 });

149 return this->insert(I, std::move(Unit))->get();

150}

151

154 auto *CU =

156 [](uint64_t LHS, const std::unique_ptr &RHS) {

157 return LHS < RHS->getNextUnitOffset();

158 });

159 if (CU != end && (*CU)->getOffset() <= Offset)

160 return CU->get();

161 return nullptr;

162}

163

167 const auto *CUOff = E.getContribution(Sec);

168 if (!CUOff)

169 return nullptr;

170

174

178 }

179

180 auto *CU =

181 std::upper_bound(begin, end, CUOff->getOffset(),

182 [](uint64_t LHS, const std::unique_ptr &RHS) {

183 return LHS < RHS->getNextUnitOffset();

184 });

185 if (CU != end && (*CU)->getOffset() <= Offset)

186 return CU->get();

187

188 if (!Parser)

189 return nullptr;

190

191 auto U = Parser(Offset, Sec, Section, &E);

192 if (!U)

193 return nullptr;

194

195 auto *NewCU = U.get();

196 this->insert(CU, std::move(U));

197 if (Sec == DW_SECT_INFO)

198 ++NumInfoUnits;

199 return NewCU;

200}

201

208 : Context(DC), InfoSection(Section), Header(Header), Abbrev(DA),

209 RangeSection(RS), LineSection(LS), StringSection(SS),

210 StringOffsetSection(SOS), AddrOffsetSection(AOS), IsLittleEndian(LE),

211 IsDWO(IsDWO), UnitVector(UnitVector) {

213}

214

216

221

222std::optionalobject::SectionedAddress

224 if (!AddrOffsetSectionBase) {

225 auto R = Context.info_section_units();

226

227

228

229

231 return (*R.begin())->getAddrOffsetSectionItem(Index);

232

233 return std::nullopt;

234 }

235

238 return std::nullopt;

243 return {{Address, Section}};

244}

245

247 if (!StringOffsetsTableContribution)

249 "DW_FORM_strx used without a valid string offsets table",

253 if (StringOffsetSection.Data.size() < Offset + ItemSize)

255 ", which is too large",

258 IsLittleEndian, 0);

259 return DA.getRelocatedValue(ItemSize, &Offset);

260}

261

266 Offset = *offset_ptr;

268 IndexEntry = nullptr;

269 std::tie(Length, FormParams.Format) =

271 FormParams.Version = debug_info.getU16(offset_ptr, &Err);

272 if (FormParams.Version >= 5) {

273 UnitType = debug_info.getU8(offset_ptr, &Err);

274 FormParams.AddrSize = debug_info.getU8(offset_ptr, &Err);

276 FormParams.getDwarfOffsetByteSize(), offset_ptr, nullptr, &Err);

277 } else {

279 FormParams.getDwarfOffsetByteSize(), offset_ptr, nullptr, &Err);

280 FormParams.AddrSize = debug_info.getU8(offset_ptr, &Err);

281

282

284 UnitType = DW_UT_type;

285 else

286 UnitType = DW_UT_compile;

287 }

289 TypeHash = debug_info.getU64(offset_ptr, &Err);

291 offset_ptr, FormParams.getDwarfOffsetByteSize(), &Err);

292 } else if (UnitType == DW_UT_split_compile || UnitType == DW_UT_skeleton)

293 DWOId = debug_info.getU64(offset_ptr, &Err);

294

295 if (Err)

299 "DWARF unit at 0x%8.8" PRIx64 " cannot be parsed:", Offset),

300 std::move(Err));

301

302

303 assert(*offset_ptr - Offset <= 255 && "unexpected header size");

304 Size = uint8_t(*offset_ptr - Offset);

306

309 "DWARF unit from offset 0x%8.8" PRIx64 " incl. "

310 "to offset 0x%8.8" PRIx64 " excl. "

311 "extends past section size 0x%8.8zx",

312 Offset, NextCUOffset, debug_info.size());

313

317 "DWARF unit at offset 0x%8.8" PRIx64 " "

318 "has unsupported version %" PRIu16 ", supported are 2-%u",

320

321

322

323 if (isTypeUnit() && TypeOffset < Size)

325 "DWARF type unit at offset "

326 "0x%8.8" PRIx64 " "

327 "has its relocated type_offset 0x%8.8" PRIx64 " "

328 "pointing inside the header",

329 Offset, Offset + TypeOffset);

330

334 "DWARF type unit from offset 0x%8.8" PRIx64 " incl. "

335 "to offset 0x%8.8" PRIx64 " excl. has its "

336 "relocated type_offset 0x%8.8" PRIx64 " pointing past the unit end",

337 Offset, NextCUOffset, Offset + TypeOffset);

338

341 "DWARF unit at offset 0x%8.8" PRIx64, Offset))

342 return SizeErr;

343

344

345 Context.setMaxVersionIfGreater(getVersion());

347}

348

352 IndexEntry = Entry;

353 if (AbbrOffset)

355 "DWARF package unit at offset 0x%8.8" PRIx64

356 " has a non-zero abbreviation offset",

357 Offset);

358

359 auto *UnitContrib = IndexEntry->getContribution();

360 if (!UnitContrib)

362 "DWARF package unit at offset 0x%8.8" PRIx64

363 " has no contribution index",

364 Offset);

365

367 if (UnitContrib->getLength() != IndexLength)

369 "DWARF package unit at offset 0x%8.8" PRIx64

370 " has an inconsistent index (expected: %" PRIu64

371 ", actual: %" PRIu64 ")",

372 Offset, UnitContrib->getLength(), IndexLength);

373

374 auto *AbbrEntry = IndexEntry->getContribution(DW_SECT_ABBREV);

375 if (!AbbrEntry)

377 "DWARF package unit at offset 0x%8.8" PRIx64

378 " missing abbreviation column",

379 Offset);

380

381 AbbrOffset = AbbrEntry->getOffset();

383}

384

387

388 assert(!DieArray.empty());

391 uint64_t ActualRangeListOffset = RangeSectionBase + RangeListOffset;

392 return RangeList.extract(RangesData, &ActualRangeListOffset);

393}

394

396 Abbrevs = nullptr;

397 BaseAddr.reset();

398 RangeSectionBase = 0;

399 LocSectionBase = 0;

400 AddrOffsetSectionBase = std::nullopt;

401 SU = nullptr;

402 clearDIEs(false);

403 AddrDieMap.clear();

404 if (DWO)

405 DWO->clear();

406 DWO.reset();

407}

408

412

413void DWARFUnit::extractDIEsToVector(

414 bool AppendCUDie, bool AppendNonCUDies,

415 std::vector &Dies) const {

416 if (!AppendCUDie && !AppendNonCUDies)

417 return;

418

419

420

425

427 std::vector<uint32_t> Parents;

428 std::vector<uint32_t> PrevSiblings;

429 bool IsCUDie = true;

430

432 ((AppendCUDie && Dies.empty()) || (!AppendCUDie && Dies.size() == 1)) &&

433 "Dies array is not empty");

434

435

436 Parents.push_back(UINT32_MAX);

437 if (!AppendCUDie)

438 Parents.push_back(0);

439 PrevSiblings.push_back(0);

440

441

442 do {

443 assert(Parents.size() > 0 && "Empty parents stack");

444 assert((Parents.back() == UINT32_MAX || Parents.back() <= Dies.size()) &&

445 "Wrong parent index");

446

447

448 if (DIE.extractFast(*this, &DIEOffset, DebugInfoData, NextCUOffset,

449 Parents.back()))

450 break;

451

452

453 if (PrevSiblings.back() > 0) {

454 assert(PrevSiblings.back() < Dies.size() &&

455 "Previous sibling index is out of Dies boundaries");

456 Dies[PrevSiblings.back()].setSiblingIdx(Dies.size());

457 }

458

459

460 if (IsCUDie) {

461 if (AppendCUDie)

462 Dies.push_back(DIE);

463 if (!AppendNonCUDies)

464 break;

465

466

467

469 } else {

470

471 PrevSiblings.back() = Dies.size();

472

473 Dies.push_back(DIE);

474 }

475

476

477 if (const DWARFAbbreviationDeclaration *AbbrDecl =

479 if (AbbrDecl->hasChildren()) {

480 if (AppendCUDie || !IsCUDie) {

481 assert(Dies.size() > 0 && "Dies does not contain any die");

482 Parents.push_back(Dies.size() - 1);

483 PrevSiblings.push_back(0);

484 }

485 } else if (IsCUDie)

486

487 break;

488 } else {

489

491 PrevSiblings.pop_back();

492 }

493

494 if (IsCUDie)

495 IsCUDie = false;

496

497

498 } while (Parents.size() > 1);

499}

500

501void DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {

503 Context.getRecoverableErrorHandler()(std::move(e));

504}

505

507 if ((CUDieOnly && !DieArray.empty()) || DieArray.size() > 1)

509

510 bool HasCUDie = !DieArray.empty();

511 extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);

512

513 if (DieArray.empty())

515

516

517 if (HasCUDie)

519

520 DWARFDie UnitDie(this, &DieArray[0]);

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

523 Header.setDWOId(*DWOId);

524 if (!IsDWO) {

525 assert(AddrOffsetSectionBase == std::nullopt);

526 assert(RangeSectionBase == 0);

527 assert(LocSectionBase == 0);

529 if (!AddrOffsetSectionBase)

530 AddrOffsetSectionBase =

532 RangeSectionBase = toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0);

534 }

535

536

537

538

539

540

541

542

544 IsLittleEndian, 0);

546 auto StringOffsetOrError =

549 if (!StringOffsetOrError)

551 "invalid reference to or invalid content in "

552 ".debug_str_offsets[.dwo]: " +

553 toString(StringOffsetOrError.takeError()));

554

555 StringOffsetsTableContribution = *StringOffsetOrError;

556 }

557

558

559

561

562 if (IsDWO) {

563 uint64_t ContributionBaseOffset = 0;

564 if (auto *IndexEntry = Header.getIndexEntry())

565 if (auto *Contrib = IndexEntry->getContribution(DW_SECT_RNGLISTS))

566 ContributionBaseOffset = Contrib->getOffset();

568 &Context.getDWARFObj().getRnglistsDWOSection(),

569 ContributionBaseOffset +

571 } else

572 setRangesSection(&Context.getDWARFObj().getRnglistsSection(),

575 Header.getFormat())));

576 }

577

578 if (IsDWO) {

579

580

582 ? Context.getDWARFObj().getLoclistsDWOSection().Data

583 : Context.getDWARFObj().getLocDWOSection().Data;

584 if (auto *IndexEntry = Header.getIndexEntry())

585 if (const auto *C = IndexEntry->getContribution(

586 Header.getVersion() >= 5 ? DW_SECT_LOCLISTS : DW_SECT_EXT_LOC))

587 Data = Data.substr(C->getOffset(), C->getLength());

588

590 LocTable =

591 std::make_unique(DWARFData, Header.getVersion());

594 LocTable = std::make_unique(

596 Context.getDWARFObj().getLoclistsSection(),

599 } else {

601 Context.getDWARFObj(), Context.getDWARFObj().getLocSection(),

603 }

604

605

606

608}

609

610bool DWARFUnit::parseDWO(StringRef DWOAlternativeLocation) {

611 if (IsDWO)

612 return false;

613 if (DWO)

614 return false;

616 if (!UnitDie)

617 return false;

621 if (!DWOFileName)

622 return false;

626 *CompilationDir) {

628 }

631 if (!DWOId)

632 return false;

633 auto DWOContext = Context.getDWOContext(AbsolutePath);

634 if (!DWOContext) {

635

636 if (DWOAlternativeLocation.empty())

637 return false;

638

639

640

641 DWOContext = Context.getDWOContext(DWOAlternativeLocation);

642 if (!DWOContext)

643 return false;

644 }

645

646 DWARFCompileUnit *DWOCU = DWOContext->getDWOCompileUnitForHash(*DWOId);

647 if (!DWOCU)

648 return false;

649 DWO = std::shared_ptr(std::move(DWOContext), DWOCU);

650 DWO->setSkeletonUnit(this);

651

652 if (AddrOffsetSectionBase)

653 DWO->setAddrOffsetSection(AddrOffsetSection, *AddrOffsetSectionBase);

656 DWO->setRangesSection(RangeSection, DWORangesBase.value_or(0));

657 }

658

659 return true;

660}

661

662void DWARFUnit::clearDIEs(bool KeepCUDie) {

663

664

665

666

667

668 DieArray = (KeepCUDie && !DieArray.empty())

669 ? std::vector({DieArray[0]})

670 : std::vector();

671}

672

678 return std::move(E);

680 }

682 IsLittleEndian, Header.getAddressByteSize());

684 auto RangeListOrError = RnglistTable.findList(RangesData, Offset);

685 if (RangeListOrError)

686 return RangeListOrError.get().getAbsoluteRanges(getBaseAddress(), *this);

687 return RangeListOrError.takeError();

688}

689

694

696 "invalid range list table index %d (possibly "

697 "missing the entire range list table)",

699}

700

703 if (!UnitDie)

705

706

708 if (!CUDIERangesOrError)

710 "decoding address ranges: %s",

711 toString(CUDIERangesOrError.takeError()).c_str());

712 return *CUDIERangesOrError;

713}

714

718

720

725 if (L)

726 Result.push_back(std::move(*L));

727 else

728 InterpretationError =

729 joinErrors(L.takeError(), std::move(InterpretationError));

730 return !InterpretationError;

731 });

732

733 if (ParseError || InterpretationError)

734 return joinErrors(std::move(ParseError), std::move(InterpretationError));

735

736 return Result;

737}

738

742 if (DIERangesOrError) {

743 for (const auto &R : DIERangesOrError.get()) {

744

745 if (R.LowPC == R.HighPC)

746 continue;

747 auto B = AddrDieMap.upper_bound(R.LowPC);

748 if (B != AddrDieMap.begin() && R.LowPC < (--B)->second.first) {

749

750

751 if (R.HighPC < B->second.first)

752 AddrDieMap[R.HighPC] = B->second;

753 if (R.LowPC > B->first)

754 AddrDieMap[B->first].first = R.LowPC;

755 }

756 AddrDieMap[R.LowPC] = std::make_pair(R.HighPC, Die);

757 }

758 } else

760 }

761

762

763

764

765

768}

769

771 extractDIEsIfNeeded(false);

772 if (AddrDieMap.empty())

774 auto R = AddrDieMap.upper_bound(Address);

775 if (R == AddrDieMap.begin())

777

778 --R;

779 if (Address >= R->second.first)

781 return R->second.second;

782}

783

786 if (isType(Child.getTag()))

787 continue;

789 }

790

791 if (Die.getTag() != DW_TAG_variable)

792 return;

793

796 if (!Locations) {

797

799 return;

800 }

801

803

808 auto It = Expr.begin();

809 if (It == Expr.end())

810 continue;

811

812

813

814

815

816

817

819 if (It->getCode() == dwarf::DW_OP_addr) {

820 LocationAddr = It->getRawOperand(0);

821 } else if (It->getCode() == dwarf::DW_OP_addrx) {

822 uint64_t DebugAddrOffset = It->getRawOperand(0);

824 LocationAddr = Pointer->Address;

825 }

826 } else {

827 continue;

828 }

829

830

831 if (++It != Expr.end()) {

832 if (It->getCode() != dwarf::DW_OP_plus_uconst)

833 continue;

834

835 LocationAddr += It->getRawOperand(0);

836

837

838 if (++It != Expr.end())

839 continue;

840 }

841

843 break;

844 }

845

846

847

848

852 GVSize = *Size;

853

856}

857

859 extractDIEsIfNeeded(false);

860

862

863 auto RootLookup = RootsParsedForVariables.insert(RootDie.getOffset());

864 if (RootLookup.second)

866

867 auto R = VariableDieMap.upper_bound(Address);

868 if (R == VariableDieMap.begin())

870

871

872 --R;

873 if (Address >= R->second.first)

875 return R->second.second;

876}

877

878void

882

883 parseDWO();

884

885

888

889 while (SubroutineDIE) {

891 InlinedChain.push_back(SubroutineDIE);

892 return;

893 }

894 if (SubroutineDIE.getTag() == DW_TAG_inlined_subroutine)

895 InlinedChain.push_back(SubroutineDIE);

896 SubroutineDIE = SubroutineDIE.getParent();

897 }

898}

899

902 if (Kind == DW_SECT_INFO)

903 return Context.getCUIndex();

905 return Context.getTUIndex();

906}

907

910 return DWARFDie(this, Entry);

911

913}

914

917 if (!Die)

918 return nullptr;

919 assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size());

920

921 if (std::optional<uint32_t> ParentIdx = Die->getParentIdx()) {

922 assert(*ParentIdx < DieArray.size() &&

923 "ParentIdx is out of DieArray boundaries");

925 }

926

927 return nullptr;

928}

929

932 return DWARFDie(this, Sibling);

933

935}

936

939 if (!Die)

940 return nullptr;

941 assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size());

942

943 if (std::optional<uint32_t> SiblingIdx = Die->getSiblingIdx()) {

944 assert(*SiblingIdx < DieArray.size() &&

945 "SiblingIdx is out of DieArray boundaries");

946 return &DieArray[*SiblingIdx];

947 }

948

949 return nullptr;

950}

951

954 return DWARFDie(this, Sibling);

955

957}

958

961 if (!Die)

962 return nullptr;

963 assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size());

964

965 std::optional<uint32_t> ParentIdx = Die->getParentIdx();

966 if (!ParentIdx)

967

968 return nullptr;

969

970 assert(*ParentIdx < DieArray.size() &&

971 "ParentIdx is out of DieArray boundaries");

973

975 if (PrevDieIdx == *ParentIdx)

976

977 return nullptr;

978

979 while (DieArray[PrevDieIdx].getParentIdx() != *ParentIdx) {

980 PrevDieIdx = *DieArray[PrevDieIdx].getParentIdx();

981

982 assert(PrevDieIdx < DieArray.size() &&

983 "PrevDieIdx is out of DieArray boundaries");

984 assert(PrevDieIdx >= *ParentIdx &&

985 "PrevDieIdx is not a child of parent of Die");

986 }

987

988 return &DieArray[PrevDieIdx];

989}

990

993 return DWARFDie(this, Child);

994

996}

997

1000 if (!Die)

1001 return nullptr;

1002 assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size());

1003

1005 return nullptr;

1006

1007

1008

1009

1011 if (I >= DieArray.size())

1012 return nullptr;

1013 return &DieArray[I];

1014}

1015

1018 return DWARFDie(this, Child);

1019

1021}

1022

1025 if (!Die)

1026 return nullptr;

1027 assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size());

1028

1030 return nullptr;

1031

1032 if (std::optional<uint32_t> SiblingIdx = Die->getSiblingIdx()) {

1033 assert(*SiblingIdx < DieArray.size() &&

1034 "SiblingIdx is out of DieArray boundaries");

1035 assert(DieArray[*SiblingIdx - 1].getTag() == dwarf::DW_TAG_null &&

1036 "Bad end of children marker");

1037 return &DieArray[*SiblingIdx - 1];

1038 }

1039

1040

1041

1042

1043

1044

1045

1046

1047

1048

1049 if (getDIEIndex(Die) == 0 && DieArray.size() > 1 &&

1050 DieArray.back().getTag() == dwarf::DW_TAG_null) {

1051

1054 "Bad unit die");

1055 return &DieArray.back();

1056 }

1057

1058 return nullptr;

1059}

1060

1062 if (!Abbrevs) {

1065 if (!AbbrevsOrError) {

1066

1068 return nullptr;

1069 }

1070 Abbrevs = *AbbrevsOrError;

1071 }

1072 return Abbrevs;

1073}

1074

1076 if (BaseAddr)

1077 return BaseAddr;

1078

1080 std::optional PC =

1081 UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc});

1083 return BaseAddr;

1084}

1085

1090

1091

1093

1094 if (ValidationSize >= Size)

1095 if (DA.isValidOffsetForDataOfSize((uint32_t)Base, ValidationSize))

1096 return *this;

1098}

1099

1100

1101

1104 if (!DA.isValidOffsetForDataOfSize(Offset, 16))

1106

1109

1112 (void)DA.getU16(&Offset);

1113

1114

1116}

1117

1118

1119

1122 if (!DA.isValidOffsetForDataOfSize(Offset, 8))

1124

1128

1130 (void)DA.getU16(&Offset);

1131

1132

1135}

1136

1142 switch (Format) {

1147 if (!DescOrError)

1148 return DescOrError.takeError();

1149 Desc = *DescOrError;

1150 break;

1151 }

1156 if (!DescOrError)

1157 return DescOrError.takeError();

1158 Desc = *DescOrError;

1159 break;

1160 }

1161 }

1162 return Desc.validateContributionSize(DA);

1163}

1164

1169 if (!OptOffset)

1170 return std::nullopt;

1171 auto DescOrError =

1173 if (!DescOrError)

1174 return DescOrError.takeError();

1175 return *DescOrError;

1176}

1177

1182 auto IndexEntry = Header.getIndexEntry();

1183 const auto *C =

1184 IndexEntry ? IndexEntry->getContribution(DW_SECT_STR_OFFSETS) : nullptr;

1185 if (C)

1186 Offset = C->getOffset();

1188 if (DA.getData().data() == nullptr)

1189 return std::nullopt;

1190

1191

1192

1196 Offset += 4;

1197

1199 if (!DescOrError)

1200 return DescOrError.takeError();

1201 return *DescOrError;

1202 }

1203

1204

1205

1207 if (C)

1209 Header.getFormat());

1210 else if (!IndexEntry && !StringOffsetSection.Data.empty())

1212 4, Header.getFormat());

1213 else

1214 return std::nullopt;

1215 auto DescOrError = Desc.validateContributionSize(DA);

1216 if (!DescOrError)

1217 return DescOrError.takeError();

1218 return *DescOrError;

1219}

1220

1222 DataExtractor RangesData(RangeSection->Data, IsLittleEndian,

1225 IsLittleEndian, 0);

1228 return *Off + RangeSectionBase;

1229 return std::nullopt;

1230}

1231

1234 LocTable->getData(), LocSectionBase, getFormat(), Index))

1235 return *Off + LocSectionBase;

1236 return std::nullopt;

1237}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

static Expected< StrOffsetsContributionDescriptor > parseDWARF64StringOffsetsTableHeader(DWARFDataExtractor &DA, uint64_t Offset)

Definition DWARFUnit.cpp:1103

static Expected< StrOffsetsContributionDescriptor > parseDWARF32StringOffsetsTableHeader(DWARFDataExtractor &DA, uint64_t Offset)

Definition DWARFUnit.cpp:1121

static Expected< StrOffsetsContributionDescriptor > parseDWARFStringOffsetsTableHeader(DWARFDataExtractor &DA, llvm::dwarf::DwarfFormat Format, uint64_t Offset)

Definition DWARFUnit.cpp:1138

This file contains constants used for implementing Dwarf debug support.

This file defines the SmallString class.

A structured debug information entry.

DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...

static bool isSupportedVersion(unsigned version)

static Error checkAddressSizeSupported(unsigned AddressSize, std::error_code EC, char const *Fmt, const Ts &...Vals)

static unsigned getMaxSupportedVersion()

DWARFDebugInfoEntry - A DIE with only the minimum required data.

std::optional< uint32_t > getSiblingIdx() const

Returns index of the sibling die.

std::optional< uint32_t > getParentIdx() const

Returns index of the parent die.

const DWARFAbbreviationDeclaration * getAbbreviationDeclarationPtr() const

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

LLVM_ABI DWARFAddressRangesVector getAbsoluteRanges(std::optional< object::SectionedAddress > BaseAddr) const

getAbsoluteRanges - Returns absolute address ranges defined by this range list.

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

LLVM_ABI Expected< DWARFAddressRangesVector > getAddressRanges() const

Get the address ranges for this DIE.

LLVM_ABI DWARFDie getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const

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

LLVM_ABI DWARFDie getParent() const

Get the parent of this DIE object.

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

Extract the specified attribute from this DIE.

LLVM_ABI DWARFDie getSibling() const

Get the sibling of this DIE object.

LLVM_ABI bool isSubroutineDIE() const

Returns true if DIE represents a subprogram or an inlined subroutine.

LLVM_ABI bool isSubprogramDIE() const

Returns true if DIE represents a subprogram (not inlined).

LLVM_ABI std::optional< uint64_t > getTypeSize(uint64_t PointerSize)

Gets the type size (in bytes) for this DIE.

LLVM_ABI DWARFDie getFirstChild() const

Get the first child of this DIE object.

dwarf::Tag getTag() const

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

LLVM_ABI std::optional< uint64_t > getRangesBaseAttribute() const

Extract the range base attribute from this DIE as absolute section offset.

Expected< DWARFListType > findList(DWARFDataExtractor Data, uint64_t Offset) const

Look up a list based on a given offset.

LLVM_ABI Error visitAbsoluteLocationList(uint64_t Offset, std::optional< object::SectionedAddress > BaseAddr, std::function< std::optional< object::SectionedAddress >(uint32_t)> LookupAddr, function_ref< bool(Expected< DWARFLocationExpression >)> Callback) const

Describe a collection of units.

LLVM_ABI DWARFUnit * addUnit(std::unique_ptr< DWARFUnit > Unit)

Add an existing DWARFUnit to this UnitVector.

Definition DWARFUnit.cpp:143

unsigned getNumInfoUnits() const

Returns number of units from all .debug_info[.dwo] sections.

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.

Definition DWARFUnit.cpp:164

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 DWARFUnit * getUnitForOffset(uint64_t Offset) const

Definition DWARFUnit.cpp:152

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

const DWARFDebugInfoEntry * getDebugInfoEntry(unsigned Index) const

Return DWARFDebugInfoEntry for the specified index Index.

const DWARFDebugInfoEntry * getSiblingEntry(const DWARFDebugInfoEntry *Die) const

Definition DWARFUnit.cpp:938

std::optional< uint64_t > getDWOId()

uint32_t getHeaderSize() const

Size in bytes of the parsed unit header.

DWARFDie getPreviousSibling(const DWARFDebugInfoEntry *Die)

Definition DWARFUnit.cpp:952

Expected< std::optional< StrOffsetsContributionDescriptor > > determineStringOffsetsTableContributionDWO(DWARFDataExtractor &DA)

Find the unit's contribution to the string offsets table and determine its length and form.

Definition DWARFUnit.cpp:1179

const DWARFLocationTable & getLocationTable()

const DWARFDebugInfoEntry * getParentEntry(const DWARFDebugInfoEntry *Die) const

Definition DWARFUnit.cpp:916

DWARFDie getFirstChild(const DWARFDebugInfoEntry *Die)

Definition DWARFUnit.cpp:991

DWARFDataExtractor getDebugInfoExtractor() const

Definition DWARFUnit.cpp:217

DWARFDie getSibling(const DWARFDebugInfoEntry *Die)

Definition DWARFUnit.cpp:930

std::optional< uint64_t > getRnglistOffset(uint32_t Index)

Return a rangelist's offset based on an index.

Definition DWARFUnit.cpp:1221

Error tryExtractDIEsIfNeeded(bool CUDieOnly)

Definition DWARFUnit.cpp:506

DWARFDie getUnitDIE(bool ExtractUnitDIEOnly=true)

uint8_t getAddressByteSize() const

DWARFDie getVariableForAddress(uint64_t Address)

Returns variable DIE for the address provided.

Definition DWARFUnit.cpp:858

void setRangesSection(const DWARFSection *RS, uint64_t Base)

uint8_t getDwarfStringOffsetsByteSize() const

const DWARFAbbreviationDeclarationSet * getAbbreviations() const

Definition DWARFUnit.cpp:1061

DWARFDie getParent(const DWARFDebugInfoEntry *Die)

Definition DWARFUnit.cpp:908

void clear()

Definition DWARFUnit.cpp:395

std::optional< uint64_t > getLoclistOffset(uint32_t Index)

Definition DWARFUnit.cpp:1232

const char * getCompilationDir()

Definition DWARFUnit.cpp:409

uint64_t getStringOffsetsBase() const

dwarf::DwarfFormat getFormat() const

DWARFUnit(DWARFContext &Context, const DWARFSection &Section, const DWARFUnitHeader &Header, const DWARFDebugAbbrev *DA, const DWARFSection *RS, const DWARFSection *LocSection, StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS, const DWARFSection &LS, bool LE, bool IsDWO, const DWARFUnitVector &UnitVector)

Definition DWARFUnit.cpp:202

Expected< std::optional< StrOffsetsContributionDescriptor > > determineStringOffsetsTableContribution(DWARFDataExtractor &DA)

Find the unit's contribution to the string offsets table and determine its length and form.

Definition DWARFUnit.cpp:1166

uint64_t getAbbreviationsOffset() const

uint16_t getVersion() const

void getInlinedChainForAddress(uint64_t Address, SmallVectorImpl< DWARFDie > &InlinedChain)

getInlinedChainForAddress - fetches inlined chain for a given address.

Definition DWARFUnit.cpp:879

Error extractRangeList(uint64_t RangeListOffset, DWARFDebugRangeList &RangeList) const

Extract the range list referenced by this compile unit from the .debug_ranges section.

Definition DWARFUnit.cpp:385

Expected< uint64_t > getStringOffsetSectionItem(uint32_t Index) const

Definition DWARFUnit.cpp:246

uint32_t getDIEIndex(const DWARFDebugInfoEntry *Die) const

Return the index of a Die entry inside the unit's DIE vector.

Expected< DWARFLocationExpressionsVector > findLoclistFromOffset(uint64_t Offset)

Definition DWARFUnit.cpp:716

Expected< DWARFAddressRangesVector > findRnglistFromOffset(uint64_t Offset)

Return a vector of address ranges resulting from a (possibly encoded) range list starting at a given ...

Definition DWARFUnit.cpp:674

bool isLittleEndian() const

const DWARFDebugInfoEntry * getPreviousSiblingEntry(const DWARFDebugInfoEntry *Die) const

Definition DWARFUnit.cpp:960

const DWARFDebugInfoEntry * getLastChildEntry(const DWARFDebugInfoEntry *Die) const

Definition DWARFUnit.cpp:1024

void updateVariableDieMap(DWARFDie Die)

Recursively update address to variable Die map.

Definition DWARFUnit.cpp:784

DWARFDie getSubroutineForAddress(uint64_t Address)

Returns subprogram DIE with address range encompassing the provided address.

Definition DWARFUnit.cpp:770

const DWARFDebugInfoEntry * getFirstChildEntry(const DWARFDebugInfoEntry *Die) const

Definition DWARFUnit.cpp:999

Expected< DWARFAddressRangesVector > findRnglistFromIndex(uint32_t Index)

Return a vector of address ranges retrieved from an encoded range list whose offset is found via a ta...

Definition DWARFUnit.cpp:691

uint64_t getNextUnitOffset() const

std::optional< object::SectionedAddress > getBaseAddress()

Definition DWARFUnit.cpp:1075

Expected< DWARFAddressRangesVector > collectAddressRanges()

Definition DWARFUnit.cpp:701

std::optional< object::SectionedAddress > getAddrOffsetSectionItem(uint32_t Index) const

Definition DWARFUnit.cpp:223

uint64_t getOffset() const

DWARFDie getLastChild(const DWARFDebugInfoEntry *Die)

Definition DWARFUnit.cpp:1016

void updateAddressDieMap(DWARFDie Die)

Recursively update address to Die map.

Definition DWARFUnit.cpp:739

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.

SectionKind - This is a simple POD value that classifies the properties of a section.

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

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

iterator insert(iterator I, std::unique_ptr< DWARFUnit > &&Elt)

void push_back(const T &Elt)

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

constexpr bool empty() const

empty - Check if the string is empty.

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

LLVM_ABI unsigned getTag(StringRef TagString)

@ C

The default llvm calling convention, compatible with C.

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.

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

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

@ DW_LENGTH_lo_reserved

Special values for an initial length field.

@ DW_LENGTH_DWARF64

Indicator of 64-bit DWARF format.

LLVM_ABI bool is_relative(const Twine &path, Style style=Style::native)

Is path relative?

LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")

Append to path.

This is an optimization pass for GlobalISel generic memory operations.

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

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

LLVM_ABI const DWARFUnitIndex & getDWARFUnitIndex(DWARFContext &Context, DWARFSectionKind Kind)

Definition DWARFUnit.cpp:900

LLVM_ABI std::error_code inconvertibleErrorCode()

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

auto upper_bound(R &&Range, T &&Value)

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

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

Create formatted StringError object.

DWARFSectionKind

The enum of section identifiers to be used in internal interfaces.

Error joinErrors(Error E1, Error E2)

Concatenate errors.

static uint64_t getDebugInfoSize(DWARFContext &Dwarf)

Compute the total size of the debug info.

bool hasSingleElement(ContainerTy &&C)

Returns true if the given container only contains a single element.

Error make_error(ArgTs &&... Args)

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

FunctionAddr VTableAddr uintptr_t uintptr_t Data

uint64_t alignTo(uint64_t Size, Align A)

Returns a multiple of A needed to store Size bytes.

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

void consumeError(Error Err)

Consume a Error without doing anything.

std::vector< DWARFLocationExpression > DWARFLocationExpressionsVector

Represents a set of absolute location expressions.

Represents a single DWARF expression, whose value is location-dependent.

Represents base address of the CU.

LLVM_ABI Expected< StrOffsetsContributionDescriptor > validateContributionSize(DWARFDataExtractor &DA)

Determine whether a contribution to the string offsets table is consistent with the relevant section ...

Definition DWARFUnit.cpp:1087

uint64_t Size

The contribution size not including the header.

uint8_t getDwarfOffsetByteSize() const