xref: /freebsd/contrib/llvm-project/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp (revision a7623790fb345e6dc986dfd31df0ace115e6f2e4)
1 #include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
2 
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"
33 
34 using namespace llvm;
35 using namespace llvm::codeview;
36 using namespace llvm::pdb;
37 
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;
42   PDB_BuiltinType Type;
43   uint32_t Size;
44 } BuiltinTypes[] = {
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
67     // needed so far.
68 };
69 
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);
75 
76   if (Dbi)
77     Compilands.resize(Dbi->modules().getModuleCount());
78 }
79 
80 std::unique_ptr<IPDBEnumSymbols>
81 SymbolCache::createTypeEnumerator(TypeLeafKind Kind) {
82   return createTypeEnumerator(std::vector<TypeLeafKind>{Kind});
83 }
84 
85 std::unique_ptr<IPDBEnumSymbols>
86 SymbolCache::createTypeEnumerator(std::vector<TypeLeafKind> Kinds) {
87   auto Tpi = Session.getPDBFile().getPDBTpiStream();
88   if (!Tpi) {
89     consumeError(Tpi.takeError());
90     return nullptr;
91   }
92   auto &Types = Tpi->typeCollection();
93   return std::unique_ptr<IPDBEnumSymbols>(
94       new NativeEnumTypes(Session, Types, std::move(Kinds)));
95 }
96 
97 std::unique_ptr<IPDBEnumSymbols>
98 SymbolCache::createGlobalsEnumerator(codeview::SymbolKind Kind) {
99   return std::unique_ptr<IPDBEnumSymbols>(
100       new NativeEnumGlobals(Session, {Kind}));
101 }
102 
103 SymIndexId SymbolCache::createSimpleType(TypeIndex Index,
104                                          ModifierOptions Mods) {
105   if (Index.getSimpleMode() != codeview::SimpleTypeMode::Direct)
106     return createSymbol<NativeTypePointer>(Index);
107 
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))
113     return 0;
114   return createSymbol<NativeTypeBuiltin>(Mods, It->Type, It->Size);
115 }
116 
117 SymIndexId
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));
123     return 0;
124   }
125 
126   if (Record.ModifiedType.isSimple())
127     return createSimpleType(Record.ModifiedType, Record.Modifiers);
128 
129   // Make sure we create and cache a record for the unmodified type.
130   SymIndexId UnmodifiedId = findSymbolByTypeIndex(Record.ModifiedType);
131   NativeRawSymbol &UnmodifiedNRS = *Cache[UnmodifiedId];
132 
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));
140   default:
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");
144     break;
145   }
146   return 0;
147 }
148 
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;
154 
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;
160     return Result;
161   }
162 
163   // We need to instantiate and cache the desired type symbol.
164   auto Tpi = Session.getPDBFile().getPDBTpiStream();
165   if (!Tpi) {
166     consumeError(Tpi.takeError());
167     return 0;
168   }
169   codeview::LazyRandomTypeCollection &Types = Tpi->typeCollection();
170   codeview::CVType CVT = Types.getType(Index);
171 
172   if (isUdtForwardRef(CVT)) {
173     Expected<TypeIndex> EFD = Tpi->findFullDeclForForwardRef(Index);
174 
175     if (!EFD)
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;
184       return Result;
185     }
186   }
187 
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.
190   SymIndexId Id = 0;
191   switch (CVT.kind()) {
192   case codeview::LF_ENUM:
193     Id = createSymbolForType<NativeTypeEnum, EnumRecord>(Index, std::move(CVT));
194     break;
195   case codeview::LF_ARRAY:
196     Id = createSymbolForType<NativeTypeArray, ArrayRecord>(Index,
197                                                            std::move(CVT));
198     break;
199   case codeview::LF_CLASS:
200   case codeview::LF_STRUCTURE:
201   case codeview::LF_INTERFACE:
202     Id = createSymbolForType<NativeTypeUDT, ClassRecord>(Index, std::move(CVT));
203     break;
204   case codeview::LF_UNION:
205     Id = createSymbolForType<NativeTypeUDT, UnionRecord>(Index, std::move(CVT));
206     break;
207   case codeview::LF_POINTER:
208     Id = createSymbolForType<NativeTypePointer, PointerRecord>(Index,
209                                                                std::move(CVT));
210     break;
211   case codeview::LF_MODIFIER:
212     Id = createSymbolForModifiedType(Index, std::move(CVT));
213     break;
214   case codeview::LF_PROCEDURE:
215     Id = createSymbolForType<NativeTypeFunctionSig, ProcedureRecord>(
216         Index, std::move(CVT));
217     break;
218   case codeview::LF_MFUNCTION:
219     Id = createSymbolForType<NativeTypeFunctionSig, MemberFunctionRecord>(
220         Index, std::move(CVT));
221     break;
222   case codeview::LF_VTSHAPE:
223     Id = createSymbolForType<NativeTypeVTShape, VFTableShapeRecord>(
224         Index, std::move(CVT));
225     break;
226   default:
227     Id = createSymbolPlaceholder();
228     break;
229   }
230   if (Id != 0) {
231     assert(TypeIndexToSymbolId.count(Index) == 0);
232     TypeIndexToSymbolId[Index] = Id;
233   }
234   return Id;
235 }
236 
237 std::unique_ptr<PDBSymbol>
238 SymbolCache::getSymbolById(SymIndexId SymbolId) const {
239   assert(SymbolId < Cache.size());
240 
241   // Id 0 is reserved.
242   if (SymbolId == 0 || SymbolId >= Cache.size())
243     return nullptr;
244 
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();
248   if (!NRS)
249     return nullptr;
250 
251   return PDBSymbol::create(Session, *NRS);
252 }
253 
254 NativeRawSymbol &SymbolCache::getNativeSymbolById(SymIndexId SymbolId) const {
255   return *Cache[SymbolId];
256 }
257 
258 uint32_t SymbolCache::getNumCompilands() const {
259   if (!Dbi)
260     return 0;
261 
262   return Dbi->modules().getModuleCount();
263 }
264 
265 SymIndexId SymbolCache::getOrCreateGlobalSymbolByOffset(uint32_t Offset) {
266   auto Iter = GlobalOffsetToSymbolId.find(Offset);
267   if (Iter != GlobalOffsetToSymbolId.end())
268     return Iter->second;
269 
270   SymbolStream &SS = cantFail(Session.getPDBFile().getPDBSymbolStream());
271   CVSymbol CVS = SS.readRecord(Offset);
272   SymIndexId Id = 0;
273   switch (CVS.kind()) {
274   case SymbolKind::S_UDT: {
275     UDTSym US = cantFail(SymbolDeserializer::deserializeAs<UDTSym>(CVS));
276     Id = createSymbol<NativeTypeTypedef>(std::move(US));
277     break;
278   }
279   default:
280     Id = createSymbolPlaceholder();
281     break;
282   }
283   if (Id != 0) {
284     assert(GlobalOffsetToSymbolId.count(Offset) == 0);
285     GlobalOffsetToSymbolId[Offset] = Id;
286   }
287 
288   return Id;
289 }
290 
291 Expected<ModuleDebugStreamRef>
292 SymbolCache::getModuleDebugStream(uint32_t Index) const {
293   assert(Dbi && "Dbi stream not present");
294 
295   DbiModuleDescriptor Modi = Dbi->modules().getModuleDescriptor(Index);
296 
297   uint16_t ModiStream = Modi.getModuleStreamIndex();
298   if (ModiStream == kInvalidStreamIndex)
299     return make_error<RawError>("Module stream not present");
300 
301   std::unique_ptr<msf::MappedBlockStream> ModStreamData =
302       Session.getPDBFile().createIndexedStream(ModiStream);
303 
304   ModuleDebugStreamRef ModS(Modi, std::move(ModStreamData));
305   if (auto EC = ModS.reload())
306     return std::move(EC);
307 
308   return std::move(ModS);
309 }
310 
311 std::unique_ptr<PDBSymbol>
312 SymbolCache::findSymbolBySectOffset(uint32_t Sect, uint32_t Offset,
313                                     PDB_SymType Type) {
314   if (AddrToModuleIndex.empty())
315     parseSectionContribs();
316 
317   switch (Type) {
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))
325       return Sym;
326     return nullptr;
327   }
328   default:
329     return nullptr;
330   }
331 }
332 
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);
338 
339   if (!Dbi)
340     return nullptr;
341 
342   auto Modi = getModuleIndexForAddr(Session.getVAFromSectOffset(Sect, Offset));
343   if (!Modi)
344     return nullptr;
345 
346   auto ExpectedModS = getModuleDebugStream(*Modi);
347   if (!ExpectedModS) {
348     consumeError(ExpectedModS.takeError());
349     return nullptr;
350   }
351   CVSymbolArray Syms = ExpectedModS->getSymbolArray();
352 
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)
356       continue;
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);
363     }
364 
365     // Jump to the end of this ProcSym.
366     I = Syms.at(PS.End);
367   }
368   return nullptr;
369 }
370 
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);
376 
377   auto Publics = Session.getPDBFile().getPDBPublicsStream();
378   if (!Publics)
379     return nullptr;
380 
381   auto ExpectedSyms = Session.getPDBFile().getPDBSymbolStream();
382   if (!ExpectedSyms)
383     return nullptr;
384   BinaryStreamRef SymStream =
385       ExpectedSyms->getSymbolArray().getUnderlyingStream();
386 
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();
393   size_t Half;
394   while (Count > 0) {
395     It = First;
396     Half = Count / 2;
397     It += Half;
398     Expected<CVSymbol> Sym = readSymbolFromStream(SymStream, *It);
399     if (!Sym) {
400       consumeError(Sym.takeError());
401       return nullptr;
402     }
403 
404     auto PS =
405         cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(Sym.get()));
406     if (PS.Segment < Sect || (PS.Segment == Sect && PS.Offset <= Offset)) {
407       First = ++It;
408       Count -= Half + 1;
409     } else
410       Count = Half;
411   }
412   if (It == AddrMap.begin())
413     return nullptr;
414   --It;
415 
416   Expected<CVSymbol> Sym = readSymbolFromStream(SymStream, *It);
417   if (!Sym) {
418     consumeError(Sym.takeError());
419     return nullptr;
420   }
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);
425 }
426 
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;
433 
434   std::vector<LineTableEntry> &ModuleLineTable = LineTable[Modi];
435 
436   // If there is an error or there are no lines, just return the
437   // empty vector.
438   Expected<ModuleDebugStreamRef> ExpectedModS = getModuleDebugStream(Modi);
439   if (!ExpectedModS) {
440     consumeError(ExpectedModS.takeError());
441     return ModuleLineTable;
442   }
443 
444   std::vector<std::vector<LineTableEntry>> EntryList;
445   for (const auto &SS : ExpectedModS->getSubsectionsArray()) {
446     if (SS.kind() != DebugSubsectionKind::Lines)
447       continue;
448 
449     DebugLinesSubsectionRef Lines;
450     BinaryStreamReader Reader(SS.getRecordData());
451     if (auto EC = Lines.initialize(Reader)) {
452       consumeError(std::move(EC));
453       continue;
454     }
455 
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())
460         continue;
461 
462       std::vector<LineTableEntry> Entries;
463 
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();
468 
469       for (const LineNumberEntry &LN : Group.LineNumbers) {
470         uint64_t VA =
471             Session.getVAFromSectOffset(RelocSegment, RelocOffset + LN.Offset);
472         LineInfo Line(LN.Flags);
473         uint32_t ColNum = 0;
474 
475         if (Lines.hasColumnInfo() && ColIt != ColsEnd) {
476           ColNum = ColIt->StartColumn;
477           ++ColIt;
478         }
479         Entries.push_back({VA, Line, ColNum, Group.NameIndex, false});
480       }
481 
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);
486       uint32_t ColNum =
487           (Lines.hasColumnInfo()) ? Group.Columns.back().StartColumn : 0;
488       Entries.push_back({VA, LastLine, ColNum, Group.NameIndex, true});
489 
490       EntryList.push_back(Entries);
491     }
492   }
493 
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;
499             });
500   for (size_t I = 0; I < EntryList.size(); ++I)
501     ModuleLineTable.insert(ModuleLineTable.end(), EntryList[I].begin(),
502                            EntryList[I].end());
503 
504   return ModuleLineTable;
505 }
506 
507 std::unique_ptr<IPDBEnumLineNumbers>
508 SymbolCache::findLineNumbersByVA(uint64_t VA, uint32_t Length) const {
509   Optional<uint16_t> MaybeModi = getModuleIndexForAddr(VA);
510   if (!MaybeModi)
511     return nullptr;
512   uint16_t Modi = *MaybeModi;
513 
514   std::vector<LineTableEntry> Lines = findLineTable(Modi);
515   if (Lines.empty())
516     return nullptr;
517 
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));
522   });
523 
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)
527       return nullptr;
528     --LineIter;
529   }
530 
531   Expected<ModuleDebugStreamRef> ExpectedModS = getModuleDebugStream(Modi);
532   if (!ExpectedModS) {
533     consumeError(ExpectedModS.takeError());
534     return nullptr;
535   }
536   Expected<DebugChecksumsSubsectionRef> ExpectedChecksums =
537       ExpectedModS->findChecksumsSubsection();
538   if (!ExpectedChecksums) {
539     consumeError(ExpectedChecksums.takeError());
540     return nullptr;
541   }
542 
543   // Populate a vector of NativeLineNumbers that have addresses in the given
544   // address range.
545   Optional<uint16_t> EndModi = getModuleIndexForAddr(VA + Length);
546   if (!EndModi)
547     return nullptr;
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()) {
553       ++Modi;
554 
555       ExpectedModS = getModuleDebugStream(Modi);
556       if (!ExpectedModS) {
557         consumeError(ExpectedModS.takeError());
558         break;
559       }
560       ExpectedChecksums = ExpectedModS->findChecksumsSubsection();
561       if (!ExpectedChecksums) {
562         consumeError(ExpectedChecksums.takeError());
563         break;
564       }
565 
566       Lines = findLineTable(Modi);
567       LineIter = Lines.begin();
568 
569       if (Lines.empty())
570         continue;
571     }
572 
573     if (LineIter->IsTerminalEntry) {
574       ++LineIter;
575       continue;
576     }
577 
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)
581       break;
582 
583     uint32_t LineSect, LineOff;
584     Session.addressForVA(LineIter->Addr, LineSect, LineOff);
585     uint32_t LineLength = std::next(LineIter)->Addr - LineIter->Addr;
586     auto ChecksumIter =
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);
592     ++LineIter;
593   }
594   return std::make_unique<NativeEnumLineNumbers>(std::move(LineNumbers));
595 }
596 
597 std::unique_ptr<PDBSymbolCompiland>
598 SymbolCache::getOrCreateCompiland(uint32_t Index) {
599   if (!Dbi)
600     return nullptr;
601 
602   if (Index >= Compilands.size())
603     return nullptr;
604 
605   if (Compilands[Index] == 0) {
606     const DbiModuleList &Modules = Dbi->modules();
607     Compilands[Index] =
608         createSymbol<NativeCompilandSymbol>(Modules.getModuleDescriptor(Index));
609   }
610 
611   return Session.getConcreteSymbolById<PDBSymbolCompiland>(Compilands[Index]);
612 }
613 
614 std::unique_ptr<IPDBSourceFile>
615 SymbolCache::getSourceFileById(SymIndexId FileId) const {
616   assert(FileId < SourceFiles.size());
617 
618   // Id 0 is reserved.
619   if (FileId == 0)
620     return nullptr;
621 
622   return std::unique_ptr<NativeSourceFile>(
623       new NativeSourceFile(*SourceFiles[FileId].get()));
624 }
625 
626 SymIndexId
627 SymbolCache::getOrCreateSourceFile(const FileChecksumEntry &Checksums) const {
628   auto Iter = FileNameOffsetToId.find(Checksums.FileNameOffset);
629   if (Iter != FileNameOffsetToId.end())
630     return Iter->second;
631 
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;
636   return Id;
637 }
638 
639 void SymbolCache::parseSectionContribs() {
640   if (!Dbi)
641     return;
642 
643   class Visitor : public ISectionContribVisitor {
644     NativeSession &Session;
645     IMap &AddrMap;
646 
647   public:
648     Visitor(NativeSession &Session, IMap &AddrMap)
649         : Session(Session), AddrMap(AddrMap) {}
650     void visit(const SectionContrib &C) override {
651       if (C.Size == 0)
652         return;
653 
654       uint64_t VA = Session.getVAFromSectOffset(C.ISect, C.Off);
655       uint64_t End = VA + C.Size;
656 
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);
661     }
662     void visit(const SectionContrib2 &C) override { visit(C.Base); }
663   };
664 
665   Visitor V(Session, AddrToModuleIndex);
666   Dbi->visitSectionContributions(V);
667 }
668 
669 Optional<uint16_t> SymbolCache::getModuleIndexForAddr(uint64_t Addr) const {
670   auto Iter = AddrToModuleIndex.find(Addr);
671   if (Iter == AddrToModuleIndex.end())
672     return None;
673   return Iter.value();
674 }
675