LLVM: lib/DebugInfo/GSYM/DwarfTransformer.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

15

22

23#include

24

25using namespace llvm;

26using namespace gsym;

27

34

45

46

47

48

49

52 return Addr == UINT32_MAX;

55 return false;

56 }

57

58

59

60

61

62

63

64

65

66

70 return std::nullopt;

72 if (GsymFileIdx != UINT32_MAX)

73 return GsymFileIdx;

74 std::string File;

75 if (LineTable->getFileNameByIndex(

79 else

80 GsymFileIdx = 0;

81 return GsymFileIdx;

82 }

83};

84

85

90 return SpecParent;

91 }

95 return AbstParent;

96 }

97

98

99

100

101 if (Die.getTag() == dwarf::DW_TAG_inlined_subroutine)

103

105 if (!ParentDie)

107

108 switch (ParentDie.getTag()) {

109 case dwarf::DW_TAG_namespace:

110 case dwarf::DW_TAG_structure_type:

111 case dwarf::DW_TAG_union_type:

112 case dwarf::DW_TAG_class_type:

113 case dwarf::DW_TAG_subprogram:

114 return ParentDie;

115 case dwarf::DW_TAG_lexical_block:

117 default:

118 break;

119 }

120

122}

123

124

125

126

127

128

129

130

131static std::optional<uint32_t>

133

135

138 }

139

142 return std::nullopt;

143

144

145 if (!(Language == dwarf::DW_LANG_C_plus_plus ||

146 Language == dwarf::DW_LANG_C_plus_plus_03 ||

147 Language == dwarf::DW_LANG_C_plus_plus_11 ||

148 Language == dwarf::DW_LANG_C_plus_plus_14 ||

149 Language == dwarf::DW_LANG_ObjC_plus_plus ||

150

151

152 Language == dwarf::DW_LANG_C))

154

155

156

157

158 if (ShortName.starts_with("_Z") &&

161

163 if (ParentDeclCtxDie) {

164 std::string Name = ShortName.str();

165 while (ParentDeclCtxDie) {

167 if (!ParentName.empty()) {

168

169

170

171 if (ParentName.front() == '<' && ParentName.back() == '>')

172 Name = "{" + ParentName.substr(1, ParentName.size() - 2).str() + "}" +

173 "::" + Name;

174 else

175 Name = ParentName.str() + "::" + Name;

176 }

178 }

179

180 return Gsym.insertString(Name, true);

181 }

182

184}

185

187 bool CheckChildren = true;

188 switch (Die.getTag()) {

189 case dwarf::DW_TAG_subprogram:

190

191 CheckChildren = Depth == 0;

192 break;

193 case dwarf::DW_TAG_inlined_subroutine:

194 return true;

195 default:

196 break;

197 }

198 if (!CheckChildren)

199 return false;

202 return true;

203 }

204 return false;

205}

206

211 if (DwarfRange.LowPC < DwarfRange.HighPC)

212 Ranges.insert({DwarfRange.LowPC, DwarfRange.HighPC});

213 }

214 return Ranges;

215}

216

221 bool &WarnIfEmpty) {

223 return;

224

226 if (Tag == dwarf::DW_TAG_inlined_subroutine) {

227

231 if (RangesOrError) {

234 for (const AddressRange &InlineRange : AllInlineRanges) {

235

236

237 if (InlineRange.empty()) {

238 ++EmptyCount;

239 } else {

241 II.Ranges.insert(InlineRange);

242 } else {

243

244

245

246

247

248

249

250 if (AllParentRanges.contains(InlineRange)) {

251 WarnIfEmpty = false;

252 } else

253 Out.Report("Function DIE has uncontained address range",

255 OS << "error: inlined function DIE at "

257 << HEX64(InlineRange.start()) << " - "

258 << HEX64(InlineRange.end())

259 << ") that isn't contained in "

260 << "any parent address ranges, this inline range "

261 "will be "

262 "removed.\n";

263 });

264 }

265 }

266 }

267

268

269

270 if (EmptyCount == AllInlineRanges.size())

271 WarnIfEmpty = false;

272 }

273 if (II.Ranges.empty())

274 return;

275

277 II.Name = *NameIndex;

279 Die.findRecursively(dwarf::DW_AT_call_file), UINT32_MAX);

280 std::optional<uint32_t> OptGSymFileIdx =

282 if (OptGSymFileIdx) {

283 II.CallFile = OptGSymFileIdx.value();

285

288 AllInlineRanges, WarnIfEmpty);

289 Parent.Children.emplace_back(std::move(II));

290 } else

292 "Inlined function die has invlaid file index in DW_AT_call_file",

294 OS << "error: inlined function DIE at " << HEX32(Die.getOffset())

295 << " has an invalid file index " << DwarfFileIdx

296 << " in its DW_AT_call_file attribute, this inline entry and "

297 "all "

298 << "children will be removed.\n";

299 });

300 return;

301 }

302 if (Tag == dwarf::DW_TAG_subprogram || Tag == dwarf::DW_TAG_lexical_block) {

303

306 AllParentRanges, WarnIfEmpty);

307 }

308}

309

313 std::vector<uint32_t> RowVector;

316 const uint64_t RangeSize = EndAddress - StartAddress;

319

320

321 std::optional<uint64_t> StmtSeqOffset;

322 if (auto StmtSeqAttr = Die.find(llvm::dwarf::DW_AT_LLVM_stmt_sequence)) {

323

324

325

326

327

328

329 const uint64_t InvalidOffset =

332 if (StmtSeqVal != InvalidOffset)

333 StmtSeqOffset = StmtSeqVal;

334 }

335

337 StmtSeqOffset)) {

338

339

342 if (FilePath.empty()) {

343

344

346 Die.findRecursively(dwarf::DW_AT_decl_file), UINT32_MAX);

347

348

349 if (DwarfFileIdx == UINT32_MAX)

350 return;

351 Out.Report("Invalid file index in DW_AT_decl_file", [&](raw_ostream &OS) {

352 OS << "error: function DIE at " << HEX32(Die.getOffset())

353 << " has an invalid file index " << DwarfFileIdx

354 << " in its DW_AT_decl_file attribute, unable to create a single "

355 << "line entry from the DW_AT_decl_file/DW_AT_decl_line "

356 << "attributes.\n";

357 });

358 return;

359 }

360 if (auto Line =

365 }

366 return;

367 }

368

371 for (uint32_t RowIndex : RowVector) {

372

374 std::optional<uint32_t> OptFileIdx =

376 if (!OptFileIdx) {

378 "Invalid file index in DWARF line table", [&](raw_ostream &OS) {

379 OS << "error: function DIE at " << HEX32(Die.getOffset()) << " has "

380 << "a line entry with invalid DWARF file index, this entry will "

381 << "be removed:\n";

382 Row.dumpTableHeader(OS, 0);

383 Row.dump(OS);

384 OS << "\n";

385 });

386 continue;

387 }

388 const uint32_t FileIdx = OptFileIdx.value();

389 uint64_t RowAddress = Row.Address.Address;

390

391

392

393

394

395

398 Out.Report("Start address lies between valid Row table entries",

400 OS << "error: DIE has a start address whose LowPC is "

401 "between the "

402 "line table Row["

403 << RowIndex << "] with address " << HEX64(RowAddress)

404 << " and the next one.\n";

406 });

408 } else {

409 continue;

410 }

411 }

412

413 LineEntry LE(RowAddress, FileIdx, Row.Line);

414 if (RowIndex != RowVector[0] && Row.Address < PrevRow.Address) {

415

416

417

418

419

420

422 if (FirstLE && *FirstLE == LE)

423

424 Out.Report("Duplicate line table detected", [&](raw_ostream &OS) {

425 OS << "warning: duplicate line table detected for DIE:\n";

427 });

428 else

429 Out.Report("Non-monotonically increasing addresses",

431 OS << "error: line table has addresses that do not "

432 << "monotonically increase:\n";

433 for (uint32_t RowIndex2 : RowVector)

436 });

437 break;

438 }

439

440

442 if (LastLE && LastLE->File == FileIdx && LastLE->Line == Row.Line)

443 continue;

444

445

446

447 if (Row.EndSequence) {

448

449

450

451

453 } else {

455 PrevRow = Row;

456 }

457 }

458

459

462}

463

466 switch (Die.getTag()) {

467 case dwarf::DW_TAG_subprogram: {

468 Expected RangesOrError = Die.getAddressRanges();

469 if (!RangesOrError) {

471 break;

472 }

475 break;

477 if (!NameIndex) {

478 Out.Report("Function has no name", [&](raw_ostream &OS) {

479 OS << "error: function at " << HEX64(Die.getOffset())

480 << " has no name\n ";

482 });

483 break;

484 }

485

486

487

488

489

490

492

493

494 for (const DWARFAddressRange &Range : Ranges) {

495

496

497

498

499

500

501

502

504 break;

505

506

507

508

509

510 if (!Gsym.IsValidTextAddress(Range.LowPC)) {

511

512

513

514

515 if (Range.LowPC != 0) {

516 if (!Gsym.isQuiet()) {

517

518 Out.Report("Address range starts outside executable section",

519 [&](raw_ostream &OS) {

520 OS << "warning: DIE has an address range whose "

521 "start address "

522 "is not in any executable sections ("

523 << *Gsym.GetValidTextRanges()

524 << ") and will not be processed:\n";

526 });

527 }

528 }

529 break;

530 }

531

532 FunctionInfo FI;

534 FI.Name = *NameIndex;

537

540 FI.Inline->Name = *NameIndex;

542 bool WarnIfEmpty = true;

544 AllSubprogramRanges, WarnIfEmpty);

545

546

547

548

549

550

551

552

553

554 if (FI.Inline->Children.empty()) {

555 if (WarnIfEmpty && !Gsym.isQuiet())

556 Out.Report("DIE contains inline functions with no valid ranges",

557 [&](raw_ostream &OS) {

558 OS << "warning: DIE contains inline function "

559 "information that has no valid ranges, removing "

560 "inline information:\n";

562 });

563 FI.Inline = std::nullopt;

564 }

565 }

566

567

568 if (LoadDwarfCallSites)

569 parseCallSiteInfoFromDwarf(CUI, Die, FI);

570

571 Gsym.addFunctionInfo(std::move(FI));

572 }

573 } break;

574 default:

575 break;

576 }

577 for (DWARFDie ChildDie : Die.children())

578 handleDie(Out, CUI, ChildDie);

579}

580

581void DwarfTransformer::parseCallSiteInfoFromDwarf(CUInfo &CUI, DWARFDie Die,

583

584

585

586

587

588

589

590 CallSiteInfoCollection CSIC;

591

592 for (DWARFDie Child : Die.children()) {

593 if (Child.getTag() != dwarf::DW_TAG_call_site)

594 continue;

595

597

598

599 auto ReturnPC =

600 dwarf::toAddress(Child.findRecursively(dwarf::DW_AT_call_return_pc));

602 continue;

603

605

606

607

608 if (DWARFDie OriginDie =

609 Child.getAttributeValueAsReferencedDie(dwarf::DW_AT_call_origin)) {

610

611

612 if (const char *LinkName = OriginDie.getLinkageName()) {

613 uint32_t LinkNameOff = Gsym.insertString(LinkName, false);

614 CSI.MatchRegex.push_back(LinkNameOff);

615 } else if (const char *ShortName = OriginDie.getShortName()) {

616 uint32_t ShortNameOff = Gsym.insertString(ShortName, false);

617 CSI.MatchRegex.push_back(ShortNameOff);

618 }

619 }

620

621

622

624

626 }

627

630 FI.CallSites = CallSiteInfoCollection();

631

633 }

634}

635

637 size_t NumBefore = Gsym.getNumFunctionInfos();

640

641 if (IsMachO)

642 return ReturnDie;

643

645 DWARFUnit *DWOCU = DwarfUnit.getNonSkeletonUnitDIE(false).getDwarfUnit();

648 "warning: Unable to retrieve DWO .debug_info section for some "

649 "object files. (Remove the --quiet flag for full output)",

653 {dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}),

654 "");

655 OS << "warning: Unable to retrieve DWO .debug_info section for "

656 << DWOName << "\n";

657 });

658 else {

659 ReturnDie = DWOCU->getUnitDIE(false);

660 }

661 }

662 return ReturnDie;

663 };

664 if (NumThreads == 1) {

665

666

667 for (const auto &CU : DICtx.compile_units()) {

670 handleDie(Out, CUI, Die);

671 }

672 } else {

673

674

675

676

677

678

679

680 for (const auto &CU : DICtx.compile_units())

681 CU->getAbbreviations();

682

683

684

686 for (const auto &CU : DICtx.compile_units())

687 pool.async([&CU]() { CU->getUnitDIE(false ); });

689

690

691 std::mutex LogMutex;

692 for (const auto &CU : DICtx.compile_units()) {

694 if (Die) {

696 pool.async([this, CUI, &LogMutex, &Out, Die]() mutable {

697 std::string storage;

700 handleDie(ThreadOut, CUI, Die);

701

702 std::lock_guardstd::mutex guard(LogMutex);

703 if (Out.GetOS()) {

704 Out << storage;

705 }

706 Out.Merge(ThreadOut);

707 });

708 }

709 }

711 }

712 size_t FunctionsAddedCount = Gsym.getNumFunctionInfos() - NumBefore;

713 Out << "Loaded " << FunctionsAddedCount << " functions from DWARF.\n";

715}

716

719 Out << "Verifying GSYM file \"" << GsymPath << "\":\n";

720

722 if (!Gsym)

723 return Gsym.takeError();

724

725 auto NumAddrs = Gsym->getNumAddresses();

728 DILineInfoSpecifier::FunctionNameKind::LinkageName);

729 std::string gsymFilename;

730 for (uint32_t I = 0; I < NumAddrs; ++I) {

731 auto FuncAddr = Gsym->getAddress(I);

732 if (!FuncAddr)

734 "failed to extract address[%i]", I);

735

736 auto FI = Gsym->getFunctionInfo(*FuncAddr);

737 if (!FI)

739 std::errc::invalid_argument,

740 "failed to extract function info for address 0x%" PRIu64, *FuncAddr);

741

742 for (auto Addr = *FuncAddr; Addr < *FuncAddr + FI->size(); ++Addr) {

745 auto LR = Gsym->lookup(Addr);

746 if (!LR)

747 return LR.takeError();

748

749 auto DwarfInlineInfos =

750 DICtx.getInliningInfoForAddress(SectAddr, DLIS);

751 uint32_t NumDwarfInlineInfos = DwarfInlineInfos.getNumberOfFrames();

752 if (NumDwarfInlineInfos == 0) {

753 DwarfInlineInfos.addFrame(

754 DICtx.getLineInfoForAddress(SectAddr, DLIS).value_or(DILineInfo()));

755 }

756

757

758 if (NumDwarfInlineInfos == 1 &&

759 DwarfInlineInfos.getFrame(0).FileName == "") {

761 NumDwarfInlineInfos = 0;

762 }

763 if (NumDwarfInlineInfos > 0 &&

764 NumDwarfInlineInfos != LR->Locations.size()) {

765 if (Out.GetOS()) {

767 Log << "error: address " << HEX64(Addr) << " has "

768 << NumDwarfInlineInfos << " DWARF inline frames and GSYM has "

769 << LR->Locations.size() << "\n";

770 Log << " " << NumDwarfInlineInfos << " DWARF frames:\n";

771 for (size_t Idx = 0; Idx < NumDwarfInlineInfos; ++Idx) {

772 const auto &dii = DwarfInlineInfos.getFrame(Idx);

773 Log << " [" << Idx << "]: " << dii.FunctionName << " @ "

774 << dii.FileName << ':' << dii.Line << '\n';

775 }

776 Log << " " << LR->Locations.size() << " GSYM frames:\n";

777 for (size_t Idx = 0, count = LR->Locations.size(); Idx < count;

778 ++Idx) {

779 const auto &gii = LR->Locations[Idx];

780 Log << " [" << Idx << "]: " << gii.Name << " @ " << gii.Dir

781 << '/' << gii.Base << ':' << gii.Line << '\n';

782 }

783 Gsym->dump(Log, *FI);

784 }

785 continue;

786 }

787

788 for (size_t Idx = 0, count = LR->Locations.size(); Idx < count;

789 ++Idx) {

790 const auto &gii = LR->Locations[Idx];

791 if (Idx < NumDwarfInlineInfos) {

792 const auto &dii = DwarfInlineInfos.getFrame(Idx);

793 gsymFilename = LR->getSourceFile(Idx);

794

796 Out << "error: address " << HEX64(Addr) << " DWARF function \""

797 << dii.FunctionName.c_str()

798 << "\" doesn't match GSYM function \"" << gii.Name << "\"\n";

799

800

801 if (dii.FileName != gsymFilename)

802 Out << "error: address " << HEX64(Addr) << " DWARF path \""

803 << dii.FileName.c_str() << "\" doesn't match GSYM path \""

804 << gsymFilename.c_str() << "\"\n";

805

806 if (dii.Line != gii.Line)

807 Out << "error: address " << HEX64(Addr) << " DWARF line "

808 << dii.Line << " != GSYM line " << gii.Line << "\n";

809 }

810 }

811 }

812 }

814}

static void parseInlineInfo(GsymCreator &Gsym, OutputAggregator &Out, CUInfo &CUI, DWARFDie Die, uint32_t Depth, FunctionInfo &FI, InlineInfo &Parent, const AddressRanges &AllParentRanges, bool &WarnIfEmpty)

Definition DwarfTransformer.cpp:217

static bool hasInlineInfo(DWARFDie Die, uint32_t Depth)

Definition DwarfTransformer.cpp:186

static AddressRanges ConvertDWARFRanges(const DWARFAddressRangesVector &DwarfRanges)

Definition DwarfTransformer.cpp:208

static std::optional< uint32_t > getQualifiedNameIndex(DWARFDie &Die, uint64_t Language, GsymCreator &Gsym)

Get the GsymCreator string table offset for the qualified name for the DIE passed in.

Definition DwarfTransformer.cpp:132

static DWARFDie GetParentDeclContextDIE(DWARFDie &Die)

Definition DwarfTransformer.cpp:86

static void convertFunctionLineTable(OutputAggregator &Out, CUInfo &CUI, DWARFDie Die, GsymCreator &Gsym, FunctionInfo &FI)

Definition DwarfTransformer.cpp:310

ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))

uint64_t IntrinsicInst * II

A class that represents an address range.

bool contains(uint64_t Addr) const

bool contains(uint64_t Addr) const

The AddressRanges class helps normalize address range collections.

A format-neutral container for inlined code description.

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

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

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

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

uint64_t getOffset() const

Get the absolute offset into the debug info or types section.

LLVM_ABI Expected< DWARFAddressRangesVector > getAddressRanges() const

Get the address ranges for this DIE.

iterator_range< iterator > children() const

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.

DWARFUnit * getDwarfUnit() const

LLVM_ABI std::optional< DWARFFormValue > findRecursively(ArrayRef< dwarf::Attribute > Attrs) const

Extract the first value of any attribute in Attrs from this DIE and recurse into any DW_AT_specificat...

LLVM_ABI const char * getName(DINameKind Kind) const

Return the DIE name resolving DW_AT_specification or DW_AT_abstract_origin references if necessary.

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

dwarf::Tag getTag() const

LLVM_ABI const char * getLinkageName() const

Return the DIE linkage name resolving DW_AT_specification or DW_AT_abstract_origin references if nece...

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.

const dwarf::FormParams & getFormParams() const

DWARFDie getUnitDIE(bool ExtractUnitDIEOnly=true)

This dwarf writer support class manages information associated with a source file.

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Tagged union holding either a T or a Error.

Error takeError()

Take ownership of the stored error.

reference get()

Returns a reference to the stored T value.

void wait() override

Blocking wait for all the tasks to execute first.

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

std::string str() const

str - Get the contents as an std::string.

constexpr StringRef substr(size_t Start, size_t N=npos) const

Return a reference to the substring from [Start, Start + N).

bool starts_with(StringRef Prefix) const

Check if this string starts with the given Prefix.

constexpr bool empty() const

empty - Check if the string is empty.

char back() const

back - Get the last character in the string.

constexpr size_t size() const

size - Get the string size.

char front() const

front - Get the first character in the string.

auto async(Function &&F, Args &&...ArgList)

Asynchronous submission of a task to the pool.

LLVM_ABI llvm::Error convert(uint32_t NumThreads, OutputAggregator &OS)

Extract the DWARF from the supplied object file and convert it into the Gsym format in the GsymCreato...

Definition DwarfTransformer.cpp:636

LLVM_ABI llvm::Error verify(StringRef GsymPath, OutputAggregator &OS)

Definition DwarfTransformer.cpp:717

GsymCreator is used to emit GSYM data to a stand alone file or section within a file.

LLVM_ABI uint32_t insertString(StringRef S, bool Copy=true)

Insert a string into the GSYM string table.

LLVM_ABI uint32_t insertFile(StringRef Path, sys::path::Style Style=sys::path::Style::native)

Insert a file into this GSYM creator.

static LLVM_ABI llvm::Expected< GsymReader > openFile(StringRef Path)

Construct a GsymReader from a file on disk.

LineTable class contains deserialized versions of line tables for each function's address ranges.

void Report(StringRef s, std::function< void(raw_ostream &o)> detailCallback)

raw_ostream * GetOS() const

void Merge(const OutputAggregator &other)

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

A raw_ostream that writes to an std::string.

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

Take an optional DWARFFormValue and try to extract an address.

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

This is an optimization pass for GlobalISel generic memory operations.

ThreadPoolStrategy hardware_concurrency(unsigned ThreadCount=0)

Returns a default thread strategy where all available hardware resources are to be used,...

decltype(auto) dyn_cast(const From &Val)

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

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

Wrapper function to append range R to container C.

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

Create formatted StringError object.

auto count(R &&Range, const E &Element)

Wrapper function around std::count to count the number of times an element Element occurs in the give...

SingleThreadExecutor DefaultThreadPool

void consumeError(Error Err)

Consume a Error without doing anything.

std::vector< DWARFAddressRange > DWARFAddressRangesVector

DWARFAddressRangesVector - represents a set of absolute address ranges.

static DIDumpOptions getForSingleDIE()

Return default option set for printing a single DIE without children.

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

A format-neutral container for source line information.

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.

object::SectionedAddress Address

The program-counter value corresponding to a machine instruction generated by the compiler and sectio...

uint64_t getDwarfMaxOffset() const

const DWARFDebugLine::LineTable * LineTable

Definition DwarfTransformer.cpp:29

std::optional< uint32_t > DWARFToGSYMFileIndex(GsymCreator &Gsym, uint32_t DwarfFileIdx)

Convert a DWARF compile unit file index into a GSYM global file index.

Definition DwarfTransformer.cpp:67

uint64_t Language

Definition DwarfTransformer.cpp:32

const char * CompDir

Definition DwarfTransformer.cpp:30

uint8_t AddrSize

Definition DwarfTransformer.cpp:33

CUInfo(DWARFContext &DICtx, DWARFCompileUnit *CU)

Definition DwarfTransformer.cpp:35

bool isHighestAddress(uint64_t Addr) const

Return true if Addr is the highest address for a given compile unit.

Definition DwarfTransformer.cpp:50

std::vector< uint32_t > FileCache

Definition DwarfTransformer.cpp:31

std::vector< CallSiteInfo > CallSites

std::vector< uint32_t > MatchRegex

Offsets into the string table for function names regex patterns.

uint64_t ReturnOffset

The return offset of the call site - relative to the function start.

Function information in GSYM files encodes information for one contiguous address range.

std::optional< InlineInfo > Inline

uint64_t startAddress() const

uint64_t endAddress() const

std::optional< CallSiteInfoCollection > CallSites

uint32_t Name

String table offset in the string table.

std::optional< LineTable > OptLineTable

Inline information stores the name of the inline function along with an array of address ranges.

std::vector< InlineInfo > Children

Line entries are used to encode the line tables in FunctionInfo objects.

static const uint64_t UndefSection