LLVM: lib/DebugInfo/PDB/Native/InputFile.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

10

29

30using namespace llvm;

34

35InputFile::InputFile() = default;

37

42 if (!DbiOrErr)

45 const auto &Modules = Dbi.modules();

46 if (Index >= Modules.getModuleCount())

47 return make_error(raw_error_code::index_out_of_bounds,

48 "Invalid module index");

49

50 auto Modi = Modules.getModuleDescriptor(Index);

51

53

54 uint16_t ModiStream = Modi.getModuleStreamIndex();

56 return make_error(raw_error_code::no_stream,

57 "Module stream not present");

58

59 auto ModStreamData = File.createIndexedStream(ModiStream);

60

63 return make_error(raw_error_code::corrupt_file,

64 "Invalid module stream");

65

66 return std::move(ModS);

67}

68

72 if (!DbiOrErr)

75 const auto &Modules = Dbi.modules();

77

78 uint16_t ModiStream = Modi.getModuleStreamIndex();

80 return make_error(raw_error_code::no_stream,

81 "Module stream not present");

82

83 auto ModStreamData = File.createIndexedStream(ModiStream);

84

87 return make_error(raw_error_code::corrupt_file,

88 "Invalid module stream");

89

90 return std::move(ModS);

91}

92

97 if (*NameOrErr != Name)

98 return false;

99 } else {

101 return false;

102 }

103

105 if (!ContentsOrErr) {

107 return false;

108 }

109

113 return false;

116 return false;

117 return true;

118}

119

124 return false;

125

127 return true;

128}

129

134 return false;

136 return true;

137}

138

140 switch (Kind) {

145 }

147}

148

149template <typename... Args>

151 if (Append)

152 Printer.format(std::forward(args)...);

153 else

154 Printer.formatLine(std::forward(args)...);

155}

156

158 if (!File)

159 return;

160

161 if (File->isPdb())

162 initializeForPdb(GroupIndex);

163 else {

164 Name = ".debug$S";

166 for (const auto &S : File->obj().sections()) {

169 continue;

170

173

174 if (I == GroupIndex)

175 Subsections = SS;

176

178 break;

179 }

180 rebuildChecksumMap();

181 }

182}

183

185

187 Subsections = SS;

188}

189

190void SymbolGroup::updatePdbModi(uint32_t Modi) { initializeForPdb(Modi); }

191

192void SymbolGroup::initializeForPdb(uint32_t Modi) {

194

195

196

201 else

203 }

204

207 if (!MDS) {

209 return;

210 }

211

212 DebugStream = std::make_shared(std::move(*MDS));

213 Subsections = DebugStream->getSubsectionsArray();

215 rebuildChecksumMap();

216}

217

218void SymbolGroup::rebuildChecksumMap() {

220 return;

221

222 for (const auto &Entry : SC.checksums()) {

224 if (!S)

225 continue;

226 ChecksumsByFile[*S] = Entry;

227 }

228}

229

231 assert(File && File->isPdb() && DebugStream);

232 return *DebugStream;

233}

234

237}

238

242 return std::move(Name);

243 }

244

247 return std::move(Name);

248 }

249

250 uint32_t FO = Iter->FileNameOffset;

252 if (!ExpectedFile) {

253 return std::move(Name);

254 }

255

256 return *ExpectedFile;

257}

258

260 bool Append) const {

261 auto FC = ChecksumsByFile.find(File);

262 if (FC == ChecksumsByFile.end()) {

264 return;

265 }

266

269 toHex(FC->getValue().Checksum), File);

270}

271

274 bool Append) const {

277 return;

278 }

279

283 return;

284 }

285

286 uint32_t FO = Iter->FileNameOffset;

288 if (!ExpectedFile) {

291 return;

292 }

293 if (Iter->Kind == FileChecksumKind::None) {

295 } else {

298 }

299}

300

304 return make_error(formatv("File {0} not found", Path),

306

309 return make_error(

310 formatv("Unable to identify file type for file {0}", Path), EC);

311

314 if (!BinaryOrErr)

316

317 IF.CoffObject = std::move(*BinaryOrErr);

318 IF.PdbOrObj = llvm::cast(IF.CoffObject.getBinary());

319 return std::move(IF);

320 }

321

323 std::unique_ptr Session;

325 return std::move(Err);

326

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

328 IF.PdbOrObj = &IF.PdbSession->getPDBFile();

329

330 return std::move(IF);

331 }

332

333 if (!AllowUnknownFile)

334 return make_error(

335 formatv("File {0} is not a supported file type", Path),

337

339 false);

340 if (!Result)

341 return make_error(

342 formatv("File {0} could not be opened", Path), Result.getError());

343

344 IF.UnknownFile = std::move(*Result);

345 IF.PdbOrObj = IF.UnknownFile.get();

346 return std::move(IF);

347}

348

351 return *cast<PDBFile *>(PdbOrObj);

352}

353

356 return *cast<PDBFile *>(PdbOrObj);

357}

358

361 return *cast<object::COFFObjectFile *>(PdbOrObj);

362}

363

366 return *cast<object::COFFObjectFile *>(PdbOrObj);

367}

368

371 return *cast<MemoryBuffer *>(PdbOrObj);

372}

373

376 return *cast<MemoryBuffer *>(PdbOrObj);

377}

378

386}

387

391

392 for (const auto &Section : obj().sections()) {

395 return true;

396 }

397 return false;

398}

399

402 return false;

404}

405

407

409 return isa<object::COFFObjectFile *>(PdbOrObj);

410}

411

413

415InputFile::getOrCreateTypeCollection(TypeCollectionKind Kind) {

416 if (Types && Kind == kTypes)

417 return *Types;

418 if (Ids && Kind == kIds)

419 return *Ids;

420

421 if (Kind == kIds) {

423 }

424

425

426

428 TypeCollectionPtr &Collection = (Kind == kIds) ? Ids : Types;

429 auto &Stream = cantFail((Kind == kIds) ? pdb().getPDBIpiStream()

430 : pdb().getPDBTpiStream());

431

432 auto &Array = Stream.typeArray();

433 uint32_t Count = Stream.getNumTypeRecords();

434 auto Offsets = Stream.getTypeIndexOffsets();

435 Collection =

436 std::make_unique(Array, Count, Offsets);

437 return *Collection;

438 }

439

443

444 for (const auto &Section : obj().sections()) {

447 continue;

448

449 Types = std::make_unique(Records, 100);

450 return *Types;

451 }

452

453 Types = std::make_unique(100);

454 return *Types;

455}

456

458 return getOrCreateTypeCollection(kTypes);

459}

460

462

463

464

465 if (isObj() || pdb().hasPDBIpiStream())

467

468 return getOrCreateTypeCollection(kIds);

469}

470

474}

475

478}

479

482}

483

485

487 if (File.isObj()) {

488 SectionIter = File.obj().section_begin();

489 scanToNextDebugS();

490 }

491}

492

494 bool E = isEnd();

495 bool RE = R.isEnd();

496 if (E || RE)

497 return E == RE;

498

499 if (Value.File != R.Value.File)

500 return false;

501 return Index == R.Index;

502}

503

507}

511}

512

515 ++Index;

516 if (isEnd())

517 return *this;

518

519 if (Value.File->isPdb()) {

520 Value.updatePdbModi(Index);

521 return *this;

522 }

523

524 scanToNextDebugS();

525 return *this;

526}

527

528void SymbolGroupIterator::scanToNextDebugS() {

530 auto End = Value.File->obj().section_end();

531 auto &Iter = *SectionIter;

533

534 while (++Iter != End) {

538 continue;

539

540 Value.updateDebugS(SS);

541 return;

542 }

543}

544

545bool SymbolGroupIterator::isEnd() const {

547 return true;

548 if (Value.File->isPdb()) {

551 assert(Index <= Count);

552 return Index == Count;

553 }

554

556 return *SectionIter == Value.File->obj().section_end();

557}

558

561 return true;

562

564 if (Name.starts_with("Import:"))

565 return false;

566 if (Name.ends_with_insensitive(".dll"))

567 return false;

568 if (Name.equals_insensitive("* linker *"))

569 return false;

570 if (Name.starts_with_insensitive("f:\\binaries\\Intermediate\\vctools"))

571 return false;

572 if (Name.starts_with_insensitive("f:\\dd\\vctools\\crt"))

573 return false;

574 return true;

575}

576

580 return false;

581

582

584 return true;

585

586

588}

bbsections Prepares for basic block sections

dxil pretty DXIL Metadata Pretty Printer

Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx

#define RETURN_CASE(Enum, X, Ret)

static bool isDebugSSection(object::SectionRef Section, DebugSubsectionArray &Subsections)

static void formatInternal(LinePrinter &Printer, bool Append, Args &&...args)

static bool isDebugTSection(SectionRef Section, CVTypeArray &Types)

static bool isCodeViewDebugSubsection(object::SectionRef Section, StringRef Name, BinaryStreamReader &Reader)

static std::string formatChecksumKind(FileChecksumKind Kind)

static bool isMyCode(const SymbolGroup &Group)

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

Provides read only access to a subclass of BinaryStream.

Error readInteger(T &Dest)

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

uint64_t bytesRemaining() const

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

Lightweight error class with error context and mandatory checking.

Tagged union holding either a T or a Error.

Error takeError()

Take ownership of the stored error.

This interface provides simple read-only access to a block of memory, and provides simple methods for...

virtual StringRef getBufferIdentifier() const

Return an identifier for this buffer, typically the filename it was read from.

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

A class that wrap the SHA1 algorithm.

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

A table of densely packed, null-terminated strings indexed by offset.

LLVM Value Representation.

Iterator at(uint32_t Offset) const

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

const FileChecksumArray & getArray() const

Expected< StringRef > getString(uint32_t Offset) const

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

void setStrings(const DebugStringTableSubsectionRef &Strings)

const DebugStringTableSubsectionRef & strings() const

bool hasChecksums() const

void initialize(T &&FragmentRange)

const DebugChecksumsSubsectionRef & checksums() const

A range adaptor for a pair of iterators.

StringRef getFileName() const

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

DbiModuleDescriptor getModuleDescriptor(uint32_t Modi) const

uint32_t getModuleCount() const

const DbiModuleList & modules() const

SymbolGroupIterator symbol_groups_begin()

iterator_range< SymbolGroupIterator > symbol_groups()

StringRef getFilePath() const

codeview::LazyRandomTypeCollection & types()

static Expected< InputFile > open(StringRef Path, bool AllowUnknownFile=false)

SymbolGroupIterator symbol_groups_end()

codeview::LazyRandomTypeCollection & ids()

object::COFFObjectFile & obj()

bool hasPDBTpiStream() const

bool hasPDBIpiStream() const

StringRef getFilePath() const

Expected< PDBStringTable & > getStringTable()

SymbolGroupIterator & operator++()

const SymbolGroup & operator*() const

bool operator==(const SymbolGroupIterator &R) const

Expected< StringRef > getNameFromChecksums(uint32_t Offset) const

Expected< StringRef > getNameFromStringTable(uint32_t Offset) const

SymbolGroup(InputFile *File, uint32_t GroupIndex=0)

void formatFromFileName(LinePrinter &Printer, StringRef File, bool Append=false) const

const ModuleDebugStreamRef & getPdbModuleStream() const

void formatFromChecksumsOffset(LinePrinter &Printer, uint32_t Offset, bool Append=false) const

const InputFile & getFile() const

constexpr char Args[]

Key for Kernel::Metadata::mArgs.

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

Create a Binary from Source, autodetecting the file type.

bool shouldDumpSymbolGroup(uint32_t Idx, const SymbolGroup &Group, const FilterOptions &Filters)

const uint16_t kInvalidStreamIndex

std::string formatUnknownEnum(T Value)

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

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

bool exists(const basic_file_status &status)

Does file exist?

This is an optimization pass for GlobalISel generic memory operations.

file_magic identify_magic(StringRef magic)

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

std::error_code inconvertibleErrorCode()

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

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

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

Report a fatal error if Err is a failure value.

void consumeError(Error Err)

Consume a Error without doing anything.

std::optional< uint32_t > DumpModi

file_magic - An "enum class" enumeration of file types based on magic (the first N bytes of the file)...

@ pdb

Windows PDB debug info file.

@ coff_object

COFF object file.