16b6b8c4fSAdrian McCarthy //===- NativeSession.cpp - Native implementation of IPDBSession -*- C++ -*-===//
26b6b8c4fSAdrian McCarthy //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66b6b8c4fSAdrian McCarthy //
76b6b8c4fSAdrian McCarthy //===----------------------------------------------------------------------===//
86b6b8c4fSAdrian McCarthy
96b6b8c4fSAdrian McCarthy #include "llvm/DebugInfo/PDB/Native/NativeSession.h"
106b6b8c4fSAdrian McCarthy
11*eb4c8608Sserge-sans-paille #include "llvm/BinaryFormat/Magic.h"
12*eb4c8608Sserge-sans-paille #include "llvm/DebugInfo/MSF/MSFCommon.h"
13*eb4c8608Sserge-sans-paille #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
146b6b8c4fSAdrian McCarthy #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
156b6b8c4fSAdrian McCarthy #include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
16*eb4c8608Sserge-sans-paille #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
17*eb4c8608Sserge-sans-paille #include "llvm/DebugInfo/PDB/Native/DbiModuleList.h"
1823609331SAmy Huang #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
19bc980340SAmy Huang #include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h"
20*eb4c8608Sserge-sans-paille #include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
21d100b5ddSNico Weber #include "llvm/DebugInfo/PDB/Native/NativeEnumInjectedSources.h"
224d93d66dSAdrian McCarthy #include "llvm/DebugInfo/PDB/Native/NativeExeSymbol.h"
236b6b8c4fSAdrian McCarthy #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
24*eb4c8608Sserge-sans-paille #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
256b6b8c4fSAdrian McCarthy #include "llvm/DebugInfo/PDB/Native/RawError.h"
26*eb4c8608Sserge-sans-paille #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
278ab7dd60SZachary Turner #include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
28*eb4c8608Sserge-sans-paille #include "llvm/DebugInfo/PDB/PDBSymbol.h"
296b6b8c4fSAdrian McCarthy #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
306b6b8c4fSAdrian McCarthy #include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
31*eb4c8608Sserge-sans-paille #include "llvm/Object/Binary.h"
3223609331SAmy Huang #include "llvm/Object/COFF.h"
336b6b8c4fSAdrian McCarthy #include "llvm/Support/Allocator.h"
34d9dc2829SZachary Turner #include "llvm/Support/BinaryByteStream.h"
35*eb4c8608Sserge-sans-paille #include "llvm/Support/BinaryStreamArray.h"
366b6b8c4fSAdrian McCarthy #include "llvm/Support/Error.h"
376b6b8c4fSAdrian McCarthy #include "llvm/Support/ErrorOr.h"
386b6b8c4fSAdrian McCarthy #include "llvm/Support/MemoryBuffer.h"
3923609331SAmy Huang #include "llvm/Support/Path.h"
40bf0afc32SAdrian McCarthy
416b6b8c4fSAdrian McCarthy #include <algorithm>
42b41f03e7SAdrian McCarthy #include <cassert>
436b6b8c4fSAdrian McCarthy #include <memory>
44bf0afc32SAdrian McCarthy #include <utility>
456b6b8c4fSAdrian McCarthy
466b6b8c4fSAdrian McCarthy using namespace llvm;
476b6b8c4fSAdrian McCarthy using namespace llvm::msf;
486b6b8c4fSAdrian McCarthy using namespace llvm::pdb;
496b6b8c4fSAdrian McCarthy
50*eb4c8608Sserge-sans-paille namespace llvm {
51*eb4c8608Sserge-sans-paille namespace codeview {
52*eb4c8608Sserge-sans-paille union DebugInfo;
53*eb4c8608Sserge-sans-paille }
54*eb4c8608Sserge-sans-paille } // namespace llvm
55*eb4c8608Sserge-sans-paille
getDbiStreamPtr(PDBFile & File)568ab7dd60SZachary Turner static DbiStream *getDbiStreamPtr(PDBFile &File) {
578ab7dd60SZachary Turner Expected<DbiStream &> DbiS = File.getPDBDbiStream();
588ab7dd60SZachary Turner if (DbiS)
598ab7dd60SZachary Turner return &DbiS.get();
608ab7dd60SZachary Turner
618ab7dd60SZachary Turner consumeError(DbiS.takeError());
628ab7dd60SZachary Turner return nullptr;
638ab7dd60SZachary Turner }
648d090fc5SAdrian McCarthy
NativeSession(std::unique_ptr<PDBFile> PdbFile,std::unique_ptr<BumpPtrAllocator> Allocator)656b6b8c4fSAdrian McCarthy NativeSession::NativeSession(std::unique_ptr<PDBFile> PdbFile,
666b6b8c4fSAdrian McCarthy std::unique_ptr<BumpPtrAllocator> Allocator)
678ab7dd60SZachary Turner : Pdb(std::move(PdbFile)), Allocator(std::move(Allocator)),
68bc980340SAmy Huang Cache(*this, getDbiStreamPtr(*Pdb)), AddrToModuleIndex(IMapAllocator) {}
696b6b8c4fSAdrian McCarthy
706b6b8c4fSAdrian McCarthy NativeSession::~NativeSession() = default;
716b6b8c4fSAdrian McCarthy
createFromPdb(std::unique_ptr<MemoryBuffer> Buffer,std::unique_ptr<IPDBSession> & Session)7275257bc2SPeter Collingbourne Error NativeSession::createFromPdb(std::unique_ptr<MemoryBuffer> Buffer,
736b6b8c4fSAdrian McCarthy std::unique_ptr<IPDBSession> &Session) {
7475257bc2SPeter Collingbourne StringRef Path = Buffer->getBufferIdentifier();
750eaee545SJonas Devlieghere auto Stream = std::make_unique<MemoryBufferByteStream>(
76695ed56bSZachary Turner std::move(Buffer), llvm::support::little);
776b6b8c4fSAdrian McCarthy
780eaee545SJonas Devlieghere auto Allocator = std::make_unique<BumpPtrAllocator>();
790eaee545SJonas Devlieghere auto File = std::make_unique<PDBFile>(Path, std::move(Stream), *Allocator);
806b6b8c4fSAdrian McCarthy if (auto EC = File->parseFileHeaders())
816b6b8c4fSAdrian McCarthy return EC;
826b6b8c4fSAdrian McCarthy if (auto EC = File->parseStreamData())
836b6b8c4fSAdrian McCarthy return EC;
846b6b8c4fSAdrian McCarthy
856b6b8c4fSAdrian McCarthy Session =
860eaee545SJonas Devlieghere std::make_unique<NativeSession>(std::move(File), std::move(Allocator));
876b6b8c4fSAdrian McCarthy
886b6b8c4fSAdrian McCarthy return Error::success();
896b6b8c4fSAdrian McCarthy }
906b6b8c4fSAdrian McCarthy
9123609331SAmy Huang static Expected<std::unique_ptr<PDBFile>>
loadPdbFile(StringRef PdbPath,std::unique_ptr<BumpPtrAllocator> & Allocator)9223609331SAmy Huang loadPdbFile(StringRef PdbPath, std::unique_ptr<BumpPtrAllocator> &Allocator) {
9323609331SAmy Huang ErrorOr<std::unique_ptr<MemoryBuffer>> ErrorOrBuffer =
94c83cd8feSAbhina Sreeskantharajan MemoryBuffer::getFile(PdbPath, /*IsText=*/false,
9523609331SAmy Huang /*RequiresNullTerminator=*/false);
9623609331SAmy Huang if (!ErrorOrBuffer)
9723609331SAmy Huang return make_error<RawError>(ErrorOrBuffer.getError());
9823609331SAmy Huang std::unique_ptr<llvm::MemoryBuffer> Buffer = std::move(*ErrorOrBuffer);
9923609331SAmy Huang
10023609331SAmy Huang PdbPath = Buffer->getBufferIdentifier();
10123609331SAmy Huang file_magic Magic;
10223609331SAmy Huang auto EC = identify_magic(PdbPath, Magic);
10323609331SAmy Huang if (EC || Magic != file_magic::pdb)
10423609331SAmy Huang return make_error<RawError>(EC);
10523609331SAmy Huang
10623609331SAmy Huang auto Stream = std::make_unique<MemoryBufferByteStream>(std::move(Buffer),
10723609331SAmy Huang llvm::support::little);
10823609331SAmy Huang
10923609331SAmy Huang auto File = std::make_unique<PDBFile>(PdbPath, std::move(Stream), *Allocator);
11023609331SAmy Huang if (auto EC = File->parseFileHeaders())
11123609331SAmy Huang return std::move(EC);
11223609331SAmy Huang
11323609331SAmy Huang if (auto EC = File->parseStreamData())
11423609331SAmy Huang return std::move(EC);
11523609331SAmy Huang
11623609331SAmy Huang return std::move(File);
117a6d8a055SAmy Huang }
118a6d8a055SAmy Huang
createFromPdbPath(StringRef PdbPath,std::unique_ptr<IPDBSession> & Session)11923609331SAmy Huang Error NativeSession::createFromPdbPath(StringRef PdbPath,
12023609331SAmy Huang std::unique_ptr<IPDBSession> &Session) {
12123609331SAmy Huang auto Allocator = std::make_unique<BumpPtrAllocator>();
12223609331SAmy Huang auto PdbFile = loadPdbFile(PdbPath, Allocator);
12323609331SAmy Huang if (!PdbFile)
12423609331SAmy Huang return PdbFile.takeError();
125a6d8a055SAmy Huang
12623609331SAmy Huang Session = std::make_unique<NativeSession>(std::move(PdbFile.get()),
12723609331SAmy Huang std::move(Allocator));
12823609331SAmy Huang return Error::success();
12923609331SAmy Huang }
13023609331SAmy Huang
getPdbPathFromExe(StringRef ExePath)13123609331SAmy Huang static Expected<std::string> getPdbPathFromExe(StringRef ExePath) {
13223609331SAmy Huang Expected<object::OwningBinary<object::Binary>> BinaryFile =
13323609331SAmy Huang object::createBinary(ExePath);
13423609331SAmy Huang if (!BinaryFile)
13523609331SAmy Huang return BinaryFile.takeError();
13623609331SAmy Huang
13723609331SAmy Huang const object::COFFObjectFile *ObjFile =
13823609331SAmy Huang dyn_cast<object::COFFObjectFile>(BinaryFile->getBinary());
13923609331SAmy Huang if (!ObjFile)
14023609331SAmy Huang return make_error<RawError>(raw_error_code::invalid_format);
14123609331SAmy Huang
14223609331SAmy Huang StringRef PdbPath;
14323609331SAmy Huang const llvm::codeview::DebugInfo *PdbInfo = nullptr;
1441c03389cSReid Kleckner if (Error E = ObjFile->getDebugPDBInfo(PdbInfo, PdbPath))
1451c03389cSReid Kleckner return std::move(E);
14623609331SAmy Huang
14723609331SAmy Huang return std::string(PdbPath);
14823609331SAmy Huang }
14923609331SAmy Huang
createFromExe(StringRef ExePath,std::unique_ptr<IPDBSession> & Session)15023609331SAmy Huang Error NativeSession::createFromExe(StringRef ExePath,
15123609331SAmy Huang std::unique_ptr<IPDBSession> &Session) {
15223609331SAmy Huang Expected<std::string> PdbPath = getPdbPathFromExe(ExePath);
15323609331SAmy Huang if (!PdbPath)
15423609331SAmy Huang return PdbPath.takeError();
15523609331SAmy Huang
15623609331SAmy Huang file_magic Magic;
15723609331SAmy Huang auto EC = identify_magic(PdbPath.get(), Magic);
15823609331SAmy Huang if (EC || Magic != file_magic::pdb)
15923609331SAmy Huang return make_error<RawError>(EC);
16023609331SAmy Huang
16123609331SAmy Huang auto Allocator = std::make_unique<BumpPtrAllocator>();
16223609331SAmy Huang auto File = loadPdbFile(PdbPath.get(), Allocator);
16323609331SAmy Huang if (!File)
16423609331SAmy Huang return File.takeError();
16523609331SAmy Huang
16623609331SAmy Huang Session = std::make_unique<NativeSession>(std::move(File.get()),
16723609331SAmy Huang std::move(Allocator));
16823609331SAmy Huang
16923609331SAmy Huang return Error::success();
17023609331SAmy Huang }
17123609331SAmy Huang
17223609331SAmy Huang Expected<std::string>
searchForPdb(const PdbSearchOptions & Opts)17323609331SAmy Huang NativeSession::searchForPdb(const PdbSearchOptions &Opts) {
17423609331SAmy Huang Expected<std::string> PathOrErr = getPdbPathFromExe(Opts.ExePath);
17523609331SAmy Huang if (!PathOrErr)
17623609331SAmy Huang return PathOrErr.takeError();
17723609331SAmy Huang StringRef PathFromExe = PathOrErr.get();
17823609331SAmy Huang sys::path::Style Style = PathFromExe.startswith("/")
17923609331SAmy Huang ? sys::path::Style::posix
18023609331SAmy Huang : sys::path::Style::windows;
18123609331SAmy Huang StringRef PdbName = sys::path::filename(PathFromExe, Style);
18223609331SAmy Huang
18323609331SAmy Huang // Check if pdb exists in the executable directory.
18423609331SAmy Huang SmallString<128> PdbPath = StringRef(Opts.ExePath);
18523609331SAmy Huang sys::path::remove_filename(PdbPath);
18623609331SAmy Huang sys::path::append(PdbPath, PdbName);
18723609331SAmy Huang
18823609331SAmy Huang auto Allocator = std::make_unique<BumpPtrAllocator>();
18923609331SAmy Huang
19023609331SAmy Huang if (auto File = loadPdbFile(PdbPath, Allocator))
19123609331SAmy Huang return std::string(PdbPath);
19223609331SAmy Huang else
193f8170d87SAmy Huang consumeError(File.takeError());
194f8170d87SAmy Huang
195f8170d87SAmy Huang // Check path that was in the executable.
196f8170d87SAmy Huang if (auto File = loadPdbFile(PathFromExe, Allocator))
197f8170d87SAmy Huang return std::string(PathFromExe);
198f8170d87SAmy Huang else
19923609331SAmy Huang return File.takeError();
20023609331SAmy Huang
20123609331SAmy Huang return make_error<RawError>("PDB not found");
20223609331SAmy Huang }
20323609331SAmy Huang
getLoadAddress() const20423609331SAmy Huang uint64_t NativeSession::getLoadAddress() const { return LoadAddress; }
20523609331SAmy Huang
setLoadAddress(uint64_t Address)20623609331SAmy Huang bool NativeSession::setLoadAddress(uint64_t Address) {
20723609331SAmy Huang LoadAddress = Address;
20823609331SAmy Huang return true;
20923609331SAmy Huang }
2106b6b8c4fSAdrian McCarthy
getGlobalScope()2116a4b080aSAdrian McCarthy std::unique_ptr<PDBSymbolExe> NativeSession::getGlobalScope() {
2127999b4faSZachary Turner return PDBSymbol::createAs<PDBSymbolExe>(*this, getNativeGlobalScope());
2136b6b8c4fSAdrian McCarthy }
2146b6b8c4fSAdrian McCarthy
2156b6b8c4fSAdrian McCarthy std::unique_ptr<PDBSymbol>
getSymbolById(SymIndexId SymbolId) const216cae73458SZachary Turner NativeSession::getSymbolById(SymIndexId SymbolId) const {
2178ab7dd60SZachary Turner return Cache.getSymbolById(SymbolId);
2186b6b8c4fSAdrian McCarthy }
2196b6b8c4fSAdrian McCarthy
addressForVA(uint64_t VA,uint32_t & Section,uint32_t & Offset) const22053708a5eSAaron Smith bool NativeSession::addressForVA(uint64_t VA, uint32_t &Section,
22153708a5eSAaron Smith uint32_t &Offset) const {
22223609331SAmy Huang uint32_t RVA = VA - getLoadAddress();
22323609331SAmy Huang return addressForRVA(RVA, Section, Offset);
224a6d8a055SAmy Huang }
225507d80fbSAmy Huang
addressForRVA(uint32_t RVA,uint32_t & Section,uint32_t & Offset) const22623609331SAmy Huang bool NativeSession::addressForRVA(uint32_t RVA, uint32_t &Section,
227507d80fbSAmy Huang uint32_t &Offset) const {
228641ae73fSAmy Huang Section = 0;
229641ae73fSAmy Huang Offset = 0;
230641ae73fSAmy Huang
23123609331SAmy Huang auto Dbi = Pdb->getPDBDbiStream();
23223609331SAmy Huang if (!Dbi)
233507d80fbSAmy Huang return false;
23423609331SAmy Huang
23523609331SAmy Huang if ((int32_t)RVA < 0)
23623609331SAmy Huang return true;
23723609331SAmy Huang
23823609331SAmy Huang Offset = RVA;
23923609331SAmy Huang for (; Section < Dbi->getSectionHeaders().size(); ++Section) {
24023609331SAmy Huang auto &Sec = Dbi->getSectionHeaders()[Section];
24123609331SAmy Huang if (RVA < Sec.VirtualAddress)
24223609331SAmy Huang return true;
24323609331SAmy Huang Offset = RVA - Sec.VirtualAddress;
24423609331SAmy Huang }
24523609331SAmy Huang return true;
24653708a5eSAaron Smith }
24753708a5eSAaron Smith
2486b6b8c4fSAdrian McCarthy std::unique_ptr<PDBSymbol>
findSymbolByAddress(uint64_t Address,PDB_SymType Type)249641ae73fSAmy Huang NativeSession::findSymbolByAddress(uint64_t Address, PDB_SymType Type) {
250641ae73fSAmy Huang uint32_t Section;
251641ae73fSAmy Huang uint32_t Offset;
252641ae73fSAmy Huang addressForVA(Address, Section, Offset);
253641ae73fSAmy Huang return findSymbolBySectOffset(Section, Offset, Type);
2546b6b8c4fSAdrian McCarthy }
2556b6b8c4fSAdrian McCarthy
findSymbolByRVA(uint32_t RVA,PDB_SymType Type)256641ae73fSAmy Huang std::unique_ptr<PDBSymbol> NativeSession::findSymbolByRVA(uint32_t RVA,
257641ae73fSAmy Huang PDB_SymType Type) {
258641ae73fSAmy Huang uint32_t Section;
259641ae73fSAmy Huang uint32_t Offset;
260641ae73fSAmy Huang addressForRVA(RVA, Section, Offset);
261641ae73fSAmy Huang return findSymbolBySectOffset(Section, Offset, Type);
2623dca0bedSAaron Smith }
2633dca0bedSAaron Smith
2643dca0bedSAaron Smith std::unique_ptr<PDBSymbol>
findSymbolBySectOffset(uint32_t Sect,uint32_t Offset,PDB_SymType Type)2653dca0bedSAaron Smith NativeSession::findSymbolBySectOffset(uint32_t Sect, uint32_t Offset,
266641ae73fSAmy Huang PDB_SymType Type) {
267bc980340SAmy Huang if (AddrToModuleIndex.empty())
268bc980340SAmy Huang parseSectionContribs();
269bc980340SAmy Huang
270641ae73fSAmy Huang return Cache.findSymbolBySectOffset(Sect, Offset, Type);
2713dca0bedSAaron Smith }
2723dca0bedSAaron Smith
2736b6b8c4fSAdrian McCarthy std::unique_ptr<IPDBEnumLineNumbers>
findLineNumbers(const PDBSymbolCompiland & Compiland,const IPDBSourceFile & File) const2746b6b8c4fSAdrian McCarthy NativeSession::findLineNumbers(const PDBSymbolCompiland &Compiland,
2756b6b8c4fSAdrian McCarthy const IPDBSourceFile &File) const {
2766b6b8c4fSAdrian McCarthy return nullptr;
2776b6b8c4fSAdrian McCarthy }
2786b6b8c4fSAdrian McCarthy
2796b6b8c4fSAdrian McCarthy std::unique_ptr<IPDBEnumLineNumbers>
findLineNumbersByAddress(uint64_t Address,uint32_t Length) const2806b6b8c4fSAdrian McCarthy NativeSession::findLineNumbersByAddress(uint64_t Address,
2816b6b8c4fSAdrian McCarthy uint32_t Length) const {
282f8170d87SAmy Huang return Cache.findLineNumbersByVA(Address, Length);
2836b6b8c4fSAdrian McCarthy }
2846b6b8c4fSAdrian McCarthy
28540198f59SAaron Smith std::unique_ptr<IPDBEnumLineNumbers>
findLineNumbersByRVA(uint32_t RVA,uint32_t Length) const286ed81a9dbSAaron Smith NativeSession::findLineNumbersByRVA(uint32_t RVA, uint32_t Length) const {
2870881d0beSAmy Huang return Cache.findLineNumbersByVA(getLoadAddress() + RVA, Length);
288ed81a9dbSAaron Smith }
289ed81a9dbSAaron Smith
290ed81a9dbSAaron Smith std::unique_ptr<IPDBEnumLineNumbers>
findLineNumbersBySectOffset(uint32_t Section,uint32_t Offset,uint32_t Length) const29140198f59SAaron Smith NativeSession::findLineNumbersBySectOffset(uint32_t Section, uint32_t Offset,
29240198f59SAaron Smith uint32_t Length) const {
293f8170d87SAmy Huang uint64_t VA = getVAFromSectOffset(Section, Offset);
2940881d0beSAmy Huang return Cache.findLineNumbersByVA(VA, Length);
29540198f59SAaron Smith }
29640198f59SAaron Smith
2976b6b8c4fSAdrian McCarthy std::unique_ptr<IPDBEnumSourceFiles>
findSourceFiles(const PDBSymbolCompiland * Compiland,StringRef Pattern,PDB_NameSearchFlags Flags) const2986b6b8c4fSAdrian McCarthy NativeSession::findSourceFiles(const PDBSymbolCompiland *Compiland,
2996b6b8c4fSAdrian McCarthy StringRef Pattern,
3006b6b8c4fSAdrian McCarthy PDB_NameSearchFlags Flags) const {
3016b6b8c4fSAdrian McCarthy return nullptr;
3026b6b8c4fSAdrian McCarthy }
3036b6b8c4fSAdrian McCarthy
3046b6b8c4fSAdrian McCarthy std::unique_ptr<IPDBSourceFile>
findOneSourceFile(const PDBSymbolCompiland * Compiland,StringRef Pattern,PDB_NameSearchFlags Flags) const3056b6b8c4fSAdrian McCarthy NativeSession::findOneSourceFile(const PDBSymbolCompiland *Compiland,
3066b6b8c4fSAdrian McCarthy StringRef Pattern,
3076b6b8c4fSAdrian McCarthy PDB_NameSearchFlags Flags) const {
3086b6b8c4fSAdrian McCarthy return nullptr;
3096b6b8c4fSAdrian McCarthy }
3106b6b8c4fSAdrian McCarthy
3116b6b8c4fSAdrian McCarthy std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
findCompilandsForSourceFile(StringRef Pattern,PDB_NameSearchFlags Flags) const3126b6b8c4fSAdrian McCarthy NativeSession::findCompilandsForSourceFile(StringRef Pattern,
3136b6b8c4fSAdrian McCarthy PDB_NameSearchFlags Flags) const {
3146b6b8c4fSAdrian McCarthy return nullptr;
3156b6b8c4fSAdrian McCarthy }
3166b6b8c4fSAdrian McCarthy
3176b6b8c4fSAdrian McCarthy std::unique_ptr<PDBSymbolCompiland>
findOneCompilandForSourceFile(StringRef Pattern,PDB_NameSearchFlags Flags) const3186b6b8c4fSAdrian McCarthy NativeSession::findOneCompilandForSourceFile(StringRef Pattern,
3196b6b8c4fSAdrian McCarthy PDB_NameSearchFlags Flags) const {
3206b6b8c4fSAdrian McCarthy return nullptr;
3216b6b8c4fSAdrian McCarthy }
3226b6b8c4fSAdrian McCarthy
getAllSourceFiles() const3236b6b8c4fSAdrian McCarthy std::unique_ptr<IPDBEnumSourceFiles> NativeSession::getAllSourceFiles() const {
3246b6b8c4fSAdrian McCarthy return nullptr;
3256b6b8c4fSAdrian McCarthy }
3266b6b8c4fSAdrian McCarthy
getSourceFilesForCompiland(const PDBSymbolCompiland & Compiland) const3276b6b8c4fSAdrian McCarthy std::unique_ptr<IPDBEnumSourceFiles> NativeSession::getSourceFilesForCompiland(
3286b6b8c4fSAdrian McCarthy const PDBSymbolCompiland &Compiland) const {
3296b6b8c4fSAdrian McCarthy return nullptr;
3306b6b8c4fSAdrian McCarthy }
3316b6b8c4fSAdrian McCarthy
3326b6b8c4fSAdrian McCarthy std::unique_ptr<IPDBSourceFile>
getSourceFileById(uint32_t FileId) const3336b6b8c4fSAdrian McCarthy NativeSession::getSourceFileById(uint32_t FileId) const {
334f8170d87SAmy Huang return Cache.getSourceFileById(FileId);
3356b6b8c4fSAdrian McCarthy }
3366b6b8c4fSAdrian McCarthy
getDebugStreams() const3376b6b8c4fSAdrian McCarthy std::unique_ptr<IPDBEnumDataStreams> NativeSession::getDebugStreams() const {
3386b6b8c4fSAdrian McCarthy return nullptr;
3396b6b8c4fSAdrian McCarthy }
34089bca9e5SAaron Smith
getEnumTables() const34189bca9e5SAaron Smith std::unique_ptr<IPDBEnumTables> NativeSession::getEnumTables() const {
34289bca9e5SAaron Smith return nullptr;
34389bca9e5SAaron Smith }
344679aeaddSZachary Turner
345679aeaddSZachary Turner std::unique_ptr<IPDBEnumInjectedSources>
getInjectedSources() const346679aeaddSZachary Turner NativeSession::getInjectedSources() const {
347d100b5ddSNico Weber auto ISS = Pdb->getInjectedSourceStream();
348d100b5ddSNico Weber if (!ISS) {
349d100b5ddSNico Weber consumeError(ISS.takeError());
350679aeaddSZachary Turner return nullptr;
351679aeaddSZachary Turner }
352d100b5ddSNico Weber auto Strings = Pdb->getStringTable();
353d100b5ddSNico Weber if (!Strings) {
354d100b5ddSNico Weber consumeError(Strings.takeError());
355d100b5ddSNico Weber return nullptr;
356d100b5ddSNico Weber }
3570eaee545SJonas Devlieghere return std::make_unique<NativeEnumInjectedSources>(*Pdb, *ISS, *Strings);
358d100b5ddSNico Weber }
359523de05aSAaron Smith
360523de05aSAaron Smith std::unique_ptr<IPDBEnumSectionContribs>
getSectionContribs() const361523de05aSAaron Smith NativeSession::getSectionContribs() const {
362523de05aSAaron Smith return nullptr;
363523de05aSAaron Smith }
3647999b4faSZachary Turner
365c43e086cSAleksandr Urakov std::unique_ptr<IPDBEnumFrameData>
getFrameData() const366c43e086cSAleksandr Urakov NativeSession::getFrameData() const {
367c43e086cSAleksandr Urakov return nullptr;
368c43e086cSAleksandr Urakov }
369c43e086cSAleksandr Urakov
initializeExeSymbol()3708ab7dd60SZachary Turner void NativeSession::initializeExeSymbol() {
3718ab7dd60SZachary Turner if (ExeSymbol == 0)
3728ab7dd60SZachary Turner ExeSymbol = Cache.createSymbol<NativeExeSymbol>();
3737999b4faSZachary Turner }
3748ab7dd60SZachary Turner
getNativeGlobalScope() const3758ab7dd60SZachary Turner NativeExeSymbol &NativeSession::getNativeGlobalScope() const {
3768ab7dd60SZachary Turner const_cast<NativeSession &>(*this).initializeExeSymbol();
3778ab7dd60SZachary Turner
3788ab7dd60SZachary Turner return Cache.getNativeSymbolById<NativeExeSymbol>(ExeSymbol);
3797999b4faSZachary Turner }
380641ae73fSAmy Huang
getRVAFromSectOffset(uint32_t Section,uint32_t Offset) const381641ae73fSAmy Huang uint32_t NativeSession::getRVAFromSectOffset(uint32_t Section,
382641ae73fSAmy Huang uint32_t Offset) const {
383641ae73fSAmy Huang if (Section <= 0)
384641ae73fSAmy Huang return 0;
385641ae73fSAmy Huang
386641ae73fSAmy Huang auto Dbi = getDbiStreamPtr(*Pdb);
387641ae73fSAmy Huang if (!Dbi)
388641ae73fSAmy Huang return 0;
389641ae73fSAmy Huang
390641ae73fSAmy Huang uint32_t MaxSection = Dbi->getSectionHeaders().size();
391641ae73fSAmy Huang if (Section > MaxSection + 1)
392641ae73fSAmy Huang Section = MaxSection + 1;
393641ae73fSAmy Huang auto &Sec = Dbi->getSectionHeaders()[Section - 1];
394641ae73fSAmy Huang return Sec.VirtualAddress + Offset;
395641ae73fSAmy Huang }
396641ae73fSAmy Huang
getVAFromSectOffset(uint32_t Section,uint32_t Offset) const397641ae73fSAmy Huang uint64_t NativeSession::getVAFromSectOffset(uint32_t Section,
398641ae73fSAmy Huang uint32_t Offset) const {
399641ae73fSAmy Huang return LoadAddress + getRVAFromSectOffset(Section, Offset);
400641ae73fSAmy Huang }
401bc980340SAmy Huang
moduleIndexForVA(uint64_t VA,uint16_t & ModuleIndex) const402bc980340SAmy Huang bool NativeSession::moduleIndexForVA(uint64_t VA, uint16_t &ModuleIndex) const {
403bc980340SAmy Huang ModuleIndex = 0;
404bc980340SAmy Huang auto Iter = AddrToModuleIndex.find(VA);
405bc980340SAmy Huang if (Iter == AddrToModuleIndex.end())
406bc980340SAmy Huang return false;
407bc980340SAmy Huang ModuleIndex = Iter.value();
408bc980340SAmy Huang return true;
409bc980340SAmy Huang }
410bc980340SAmy Huang
moduleIndexForSectOffset(uint32_t Sect,uint32_t Offset,uint16_t & ModuleIndex) const411bc980340SAmy Huang bool NativeSession::moduleIndexForSectOffset(uint32_t Sect, uint32_t Offset,
412bc980340SAmy Huang uint16_t &ModuleIndex) const {
413bc980340SAmy Huang ModuleIndex = 0;
414bc980340SAmy Huang auto Iter = AddrToModuleIndex.find(getVAFromSectOffset(Sect, Offset));
415bc980340SAmy Huang if (Iter == AddrToModuleIndex.end())
416bc980340SAmy Huang return false;
417bc980340SAmy Huang ModuleIndex = Iter.value();
418bc980340SAmy Huang return true;
419bc980340SAmy Huang }
420bc980340SAmy Huang
parseSectionContribs()421bc980340SAmy Huang void NativeSession::parseSectionContribs() {
422bc980340SAmy Huang auto Dbi = Pdb->getPDBDbiStream();
423bc980340SAmy Huang if (!Dbi)
424bc980340SAmy Huang return;
425bc980340SAmy Huang
426bc980340SAmy Huang class Visitor : public ISectionContribVisitor {
427bc980340SAmy Huang NativeSession &Session;
428bc980340SAmy Huang IMap &AddrMap;
429bc980340SAmy Huang
430bc980340SAmy Huang public:
431bc980340SAmy Huang Visitor(NativeSession &Session, IMap &AddrMap)
432bc980340SAmy Huang : Session(Session), AddrMap(AddrMap) {}
433bc980340SAmy Huang void visit(const SectionContrib &C) override {
434bc980340SAmy Huang if (C.Size == 0)
435bc980340SAmy Huang return;
436bc980340SAmy Huang
437bc980340SAmy Huang uint64_t VA = Session.getVAFromSectOffset(C.ISect, C.Off);
438bc980340SAmy Huang uint64_t End = VA + C.Size;
439bc980340SAmy Huang
440bc980340SAmy Huang // Ignore overlapping sections based on the assumption that a valid
441bc980340SAmy Huang // PDB file should not have overlaps.
442bc980340SAmy Huang if (!AddrMap.overlaps(VA, End))
443bc980340SAmy Huang AddrMap.insert(VA, End, C.Imod);
444bc980340SAmy Huang }
445bc980340SAmy Huang void visit(const SectionContrib2 &C) override { visit(C.Base); }
446bc980340SAmy Huang };
447bc980340SAmy Huang
448bc980340SAmy Huang Visitor V(*this, AddrToModuleIndex);
449bc980340SAmy Huang Dbi->visitSectionContributions(V);
450bc980340SAmy Huang }
451bc980340SAmy Huang
452bc980340SAmy Huang Expected<ModuleDebugStreamRef>
getModuleDebugStream(uint32_t Index) const453bc980340SAmy Huang NativeSession::getModuleDebugStream(uint32_t Index) const {
454bc980340SAmy Huang auto *Dbi = getDbiStreamPtr(*Pdb);
455bc980340SAmy Huang assert(Dbi && "Dbi stream not present");
456bc980340SAmy Huang
457bc980340SAmy Huang DbiModuleDescriptor Modi = Dbi->modules().getModuleDescriptor(Index);
458bc980340SAmy Huang
459bc980340SAmy Huang uint16_t ModiStream = Modi.getModuleStreamIndex();
460bc980340SAmy Huang if (ModiStream == kInvalidStreamIndex)
461bc980340SAmy Huang return make_error<RawError>("Module stream not present");
462bc980340SAmy Huang
463bc980340SAmy Huang std::unique_ptr<msf::MappedBlockStream> ModStreamData =
464bc980340SAmy Huang Pdb->createIndexedStream(ModiStream);
465bc980340SAmy Huang
466bc980340SAmy Huang ModuleDebugStreamRef ModS(Modi, std::move(ModStreamData));
467bc980340SAmy Huang if (auto EC = ModS.reload())
468bc980340SAmy Huang return std::move(EC);
469bc980340SAmy Huang
470bc980340SAmy Huang return std::move(ModS);
471bc980340SAmy Huang }
472