LCOV - code coverage report
Current view: top level - lib/DebugInfo/PDB/Native - NativeSession.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 64 94 68.1 %
Date: 2017-09-14 15:23:50 Functions: 8 22 36.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- NativeSession.cpp - Native implementation of IPDBSession -*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : 
      10             : #include "llvm/DebugInfo/PDB/Native/NativeSession.h"
      11             : 
      12             : #include "llvm/ADT/STLExtras.h"
      13             : #include "llvm/DebugInfo/CodeView/TypeIndex.h"
      14             : #include "llvm/DebugInfo/PDB/GenericError.h"
      15             : #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
      16             : #include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
      17             : #include "llvm/DebugInfo/PDB/Native/NativeBuiltinSymbol.h"
      18             : #include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
      19             : #include "llvm/DebugInfo/PDB/Native/NativeEnumSymbol.h"
      20             : #include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
      21             : #include "llvm/DebugInfo/PDB/Native/NativeExeSymbol.h"
      22             : #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
      23             : #include "llvm/DebugInfo/PDB/Native/RawError.h"
      24             : #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
      25             : #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
      26             : #include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
      27             : #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
      28             : #include "llvm/Support/Allocator.h"
      29             : #include "llvm/Support/BinaryByteStream.h"
      30             : #include "llvm/Support/Error.h"
      31             : #include "llvm/Support/ErrorOr.h"
      32             : #include "llvm/Support/MemoryBuffer.h"
      33             : 
      34             : #include <algorithm>
      35             : #include <cassert>
      36             : #include <memory>
      37             : #include <utility>
      38             : 
      39             : using namespace llvm;
      40             : using namespace llvm::msf;
      41             : using namespace llvm::pdb;
      42             : 
      43             : namespace {
      44             : // Maps codeview::SimpleTypeKind of a built-in type to the parameters necessary
      45             : // to instantiate a NativeBuiltinSymbol for that type.
      46             : static const struct BuiltinTypeEntry {
      47             :   codeview::SimpleTypeKind Kind;
      48             :   PDB_BuiltinType Type;
      49             :   uint32_t Size;
      50             : } BuiltinTypes[] = {
      51             :     {codeview::SimpleTypeKind::Int32, PDB_BuiltinType::Int, 4},
      52             :     {codeview::SimpleTypeKind::UInt32, PDB_BuiltinType::UInt, 4},
      53             :     {codeview::SimpleTypeKind::UInt32Long, PDB_BuiltinType::UInt, 4},
      54             :     {codeview::SimpleTypeKind::UInt64Quad, PDB_BuiltinType::UInt, 8},
      55             :     {codeview::SimpleTypeKind::NarrowCharacter, PDB_BuiltinType::Char, 1},
      56             :     {codeview::SimpleTypeKind::SignedCharacter, PDB_BuiltinType::Char, 1},
      57             :     {codeview::SimpleTypeKind::UnsignedCharacter, PDB_BuiltinType::UInt, 1},
      58             :     {codeview::SimpleTypeKind::UInt16Short, PDB_BuiltinType::UInt, 2},
      59             :     {codeview::SimpleTypeKind::Boolean8, PDB_BuiltinType::Bool, 1}
      60             :     // This table can be grown as necessary, but these are the only types we've
      61             :     // needed so far.
      62             : };
      63             : } // namespace
      64             : 
      65          97 : NativeSession::NativeSession(std::unique_ptr<PDBFile> PdbFile,
      66          97 :                              std::unique_ptr<BumpPtrAllocator> Allocator)
      67         485 :     : Pdb(std::move(PdbFile)), Allocator(std::move(Allocator)) {}
      68             : 
      69             : NativeSession::~NativeSession() = default;
      70             : 
      71          99 : Error NativeSession::createFromPdb(StringRef Path,
      72             :                                    std::unique_ptr<IPDBSession> &Session) {
      73             :   ErrorOr<std::unique_ptr<MemoryBuffer>> ErrorOrBuffer =
      74             :       MemoryBuffer::getFileOrSTDIN(Path, /*FileSize=*/-1,
      75         198 :                                    /*RequiresNullTerminator=*/false);
      76          99 :   if (!ErrorOrBuffer)
      77           1 :     return make_error<GenericError>(generic_error_code::invalid_path);
      78             : 
      79         196 :   std::unique_ptr<MemoryBuffer> Buffer = std::move(*ErrorOrBuffer);
      80             :   auto Stream = llvm::make_unique<MemoryBufferByteStream>(
      81         196 :       std::move(Buffer), llvm::support::little);
      82             : 
      83         196 :   auto Allocator = llvm::make_unique<BumpPtrAllocator>();
      84         196 :   auto File = llvm::make_unique<PDBFile>(Path, std::move(Stream), *Allocator);
      85         293 :   if (auto EC = File->parseFileHeaders())
      86           2 :     return EC;
      87         291 :   if (auto EC = File->parseStreamData())
      88           0 :     return EC;
      89             : 
      90          97 :   Session =
      91         194 :       llvm::make_unique<NativeSession>(std::move(File), std::move(Allocator));
      92             : 
      93         291 :   return Error::success();
      94             : }
      95             : 
      96           0 : Error NativeSession::createFromExe(StringRef Path,
      97             :                                    std::unique_ptr<IPDBSession> &Session) {
      98           0 :   return make_error<RawError>(raw_error_code::feature_unsupported);
      99             : }
     100             : 
     101             : std::unique_ptr<PDBSymbolCompiland>
     102          50 : NativeSession::createCompilandSymbol(DbiModuleDescriptor MI) {
     103         100 :   const auto Id = static_cast<SymIndexId>(SymbolCache.size());
     104         200 :   SymbolCache.push_back(
     105         100 :       llvm::make_unique<NativeCompilandSymbol>(*this, Id, MI));
     106             :   return llvm::make_unique<PDBSymbolCompiland>(
     107         300 :       *this, std::unique_ptr<IPDBRawSymbol>(SymbolCache[Id]->clone()));
     108             : }
     109             : 
     110             : std::unique_ptr<PDBSymbolTypeEnum>
     111           9 : NativeSession::createEnumSymbol(codeview::TypeIndex Index) {
     112           9 :   const auto Id = findSymbolByTypeIndex(Index);
     113             :   return llvm::make_unique<PDBSymbolTypeEnum>(
     114          54 :       *this, std::unique_ptr<IPDBRawSymbol>(SymbolCache[Id]->clone()));
     115             : }
     116             : 
     117             : std::unique_ptr<IPDBEnumSymbols>
     118           1 : NativeSession::createTypeEnumerator(codeview::TypeLeafKind Kind) {
     119           3 :   auto Tpi = Pdb->getPDBTpiStream();
     120           1 :   if (!Tpi) {
     121           0 :     consumeError(Tpi.takeError());
     122             :     return nullptr;
     123             :   }
     124           2 :   auto &Types = Tpi->typeCollection();
     125             :   return std::unique_ptr<IPDBEnumSymbols>(
     126           1 :       new NativeEnumTypes(*this, Types, codeview::LF_ENUM));
     127             : }
     128             : 
     129          27 : SymIndexId NativeSession::findSymbolByTypeIndex(codeview::TypeIndex Index) {
     130             :   // First see if it's already in our cache.
     131          27 :   const auto Entry = TypeIndexToSymbolId.find(Index);
     132          81 :   if (Entry != TypeIndexToSymbolId.end())
     133          17 :     return Entry->second;
     134             : 
     135             :   // Symbols for built-in types are created on the fly.
     136          10 :   if (Index.isSimple()) {
     137             :     // FIXME:  We will eventually need to handle pointers to other simple types,
     138             :     // which are still simple types in the world of CodeView TypeIndexes.
     139           1 :     if (Index.getSimpleMode() != codeview::SimpleTypeMode::Direct)
     140             :       return 0;
     141           1 :     const auto Kind = Index.getSimpleKind();
     142             :     const auto It =
     143           1 :         std::find_if(std::begin(BuiltinTypes), std::end(BuiltinTypes),
     144             :                      [Kind](const BuiltinTypeEntry &Builtin) {
     145             :                        return Builtin.Kind == Kind;
     146           1 :                      });
     147           1 :     if (It == std::end(BuiltinTypes))
     148             :       return 0;
     149           2 :     SymIndexId Id = SymbolCache.size();
     150           2 :     SymbolCache.emplace_back(
     151           3 :         llvm::make_unique<NativeBuiltinSymbol>(*this, Id, It->Type, It->Size));
     152           2 :     TypeIndexToSymbolId[Index] = Id;
     153           1 :     return Id;
     154             :   }
     155             : 
     156             :   // We need to instantiate and cache the desired type symbol.
     157          18 :   auto Tpi = Pdb->getPDBTpiStream();
     158           9 :   if (!Tpi) {
     159           0 :     consumeError(Tpi.takeError());
     160           0 :     return 0;
     161             :   }
     162          18 :   auto &Types = Tpi->typeCollection();
     163           9 :   const auto &I = Types.getType(Index);
     164          18 :   const auto Id = static_cast<SymIndexId>(SymbolCache.size());
     165             :   // TODO(amccarth):  Make this handle all types, not just LF_ENUMs.
     166             :   assert(I.kind() == codeview::LF_ENUM);
     167          27 :   SymbolCache.emplace_back(llvm::make_unique<NativeEnumSymbol>(*this, Id, I));
     168          18 :   TypeIndexToSymbolId[Index] = Id;
     169           9 :   return Id;
     170             : }
     171             : 
     172           0 : uint64_t NativeSession::getLoadAddress() const { return 0; }
     173             : 
     174           0 : void NativeSession::setLoadAddress(uint64_t Address) {}
     175             : 
     176           4 : std::unique_ptr<PDBSymbolExe> NativeSession::getGlobalScope() {
     177           8 :   const auto Id = static_cast<SymIndexId>(SymbolCache.size());
     178          24 :   SymbolCache.push_back(llvm::make_unique<NativeExeSymbol>(*this, Id));
     179          16 :   auto RawSymbol = SymbolCache[Id]->clone();
     180          16 :   auto PdbSymbol(PDBSymbol::create(*this, std::move(RawSymbol)));
     181             :   std::unique_ptr<PDBSymbolExe> ExeSymbol(
     182           8 :       static_cast<PDBSymbolExe *>(PdbSymbol.release()));
     183           4 :   return ExeSymbol;
     184             : }
     185             : 
     186             : std::unique_ptr<PDBSymbol>
     187          27 : NativeSession::getSymbolById(uint32_t SymbolId) const {
     188             :   // If the caller has a SymbolId, it'd better be in our SymbolCache.
     189          27 :   return SymbolId < SymbolCache.size()
     190         108 :              ? PDBSymbol::create(*this, SymbolCache[SymbolId]->clone())
     191         117 :              : nullptr;
     192             : }
     193             : 
     194             : std::unique_ptr<PDBSymbol>
     195           0 : NativeSession::findSymbolByAddress(uint64_t Address, PDB_SymType Type) const {
     196           0 :   return nullptr;
     197             : }
     198             : 
     199             : std::unique_ptr<IPDBEnumLineNumbers>
     200           0 : NativeSession::findLineNumbers(const PDBSymbolCompiland &Compiland,
     201             :                                const IPDBSourceFile &File) const {
     202           0 :   return nullptr;
     203             : }
     204             : 
     205             : std::unique_ptr<IPDBEnumLineNumbers>
     206           0 : NativeSession::findLineNumbersByAddress(uint64_t Address,
     207             :                                         uint32_t Length) const {
     208           0 :   return nullptr;
     209             : }
     210             : 
     211             : std::unique_ptr<IPDBEnumSourceFiles>
     212           0 : NativeSession::findSourceFiles(const PDBSymbolCompiland *Compiland,
     213             :                                StringRef Pattern,
     214             :                                PDB_NameSearchFlags Flags) const {
     215           0 :   return nullptr;
     216             : }
     217             : 
     218             : std::unique_ptr<IPDBSourceFile>
     219           0 : NativeSession::findOneSourceFile(const PDBSymbolCompiland *Compiland,
     220             :                                  StringRef Pattern,
     221             :                                  PDB_NameSearchFlags Flags) const {
     222           0 :   return nullptr;
     223             : }
     224             : 
     225             : std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
     226           0 : NativeSession::findCompilandsForSourceFile(StringRef Pattern,
     227             :                                            PDB_NameSearchFlags Flags) const {
     228           0 :   return nullptr;
     229             : }
     230             : 
     231             : std::unique_ptr<PDBSymbolCompiland>
     232           0 : NativeSession::findOneCompilandForSourceFile(StringRef Pattern,
     233             :                                              PDB_NameSearchFlags Flags) const {
     234           0 :   return nullptr;
     235             : }
     236             : 
     237           0 : std::unique_ptr<IPDBEnumSourceFiles> NativeSession::getAllSourceFiles() const {
     238           0 :   return nullptr;
     239             : }
     240             : 
     241           0 : std::unique_ptr<IPDBEnumSourceFiles> NativeSession::getSourceFilesForCompiland(
     242             :     const PDBSymbolCompiland &Compiland) const {
     243           0 :   return nullptr;
     244             : }
     245             : 
     246             : std::unique_ptr<IPDBSourceFile>
     247           0 : NativeSession::getSourceFileById(uint32_t FileId) const {
     248           0 :   return nullptr;
     249             : }
     250             : 
     251           0 : std::unique_ptr<IPDBEnumDataStreams> NativeSession::getDebugStreams() const {
     252           0 :   return nullptr;
     253             : }

Generated by: LCOV version 1.13