Home | History | Annotate | Download | only in llvm-pdbutil
      1 //===- InputFile.h -------------------------------------------- *- C++ --*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #ifndef LLVM_TOOLS_LLVMPDBDUMP_INPUTFILE_H
     11 #define LLVM_TOOLS_LLVMPDBDUMP_INPUTFILE_H
     12 
     13 #include "llvm/ADT/Optional.h"
     14 #include "llvm/ADT/PointerUnion.h"
     15 #include "llvm/ADT/StringMap.h"
     16 #include "llvm/ADT/iterator.h"
     17 #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
     18 #include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
     19 #include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
     20 #include "llvm/Object/Binary.h"
     21 #include "llvm/Object/ObjectFile.h"
     22 #include "llvm/Support/Error.h"
     23 
     24 namespace llvm {
     25 namespace codeview {
     26 class LazyRandomTypeCollection;
     27 }
     28 namespace object {
     29 class COFFObjectFile;
     30 class SectionRef;
     31 } // namespace object
     32 
     33 namespace pdb {
     34 class InputFile;
     35 class LinePrinter;
     36 class PDBFile;
     37 class NativeSession;
     38 class SymbolGroupIterator;
     39 class SymbolGroup;
     40 
     41 class InputFile {
     42   InputFile();
     43 
     44   std::unique_ptr<NativeSession> PdbSession;
     45   object::OwningBinary<object::Binary> CoffObject;
     46   std::unique_ptr<MemoryBuffer> UnknownFile;
     47   PointerUnion3<PDBFile *, object::COFFObjectFile *, MemoryBuffer *> PdbOrObj;
     48 
     49   using TypeCollectionPtr = std::unique_ptr<codeview::LazyRandomTypeCollection>;
     50 
     51   TypeCollectionPtr Types;
     52   TypeCollectionPtr Ids;
     53 
     54   enum TypeCollectionKind { kTypes, kIds };
     55   codeview::LazyRandomTypeCollection &
     56   getOrCreateTypeCollection(TypeCollectionKind Kind);
     57 
     58 public:
     59   ~InputFile();
     60   InputFile(InputFile &&Other) = default;
     61 
     62   static Expected<InputFile> open(StringRef Path,
     63                                   bool AllowUnknownFile = false);
     64 
     65   PDBFile &pdb();
     66   const PDBFile &pdb() const;
     67   object::COFFObjectFile &obj();
     68   const object::COFFObjectFile &obj() const;
     69   MemoryBuffer &unknown();
     70   const MemoryBuffer &unknown() const;
     71 
     72   StringRef getFilePath() const;
     73 
     74   bool hasTypes() const;
     75   bool hasIds() const;
     76 
     77   codeview::LazyRandomTypeCollection &types();
     78   codeview::LazyRandomTypeCollection &ids();
     79 
     80   iterator_range<SymbolGroupIterator> symbol_groups();
     81   SymbolGroupIterator symbol_groups_begin();
     82   SymbolGroupIterator symbol_groups_end();
     83 
     84   bool isPdb() const;
     85   bool isObj() const;
     86   bool isUnknown() const;
     87 };
     88 
     89 class SymbolGroup {
     90   friend class SymbolGroupIterator;
     91 
     92 public:
     93   explicit SymbolGroup(InputFile *File, uint32_t GroupIndex = 0);
     94 
     95   Expected<StringRef> getNameFromStringTable(uint32_t Offset) const;
     96 
     97   void formatFromFileName(LinePrinter &Printer, StringRef File,
     98                           bool Append = false) const;
     99 
    100   void formatFromChecksumsOffset(LinePrinter &Printer, uint32_t Offset,
    101                                  bool Append = false) const;
    102 
    103   StringRef name() const;
    104 
    105   codeview::DebugSubsectionArray getDebugSubsections() const {
    106     return Subsections;
    107   }
    108   const ModuleDebugStreamRef &getPdbModuleStream() const;
    109 
    110   const InputFile &getFile() const { return *File; }
    111   InputFile &getFile() { return *File; }
    112 
    113 private:
    114   void initializeForPdb(uint32_t Modi);
    115   void updatePdbModi(uint32_t Modi);
    116   void updateDebugS(const codeview::DebugSubsectionArray &SS);
    117 
    118   void rebuildChecksumMap();
    119   InputFile *File = nullptr;
    120   StringRef Name;
    121   codeview::DebugSubsectionArray Subsections;
    122   std::shared_ptr<ModuleDebugStreamRef> DebugStream;
    123   codeview::StringsAndChecksumsRef SC;
    124   StringMap<codeview::FileChecksumEntry> ChecksumsByFile;
    125 };
    126 
    127 class SymbolGroupIterator
    128     : public iterator_facade_base<SymbolGroupIterator,
    129                                   std::forward_iterator_tag, SymbolGroup> {
    130 public:
    131   SymbolGroupIterator();
    132   explicit SymbolGroupIterator(InputFile &File);
    133   SymbolGroupIterator(const SymbolGroupIterator &Other) = default;
    134   SymbolGroupIterator &operator=(const SymbolGroupIterator &R) = default;
    135 
    136   const SymbolGroup &operator*() const;
    137   SymbolGroup &operator*();
    138 
    139   bool operator==(const SymbolGroupIterator &R) const;
    140   SymbolGroupIterator &operator++();
    141 
    142 private:
    143   void scanToNextDebugS();
    144   bool isEnd() const;
    145 
    146   uint32_t Index = 0;
    147   Optional<object::section_iterator> SectionIter;
    148   SymbolGroup Value;
    149 };
    150 
    151 } // namespace pdb
    152 } // namespace llvm
    153 
    154 #endif
    155