1 #include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
3 #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
4 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
5 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
6 #include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
7 #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
8 #include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
9 #include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h"
10 #include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
11 #include "llvm/DebugInfo/PDB/Native/NativeEnumGlobals.h"
12 #include "llvm/DebugInfo/PDB/Native/NativeEnumLineNumbers.h"
13 #include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
14 #include "llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h"
15 #include "llvm/DebugInfo/PDB/Native/NativePublicSymbol.h"
16 #include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
17 #include "llvm/DebugInfo/PDB/Native/NativeSession.h"
18 #include "llvm/DebugInfo/PDB/Native/NativeTypeArray.h"
19 #include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
20 #include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
21 #include "llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h"
22 #include "llvm/DebugInfo/PDB/Native/NativeTypePointer.h"
23 #include "llvm/DebugInfo/PDB/Native/NativeTypeTypedef.h"
24 #include "llvm/DebugInfo/PDB/Native/NativeTypeUDT.h"
25 #include "llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h"
26 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
27 #include "llvm/DebugInfo/PDB/Native/PublicsStream.h"
28 #include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
29 #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
30 #include "llvm/DebugInfo/PDB/PDBSymbol.h"
31 #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
32 #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
35 using namespace llvm::codeview;
36 using namespace llvm::pdb;
38 // Maps codeview::SimpleTypeKind of a built-in type to the parameters necessary
39 // to instantiate a NativeBuiltinSymbol for that type.
40 static const struct BuiltinTypeEntry {
41 codeview::SimpleTypeKind Kind;
45 {codeview::SimpleTypeKind::None, PDB_BuiltinType::None, 0},
46 {codeview::SimpleTypeKind::Void, PDB_BuiltinType::Void, 0},
47 {codeview::SimpleTypeKind::HResult, PDB_BuiltinType::HResult, 4},
48 {codeview::SimpleTypeKind::Int16Short, PDB_BuiltinType::Int, 2},
49 {codeview::SimpleTypeKind::UInt16Short, PDB_BuiltinType::UInt, 2},
50 {codeview::SimpleTypeKind::Int32, PDB_BuiltinType::Int, 4},
51 {codeview::SimpleTypeKind::UInt32, PDB_BuiltinType::UInt, 4},
52 {codeview::SimpleTypeKind::Int32Long, PDB_BuiltinType::Int, 4},
53 {codeview::SimpleTypeKind::UInt32Long, PDB_BuiltinType::UInt, 4},
54 {codeview::SimpleTypeKind::Int64Quad, PDB_BuiltinType::Int, 8},
55 {codeview::SimpleTypeKind::UInt64Quad, PDB_BuiltinType::UInt, 8},
56 {codeview::SimpleTypeKind::NarrowCharacter, PDB_BuiltinType::Char, 1},
57 {codeview::SimpleTypeKind::WideCharacter, PDB_BuiltinType::WCharT, 2},
58 {codeview::SimpleTypeKind::Character16, PDB_BuiltinType::Char16, 2},
59 {codeview::SimpleTypeKind::Character32, PDB_BuiltinType::Char32, 4},
60 {codeview::SimpleTypeKind::SignedCharacter, PDB_BuiltinType::Char, 1},
61 {codeview::SimpleTypeKind::UnsignedCharacter, PDB_BuiltinType::UInt, 1},
62 {codeview::SimpleTypeKind::Float32, PDB_BuiltinType::Float, 4},
63 {codeview::SimpleTypeKind::Float64, PDB_BuiltinType::Float, 8},
64 {codeview::SimpleTypeKind::Float80, PDB_BuiltinType::Float, 10},
65 {codeview::SimpleTypeKind::Boolean8, PDB_BuiltinType::Bool, 1},
66 // This table can be grown as necessary, but these are the only types we've
70 SymbolCache::SymbolCache(NativeSession &Session, DbiStream *Dbi)
71 : Session(Session), Dbi(Dbi), AddrToModuleIndex(IMapAllocator) {
72 // Id 0 is reserved for the invalid symbol.
73 Cache.push_back(nullptr);
74 SourceFiles.push_back(nullptr);
77 Compilands.resize(Dbi->modules().getModuleCount());
80 std::unique_ptr<IPDBEnumSymbols>
81 SymbolCache::createTypeEnumerator(TypeLeafKind Kind) {
82 return createTypeEnumerator(std::vector<TypeLeafKind>{Kind});
85 std::unique_ptr<IPDBEnumSymbols>
86 SymbolCache::createTypeEnumerator(std::vector<TypeLeafKind> Kinds) {
87 auto Tpi = Session.getPDBFile().getPDBTpiStream();
89 consumeError(Tpi.takeError());
92 auto &Types = Tpi->typeCollection();
93 return std::unique_ptr<IPDBEnumSymbols>(
94 new NativeEnumTypes(Session, Types, std::move(Kinds)));
97 std::unique_ptr<IPDBEnumSymbols>
98 SymbolCache::createGlobalsEnumerator(codeview::SymbolKind Kind) {
99 return std::unique_ptr<IPDBEnumSymbols>(
100 new NativeEnumGlobals(Session, {Kind}));
103 SymIndexId SymbolCache::createSimpleType(TypeIndex Index,
104 ModifierOptions Mods) {
105 if (Index.getSimpleMode() != codeview::SimpleTypeMode::Direct)
106 return createSymbol<NativeTypePointer>(Index);
108 const auto Kind = Index.getSimpleKind();
109 const auto It = std::find_if(
110 std::begin(BuiltinTypes), std::end(BuiltinTypes),
111 [Kind](const BuiltinTypeEntry &Builtin) { return Builtin.Kind == Kind; });
112 if (It == std::end(BuiltinTypes))
114 return createSymbol<NativeTypeBuiltin>(Mods, It->Type, It->Size);
118 SymbolCache::createSymbolForModifiedType(codeview::TypeIndex ModifierTI,
119 codeview::CVType CVT) {
120 ModifierRecord Record;
121 if (auto EC = TypeDeserializer::deserializeAs<ModifierRecord>(CVT, Record)) {
122 consumeError(std::move(EC));
126 if (Record.ModifiedType.isSimple())
127 return createSimpleType(Record.ModifiedType, Record.Modifiers);
129 // Make sure we create and cache a record for the unmodified type.
130 SymIndexId UnmodifiedId = findSymbolByTypeIndex(Record.ModifiedType);
131 NativeRawSymbol &UnmodifiedNRS = *Cache[UnmodifiedId];
133 switch (UnmodifiedNRS.getSymTag()) {
134 case PDB_SymType::Enum:
135 return createSymbol<NativeTypeEnum>(
136 static_cast<NativeTypeEnum &>(UnmodifiedNRS), std::move(Record));
137 case PDB_SymType::UDT:
138 return createSymbol<NativeTypeUDT>(
139 static_cast<NativeTypeUDT &>(UnmodifiedNRS), std::move(Record));
141 // No other types can be modified. (LF_POINTER, for example, records
142 // its modifiers a different way.
143 assert(false && "Invalid LF_MODIFIER record");
149 SymIndexId SymbolCache::findSymbolByTypeIndex(codeview::TypeIndex Index) {
150 // First see if it's already in our cache.
151 const auto Entry = TypeIndexToSymbolId.find(Index);
152 if (Entry != TypeIndexToSymbolId.end())
153 return Entry->second;
155 // Symbols for built-in types are created on the fly.
156 if (Index.isSimple()) {
157 SymIndexId Result = createSimpleType(Index, ModifierOptions::None);
158 assert(TypeIndexToSymbolId.count(Index) == 0);
159 TypeIndexToSymbolId[Index] = Result;
163 // We need to instantiate and cache the desired type symbol.
164 auto Tpi = Session.getPDBFile().getPDBTpiStream();
166 consumeError(Tpi.takeError());
169 codeview::LazyRandomTypeCollection &Types = Tpi->typeCollection();
170 codeview::CVType CVT = Types.getType(Index);
172 if (isUdtForwardRef(CVT)) {
173 Expected<TypeIndex> EFD = Tpi->findFullDeclForForwardRef(Index);
176 consumeError(EFD.takeError());
177 else if (*EFD != Index) {
178 assert(!isUdtForwardRef(Types.getType(*EFD)));
179 SymIndexId Result = findSymbolByTypeIndex(*EFD);
180 // Record a mapping from ForwardRef -> SymIndex of complete type so that
181 // we'll take the fast path next time.
182 assert(TypeIndexToSymbolId.count(Index) == 0);
183 TypeIndexToSymbolId[Index] = Result;
188 // At this point if we still have a forward ref udt it means the full decl was
189 // not in the PDB. We just have to deal with it and use the forward ref.
191 switch (CVT.kind()) {
192 case codeview::LF_ENUM:
193 Id = createSymbolForType<NativeTypeEnum, EnumRecord>(Index, std::move(CVT));
195 case codeview::LF_ARRAY:
196 Id = createSymbolForType<NativeTypeArray, ArrayRecord>(Index,
199 case codeview::LF_CLASS:
200 case codeview::LF_STRUCTURE:
201 case codeview::LF_INTERFACE:
202 Id = createSymbolForType<NativeTypeUDT, ClassRecord>(Index, std::move(CVT));
204 case codeview::LF_UNION:
205 Id = createSymbolForType<NativeTypeUDT, UnionRecord>(Index, std::move(CVT));
207 case codeview::LF_POINTER:
208 Id = createSymbolForType<NativeTypePointer, PointerRecord>(Index,
211 case codeview::LF_MODIFIER:
212 Id = createSymbolForModifiedType(Index, std::move(CVT));
214 case codeview::LF_PROCEDURE:
215 Id = createSymbolForType<NativeTypeFunctionSig, ProcedureRecord>(
216 Index, std::move(CVT));
218 case codeview::LF_MFUNCTION:
219 Id = createSymbolForType<NativeTypeFunctionSig, MemberFunctionRecord>(
220 Index, std::move(CVT));
222 case codeview::LF_VTSHAPE:
223 Id = createSymbolForType<NativeTypeVTShape, VFTableShapeRecord>(
224 Index, std::move(CVT));
227 Id = createSymbolPlaceholder();
231 assert(TypeIndexToSymbolId.count(Index) == 0);
232 TypeIndexToSymbolId[Index] = Id;
237 std::unique_ptr<PDBSymbol>
238 SymbolCache::getSymbolById(SymIndexId SymbolId) const {
239 assert(SymbolId < Cache.size());
242 if (SymbolId == 0 || SymbolId >= Cache.size())
245 // Make sure to handle the case where we've inserted a placeholder symbol
246 // for types we don't yet suppport.
247 NativeRawSymbol *NRS = Cache[SymbolId].get();
251 return PDBSymbol::create(Session, *NRS);
254 NativeRawSymbol &SymbolCache::getNativeSymbolById(SymIndexId SymbolId) const {
255 return *Cache[SymbolId];
258 uint32_t SymbolCache::getNumCompilands() const {
262 return Dbi->modules().getModuleCount();
265 SymIndexId SymbolCache::getOrCreateGlobalSymbolByOffset(uint32_t Offset) {
266 auto Iter = GlobalOffsetToSymbolId.find(Offset);
267 if (Iter != GlobalOffsetToSymbolId.end())
270 SymbolStream &SS = cantFail(Session.getPDBFile().getPDBSymbolStream());
271 CVSymbol CVS = SS.readRecord(Offset);
273 switch (CVS.kind()) {
274 case SymbolKind::S_UDT: {
275 UDTSym US = cantFail(SymbolDeserializer::deserializeAs<UDTSym>(CVS));
276 Id = createSymbol<NativeTypeTypedef>(std::move(US));
280 Id = createSymbolPlaceholder();
284 assert(GlobalOffsetToSymbolId.count(Offset) == 0);
285 GlobalOffsetToSymbolId[Offset] = Id;
291 Expected<ModuleDebugStreamRef>
292 SymbolCache::getModuleDebugStream(uint32_t Index) const {
293 assert(Dbi && "Dbi stream not present");
295 DbiModuleDescriptor Modi = Dbi->modules().getModuleDescriptor(Index);
297 uint16_t ModiStream = Modi.getModuleStreamIndex();
298 if (ModiStream == kInvalidStreamIndex)
299 return make_error<RawError>("Module stream not present");
301 std::unique_ptr<msf::MappedBlockStream> ModStreamData =
302 Session.getPDBFile().createIndexedStream(ModiStream);
304 ModuleDebugStreamRef ModS(Modi, std::move(ModStreamData));
305 if (auto EC = ModS.reload())
306 return std::move(EC);
308 return std::move(ModS);
311 std::unique_ptr<PDBSymbol>
312 SymbolCache::findSymbolBySectOffset(uint32_t Sect, uint32_t Offset,
314 if (AddrToModuleIndex.empty())
315 parseSectionContribs();
318 case PDB_SymType::Function:
319 return findFunctionSymbolBySectOffset(Sect, Offset);
320 case PDB_SymType::PublicSymbol:
321 return findPublicSymbolBySectOffset(Sect, Offset);
322 case PDB_SymType::None: {
323 // FIXME: Implement for PDB_SymType::Data.
324 if (auto Sym = findFunctionSymbolBySectOffset(Sect, Offset))
333 std::unique_ptr<PDBSymbol>
334 SymbolCache::findFunctionSymbolBySectOffset(uint32_t Sect, uint32_t Offset) {
335 auto Iter = AddressToFunctionSymId.find({Sect, Offset});
336 if (Iter != AddressToFunctionSymId.end())
337 return getSymbolById(Iter->second);
342 auto Modi = getModuleIndexForAddr(Session.getVAFromSectOffset(Sect, Offset));
346 auto ExpectedModS = getModuleDebugStream(*Modi);
348 consumeError(ExpectedModS.takeError());
351 CVSymbolArray Syms = ExpectedModS->getSymbolArray();
353 // Search for the symbol in this module.
354 for (auto I = Syms.begin(), E = Syms.end(); I != E; ++I) {
355 if (I->kind() != S_LPROC32 && I->kind() != S_GPROC32)
357 auto PS = cantFail(SymbolDeserializer::deserializeAs<ProcSym>(*I));
358 if (Sect == PS.Segment && Offset >= PS.CodeOffset &&
359 Offset < PS.CodeOffset + PS.CodeSize) {
360 SymIndexId Id = createSymbol<NativeFunctionSymbol>(PS);
361 AddressToFunctionSymId.insert({{Sect, Offset}, Id});
362 return getSymbolById(Id);
365 // Jump to the end of this ProcSym.
371 std::unique_ptr<PDBSymbol>
372 SymbolCache::findPublicSymbolBySectOffset(uint32_t Sect, uint32_t Offset) {
373 auto Iter = AddressToPublicSymId.find({Sect, Offset});
374 if (Iter != AddressToPublicSymId.end())
375 return getSymbolById(Iter->second);
377 auto Publics = Session.getPDBFile().getPDBPublicsStream();
381 auto ExpectedSyms = Session.getPDBFile().getPDBSymbolStream();
384 BinaryStreamRef SymStream =
385 ExpectedSyms->getSymbolArray().getUnderlyingStream();
387 // Use binary search to find the first public symbol with an address greater
388 // than or equal to Sect, Offset.
389 auto AddrMap = Publics->getAddressMap();
390 auto First = AddrMap.begin();
391 auto It = AddrMap.begin();
392 size_t Count = AddrMap.size();
398 Expected<CVSymbol> Sym = readSymbolFromStream(SymStream, *It);
400 consumeError(Sym.takeError());
405 cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(Sym.get()));
406 if (PS.Segment < Sect || (PS.Segment == Sect && PS.Offset <= Offset)) {
412 if (It == AddrMap.begin())
416 Expected<CVSymbol> Sym = readSymbolFromStream(SymStream, *It);
418 consumeError(Sym.takeError());
421 auto PS = cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(Sym.get()));
422 SymIndexId Id = createSymbol<NativePublicSymbol>(PS);
423 AddressToPublicSymId.insert({{Sect, Offset}, Id});
424 return getSymbolById(Id);
427 std::vector<SymbolCache::LineTableEntry>
428 SymbolCache::findLineTable(uint16_t Modi) const {
429 // Check if this module has already been added.
430 auto LineTableIter = LineTable.find(Modi);
431 if (LineTableIter != LineTable.end())
432 return LineTableIter->second;
434 std::vector<LineTableEntry> &ModuleLineTable = LineTable[Modi];
436 // If there is an error or there are no lines, just return the
438 Expected<ModuleDebugStreamRef> ExpectedModS = getModuleDebugStream(Modi);
440 consumeError(ExpectedModS.takeError());
441 return ModuleLineTable;
444 std::vector<std::vector<LineTableEntry>> EntryList;
445 for (const auto &SS : ExpectedModS->getSubsectionsArray()) {
446 if (SS.kind() != DebugSubsectionKind::Lines)
449 DebugLinesSubsectionRef Lines;
450 BinaryStreamReader Reader(SS.getRecordData());
451 if (auto EC = Lines.initialize(Reader)) {
452 consumeError(std::move(EC));
456 uint32_t RelocSegment = Lines.header()->RelocSegment;
457 uint32_t RelocOffset = Lines.header()->RelocOffset;
458 for (const LineColumnEntry &Group : Lines) {
459 if (Group.LineNumbers.empty())
462 std::vector<LineTableEntry> Entries;
464 // If there are column numbers, then they should be in a parallel stream
465 // to the line numbers.
466 auto ColIt = Group.Columns.begin();
467 auto ColsEnd = Group.Columns.end();
469 for (const LineNumberEntry &LN : Group.LineNumbers) {
471 Session.getVAFromSectOffset(RelocSegment, RelocOffset + LN.Offset);
472 LineInfo Line(LN.Flags);
475 if (Lines.hasColumnInfo() && ColIt != ColsEnd) {
476 ColNum = ColIt->StartColumn;
479 Entries.push_back({VA, Line, ColNum, Group.NameIndex, false});
482 // Add a terminal entry line to mark the end of this subsection.
483 uint64_t VA = Session.getVAFromSectOffset(
484 RelocSegment, RelocOffset + Lines.header()->CodeSize);
485 LineInfo LastLine(Group.LineNumbers.back().Flags);
487 (Lines.hasColumnInfo()) ? Group.Columns.back().StartColumn : 0;
488 Entries.push_back({VA, LastLine, ColNum, Group.NameIndex, true});
490 EntryList.push_back(Entries);
494 // Sort EntryList, and add flattened contents to the line table.
495 std::sort(EntryList.begin(), EntryList.end(),
496 [](const std::vector<LineTableEntry> &LHS,
497 const std::vector<LineTableEntry> &RHS) {
498 return LHS[0].Addr < RHS[0].Addr;
500 for (size_t I = 0; I < EntryList.size(); ++I)
501 ModuleLineTable.insert(ModuleLineTable.end(), EntryList[I].begin(),
504 return ModuleLineTable;
507 std::unique_ptr<IPDBEnumLineNumbers>
508 SymbolCache::findLineNumbersByVA(uint64_t VA, uint32_t Length) const {
509 Optional<uint16_t> MaybeModi = getModuleIndexForAddr(VA);
512 uint16_t Modi = *MaybeModi;
514 std::vector<LineTableEntry> Lines = findLineTable(Modi);
518 // Find the first line in the line table whose address is not greater than
519 // the one we are searching for.
520 auto LineIter = llvm::partition_point(Lines, [&](const LineTableEntry &E) {
521 return (E.Addr < VA || (E.Addr == VA && E.IsTerminalEntry));
524 // Try to back up if we've gone too far.
525 if (LineIter == Lines.end() || LineIter->Addr > VA) {
526 if (LineIter == Lines.begin() || std::prev(LineIter)->IsTerminalEntry)
531 Expected<ModuleDebugStreamRef> ExpectedModS = getModuleDebugStream(Modi);
533 consumeError(ExpectedModS.takeError());
536 Expected<DebugChecksumsSubsectionRef> ExpectedChecksums =
537 ExpectedModS->findChecksumsSubsection();
538 if (!ExpectedChecksums) {
539 consumeError(ExpectedChecksums.takeError());
543 // Populate a vector of NativeLineNumbers that have addresses in the given
545 Optional<uint16_t> EndModi = getModuleIndexForAddr(VA + Length);
548 std::vector<NativeLineNumber> LineNumbers;
549 while (Modi <= *EndModi) {
550 // If we reached the end of the current module, increment Modi and get the
551 // new line table and checksums array.
552 if (LineIter == Lines.end()) {
555 ExpectedModS = getModuleDebugStream(Modi);
557 consumeError(ExpectedModS.takeError());
560 ExpectedChecksums = ExpectedModS->findChecksumsSubsection();
561 if (!ExpectedChecksums) {
562 consumeError(ExpectedChecksums.takeError());
566 Lines = findLineTable(Modi);
567 LineIter = Lines.begin();
573 if (LineIter->IsTerminalEntry) {
578 // If the line is still within the address range, create a NativeLineNumber
579 // and add to the list.
580 if (LineIter->Addr > VA + Length)
583 uint32_t LineSect, LineOff;
584 Session.addressForVA(LineIter->Addr, LineSect, LineOff);
585 uint32_t LineLength = std::next(LineIter)->Addr - LineIter->Addr;
587 ExpectedChecksums->getArray().at(LineIter->FileNameIndex);
588 uint32_t SrcFileId = getOrCreateSourceFile(*ChecksumIter);
589 NativeLineNumber LineNum(Session, LineIter->Line, LineIter->ColumnNumber,
590 LineSect, LineOff, LineLength, SrcFileId);
591 LineNumbers.push_back(LineNum);
594 return std::make_unique<NativeEnumLineNumbers>(std::move(LineNumbers));
597 std::unique_ptr<PDBSymbolCompiland>
598 SymbolCache::getOrCreateCompiland(uint32_t Index) {
602 if (Index >= Compilands.size())
605 if (Compilands[Index] == 0) {
606 const DbiModuleList &Modules = Dbi->modules();
608 createSymbol<NativeCompilandSymbol>(Modules.getModuleDescriptor(Index));
611 return Session.getConcreteSymbolById<PDBSymbolCompiland>(Compilands[Index]);
614 std::unique_ptr<IPDBSourceFile>
615 SymbolCache::getSourceFileById(SymIndexId FileId) const {
616 assert(FileId < SourceFiles.size());
622 return std::unique_ptr<NativeSourceFile>(
623 new NativeSourceFile(*SourceFiles[FileId].get()));
627 SymbolCache::getOrCreateSourceFile(const FileChecksumEntry &Checksums) const {
628 auto Iter = FileNameOffsetToId.find(Checksums.FileNameOffset);
629 if (Iter != FileNameOffsetToId.end())
632 SymIndexId Id = SourceFiles.size();
633 auto SrcFile = std::make_unique<NativeSourceFile>(Session, Id, Checksums);
634 SourceFiles.push_back(std::move(SrcFile));
635 FileNameOffsetToId[Checksums.FileNameOffset] = Id;
639 void SymbolCache::parseSectionContribs() {
643 class Visitor : public ISectionContribVisitor {
644 NativeSession &Session;
648 Visitor(NativeSession &Session, IMap &AddrMap)
649 : Session(Session), AddrMap(AddrMap) {}
650 void visit(const SectionContrib &C) override {
654 uint64_t VA = Session.getVAFromSectOffset(C.ISect, C.Off);
655 uint64_t End = VA + C.Size;
657 // Ignore overlapping sections based on the assumption that a valid
658 // PDB file should not have overlaps.
659 if (!AddrMap.overlaps(VA, End))
660 AddrMap.insert(VA, End, C.Imod);
662 void visit(const SectionContrib2 &C) override { visit(C.Base); }
665 Visitor V(Session, AddrToModuleIndex);
666 Dbi->visitSectionContributions(V);
669 Optional<uint16_t> SymbolCache::getModuleIndexForAddr(uint64_t Addr) const {
670 auto Iter = AddrToModuleIndex.find(Addr);
671 if (Iter == AddrToModuleIndex.end())