Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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_DEBUGINFO_PDB_NATIVE_INPUTFILE_H
10
#define LLVM_DEBUGINFO_PDB_NATIVE_INPUTFILE_H
11
 
12
#include "llvm/ADT/PointerUnion.h"
13
#include "llvm/ADT/StringMap.h"
14
#include "llvm/ADT/iterator.h"
15
#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
16
#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
17
#include "llvm/DebugInfo/PDB/Native/LinePrinter.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
} // namespace object
30
 
31
namespace pdb {
32
class InputFile;
33
class LinePrinter;
34
class PDBFile;
35
class NativeSession;
36
class SymbolGroupIterator;
37
class SymbolGroup;
38
 
39
class InputFile {
40
  InputFile();
41
 
42
  std::unique_ptr<NativeSession> PdbSession;
43
  object::OwningBinary<object::Binary> CoffObject;
44
  std::unique_ptr<MemoryBuffer> UnknownFile;
45
  PointerUnion<PDBFile *, object::COFFObjectFile *, MemoryBuffer *> PdbOrObj;
46
 
47
  using TypeCollectionPtr = std::unique_ptr<codeview::LazyRandomTypeCollection>;
48
 
49
  TypeCollectionPtr Types;
50
  TypeCollectionPtr Ids;
51
 
52
  enum TypeCollectionKind { kTypes, kIds };
53
  codeview::LazyRandomTypeCollection &
54
  getOrCreateTypeCollection(TypeCollectionKind Kind);
55
 
56
public:
57
  InputFile(PDBFile *Pdb) { PdbOrObj = Pdb; }
58
  InputFile(object::COFFObjectFile *Obj) { PdbOrObj = Obj; }
59
  InputFile(MemoryBuffer *Buffer) { PdbOrObj = Buffer; }
60
  ~InputFile();
61
  InputFile(InputFile &&Other) = default;
62
 
63
  static Expected<InputFile> open(StringRef Path,
64
                                  bool AllowUnknownFile = false);
65
 
66
  PDBFile &pdb();
67
  const PDBFile &pdb() const;
68
  object::COFFObjectFile &obj();
69
  const object::COFFObjectFile &obj() const;
70
  MemoryBuffer &unknown();
71
  const MemoryBuffer &unknown() const;
72
 
73
  StringRef getFilePath() const;
74
 
75
  bool hasTypes() const;
76
  bool hasIds() const;
77
 
78
  codeview::LazyRandomTypeCollection &types();
79
  codeview::LazyRandomTypeCollection &ids();
80
 
81
  iterator_range<SymbolGroupIterator> symbol_groups();
82
  SymbolGroupIterator symbol_groups_begin();
83
  SymbolGroupIterator symbol_groups_end();
84
 
85
  bool isPdb() const;
86
  bool isObj() const;
87
  bool isUnknown() const;
88
};
89
 
90
class SymbolGroup {
91
  friend class SymbolGroupIterator;
92
 
93
public:
94
  explicit SymbolGroup(InputFile *File, uint32_t GroupIndex = 0);
95
 
96
  Expected<StringRef> getNameFromStringTable(uint32_t Offset) const;
97
  Expected<StringRef> getNameFromChecksums(uint32_t Offset) const;
98
 
99
  void formatFromFileName(LinePrinter &Printer, StringRef File,
100
                          bool Append = false) const;
101
 
102
  void formatFromChecksumsOffset(LinePrinter &Printer, uint32_t Offset,
103
                                 bool Append = false) const;
104
 
105
  StringRef name() const;
106
 
107
  codeview::DebugSubsectionArray getDebugSubsections() const {
108
    return Subsections;
109
  }
110
  const ModuleDebugStreamRef &getPdbModuleStream() const;
111
 
112
  const InputFile &getFile() const { return *File; }
113
  InputFile &getFile() { return *File; }
114
 
115
  bool hasDebugStream() const { return DebugStream != nullptr; }
116
 
117
private:
118
  void initializeForPdb(uint32_t Modi);
119
  void updatePdbModi(uint32_t Modi);
120
  void updateDebugS(const codeview::DebugSubsectionArray &SS);
121
 
122
  void rebuildChecksumMap();
123
  InputFile *File = nullptr;
124
  StringRef Name;
125
  codeview::DebugSubsectionArray Subsections;
126
  std::shared_ptr<ModuleDebugStreamRef> DebugStream;
127
  codeview::StringsAndChecksumsRef SC;
128
  StringMap<codeview::FileChecksumEntry> ChecksumsByFile;
129
};
130
 
131
class SymbolGroupIterator
132
    : public iterator_facade_base<SymbolGroupIterator,
133
                                  std::forward_iterator_tag, SymbolGroup> {
134
public:
135
  SymbolGroupIterator();
136
  explicit SymbolGroupIterator(InputFile &File);
137
  SymbolGroupIterator(const SymbolGroupIterator &Other) = default;
138
  SymbolGroupIterator &operator=(const SymbolGroupIterator &R) = default;
139
 
140
  const SymbolGroup &operator*() const;
141
  SymbolGroup &operator*();
142
 
143
  bool operator==(const SymbolGroupIterator &R) const;
144
  SymbolGroupIterator &operator++();
145
 
146
private:
147
  void scanToNextDebugS();
148
  bool isEnd() const;
149
 
150
  uint32_t Index = 0;
151
  std::optional<object::section_iterator> SectionIter;
152
  SymbolGroup Value;
153
};
154
 
155
Expected<ModuleDebugStreamRef>
156
getModuleDebugStream(PDBFile &File, StringRef &ModuleName, uint32_t Index);
157
Expected<ModuleDebugStreamRef> getModuleDebugStream(PDBFile &File,
158
                                                    uint32_t Index);
159
 
160
bool shouldDumpSymbolGroup(uint32_t Idx, const SymbolGroup &Group,
161
                           const FilterOptions &Filters);
162
 
163
// TODO: Change these callbacks to be function_refs (de-templatify them).
164
template <typename CallbackT>
165
Error iterateOneModule(InputFile &File, const PrintScope &HeaderScope,
166
                       const SymbolGroup &SG, uint32_t Modi,
167
                       CallbackT Callback) {
168
  HeaderScope.P.formatLine(
169
      "Mod {0:4} | `{1}`: ",
170
      fmt_align(Modi, AlignStyle::Right, HeaderScope.LabelWidth), SG.name());
171
 
172
  AutoIndent Indent(HeaderScope);
173
  return Callback(Modi, SG);
174
}
175
 
176
template <typename CallbackT>
177
Error iterateSymbolGroups(InputFile &Input, const PrintScope &HeaderScope,
178
                          CallbackT Callback) {
179
  AutoIndent Indent(HeaderScope);
180
 
181
  FilterOptions Filters = HeaderScope.P.getFilters();
182
  if (Filters.DumpModi) {
183
    uint32_t Modi = *Filters.DumpModi;
184
    SymbolGroup SG(&Input, Modi);
185
    return iterateOneModule(Input, withLabelWidth(HeaderScope, NumDigits(Modi)),
186
                            SG, Modi, Callback);
187
  }
188
 
189
  uint32_t I = 0;
190
 
191
  for (const auto &SG : Input.symbol_groups()) {
192
    if (shouldDumpSymbolGroup(I, SG, Filters))
193
      if (auto Err =
194
              iterateOneModule(Input, withLabelWidth(HeaderScope, NumDigits(I)),
195
                               SG, I, Callback))
196
        return Err;
197
 
198
    ++I;
199
  }
200
  return Error::success();
201
}
202
 
203
template <typename SubsectionT>
204
Error iterateModuleSubsections(
205
    InputFile &File, const PrintScope &HeaderScope,
206
    llvm::function_ref<Error(uint32_t, const SymbolGroup &, SubsectionT &)>
207
        Callback) {
208
 
209
  return iterateSymbolGroups(
210
      File, HeaderScope, [&](uint32_t Modi, const SymbolGroup &SG) -> Error {
211
        for (const auto &SS : SG.getDebugSubsections()) {
212
          SubsectionT Subsection;
213
 
214
          if (SS.kind() != Subsection.kind())
215
            continue;
216
 
217
          BinaryStreamReader Reader(SS.getRecordData());
218
          if (auto Err = Subsection.initialize(Reader))
219
            continue;
220
          if (auto Err = Callback(Modi, SG, Subsection))
221
            return Err;
222
        }
223
        return Error::success();
224
      });
225
}
226
 
227
} // namespace pdb
228
} // namespace llvm
229
 
230
#endif