Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:44

0001 //===- InputFile.h -------------------------------------------- *- C++ --*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_DEBUGINFO_PDB_NATIVE_INPUTFILE_H
0010 #define LLVM_DEBUGINFO_PDB_NATIVE_INPUTFILE_H
0011 
0012 #include "llvm/ADT/PointerUnion.h"
0013 #include "llvm/ADT/StringMap.h"
0014 #include "llvm/ADT/iterator.h"
0015 #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
0016 #include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
0017 #include "llvm/DebugInfo/PDB/Native/LinePrinter.h"
0018 #include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
0019 #include "llvm/Object/Binary.h"
0020 #include "llvm/Object/ObjectFile.h"
0021 #include "llvm/Support/Error.h"
0022 
0023 namespace llvm {
0024 namespace codeview {
0025 class LazyRandomTypeCollection;
0026 }
0027 namespace object {
0028 class COFFObjectFile;
0029 } // namespace object
0030 
0031 namespace pdb {
0032 class InputFile;
0033 class LinePrinter;
0034 class PDBFile;
0035 class NativeSession;
0036 class SymbolGroupIterator;
0037 class SymbolGroup;
0038 
0039 class InputFile {
0040   InputFile();
0041 
0042   std::unique_ptr<NativeSession> PdbSession;
0043   object::OwningBinary<object::Binary> CoffObject;
0044   std::unique_ptr<MemoryBuffer> UnknownFile;
0045   PointerUnion<PDBFile *, object::COFFObjectFile *, MemoryBuffer *> PdbOrObj;
0046 
0047   using TypeCollectionPtr = std::unique_ptr<codeview::LazyRandomTypeCollection>;
0048 
0049   TypeCollectionPtr Types;
0050   TypeCollectionPtr Ids;
0051 
0052   enum TypeCollectionKind { kTypes, kIds };
0053   codeview::LazyRandomTypeCollection &
0054   getOrCreateTypeCollection(TypeCollectionKind Kind);
0055 
0056 public:
0057   InputFile(PDBFile *Pdb) { PdbOrObj = Pdb; }
0058   InputFile(object::COFFObjectFile *Obj) { PdbOrObj = Obj; }
0059   InputFile(MemoryBuffer *Buffer) { PdbOrObj = Buffer; }
0060   ~InputFile();
0061   InputFile(InputFile &&Other) = default;
0062 
0063   static Expected<InputFile> open(StringRef Path,
0064                                   bool AllowUnknownFile = false);
0065 
0066   PDBFile &pdb();
0067   const PDBFile &pdb() const;
0068   object::COFFObjectFile &obj();
0069   const object::COFFObjectFile &obj() const;
0070   MemoryBuffer &unknown();
0071   const MemoryBuffer &unknown() const;
0072 
0073   StringRef getFilePath() const;
0074 
0075   bool hasTypes() const;
0076   bool hasIds() const;
0077 
0078   codeview::LazyRandomTypeCollection &types();
0079   codeview::LazyRandomTypeCollection &ids();
0080 
0081   iterator_range<SymbolGroupIterator> symbol_groups();
0082   SymbolGroupIterator symbol_groups_begin();
0083   SymbolGroupIterator symbol_groups_end();
0084 
0085   bool isPdb() const;
0086   bool isObj() const;
0087   bool isUnknown() const;
0088 };
0089 
0090 class SymbolGroup {
0091   friend class SymbolGroupIterator;
0092 
0093 public:
0094   explicit SymbolGroup(InputFile *File, uint32_t GroupIndex = 0);
0095 
0096   Expected<StringRef> getNameFromStringTable(uint32_t Offset) const;
0097   Expected<StringRef> getNameFromChecksums(uint32_t Offset) const;
0098 
0099   void formatFromFileName(LinePrinter &Printer, StringRef File,
0100                           bool Append = false) const;
0101 
0102   void formatFromChecksumsOffset(LinePrinter &Printer, uint32_t Offset,
0103                                  bool Append = false) const;
0104 
0105   StringRef name() const;
0106 
0107   codeview::DebugSubsectionArray getDebugSubsections() const {
0108     return Subsections;
0109   }
0110   const ModuleDebugStreamRef &getPdbModuleStream() const;
0111 
0112   const InputFile &getFile() const { return *File; }
0113   InputFile &getFile() { return *File; }
0114 
0115   bool hasDebugStream() const { return DebugStream != nullptr; }
0116 
0117 private:
0118   void initializeForPdb(uint32_t Modi);
0119   void updatePdbModi(uint32_t Modi);
0120   void updateDebugS(const codeview::DebugSubsectionArray &SS);
0121 
0122   void rebuildChecksumMap();
0123   InputFile *File = nullptr;
0124   StringRef Name;
0125   codeview::DebugSubsectionArray Subsections;
0126   std::shared_ptr<ModuleDebugStreamRef> DebugStream;
0127   codeview::StringsAndChecksumsRef SC;
0128   StringMap<codeview::FileChecksumEntry> ChecksumsByFile;
0129 };
0130 
0131 class SymbolGroupIterator
0132     : public iterator_facade_base<SymbolGroupIterator,
0133                                   std::forward_iterator_tag, SymbolGroup> {
0134 public:
0135   SymbolGroupIterator();
0136   explicit SymbolGroupIterator(InputFile &File);
0137   SymbolGroupIterator(const SymbolGroupIterator &Other) = default;
0138   SymbolGroupIterator &operator=(const SymbolGroupIterator &R) = default;
0139 
0140   const SymbolGroup &operator*() const;
0141   SymbolGroup &operator*();
0142 
0143   bool operator==(const SymbolGroupIterator &R) const;
0144   SymbolGroupIterator &operator++();
0145 
0146 private:
0147   void scanToNextDebugS();
0148   bool isEnd() const;
0149 
0150   uint32_t Index = 0;
0151   std::optional<object::section_iterator> SectionIter;
0152   SymbolGroup Value;
0153 };
0154 
0155 Expected<ModuleDebugStreamRef>
0156 getModuleDebugStream(PDBFile &File, StringRef &ModuleName, uint32_t Index);
0157 Expected<ModuleDebugStreamRef> getModuleDebugStream(PDBFile &File,
0158                                                     uint32_t Index);
0159 
0160 bool shouldDumpSymbolGroup(uint32_t Idx, const SymbolGroup &Group,
0161                            const FilterOptions &Filters);
0162 
0163 // TODO: Change these callbacks to be function_refs (de-templatify them).
0164 template <typename CallbackT>
0165 Error iterateOneModule(InputFile &File, const PrintScope &HeaderScope,
0166                        const SymbolGroup &SG, uint32_t Modi,
0167                        CallbackT Callback) {
0168   HeaderScope.P.formatLine(
0169       "Mod {0:4} | `{1}`: ",
0170       fmt_align(Modi, AlignStyle::Right, HeaderScope.LabelWidth), SG.name());
0171 
0172   AutoIndent Indent(HeaderScope);
0173   return Callback(Modi, SG);
0174 }
0175 
0176 template <typename CallbackT>
0177 Error iterateSymbolGroups(InputFile &Input, const PrintScope &HeaderScope,
0178                           CallbackT Callback) {
0179   AutoIndent Indent(HeaderScope);
0180 
0181   FilterOptions Filters = HeaderScope.P.getFilters();
0182   if (Filters.DumpModi) {
0183     uint32_t Modi = *Filters.DumpModi;
0184     SymbolGroup SG(&Input, Modi);
0185     return iterateOneModule(Input, withLabelWidth(HeaderScope, NumDigits(Modi)),
0186                             SG, Modi, Callback);
0187   }
0188 
0189   uint32_t I = 0;
0190 
0191   for (const auto &SG : Input.symbol_groups()) {
0192     if (shouldDumpSymbolGroup(I, SG, Filters))
0193       if (auto Err =
0194               iterateOneModule(Input, withLabelWidth(HeaderScope, NumDigits(I)),
0195                                SG, I, Callback))
0196         return Err;
0197 
0198     ++I;
0199   }
0200   return Error::success();
0201 }
0202 
0203 template <typename SubsectionT>
0204 Error iterateModuleSubsections(
0205     InputFile &File, const PrintScope &HeaderScope,
0206     llvm::function_ref<Error(uint32_t, const SymbolGroup &, SubsectionT &)>
0207         Callback) {
0208 
0209   return iterateSymbolGroups(
0210       File, HeaderScope, [&](uint32_t Modi, const SymbolGroup &SG) -> Error {
0211         for (const auto &SS : SG.getDebugSubsections()) {
0212           SubsectionT Subsection;
0213 
0214           if (SS.kind() != Subsection.kind())
0215             continue;
0216 
0217           BinaryStreamReader Reader(SS.getRecordData());
0218           if (auto Err = Subsection.initialize(Reader))
0219             continue;
0220           if (auto Err = Callback(Modi, SG, Subsection))
0221             return Err;
0222         }
0223         return Error::success();
0224       });
0225 }
0226 
0227 } // namespace pdb
0228 } // namespace llvm
0229 
0230 #endif