Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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
  231.