171d5a254SDimitry Andric //===- NativeSession.cpp - Native implementation of IPDBSession -*- C++ -*-===//
271d5a254SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
671d5a254SDimitry Andric //
771d5a254SDimitry Andric //===----------------------------------------------------------------------===//
871d5a254SDimitry Andric
971d5a254SDimitry Andric #include "llvm/DebugInfo/PDB/Native/NativeSession.h"
1071d5a254SDimitry Andric
117fa27ce4SDimitry Andric #include "llvm/ADT/SmallString.h"
12145449b1SDimitry Andric #include "llvm/BinaryFormat/Magic.h"
13145449b1SDimitry Andric #include "llvm/DebugInfo/MSF/MSFCommon.h"
14145449b1SDimitry Andric #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
1571d5a254SDimitry Andric #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
1671d5a254SDimitry Andric #include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
17145449b1SDimitry Andric #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
18145449b1SDimitry Andric #include "llvm/DebugInfo/PDB/Native/DbiModuleList.h"
19cfca06d7SDimitry Andric #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
20b60736ecSDimitry Andric #include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h"
21145449b1SDimitry Andric #include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
22e6d15924SDimitry Andric #include "llvm/DebugInfo/PDB/Native/NativeEnumInjectedSources.h"
2371d5a254SDimitry Andric #include "llvm/DebugInfo/PDB/Native/NativeExeSymbol.h"
2471d5a254SDimitry Andric #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
25145449b1SDimitry Andric #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
2671d5a254SDimitry Andric #include "llvm/DebugInfo/PDB/Native/RawError.h"
27145449b1SDimitry Andric #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
28d8e91e46SDimitry Andric #include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
29145449b1SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbol.h"
3071d5a254SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
3171d5a254SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
32145449b1SDimitry Andric #include "llvm/Object/Binary.h"
33cfca06d7SDimitry Andric #include "llvm/Object/COFF.h"
3471d5a254SDimitry Andric #include "llvm/Support/Allocator.h"
3571d5a254SDimitry Andric #include "llvm/Support/BinaryByteStream.h"
36145449b1SDimitry Andric #include "llvm/Support/BinaryStreamArray.h"
3771d5a254SDimitry Andric #include "llvm/Support/Error.h"
3871d5a254SDimitry Andric #include "llvm/Support/ErrorOr.h"
3971d5a254SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
40cfca06d7SDimitry Andric #include "llvm/Support/Path.h"
419df3605dSDimitry Andric
4271d5a254SDimitry Andric #include <algorithm>
43044eb2f6SDimitry Andric #include <cassert>
4471d5a254SDimitry Andric #include <memory>
459df3605dSDimitry Andric #include <utility>
4671d5a254SDimitry Andric
4771d5a254SDimitry Andric using namespace llvm;
4871d5a254SDimitry Andric using namespace llvm::msf;
4971d5a254SDimitry Andric using namespace llvm::pdb;
5071d5a254SDimitry Andric
51145449b1SDimitry Andric namespace llvm {
52145449b1SDimitry Andric namespace codeview {
53145449b1SDimitry Andric union DebugInfo;
54145449b1SDimitry Andric }
55145449b1SDimitry Andric } // namespace llvm
56145449b1SDimitry Andric
getDbiStreamPtr(PDBFile & File)57d8e91e46SDimitry Andric static DbiStream *getDbiStreamPtr(PDBFile &File) {
58d8e91e46SDimitry Andric Expected<DbiStream &> DbiS = File.getPDBDbiStream();
59d8e91e46SDimitry Andric if (DbiS)
60d8e91e46SDimitry Andric return &DbiS.get();
61d8e91e46SDimitry Andric
62d8e91e46SDimitry Andric consumeError(DbiS.takeError());
63d8e91e46SDimitry Andric return nullptr;
64d8e91e46SDimitry Andric }
65ca089b24SDimitry Andric
NativeSession(std::unique_ptr<PDBFile> PdbFile,std::unique_ptr<BumpPtrAllocator> Allocator)6671d5a254SDimitry Andric NativeSession::NativeSession(std::unique_ptr<PDBFile> PdbFile,
6771d5a254SDimitry Andric std::unique_ptr<BumpPtrAllocator> Allocator)
68d8e91e46SDimitry Andric : Pdb(std::move(PdbFile)), Allocator(std::move(Allocator)),
69b60736ecSDimitry Andric Cache(*this, getDbiStreamPtr(*Pdb)), AddrToModuleIndex(IMapAllocator) {}
7071d5a254SDimitry Andric
7171d5a254SDimitry Andric NativeSession::~NativeSession() = default;
7271d5a254SDimitry Andric
createFromPdb(std::unique_ptr<MemoryBuffer> Buffer,std::unique_ptr<IPDBSession> & Session)73044eb2f6SDimitry Andric Error NativeSession::createFromPdb(std::unique_ptr<MemoryBuffer> Buffer,
7471d5a254SDimitry Andric std::unique_ptr<IPDBSession> &Session) {
75044eb2f6SDimitry Andric StringRef Path = Buffer->getBufferIdentifier();
761d5ae102SDimitry Andric auto Stream = std::make_unique<MemoryBufferByteStream>(
77b1c73532SDimitry Andric std::move(Buffer), llvm::endianness::little);
7871d5a254SDimitry Andric
791d5ae102SDimitry Andric auto Allocator = std::make_unique<BumpPtrAllocator>();
801d5ae102SDimitry Andric auto File = std::make_unique<PDBFile>(Path, std::move(Stream), *Allocator);
8171d5a254SDimitry Andric if (auto EC = File->parseFileHeaders())
8271d5a254SDimitry Andric return EC;
8371d5a254SDimitry Andric if (auto EC = File->parseStreamData())
8471d5a254SDimitry Andric return EC;
8571d5a254SDimitry Andric
8671d5a254SDimitry Andric Session =
871d5ae102SDimitry Andric std::make_unique<NativeSession>(std::move(File), std::move(Allocator));
8871d5a254SDimitry Andric
8971d5a254SDimitry Andric return Error::success();
9071d5a254SDimitry Andric }
9171d5a254SDimitry Andric
92cfca06d7SDimitry Andric static Expected<std::unique_ptr<PDBFile>>
loadPdbFile(StringRef PdbPath,std::unique_ptr<BumpPtrAllocator> & Allocator)93cfca06d7SDimitry Andric loadPdbFile(StringRef PdbPath, std::unique_ptr<BumpPtrAllocator> &Allocator) {
94cfca06d7SDimitry Andric ErrorOr<std::unique_ptr<MemoryBuffer>> ErrorOrBuffer =
95344a3780SDimitry Andric MemoryBuffer::getFile(PdbPath, /*IsText=*/false,
96cfca06d7SDimitry Andric /*RequiresNullTerminator=*/false);
97cfca06d7SDimitry Andric if (!ErrorOrBuffer)
98cfca06d7SDimitry Andric return make_error<RawError>(ErrorOrBuffer.getError());
99cfca06d7SDimitry Andric std::unique_ptr<llvm::MemoryBuffer> Buffer = std::move(*ErrorOrBuffer);
100cfca06d7SDimitry Andric
101cfca06d7SDimitry Andric PdbPath = Buffer->getBufferIdentifier();
102cfca06d7SDimitry Andric file_magic Magic;
103cfca06d7SDimitry Andric auto EC = identify_magic(PdbPath, Magic);
104cfca06d7SDimitry Andric if (EC || Magic != file_magic::pdb)
105cfca06d7SDimitry Andric return make_error<RawError>(EC);
106cfca06d7SDimitry Andric
107b1c73532SDimitry Andric auto Stream = std::make_unique<MemoryBufferByteStream>(
108b1c73532SDimitry Andric std::move(Buffer), llvm::endianness::little);
109cfca06d7SDimitry Andric
110cfca06d7SDimitry Andric auto File = std::make_unique<PDBFile>(PdbPath, std::move(Stream), *Allocator);
111cfca06d7SDimitry Andric if (auto EC = File->parseFileHeaders())
112cfca06d7SDimitry Andric return std::move(EC);
113cfca06d7SDimitry Andric
114cfca06d7SDimitry Andric if (auto EC = File->parseStreamData())
115cfca06d7SDimitry Andric return std::move(EC);
116cfca06d7SDimitry Andric
117cfca06d7SDimitry Andric return std::move(File);
11871d5a254SDimitry Andric }
11971d5a254SDimitry Andric
createFromPdbPath(StringRef PdbPath,std::unique_ptr<IPDBSession> & Session)120cfca06d7SDimitry Andric Error NativeSession::createFromPdbPath(StringRef PdbPath,
121cfca06d7SDimitry Andric std::unique_ptr<IPDBSession> &Session) {
122cfca06d7SDimitry Andric auto Allocator = std::make_unique<BumpPtrAllocator>();
123cfca06d7SDimitry Andric auto PdbFile = loadPdbFile(PdbPath, Allocator);
124cfca06d7SDimitry Andric if (!PdbFile)
125cfca06d7SDimitry Andric return PdbFile.takeError();
12671d5a254SDimitry Andric
127cfca06d7SDimitry Andric Session = std::make_unique<NativeSession>(std::move(PdbFile.get()),
128cfca06d7SDimitry Andric std::move(Allocator));
129cfca06d7SDimitry Andric return Error::success();
130cfca06d7SDimitry Andric }
131cfca06d7SDimitry Andric
getPdbPathFromExe(StringRef ExePath)132cfca06d7SDimitry Andric static Expected<std::string> getPdbPathFromExe(StringRef ExePath) {
133cfca06d7SDimitry Andric Expected<object::OwningBinary<object::Binary>> BinaryFile =
134cfca06d7SDimitry Andric object::createBinary(ExePath);
135cfca06d7SDimitry Andric if (!BinaryFile)
136cfca06d7SDimitry Andric return BinaryFile.takeError();
137cfca06d7SDimitry Andric
138cfca06d7SDimitry Andric const object::COFFObjectFile *ObjFile =
139cfca06d7SDimitry Andric dyn_cast<object::COFFObjectFile>(BinaryFile->getBinary());
140cfca06d7SDimitry Andric if (!ObjFile)
141cfca06d7SDimitry Andric return make_error<RawError>(raw_error_code::invalid_format);
142cfca06d7SDimitry Andric
143cfca06d7SDimitry Andric StringRef PdbPath;
144cfca06d7SDimitry Andric const llvm::codeview::DebugInfo *PdbInfo = nullptr;
145cfca06d7SDimitry Andric if (Error E = ObjFile->getDebugPDBInfo(PdbInfo, PdbPath))
146cfca06d7SDimitry Andric return std::move(E);
147cfca06d7SDimitry Andric
148cfca06d7SDimitry Andric return std::string(PdbPath);
149cfca06d7SDimitry Andric }
150cfca06d7SDimitry Andric
createFromExe(StringRef ExePath,std::unique_ptr<IPDBSession> & Session)151cfca06d7SDimitry Andric Error NativeSession::createFromExe(StringRef ExePath,
152cfca06d7SDimitry Andric std::unique_ptr<IPDBSession> &Session) {
153cfca06d7SDimitry Andric Expected<std::string> PdbPath = getPdbPathFromExe(ExePath);
154cfca06d7SDimitry Andric if (!PdbPath)
155cfca06d7SDimitry Andric return PdbPath.takeError();
156cfca06d7SDimitry Andric
157cfca06d7SDimitry Andric file_magic Magic;
158cfca06d7SDimitry Andric auto EC = identify_magic(PdbPath.get(), Magic);
159cfca06d7SDimitry Andric if (EC || Magic != file_magic::pdb)
160cfca06d7SDimitry Andric return make_error<RawError>(EC);
161cfca06d7SDimitry Andric
162cfca06d7SDimitry Andric auto Allocator = std::make_unique<BumpPtrAllocator>();
163cfca06d7SDimitry Andric auto File = loadPdbFile(PdbPath.get(), Allocator);
164cfca06d7SDimitry Andric if (!File)
165cfca06d7SDimitry Andric return File.takeError();
166cfca06d7SDimitry Andric
167cfca06d7SDimitry Andric Session = std::make_unique<NativeSession>(std::move(File.get()),
168cfca06d7SDimitry Andric std::move(Allocator));
169cfca06d7SDimitry Andric
170cfca06d7SDimitry Andric return Error::success();
171cfca06d7SDimitry Andric }
172cfca06d7SDimitry Andric
173cfca06d7SDimitry Andric Expected<std::string>
searchForPdb(const PdbSearchOptions & Opts)174cfca06d7SDimitry Andric NativeSession::searchForPdb(const PdbSearchOptions &Opts) {
175cfca06d7SDimitry Andric Expected<std::string> PathOrErr = getPdbPathFromExe(Opts.ExePath);
176cfca06d7SDimitry Andric if (!PathOrErr)
177cfca06d7SDimitry Andric return PathOrErr.takeError();
178cfca06d7SDimitry Andric StringRef PathFromExe = PathOrErr.get();
179b1c73532SDimitry Andric sys::path::Style Style = PathFromExe.starts_with("/")
180cfca06d7SDimitry Andric ? sys::path::Style::posix
181cfca06d7SDimitry Andric : sys::path::Style::windows;
182cfca06d7SDimitry Andric StringRef PdbName = sys::path::filename(PathFromExe, Style);
183cfca06d7SDimitry Andric
184cfca06d7SDimitry Andric // Check if pdb exists in the executable directory.
185cfca06d7SDimitry Andric SmallString<128> PdbPath = StringRef(Opts.ExePath);
186cfca06d7SDimitry Andric sys::path::remove_filename(PdbPath);
187cfca06d7SDimitry Andric sys::path::append(PdbPath, PdbName);
188cfca06d7SDimitry Andric
189cfca06d7SDimitry Andric auto Allocator = std::make_unique<BumpPtrAllocator>();
190cfca06d7SDimitry Andric
191cfca06d7SDimitry Andric if (auto File = loadPdbFile(PdbPath, Allocator))
192cfca06d7SDimitry Andric return std::string(PdbPath);
193cfca06d7SDimitry Andric else
194cfca06d7SDimitry Andric consumeError(File.takeError());
195cfca06d7SDimitry Andric
196cfca06d7SDimitry Andric // Check path that was in the executable.
197cfca06d7SDimitry Andric if (auto File = loadPdbFile(PathFromExe, Allocator))
198cfca06d7SDimitry Andric return std::string(PathFromExe);
199cfca06d7SDimitry Andric else
200cfca06d7SDimitry Andric return File.takeError();
201cfca06d7SDimitry Andric
202cfca06d7SDimitry Andric return make_error<RawError>("PDB not found");
203cfca06d7SDimitry Andric }
204cfca06d7SDimitry Andric
getLoadAddress() const205cfca06d7SDimitry Andric uint64_t NativeSession::getLoadAddress() const { return LoadAddress; }
206cfca06d7SDimitry Andric
setLoadAddress(uint64_t Address)207cfca06d7SDimitry Andric bool NativeSession::setLoadAddress(uint64_t Address) {
208cfca06d7SDimitry Andric LoadAddress = Address;
209cfca06d7SDimitry Andric return true;
210cfca06d7SDimitry Andric }
21171d5a254SDimitry Andric
getGlobalScope()21208bbd35aSDimitry Andric std::unique_ptr<PDBSymbolExe> NativeSession::getGlobalScope() {
213d8e91e46SDimitry Andric return PDBSymbol::createAs<PDBSymbolExe>(*this, getNativeGlobalScope());
21471d5a254SDimitry Andric }
21571d5a254SDimitry Andric
21671d5a254SDimitry Andric std::unique_ptr<PDBSymbol>
getSymbolById(SymIndexId SymbolId) const217d8e91e46SDimitry Andric NativeSession::getSymbolById(SymIndexId SymbolId) const {
218d8e91e46SDimitry Andric return Cache.getSymbolById(SymbolId);
21971d5a254SDimitry Andric }
22071d5a254SDimitry Andric
addressForVA(uint64_t VA,uint32_t & Section,uint32_t & Offset) const221eb11fae6SDimitry Andric bool NativeSession::addressForVA(uint64_t VA, uint32_t &Section,
222eb11fae6SDimitry Andric uint32_t &Offset) const {
223cfca06d7SDimitry Andric uint32_t RVA = VA - getLoadAddress();
224cfca06d7SDimitry Andric return addressForRVA(RVA, Section, Offset);
225eb11fae6SDimitry Andric }
226eb11fae6SDimitry Andric
addressForRVA(uint32_t RVA,uint32_t & Section,uint32_t & Offset) const227cfca06d7SDimitry Andric bool NativeSession::addressForRVA(uint32_t RVA, uint32_t &Section,
228eb11fae6SDimitry Andric uint32_t &Offset) const {
229cfca06d7SDimitry Andric Section = 0;
230cfca06d7SDimitry Andric Offset = 0;
231cfca06d7SDimitry Andric
232cfca06d7SDimitry Andric auto Dbi = Pdb->getPDBDbiStream();
233cfca06d7SDimitry Andric if (!Dbi)
234eb11fae6SDimitry Andric return false;
235cfca06d7SDimitry Andric
236cfca06d7SDimitry Andric if ((int32_t)RVA < 0)
237cfca06d7SDimitry Andric return true;
238cfca06d7SDimitry Andric
239cfca06d7SDimitry Andric Offset = RVA;
240cfca06d7SDimitry Andric for (; Section < Dbi->getSectionHeaders().size(); ++Section) {
241cfca06d7SDimitry Andric auto &Sec = Dbi->getSectionHeaders()[Section];
242cfca06d7SDimitry Andric if (RVA < Sec.VirtualAddress)
243cfca06d7SDimitry Andric return true;
244cfca06d7SDimitry Andric Offset = RVA - Sec.VirtualAddress;
245cfca06d7SDimitry Andric }
246cfca06d7SDimitry Andric return true;
247eb11fae6SDimitry Andric }
248eb11fae6SDimitry Andric
24971d5a254SDimitry Andric std::unique_ptr<PDBSymbol>
findSymbolByAddress(uint64_t Address,PDB_SymType Type)250cfca06d7SDimitry Andric NativeSession::findSymbolByAddress(uint64_t Address, PDB_SymType Type) {
251cfca06d7SDimitry Andric uint32_t Section;
252cfca06d7SDimitry Andric uint32_t Offset;
253cfca06d7SDimitry Andric addressForVA(Address, Section, Offset);
254cfca06d7SDimitry Andric return findSymbolBySectOffset(Section, Offset, Type);
25571d5a254SDimitry Andric }
25671d5a254SDimitry Andric
findSymbolByRVA(uint32_t RVA,PDB_SymType Type)257cfca06d7SDimitry Andric std::unique_ptr<PDBSymbol> NativeSession::findSymbolByRVA(uint32_t RVA,
258cfca06d7SDimitry Andric PDB_SymType Type) {
259cfca06d7SDimitry Andric uint32_t Section;
260cfca06d7SDimitry Andric uint32_t Offset;
261cfca06d7SDimitry Andric addressForRVA(RVA, Section, Offset);
262cfca06d7SDimitry Andric return findSymbolBySectOffset(Section, Offset, Type);
263eb11fae6SDimitry Andric }
264eb11fae6SDimitry Andric
265eb11fae6SDimitry Andric std::unique_ptr<PDBSymbol>
findSymbolBySectOffset(uint32_t Sect,uint32_t Offset,PDB_SymType Type)266eb11fae6SDimitry Andric NativeSession::findSymbolBySectOffset(uint32_t Sect, uint32_t Offset,
267cfca06d7SDimitry Andric PDB_SymType Type) {
268b60736ecSDimitry Andric if (AddrToModuleIndex.empty())
269b60736ecSDimitry Andric parseSectionContribs();
270b60736ecSDimitry Andric
271cfca06d7SDimitry Andric return Cache.findSymbolBySectOffset(Sect, Offset, Type);
272eb11fae6SDimitry Andric }
273eb11fae6SDimitry Andric
27471d5a254SDimitry Andric std::unique_ptr<IPDBEnumLineNumbers>
findLineNumbers(const PDBSymbolCompiland & Compiland,const IPDBSourceFile & File) const27571d5a254SDimitry Andric NativeSession::findLineNumbers(const PDBSymbolCompiland &Compiland,
27671d5a254SDimitry Andric const IPDBSourceFile &File) const {
27771d5a254SDimitry Andric return nullptr;
27871d5a254SDimitry Andric }
27971d5a254SDimitry Andric
28071d5a254SDimitry Andric std::unique_ptr<IPDBEnumLineNumbers>
findLineNumbersByAddress(uint64_t Address,uint32_t Length) const28171d5a254SDimitry Andric NativeSession::findLineNumbersByAddress(uint64_t Address,
28271d5a254SDimitry Andric uint32_t Length) const {
283cfca06d7SDimitry Andric return Cache.findLineNumbersByVA(Address, Length);
28471d5a254SDimitry Andric }
28571d5a254SDimitry Andric
286eb11fae6SDimitry Andric std::unique_ptr<IPDBEnumLineNumbers>
findLineNumbersByRVA(uint32_t RVA,uint32_t Length) const287eb11fae6SDimitry Andric NativeSession::findLineNumbersByRVA(uint32_t RVA, uint32_t Length) const {
288b60736ecSDimitry Andric return Cache.findLineNumbersByVA(getLoadAddress() + RVA, Length);
289eb11fae6SDimitry Andric }
290eb11fae6SDimitry Andric
291eb11fae6SDimitry Andric std::unique_ptr<IPDBEnumLineNumbers>
findLineNumbersBySectOffset(uint32_t Section,uint32_t Offset,uint32_t Length) const292eb11fae6SDimitry Andric NativeSession::findLineNumbersBySectOffset(uint32_t Section, uint32_t Offset,
293eb11fae6SDimitry Andric uint32_t Length) const {
294cfca06d7SDimitry Andric uint64_t VA = getVAFromSectOffset(Section, Offset);
295b60736ecSDimitry Andric return Cache.findLineNumbersByVA(VA, Length);
296eb11fae6SDimitry Andric }
297eb11fae6SDimitry Andric
29871d5a254SDimitry Andric std::unique_ptr<IPDBEnumSourceFiles>
findSourceFiles(const PDBSymbolCompiland * Compiland,StringRef Pattern,PDB_NameSearchFlags Flags) const29971d5a254SDimitry Andric NativeSession::findSourceFiles(const PDBSymbolCompiland *Compiland,
30071d5a254SDimitry Andric StringRef Pattern,
30171d5a254SDimitry Andric PDB_NameSearchFlags Flags) const {
30271d5a254SDimitry Andric return nullptr;
30371d5a254SDimitry Andric }
30471d5a254SDimitry Andric
30571d5a254SDimitry Andric std::unique_ptr<IPDBSourceFile>
findOneSourceFile(const PDBSymbolCompiland * Compiland,StringRef Pattern,PDB_NameSearchFlags Flags) const30671d5a254SDimitry Andric NativeSession::findOneSourceFile(const PDBSymbolCompiland *Compiland,
30771d5a254SDimitry Andric StringRef Pattern,
30871d5a254SDimitry Andric PDB_NameSearchFlags Flags) const {
30971d5a254SDimitry Andric return nullptr;
31071d5a254SDimitry Andric }
31171d5a254SDimitry Andric
31271d5a254SDimitry Andric std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
findCompilandsForSourceFile(StringRef Pattern,PDB_NameSearchFlags Flags) const31371d5a254SDimitry Andric NativeSession::findCompilandsForSourceFile(StringRef Pattern,
31471d5a254SDimitry Andric PDB_NameSearchFlags Flags) const {
31571d5a254SDimitry Andric return nullptr;
31671d5a254SDimitry Andric }
31771d5a254SDimitry Andric
31871d5a254SDimitry Andric std::unique_ptr<PDBSymbolCompiland>
findOneCompilandForSourceFile(StringRef Pattern,PDB_NameSearchFlags Flags) const31971d5a254SDimitry Andric NativeSession::findOneCompilandForSourceFile(StringRef Pattern,
32071d5a254SDimitry Andric PDB_NameSearchFlags Flags) const {
32171d5a254SDimitry Andric return nullptr;
32271d5a254SDimitry Andric }
32371d5a254SDimitry Andric
getAllSourceFiles() const32471d5a254SDimitry Andric std::unique_ptr<IPDBEnumSourceFiles> NativeSession::getAllSourceFiles() const {
32571d5a254SDimitry Andric return nullptr;
32671d5a254SDimitry Andric }
32771d5a254SDimitry Andric
getSourceFilesForCompiland(const PDBSymbolCompiland & Compiland) const32871d5a254SDimitry Andric std::unique_ptr<IPDBEnumSourceFiles> NativeSession::getSourceFilesForCompiland(
32971d5a254SDimitry Andric const PDBSymbolCompiland &Compiland) const {
33071d5a254SDimitry Andric return nullptr;
33171d5a254SDimitry Andric }
33271d5a254SDimitry Andric
33371d5a254SDimitry Andric std::unique_ptr<IPDBSourceFile>
getSourceFileById(uint32_t FileId) const33471d5a254SDimitry Andric NativeSession::getSourceFileById(uint32_t FileId) const {
335cfca06d7SDimitry Andric return Cache.getSourceFileById(FileId);
33671d5a254SDimitry Andric }
33771d5a254SDimitry Andric
getDebugStreams() const33871d5a254SDimitry Andric std::unique_ptr<IPDBEnumDataStreams> NativeSession::getDebugStreams() const {
33971d5a254SDimitry Andric return nullptr;
34071d5a254SDimitry Andric }
341044eb2f6SDimitry Andric
getEnumTables() const342044eb2f6SDimitry Andric std::unique_ptr<IPDBEnumTables> NativeSession::getEnumTables() const {
343044eb2f6SDimitry Andric return nullptr;
344044eb2f6SDimitry Andric }
345eb11fae6SDimitry Andric
346eb11fae6SDimitry Andric std::unique_ptr<IPDBEnumInjectedSources>
getInjectedSources() const347eb11fae6SDimitry Andric NativeSession::getInjectedSources() const {
348e6d15924SDimitry Andric auto ISS = Pdb->getInjectedSourceStream();
349e6d15924SDimitry Andric if (!ISS) {
350e6d15924SDimitry Andric consumeError(ISS.takeError());
351eb11fae6SDimitry Andric return nullptr;
352eb11fae6SDimitry Andric }
353e6d15924SDimitry Andric auto Strings = Pdb->getStringTable();
354e6d15924SDimitry Andric if (!Strings) {
355e6d15924SDimitry Andric consumeError(Strings.takeError());
356e6d15924SDimitry Andric return nullptr;
357e6d15924SDimitry Andric }
3581d5ae102SDimitry Andric return std::make_unique<NativeEnumInjectedSources>(*Pdb, *ISS, *Strings);
359e6d15924SDimitry Andric }
360eb11fae6SDimitry Andric
361eb11fae6SDimitry Andric std::unique_ptr<IPDBEnumSectionContribs>
getSectionContribs() const362eb11fae6SDimitry Andric NativeSession::getSectionContribs() const {
363eb11fae6SDimitry Andric return nullptr;
364eb11fae6SDimitry Andric }
365d8e91e46SDimitry Andric
366d8e91e46SDimitry Andric std::unique_ptr<IPDBEnumFrameData>
getFrameData() const367d8e91e46SDimitry Andric NativeSession::getFrameData() const {
368d8e91e46SDimitry Andric return nullptr;
369d8e91e46SDimitry Andric }
370d8e91e46SDimitry Andric
initializeExeSymbol()371d8e91e46SDimitry Andric void NativeSession::initializeExeSymbol() {
372d8e91e46SDimitry Andric if (ExeSymbol == 0)
373d8e91e46SDimitry Andric ExeSymbol = Cache.createSymbol<NativeExeSymbol>();
374d8e91e46SDimitry Andric }
375d8e91e46SDimitry Andric
getNativeGlobalScope() const376d8e91e46SDimitry Andric NativeExeSymbol &NativeSession::getNativeGlobalScope() const {
377d8e91e46SDimitry Andric const_cast<NativeSession &>(*this).initializeExeSymbol();
378d8e91e46SDimitry Andric
379d8e91e46SDimitry Andric return Cache.getNativeSymbolById<NativeExeSymbol>(ExeSymbol);
380d8e91e46SDimitry Andric }
381cfca06d7SDimitry Andric
getRVAFromSectOffset(uint32_t Section,uint32_t Offset) const382cfca06d7SDimitry Andric uint32_t NativeSession::getRVAFromSectOffset(uint32_t Section,
383cfca06d7SDimitry Andric uint32_t Offset) const {
384cfca06d7SDimitry Andric if (Section <= 0)
385cfca06d7SDimitry Andric return 0;
386cfca06d7SDimitry Andric
387cfca06d7SDimitry Andric auto Dbi = getDbiStreamPtr(*Pdb);
388cfca06d7SDimitry Andric if (!Dbi)
389cfca06d7SDimitry Andric return 0;
390cfca06d7SDimitry Andric
391cfca06d7SDimitry Andric uint32_t MaxSection = Dbi->getSectionHeaders().size();
392cfca06d7SDimitry Andric if (Section > MaxSection + 1)
393cfca06d7SDimitry Andric Section = MaxSection + 1;
394cfca06d7SDimitry Andric auto &Sec = Dbi->getSectionHeaders()[Section - 1];
395cfca06d7SDimitry Andric return Sec.VirtualAddress + Offset;
396cfca06d7SDimitry Andric }
397cfca06d7SDimitry Andric
getVAFromSectOffset(uint32_t Section,uint32_t Offset) const398cfca06d7SDimitry Andric uint64_t NativeSession::getVAFromSectOffset(uint32_t Section,
399cfca06d7SDimitry Andric uint32_t Offset) const {
400cfca06d7SDimitry Andric return LoadAddress + getRVAFromSectOffset(Section, Offset);
401cfca06d7SDimitry Andric }
402b60736ecSDimitry Andric
moduleIndexForVA(uint64_t VA,uint16_t & ModuleIndex) const403b60736ecSDimitry Andric bool NativeSession::moduleIndexForVA(uint64_t VA, uint16_t &ModuleIndex) const {
404b60736ecSDimitry Andric ModuleIndex = 0;
405b60736ecSDimitry Andric auto Iter = AddrToModuleIndex.find(VA);
406b60736ecSDimitry Andric if (Iter == AddrToModuleIndex.end())
407b60736ecSDimitry Andric return false;
408b60736ecSDimitry Andric ModuleIndex = Iter.value();
409b60736ecSDimitry Andric return true;
410b60736ecSDimitry Andric }
411b60736ecSDimitry Andric
moduleIndexForSectOffset(uint32_t Sect,uint32_t Offset,uint16_t & ModuleIndex) const412b60736ecSDimitry Andric bool NativeSession::moduleIndexForSectOffset(uint32_t Sect, uint32_t Offset,
413b60736ecSDimitry Andric uint16_t &ModuleIndex) const {
414b60736ecSDimitry Andric ModuleIndex = 0;
415b60736ecSDimitry Andric auto Iter = AddrToModuleIndex.find(getVAFromSectOffset(Sect, Offset));
416b60736ecSDimitry Andric if (Iter == AddrToModuleIndex.end())
417b60736ecSDimitry Andric return false;
418b60736ecSDimitry Andric ModuleIndex = Iter.value();
419b60736ecSDimitry Andric return true;
420b60736ecSDimitry Andric }
421b60736ecSDimitry Andric
parseSectionContribs()422b60736ecSDimitry Andric void NativeSession::parseSectionContribs() {
423b60736ecSDimitry Andric auto Dbi = Pdb->getPDBDbiStream();
424b60736ecSDimitry Andric if (!Dbi)
425b60736ecSDimitry Andric return;
426b60736ecSDimitry Andric
427b60736ecSDimitry Andric class Visitor : public ISectionContribVisitor {
428b60736ecSDimitry Andric NativeSession &Session;
429b60736ecSDimitry Andric IMap &AddrMap;
430b60736ecSDimitry Andric
431b60736ecSDimitry Andric public:
432b60736ecSDimitry Andric Visitor(NativeSession &Session, IMap &AddrMap)
433b60736ecSDimitry Andric : Session(Session), AddrMap(AddrMap) {}
434b60736ecSDimitry Andric void visit(const SectionContrib &C) override {
435b60736ecSDimitry Andric if (C.Size == 0)
436b60736ecSDimitry Andric return;
437b60736ecSDimitry Andric
438b60736ecSDimitry Andric uint64_t VA = Session.getVAFromSectOffset(C.ISect, C.Off);
439b60736ecSDimitry Andric uint64_t End = VA + C.Size;
440b60736ecSDimitry Andric
441b60736ecSDimitry Andric // Ignore overlapping sections based on the assumption that a valid
442b60736ecSDimitry Andric // PDB file should not have overlaps.
443b60736ecSDimitry Andric if (!AddrMap.overlaps(VA, End))
444b60736ecSDimitry Andric AddrMap.insert(VA, End, C.Imod);
445b60736ecSDimitry Andric }
446b60736ecSDimitry Andric void visit(const SectionContrib2 &C) override { visit(C.Base); }
447b60736ecSDimitry Andric };
448b60736ecSDimitry Andric
449b60736ecSDimitry Andric Visitor V(*this, AddrToModuleIndex);
450b60736ecSDimitry Andric Dbi->visitSectionContributions(V);
451b60736ecSDimitry Andric }
452b60736ecSDimitry Andric
453b60736ecSDimitry Andric Expected<ModuleDebugStreamRef>
getModuleDebugStream(uint32_t Index) const454b60736ecSDimitry Andric NativeSession::getModuleDebugStream(uint32_t Index) const {
455b60736ecSDimitry Andric auto *Dbi = getDbiStreamPtr(*Pdb);
456b60736ecSDimitry Andric assert(Dbi && "Dbi stream not present");
457b60736ecSDimitry Andric
458b60736ecSDimitry Andric DbiModuleDescriptor Modi = Dbi->modules().getModuleDescriptor(Index);
459b60736ecSDimitry Andric
460b60736ecSDimitry Andric uint16_t ModiStream = Modi.getModuleStreamIndex();
461b60736ecSDimitry Andric if (ModiStream == kInvalidStreamIndex)
462b60736ecSDimitry Andric return make_error<RawError>("Module stream not present");
463b60736ecSDimitry Andric
464b60736ecSDimitry Andric std::unique_ptr<msf::MappedBlockStream> ModStreamData =
465b60736ecSDimitry Andric Pdb->createIndexedStream(ModiStream);
466b60736ecSDimitry Andric
467b60736ecSDimitry Andric ModuleDebugStreamRef ModS(Modi, std::move(ModStreamData));
468b60736ecSDimitry Andric if (auto EC = ModS.reload())
469b60736ecSDimitry Andric return std::move(EC);
470b60736ecSDimitry Andric
471b60736ecSDimitry Andric return std::move(ModS);
472b60736ecSDimitry Andric }
473