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
23namespace llvm {
24namespace codeview {
25class LazyRandomTypeCollection;
26}
27namespace object {
28class COFFObjectFile;
29class SectionRef;
30} // namespace object
31
32namespace pdb {
33class InputFile;
34class LinePrinter;
35class PDBFile;
36class NativeSession;
37class SymbolGroupIterator;
38class SymbolGroup;
39
40class 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
57public:
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
88class SymbolGroup {
89  friend class SymbolGroupIterator;
90
91public:
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
104  codeview::DebugSubsectionArray getDebugSubsections() const {
105    return Subsections;
106  }
107  const ModuleDebugStreamRef &getPdbModuleStream() const;
108
109  const InputFile &getFile() const { return *File; }
110  InputFile &getFile() { return *File; }
111
112  bool hasDebugStream() const { return DebugStream != nullptr; }
113
114private:
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
128class SymbolGroupIterator
129    : public iterator_facade_base<SymbolGroupIterator,
130                                  std::forward_iterator_tag, SymbolGroup> {
131public:
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
143private:
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