1 #include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
2 
3 #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
4 #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
5 #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
6 #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
7 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
8 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
9 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
10 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
11 #include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
12 #include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
13 #include "llvm/DebugInfo/PDB/Native/DbiModuleList.h"
14 #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
15 #include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
16 #include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
17 #include "llvm/DebugInfo/PDB/Native/NativeEnumGlobals.h"
18 #include "llvm/DebugInfo/PDB/Native/NativeEnumLineNumbers.h"
19 #include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
20 #include "llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h"
21 #include "llvm/DebugInfo/PDB/Native/NativeInlineSiteSymbol.h"
22 #include "llvm/DebugInfo/PDB/Native/NativeLineNumber.h"
23 #include "llvm/DebugInfo/PDB/Native/NativePublicSymbol.h"
24 #include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
25 #include "llvm/DebugInfo/PDB/Native/NativeSession.h"
26 #include "llvm/DebugInfo/PDB/Native/NativeTypeArray.h"
27 #include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
28 #include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
29 #include "llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h"
30 #include "llvm/DebugInfo/PDB/Native/NativeTypePointer.h"
31 #include "llvm/DebugInfo/PDB/Native/NativeTypeTypedef.h"
32 #include "llvm/DebugInfo/PDB/Native/NativeTypeUDT.h"
33 #include "llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h"
34 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
35 #include "llvm/DebugInfo/PDB/Native/PublicsStream.h"
36 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
37 #include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
38 #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
39 #include "llvm/DebugInfo/PDB/PDBSymbol.h"
40 #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
41 #include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
42 #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
43 
44 using namespace llvm;
45 using namespace llvm::codeview;
46 using namespace llvm::pdb;
47 
48 // Maps codeview::SimpleTypeKind of a built-in type to the parameters necessary
49 // to instantiate a NativeBuiltinSymbol for that type.
50 static const struct BuiltinTypeEntry {
51   codeview::SimpleTypeKind Kind;
52   PDB_BuiltinType Type;
53   uint32_t Size;
54 } BuiltinTypes[] = {
55     {codeview::SimpleTypeKind::None, PDB_BuiltinType::None, 0},
56     {codeview::SimpleTypeKind::Void, PDB_BuiltinType::Void, 0},
57     {codeview::SimpleTypeKind::HResult, PDB_BuiltinType::HResult, 4},
58     {codeview::SimpleTypeKind::Int16Short, PDB_BuiltinType::Int, 2},
59     {codeview::SimpleTypeKind::UInt16Short, PDB_BuiltinType::UInt, 2},
60     {codeview::SimpleTypeKind::Int32, PDB_BuiltinType::Int, 4},
61     {codeview::SimpleTypeKind::UInt32, PDB_BuiltinType::UInt, 4},
62     {codeview::SimpleTypeKind::Int32Long, PDB_BuiltinType::Int, 4},
63     {codeview::SimpleTypeKind::UInt32Long, PDB_BuiltinType::UInt, 4},
64     {codeview::SimpleTypeKind::Int64Quad, PDB_BuiltinType::Int, 8},
65     {codeview::SimpleTypeKind::UInt64Quad, PDB_BuiltinType::UInt, 8},
66     {codeview::SimpleTypeKind::NarrowCharacter, PDB_BuiltinType::Char, 1},
67     {codeview::SimpleTypeKind::WideCharacter, PDB_BuiltinType::WCharT, 2},
68     {codeview::SimpleTypeKind::Character16, PDB_BuiltinType::Char16, 2},
69     {codeview::SimpleTypeKind::Character32, PDB_BuiltinType::Char32, 4},
70     {codeview::SimpleTypeKind::Character8, PDB_BuiltinType::Char8, 1},
71     {codeview::SimpleTypeKind::SignedCharacter, PDB_BuiltinType::Char, 1},
72     {codeview::SimpleTypeKind::UnsignedCharacter, PDB_BuiltinType::UInt, 1},
73     {codeview::SimpleTypeKind::Float32, PDB_BuiltinType::Float, 4},
74     {codeview::SimpleTypeKind::Float64, PDB_BuiltinType::Float, 8},
75     {codeview::SimpleTypeKind::Float80, PDB_BuiltinType::Float, 10},
76     {codeview::SimpleTypeKind::Boolean8, PDB_BuiltinType::Bool, 1},
77     // This table can be grown as necessary, but these are the only types we've
78     // needed so far.
79 };
80 
81 SymbolCache::SymbolCache(NativeSession &Session, DbiStream *Dbi)
82     : Session(Session), Dbi(Dbi) {
83   // Id 0 is reserved for the invalid symbol.
84   Cache.push_back(nullptr);
85   SourceFiles.push_back(nullptr);
86 
87   if (Dbi)
88     Compilands.resize(Dbi->modules().getModuleCount());
89 }
90 
91 std::unique_ptr<IPDBEnumSymbols>
92 SymbolCache::createTypeEnumerator(TypeLeafKind Kind) {
93   return createTypeEnumerator(std::vector<TypeLeafKind>{Kind});
94 }
95 
96 std::unique_ptr<IPDBEnumSymbols>
97 SymbolCache::createTypeEnumerator(std::vector<TypeLeafKind> Kinds) {
98   auto Tpi = Session.getPDBFile().getPDBTpiStream();
99   if (!Tpi) {
100     consumeError(Tpi.takeError());
101     return nullptr;
102   }
103   auto &Types = Tpi->typeCollection();
104   return std::unique_ptr<IPDBEnumSymbols>(
105       new NativeEnumTypes(Session, Types, std::move(Kinds)));
106 }
107 
108 std::unique_ptr<IPDBEnumSymbols>
109 SymbolCache::createGlobalsEnumerator(codeview::SymbolKind Kind) {
110   return std::unique_ptr<IPDBEnumSymbols>(
111       new NativeEnumGlobals(Session, {Kind}));
112 }
113 
114 SymIndexId SymbolCache::createSimpleType(TypeIndex Index,
115                                          ModifierOptions Mods) const {
116   if (Index.getSimpleMode() != codeview::SimpleTypeMode::Direct)
117     return createSymbol<NativeTypePointer>(Index);
118 
119   const auto Kind = Index.getSimpleKind();
120   const auto It =
121       llvm::find_if(BuiltinTypes, [Kind](const BuiltinTypeEntry &Builtin) {
122         return Builtin.Kind == Kind;
123       });
124   if (It == std::end(BuiltinTypes))
125     return 0;
126   return createSymbol<NativeTypeBuiltin>(Mods, It->Type, It->Size);
127 }
128 
129 SymIndexId
130 SymbolCache::createSymbolForModifiedType(codeview::TypeIndex ModifierTI,
131                                          codeview::CVType CVT) const {
132   ModifierRecord Record;
133   if (auto EC = TypeDeserializer::deserializeAs<ModifierRecord>(CVT, Record)) {
134     consumeError(std::move(EC));
135     return 0;
136   }
137 
138   if (Record.ModifiedType.isSimple())
139     return createSimpleType(Record.ModifiedType, Record.Modifiers);
140 
141   // Make sure we create and cache a record for the unmodified type.
142   SymIndexId UnmodifiedId = findSymbolByTypeIndex(Record.ModifiedType);
143   NativeRawSymbol &UnmodifiedNRS = *Cache[UnmodifiedId];
144 
145   switch (UnmodifiedNRS.getSymTag()) {
146   case PDB_SymType::Enum:
147     return createSymbol<NativeTypeEnum>(
148         static_cast<NativeTypeEnum &>(UnmodifiedNRS), std::move(Record));
149   case PDB_SymType::UDT:
150     return createSymbol<NativeTypeUDT>(
151         static_cast<NativeTypeUDT &>(UnmodifiedNRS), std::move(Record));
152   default:
153     // No other types can be modified.  (LF_POINTER, for example, records
154     // its modifiers a different way.
155     assert(false && "Invalid LF_MODIFIER record");
156     break;
157   }
158   return 0;
159 }
160 
161 SymIndexId SymbolCache::findSymbolByTypeIndex(codeview::TypeIndex Index) const {
162   // First see if it's already in our cache.
163   const auto Entry = TypeIndexToSymbolId.find(Index);
164   if (Entry != TypeIndexToSymbolId.end())
165     return Entry->second;
166 
167   // Symbols for built-in types are created on the fly.
168   if (Index.isSimple()) {
169     SymIndexId Result = createSimpleType(Index, ModifierOptions::None);
170     assert(TypeIndexToSymbolId.count(Index) == 0);
171     TypeIndexToSymbolId[Index] = Result;
172     return Result;
173   }
174 
175   // We need to instantiate and cache the desired type symbol.
176   auto Tpi = Session.getPDBFile().getPDBTpiStream();
177   if (!Tpi) {
178     consumeError(Tpi.takeError());
179     return 0;
180   }
181   codeview::LazyRandomTypeCollection &Types = Tpi->typeCollection();
182   codeview::CVType CVT = Types.getType(Index);
183 
184   if (isUdtForwardRef(CVT)) {
185     Expected<TypeIndex> EFD = Tpi->findFullDeclForForwardRef(Index);
186 
187     if (!EFD)
188       consumeError(EFD.takeError());
189     else if (*EFD != Index) {
190       assert(!isUdtForwardRef(Types.getType(*EFD)));
191       SymIndexId Result = findSymbolByTypeIndex(*EFD);
192       // Record a mapping from ForwardRef -> SymIndex of complete type so that
193       // we'll take the fast path next time.
194       assert(TypeIndexToSymbolId.count(Index) == 0);
195       TypeIndexToSymbolId[Index] = Result;
196       return Result;
197     }
198   }
199 
200   // At this point if we still have a forward ref udt it means the full decl was
201   // not in the PDB.  We just have to deal with it and use the forward ref.
202   SymIndexId Id = 0;
203   switch (CVT.kind()) {
204   case codeview::LF_ENUM:
205     Id = createSymbolForType<NativeTypeEnum, EnumRecord>(Index, std::move(CVT));
206     break;
207   case codeview::LF_ARRAY:
208     Id = createSymbolForType<NativeTypeArray, ArrayRecord>(Index,
209                                                            std::move(CVT));
210     break;
211   case codeview::LF_CLASS:
212   case codeview::LF_STRUCTURE:
213   case codeview::LF_INTERFACE:
214     Id = createSymbolForType<NativeTypeUDT, ClassRecord>(Index, std::move(CVT));
215     break;
216   case codeview::LF_UNION:
217     Id = createSymbolForType<NativeTypeUDT, UnionRecord>(Index, std::move(CVT));
218     break;
219   case codeview::LF_POINTER:
220     Id = createSymbolForType<NativeTypePointer, PointerRecord>(Index,
221                                                                std::move(CVT));
222     break;
223   case codeview::LF_MODIFIER:
224     Id = createSymbolForModifiedType(Index, std::move(CVT));
225     break;
226   case codeview::LF_PROCEDURE:
227     Id = createSymbolForType<NativeTypeFunctionSig, ProcedureRecord>(
228         Index, std::move(CVT));
229     break;
230   case codeview::LF_MFUNCTION:
231     Id = createSymbolForType<NativeTypeFunctionSig, MemberFunctionRecord>(
232         Index, std::move(CVT));
233     break;
234   case codeview::LF_VTSHAPE:
235     Id = createSymbolForType<NativeTypeVTShape, VFTableShapeRecord>(
236         Index, std::move(CVT));
237     break;
238   default:
239     Id = createSymbolPlaceholder();
240     break;
241   }
242   if (Id != 0) {
243     assert(TypeIndexToSymbolId.count(Index) == 0);
244     TypeIndexToSymbolId[Index] = Id;
245   }
246   return Id;
247 }
248 
249 std::unique_ptr<PDBSymbol>
250 SymbolCache::getSymbolById(SymIndexId SymbolId) const {
251   assert(SymbolId < Cache.size());
252 
253   // Id 0 is reserved.
254   if (SymbolId == 0 || SymbolId >= Cache.size())
255     return nullptr;
256 
257   // Make sure to handle the case where we've inserted a placeholder symbol
258   // for types we don't yet support.
259   NativeRawSymbol *NRS = Cache[SymbolId].get();
260   if (!NRS)
261     return nullptr;
262 
263   return PDBSymbol::create(Session, *NRS);
264 }
265 
266 NativeRawSymbol &SymbolCache::getNativeSymbolById(SymIndexId SymbolId) const {
267   return *Cache[SymbolId];
268 }
269 
270 uint32_t SymbolCache::getNumCompilands() const {
271   if (!Dbi)
272     return 0;
273 
274   return Dbi->modules().getModuleCount();
275 }
276 
277 SymIndexId SymbolCache::getOrCreateGlobalSymbolByOffset(uint32_t Offset) {
278   auto Iter = GlobalOffsetToSymbolId.find(Offset);
279   if (Iter != GlobalOffsetToSymbolId.end())
280     return Iter->second;
281 
282   SymbolStream &SS = cantFail(Session.getPDBFile().getPDBSymbolStream());
283   CVSymbol CVS = SS.readRecord(Offset);
284   SymIndexId Id = 0;
285   switch (CVS.kind()) {
286   case SymbolKind::S_UDT: {
287     UDTSym US = cantFail(SymbolDeserializer::deserializeAs<UDTSym>(CVS));
288     Id = createSymbol<NativeTypeTypedef>(std::move(US));
289     break;
290   }
291   default:
292     Id = createSymbolPlaceholder();
293     break;
294   }
295   if (Id != 0) {
296     assert(GlobalOffsetToSymbolId.count(Offset) == 0);
297     GlobalOffsetToSymbolId[Offset] = Id;
298   }
299 
300   return Id;
301 }
302 
303 SymIndexId SymbolCache::getOrCreateInlineSymbol(InlineSiteSym Sym,
304                                                 uint64_t ParentAddr,
305                                                 uint16_t Modi,
306                                                 uint32_t RecordOffset) const {
307   auto Iter = SymTabOffsetToSymbolId.find({Modi, RecordOffset});
308   if (Iter != SymTabOffsetToSymbolId.end())
309     return Iter->second;
310 
311   SymIndexId Id = createSymbol<NativeInlineSiteSymbol>(Sym, ParentAddr);
312   SymTabOffsetToSymbolId.insert({{Modi, RecordOffset}, Id});
313   return Id;
314 }
315 
316 std::unique_ptr<PDBSymbol>
317 SymbolCache::findSymbolBySectOffset(uint32_t Sect, uint32_t Offset,
318                                     PDB_SymType Type) {
319   switch (Type) {
320   case PDB_SymType::Function:
321     return findFunctionSymbolBySectOffset(Sect, Offset);
322   case PDB_SymType::PublicSymbol:
323     return findPublicSymbolBySectOffset(Sect, Offset);
324   case PDB_SymType::Compiland: {
325     uint16_t Modi;
326     if (!Session.moduleIndexForSectOffset(Sect, Offset, Modi))
327       return nullptr;
328     return getOrCreateCompiland(Modi);
329   }
330   case PDB_SymType::None: {
331     // FIXME: Implement for PDB_SymType::Data. The symbolizer calls this but
332     // only uses it to find the symbol length.
333     if (auto Sym = findFunctionSymbolBySectOffset(Sect, Offset))
334       return Sym;
335     return nullptr;
336   }
337   default:
338     return nullptr;
339   }
340 }
341 
342 std::unique_ptr<PDBSymbol>
343 SymbolCache::findFunctionSymbolBySectOffset(uint32_t Sect, uint32_t Offset) {
344   auto Iter = AddressToSymbolId.find({Sect, Offset});
345   if (Iter != AddressToSymbolId.end())
346     return getSymbolById(Iter->second);
347 
348   if (!Dbi)
349     return nullptr;
350 
351   uint16_t Modi;
352   if (!Session.moduleIndexForSectOffset(Sect, Offset, Modi))
353     return nullptr;
354 
355   Expected<ModuleDebugStreamRef> ExpectedModS =
356       Session.getModuleDebugStream(Modi);
357   if (!ExpectedModS) {
358     consumeError(ExpectedModS.takeError());
359     return nullptr;
360   }
361   CVSymbolArray Syms = ExpectedModS->getSymbolArray();
362 
363   // Search for the symbol in this module.
364   for (auto I = Syms.begin(), E = Syms.end(); I != E; ++I) {
365     if (I->kind() != S_LPROC32 && I->kind() != S_GPROC32)
366       continue;
367     auto PS = cantFail(SymbolDeserializer::deserializeAs<ProcSym>(*I));
368     if (Sect == PS.Segment && Offset >= PS.CodeOffset &&
369         Offset < PS.CodeOffset + PS.CodeSize) {
370       // Check if the symbol is already cached.
371       auto Found = AddressToSymbolId.find({PS.Segment, PS.CodeOffset});
372       if (Found != AddressToSymbolId.end())
373         return getSymbolById(Found->second);
374 
375       // Otherwise, create a new symbol.
376       SymIndexId Id = createSymbol<NativeFunctionSymbol>(PS, I.offset());
377       AddressToSymbolId.insert({{PS.Segment, PS.CodeOffset}, Id});
378       return getSymbolById(Id);
379     }
380 
381     // Jump to the end of this ProcSym.
382     I = Syms.at(PS.End);
383   }
384   return nullptr;
385 }
386 
387 std::unique_ptr<PDBSymbol>
388 SymbolCache::findPublicSymbolBySectOffset(uint32_t Sect, uint32_t Offset) {
389   auto Iter = AddressToPublicSymId.find({Sect, Offset});
390   if (Iter != AddressToPublicSymId.end())
391     return getSymbolById(Iter->second);
392 
393   auto Publics = Session.getPDBFile().getPDBPublicsStream();
394   if (!Publics)
395     return nullptr;
396 
397   auto ExpectedSyms = Session.getPDBFile().getPDBSymbolStream();
398   if (!ExpectedSyms)
399     return nullptr;
400   BinaryStreamRef SymStream =
401       ExpectedSyms->getSymbolArray().getUnderlyingStream();
402 
403   // Use binary search to find the first public symbol with an address greater
404   // than or equal to Sect, Offset.
405   auto AddrMap = Publics->getAddressMap();
406   auto First = AddrMap.begin();
407   auto It = AddrMap.begin();
408   size_t Count = AddrMap.size();
409   size_t Half;
410   while (Count > 0) {
411     It = First;
412     Half = Count / 2;
413     It += Half;
414     Expected<CVSymbol> Sym = readSymbolFromStream(SymStream, *It);
415     if (!Sym) {
416       consumeError(Sym.takeError());
417       return nullptr;
418     }
419 
420     auto PS =
421         cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(Sym.get()));
422     if (PS.Segment < Sect || (PS.Segment == Sect && PS.Offset <= Offset)) {
423       First = ++It;
424       Count -= Half + 1;
425     } else
426       Count = Half;
427   }
428   if (It == AddrMap.begin())
429     return nullptr;
430   --It;
431 
432   Expected<CVSymbol> Sym = readSymbolFromStream(SymStream, *It);
433   if (!Sym) {
434     consumeError(Sym.takeError());
435     return nullptr;
436   }
437 
438   // Check if the symbol is already cached.
439   auto PS = cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(Sym.get()));
440   auto Found = AddressToPublicSymId.find({PS.Segment, PS.Offset});
441   if (Found != AddressToPublicSymId.end())
442     return getSymbolById(Found->second);
443 
444   // Otherwise, create a new symbol.
445   SymIndexId Id = createSymbol<NativePublicSymbol>(PS);
446   AddressToPublicSymId.insert({{PS.Segment, PS.Offset}, Id});
447   return getSymbolById(Id);
448 }
449 
450 std::vector<SymbolCache::LineTableEntry>
451 SymbolCache::findLineTable(uint16_t Modi) const {
452   // Check if this module has already been added.
453   auto LineTableIter = LineTable.find(Modi);
454   if (LineTableIter != LineTable.end())
455     return LineTableIter->second;
456 
457   std::vector<LineTableEntry> &ModuleLineTable = LineTable[Modi];
458 
459   // If there is an error or there are no lines, just return the
460   // empty vector.
461   Expected<ModuleDebugStreamRef> ExpectedModS =
462       Session.getModuleDebugStream(Modi);
463   if (!ExpectedModS) {
464     consumeError(ExpectedModS.takeError());
465     return ModuleLineTable;
466   }
467 
468   std::vector<std::vector<LineTableEntry>> EntryList;
469   for (const auto &SS : ExpectedModS->getSubsectionsArray()) {
470     if (SS.kind() != DebugSubsectionKind::Lines)
471       continue;
472 
473     DebugLinesSubsectionRef Lines;
474     BinaryStreamReader Reader(SS.getRecordData());
475     if (auto EC = Lines.initialize(Reader)) {
476       consumeError(std::move(EC));
477       continue;
478     }
479 
480     uint32_t RelocSegment = Lines.header()->RelocSegment;
481     uint32_t RelocOffset = Lines.header()->RelocOffset;
482     for (const LineColumnEntry &Group : Lines) {
483       if (Group.LineNumbers.empty())
484         continue;
485 
486       std::vector<LineTableEntry> Entries;
487 
488       // If there are column numbers, then they should be in a parallel stream
489       // to the line numbers.
490       auto ColIt = Group.Columns.begin();
491       auto ColsEnd = Group.Columns.end();
492 
493       // Add a line to mark the beginning of this section.
494       uint64_t StartAddr =
495           Session.getVAFromSectOffset(RelocSegment, RelocOffset);
496       LineInfo FirstLine(Group.LineNumbers.front().Flags);
497       uint32_t ColNum =
498           (Lines.hasColumnInfo()) ? Group.Columns.front().StartColumn : 0;
499       Entries.push_back({StartAddr, FirstLine, ColNum, Group.NameIndex, false});
500 
501       for (const LineNumberEntry &LN : Group.LineNumbers) {
502         uint64_t VA =
503             Session.getVAFromSectOffset(RelocSegment, RelocOffset + LN.Offset);
504         LineInfo Line(LN.Flags);
505         ColNum = 0;
506 
507         if (Lines.hasColumnInfo() && ColIt != ColsEnd) {
508           ColNum = ColIt->StartColumn;
509           ++ColIt;
510         }
511         Entries.push_back({VA, Line, ColNum, Group.NameIndex, false});
512       }
513 
514       // Add a terminal entry line to mark the end of this subsection.
515       uint64_t EndAddr = StartAddr + Lines.header()->CodeSize;
516       LineInfo LastLine(Group.LineNumbers.back().Flags);
517       ColNum = (Lines.hasColumnInfo()) ? Group.Columns.back().StartColumn : 0;
518       Entries.push_back({EndAddr, LastLine, ColNum, Group.NameIndex, true});
519 
520       EntryList.push_back(Entries);
521     }
522   }
523 
524   // Sort EntryList, and add flattened contents to the line table.
525   llvm::sort(EntryList, [](const std::vector<LineTableEntry> &LHS,
526                            const std::vector<LineTableEntry> &RHS) {
527     return LHS[0].Addr < RHS[0].Addr;
528   });
529   for (std::vector<LineTableEntry> &I : EntryList)
530     llvm::append_range(ModuleLineTable, I);
531 
532   return ModuleLineTable;
533 }
534 
535 std::unique_ptr<IPDBEnumLineNumbers>
536 SymbolCache::findLineNumbersByVA(uint64_t VA, uint32_t Length) const {
537   uint16_t Modi;
538   if (!Session.moduleIndexForVA(VA, Modi))
539     return nullptr;
540 
541   std::vector<LineTableEntry> Lines = findLineTable(Modi);
542   if (Lines.empty())
543     return nullptr;
544 
545   // Find the first line in the line table whose address is not greater than
546   // the one we are searching for.
547   auto LineIter = llvm::partition_point(Lines, [&](const LineTableEntry &E) {
548     return (E.Addr < VA || (E.Addr == VA && E.IsTerminalEntry));
549   });
550 
551   // Try to back up if we've gone too far.
552   if (LineIter == Lines.end() || LineIter->Addr > VA) {
553     if (LineIter == Lines.begin() || std::prev(LineIter)->IsTerminalEntry)
554       return nullptr;
555     --LineIter;
556   }
557 
558   Expected<ModuleDebugStreamRef> ExpectedModS =
559       Session.getModuleDebugStream(Modi);
560   if (!ExpectedModS) {
561     consumeError(ExpectedModS.takeError());
562     return nullptr;
563   }
564   Expected<DebugChecksumsSubsectionRef> ExpectedChecksums =
565       ExpectedModS->findChecksumsSubsection();
566   if (!ExpectedChecksums) {
567     consumeError(ExpectedChecksums.takeError());
568     return nullptr;
569   }
570 
571   // Populate a vector of NativeLineNumbers that have addresses in the given
572   // address range.
573   std::vector<NativeLineNumber> LineNumbers;
574   while (LineIter != Lines.end()) {
575     if (LineIter->IsTerminalEntry) {
576       ++LineIter;
577       continue;
578     }
579 
580     // If the line is still within the address range, create a NativeLineNumber
581     // and add to the list.
582     if (LineIter->Addr > VA + Length)
583       break;
584 
585     uint32_t LineSect, LineOff;
586     Session.addressForVA(LineIter->Addr, LineSect, LineOff);
587     uint32_t LineLength = std::next(LineIter)->Addr - LineIter->Addr;
588     auto ChecksumIter =
589         ExpectedChecksums->getArray().at(LineIter->FileNameIndex);
590     uint32_t SrcFileId = getOrCreateSourceFile(*ChecksumIter);
591     NativeLineNumber LineNum(Session, LineIter->Line, LineIter->ColumnNumber,
592                              LineSect, LineOff, LineLength, SrcFileId, Modi);
593     LineNumbers.push_back(LineNum);
594     ++LineIter;
595   }
596   return std::make_unique<NativeEnumLineNumbers>(std::move(LineNumbers));
597 }
598 
599 std::unique_ptr<PDBSymbolCompiland>
600 SymbolCache::getOrCreateCompiland(uint32_t Index) {
601   if (!Dbi)
602     return nullptr;
603 
604   if (Index >= Compilands.size())
605     return nullptr;
606 
607   if (Compilands[Index] == 0) {
608     const DbiModuleList &Modules = Dbi->modules();
609     Compilands[Index] =
610         createSymbol<NativeCompilandSymbol>(Modules.getModuleDescriptor(Index));
611   }
612 
613   return Session.getConcreteSymbolById<PDBSymbolCompiland>(Compilands[Index]);
614 }
615 
616 std::unique_ptr<IPDBSourceFile>
617 SymbolCache::getSourceFileById(SymIndexId FileId) const {
618   assert(FileId < SourceFiles.size());
619 
620   // Id 0 is reserved.
621   if (FileId == 0)
622     return nullptr;
623 
624   return std::unique_ptr<NativeSourceFile>(
625       new NativeSourceFile(*SourceFiles[FileId].get()));
626 }
627 
628 SymIndexId
629 SymbolCache::getOrCreateSourceFile(const FileChecksumEntry &Checksums) const {
630   auto Iter = FileNameOffsetToId.find(Checksums.FileNameOffset);
631   if (Iter != FileNameOffsetToId.end())
632     return Iter->second;
633 
634   SymIndexId Id = SourceFiles.size();
635   auto SrcFile = std::make_unique<NativeSourceFile>(Session, Id, Checksums);
636   SourceFiles.push_back(std::move(SrcFile));
637   FileNameOffsetToId[Checksums.FileNameOffset] = Id;
638   return Id;
639 }
640 
641 
642