16b6b8c4fSAdrian McCarthy //===- NativeSession.cpp - Native implementation of IPDBSession -*- C++ -*-===// 26b6b8c4fSAdrian McCarthy // 36b6b8c4fSAdrian McCarthy // The LLVM Compiler Infrastructure 46b6b8c4fSAdrian McCarthy // 56b6b8c4fSAdrian McCarthy // This file is distributed under the University of Illinois Open Source 66b6b8c4fSAdrian McCarthy // License. See LICENSE.TXT for details. 76b6b8c4fSAdrian McCarthy // 86b6b8c4fSAdrian McCarthy //===----------------------------------------------------------------------===// 96b6b8c4fSAdrian McCarthy 106b6b8c4fSAdrian McCarthy #include "llvm/DebugInfo/PDB/Native/NativeSession.h" 116b6b8c4fSAdrian McCarthy 126b6b8c4fSAdrian McCarthy #include "llvm/ADT/STLExtras.h" 138d090fc5SAdrian McCarthy #include "llvm/DebugInfo/CodeView/TypeIndex.h" 146b6b8c4fSAdrian McCarthy #include "llvm/DebugInfo/PDB/GenericError.h" 156b6b8c4fSAdrian McCarthy #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" 166b6b8c4fSAdrian McCarthy #include "llvm/DebugInfo/PDB/IPDBSourceFile.h" 178d090fc5SAdrian McCarthy #include "llvm/DebugInfo/PDB/Native/NativeBuiltinSymbol.h" 18bf0afc32SAdrian McCarthy #include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h" 19b41f03e7SAdrian McCarthy #include "llvm/DebugInfo/PDB/Native/NativeEnumSymbol.h" 20b41f03e7SAdrian McCarthy #include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h" 214d93d66dSAdrian McCarthy #include "llvm/DebugInfo/PDB/Native/NativeExeSymbol.h" 226b6b8c4fSAdrian McCarthy #include "llvm/DebugInfo/PDB/Native/PDBFile.h" 236b6b8c4fSAdrian McCarthy #include "llvm/DebugInfo/PDB/Native/RawError.h" 24b41f03e7SAdrian McCarthy #include "llvm/DebugInfo/PDB/Native/TpiStream.h" 256b6b8c4fSAdrian McCarthy #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h" 266b6b8c4fSAdrian McCarthy #include "llvm/DebugInfo/PDB/PDBSymbolExe.h" 27b41f03e7SAdrian McCarthy #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" 286b6b8c4fSAdrian McCarthy #include "llvm/Support/Allocator.h" 29d9dc2829SZachary Turner #include "llvm/Support/BinaryByteStream.h" 306b6b8c4fSAdrian McCarthy #include "llvm/Support/Error.h" 316b6b8c4fSAdrian McCarthy #include "llvm/Support/ErrorOr.h" 326b6b8c4fSAdrian McCarthy #include "llvm/Support/MemoryBuffer.h" 33bf0afc32SAdrian McCarthy 346b6b8c4fSAdrian McCarthy #include <algorithm> 35b41f03e7SAdrian McCarthy #include <cassert> 366b6b8c4fSAdrian McCarthy #include <memory> 37bf0afc32SAdrian McCarthy #include <utility> 386b6b8c4fSAdrian McCarthy 396b6b8c4fSAdrian McCarthy using namespace llvm; 406b6b8c4fSAdrian McCarthy using namespace llvm::msf; 416b6b8c4fSAdrian McCarthy using namespace llvm::pdb; 426b6b8c4fSAdrian McCarthy 438d090fc5SAdrian McCarthy namespace { 448d090fc5SAdrian McCarthy // Maps codeview::SimpleTypeKind of a built-in type to the parameters necessary 458d090fc5SAdrian McCarthy // to instantiate a NativeBuiltinSymbol for that type. 460962cb2eSReid Kleckner static const struct BuiltinTypeEntry { 478d090fc5SAdrian McCarthy codeview::SimpleTypeKind Kind; 488d090fc5SAdrian McCarthy PDB_BuiltinType Type; 498d090fc5SAdrian McCarthy uint32_t Size; 508d090fc5SAdrian McCarthy } BuiltinTypes[] = { 518d090fc5SAdrian McCarthy {codeview::SimpleTypeKind::Int32, PDB_BuiltinType::Int, 4}, 528d090fc5SAdrian McCarthy {codeview::SimpleTypeKind::UInt32, PDB_BuiltinType::UInt, 4}, 538d090fc5SAdrian McCarthy {codeview::SimpleTypeKind::UInt32Long, PDB_BuiltinType::UInt, 4}, 548d090fc5SAdrian McCarthy {codeview::SimpleTypeKind::UInt64Quad, PDB_BuiltinType::UInt, 8}, 558d090fc5SAdrian McCarthy {codeview::SimpleTypeKind::NarrowCharacter, PDB_BuiltinType::Char, 1}, 568d090fc5SAdrian McCarthy {codeview::SimpleTypeKind::SignedCharacter, PDB_BuiltinType::Char, 1}, 578d090fc5SAdrian McCarthy {codeview::SimpleTypeKind::UnsignedCharacter, PDB_BuiltinType::UInt, 1}, 588d090fc5SAdrian McCarthy {codeview::SimpleTypeKind::UInt16Short, PDB_BuiltinType::UInt, 2}, 598d090fc5SAdrian McCarthy {codeview::SimpleTypeKind::Boolean8, PDB_BuiltinType::Bool, 1} 608d090fc5SAdrian McCarthy // This table can be grown as necessary, but these are the only types we've 618d090fc5SAdrian McCarthy // needed so far. 628d090fc5SAdrian McCarthy }; 638d090fc5SAdrian McCarthy } // namespace 648d090fc5SAdrian McCarthy 656b6b8c4fSAdrian McCarthy NativeSession::NativeSession(std::unique_ptr<PDBFile> PdbFile, 666b6b8c4fSAdrian McCarthy std::unique_ptr<BumpPtrAllocator> Allocator) 676b6b8c4fSAdrian McCarthy : Pdb(std::move(PdbFile)), Allocator(std::move(Allocator)) {} 686b6b8c4fSAdrian McCarthy 696b6b8c4fSAdrian McCarthy NativeSession::~NativeSession() = default; 706b6b8c4fSAdrian McCarthy 7175257bc2SPeter Collingbourne Error NativeSession::createFromPdb(std::unique_ptr<MemoryBuffer> Buffer, 726b6b8c4fSAdrian McCarthy std::unique_ptr<IPDBSession> &Session) { 7375257bc2SPeter Collingbourne StringRef Path = Buffer->getBufferIdentifier(); 74695ed56bSZachary Turner auto Stream = llvm::make_unique<MemoryBufferByteStream>( 75695ed56bSZachary Turner std::move(Buffer), llvm::support::little); 766b6b8c4fSAdrian McCarthy 776b6b8c4fSAdrian McCarthy auto Allocator = llvm::make_unique<BumpPtrAllocator>(); 787b327d05SZachary Turner auto File = llvm::make_unique<PDBFile>(Path, std::move(Stream), *Allocator); 796b6b8c4fSAdrian McCarthy if (auto EC = File->parseFileHeaders()) 806b6b8c4fSAdrian McCarthy return EC; 816b6b8c4fSAdrian McCarthy if (auto EC = File->parseStreamData()) 826b6b8c4fSAdrian McCarthy return EC; 836b6b8c4fSAdrian McCarthy 846b6b8c4fSAdrian McCarthy Session = 856b6b8c4fSAdrian McCarthy llvm::make_unique<NativeSession>(std::move(File), std::move(Allocator)); 866b6b8c4fSAdrian McCarthy 876b6b8c4fSAdrian McCarthy return Error::success(); 886b6b8c4fSAdrian McCarthy } 896b6b8c4fSAdrian McCarthy 906b6b8c4fSAdrian McCarthy Error NativeSession::createFromExe(StringRef Path, 916b6b8c4fSAdrian McCarthy std::unique_ptr<IPDBSession> &Session) { 926b6b8c4fSAdrian McCarthy return make_error<RawError>(raw_error_code::feature_unsupported); 936b6b8c4fSAdrian McCarthy } 946b6b8c4fSAdrian McCarthy 95bf0afc32SAdrian McCarthy std::unique_ptr<PDBSymbolCompiland> 96bf0afc32SAdrian McCarthy NativeSession::createCompilandSymbol(DbiModuleDescriptor MI) { 978d090fc5SAdrian McCarthy const auto Id = static_cast<SymIndexId>(SymbolCache.size()); 98bf0afc32SAdrian McCarthy SymbolCache.push_back( 99bf0afc32SAdrian McCarthy llvm::make_unique<NativeCompilandSymbol>(*this, Id, MI)); 100bf0afc32SAdrian McCarthy return llvm::make_unique<PDBSymbolCompiland>( 101bf0afc32SAdrian McCarthy *this, std::unique_ptr<IPDBRawSymbol>(SymbolCache[Id]->clone())); 102bf0afc32SAdrian McCarthy } 103bf0afc32SAdrian McCarthy 104b41f03e7SAdrian McCarthy std::unique_ptr<PDBSymbolTypeEnum> 105b41f03e7SAdrian McCarthy NativeSession::createEnumSymbol(codeview::TypeIndex Index) { 106b41f03e7SAdrian McCarthy const auto Id = findSymbolByTypeIndex(Index); 107b41f03e7SAdrian McCarthy return llvm::make_unique<PDBSymbolTypeEnum>( 108b41f03e7SAdrian McCarthy *this, std::unique_ptr<IPDBRawSymbol>(SymbolCache[Id]->clone())); 109b41f03e7SAdrian McCarthy } 110b41f03e7SAdrian McCarthy 111b41f03e7SAdrian McCarthy std::unique_ptr<IPDBEnumSymbols> 112b41f03e7SAdrian McCarthy NativeSession::createTypeEnumerator(codeview::TypeLeafKind Kind) { 113b41f03e7SAdrian McCarthy auto Tpi = Pdb->getPDBTpiStream(); 114b41f03e7SAdrian McCarthy if (!Tpi) { 115b41f03e7SAdrian McCarthy consumeError(Tpi.takeError()); 116b41f03e7SAdrian McCarthy return nullptr; 117b41f03e7SAdrian McCarthy } 118b41f03e7SAdrian McCarthy auto &Types = Tpi->typeCollection(); 119b41f03e7SAdrian McCarthy return std::unique_ptr<IPDBEnumSymbols>( 120b41f03e7SAdrian McCarthy new NativeEnumTypes(*this, Types, codeview::LF_ENUM)); 121b41f03e7SAdrian McCarthy } 122b41f03e7SAdrian McCarthy 1238d090fc5SAdrian McCarthy SymIndexId NativeSession::findSymbolByTypeIndex(codeview::TypeIndex Index) { 1248d090fc5SAdrian McCarthy // First see if it's already in our cache. 1258d090fc5SAdrian McCarthy const auto Entry = TypeIndexToSymbolId.find(Index); 1268d090fc5SAdrian McCarthy if (Entry != TypeIndexToSymbolId.end()) 1278d090fc5SAdrian McCarthy return Entry->second; 1288d090fc5SAdrian McCarthy 1298d090fc5SAdrian McCarthy // Symbols for built-in types are created on the fly. 1308d090fc5SAdrian McCarthy if (Index.isSimple()) { 1318d090fc5SAdrian McCarthy // FIXME: We will eventually need to handle pointers to other simple types, 1328d090fc5SAdrian McCarthy // which are still simple types in the world of CodeView TypeIndexes. 1338d090fc5SAdrian McCarthy if (Index.getSimpleMode() != codeview::SimpleTypeMode::Direct) 1348d090fc5SAdrian McCarthy return 0; 1358d090fc5SAdrian McCarthy const auto Kind = Index.getSimpleKind(); 1360962cb2eSReid Kleckner const auto It = 1370962cb2eSReid Kleckner std::find_if(std::begin(BuiltinTypes), std::end(BuiltinTypes), 1380962cb2eSReid Kleckner [Kind](const BuiltinTypeEntry &Builtin) { 1390962cb2eSReid Kleckner return Builtin.Kind == Kind; 1400962cb2eSReid Kleckner }); 1418d090fc5SAdrian McCarthy if (It == std::end(BuiltinTypes)) 1428d090fc5SAdrian McCarthy return 0; 1438d090fc5SAdrian McCarthy SymIndexId Id = SymbolCache.size(); 1448d090fc5SAdrian McCarthy SymbolCache.emplace_back( 1450962cb2eSReid Kleckner llvm::make_unique<NativeBuiltinSymbol>(*this, Id, It->Type, It->Size)); 1468d090fc5SAdrian McCarthy TypeIndexToSymbolId[Index] = Id; 1478d090fc5SAdrian McCarthy return Id; 1488d090fc5SAdrian McCarthy } 1498d090fc5SAdrian McCarthy 150b41f03e7SAdrian McCarthy // We need to instantiate and cache the desired type symbol. 151b41f03e7SAdrian McCarthy auto Tpi = Pdb->getPDBTpiStream(); 152b41f03e7SAdrian McCarthy if (!Tpi) { 153b41f03e7SAdrian McCarthy consumeError(Tpi.takeError()); 1548d090fc5SAdrian McCarthy return 0; 1558d090fc5SAdrian McCarthy } 156b41f03e7SAdrian McCarthy auto &Types = Tpi->typeCollection(); 157b41f03e7SAdrian McCarthy const auto &I = Types.getType(Index); 158b41f03e7SAdrian McCarthy const auto Id = static_cast<SymIndexId>(SymbolCache.size()); 159b41f03e7SAdrian McCarthy // TODO(amccarth): Make this handle all types, not just LF_ENUMs. 160b41f03e7SAdrian McCarthy assert(I.kind() == codeview::LF_ENUM); 161b41f03e7SAdrian McCarthy SymbolCache.emplace_back(llvm::make_unique<NativeEnumSymbol>(*this, Id, I)); 162b41f03e7SAdrian McCarthy TypeIndexToSymbolId[Index] = Id; 163b41f03e7SAdrian McCarthy return Id; 164b41f03e7SAdrian McCarthy } 1658d090fc5SAdrian McCarthy 1666b6b8c4fSAdrian McCarthy uint64_t NativeSession::getLoadAddress() const { return 0; } 1676b6b8c4fSAdrian McCarthy 168*89a19ac3SAaron Smith bool NativeSession::setLoadAddress(uint64_t Address) { return false; } 1696b6b8c4fSAdrian McCarthy 1706a4b080aSAdrian McCarthy std::unique_ptr<PDBSymbolExe> NativeSession::getGlobalScope() { 1718d090fc5SAdrian McCarthy const auto Id = static_cast<SymIndexId>(SymbolCache.size()); 172bf0afc32SAdrian McCarthy SymbolCache.push_back(llvm::make_unique<NativeExeSymbol>(*this, Id)); 173bf0afc32SAdrian McCarthy auto RawSymbol = SymbolCache[Id]->clone(); 174649b8e0cSAdrian McCarthy auto PdbSymbol(PDBSymbol::create(*this, std::move(RawSymbol))); 175649b8e0cSAdrian McCarthy std::unique_ptr<PDBSymbolExe> ExeSymbol( 176649b8e0cSAdrian McCarthy static_cast<PDBSymbolExe *>(PdbSymbol.release())); 177649b8e0cSAdrian McCarthy return ExeSymbol; 1786b6b8c4fSAdrian McCarthy } 1796b6b8c4fSAdrian McCarthy 1806b6b8c4fSAdrian McCarthy std::unique_ptr<PDBSymbol> 1816b6b8c4fSAdrian McCarthy NativeSession::getSymbolById(uint32_t SymbolId) const { 182bf0afc32SAdrian McCarthy // If the caller has a SymbolId, it'd better be in our SymbolCache. 183bf0afc32SAdrian McCarthy return SymbolId < SymbolCache.size() 184bf0afc32SAdrian McCarthy ? PDBSymbol::create(*this, SymbolCache[SymbolId]->clone()) 185bf0afc32SAdrian McCarthy : nullptr; 1866b6b8c4fSAdrian McCarthy } 1876b6b8c4fSAdrian McCarthy 1886b6b8c4fSAdrian McCarthy std::unique_ptr<PDBSymbol> 1896b6b8c4fSAdrian McCarthy NativeSession::findSymbolByAddress(uint64_t Address, PDB_SymType Type) const { 1906b6b8c4fSAdrian McCarthy return nullptr; 1916b6b8c4fSAdrian McCarthy } 1926b6b8c4fSAdrian McCarthy 1936b6b8c4fSAdrian McCarthy std::unique_ptr<IPDBEnumLineNumbers> 1946b6b8c4fSAdrian McCarthy NativeSession::findLineNumbers(const PDBSymbolCompiland &Compiland, 1956b6b8c4fSAdrian McCarthy const IPDBSourceFile &File) const { 1966b6b8c4fSAdrian McCarthy return nullptr; 1976b6b8c4fSAdrian McCarthy } 1986b6b8c4fSAdrian McCarthy 1996b6b8c4fSAdrian McCarthy std::unique_ptr<IPDBEnumLineNumbers> 2006b6b8c4fSAdrian McCarthy NativeSession::findLineNumbersByAddress(uint64_t Address, 2016b6b8c4fSAdrian McCarthy uint32_t Length) const { 2026b6b8c4fSAdrian McCarthy return nullptr; 2036b6b8c4fSAdrian McCarthy } 2046b6b8c4fSAdrian McCarthy 2056b6b8c4fSAdrian McCarthy std::unique_ptr<IPDBEnumSourceFiles> 2066b6b8c4fSAdrian McCarthy NativeSession::findSourceFiles(const PDBSymbolCompiland *Compiland, 2076b6b8c4fSAdrian McCarthy StringRef Pattern, 2086b6b8c4fSAdrian McCarthy PDB_NameSearchFlags Flags) const { 2096b6b8c4fSAdrian McCarthy return nullptr; 2106b6b8c4fSAdrian McCarthy } 2116b6b8c4fSAdrian McCarthy 2126b6b8c4fSAdrian McCarthy std::unique_ptr<IPDBSourceFile> 2136b6b8c4fSAdrian McCarthy NativeSession::findOneSourceFile(const PDBSymbolCompiland *Compiland, 2146b6b8c4fSAdrian McCarthy StringRef Pattern, 2156b6b8c4fSAdrian McCarthy PDB_NameSearchFlags Flags) const { 2166b6b8c4fSAdrian McCarthy return nullptr; 2176b6b8c4fSAdrian McCarthy } 2186b6b8c4fSAdrian McCarthy 2196b6b8c4fSAdrian McCarthy std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>> 2206b6b8c4fSAdrian McCarthy NativeSession::findCompilandsForSourceFile(StringRef Pattern, 2216b6b8c4fSAdrian McCarthy PDB_NameSearchFlags Flags) const { 2226b6b8c4fSAdrian McCarthy return nullptr; 2236b6b8c4fSAdrian McCarthy } 2246b6b8c4fSAdrian McCarthy 2256b6b8c4fSAdrian McCarthy std::unique_ptr<PDBSymbolCompiland> 2266b6b8c4fSAdrian McCarthy NativeSession::findOneCompilandForSourceFile(StringRef Pattern, 2276b6b8c4fSAdrian McCarthy PDB_NameSearchFlags Flags) const { 2286b6b8c4fSAdrian McCarthy return nullptr; 2296b6b8c4fSAdrian McCarthy } 2306b6b8c4fSAdrian McCarthy 2316b6b8c4fSAdrian McCarthy std::unique_ptr<IPDBEnumSourceFiles> NativeSession::getAllSourceFiles() const { 2326b6b8c4fSAdrian McCarthy return nullptr; 2336b6b8c4fSAdrian McCarthy } 2346b6b8c4fSAdrian McCarthy 2356b6b8c4fSAdrian McCarthy std::unique_ptr<IPDBEnumSourceFiles> NativeSession::getSourceFilesForCompiland( 2366b6b8c4fSAdrian McCarthy const PDBSymbolCompiland &Compiland) const { 2376b6b8c4fSAdrian McCarthy return nullptr; 2386b6b8c4fSAdrian McCarthy } 2396b6b8c4fSAdrian McCarthy 2406b6b8c4fSAdrian McCarthy std::unique_ptr<IPDBSourceFile> 2416b6b8c4fSAdrian McCarthy NativeSession::getSourceFileById(uint32_t FileId) const { 2426b6b8c4fSAdrian McCarthy return nullptr; 2436b6b8c4fSAdrian McCarthy } 2446b6b8c4fSAdrian McCarthy 2456b6b8c4fSAdrian McCarthy std::unique_ptr<IPDBEnumDataStreams> NativeSession::getDebugStreams() const { 2466b6b8c4fSAdrian McCarthy return nullptr; 2476b6b8c4fSAdrian McCarthy } 24889bca9e5SAaron Smith 24989bca9e5SAaron Smith std::unique_ptr<IPDBEnumTables> NativeSession::getEnumTables() const { 25089bca9e5SAaron Smith return nullptr; 25189bca9e5SAaron Smith } 252