InputFile.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- InputFile.h -------------------------------------------- *- C++ --*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_DEBUGINFO_PDB_NATIVE_INPUTFILE_H
  14. #define LLVM_DEBUGINFO_PDB_NATIVE_INPUTFILE_H
  15. #include "llvm/ADT/PointerUnion.h"
  16. #include "llvm/ADT/StringMap.h"
  17. #include "llvm/ADT/iterator.h"
  18. #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
  19. #include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
  20. #include "llvm/DebugInfo/PDB/Native/LinePrinter.h"
  21. #include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
  22. #include "llvm/Object/Binary.h"
  23. #include "llvm/Object/ObjectFile.h"
  24. #include "llvm/Support/Error.h"
  25. namespace llvm {
  26. namespace codeview {
  27. class LazyRandomTypeCollection;
  28. }
  29. namespace object {
  30. class COFFObjectFile;
  31. } // namespace object
  32. namespace pdb {
  33. class InputFile;
  34. class LinePrinter;
  35. class PDBFile;
  36. class NativeSession;
  37. class SymbolGroupIterator;
  38. class SymbolGroup;
  39. class InputFile {
  40. InputFile();
  41. std::unique_ptr<NativeSession> PdbSession;
  42. object::OwningBinary<object::Binary> CoffObject;
  43. std::unique_ptr<MemoryBuffer> UnknownFile;
  44. PointerUnion<PDBFile *, object::COFFObjectFile *, MemoryBuffer *> PdbOrObj;
  45. using TypeCollectionPtr = std::unique_ptr<codeview::LazyRandomTypeCollection>;
  46. TypeCollectionPtr Types;
  47. TypeCollectionPtr Ids;
  48. enum TypeCollectionKind { kTypes, kIds };
  49. codeview::LazyRandomTypeCollection &
  50. getOrCreateTypeCollection(TypeCollectionKind Kind);
  51. public:
  52. InputFile(PDBFile *Pdb) { PdbOrObj = Pdb; }
  53. InputFile(object::COFFObjectFile *Obj) { PdbOrObj = Obj; }
  54. InputFile(MemoryBuffer *Buffer) { PdbOrObj = Buffer; }
  55. ~InputFile();
  56. InputFile(InputFile &&Other) = default;
  57. static Expected<InputFile> open(StringRef Path,
  58. bool AllowUnknownFile = false);
  59. PDBFile &pdb();
  60. const PDBFile &pdb() const;
  61. object::COFFObjectFile &obj();
  62. const object::COFFObjectFile &obj() const;
  63. MemoryBuffer &unknown();
  64. const MemoryBuffer &unknown() const;
  65. StringRef getFilePath() const;
  66. bool hasTypes() const;
  67. bool hasIds() const;
  68. codeview::LazyRandomTypeCollection &types();
  69. codeview::LazyRandomTypeCollection &ids();
  70. iterator_range<SymbolGroupIterator> symbol_groups();
  71. SymbolGroupIterator symbol_groups_begin();
  72. SymbolGroupIterator symbol_groups_end();
  73. bool isPdb() const;
  74. bool isObj() const;
  75. bool isUnknown() const;
  76. };
  77. class SymbolGroup {
  78. friend class SymbolGroupIterator;
  79. public:
  80. explicit SymbolGroup(InputFile *File, uint32_t GroupIndex = 0);
  81. Expected<StringRef> getNameFromStringTable(uint32_t Offset) const;
  82. Expected<StringRef> getNameFromChecksums(uint32_t Offset) const;
  83. void formatFromFileName(LinePrinter &Printer, StringRef File,
  84. bool Append = false) const;
  85. void formatFromChecksumsOffset(LinePrinter &Printer, uint32_t Offset,
  86. bool Append = false) const;
  87. StringRef name() const;
  88. codeview::DebugSubsectionArray getDebugSubsections() const {
  89. return Subsections;
  90. }
  91. const ModuleDebugStreamRef &getPdbModuleStream() const;
  92. const InputFile &getFile() const { return *File; }
  93. InputFile &getFile() { return *File; }
  94. bool hasDebugStream() const { return DebugStream != nullptr; }
  95. private:
  96. void initializeForPdb(uint32_t Modi);
  97. void updatePdbModi(uint32_t Modi);
  98. void updateDebugS(const codeview::DebugSubsectionArray &SS);
  99. void rebuildChecksumMap();
  100. InputFile *File = nullptr;
  101. StringRef Name;
  102. codeview::DebugSubsectionArray Subsections;
  103. std::shared_ptr<ModuleDebugStreamRef> DebugStream;
  104. codeview::StringsAndChecksumsRef SC;
  105. StringMap<codeview::FileChecksumEntry> ChecksumsByFile;
  106. };
  107. class SymbolGroupIterator
  108. : public iterator_facade_base<SymbolGroupIterator,
  109. std::forward_iterator_tag, SymbolGroup> {
  110. public:
  111. SymbolGroupIterator();
  112. explicit SymbolGroupIterator(InputFile &File);
  113. SymbolGroupIterator(const SymbolGroupIterator &Other) = default;
  114. SymbolGroupIterator &operator=(const SymbolGroupIterator &R) = default;
  115. const SymbolGroup &operator*() const;
  116. SymbolGroup &operator*();
  117. bool operator==(const SymbolGroupIterator &R) const;
  118. SymbolGroupIterator &operator++();
  119. private:
  120. void scanToNextDebugS();
  121. bool isEnd() const;
  122. uint32_t Index = 0;
  123. std::optional<object::section_iterator> SectionIter;
  124. SymbolGroup Value;
  125. };
  126. Expected<ModuleDebugStreamRef>
  127. getModuleDebugStream(PDBFile &File, StringRef &ModuleName, uint32_t Index);
  128. Expected<ModuleDebugStreamRef> getModuleDebugStream(PDBFile &File,
  129. uint32_t Index);
  130. bool shouldDumpSymbolGroup(uint32_t Idx, const SymbolGroup &Group,
  131. const FilterOptions &Filters);
  132. // TODO: Change these callbacks to be function_refs (de-templatify them).
  133. template <typename CallbackT>
  134. Error iterateOneModule(InputFile &File, const PrintScope &HeaderScope,
  135. const SymbolGroup &SG, uint32_t Modi,
  136. CallbackT Callback) {
  137. HeaderScope.P.formatLine(
  138. "Mod {0:4} | `{1}`: ",
  139. fmt_align(Modi, AlignStyle::Right, HeaderScope.LabelWidth), SG.name());
  140. AutoIndent Indent(HeaderScope);
  141. return Callback(Modi, SG);
  142. }
  143. template <typename CallbackT>
  144. Error iterateSymbolGroups(InputFile &Input, const PrintScope &HeaderScope,
  145. CallbackT Callback) {
  146. AutoIndent Indent(HeaderScope);
  147. FilterOptions Filters = HeaderScope.P.getFilters();
  148. if (Filters.DumpModi) {
  149. uint32_t Modi = *Filters.DumpModi;
  150. SymbolGroup SG(&Input, Modi);
  151. return iterateOneModule(Input, withLabelWidth(HeaderScope, NumDigits(Modi)),
  152. SG, Modi, Callback);
  153. }
  154. uint32_t I = 0;
  155. for (const auto &SG : Input.symbol_groups()) {
  156. if (shouldDumpSymbolGroup(I, SG, Filters))
  157. if (auto Err =
  158. iterateOneModule(Input, withLabelWidth(HeaderScope, NumDigits(I)),
  159. SG, I, Callback))
  160. return Err;
  161. ++I;
  162. }
  163. return Error::success();
  164. }
  165. template <typename SubsectionT>
  166. Error iterateModuleSubsections(
  167. InputFile &File, const PrintScope &HeaderScope,
  168. llvm::function_ref<Error(uint32_t, const SymbolGroup &, SubsectionT &)>
  169. Callback) {
  170. return iterateSymbolGroups(
  171. File, HeaderScope, [&](uint32_t Modi, const SymbolGroup &SG) -> Error {
  172. for (const auto &SS : SG.getDebugSubsections()) {
  173. SubsectionT Subsection;
  174. if (SS.kind() != Subsection.kind())
  175. continue;
  176. BinaryStreamReader Reader(SS.getRecordData());
  177. if (auto Err = Subsection.initialize(Reader))
  178. continue;
  179. if (auto Err = Callback(Modi, SG, Subsection))
  180. return Err;
  181. }
  182. return Error::success();
  183. });
  184. }
  185. } // namespace pdb
  186. } // namespace llvm
  187. #endif
  188. #ifdef __GNUC__
  189. #pragma GCC diagnostic pop
  190. #endif