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