79 : Session(Session), Dbi(Dbi) {
81 Cache.push_back(
nullptr);
82 SourceFiles.push_back(
nullptr);
88 std::unique_ptr<IPDBEnumSymbols>
93 std::unique_ptr<IPDBEnumSymbols>
100 auto &Types = Tpi->typeCollection();
101 return std::unique_ptr<IPDBEnumSymbols>(
105 std::unique_ptr<IPDBEnumSymbols>
107 return std::unique_ptr<IPDBEnumSymbols>(
114 return createSymbol<NativeTypePointer>(
Index);
123 return createSymbol<NativeTypeBuiltin>(Mods, It->Type, It->Size);
130 if (
auto EC = TypeDeserializer::deserializeAs<ModifierRecord>(CVT,
Record)) {
135 if (
Record.ModifiedType.isSimple())
136 return createSimpleType(
Record.ModifiedType,
Record.Modifiers);
144 return createSymbol<NativeTypeEnum>(
147 return createSymbol<NativeTypeUDT>(
152 assert(
false &&
"Invalid LF_MODIFIER record");
160 const auto Entry = TypeIndexToSymbolId.find(
Index);
161 if (Entry != TypeIndexToSymbolId.end())
162 return Entry->second;
165 if (
Index.isSimple()) {
168 TypeIndexToSymbolId[
Index] = Result;
186 else if (*EFD !=
Index) {
192 TypeIndexToSymbolId[
Index] = Result;
200 switch (CVT.
kind()) {
201 case codeview::LF_ENUM:
202 Id = createSymbolForType<NativeTypeEnum, EnumRecord>(
Index,
std::move(CVT));
204 case codeview::LF_ARRAY:
205 Id = createSymbolForType<NativeTypeArray, ArrayRecord>(
Index,
208 case codeview::LF_CLASS:
209 case codeview::LF_STRUCTURE:
210 case codeview::LF_INTERFACE:
211 Id = createSymbolForType<NativeTypeUDT, ClassRecord>(
Index,
std::move(CVT));
213 case codeview::LF_UNION:
214 Id = createSymbolForType<NativeTypeUDT, UnionRecord>(
Index,
std::move(CVT));
216 case codeview::LF_POINTER:
217 Id = createSymbolForType<NativeTypePointer, PointerRecord>(
Index,
220 case codeview::LF_MODIFIER:
223 case codeview::LF_PROCEDURE:
224 Id = createSymbolForType<NativeTypeFunctionSig, ProcedureRecord>(
227 case codeview::LF_MFUNCTION:
228 Id = createSymbolForType<NativeTypeFunctionSig, MemberFunctionRecord>(
231 case codeview::LF_VTSHAPE:
232 Id = createSymbolForType<NativeTypeVTShape, VFTableShapeRecord>(
236 Id = createSymbolPlaceholder();
241 TypeIndexToSymbolId[
Index] =
Id;
246 std::unique_ptr<PDBSymbol>
248 assert(SymbolId < Cache.size());
251 if (SymbolId == 0 || SymbolId >= Cache.size())
264 return *Cache[SymbolId];
275 auto Iter = GlobalOffsetToSymbolId.find(Offset);
276 if (Iter != GlobalOffsetToSymbolId.end())
282 switch (CVS.
kind()) {
283 case SymbolKind::S_UDT: {
284 UDTSym US =
cantFail(SymbolDeserializer::deserializeAs<UDTSym>(CVS));
285 Id = createSymbol<NativeTypeTypedef>(
std::move(US));
289 Id = createSymbolPlaceholder();
293 assert(GlobalOffsetToSymbolId.count(Offset) == 0);
294 GlobalOffsetToSymbolId[Offset] =
Id;
304 auto Iter = SymTabOffsetToSymbolId.find({Modi, RecordOffset});
305 if (Iter != SymTabOffsetToSymbolId.end())
308 SymIndexId Id = createSymbol<NativeInlineSiteSymbol>(Sym, ParentAddr);
309 SymTabOffsetToSymbolId.insert({{Modi, RecordOffset},
Id});
313 std::unique_ptr<PDBSymbol>
318 return findFunctionSymbolBySectOffset(Sect, Offset);
320 return findPublicSymbolBySectOffset(Sect, Offset);
330 if (
auto Sym = findFunctionSymbolBySectOffset(Sect, Offset))
339 std::unique_ptr<PDBSymbol>
340 SymbolCache::findFunctionSymbolBySectOffset(
uint32_t Sect,
uint32_t Offset) {
341 auto Iter = AddressToSymbolId.find({Sect, Offset});
342 if (Iter != AddressToSymbolId.end())
362 if (
I->kind() != S_LPROC32 &&
I->kind() != S_GPROC32)
364 auto PS =
cantFail(SymbolDeserializer::deserializeAs<ProcSym>(*
I));
365 if (Sect == PS.Segment && Offset >= PS.CodeOffset &&
366 Offset < PS.CodeOffset + PS.CodeSize) {
368 auto Found = AddressToSymbolId.find({PS.Segment, PS.CodeOffset});
369 if (Found != AddressToSymbolId.end())
373 SymIndexId Id = createSymbol<NativeFunctionSymbol>(PS,
I.offset());
374 AddressToSymbolId.insert({{PS.Segment, PS.CodeOffset},
Id});
384 std::unique_ptr<PDBSymbol>
386 auto Iter = AddressToPublicSymId.find({Sect,
Offset});
387 if (Iter != AddressToPublicSymId.end())
398 ExpectedSyms->getSymbolArray().getUnderlyingStream();
402 auto AddrMap = Publics->getAddressMap();
403 auto First = AddrMap.begin();
404 auto It = AddrMap.begin();
405 size_t Count = AddrMap.size();
418 cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(Sym.
get()));
419 if (PS.Segment < Sect || (PS.Segment == Sect && PS.Offset <= Offset)) {
425 if (It == AddrMap.begin())
436 auto PS =
cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(Sym.
get()));
437 auto Found = AddressToPublicSymId.find({PS.Segment, PS.Offset});
438 if (Found != AddressToPublicSymId.end())
443 AddressToPublicSymId.insert({{PS.Segment, PS.Offset},
Id});
447 std::vector<SymbolCache::LineTableEntry>
448 SymbolCache::findLineTable(
uint16_t Modi)
const {
450 auto LineTableIter = LineTable.
find(Modi);
451 if (LineTableIter != LineTable.
end())
452 return LineTableIter->second;
454 std::vector<LineTableEntry> &ModuleLineTable = LineTable[Modi];
462 return ModuleLineTable;
465 std::vector<std::vector<LineTableEntry>> EntryList;
466 for (
const auto &
SS : ExpectedModS->getSubsectionsArray()) {
467 if (
SS.kind() != DebugSubsectionKind::Lines)
472 if (
auto EC =
Lines.initialize(Reader)) {
480 if (Group.LineNumbers.empty())
483 std::vector<LineTableEntry> Entries;
487 auto ColIt = Group.Columns.begin();
488 auto ColsEnd = Group.Columns.end();
493 LineInfo FirstLine(Group.LineNumbers.front().Flags);
495 (
Lines.hasColumnInfo()) ? Group.Columns.front().StartColumn : 0;
496 Entries.push_back({StartAddr, FirstLine, ColNum, Group.NameIndex,
false});
504 if (
Lines.hasColumnInfo() && ColIt != ColsEnd) {
505 ColNum = ColIt->StartColumn;
508 Entries.push_back({VA,
Line, ColNum, Group.NameIndex,
false});
513 LineInfo LastLine(Group.LineNumbers.back().Flags);
514 ColNum = (
Lines.hasColumnInfo()) ? Group.Columns.back().StartColumn : 0;
515 Entries.push_back({EndAddr, LastLine, ColNum, Group.NameIndex,
true});
517 EntryList.push_back(Entries);
522 llvm::sort(EntryList, [](
const std::vector<LineTableEntry> &
LHS,
523 const std::vector<LineTableEntry> &
RHS) {
524 return LHS[0].Addr <
RHS[0].Addr;
526 for (std::vector<LineTableEntry> &
I : EntryList)
529 return ModuleLineTable;
532 std::unique_ptr<IPDBEnumLineNumbers>
538 std::vector<LineTableEntry>
Lines = findLineTable(Modi);
545 return (
E.Addr < VA || (
E.Addr == VA &&
E.IsTerminalEntry));
549 if (LineIter ==
Lines.end() || LineIter->Addr > VA) {
550 if (LineIter ==
Lines.begin() || std::prev(LineIter)->IsTerminalEntry)
562 ExpectedModS->findChecksumsSubsection();
563 if (!ExpectedChecksums) {
571 while (LineIter !=
Lines.end()) {
572 if (LineIter->IsTerminalEntry) {
579 if (LineIter->Addr > VA + Length)
583 Session.
addressForVA(LineIter->Addr, LineSect, LineOff);
584 uint32_t LineLength = std::next(LineIter)->Addr - LineIter->Addr;
586 ExpectedChecksums->getArray().at(LineIter->FileNameIndex);
589 LineSect, LineOff, LineLength, SrcFileId, Modi);
596 std::unique_ptr<PDBSymbolCompiland>
601 if (
Index >= Compilands.size())
604 if (Compilands[
Index] == 0) {
613 std::unique_ptr<IPDBSourceFile>
615 assert(FileId < SourceFiles.size());
621 return std::unique_ptr<NativeSourceFile>(
628 if (Iter != FileNameOffsetToId.end())
632 auto SrcFile = std::make_unique<NativeSourceFile>(Session,
Id, Checksums);
633 SourceFiles.push_back(
std::move(SrcFile));