003 File Manager
Current Path:
/usr/src/contrib/llvm-project/llvm/lib/DebugInfo/PDB/Native
usr
/
src
/
contrib
/
llvm-project
/
llvm
/
lib
/
DebugInfo
/
PDB
/
Native
/
📁
..
📄
DbiModuleDescriptor.cpp
(2.5 KB)
📄
DbiModuleDescriptorBuilder.cpp
(6.63 KB)
📄
DbiModuleList.cpp
(8.3 KB)
📄
DbiStream.cpp
(12.8 KB)
📄
DbiStreamBuilder.cpp
(14.82 KB)
📄
EnumTables.cpp
(1.33 KB)
📄
GSIStreamBuilder.cpp
(17.23 KB)
📄
GlobalsStream.cpp
(6.56 KB)
📄
Hash.cpp
(2.39 KB)
📄
HashTable.cpp
(2.55 KB)
📄
InfoStream.cpp
(3.94 KB)
📄
InfoStreamBuilder.cpp
(2.67 KB)
📄
InjectedSourceStream.cpp
(2.31 KB)
📄
ModuleDebugStream.cpp
(4.74 KB)
📄
NamedStreamMap.cpp
(4.2 KB)
📄
NativeCompilandSymbol.cpp
(2.22 KB)
📄
NativeEnumGlobals.cpp
(1.87 KB)
📄
NativeEnumInjectedSources.cpp
(4.05 KB)
📄
NativeEnumLineNumbers.cpp
(1.44 KB)
📄
NativeEnumModules.cpp
(1.36 KB)
📄
NativeEnumTypes.cpp
(2.62 KB)
📄
NativeExeSymbol.cpp
(3.25 KB)
📄
NativeFunctionSymbol.cpp
(2.12 KB)
📄
NativeLineNumber.cpp
(1.88 KB)
📄
NativePublicSymbol.cpp
(1.92 KB)
📄
NativeRawSymbol.cpp
(14.98 KB)
📄
NativeSession.cpp
(12.36 KB)
📄
NativeSourceFile.cpp
(1.47 KB)
📄
NativeSymbolEnumerator.cpp
(4.24 KB)
📄
NativeTypeArray.cpp
(2.6 KB)
📄
NativeTypeBuiltin.cpp
(1.67 KB)
📄
NativeTypeEnum.cpp
(12.55 KB)
📄
NativeTypeFunctionSig.cpp
(7.3 KB)
📄
NativeTypePointer.cpp
(6.41 KB)
📄
NativeTypeTypedef.cpp
(1.05 KB)
📄
NativeTypeUDT.cpp
(6.93 KB)
📄
NativeTypeVTShape.cpp
(1.42 KB)
📄
PDBFile.cpp
(16.2 KB)
📄
PDBFileBuilder.cpp
(11 KB)
📄
PDBStringTable.cpp
(4.53 KB)
📄
PDBStringTableBuilder.cpp
(6.88 KB)
📄
PublicsStream.cpp
(3.89 KB)
📄
RawError.cpp
(2.13 KB)
📄
SymbolCache.cpp
(22.39 KB)
📄
SymbolStream.cpp
(1.4 KB)
📄
TpiHashing.cpp
(4.32 KB)
📄
TpiStream.cpp
(7.85 KB)
📄
TpiStreamBuilder.cpp
(6.32 KB)
Editing: SymbolCache.cpp
#include "llvm/DebugInfo/PDB/Native/SymbolCache.h" #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h" #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" #include "llvm/DebugInfo/CodeView/TypeDeserializer.h" #include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h" #include "llvm/DebugInfo/PDB/Native/DbiStream.h" #include "llvm/DebugInfo/PDB/Native/GlobalsStream.h" #include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h" #include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h" #include "llvm/DebugInfo/PDB/Native/NativeEnumGlobals.h" #include "llvm/DebugInfo/PDB/Native/NativeEnumLineNumbers.h" #include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h" #include "llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h" #include "llvm/DebugInfo/PDB/Native/NativePublicSymbol.h" #include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h" #include "llvm/DebugInfo/PDB/Native/NativeSession.h" #include "llvm/DebugInfo/PDB/Native/NativeTypeArray.h" #include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h" #include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h" #include "llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h" #include "llvm/DebugInfo/PDB/Native/NativeTypePointer.h" #include "llvm/DebugInfo/PDB/Native/NativeTypeTypedef.h" #include "llvm/DebugInfo/PDB/Native/NativeTypeUDT.h" #include "llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h" #include "llvm/DebugInfo/PDB/Native/PDBFile.h" #include "llvm/DebugInfo/PDB/Native/PublicsStream.h" #include "llvm/DebugInfo/PDB/Native/SymbolStream.h" #include "llvm/DebugInfo/PDB/Native/TpiStream.h" #include "llvm/DebugInfo/PDB/PDBSymbol.h" #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" using namespace llvm; using namespace llvm::codeview; using namespace llvm::pdb; // Maps codeview::SimpleTypeKind of a built-in type to the parameters necessary // to instantiate a NativeBuiltinSymbol for that type. static const struct BuiltinTypeEntry { codeview::SimpleTypeKind Kind; PDB_BuiltinType Type; uint32_t Size; } BuiltinTypes[] = { {codeview::SimpleTypeKind::None, PDB_BuiltinType::None, 0}, {codeview::SimpleTypeKind::Void, PDB_BuiltinType::Void, 0}, {codeview::SimpleTypeKind::HResult, PDB_BuiltinType::HResult, 4}, {codeview::SimpleTypeKind::Int16Short, PDB_BuiltinType::Int, 2}, {codeview::SimpleTypeKind::UInt16Short, PDB_BuiltinType::UInt, 2}, {codeview::SimpleTypeKind::Int32, PDB_BuiltinType::Int, 4}, {codeview::SimpleTypeKind::UInt32, PDB_BuiltinType::UInt, 4}, {codeview::SimpleTypeKind::Int32Long, PDB_BuiltinType::Int, 4}, {codeview::SimpleTypeKind::UInt32Long, PDB_BuiltinType::UInt, 4}, {codeview::SimpleTypeKind::Int64Quad, PDB_BuiltinType::Int, 8}, {codeview::SimpleTypeKind::UInt64Quad, PDB_BuiltinType::UInt, 8}, {codeview::SimpleTypeKind::NarrowCharacter, PDB_BuiltinType::Char, 1}, {codeview::SimpleTypeKind::WideCharacter, PDB_BuiltinType::WCharT, 2}, {codeview::SimpleTypeKind::Character16, PDB_BuiltinType::Char16, 2}, {codeview::SimpleTypeKind::Character32, PDB_BuiltinType::Char32, 4}, {codeview::SimpleTypeKind::SignedCharacter, PDB_BuiltinType::Char, 1}, {codeview::SimpleTypeKind::UnsignedCharacter, PDB_BuiltinType::UInt, 1}, {codeview::SimpleTypeKind::Float32, PDB_BuiltinType::Float, 4}, {codeview::SimpleTypeKind::Float64, PDB_BuiltinType::Float, 8}, {codeview::SimpleTypeKind::Float80, PDB_BuiltinType::Float, 10}, {codeview::SimpleTypeKind::Boolean8, PDB_BuiltinType::Bool, 1}, // This table can be grown as necessary, but these are the only types we've // needed so far. }; SymbolCache::SymbolCache(NativeSession &Session, DbiStream *Dbi) : Session(Session), Dbi(Dbi), AddrToModuleIndex(IMapAllocator) { // Id 0 is reserved for the invalid symbol. Cache.push_back(nullptr); SourceFiles.push_back(nullptr); if (Dbi) Compilands.resize(Dbi->modules().getModuleCount()); } std::unique_ptr<IPDBEnumSymbols> SymbolCache::createTypeEnumerator(TypeLeafKind Kind) { return createTypeEnumerator(std::vector<TypeLeafKind>{Kind}); } std::unique_ptr<IPDBEnumSymbols> SymbolCache::createTypeEnumerator(std::vector<TypeLeafKind> Kinds) { auto Tpi = Session.getPDBFile().getPDBTpiStream(); if (!Tpi) { consumeError(Tpi.takeError()); return nullptr; } auto &Types = Tpi->typeCollection(); return std::unique_ptr<IPDBEnumSymbols>( new NativeEnumTypes(Session, Types, std::move(Kinds))); } std::unique_ptr<IPDBEnumSymbols> SymbolCache::createGlobalsEnumerator(codeview::SymbolKind Kind) { return std::unique_ptr<IPDBEnumSymbols>( new NativeEnumGlobals(Session, {Kind})); } SymIndexId SymbolCache::createSimpleType(TypeIndex Index, ModifierOptions Mods) { if (Index.getSimpleMode() != codeview::SimpleTypeMode::Direct) return createSymbol<NativeTypePointer>(Index); const auto Kind = Index.getSimpleKind(); const auto It = std::find_if( std::begin(BuiltinTypes), std::end(BuiltinTypes), [Kind](const BuiltinTypeEntry &Builtin) { return Builtin.Kind == Kind; }); if (It == std::end(BuiltinTypes)) return 0; return createSymbol<NativeTypeBuiltin>(Mods, It->Type, It->Size); } SymIndexId SymbolCache::createSymbolForModifiedType(codeview::TypeIndex ModifierTI, codeview::CVType CVT) { ModifierRecord Record; if (auto EC = TypeDeserializer::deserializeAs<ModifierRecord>(CVT, Record)) { consumeError(std::move(EC)); return 0; } if (Record.ModifiedType.isSimple()) return createSimpleType(Record.ModifiedType, Record.Modifiers); // Make sure we create and cache a record for the unmodified type. SymIndexId UnmodifiedId = findSymbolByTypeIndex(Record.ModifiedType); NativeRawSymbol &UnmodifiedNRS = *Cache[UnmodifiedId]; switch (UnmodifiedNRS.getSymTag()) { case PDB_SymType::Enum: return createSymbol<NativeTypeEnum>( static_cast<NativeTypeEnum &>(UnmodifiedNRS), std::move(Record)); case PDB_SymType::UDT: return createSymbol<NativeTypeUDT>( static_cast<NativeTypeUDT &>(UnmodifiedNRS), std::move(Record)); default: // No other types can be modified. (LF_POINTER, for example, records // its modifiers a different way. assert(false && "Invalid LF_MODIFIER record"); break; } return 0; } SymIndexId SymbolCache::findSymbolByTypeIndex(codeview::TypeIndex Index) { // First see if it's already in our cache. const auto Entry = TypeIndexToSymbolId.find(Index); if (Entry != TypeIndexToSymbolId.end()) return Entry->second; // Symbols for built-in types are created on the fly. if (Index.isSimple()) { SymIndexId Result = createSimpleType(Index, ModifierOptions::None); assert(TypeIndexToSymbolId.count(Index) == 0); TypeIndexToSymbolId[Index] = Result; return Result; } // We need to instantiate and cache the desired type symbol. auto Tpi = Session.getPDBFile().getPDBTpiStream(); if (!Tpi) { consumeError(Tpi.takeError()); return 0; } codeview::LazyRandomTypeCollection &Types = Tpi->typeCollection(); codeview::CVType CVT = Types.getType(Index); if (isUdtForwardRef(CVT)) { Expected<TypeIndex> EFD = Tpi->findFullDeclForForwardRef(Index); if (!EFD) consumeError(EFD.takeError()); else if (*EFD != Index) { assert(!isUdtForwardRef(Types.getType(*EFD))); SymIndexId Result = findSymbolByTypeIndex(*EFD); // Record a mapping from ForwardRef -> SymIndex of complete type so that // we'll take the fast path next time. assert(TypeIndexToSymbolId.count(Index) == 0); TypeIndexToSymbolId[Index] = Result; return Result; } } // At this point if we still have a forward ref udt it means the full decl was // not in the PDB. We just have to deal with it and use the forward ref. SymIndexId Id = 0; switch (CVT.kind()) { case codeview::LF_ENUM: Id = createSymbolForType<NativeTypeEnum, EnumRecord>(Index, std::move(CVT)); break; case codeview::LF_ARRAY: Id = createSymbolForType<NativeTypeArray, ArrayRecord>(Index, std::move(CVT)); break; case codeview::LF_CLASS: case codeview::LF_STRUCTURE: case codeview::LF_INTERFACE: Id = createSymbolForType<NativeTypeUDT, ClassRecord>(Index, std::move(CVT)); break; case codeview::LF_UNION: Id = createSymbolForType<NativeTypeUDT, UnionRecord>(Index, std::move(CVT)); break; case codeview::LF_POINTER: Id = createSymbolForType<NativeTypePointer, PointerRecord>(Index, std::move(CVT)); break; case codeview::LF_MODIFIER: Id = createSymbolForModifiedType(Index, std::move(CVT)); break; case codeview::LF_PROCEDURE: Id = createSymbolForType<NativeTypeFunctionSig, ProcedureRecord>( Index, std::move(CVT)); break; case codeview::LF_MFUNCTION: Id = createSymbolForType<NativeTypeFunctionSig, MemberFunctionRecord>( Index, std::move(CVT)); break; case codeview::LF_VTSHAPE: Id = createSymbolForType<NativeTypeVTShape, VFTableShapeRecord>( Index, std::move(CVT)); break; default: Id = createSymbolPlaceholder(); break; } if (Id != 0) { assert(TypeIndexToSymbolId.count(Index) == 0); TypeIndexToSymbolId[Index] = Id; } return Id; } std::unique_ptr<PDBSymbol> SymbolCache::getSymbolById(SymIndexId SymbolId) const { assert(SymbolId < Cache.size()); // Id 0 is reserved. if (SymbolId == 0 || SymbolId >= Cache.size()) return nullptr; // Make sure to handle the case where we've inserted a placeholder symbol // for types we don't yet suppport. NativeRawSymbol *NRS = Cache[SymbolId].get(); if (!NRS) return nullptr; return PDBSymbol::create(Session, *NRS); } NativeRawSymbol &SymbolCache::getNativeSymbolById(SymIndexId SymbolId) const { return *Cache[SymbolId]; } uint32_t SymbolCache::getNumCompilands() const { if (!Dbi) return 0; return Dbi->modules().getModuleCount(); } SymIndexId SymbolCache::getOrCreateGlobalSymbolByOffset(uint32_t Offset) { auto Iter = GlobalOffsetToSymbolId.find(Offset); if (Iter != GlobalOffsetToSymbolId.end()) return Iter->second; SymbolStream &SS = cantFail(Session.getPDBFile().getPDBSymbolStream()); CVSymbol CVS = SS.readRecord(Offset); SymIndexId Id = 0; switch (CVS.kind()) { case SymbolKind::S_UDT: { UDTSym US = cantFail(SymbolDeserializer::deserializeAs<UDTSym>(CVS)); Id = createSymbol<NativeTypeTypedef>(std::move(US)); break; } default: Id = createSymbolPlaceholder(); break; } if (Id != 0) { assert(GlobalOffsetToSymbolId.count(Offset) == 0); GlobalOffsetToSymbolId[Offset] = Id; } return Id; } Expected<ModuleDebugStreamRef> SymbolCache::getModuleDebugStream(uint32_t Index) const { assert(Dbi && "Dbi stream not present"); DbiModuleDescriptor Modi = Dbi->modules().getModuleDescriptor(Index); uint16_t ModiStream = Modi.getModuleStreamIndex(); if (ModiStream == kInvalidStreamIndex) return make_error<RawError>("Module stream not present"); std::unique_ptr<msf::MappedBlockStream> ModStreamData = Session.getPDBFile().createIndexedStream(ModiStream); ModuleDebugStreamRef ModS(Modi, std::move(ModStreamData)); if (auto EC = ModS.reload()) return std::move(EC); return std::move(ModS); } std::unique_ptr<PDBSymbol> SymbolCache::findSymbolBySectOffset(uint32_t Sect, uint32_t Offset, PDB_SymType Type) { if (AddrToModuleIndex.empty()) parseSectionContribs(); switch (Type) { case PDB_SymType::Function: return findFunctionSymbolBySectOffset(Sect, Offset); case PDB_SymType::PublicSymbol: return findPublicSymbolBySectOffset(Sect, Offset); case PDB_SymType::None: { // FIXME: Implement for PDB_SymType::Data. if (auto Sym = findFunctionSymbolBySectOffset(Sect, Offset)) return Sym; return nullptr; } default: return nullptr; } } std::unique_ptr<PDBSymbol> SymbolCache::findFunctionSymbolBySectOffset(uint32_t Sect, uint32_t Offset) { auto Iter = AddressToFunctionSymId.find({Sect, Offset}); if (Iter != AddressToFunctionSymId.end()) return getSymbolById(Iter->second); if (!Dbi) return nullptr; auto Modi = getModuleIndexForAddr(Session.getVAFromSectOffset(Sect, Offset)); if (!Modi) return nullptr; auto ExpectedModS = getModuleDebugStream(*Modi); if (!ExpectedModS) { consumeError(ExpectedModS.takeError()); return nullptr; } CVSymbolArray Syms = ExpectedModS->getSymbolArray(); // Search for the symbol in this module. for (auto I = Syms.begin(), E = Syms.end(); I != E; ++I) { if (I->kind() != S_LPROC32 && I->kind() != S_GPROC32) continue; auto PS = cantFail(SymbolDeserializer::deserializeAs<ProcSym>(*I)); if (Sect == PS.Segment && Offset >= PS.CodeOffset && Offset < PS.CodeOffset + PS.CodeSize) { SymIndexId Id = createSymbol<NativeFunctionSymbol>(PS); AddressToFunctionSymId.insert({{Sect, Offset}, Id}); return getSymbolById(Id); } // Jump to the end of this ProcSym. I = Syms.at(PS.End); } return nullptr; } std::unique_ptr<PDBSymbol> SymbolCache::findPublicSymbolBySectOffset(uint32_t Sect, uint32_t Offset) { auto Iter = AddressToPublicSymId.find({Sect, Offset}); if (Iter != AddressToPublicSymId.end()) return getSymbolById(Iter->second); auto Publics = Session.getPDBFile().getPDBPublicsStream(); if (!Publics) return nullptr; auto ExpectedSyms = Session.getPDBFile().getPDBSymbolStream(); if (!ExpectedSyms) return nullptr; BinaryStreamRef SymStream = ExpectedSyms->getSymbolArray().getUnderlyingStream(); // Use binary search to find the first public symbol with an address greater // than or equal to Sect, Offset. auto AddrMap = Publics->getAddressMap(); auto First = AddrMap.begin(); auto It = AddrMap.begin(); size_t Count = AddrMap.size(); size_t Half; while (Count > 0) { It = First; Half = Count / 2; It += Half; Expected<CVSymbol> Sym = readSymbolFromStream(SymStream, *It); if (!Sym) { consumeError(Sym.takeError()); return nullptr; } auto PS = cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(Sym.get())); if (PS.Segment < Sect || (PS.Segment == Sect && PS.Offset <= Offset)) { First = ++It; Count -= Half + 1; } else Count = Half; } if (It == AddrMap.begin()) return nullptr; --It; Expected<CVSymbol> Sym = readSymbolFromStream(SymStream, *It); if (!Sym) { consumeError(Sym.takeError()); return nullptr; } auto PS = cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(Sym.get())); SymIndexId Id = createSymbol<NativePublicSymbol>(PS); AddressToPublicSymId.insert({{Sect, Offset}, Id}); return getSymbolById(Id); } std::vector<SymbolCache::LineTableEntry> SymbolCache::findLineTable(uint16_t Modi) const { // Check if this module has already been added. auto LineTableIter = LineTable.find(Modi); if (LineTableIter != LineTable.end()) return LineTableIter->second; std::vector<LineTableEntry> &ModuleLineTable = LineTable[Modi]; // If there is an error or there are no lines, just return the // empty vector. Expected<ModuleDebugStreamRef> ExpectedModS = getModuleDebugStream(Modi); if (!ExpectedModS) { consumeError(ExpectedModS.takeError()); return ModuleLineTable; } std::vector<std::vector<LineTableEntry>> EntryList; for (const auto &SS : ExpectedModS->getSubsectionsArray()) { if (SS.kind() != DebugSubsectionKind::Lines) continue; DebugLinesSubsectionRef Lines; BinaryStreamReader Reader(SS.getRecordData()); if (auto EC = Lines.initialize(Reader)) { consumeError(std::move(EC)); continue; } uint32_t RelocSegment = Lines.header()->RelocSegment; uint32_t RelocOffset = Lines.header()->RelocOffset; for (const LineColumnEntry &Group : Lines) { if (Group.LineNumbers.empty()) continue; std::vector<LineTableEntry> Entries; // If there are column numbers, then they should be in a parallel stream // to the line numbers. auto ColIt = Group.Columns.begin(); auto ColsEnd = Group.Columns.end(); for (const LineNumberEntry &LN : Group.LineNumbers) { uint64_t VA = Session.getVAFromSectOffset(RelocSegment, RelocOffset + LN.Offset); LineInfo Line(LN.Flags); uint32_t ColNum = 0; if (Lines.hasColumnInfo() && ColIt != ColsEnd) { ColNum = ColIt->StartColumn; ++ColIt; } Entries.push_back({VA, Line, ColNum, Group.NameIndex, false}); } // Add a terminal entry line to mark the end of this subsection. uint64_t VA = Session.getVAFromSectOffset( RelocSegment, RelocOffset + Lines.header()->CodeSize); LineInfo LastLine(Group.LineNumbers.back().Flags); uint32_t ColNum = (Lines.hasColumnInfo()) ? Group.Columns.back().StartColumn : 0; Entries.push_back({VA, LastLine, ColNum, Group.NameIndex, true}); EntryList.push_back(Entries); } } // Sort EntryList, and add flattened contents to the line table. std::sort(EntryList.begin(), EntryList.end(), [](const std::vector<LineTableEntry> &LHS, const std::vector<LineTableEntry> &RHS) { return LHS[0].Addr < RHS[0].Addr; }); for (size_t I = 0; I < EntryList.size(); ++I) ModuleLineTable.insert(ModuleLineTable.end(), EntryList[I].begin(), EntryList[I].end()); return ModuleLineTable; } std::unique_ptr<IPDBEnumLineNumbers> SymbolCache::findLineNumbersByVA(uint64_t VA, uint32_t Length) const { Optional<uint16_t> MaybeModi = getModuleIndexForAddr(VA); if (!MaybeModi) return nullptr; uint16_t Modi = *MaybeModi; std::vector<LineTableEntry> Lines = findLineTable(Modi); if (Lines.empty()) return nullptr; // Find the first line in the line table whose address is not greater than // the one we are searching for. auto LineIter = llvm::partition_point(Lines, [&](const LineTableEntry &E) { return (E.Addr < VA || (E.Addr == VA && E.IsTerminalEntry)); }); // Try to back up if we've gone too far. if (LineIter == Lines.end() || LineIter->Addr > VA) { if (LineIter == Lines.begin() || std::prev(LineIter)->IsTerminalEntry) return nullptr; --LineIter; } Expected<ModuleDebugStreamRef> ExpectedModS = getModuleDebugStream(Modi); if (!ExpectedModS) { consumeError(ExpectedModS.takeError()); return nullptr; } Expected<DebugChecksumsSubsectionRef> ExpectedChecksums = ExpectedModS->findChecksumsSubsection(); if (!ExpectedChecksums) { consumeError(ExpectedChecksums.takeError()); return nullptr; } // Populate a vector of NativeLineNumbers that have addresses in the given // address range. Optional<uint16_t> EndModi = getModuleIndexForAddr(VA + Length); if (!EndModi) return nullptr; std::vector<NativeLineNumber> LineNumbers; while (Modi <= *EndModi) { // If we reached the end of the current module, increment Modi and get the // new line table and checksums array. if (LineIter == Lines.end()) { ++Modi; ExpectedModS = getModuleDebugStream(Modi); if (!ExpectedModS) { consumeError(ExpectedModS.takeError()); break; } ExpectedChecksums = ExpectedModS->findChecksumsSubsection(); if (!ExpectedChecksums) { consumeError(ExpectedChecksums.takeError()); break; } Lines = findLineTable(Modi); LineIter = Lines.begin(); if (Lines.empty()) continue; } if (LineIter->IsTerminalEntry) { ++LineIter; continue; } // If the line is still within the address range, create a NativeLineNumber // and add to the list. if (LineIter->Addr > VA + Length) break; uint32_t LineSect, LineOff; Session.addressForVA(LineIter->Addr, LineSect, LineOff); uint32_t LineLength = std::next(LineIter)->Addr - LineIter->Addr; auto ChecksumIter = ExpectedChecksums->getArray().at(LineIter->FileNameIndex); uint32_t SrcFileId = getOrCreateSourceFile(*ChecksumIter); NativeLineNumber LineNum(Session, LineIter->Line, LineIter->ColumnNumber, LineSect, LineOff, LineLength, SrcFileId); LineNumbers.push_back(LineNum); ++LineIter; } return std::make_unique<NativeEnumLineNumbers>(std::move(LineNumbers)); } std::unique_ptr<PDBSymbolCompiland> SymbolCache::getOrCreateCompiland(uint32_t Index) { if (!Dbi) return nullptr; if (Index >= Compilands.size()) return nullptr; if (Compilands[Index] == 0) { const DbiModuleList &Modules = Dbi->modules(); Compilands[Index] = createSymbol<NativeCompilandSymbol>(Modules.getModuleDescriptor(Index)); } return Session.getConcreteSymbolById<PDBSymbolCompiland>(Compilands[Index]); } std::unique_ptr<IPDBSourceFile> SymbolCache::getSourceFileById(SymIndexId FileId) const { assert(FileId < SourceFiles.size()); // Id 0 is reserved. if (FileId == 0) return nullptr; return std::unique_ptr<NativeSourceFile>( new NativeSourceFile(*SourceFiles[FileId].get())); } SymIndexId SymbolCache::getOrCreateSourceFile(const FileChecksumEntry &Checksums) const { auto Iter = FileNameOffsetToId.find(Checksums.FileNameOffset); if (Iter != FileNameOffsetToId.end()) return Iter->second; SymIndexId Id = SourceFiles.size(); auto SrcFile = std::make_unique<NativeSourceFile>(Session, Id, Checksums); SourceFiles.push_back(std::move(SrcFile)); FileNameOffsetToId[Checksums.FileNameOffset] = Id; return Id; } void SymbolCache::parseSectionContribs() { if (!Dbi) return; class Visitor : public ISectionContribVisitor { NativeSession &Session; IMap &AddrMap; public: Visitor(NativeSession &Session, IMap &AddrMap) : Session(Session), AddrMap(AddrMap) {} void visit(const SectionContrib &C) override { if (C.Size == 0) return; uint64_t VA = Session.getVAFromSectOffset(C.ISect, C.Off); uint64_t End = VA + C.Size; // Ignore overlapping sections based on the assumption that a valid // PDB file should not have overlaps. if (!AddrMap.overlaps(VA, End)) AddrMap.insert(VA, End, C.Imod); } void visit(const SectionContrib2 &C) override { visit(C.Base); } }; Visitor V(Session, AddrToModuleIndex); Dbi->visitSectionContributions(V); } Optional<uint16_t> SymbolCache::getModuleIndexForAddr(uint64_t Addr) const { auto Iter = AddrToModuleIndex.find(Addr); if (Iter == AddrToModuleIndex.end()) return None; return Iter.value(); }
Upload File
Create Folder