Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //==- SymbolCache.h - Cache of native symbols and ids ------------*- 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_SYMBOLCACHE_H
0010 #define LLVM_DEBUGINFO_PDB_NATIVE_SYMBOLCACHE_H
0011 
0012 #include "llvm/ADT/DenseMap.h"
0013 #include "llvm/DebugInfo/CodeView/CVRecord.h"
0014 #include "llvm/DebugInfo/CodeView/CodeView.h"
0015 #include "llvm/DebugInfo/CodeView/Line.h"
0016 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
0017 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
0018 #include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
0019 #include "llvm/DebugInfo/PDB/Native/NativeSourceFile.h"
0020 #include "llvm/DebugInfo/PDB/PDBTypes.h"
0021 
0022 #include <memory>
0023 #include <vector>
0024 
0025 namespace llvm {
0026 namespace codeview {
0027 class InlineSiteSym;
0028 struct FileChecksumEntry;
0029 } // namespace codeview
0030 namespace pdb {
0031 class IPDBSourceFile;
0032 class NativeSession;
0033 class PDBSymbol;
0034 class PDBSymbolCompiland;
0035 class DbiStream;
0036 
0037 class SymbolCache {
0038   NativeSession &Session;
0039   DbiStream *Dbi = nullptr;
0040 
0041   /// Cache of all stable symbols, indexed by SymIndexId.  Just because a
0042   /// symbol has been parsed does not imply that it will be stable and have
0043   /// an Id.  Id allocation is an implementation, with the only guarantee
0044   /// being that once an Id is allocated, the symbol can be assumed to be
0045   /// cached.
0046   mutable std::vector<std::unique_ptr<NativeRawSymbol>> Cache;
0047 
0048   /// For type records from the TPI stream which have been paresd and cached,
0049   /// stores a mapping to SymIndexId of the cached symbol.
0050   mutable DenseMap<codeview::TypeIndex, SymIndexId> TypeIndexToSymbolId;
0051 
0052   /// For field list members which have been parsed and cached, stores a mapping
0053   /// from (IndexOfClass, MemberIndex) to the corresponding SymIndexId of the
0054   /// cached symbol.
0055   mutable DenseMap<std::pair<codeview::TypeIndex, uint32_t>, SymIndexId>
0056       FieldListMembersToSymbolId;
0057 
0058   /// List of SymIndexIds for each compiland, indexed by compiland index as they
0059   /// appear in the PDB file.
0060   mutable std::vector<SymIndexId> Compilands;
0061 
0062   /// List of source files, indexed by unique source file index.
0063   mutable std::vector<std::unique_ptr<NativeSourceFile>> SourceFiles;
0064 
0065   /// Map from string table offset to source file Id.
0066   mutable DenseMap<uint32_t, SymIndexId> FileNameOffsetToId;
0067 
0068   /// Map from global symbol offset to SymIndexId.
0069   mutable DenseMap<uint32_t, SymIndexId> GlobalOffsetToSymbolId;
0070 
0071   /// Map from segment and code offset to function symbols.
0072   mutable DenseMap<std::pair<uint32_t, uint32_t>, SymIndexId> AddressToSymbolId;
0073   /// Map from segment and code offset to public symbols.
0074   mutable DenseMap<std::pair<uint32_t, uint32_t>, SymIndexId>
0075       AddressToPublicSymId;
0076 
0077   /// Map from module index and symbol table offset to SymIndexId.
0078   mutable DenseMap<std::pair<uint16_t, uint32_t>, SymIndexId>
0079       SymTabOffsetToSymbolId;
0080 
0081   struct LineTableEntry {
0082     uint64_t Addr;
0083     codeview::LineInfo Line;
0084     uint32_t ColumnNumber;
0085     uint32_t FileNameIndex;
0086     bool IsTerminalEntry;
0087   };
0088 
0089   std::vector<LineTableEntry> findLineTable(uint16_t Modi) const;
0090   mutable DenseMap<uint16_t, std::vector<LineTableEntry>> LineTable;
0091 
0092   SymIndexId createSymbolPlaceholder() const {
0093     SymIndexId Id = Cache.size();
0094     Cache.push_back(nullptr);
0095     return Id;
0096   }
0097 
0098   template <typename ConcreteSymbolT, typename CVRecordT, typename... Args>
0099   SymIndexId createSymbolForType(codeview::TypeIndex TI, codeview::CVType CVT,
0100                                  Args &&...ConstructorArgs) const {
0101     CVRecordT Record;
0102     if (auto EC =
0103             codeview::TypeDeserializer::deserializeAs<CVRecordT>(CVT, Record)) {
0104       consumeError(std::move(EC));
0105       return 0;
0106     }
0107 
0108     return createSymbol<ConcreteSymbolT>(
0109         TI, std::move(Record), std::forward<Args>(ConstructorArgs)...);
0110   }
0111 
0112   SymIndexId createSymbolForModifiedType(codeview::TypeIndex ModifierTI,
0113                                          codeview::CVType CVT) const;
0114 
0115   SymIndexId createSimpleType(codeview::TypeIndex TI,
0116                               codeview::ModifierOptions Mods) const;
0117 
0118   std::unique_ptr<PDBSymbol> findFunctionSymbolBySectOffset(uint32_t Sect,
0119                                                             uint32_t Offset);
0120   std::unique_ptr<PDBSymbol> findPublicSymbolBySectOffset(uint32_t Sect,
0121                                                           uint32_t Offset);
0122 
0123 public:
0124   SymbolCache(NativeSession &Session, DbiStream *Dbi);
0125 
0126   template <typename ConcreteSymbolT, typename... Args>
0127   SymIndexId createSymbol(Args &&...ConstructorArgs) const {
0128     SymIndexId Id = Cache.size();
0129 
0130     // Initial construction must not access the cache, since it must be done
0131     // atomically.
0132     auto Result = std::make_unique<ConcreteSymbolT>(
0133         Session, Id, std::forward<Args>(ConstructorArgs)...);
0134     Result->SymbolId = Id;
0135 
0136     NativeRawSymbol *NRS = static_cast<NativeRawSymbol *>(Result.get());
0137     Cache.push_back(std::move(Result));
0138 
0139     // After the item is in the cache, we can do further initialization which
0140     // is then allowed to access the cache.
0141     NRS->initialize();
0142     return Id;
0143   }
0144 
0145   std::unique_ptr<IPDBEnumSymbols>
0146   createTypeEnumerator(codeview::TypeLeafKind Kind);
0147 
0148   std::unique_ptr<IPDBEnumSymbols>
0149   createTypeEnumerator(std::vector<codeview::TypeLeafKind> Kinds);
0150 
0151   std::unique_ptr<IPDBEnumSymbols>
0152   createGlobalsEnumerator(codeview::SymbolKind Kind);
0153 
0154   SymIndexId findSymbolByTypeIndex(codeview::TypeIndex TI) const;
0155 
0156   template <typename ConcreteSymbolT, typename... Args>
0157   SymIndexId getOrCreateFieldListMember(codeview::TypeIndex FieldListTI,
0158                                         uint32_t Index,
0159                                         Args &&... ConstructorArgs) {
0160     SymIndexId SymId = Cache.size();
0161     std::pair<codeview::TypeIndex, uint32_t> Key{FieldListTI, Index};
0162     auto Result = FieldListMembersToSymbolId.try_emplace(Key, SymId);
0163     if (Result.second)
0164       SymId =
0165           createSymbol<ConcreteSymbolT>(std::forward<Args>(ConstructorArgs)...);
0166     else
0167       SymId = Result.first->second;
0168     return SymId;
0169   }
0170 
0171   SymIndexId getOrCreateGlobalSymbolByOffset(uint32_t Offset);
0172   SymIndexId getOrCreateInlineSymbol(codeview::InlineSiteSym Sym,
0173                                      uint64_t ParentAddr, uint16_t Modi,
0174                                      uint32_t RecordOffset) const;
0175 
0176   std::unique_ptr<PDBSymbol>
0177   findSymbolBySectOffset(uint32_t Sect, uint32_t Offset, PDB_SymType Type);
0178 
0179   std::unique_ptr<IPDBEnumLineNumbers>
0180   findLineNumbersByVA(uint64_t VA, uint32_t Length) const;
0181 
0182   std::unique_ptr<PDBSymbolCompiland> getOrCreateCompiland(uint32_t Index);
0183   uint32_t getNumCompilands() const;
0184 
0185   std::unique_ptr<PDBSymbol> getSymbolById(SymIndexId SymbolId) const;
0186 
0187   NativeRawSymbol &getNativeSymbolById(SymIndexId SymbolId) const;
0188 
0189   template <typename ConcreteT>
0190   ConcreteT &getNativeSymbolById(SymIndexId SymbolId) const {
0191     return static_cast<ConcreteT &>(getNativeSymbolById(SymbolId));
0192   }
0193 
0194   std::unique_ptr<IPDBSourceFile> getSourceFileById(SymIndexId FileId) const;
0195   SymIndexId
0196   getOrCreateSourceFile(const codeview::FileChecksumEntry &Checksum) const;
0197 };
0198 
0199 } // namespace pdb
0200 } // namespace llvm
0201 
0202 #endif