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/PDB/GenericError.h"
14 #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
15 #include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
16 #include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
17 #include "llvm/DebugInfo/PDB/Native/NativeExeSymbol.h"
18 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
19 #include "llvm/DebugInfo/PDB/Native/RawError.h"
20 #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
21 #include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
22 #include "llvm/Support/Allocator.h"
23 #include "llvm/Support/BinaryByteStream.h"
24 #include "llvm/Support/Error.h"
25 #include "llvm/Support/ErrorOr.h"
26 #include "llvm/Support/MemoryBuffer.h"
27 
28 #include <algorithm>
29 #include <memory>
30 #include <utility>
31 
32 using namespace llvm;
33 using namespace llvm::msf;
34 using namespace llvm::pdb;
35 
36 NativeSession::NativeSession(std::unique_ptr<PDBFile> PdbFile,
37                              std::unique_ptr<BumpPtrAllocator> Allocator)
38     : Pdb(std::move(PdbFile)), Allocator(std::move(Allocator)) {}
39 
40 NativeSession::~NativeSession() = default;
41 
42 Error NativeSession::createFromPdb(StringRef Path,
43                                    std::unique_ptr<IPDBSession> &Session) {
44   ErrorOr<std::unique_ptr<MemoryBuffer>> ErrorOrBuffer =
45       MemoryBuffer::getFileOrSTDIN(Path, /*FileSize=*/-1,
46                                    /*RequiresNullTerminator=*/false);
47   if (!ErrorOrBuffer)
48     return make_error<GenericError>(generic_error_code::invalid_path);
49 
50   std::unique_ptr<MemoryBuffer> Buffer = std::move(*ErrorOrBuffer);
51   auto Stream = llvm::make_unique<MemoryBufferByteStream>(
52       std::move(Buffer), llvm::support::little);
53 
54   auto Allocator = llvm::make_unique<BumpPtrAllocator>();
55   auto File = llvm::make_unique<PDBFile>(Path, std::move(Stream), *Allocator);
56   if (auto EC = File->parseFileHeaders())
57     return EC;
58   if (auto EC = File->parseStreamData())
59     return EC;
60 
61   Session =
62       llvm::make_unique<NativeSession>(std::move(File), std::move(Allocator));
63 
64   return Error::success();
65 }
66 
67 Error NativeSession::createFromExe(StringRef Path,
68                                    std::unique_ptr<IPDBSession> &Session) {
69   return make_error<RawError>(raw_error_code::feature_unsupported);
70 }
71 
72 std::unique_ptr<PDBSymbolCompiland>
73 NativeSession::createCompilandSymbol(DbiModuleDescriptor MI) {
74   const auto Id = static_cast<uint32_t>(SymbolCache.size());
75   SymbolCache.push_back(
76       llvm::make_unique<NativeCompilandSymbol>(*this, Id, MI));
77   return llvm::make_unique<PDBSymbolCompiland>(
78       *this, std::unique_ptr<IPDBRawSymbol>(SymbolCache[Id]->clone()));
79 }
80 
81 uint64_t NativeSession::getLoadAddress() const { return 0; }
82 
83 void NativeSession::setLoadAddress(uint64_t Address) {}
84 
85 std::unique_ptr<PDBSymbolExe> NativeSession::getGlobalScope() {
86   const auto Id = static_cast<uint32_t>(SymbolCache.size());
87   SymbolCache.push_back(llvm::make_unique<NativeExeSymbol>(*this, Id));
88   auto RawSymbol = SymbolCache[Id]->clone();
89   auto PdbSymbol(PDBSymbol::create(*this, std::move(RawSymbol)));
90   std::unique_ptr<PDBSymbolExe> ExeSymbol(
91       static_cast<PDBSymbolExe *>(PdbSymbol.release()));
92   return ExeSymbol;
93 }
94 
95 std::unique_ptr<PDBSymbol>
96 NativeSession::getSymbolById(uint32_t SymbolId) const {
97   // If the caller has a SymbolId, it'd better be in our SymbolCache.
98   return SymbolId < SymbolCache.size()
99              ? PDBSymbol::create(*this, SymbolCache[SymbolId]->clone())
100              : nullptr;
101 }
102 
103 std::unique_ptr<PDBSymbol>
104 NativeSession::findSymbolByAddress(uint64_t Address, PDB_SymType Type) const {
105   return nullptr;
106 }
107 
108 std::unique_ptr<IPDBEnumLineNumbers>
109 NativeSession::findLineNumbers(const PDBSymbolCompiland &Compiland,
110                                const IPDBSourceFile &File) const {
111   return nullptr;
112 }
113 
114 std::unique_ptr<IPDBEnumLineNumbers>
115 NativeSession::findLineNumbersByAddress(uint64_t Address,
116                                         uint32_t Length) const {
117   return nullptr;
118 }
119 
120 std::unique_ptr<IPDBEnumSourceFiles>
121 NativeSession::findSourceFiles(const PDBSymbolCompiland *Compiland,
122                                StringRef Pattern,
123                                PDB_NameSearchFlags Flags) const {
124   return nullptr;
125 }
126 
127 std::unique_ptr<IPDBSourceFile>
128 NativeSession::findOneSourceFile(const PDBSymbolCompiland *Compiland,
129                                  StringRef Pattern,
130                                  PDB_NameSearchFlags Flags) const {
131   return nullptr;
132 }
133 
134 std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
135 NativeSession::findCompilandsForSourceFile(StringRef Pattern,
136                                            PDB_NameSearchFlags Flags) const {
137   return nullptr;
138 }
139 
140 std::unique_ptr<PDBSymbolCompiland>
141 NativeSession::findOneCompilandForSourceFile(StringRef Pattern,
142                                              PDB_NameSearchFlags Flags) const {
143   return nullptr;
144 }
145 
146 std::unique_ptr<IPDBEnumSourceFiles> NativeSession::getAllSourceFiles() const {
147   return nullptr;
148 }
149 
150 std::unique_ptr<IPDBEnumSourceFiles> NativeSession::getSourceFilesForCompiland(
151     const PDBSymbolCompiland &Compiland) const {
152   return nullptr;
153 }
154 
155 std::unique_ptr<IPDBSourceFile>
156 NativeSession::getSourceFileById(uint32_t FileId) const {
157   return nullptr;
158 }
159 
160 std::unique_ptr<IPDBEnumDataStreams> NativeSession::getDebugStreams() const {
161   return nullptr;
162 }
163