Viewing file: InputFile.h (6.91 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
//===- InputFile.h -------------------------------------------- *- C++ --*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===//
#ifndef LLVM_DEBUGINFO_PDB_NATIVE_INPUTFILE_H #define LLVM_DEBUGINFO_PDB_NATIVE_INPUTFILE_H
#include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/iterator.h" #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h" #include "llvm/DebugInfo/CodeView/StringsAndChecksums.h" #include "llvm/DebugInfo/PDB/Native/LinePrinter.h" #include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h" #include "llvm/Object/Binary.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Error.h"
namespace llvm { namespace codeview { class LazyRandomTypeCollection; } namespace object { class COFFObjectFile; } // namespace object
namespace pdb { class InputFile; class LinePrinter; class PDBFile; class NativeSession; class SymbolGroupIterator; class SymbolGroup;
class InputFile { InputFile();
std::unique_ptr<NativeSession> PdbSession; object::OwningBinary<object::Binary> CoffObject; std::unique_ptr<MemoryBuffer> UnknownFile; PointerUnion<PDBFile *, object::COFFObjectFile *, MemoryBuffer *> PdbOrObj;
using TypeCollectionPtr = std::unique_ptr<codeview::LazyRandomTypeCollection>;
TypeCollectionPtr Types; TypeCollectionPtr Ids;
enum TypeCollectionKind { kTypes, kIds }; codeview::LazyRandomTypeCollection & getOrCreateTypeCollection(TypeCollectionKind Kind);
public: InputFile(PDBFile *Pdb) { PdbOrObj = Pdb; } InputFile(object::COFFObjectFile *Obj) { PdbOrObj = Obj; } InputFile(MemoryBuffer *Buffer) { PdbOrObj = Buffer; } ~InputFile(); InputFile(InputFile &&Other) = default;
static Expected<InputFile> open(StringRef Path, bool AllowUnknownFile = false);
PDBFile &pdb(); const PDBFile &pdb() const; object::COFFObjectFile &obj(); const object::COFFObjectFile &obj() const; MemoryBuffer &unknown(); const MemoryBuffer &unknown() const;
StringRef getFilePath() const;
bool hasTypes() const; bool hasIds() const;
codeview::LazyRandomTypeCollection &types(); codeview::LazyRandomTypeCollection &ids();
iterator_range<SymbolGroupIterator> symbol_groups(); SymbolGroupIterator symbol_groups_begin(); SymbolGroupIterator symbol_groups_end();
bool isPdb() const; bool isObj() const; bool isUnknown() const; };
class SymbolGroup { friend class SymbolGroupIterator;
public: explicit SymbolGroup(InputFile *File, uint32_t GroupIndex = 0);
Expected<StringRef> getNameFromStringTable(uint32_t Offset) const; Expected<StringRef> getNameFromChecksums(uint32_t Offset) const;
void formatFromFileName(LinePrinter &Printer, StringRef File, bool Append = false) const;
void formatFromChecksumsOffset(LinePrinter &Printer, uint32_t Offset, bool Append = false) const;
StringRef name() const;
codeview::DebugSubsectionArray getDebugSubsections() const { return Subsections; } const ModuleDebugStreamRef &getPdbModuleStream() const;
const InputFile &getFile() const { return *File; } InputFile &getFile() { return *File; }
bool hasDebugStream() const { return DebugStream != nullptr; }
private: void initializeForPdb(uint32_t Modi); void updatePdbModi(uint32_t Modi); void updateDebugS(const codeview::DebugSubsectionArray &SS);
void rebuildChecksumMap(); InputFile *File = nullptr; StringRef Name; codeview::DebugSubsectionArray Subsections; std::shared_ptr<ModuleDebugStreamRef> DebugStream; codeview::StringsAndChecksumsRef SC; StringMap<codeview::FileChecksumEntry> ChecksumsByFile; };
class SymbolGroupIterator : public iterator_facade_base<SymbolGroupIterator, std::forward_iterator_tag, SymbolGroup> { public: SymbolGroupIterator(); explicit SymbolGroupIterator(InputFile &File); SymbolGroupIterator(const SymbolGroupIterator &Other) = default; SymbolGroupIterator &operator=(const SymbolGroupIterator &R) = default;
const SymbolGroup &operator*() const; SymbolGroup &operator*();
bool operator==(const SymbolGroupIterator &R) const; SymbolGroupIterator &operator++();
private: void scanToNextDebugS(); bool isEnd() const;
uint32_t Index = 0; std::optional<object::section_iterator> SectionIter; SymbolGroup Value; };
Expected<ModuleDebugStreamRef> getModuleDebugStream(PDBFile &File, StringRef &ModuleName, uint32_t Index); Expected<ModuleDebugStreamRef> getModuleDebugStream(PDBFile &File, uint32_t Index);
bool shouldDumpSymbolGroup(uint32_t Idx, const SymbolGroup &Group, const FilterOptions &Filters);
// TODO: Change these callbacks to be function_refs (de-templatify them). template <typename CallbackT> Error iterateOneModule(InputFile &File, const PrintScope &HeaderScope, const SymbolGroup &SG, uint32_t Modi, CallbackT Callback) { HeaderScope.P.formatLine( "Mod {0:4} | `{1}`: ", fmt_align(Modi, AlignStyle::Right, HeaderScope.LabelWidth), SG.name());
AutoIndent Indent(HeaderScope); return Callback(Modi, SG); }
template <typename CallbackT> Error iterateSymbolGroups(InputFile &Input, const PrintScope &HeaderScope, CallbackT Callback) { AutoIndent Indent(HeaderScope);
FilterOptions Filters = HeaderScope.P.getFilters(); if (Filters.DumpModi) { uint32_t Modi = *Filters.DumpModi; SymbolGroup SG(&Input, Modi); return iterateOneModule(Input, withLabelWidth(HeaderScope, NumDigits(Modi)), SG, Modi, Callback); }
uint32_t I = 0;
for (const auto &SG : Input.symbol_groups()) { if (shouldDumpSymbolGroup(I, SG, Filters)) if (auto Err = iterateOneModule(Input, withLabelWidth(HeaderScope, NumDigits(I)), SG, I, Callback)) return Err;
++I; } return Error::success(); }
template <typename SubsectionT> Error iterateModuleSubsections( InputFile &File, const PrintScope &HeaderScope, llvm::function_ref<Error(uint32_t, const SymbolGroup &, SubsectionT &)> Callback) {
return iterateSymbolGroups( File, HeaderScope, [&](uint32_t Modi, const SymbolGroup &SG) -> Error { for (const auto &SS : SG.getDebugSubsections()) { SubsectionT Subsection;
if (SS.kind() != Subsection.kind()) continue;
BinaryStreamReader Reader(SS.getRecordData()); if (auto Err = Subsection.initialize(Reader)) continue; if (auto Err = Callback(Modi, SG, Subsection)) return Err; } return Error::success(); }); }
} // namespace pdb } // namespace llvm
#endif
|