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