123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- 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
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|