LLVM: lib/DebugInfo/LogicalView/Readers/LVCodeViewReader.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

35

36using namespace llvm;

42

43#define DEBUG_TYPE "CodeViewReader"

44

46 switch (Kind) {

47#define SYMBOL_RECORD(EnumName, EnumVal, Name) \

48 case EnumName: \

49 return #EnumName;

50#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"

51 default:

52 return "UnknownSym";

53 }

55}

56

59#define RETURN_CASE(Enum, X, Ret) \

60 case Enum::X: \

61 return Ret;

62

65#define CV_REGISTERS_ARM

66#define CV_REGISTER(name, val) RETURN_CASE(RegisterId, name, #name)

67#include "llvm/DebugInfo/CodeView/CodeViewRegisters.def"

68#undef CV_REGISTER

69#undef CV_REGISTERS_ARM

70

71 default:

72 break;

73 }

76#define CV_REGISTERS_ARM64

77#define CV_REGISTER(name, val) RETURN_CASE(RegisterId, name, #name)

78#include "llvm/DebugInfo/CodeView/CodeViewRegisters.def"

79#undef CV_REGISTER

80#undef CV_REGISTERS_ARM64

81

82 default:

83 break;

84 }

85 } else {

87#define CV_REGISTERS_X86

88#define CV_REGISTER(name, val) RETURN_CASE(RegisterId, name, #name)

89#include "llvm/DebugInfo/CodeView/CodeViewRegisters.def"

90#undef CV_REGISTER

91#undef CV_REGISTERS_X86

92

93 default:

94 break;

95 }

96 }

97 return "formatUnknownEnum(Id)";

98}

99

100void LVCodeViewReader::printRelocatedField(StringRef Label,

106 StringRef &Symbol = RelocSym ? *RelocSym : SymStorage;

107 if (!resolveSymbolName(CoffSection, RelocOffset, Symbol))

109 else

111}

112

117 StringRef &Symbol = RelocSym ? *RelocSym : SymStorage;

118 if (resolveSymbolName(CoffSection, RelocOffset, Symbol))

119 Symbol = "";

120}

121

123LVCodeViewReader::getFileNameForFileOffset(uint32_t FileOffset,

125 if (SG) {

130 }

132 }

133

134

135 if (!CVFileChecksumTable.valid() || !CVStringTable.valid())

137

139 CVFileChecksumTable.getArray().at(FileOffset);

140

141

142 if (Iter == CVFileChecksumTable.end())

144

146 if (!NameOrErr)

148 return *NameOrErr;

149}

150

151Error LVCodeViewReader::printFileNameForOffset(StringRef Label,

152 uint32_t FileOffset,

153 const SymbolGroup *SG) {

154 Expected NameOrErr = getFileNameForFileOffset(FileOffset, SG);

155 if (!NameOrErr)

157 W.printHex(Label, *NameOrErr, FileOffset);

159}

160

161void LVCodeViewReader::cacheRelocations() {

162 for (const SectionRef &Section : getObj().sections()) {

163 const coff_section *CoffSection = getObj().getCOFFSection(Section);

164

165 auto &RM = RelocMap[CoffSection];

167

168

169 llvm::sort(RM, [](RelocationRef L, RelocationRef R) {

170 return L.getOffset() < R.getOffset();

171 });

172 }

173}

174

175

176

177Error LVCodeViewReader::resolveSymbol(const coff_section *CoffSection,

178 uint64_t Offset, SymbolRef &Sym) {

179 const auto &Relocations = RelocMap[CoffSection];

181 for (const RelocationRef &Relocation : Relocations) {

182 uint64_t RelocationOffset = Relocation.getOffset();

183

184 if (RelocationOffset == Offset) {

185 SymI = Relocation.getSymbol();

186 break;

187 }

188 }

189 if (SymI == getObj().symbol_end())

191 Sym = *SymI;

192 return ErrorSuccess();

193}

194

195

196

197Error LVCodeViewReader::resolveSymbolName(const coff_section *CoffSection,

200 if (Error E = resolveSymbol(CoffSection, Offset, Symbol))

201 return E;

202 Expected NameOrErr = Symbol.getName();

203 if (!NameOrErr)

205 Name = *NameOrErr;

206 return ErrorSuccess();

207}

208

209

210

211

212

215 auto Find = [=](const char *String) -> bool { return Name.contains(String); };

216 auto Starts = [=](const char *Pattern) -> bool {

218 };

219 auto CheckExclude = [&]() -> bool {

220 if (Starts("__") || Starts("_PMD") || Starts("_PMFN"))

221 return true;

222 if (Find("_s__"))

223 return true;

224 if (Find("_CatchableType") || Find("_TypeDescriptor"))

225 return true;

226 if (Find("Intermediate\\vctools"))

227 return true;

228 if (Find("$initializer$") || Find("dynamic initializer"))

229 return true;

230 if (Find("`vftable'") || Find("_GLOBAL__sub"))

231 return true;

232 return false;

233 };

234 bool Excluded = CheckExclude();

235 if (Excluded)

236 Element->setIsSystem();

237

238 return Excluded;

239}

240

241Error LVCodeViewReader::collectInlineeInfo(

245 uint32_t LineNumber = Line.Header->SourceLineNum;

250 if (Error Err = printFileNameForOffset("FileID", FileOffset, SG))

251 return Err;

253

254 if (Lines.hasExtraFiles()) {

258 if (Error Err = printFileNameForOffset("FileID", FID, SG))

259 return Err;

260 }

261 });

262 Expected NameOrErr = getFileNameForFileOffset(FileOffset, SG);

263 if (!NameOrErr)

264 return NameOrErr.takeError();

265 LogicalVisitor.addInlineeInfo(TIInlinee, LineNumber, *NameOrErr);

266 }

267

269}

270

271Error LVCodeViewReader::traverseInlineeLines(StringRef Subsection) {

273 DebugInlineeLinesSubsectionRef Lines;

274 if (Error E = Lines.initialize(SR))

276

277 return collectInlineeInfo(Lines);

278}

279

280Error LVCodeViewReader::createLines(

282 uint32_t Segment, uint32_t Begin, uint32_t Size, uint32_t NameIndex,

283 const SymbolGroup *SG) {

285 uint32_t End = Begin + Size;

286 W.getOStream() << formatv("{0:x-4}:{1:x-8}-{2:x-8}\n", Segment, Begin, End);

287 });

288

291 return createStringError(object_error::parse_failed, getFileName());

292

293 LineInfo LI(Line.Flags);

294

297 "{0} {1:x-8}\n", utostr(LI.getStartLine()),

299 });

300

301

302

303

304 LVLineDebug *LineDebug = createLineDebug();

305 CULines.push_back(LineDebug);

307 LineDebug->setAddress(Address + Addendum);

308

309 if (LI.isAlwaysStepInto())

310 LineDebug->setIsAlwaysStepInto();

311 else if (LI.isNeverStepInto())

312 LineDebug->setIsNeverStepInto();

313 else

314 LineDebug->setLineNumber(LI.getStartLine());

315

316 if (LI.isStatement())

317 LineDebug->setIsNewStatement();

318

319 Expected NameOrErr = getFileNameForFileOffset(NameIndex, SG);

320 if (!NameOrErr)

322 LineDebug->setFilename(*NameOrErr);

323 }

324

326}

327

328Error LVCodeViewReader::initializeFileAndStringTables(

329 BinaryStreamReader &Reader) {

331 (!CVFileChecksumTable.valid() || !CVStringTable.valid())) {

332

333

334 uint32_t SubType, SubSectionSize;

335

340

341 StringRef Contents;

344

347 case DebugSubsectionKind::FileChecksums:

348 if (Error E = CVFileChecksumTable.initialize(ST))

350 break;

351 case DebugSubsectionKind::StringTable:

352 if (Error E = CVStringTable.initialize(ST))

354 break;

355 default:

356 break;

357 }

358

359 uint32_t PaddedSize = alignTo(SubSectionSize, 4);

360 if (Error E = Reader.skip(PaddedSize - SubSectionSize))

362 }

363

365}

366

369 W.printString("Guid", formatv("{0}", TS.getGuid()).str());

370 W.printNumber("Age", TS.getAge());

371 W.printString("Name", TS.getName());

372 });

373

374 SmallString<128> ServerName(TS.getName());

376 if (BuffOrErr.getError()) {

377

378

381 if (BuffOrErr.getError()) {

382

384 "File '%s' does not exist.",

386 }

387 }

388 MemBuffer = std::move(BuffOrErr.get());

389

390

392 "Invalid PDB file.");

393

394 if (Error Err = loadDataForPDB(PDB_ReaderType::Native, ServerName, Session))

396 ServerName.c_str());

397

398 PdbSession.reset(static_cast<NativeSession *>(Session.release()));

399 PDBFile &Pdb = PdbSession->getPDBFile();

400

401

402

403

404 Expected<InfoStream &> expectedInfo = Pdb.getPDBInfoStream();

405 if (!expectedInfo || expectedInfo->getGuid() != TS.getGuid())

407

408

409

410

411 TypeServer = std::make_shared(&Pdb);

412 LogicalVisitor.setInput(TypeServer);

413

414 LazyRandomTypeCollection &Types = types();

415 LazyRandomTypeCollection &Ids = ids();

416 if (Error Err = traverseTypes(Pdb, Types, Ids))

417 return Err;

418

420}

421

428 });

429

432 if (BuffOrErr.getError()) {

433

435 if (BuffOrErr.getError()) {

436

438 "File '%s' does not exist.",

440 }

441 }

442 MemBuffer = std::move(BuffOrErr.get());

443

444 Expected<std::unique_ptr> BinOrErr = createBinary(*MemBuffer);

447 "Binary object format in '%s' is not supported.",

448 ServerName.c_str());

449

450 Binary &BinaryObj = *BinOrErr.get();

451 if (!BinaryObj.isCOFF())

453 ServerName.c_str());

454

455 Builder = std::make_unique(BuilderAllocator);

456

457

458

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

461 Expected SectionNameOrErr = Section.getName();

462 if (!SectionNameOrErr)

463 return SectionNameOrErr.takeError();

464 if (*SectionNameOrErr == ".debug$P") {

465 Expected DataOrErr = Section.getContents();

466 if (!DataOrErr)

470 return Err;

473

474 ReaderPrecomp = std::make_unique(

477 ReaderPrecomp->readArray(CVTypesPrecomp, ReaderPrecomp->getLength()));

478

479

480

481 for (const CVType &Type : CVTypesPrecomp) {

482 ArrayRef<uint8_t> TypeData = Type.data();

483 if (Type.kind() == LF_ENDPRECOMP) {

484 EndPrecompRecord EndPrecomp = cantFail(

488 break;

489 }

490 Builder->insertRecordBytes(TypeData);

491 }

492

493 break;

494 }

495 }

496

497

498

499 for (const CVType &Type : CVTypesObj) {

500 ArrayRef<uint8_t> TypeData = Type.data();

501 if (Type.kind() != LF_PRECOMP)

502 Builder->insertRecordBytes(TypeData);

503 }

504

505

506 Builder->ForEachRecord(

507 [&](TypeIndex TI, const CVType &Type) { TypeArray.push_back(Type); });

508

509 ItemStream =

511 ItemStream->setItems(TypeArray);

512 TypeStream.setUnderlyingStream(*ItemStream);

513

514 PrecompHeader =

515 std::make_shared(TypeStream, TypeArray.size());

516

517

518 LogicalVisitor.setInput(PrecompHeader);

519

520 LazyRandomTypeCollection &Types = types();

521 LazyRandomTypeCollection &Ids = ids();

523 LogicalVisitor.getShared());

525}

526

527Error LVCodeViewReader::traverseTypeSection(StringRef SectionName,

528 const SectionRef &Section) {

530 ListScope D(W, "CodeViewTypes");

531 W.printNumber("Section", SectionName, getObj().getSectionID(Section));

532 });

533

534 Expected DataOrErr = Section.getContents();

535 if (!DataOrErr)

536 return DataOrErr.takeError();

539 return Err;

542

543

544

549

550

551 if (FirstType->kind() == LF_TYPESERVER2) {

552 TypeServer2Record TS = cantFail(

554 return loadTypeServer(TS);

555 }

556

557

558

559 if (FirstType->kind() == LF_PRECOMP) {

560 PrecompRecord Precomp = cantFail(

562 return loadPrecompiledObject(Precomp, CVTypes);

563 }

564

565 LazyRandomTypeCollection &Types = types();

566 LazyRandomTypeCollection &Ids = ids();

567 Types.reset(*DataOrErr, 100);

569 LogicalVisitor.getShared());

571}

572

573Error LVCodeViewReader::traverseTypes(PDBFile &Pdb,

576

577 auto VisitTypes = [&](LazyRandomTypeCollection &Types,

578 LazyRandomTypeCollection &Ids,

580 LVTypeVisitor TDV(W, &LogicalVisitor, Types, Ids, StreamIdx,

581 LogicalVisitor.getShared());

583 };

584

585 Expected<TpiStream &> StreamTpiOrErr = Pdb.getPDBTpiStream();

586 if (!StreamTpiOrErr)

587 return StreamTpiOrErr.takeError();

588 TpiStream &StreamTpi = *StreamTpiOrErr;

591 W.getOStream() << formatv("Showing {0:N} TPI records\n",

593 });

595 return Err;

596

597 Expected<TpiStream &> StreamIpiOrErr = Pdb.getPDBIpiStream();

598 if (!StreamIpiOrErr)

599 return StreamIpiOrErr.takeError();

600 TpiStream &StreamIpi = *StreamIpiOrErr;

603 W.getOStream() << formatv("Showing {0:N} IPI records\n",

605 });

606 return VisitTypes(Ids, Ids, StreamIPI);

607}

608

609Error LVCodeViewReader::traverseSymbolsSubsection(StringRef Subsection,

610 const SectionRef &Section,

611 StringRef SectionContents) {

612 ArrayRef<uint8_t> BinaryData(Subsection.bytes_begin(),

615 SectionContents);

620

621 LazyRandomTypeCollection &Types = types();

622 LazyRandomTypeCollection &Ids = ids();

623 SymbolVisitorCallbackPipeline Pipeline;

624 SymbolDeserializer Deserializer(&VisitorDelegate,

625 CodeViewContainer::ObjectFile);

626

627

628 LVSymbolVisitor Traverser(this, W, &LogicalVisitor, Types, Ids,

629 &VisitorDelegate, LogicalVisitor.getShared());

630

633 CVSymbolVisitor Visitor(Pipeline);

634 return Visitor.visitSymbolStream(Symbols);

635}

636

637Error LVCodeViewReader::traverseSymbolSection(StringRef SectionName,

638 const SectionRef &Section) {

640 ListScope D(W, "CodeViewDebugInfo");

641 W.printNumber("Section", SectionName, getObj().getSectionID(Section));

642 });

643

644 Expected SectionOrErr = Section.getContents();

645 if (!SectionOrErr)

646 return SectionOrErr.takeError();

647 StringRef SectionContents = *SectionOrErr;

648 StringRef Data = SectionContents;

649

651 StringMap FunctionLineTables;

652

656

658 return createStringError(object_error::parse_failed, getFileName());

659

661 if (Error Err = initializeFileAndStringTables(FSReader))

662 return Err;

663

664 while (Data.empty()) {

665

666

667 uint32_t SubType, SubSectionSize;

672

673

674 SubType &= ~SubsectionIgnoreFlag;

675

676

677 if (SubSectionSize > Data.size())

678 return createStringError(object_error::parse_failed, getFileName());

679 StringRef Contents = Data.substr(0, SubSectionSize);

680

681

682

683 size_t SectionOffset = Data.data() - SectionContents.data();

684 size_t NextOffset = SectionOffset + SubSectionSize;

685 NextOffset = alignTo(NextOffset, 4);

686 if (NextOffset > SectionContents.size())

687 return createStringError(object_error::parse_failed, getFileName());

689

691 case DebugSubsectionKind::Symbols:

693 traverseSymbolsSubsection(Contents, Section, SectionContents))

694 return Err;

695 break;

696

697 case DebugSubsectionKind::InlineeLines:

698 if (Error Err = traverseInlineeLines(Contents))

699 return Err;

700 break;

701

702 case DebugSubsectionKind::Lines:

703

704

705

706

707

708 if (options().getGeneralCollectRanges()) {

709

710 if (SubSectionSize < 12) {

711

712

713 return createStringError(object_error::parse_failed, getFileName());

714 }

715

717 if (Error Err = resolveSymbolName(getObj().getCOFFSection(Section),

718 SectionOffset, SymbolName))

720 getFileName());

721

722 LLVM_DEBUG({ W.printString("Symbol Name", SymbolName); });

723 if (!FunctionLineTables.try_emplace(SymbolName, Contents).second) {

724

725 return createStringError(object_error::parse_failed, getFileName());

726 }

727

728 SymbolNames.push_back(SymbolName);

729 }

730 break;

731

732

733 default:

734 break;

735 }

736 W.flush();

737 }

738

739

740

741 for (StringRef SymbolName : SymbolNames) {

743 ListScope S(W, "FunctionLineTable");

744 W.printString("Symbol Name", SymbolName);

745 });

746

747 BinaryStreamReader Reader(FunctionLineTables[SymbolName],

749

750 DebugLinesSubsectionRef Lines;

751 if (Error E = Lines.initialize(Reader))

753

754

758 continue;

759

762

763

764

766

767

769 ScopesWithRanges->clear();

770 Function->getRanges(*ScopesWithRanges);

771 ScopesWithRanges->sort();

772

773 uint16_t Segment = Lines.header()->RelocSegment;

774 uint32_t Begin = Lines.header()->RelocOffset;

775 uint32_t Size = Lines.header()->CodeSize;

776 for (const LineColumnEntry &Block : Lines)

777 if (Error Err = createLines(Block.LineNumbers, Addendum, Segment, Begin,

779 return Err;

780

781

783

785 return Err;

786

788 }

789

791}

792

794

798

799void LVCodeViewReader::mapRangeAddress(const ObjectFile &Obj,

801 bool IsComdat) {

802 if (!Obj.isCOFF())

803 return;

804

806

807 for (const SymbolRef &Sym : Object->symbols()) {

808 if (!Section.containsSymbol(Sym))

809 continue;

810

811 COFFSymbolRef Symbol = Object->getCOFFSymbol(Sym);

813 continue;

814

817 if (!SymNameOrErr) {

818 W.startLine() << "Invalid symbol name: " << Symbol.getSectionNumber()

819 << "\n";

821 continue;

822 }

823 SymbolName = *SymNameOrErr;

824

827 Object->getSection(Symbol.getSectionNumber());

828 if (!SectionOrErr) {

829 W.startLine() << "Invalid section number: " << Symbol.getSectionNumber()

830 << "\n";

832 return;

833 }

834 W.printNumber("Section #", Symbol.getSectionNumber());

836 W.printHex("Value", Symbol.getValue());

837 });

838

839

841 IsComdat);

842 }

843}

844

846 if (Error Err = loadTargetInfo(Obj))

847 return Err;

848

849

850

851

852

853 cacheRelocations();

855

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

857 Expected SectionNameOrErr = Section.getName();

858 if (!SectionNameOrErr)

859 return SectionNameOrErr.takeError();

860

861

862 if (*SectionNameOrErr == ".debug$T" || *SectionNameOrErr == ".debug$P")

863 if (Error Err = traverseTypeSection(*SectionNameOrErr, Section))

864 return Err;

865 }

866

867

868 LogicalVisitor.processNamespaces();

869

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

871 Expected SectionNameOrErr = Section.getName();

872 if (!SectionNameOrErr)

873 return SectionNameOrErr.takeError();

874 if (*SectionNameOrErr == ".debug$S")

875 if (Error Err = traverseSymbolSection(*SectionNameOrErr, Section))

876 return Err;

877 }

878

879

880 LogicalVisitor.closeScope();

881

882

883 LogicalVisitor.processFiles();

884

885

886 LogicalVisitor.processLines();

887

888

889 Root->transformScopedName();

891}

892

894 if (Error Err = loadTargetInfo(Pdb))

895 return Err;

896

897 if (Pdb.hasPDBTpiStream() || Pdb.hasPDBDbiStream())

899

900

901

902 if (!ExePath.empty()) {

903 ErrorOr<std::unique_ptr> BuffOrErr =

905 if (BuffOrErr.getError()) {

907 "File '%s' does not exist.", ExePath.c_str());

908 }

909 BinaryBuffer = std::move(BuffOrErr.get());

910

911

914 "Invalid PECOFF executable file.");

915

916 Expected<std::unique_ptr> BinOrErr =

917 createBinary(BinaryBuffer->getMemBufferRef());

920 "Binary object format in '%s' is not supported.",

921 ExePath.c_str());

922 }

923 BinaryExecutable = std::move(*BinOrErr);

924 if (COFFObjectFile *COFFObject =

927 }

928

929

930

931

932

933

934

935

936

937

938

939

940

941

942

943

944

945

946 LazyRandomTypeCollection &Types = types();

947 LazyRandomTypeCollection &Ids = ids();

948 if (Error Err = traverseTypes(Pdb, Types, Ids))

949 return Err;

950

951

952 LogicalVisitor.processNamespaces();

953

954 LLVM_DEBUG({ W.getOStream() << "Traversing inlined lines\n"; });

955

956 auto VisitInlineeLines = [&](int32_t Modi, const SymbolGroup &SG,

957 DebugInlineeLinesSubsectionRef &Lines) -> Error {

958 return collectInlineeInfo(Lines, &SG);

959 };

960

961 FilterOptions Filters = {};

962 LinePrinter Printer(2, false, nulls(), Filters);

963 const PrintScope HeaderScope(Printer, 2);

965 Input, HeaderScope, VisitInlineeLines))

966 return Err;

967

968

969 LLVM_DEBUG({ W.getOStream() << "Traversing global symbols\n"; });

970 if (Pdb.hasPDBGlobalsStream()) {

971 Expected<GlobalsStream &> GlobalsOrErr = Pdb.getPDBGlobalsStream();

972 if (!GlobalsOrErr)

974 GlobalsStream &Globals = *GlobalsOrErr;

976 Expected<SymbolStream &> ExpectedSyms = Pdb.getPDBSymbolStream();

977 if (ExpectedSyms) {

978

979 SymbolVisitorCallbackPipeline Pipeline;

980 SymbolDeserializer Deserializer(nullptr, CodeViewContainer::Pdb);

981 LVSymbolVisitor Traverser(this, W, &LogicalVisitor, Types, Ids, nullptr,

982 LogicalVisitor.getShared());

983

984

985

986 RecordPrefix Prefix(SymbolKind::S_COMPILE3);

989 if (Error Err = Traverser.visitSymbolBegin(Symbol, Offset))

991 else {

992

993

994

995 std::string Name(CompileUnit->getParentScope()->getName());

997

1000 CVSymbolVisitor Visitor(Pipeline);

1001

1002 BinaryStreamRef SymStream =

1003 ExpectedSyms->getSymbolArray().getUnderlyingStream();

1004 for (uint32_t PubSymOff : Table) {

1006 if (Sym) {

1007 if (Error Err = Visitor.visitSymbolRecord(*Sym, PubSymOff))

1009 getFileName());

1010 } else {

1012 }

1013 }

1014 }

1015

1016 LogicalVisitor.closeScope();

1017 } else {

1019 }

1020 }

1021

1022

1023 LLVM_DEBUG({ W.getOStream() << "Traversing symbol groups\n"; });

1024

1025 auto VisitSymbolGroup = [&](uint32_t Modi, const SymbolGroup &SG) -> Error {

1026 Expected ExpectedModS =

1028 if (ExpectedModS) {

1029 ModuleDebugStreamRef &ModS = *ExpectedModS;

1030

1032 W.getOStream() << formatv("Traversing Group: Mod {0:4}\n", Modi);

1033 });

1034

1035 SymbolVisitorCallbackPipeline Pipeline;

1036 SymbolDeserializer Deserializer(nullptr, CodeViewContainer::Pdb);

1037 LVSymbolVisitor Traverser(this, W, &LogicalVisitor, Types, Ids, nullptr,

1038 LogicalVisitor.getShared());

1039

1040 Pipeline.addCallbackToPipeline(Deserializer);

1041 Pipeline.addCallbackToPipeline(Traverser);

1042 CVSymbolVisitor Visitor(Pipeline);

1045 Visitor.visitSymbolStream(ModS.getSymbolArray(), SS.Offset))

1047 getFileName());

1048 } else {

1049

1051 }

1052

1054 };

1055

1057 return Err;

1058

1059

1060

1061

1062

1063

1064 LLVM_DEBUG({ W.getOStream() << "Traversing lines\n"; });

1065

1066

1068

1069 auto VisitDebugLines = [this](int32_t Modi, const SymbolGroup &SG,

1070 DebugLinesSubsectionRef &Lines) -> Error {

1071 if (options().getPrintLines())

1073

1074 uint16_t Segment = Lines.header()->RelocSegment;

1075 uint32_t Begin = Lines.header()->RelocOffset;

1076 uint32_t Size = Lines.header()->CodeSize;

1077

1079

1080

1081

1082

1083 if (CurrentModule != Modi) {

1084 if (Error Err = processModule())

1085 return Err;

1087 CurrentModule = Modi;

1088 }

1089

1090 for (const LineColumnEntry &Block : Lines)

1091 if (Error Err = createLines(Block.LineNumbers, 0, Segment,

1092 Begin, Size, Block.NameIndex, &SG))

1093 return Err;

1094

1096 };

1097

1099 Input, HeaderScope, VisitDebugLines))

1100 return Err;

1101

1102

1103 LogicalVisitor.closeScope();

1104

1105

1106 LogicalVisitor.processLines();

1107

1108

1109 Root->transformScopedName();

1111}

1112

1113Error LVCodeViewReader::processModule() {

1116

1117 LLVM_DEBUG({ dbgs() << "Processing Scope: " << Scope->getName() << "\n"; });

1118

1119

1120

1121

1122

1123

1124

1127 ScopesWithRanges->clear();

1128 CompileUnit->getRanges(*ScopesWithRanges);

1129 if (!ScopesWithRanges->empty())

1131 ScopesWithRanges->getUpper());

1132 ScopesWithRanges->sort();

1133

1135 return Err;

1136

1137

1139

1141 }

1142

1144}

1145

1146

1147

1148

1149

1150

1151

1152

1155 W.startLine() << "\n";

1156 W.printString("File", getFileName().str());

1157 W.printString("Exe", ExePath);

1159 });

1160

1162 return Err;

1163

1164 LogicalVisitor.setRoot(Root);

1165

1166 if (isObj()) {

1168 return Err;

1169 } else {

1171 return Err;

1172 }

1173

1175}

1176

1177Error LVCodeViewReader::loadTargetInfo(const ObjectFile &Obj) {

1178

1179

1184

1185

1188 if (!Features) {

1191 }

1192 FeaturesValue = *Features;

1193

1195 if (auto OptCPU = Obj.tryGetCPUName())

1196 CPU = *OptCPU;

1197

1199}

1200

1201Error LVCodeViewReader::loadTargetInfo(const PDBFile &Pdb) {

1206

1209

1211}

1212

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

bbsections Prepares for basic block sections

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)

dxil pretty DXIL Metadata Pretty Printer

static const T * Find(StringRef S, ArrayRef< T > A)

Find KV in array using binary search.

static unsigned getSectionID(const ObjectFile &O, SectionRef Sec)

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

uint64_t getLength() const

Error readInteger(T &Dest)

Read an integer of the specified endianness into Dest and update the stream's offset.

uint64_t bytesRemaining() const

LLVM_ABI Error readFixedString(StringRef &Dest, uint32_t Length)

Read a Length byte string into Dest.

Error readArray(ArrayRef< T > &Array, uint32_t NumElements)

Get a reference to a NumElements element array of objects of type T from the underlying stream as if ...

LLVM_ABI Error skip(uint64_t Amount)

Advance the stream's offset by Amount bytes.

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.

static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileOrSTDIN(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, std::optional< Align > Alignment=std::nullopt)

Open the specified file as a MemoryBuffer, or open stdin if the Filename is "-".

static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)

Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...

virtual void printString(StringRef Value)

virtual raw_ostream & startLine()

virtual void printNumber(StringRef Label, char Value)

void printHex(StringRef Label, T Value)

void printSymbolOffset(StringRef Label, StringRef Symbol, T Value)

void push_back(const T &Elt)

std::pair< iterator, bool > try_emplace(StringRef Key, ArgsTy &&...Args)

Emplace a new element for the specified key into the map if the key isn't already in the map.

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

std::string str() const

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

const unsigned char * bytes_end() const

StringRef drop_front(size_t N=1) const

Return a StringRef equal to 'this' but with the first N elements dropped.

constexpr size_t size() const

size - Get the string size.

constexpr const char * data() const

data - Get a pointer to the start of the string (which may not be null terminated).

const unsigned char * bytes_begin() const

Manages the enabling and disabling of subtarget specific features.

LLVM_ABI std::string getString() const

Returns features as a string.

Triple - Helper class for working with autoconf configuration names.

Iterator at(uint32_t Offset) const

given an offset into the array's underlying stream, return an iterator to the record at that offset.

Iterator begin(bool *HadError=nullptr) const

VarStreamArrayIterator< ValueType, Extractor > Iterator

const FileChecksumArray & getArray() const

LLVM_ABI Expected< StringRef > getString(uint32_t Offset) const

uint32_t getSignature() const

Provides amortized O(1) random access to a CodeView type stream.

uint32_t getSignature() const

StringRef getPrecompFilePath() const

uint32_t getTypesCount() const

void addCallbackToPipeline(SymbolVisitorCallbacks &Callbacks)

static Error deserializeAs(CVType &CVT, T &Record)

StringRef getName() const

const GUID & getGuid() const

const LVSymbolTableEntry & getSymbolTableEntry(StringRef Name)

void includeInlineeLines(LVSectionIndex SectionIndex, LVScope *Function)

Error loadGenericTargetInfo(StringRef TheTriple, StringRef TheFeatures, StringRef TheCPU)

LVAddress linearAddress(uint16_t Segment, uint32_t Offset, LVAddress Addendum=0)

void addToSymbolTable(StringRef Name, LVScope *Function, LVSectionIndex SectionIndex=0)

void processLines(LVLines *DebugLines, LVSectionIndex SectionIndex)

void mapVirtualAddress(const object::ObjectFile &Obj)

Error createInstructions()

void getLinkageName(const llvm::object::coff_section *CoffSection, uint32_t RelocOffset, uint32_t Offset, StringRef *RelocSym)

Definition LVCodeViewReader.cpp:113

void print(raw_ostream &OS) const

Definition LVCodeViewReader.cpp:795

static std::string formatRegisterId(RegisterId Register, CPUType CPU)

Definition LVCodeViewReader.cpp:57

std::string getRegisterName(LVSmall Opcode, ArrayRef< uint64_t > Operands) override

Definition LVCodeViewReader.cpp:1213

friend class LVTypeVisitor

LVScope * getScopeForModule(uint32_t Modi)

Error createScopes() override

Definition LVCodeViewReader.cpp:1153

static StringRef getSymbolKindName(SymbolKind Kind)

Definition LVCodeViewReader.cpp:45

friend class LVSymbolVisitor

friend class LVSymbolVisitorDelegate

bool isSystemEntry(LVElement *Element, StringRef Name) const override

Definition LVCodeViewReader.cpp:213

void sortScopes() override

Definition LVCodeViewReader.cpp:793

StringRef getName() const override

void addInlineeInfo(TypeIndex TI, uint32_t LineNumber, StringRef Filename)

void printTypeIndex(StringRef FieldName, TypeIndex TI, uint32_t StreamIdx)

LVAddress getLower() const

LVAddress getUpper() const

LVRange * getSectionRanges(LVSectionIndex SectionIndex)

std::string FileFormatName

codeview::CPUType getCompileUnitCPUType()

std::string createAlternativePath(StringRef From)

LVScopeCompileUnit * CompileUnit

LVSectionIndex DotTextSectionIndex

virtual Error createScopes()

This is a value type class that represents a single section in the list of sections in the object fil...

This is a value type class that represents a single symbol in the list of symbols in the object file.

const GSIHashTable & getGlobalsTable() const

LLVM_ABI BinarySubstreamRef getSymbolsSubstream() const

const codeview::CVSymbolArray & getSymbolArray() const

LLVM_ABI Expected< StringRef > getNameFromChecksums(uint32_t Offset) const

LLVM_ABI void buildHashMap()

LLVM_ABI uint32_t getNumTypeRecords() const

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

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

constexpr char SymbolName[]

Key for Kernel::Metadata::mSymbolName.

@ IMAGE_SYM_DTYPE_FUNCTION

A function that returns a base type.

CVRecord< TypeLeafKind > CVType

VarStreamArray< CVSymbol > CVSymbolArray

CPUType

These values correspond to the CV_CPU_TYPE_e enumeration, and are documented here: https://msdn....

VarStreamArray< CVType > CVTypeArray

CVRecord< SymbolKind > CVSymbol

LLVM_ABI Error visitTypeStream(const CVTypeArray &Types, TypeVisitorCallbacks &Callbacks, VisitorDataSource Source=VDS_BytesPresent)

SymbolKind

Duplicate copy of the above enum, but using the official CV names.

LLVM_ABI Expected< CVSymbol > readSymbolFromStream(BinaryStreamRef Stream, uint32_t Offset)

Scope

Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...

static const char Magic[]

content_iterator< BasicSymbolRef > basic_symbol_iterator

LLVM_ABI Expected< std::unique_ptr< Binary > > createBinary(MemoryBufferRef Source, LLVMContext *Context=nullptr, bool InitContent=true)

Create a Binary from Source, autodetecting the file type.

LLVM_ABI Expected< ModuleDebugStreamRef > getModuleDebugStream(PDBFile &File, StringRef &ModuleName, uint32_t Index)

Error iterateModuleSubsections(InputFile &File, const PrintScope &HeaderScope, llvm::function_ref< Error(uint32_t, const SymbolGroup &, SubsectionT &)> Callback)

LLVM_ABI Error loadDataForPDB(PDB_ReaderType Type, StringRef Path, std::unique_ptr< IPDBSession > &Session)

Error iterateSymbolGroups(InputFile &Input, const PrintScope &HeaderScope, CallbackT Callback)

detail::packed_endian_specific_integral< uint32_t, llvm::endianness::little, unaligned > ulittle32_t

This is an optimization pass for GlobalISel generic memory operations.

LLVM_ABI file_magic identify_magic(StringRef magic)

Identify the type of a binary file based on how magical it is.

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

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

Wrapper function to append range R to container C.

std::string utostr(uint64_t X, bool isNeg=false)

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

Create formatted StringError object.

auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)

void sort(IteratorTy Start, IteratorTy End)

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

LLVM_ABI raw_ostream & nulls()

This returns a reference to a raw_ostream which simply discards output.

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

Error make_error(ArgTs &&... Args)

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

void cantFail(Error Err, const char *Msg=nullptr)

Report a fatal error if Err is a failure value.

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.

support::detail::AlignAdapter< T > fmt_align(T &&Item, AlignStyle Where, size_t Amount, char Fill=' ')

decltype(auto) cast(const From &Val)

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

LLVM_ABI Error errorCodeToError(std::error_code EC)

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

LLVM_ABI std::error_code errorToErrorCode(Error Err)

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

void consumeError(Error Err)

Consume a Error without doing anything.

@ pdb

Windows PDB debug info file.

@ pecoff_executable

PECOFF executable file.

LVSectionIndex SectionIndex