LLVM  16.0.0git
SymbolCache.h
Go to the documentation of this file.
1 //==- SymbolCache.h - Cache of native symbols and ids ------------*- 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_SYMBOLCACHE_H
10 #define LLVM_DEBUGINFO_PDB_NATIVE_SYMBOLCACHE_H
11 
12 #include "llvm/ADT/DenseMap.h"
21 
22 #include <memory>
23 #include <vector>
24 
25 namespace llvm {
26 namespace codeview {
27 class InlineSiteSym;
28 struct FileChecksumEntry;
29 } // namespace codeview
30 namespace pdb {
31 class IPDBSourceFile;
32 class NativeSession;
33 class PDBSymbol;
34 class PDBSymbolCompiland;
35 class DbiStream;
36 
37 class SymbolCache {
38  NativeSession &Session;
39  DbiStream *Dbi = nullptr;
40 
41  /// Cache of all stable symbols, indexed by SymIndexId. Just because a
42  /// symbol has been parsed does not imply that it will be stable and have
43  /// an Id. Id allocation is an implementation, with the only guarantee
44  /// being that once an Id is allocated, the symbol can be assumed to be
45  /// cached.
46  mutable std::vector<std::unique_ptr<NativeRawSymbol>> Cache;
47 
48  /// For type records from the TPI stream which have been paresd and cached,
49  /// stores a mapping to SymIndexId of the cached symbol.
50  mutable DenseMap<codeview::TypeIndex, SymIndexId> TypeIndexToSymbolId;
51 
52  /// For field list members which have been parsed and cached, stores a mapping
53  /// from (IndexOfClass, MemberIndex) to the corresponding SymIndexId of the
54  /// cached symbol.
56  FieldListMembersToSymbolId;
57 
58  /// List of SymIndexIds for each compiland, indexed by compiland index as they
59  /// appear in the PDB file.
60  mutable std::vector<SymIndexId> Compilands;
61 
62  /// List of source files, indexed by unique source file index.
63  mutable std::vector<std::unique_ptr<NativeSourceFile>> SourceFiles;
64 
65  /// Map from string table offset to source file Id.
66  mutable DenseMap<uint32_t, SymIndexId> FileNameOffsetToId;
67 
68  /// Map from global symbol offset to SymIndexId.
69  mutable DenseMap<uint32_t, SymIndexId> GlobalOffsetToSymbolId;
70 
71  /// Map from segment and code offset to function symbols.
72  mutable DenseMap<std::pair<uint32_t, uint32_t>, SymIndexId> AddressToSymbolId;
73  /// Map from segment and code offset to public symbols.
75  AddressToPublicSymId;
76 
77  /// Map from module index and symbol table offset to SymIndexId.
79  SymTabOffsetToSymbolId;
80 
81  struct LineTableEntry {
82  uint64_t Addr;
83  codeview::LineInfo Line;
84  uint32_t ColumnNumber;
85  uint32_t FileNameIndex;
86  bool IsTerminalEntry;
87  };
88 
89  std::vector<LineTableEntry> findLineTable(uint16_t Modi) const;
91 
92  SymIndexId createSymbolPlaceholder() const {
93  SymIndexId Id = Cache.size();
94  Cache.push_back(nullptr);
95  return Id;
96  }
97 
98  template <typename ConcreteSymbolT, typename CVRecordT, typename... Args>
99  SymIndexId createSymbolForType(codeview::TypeIndex TI, codeview::CVType CVT,
100  Args &&...ConstructorArgs) const {
101  CVRecordT Record;
102  if (auto EC =
103  codeview::TypeDeserializer::deserializeAs<CVRecordT>(CVT, Record)) {
104  consumeError(std::move(EC));
105  return 0;
106  }
107 
108  return createSymbol<ConcreteSymbolT>(
109  TI, std::move(Record), std::forward<Args>(ConstructorArgs)...);
110  }
111 
112  SymIndexId createSymbolForModifiedType(codeview::TypeIndex ModifierTI,
113  codeview::CVType CVT) const;
114 
115  SymIndexId createSimpleType(codeview::TypeIndex TI,
116  codeview::ModifierOptions Mods) const;
117 
118  std::unique_ptr<PDBSymbol> findFunctionSymbolBySectOffset(uint32_t Sect,
119  uint32_t Offset);
120  std::unique_ptr<PDBSymbol> findPublicSymbolBySectOffset(uint32_t Sect,
121  uint32_t Offset);
122 
123 public:
124  SymbolCache(NativeSession &Session, DbiStream *Dbi);
125 
126  template <typename ConcreteSymbolT, typename... Args>
127  SymIndexId createSymbol(Args &&...ConstructorArgs) const {
128  SymIndexId Id = Cache.size();
129 
130  // Initial construction must not access the cache, since it must be done
131  // atomically.
132  auto Result = std::make_unique<ConcreteSymbolT>(
133  Session, Id, std::forward<Args>(ConstructorArgs)...);
134  Result->SymbolId = Id;
135 
136  NativeRawSymbol *NRS = static_cast<NativeRawSymbol *>(Result.get());
137  Cache.push_back(std::move(Result));
138 
139  // After the item is in the cache, we can do further initialization which
140  // is then allowed to access the cache.
141  NRS->initialize();
142  return Id;
143  }
144 
145  std::unique_ptr<IPDBEnumSymbols>
147 
148  std::unique_ptr<IPDBEnumSymbols>
149  createTypeEnumerator(std::vector<codeview::TypeLeafKind> Kinds);
150 
151  std::unique_ptr<IPDBEnumSymbols>
153 
155 
156  template <typename ConcreteSymbolT, typename... Args>
158  uint32_t Index,
159  Args &&... ConstructorArgs) {
160  SymIndexId SymId = Cache.size();
161  std::pair<codeview::TypeIndex, uint32_t> Key{FieldListTI, Index};
162  auto Result = FieldListMembersToSymbolId.try_emplace(Key, SymId);
163  if (Result.second)
164  SymId =
165  createSymbol<ConcreteSymbolT>(std::forward<Args>(ConstructorArgs)...);
166  else
167  SymId = Result.first->second;
168  return SymId;
169  }
170 
173  uint64_t ParentAddr, uint16_t Modi,
174  uint32_t RecordOffset) const;
175 
176  std::unique_ptr<PDBSymbol>
178 
179  std::unique_ptr<IPDBEnumLineNumbers>
180  findLineNumbersByVA(uint64_t VA, uint32_t Length) const;
181 
182  std::unique_ptr<PDBSymbolCompiland> getOrCreateCompiland(uint32_t Index);
183  uint32_t getNumCompilands() const;
184 
185  std::unique_ptr<PDBSymbol> getSymbolById(SymIndexId SymbolId) const;
186 
188 
189  template <typename ConcreteT>
190  ConcreteT &getNativeSymbolById(SymIndexId SymbolId) const {
191  return static_cast<ConcreteT &>(getNativeSymbolById(SymbolId));
192  }
193 
194  std::unique_ptr<IPDBSourceFile> getSourceFileById(SymIndexId FileId) const;
195  SymIndexId
196  getOrCreateSourceFile(const codeview::FileChecksumEntry &Checksum) const;
197 };
198 
199 } // namespace pdb
200 } // namespace llvm
201 
202 #endif
llvm::pdb::SymbolCache::createTypeEnumerator
std::unique_ptr< IPDBEnumSymbols > createTypeEnumerator(codeview::TypeLeafKind Kind)
Definition: SymbolCache.cpp:89
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::codeview::ModifierOptions
ModifierOptions
Equivalent to CV_modifier_t.
Definition: CodeView.h:301
llvm::codeview::SymbolKind
SymbolKind
Duplicate copy of the above enum, but using the official CV names.
Definition: CodeView.h:47
llvm::pdb::SymbolCache::getOrCreateInlineSymbol
SymIndexId getOrCreateInlineSymbol(codeview::InlineSiteSym Sym, uint64_t ParentAddr, uint16_t Modi, uint32_t RecordOffset) const
Definition: SymbolCache.cpp:300
llvm::pdb::SymbolCache::getSourceFileById
std::unique_ptr< IPDBSourceFile > getSourceFileById(SymIndexId FileId) const
Definition: SymbolCache.cpp:614
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
DenseMap.h
llvm::pdb::SymbolCache::createSymbol
SymIndexId createSymbol(Args &&...ConstructorArgs) const
Definition: SymbolCache.h:127
llvm::pdb::DbiStream
Definition: DbiStream.h:39
llvm::pdb::SymbolCache
Definition: SymbolCache.h:37
llvm::pdb::SymbolCache::getOrCreateFieldListMember
SymIndexId getOrCreateFieldListMember(codeview::TypeIndex FieldListTI, uint32_t Index, Args &&... ConstructorArgs)
Definition: SymbolCache.h:157
llvm::consumeError
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1042
llvm::pdb::PDB_SymType
PDB_SymType
These values correspond to the SymTagEnum enumeration, and are documented here: https://msdn....
Definition: PDBTypes.h:243
llvm::codeview::InlineSiteSym
Definition: SymbolRecord.h:333
llvm::pdb::SymIndexId
uint32_t SymIndexId
Definition: PDBTypes.h:26
llvm::AMDGPU::PALMD::Key
Key
PAL metadata keys.
Definition: AMDGPUMetadata.h:486
llvm::dwarf::Index
Index
Definition: Dwarf.h:472
llvm::codeview::FileChecksumEntry
Definition: DebugChecksumsSubsection.h:33
CodeView.h
PDBTypes.h
llvm::pdb::SymbolCache::getNativeSymbolById
ConcreteT & getNativeSymbolById(SymIndexId SymbolId) const
Definition: SymbolCache.h:190
Line.h
llvm::pdb::SymbolCache::getSymbolById
std::unique_ptr< PDBSymbol > getSymbolById(SymIndexId SymbolId) const
Definition: SymbolCache.cpp:247
llvm::pdb::SymbolCache::findSymbolBySectOffset
std::unique_ptr< PDBSymbol > findSymbolBySectOffset(uint32_t Sect, uint32_t Offset, PDB_SymType Type)
Definition: SymbolCache.cpp:314
uint64_t
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:79
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::DenseMap
Definition: DenseMap.h:714
llvm::pdb::SymbolCache::getNumCompilands
uint32_t getNumCompilands() const
Definition: SymbolCache.cpp:267
llvm::Record
Definition: Record.h:1573
llvm::codeview::CVRecord< TypeLeafKind >
uint32_t
llvm::codeview::LineInfo
Definition: Line.h:20
llvm::pdb::SymbolCache::findSymbolByTypeIndex
SymIndexId findSymbolByTypeIndex(codeview::TypeIndex TI) const
Definition: SymbolCache.cpp:158
uint16_t
TypeDeserializer.h
NativeSourceFile.h
CVRecord.h
NativeRawSymbol.h
TypeIndex.h
llvm::pdb::NativeSession
Definition: NativeSession.h:32
llvm::pdb::SymbolCache::getOrCreateCompiland
std::unique_ptr< PDBSymbolCompiland > getOrCreateCompiland(uint32_t Index)
Definition: SymbolCache.cpp:597
llvm::codeview::TypeLeafKind
TypeLeafKind
Duplicate copy of the above enum, but using the official CV names.
Definition: CodeView.h:33
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::try_emplace
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&... Args)
Definition: DenseMap.h:222
llvm::codeview::TypeIndex
A 32-bit type reference.
Definition: TypeIndex.h:96
llvm::pdb::SymbolCache::getOrCreateGlobalSymbolByOffset
SymIndexId getOrCreateGlobalSymbolByOffset(uint32_t Offset)
Definition: SymbolCache.cpp:274
llvm::pdb::SymbolCache::getNativeSymbolById
NativeRawSymbol & getNativeSymbolById(SymIndexId SymbolId) const
Definition: SymbolCache.cpp:263
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:394
llvm::pdb::SymbolCache::getOrCreateSourceFile
SymIndexId getOrCreateSourceFile(const codeview::FileChecksumEntry &Checksum) const
Definition: SymbolCache.cpp:626
llvm::AMDGPU::VGPRIndexMode::Id
Id
Definition: SIDefines.h:241
llvm::pdb::SymbolCache::SymbolCache
SymbolCache(NativeSession &Session, DbiStream *Dbi)
Definition: SymbolCache.cpp:78
llvm::pdb::NativeRawSymbol
Definition: NativeRawSymbol.h:21
llvm::pdb::SymbolCache::findLineNumbersByVA
std::unique_ptr< IPDBEnumLineNumbers > findLineNumbersByVA(uint64_t VA, uint32_t Length) const
Definition: SymbolCache.cpp:533
llvm::pdb::SymbolCache::createGlobalsEnumerator
std::unique_ptr< IPDBEnumSymbols > createGlobalsEnumerator(codeview::SymbolKind Kind)
Definition: SymbolCache.cpp:106