diff options
author | orivej <orivej@yandex-team.ru> | 2022-02-10 16:45:01 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:01 +0300 |
commit | 2d37894b1b037cf24231090eda8589bbb44fb6fc (patch) | |
tree | be835aa92c6248212e705f25388ebafcf84bc7a1 /contrib/libs/llvm12/lib/DebugInfo/PDB/Native/SymbolCache.cpp | |
parent | 718c552901d703c502ccbefdfc3c9028d608b947 (diff) | |
download | ydb-2d37894b1b037cf24231090eda8589bbb44fb6fc.tar.gz |
Restoring authorship annotation for <orivej@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/libs/llvm12/lib/DebugInfo/PDB/Native/SymbolCache.cpp')
-rw-r--r-- | contrib/libs/llvm12/lib/DebugInfo/PDB/Native/SymbolCache.cpp | 1112 |
1 files changed, 556 insertions, 556 deletions
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/SymbolCache.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/SymbolCache.cpp index eca69a4a83..fd9a0deb54 100644 --- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/SymbolCache.cpp +++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/SymbolCache.cpp @@ -1,297 +1,297 @@ -#include "llvm/DebugInfo/PDB/Native/SymbolCache.h" - +#include "llvm/DebugInfo/PDB/Native/SymbolCache.h" + #include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.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/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/NativeEnumSymbols.h" -#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h" -#include "llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h" +#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h" +#include "llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h" #include "llvm/DebugInfo/PDB/Native/NativeInlineSiteSymbol.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) +#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) { - // 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, + // 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) const { - if (Index.getSimpleMode() != codeview::SimpleTypeMode::Direct) - return createSymbol<NativeTypePointer>(Index); - - const auto Kind = Index.getSimpleKind(); + if (Index.getSimpleMode() != codeview::SimpleTypeMode::Direct) + return createSymbol<NativeTypePointer>(Index); + + const auto Kind = Index.getSimpleKind(); const auto It = llvm::find_if(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, + if (It == std::end(BuiltinTypes)) + return 0; + return createSymbol<NativeTypeBuiltin>(Mods, It->Type, It->Size); +} + +SymIndexId +SymbolCache::createSymbolForModifiedType(codeview::TypeIndex ModifierTI, codeview::CVType CVT) const { - 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; -} - + 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) const { - // 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 + // 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 support. - 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; -} - + 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; +} + SymIndexId SymbolCache::getOrCreateInlineSymbol(InlineSiteSym Sym, uint64_t ParentAddr, uint16_t Modi, @@ -299,66 +299,66 @@ SymIndexId SymbolCache::getOrCreateInlineSymbol(InlineSiteSym Sym, auto Iter = SymTabOffsetToSymbolId.find({Modi, RecordOffset}); if (Iter != SymTabOffsetToSymbolId.end()) return Iter->second; - + SymIndexId Id = createSymbol<NativeInlineSiteSymbol>(Sym, ParentAddr); SymTabOffsetToSymbolId.insert({{Modi, RecordOffset}, Id}); return Id; -} - -std::unique_ptr<PDBSymbol> -SymbolCache::findSymbolBySectOffset(uint32_t Sect, uint32_t Offset, - PDB_SymType Type) { - switch (Type) { - case PDB_SymType::Function: - return findFunctionSymbolBySectOffset(Sect, Offset); - case PDB_SymType::PublicSymbol: - return findPublicSymbolBySectOffset(Sect, Offset); +} + +std::unique_ptr<PDBSymbol> +SymbolCache::findSymbolBySectOffset(uint32_t Sect, uint32_t Offset, + PDB_SymType Type) { + switch (Type) { + case PDB_SymType::Function: + return findFunctionSymbolBySectOffset(Sect, Offset); + case PDB_SymType::PublicSymbol: + return findPublicSymbolBySectOffset(Sect, Offset); case PDB_SymType::Compiland: { uint16_t Modi; if (!Session.moduleIndexForSectOffset(Sect, Offset, Modi)) return nullptr; return getOrCreateCompiland(Modi); } - case PDB_SymType::None: { + case PDB_SymType::None: { // FIXME: Implement for PDB_SymType::Data. The symbolizer calls this but // only uses it to find the symbol length. - 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) { + 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 = AddressToSymbolId.find({Sect, Offset}); if (Iter != AddressToSymbolId.end()) - return getSymbolById(Iter->second); - - if (!Dbi) - return nullptr; - + return getSymbolById(Iter->second); + + if (!Dbi) + return nullptr; + uint16_t Modi; if (!Session.moduleIndexForSectOffset(Sect, Offset, Modi)) - return nullptr; - + return nullptr; + Expected<ModuleDebugStreamRef> ExpectedModS = Session.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) { + 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) { // Check if the symbol is already cached. auto Found = AddressToSymbolId.find({PS.Segment, PS.CodeOffset}); if (Found != AddressToSymbolId.end()) @@ -367,121 +367,121 @@ SymbolCache::findFunctionSymbolBySectOffset(uint32_t Sect, uint32_t Offset) { // Otherwise, create a new symbol. SymIndexId Id = createSymbol<NativeFunctionSymbol>(PS, I.offset()); AddressToSymbolId.insert({{PS.Segment, PS.CodeOffset}, 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; - } + 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; + } // Check if the symbol is already cached. - auto PS = cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(Sym.get())); + auto PS = cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(Sym.get())); auto Found = AddressToPublicSymId.find({PS.Segment, PS.Offset}); if (Found != AddressToPublicSymId.end()) return getSymbolById(Found->second); // Otherwise, create a new symbol. - SymIndexId Id = createSymbol<NativePublicSymbol>(PS); + SymIndexId Id = createSymbol<NativePublicSymbol>(PS); AddressToPublicSymId.insert({{PS.Segment, PS.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. + 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 = Session.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(); - + 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(); + // Add a line to mark the beginning of this section. uint64_t StartAddr = Session.getVAFromSectOffset(RelocSegment, RelocOffset); @@ -490,144 +490,144 @@ SymbolCache::findLineTable(uint16_t Modi) const { (Lines.hasColumnInfo()) ? Group.Columns.front().StartColumn : 0; Entries.push_back({StartAddr, FirstLine, ColNum, Group.NameIndex, false}); - for (const LineNumberEntry &LN : Group.LineNumbers) { - uint64_t VA = - Session.getVAFromSectOffset(RelocSegment, RelocOffset + LN.Offset); - LineInfo Line(LN.Flags); + for (const LineNumberEntry &LN : Group.LineNumbers) { + uint64_t VA = + Session.getVAFromSectOffset(RelocSegment, RelocOffset + LN.Offset); + LineInfo Line(LN.Flags); 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. + + 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 EndAddr = StartAddr + Lines.header()->CodeSize; - LineInfo LastLine(Group.LineNumbers.back().Flags); + LineInfo LastLine(Group.LineNumbers.back().Flags); ColNum = (Lines.hasColumnInfo()) ? Group.Columns.back().StartColumn : 0; Entries.push_back({EndAddr, LastLine, ColNum, Group.NameIndex, true}); - - EntryList.push_back(Entries); - } - } - - // Sort EntryList, and add flattened contents to the line table. + + EntryList.push_back(Entries); + } + } + + // Sort EntryList, and add flattened contents to the line table. llvm::sort(EntryList, [](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) + for (size_t I = 0; I < EntryList.size(); ++I) llvm::append_range(ModuleLineTable, EntryList[I]); - - return ModuleLineTable; -} - -std::unique_ptr<IPDBEnumLineNumbers> -SymbolCache::findLineNumbersByVA(uint64_t VA, uint32_t Length) const { + + return ModuleLineTable; +} + +std::unique_ptr<IPDBEnumLineNumbers> +SymbolCache::findLineNumbersByVA(uint64_t VA, uint32_t Length) const { uint16_t Modi; if (!Session.moduleIndexForVA(VA, Modi)) - return nullptr; - - 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; - } - + return nullptr; + + 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 = Session.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. - std::vector<NativeLineNumber> LineNumbers; + 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. + std::vector<NativeLineNumber> LineNumbers; while (LineIter != Lines.end()) { - 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, + 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, Modi); - 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; -} - - + 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; +} + + |