diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/DebugInfo/PDB/Native/NativeExeSymbol.h | 16 | ||||
| -rw-r--r-- | llvm/include/llvm/DebugInfo/PDB/Native/NativeSession.h | 31 | ||||
| -rw-r--r-- | llvm/include/llvm/DebugInfo/PDB/Native/SymbolCache.h | 73 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp | 4 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/Native/NativeEnumSymbol.cpp | 7 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp | 56 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp | 117 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp | 147 | 
10 files changed, 279 insertions, 175 deletions
diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/NativeExeSymbol.h b/llvm/include/llvm/DebugInfo/PDB/Native/NativeExeSymbol.h index 634eb75d7fd..81f0ac07d47 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Native/NativeExeSymbol.h +++ b/llvm/include/llvm/DebugInfo/PDB/Native/NativeExeSymbol.h @@ -19,8 +19,11 @@ namespace pdb {  class DbiStream;  class NativeExeSymbol : public NativeRawSymbol { +  // EXE symbol is the authority on the various symbol types. +  DbiStream *Dbi = nullptr; +  public: -  NativeExeSymbol(NativeSession &Session, SymIndexId SymbolId); +  NativeExeSymbol(NativeSession &Session, SymIndexId Id);    std::unique_ptr<NativeRawSymbol> clone() const override; @@ -32,17 +35,6 @@ public:    codeview::GUID getGuid() const override;    bool hasCTypes() const override;    bool hasPrivateSymbols() const override; - -  std::unique_ptr<PDBSymbolCompiland> getOrCreateCompiland(uint32_t Index); -  uint32_t getNumCompilands() const; - -private: -  PDBFile &File; - -  DbiStream *Dbi = nullptr; - -  // EXE symbol is the authority on the various symbol types. -  mutable std::vector<SymIndexId> Compilands;  };  } // namespace pdb diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/NativeSession.h b/llvm/include/llvm/DebugInfo/PDB/Native/NativeSession.h index 398157a211a..fc1019c3d4a 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Native/NativeSession.h +++ b/llvm/include/llvm/DebugInfo/PDB/Native/NativeSession.h @@ -17,6 +17,7 @@  #include "llvm/DebugInfo/PDB/IPDBSession.h"  #include "llvm/DebugInfo/PDB/Native/NativeBuiltinSymbol.h"  #include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h" +#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"  #include "llvm/Support/Allocator.h"  #include "llvm/Support/Error.h" @@ -37,25 +38,6 @@ public:    static Error createFromExe(StringRef Path,                               std::unique_ptr<IPDBSession> &Session); -  template <typename ConcreteSymbolT, typename... Args> -  SymIndexId createSymbol(Args &&... ConstructorArgs) { -    SymIndexId Id = SymbolCache.size(); -    std::unique_ptr<ConcreteSymbolT> Symbol = -        llvm::make_unique<ConcreteSymbolT>( -            *this, Id, std::forward<Args>(ConstructorArgs)...); -    std::unique_ptr<NativeRawSymbol> NRS = std::move(Symbol); -    SymbolCache.push_back(std::move(NRS)); -    return Id; -  } - -  std::unique_ptr<PDBSymbolTypeEnum> -  createEnumSymbol(codeview::TypeIndex Index); - -  std::unique_ptr<IPDBEnumSymbols> -  createTypeEnumerator(codeview::TypeLeafKind Kind); - -  SymIndexId findSymbolByTypeIndex(codeview::TypeIndex TI); -    uint64_t getLoadAddress() const override;    bool setLoadAddress(uint64_t Address) override;    std::unique_ptr<PDBSymbolExe> getGlobalScope() override; @@ -115,15 +97,18 @@ public:    PDBFile &getPDBFile() { return *Pdb; }    const PDBFile &getPDBFile() const { return *Pdb; } -  NativeExeSymbol &getNativeGlobalScope(); +  NativeExeSymbol &getNativeGlobalScope() const; +  SymbolCache &getSymbolCache() { return Cache; } +  const SymbolCache &getSymbolCache() const { return Cache; }  private: -  SymIndexId ExeSymbol = 0; +  void initializeExeSymbol();    std::unique_ptr<PDBFile> Pdb;    std::unique_ptr<BumpPtrAllocator> Allocator; -  std::vector<std::unique_ptr<NativeRawSymbol>> SymbolCache; -  DenseMap<codeview::TypeIndex, SymIndexId> TypeIndexToSymbolId; + +  SymbolCache Cache; +  SymIndexId ExeSymbol = 0;  };  } // namespace pdb  } // namespace llvm diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/SymbolCache.h b/llvm/include/llvm/DebugInfo/PDB/Native/SymbolCache.h new file mode 100644 index 00000000000..8cbee8b19a0 --- /dev/null +++ b/llvm/include/llvm/DebugInfo/PDB/Native/SymbolCache.h @@ -0,0 +1,73 @@ +//==- SymbolCache.h - Cache of native symbols and ids ------------*- C++ -*-==// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_PDB_NATIVE_SYMBOLCACHE_H +#define LLVM_DEBUGINFO_PDB_NATIVE_SYMBOLCACHE_H + +#include "llvm/ADT/DenseMap.h" +#include "llvm/DebugInfo/CodeView/TypeIndex.h" +#include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h" +#include "llvm/Support/Allocator.h" + +#include <memory> +#include <vector> + +namespace llvm { +namespace pdb { +class DbiStream; +class PDBFile; + +class SymbolCache { +  NativeSession &Session; +  DbiStream *Dbi = nullptr; + +  std::vector<std::unique_ptr<NativeRawSymbol>> Cache; +  DenseMap<codeview::TypeIndex, SymIndexId> TypeIndexToSymbolId; +  std::vector<SymIndexId> Compilands; + +public: +  SymbolCache(NativeSession &Session, DbiStream *Dbi); + +  template <typename ConcreteSymbolT, typename... Args> +  SymIndexId createSymbol(Args &&... ConstructorArgs) { +    SymIndexId Id = Cache.size(); +    std::unique_ptr<ConcreteSymbolT> Symbol = +        llvm::make_unique<ConcreteSymbolT>( +            Session, Id, std::forward<Args>(ConstructorArgs)...); +    std::unique_ptr<NativeRawSymbol> NRS = std::move(Symbol); +    Cache.push_back(std::move(NRS)); +    return Id; +  } + +  std::unique_ptr<PDBSymbolTypeEnum> +  createEnumSymbol(codeview::TypeIndex Index); + +  std::unique_ptr<IPDBEnumSymbols> +  createTypeEnumerator(codeview::TypeLeafKind Kind); + +  SymIndexId findSymbolByTypeIndex(codeview::TypeIndex TI); + +  std::unique_ptr<PDBSymbolCompiland> getOrCreateCompiland(uint32_t Index); +  uint32_t getNumCompilands() const; + +  std::unique_ptr<PDBSymbol> getSymbolById(SymIndexId SymbolId) const; + +  NativeRawSymbol &getNativeSymbolById(SymIndexId SymbolId) const; + +  template <typename ConcreteT> +  ConcreteT &getNativeSymbolById(SymIndexId SymbolId) const { +    return static_cast<ConcreteT &>(getNativeSymbolById(SymbolId)); +  } +}; + +} // namespace pdb +} // namespace llvm + +#endif diff --git a/llvm/lib/DebugInfo/PDB/CMakeLists.txt b/llvm/lib/DebugInfo/PDB/CMakeLists.txt index f6a529a69a8..9bf97ddb425 100644 --- a/llvm/lib/DebugInfo/PDB/CMakeLists.txt +++ b/llvm/lib/DebugInfo/PDB/CMakeLists.txt @@ -62,6 +62,7 @@ add_pdb_impl_folder(Native    Native/PublicsStream.cpp    Native/GSIStreamBuilder.cpp    Native/RawError.cpp +  Native/SymbolCache.cpp    Native/SymbolStream.cpp    Native/TpiHashing.cpp    Native/TpiStream.cpp diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp index f54568865aa..9dd66f3f0c4 100644 --- a/llvm/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp @@ -24,12 +24,12 @@ NativeEnumModules::NativeEnumModules(NativeSession &PDBSession, uint32_t Index)      : Session(PDBSession), Index(Index) {}  uint32_t NativeEnumModules::getChildCount() const { -  return Session.getNativeGlobalScope().getNumCompilands(); +  return Session.getSymbolCache().getNumCompilands();  }  std::unique_ptr<PDBSymbol>  NativeEnumModules::getChildAtIndex(uint32_t N) const { -  return Session.getNativeGlobalScope().getOrCreateCompiland(N); +  return Session.getSymbolCache().getOrCreateCompiland(N);  }  std::unique_ptr<PDBSymbol> NativeEnumModules::getNext() { diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeEnumSymbol.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeEnumSymbol.cpp index 5dbdff7e746..893afd44d61 100644 --- a/llvm/lib/DebugInfo/PDB/Native/NativeEnumSymbol.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/NativeEnumSymbol.cpp @@ -12,6 +12,7 @@  #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"  #include "llvm/DebugInfo/CodeView/TypeRecord.h"  #include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h" +#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"  #include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"  #include <cassert> @@ -78,7 +79,8 @@ bool NativeEnumSymbol::hasCastOperator() const {  }  uint64_t NativeEnumSymbol::getLength() const { -  const auto Id = Session.findSymbolByTypeIndex(Record.getUnderlyingType()); +  const auto Id = Session.getSymbolCache().findSymbolByTypeIndex( +      Record.getUnderlyingType());    const auto UnderlyingType =        Session.getConcreteSymbolById<PDBSymbolTypeBuiltin>(Id);    return UnderlyingType ? UnderlyingType->getLength() : 0; @@ -104,5 +106,6 @@ bool NativeEnumSymbol::isScoped() const {  }  uint32_t NativeEnumSymbol::getTypeId() const { -  return Session.findSymbolByTypeIndex(Record.getUnderlyingType()); +  return Session.getSymbolCache().findSymbolByTypeIndex( +      Record.getUnderlyingType());  } diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp index 36a68a1c62d..70a187b14af 100644 --- a/llvm/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp @@ -41,7 +41,7 @@ uint32_t NativeEnumTypes::getChildCount() const {  std::unique_ptr<PDBSymbol>  NativeEnumTypes::getChildAtIndex(uint32_t Index) const {    if (Index < Matches.size()) -    return Session.createEnumSymbol(Matches[Index]); +    return Session.getSymbolCache().createEnumSymbol(Matches[Index]);    return nullptr;  } diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp index 35305708a95..59eaf3e8d49 100644 --- a/llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp @@ -15,22 +15,24 @@  #include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"  #include "llvm/DebugInfo/PDB/Native/NativeEnumModules.h"  #include "llvm/DebugInfo/PDB/Native/PDBFile.h" +#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"  #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"  using namespace llvm;  using namespace llvm::pdb; +static DbiStream *getDbiStreamPtr(NativeSession &Session) { +  Expected<DbiStream &> DbiS = Session.getPDBFile().getPDBDbiStream(); +  if (DbiS) +    return &DbiS.get(); + +  consumeError(DbiS.takeError()); +  return nullptr; +} +  NativeExeSymbol::NativeExeSymbol(NativeSession &Session, SymIndexId SymbolId)      : NativeRawSymbol(Session, PDB_SymType::Exe, SymbolId), -      File(Session.getPDBFile()) { -  Expected<DbiStream &> DbiS = File.getPDBDbiStream(); -  if (!DbiS) { -    consumeError(DbiS.takeError()); -    return; -  } -  Dbi = &DbiS.get(); -  Compilands.resize(Dbi->modules().getModuleCount()); -} +      Dbi(getDbiStreamPtr(Session)) {}  std::unique_ptr<NativeRawSymbol> NativeExeSymbol::clone() const {    return llvm::make_unique<NativeExeSymbol>(Session, SymbolId); @@ -44,7 +46,7 @@ NativeExeSymbol::findChildren(PDB_SymType Type) const {      break;    }    case PDB_SymType::Enum: -    return Session.createTypeEnumerator(codeview::LF_ENUM); +    return Session.getSymbolCache().createTypeEnumerator(codeview::LF_ENUM);    default:      break;    } @@ -52,7 +54,7 @@ NativeExeSymbol::findChildren(PDB_SymType Type) const {  }  uint32_t NativeExeSymbol::getAge() const { -  auto IS = File.getPDBInfoStream(); +  auto IS = Session.getPDBFile().getPDBInfoStream();    if (IS)      return IS->getAge();    consumeError(IS.takeError()); @@ -60,11 +62,11 @@ uint32_t NativeExeSymbol::getAge() const {  }  std::string NativeExeSymbol::getSymbolsFileName() const { -  return File.getFilePath(); +  return Session.getPDBFile().getFilePath();  }  codeview::GUID NativeExeSymbol::getGuid() const { -  auto IS = File.getPDBInfoStream(); +  auto IS = Session.getPDBFile().getPDBInfoStream();    if (IS)      return IS->getGuid();    consumeError(IS.takeError()); @@ -72,7 +74,7 @@ codeview::GUID NativeExeSymbol::getGuid() const {  }  bool NativeExeSymbol::hasCTypes() const { -  auto Dbi = File.getPDBDbiStream(); +  auto Dbi = Session.getPDBFile().getPDBDbiStream();    if (Dbi)      return Dbi->hasCTypes();    consumeError(Dbi.takeError()); @@ -80,33 +82,9 @@ bool NativeExeSymbol::hasCTypes() const {  }  bool NativeExeSymbol::hasPrivateSymbols() const { -  auto Dbi = File.getPDBDbiStream(); +  auto Dbi = Session.getPDBFile().getPDBDbiStream();    if (Dbi)      return !Dbi->isStripped();    consumeError(Dbi.takeError());    return false;  } - -uint32_t NativeExeSymbol::getNumCompilands() const { -  if (!Dbi) -    return 0; - -  return Dbi->modules().getModuleCount(); -} - -std::unique_ptr<PDBSymbolCompiland> -NativeExeSymbol::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] = Session.createSymbol<NativeCompilandSymbol>( -        Modules.getModuleDescriptor(Index)); -  } - -  return Session.getConcreteSymbolById<PDBSymbolCompiland>(Compilands[Index]); -} diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp index f3de40811b1..1601b35aa7f 100644 --- a/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp @@ -20,6 +20,7 @@  #include "llvm/DebugInfo/PDB/Native/NativeExeSymbol.h"  #include "llvm/DebugInfo/PDB/Native/PDBFile.h"  #include "llvm/DebugInfo/PDB/Native/RawError.h" +#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"  #include "llvm/DebugInfo/PDB/Native/TpiStream.h"  #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"  #include "llvm/DebugInfo/PDB/PDBSymbolExe.h" @@ -39,34 +40,19 @@ using namespace llvm;  using namespace llvm::msf;  using namespace llvm::pdb; -namespace { -// 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::Int32, PDB_BuiltinType::Int, 4}, -    {codeview::SimpleTypeKind::UInt32, PDB_BuiltinType::UInt, 4}, -    {codeview::SimpleTypeKind::UInt32Long, PDB_BuiltinType::UInt, 4}, -    {codeview::SimpleTypeKind::UInt64Quad, PDB_BuiltinType::UInt, 8}, -    {codeview::SimpleTypeKind::NarrowCharacter, PDB_BuiltinType::Char, 1}, -    {codeview::SimpleTypeKind::SignedCharacter, PDB_BuiltinType::Char, 1}, -    {codeview::SimpleTypeKind::UnsignedCharacter, PDB_BuiltinType::UInt, 1}, -    {codeview::SimpleTypeKind::UInt16Short, PDB_BuiltinType::UInt, 2}, -    {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. -}; -} // namespace +static DbiStream *getDbiStreamPtr(PDBFile &File) { +  Expected<DbiStream &> DbiS = File.getPDBDbiStream(); +  if (DbiS) +    return &DbiS.get(); + +  consumeError(DbiS.takeError()); +  return nullptr; +}  NativeSession::NativeSession(std::unique_ptr<PDBFile> PdbFile,                               std::unique_ptr<BumpPtrAllocator> Allocator) -    : Pdb(std::move(PdbFile)), Allocator(std::move(Allocator)) { -  // Id 0 is reserved for the invalid symbol. -  SymbolCache.push_back(nullptr); -} +    : Pdb(std::move(PdbFile)), Allocator(std::move(Allocator)), +      Cache(*this, getDbiStreamPtr(*Pdb)) {}  NativeSession::~NativeSession() = default; @@ -94,67 +80,6 @@ Error NativeSession::createFromExe(StringRef Path,    return make_error<RawError>(raw_error_code::feature_unsupported);  } -std::unique_ptr<PDBSymbolTypeEnum> -NativeSession::createEnumSymbol(codeview::TypeIndex Index) { -  const auto Id = findSymbolByTypeIndex(Index); -  return PDBSymbol::createAs<PDBSymbolTypeEnum>(*this, *SymbolCache[Id]); -} - -std::unique_ptr<IPDBEnumSymbols> -NativeSession::createTypeEnumerator(codeview::TypeLeafKind Kind) { -  auto Tpi = Pdb->getPDBTpiStream(); -  if (!Tpi) { -    consumeError(Tpi.takeError()); -    return nullptr; -  } -  auto &Types = Tpi->typeCollection(); -  return std::unique_ptr<IPDBEnumSymbols>( -      new NativeEnumTypes(*this, Types, codeview::LF_ENUM)); -} - -SymIndexId NativeSession::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()) { -    // FIXME:  We will eventually need to handle pointers to other simple types, -    // which are still simple types in the world of CodeView TypeIndexes. -    if (Index.getSimpleMode() != codeview::SimpleTypeMode::Direct) -      return 0; -    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; -    SymIndexId Id = SymbolCache.size(); -    SymbolCache.emplace_back( -        llvm::make_unique<NativeBuiltinSymbol>(*this, Id, It->Type, It->Size)); -    TypeIndexToSymbolId[Index] = Id; -    return Id; -  } - -  // We need to instantiate and cache the desired type symbol. -  auto Tpi = Pdb->getPDBTpiStream(); -  if (!Tpi) { -    consumeError(Tpi.takeError()); -    return 0; -  } -  auto &Types = Tpi->typeCollection(); -  const auto &I = Types.getType(Index); -  const auto Id = static_cast<SymIndexId>(SymbolCache.size()); -  // TODO(amccarth):  Make this handle all types, not just LF_ENUMs. -  assert(I.kind() == codeview::LF_ENUM); -  SymbolCache.emplace_back(llvm::make_unique<NativeEnumSymbol>(*this, Id, I)); -  TypeIndexToSymbolId[Index] = Id; -  return Id; -} -  uint64_t NativeSession::getLoadAddress() const { return 0; }  bool NativeSession::setLoadAddress(uint64_t Address) { return false; } @@ -165,10 +90,7 @@ std::unique_ptr<PDBSymbolExe> NativeSession::getGlobalScope() {  std::unique_ptr<PDBSymbol>  NativeSession::getSymbolById(uint32_t SymbolId) const { -  // If the caller has a SymbolId, it'd better be in our SymbolCache. -  return SymbolId < SymbolCache.size() -             ? PDBSymbol::create(*this, *SymbolCache[SymbolId]) -             : nullptr; +  return Cache.getSymbolById(SymbolId);  }  bool NativeSession::addressForVA(uint64_t VA, uint32_t &Section, @@ -278,10 +200,13 @@ NativeSession::getSectionContribs() const {    return nullptr;  } -NativeExeSymbol &NativeSession::getNativeGlobalScope() { -  if (ExeSymbol == 0) { -    ExeSymbol = static_cast<SymIndexId>(SymbolCache.size()); -    SymbolCache.push_back(llvm::make_unique<NativeExeSymbol>(*this, ExeSymbol)); -  } -  return static_cast<NativeExeSymbol &>(*SymbolCache[ExeSymbol]); +void NativeSession::initializeExeSymbol() { +  if (ExeSymbol == 0) +    ExeSymbol = Cache.createSymbol<NativeExeSymbol>(); +} + +NativeExeSymbol &NativeSession::getNativeGlobalScope() const { +  const_cast<NativeSession &>(*this).initializeExeSymbol(); + +  return Cache.getNativeSymbolById<NativeExeSymbol>(ExeSymbol);  } diff --git a/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp b/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp new file mode 100644 index 00000000000..9f8e0209744 --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp @@ -0,0 +1,147 @@ +#include "llvm/DebugInfo/PDB/Native/SymbolCache.h" + +#include "llvm/DebugInfo/PDB/Native/DbiStream.h" +#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h" +#include "llvm/DebugInfo/PDB/Native/NativeEnumSymbol.h" +#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h" +#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h" +#include "llvm/DebugInfo/PDB/Native/NativeSession.h" +#include "llvm/DebugInfo/PDB/Native/PDBFile.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::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::Int32, PDB_BuiltinType::Int, 4}, +    {codeview::SimpleTypeKind::UInt32, PDB_BuiltinType::UInt, 4}, +    {codeview::SimpleTypeKind::UInt32Long, PDB_BuiltinType::UInt, 4}, +    {codeview::SimpleTypeKind::UInt64Quad, PDB_BuiltinType::UInt, 8}, +    {codeview::SimpleTypeKind::NarrowCharacter, PDB_BuiltinType::Char, 1}, +    {codeview::SimpleTypeKind::SignedCharacter, PDB_BuiltinType::Char, 1}, +    {codeview::SimpleTypeKind::UnsignedCharacter, PDB_BuiltinType::UInt, 1}, +    {codeview::SimpleTypeKind::UInt16Short, PDB_BuiltinType::UInt, 2}, +    {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); + +  if (Dbi) +    Compilands.resize(Dbi->modules().getModuleCount()); +} + +std::unique_ptr<PDBSymbolTypeEnum> +SymbolCache::createEnumSymbol(codeview::TypeIndex Index) { +  const auto Id = findSymbolByTypeIndex(Index); +  return PDBSymbol::createAs<PDBSymbolTypeEnum>(Session, *Cache[Id]); +} + +std::unique_ptr<IPDBEnumSymbols> +SymbolCache::createTypeEnumerator(codeview::TypeLeafKind Kind) { +  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, codeview::LF_ENUM)); +} + +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()) { +    // FIXME:  We will eventually need to handle pointers to other simple types, +    // which are still simple types in the world of CodeView TypeIndexes. +    if (Index.getSimpleMode() != codeview::SimpleTypeMode::Direct) +      return 0; +    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; +    SymIndexId Id = Cache.size(); +    Cache.emplace_back(llvm::make_unique<NativeBuiltinSymbol>( +        Session, Id, It->Type, It->Size)); +    TypeIndexToSymbolId[Index] = Id; +    return Id; +  } + +  // 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(); +  const codeview::CVType &CVT = Types.getType(Index); +  // TODO(amccarth):  Make this handle all types, not just LF_ENUMs. +  SymIndexId Id = 0; +  switch (CVT.kind()) { +  case codeview::LF_ENUM: +    Id = createSymbol<NativeEnumSymbol>(CVT); +    break; +  default: +    assert(false && "Unsupported native symbol type!"); +    return 0; +  } +  TypeIndexToSymbolId[Index] = Id; +  return Id; +} + +std::unique_ptr<PDBSymbol> +SymbolCache::getSymbolById(SymIndexId SymbolId) const { +  // If the caller has a SymbolId, it'd better be in our SymbolCache. +  return SymbolId < Cache.size() ? PDBSymbol::create(Session, *Cache[SymbolId]) +                                 : nullptr; +} + +NativeRawSymbol &SymbolCache::getNativeSymbolById(SymIndexId SymbolId) const { +  return *Cache[SymbolId]; +} + +uint32_t SymbolCache::getNumCompilands() const { +  if (!Dbi) +    return 0; + +  return Dbi->modules().getModuleCount(); +} + +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]); +}  | 

