10b57cec5SDimitry Andric //===- NativeSession.cpp - Native implementation of IPDBSession -*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/NativeSession.h"
100b57cec5SDimitry Andric
1106c3fb27SDimitry Andric #include "llvm/ADT/SmallString.h"
1281ad6265SDimitry Andric #include "llvm/BinaryFormat/Magic.h"
1381ad6265SDimitry Andric #include "llvm/DebugInfo/MSF/MSFCommon.h"
1481ad6265SDimitry Andric #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
150b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
160b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
1781ad6265SDimitry Andric #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
1881ad6265SDimitry Andric #include "llvm/DebugInfo/PDB/Native/DbiModuleList.h"
195ffd83dbSDimitry Andric #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
20e8d8bef9SDimitry Andric #include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h"
2181ad6265SDimitry Andric #include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
220b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/NativeEnumInjectedSources.h"
230b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/NativeExeSymbol.h"
240b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
2581ad6265SDimitry Andric #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
260b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/RawError.h"
2781ad6265SDimitry Andric #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
280b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
2981ad6265SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbol.h"
300b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
310b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
3281ad6265SDimitry Andric #include "llvm/Object/Binary.h"
335ffd83dbSDimitry Andric #include "llvm/Object/COFF.h"
340b57cec5SDimitry Andric #include "llvm/Support/Allocator.h"
350b57cec5SDimitry Andric #include "llvm/Support/BinaryByteStream.h"
3681ad6265SDimitry Andric #include "llvm/Support/BinaryStreamArray.h"
370b57cec5SDimitry Andric #include "llvm/Support/Error.h"
380b57cec5SDimitry Andric #include "llvm/Support/ErrorOr.h"
390b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
405ffd83dbSDimitry Andric #include "llvm/Support/Path.h"
410b57cec5SDimitry Andric
420b57cec5SDimitry Andric #include <algorithm>
430b57cec5SDimitry Andric #include <cassert>
440b57cec5SDimitry Andric #include <memory>
450b57cec5SDimitry Andric #include <utility>
460b57cec5SDimitry Andric
470b57cec5SDimitry Andric using namespace llvm;
480b57cec5SDimitry Andric using namespace llvm::msf;
490b57cec5SDimitry Andric using namespace llvm::pdb;
500b57cec5SDimitry Andric
5181ad6265SDimitry Andric namespace llvm {
5281ad6265SDimitry Andric namespace codeview {
5381ad6265SDimitry Andric union DebugInfo;
5481ad6265SDimitry Andric }
5581ad6265SDimitry Andric } // namespace llvm
5681ad6265SDimitry Andric
getDbiStreamPtr(PDBFile & File)570b57cec5SDimitry Andric static DbiStream *getDbiStreamPtr(PDBFile &File) {
580b57cec5SDimitry Andric Expected<DbiStream &> DbiS = File.getPDBDbiStream();
590b57cec5SDimitry Andric if (DbiS)
600b57cec5SDimitry Andric return &DbiS.get();
610b57cec5SDimitry Andric
620b57cec5SDimitry Andric consumeError(DbiS.takeError());
630b57cec5SDimitry Andric return nullptr;
640b57cec5SDimitry Andric }
650b57cec5SDimitry Andric
NativeSession(std::unique_ptr<PDBFile> PdbFile,std::unique_ptr<BumpPtrAllocator> Allocator)660b57cec5SDimitry Andric NativeSession::NativeSession(std::unique_ptr<PDBFile> PdbFile,
670b57cec5SDimitry Andric std::unique_ptr<BumpPtrAllocator> Allocator)
680b57cec5SDimitry Andric : Pdb(std::move(PdbFile)), Allocator(std::move(Allocator)),
69e8d8bef9SDimitry Andric Cache(*this, getDbiStreamPtr(*Pdb)), AddrToModuleIndex(IMapAllocator) {}
700b57cec5SDimitry Andric
710b57cec5SDimitry Andric NativeSession::~NativeSession() = default;
720b57cec5SDimitry Andric
createFromPdb(std::unique_ptr<MemoryBuffer> Buffer,std::unique_ptr<IPDBSession> & Session)730b57cec5SDimitry Andric Error NativeSession::createFromPdb(std::unique_ptr<MemoryBuffer> Buffer,
740b57cec5SDimitry Andric std::unique_ptr<IPDBSession> &Session) {
750b57cec5SDimitry Andric StringRef Path = Buffer->getBufferIdentifier();
768bcb0991SDimitry Andric auto Stream = std::make_unique<MemoryBufferByteStream>(
77*5f757f3fSDimitry Andric std::move(Buffer), llvm::endianness::little);
780b57cec5SDimitry Andric
798bcb0991SDimitry Andric auto Allocator = std::make_unique<BumpPtrAllocator>();
808bcb0991SDimitry Andric auto File = std::make_unique<PDBFile>(Path, std::move(Stream), *Allocator);
810b57cec5SDimitry Andric if (auto EC = File->parseFileHeaders())
820b57cec5SDimitry Andric return EC;
830b57cec5SDimitry Andric if (auto EC = File->parseStreamData())
840b57cec5SDimitry Andric return EC;
850b57cec5SDimitry Andric
860b57cec5SDimitry Andric Session =
878bcb0991SDimitry Andric std::make_unique<NativeSession>(std::move(File), std::move(Allocator));
880b57cec5SDimitry Andric
890b57cec5SDimitry Andric return Error::success();
900b57cec5SDimitry Andric }
910b57cec5SDimitry Andric
925ffd83dbSDimitry Andric static Expected<std::unique_ptr<PDBFile>>
loadPdbFile(StringRef PdbPath,std::unique_ptr<BumpPtrAllocator> & Allocator)935ffd83dbSDimitry Andric loadPdbFile(StringRef PdbPath, std::unique_ptr<BumpPtrAllocator> &Allocator) {
945ffd83dbSDimitry Andric ErrorOr<std::unique_ptr<MemoryBuffer>> ErrorOrBuffer =
95fe6060f1SDimitry Andric MemoryBuffer::getFile(PdbPath, /*IsText=*/false,
965ffd83dbSDimitry Andric /*RequiresNullTerminator=*/false);
975ffd83dbSDimitry Andric if (!ErrorOrBuffer)
985ffd83dbSDimitry Andric return make_error<RawError>(ErrorOrBuffer.getError());
995ffd83dbSDimitry Andric std::unique_ptr<llvm::MemoryBuffer> Buffer = std::move(*ErrorOrBuffer);
1005ffd83dbSDimitry Andric
1015ffd83dbSDimitry Andric PdbPath = Buffer->getBufferIdentifier();
1025ffd83dbSDimitry Andric file_magic Magic;
1035ffd83dbSDimitry Andric auto EC = identify_magic(PdbPath, Magic);
1045ffd83dbSDimitry Andric if (EC || Magic != file_magic::pdb)
1055ffd83dbSDimitry Andric return make_error<RawError>(EC);
1065ffd83dbSDimitry Andric
107*5f757f3fSDimitry Andric auto Stream = std::make_unique<MemoryBufferByteStream>(
108*5f757f3fSDimitry Andric std::move(Buffer), llvm::endianness::little);
1095ffd83dbSDimitry Andric
1105ffd83dbSDimitry Andric auto File = std::make_unique<PDBFile>(PdbPath, std::move(Stream), *Allocator);
1115ffd83dbSDimitry Andric if (auto EC = File->parseFileHeaders())
1125ffd83dbSDimitry Andric return std::move(EC);
1135ffd83dbSDimitry Andric
1145ffd83dbSDimitry Andric if (auto EC = File->parseStreamData())
1155ffd83dbSDimitry Andric return std::move(EC);
1165ffd83dbSDimitry Andric
1175ffd83dbSDimitry Andric return std::move(File);
1180b57cec5SDimitry Andric }
1190b57cec5SDimitry Andric
createFromPdbPath(StringRef PdbPath,std::unique_ptr<IPDBSession> & Session)1205ffd83dbSDimitry Andric Error NativeSession::createFromPdbPath(StringRef PdbPath,
1215ffd83dbSDimitry Andric std::unique_ptr<IPDBSession> &Session) {
1225ffd83dbSDimitry Andric auto Allocator = std::make_unique<BumpPtrAllocator>();
1235ffd83dbSDimitry Andric auto PdbFile = loadPdbFile(PdbPath, Allocator);
1245ffd83dbSDimitry Andric if (!PdbFile)
1255ffd83dbSDimitry Andric return PdbFile.takeError();
1260b57cec5SDimitry Andric
1275ffd83dbSDimitry Andric Session = std::make_unique<NativeSession>(std::move(PdbFile.get()),
1285ffd83dbSDimitry Andric std::move(Allocator));
1295ffd83dbSDimitry Andric return Error::success();
1305ffd83dbSDimitry Andric }
1315ffd83dbSDimitry Andric
getPdbPathFromExe(StringRef ExePath)1325ffd83dbSDimitry Andric static Expected<std::string> getPdbPathFromExe(StringRef ExePath) {
1335ffd83dbSDimitry Andric Expected<object::OwningBinary<object::Binary>> BinaryFile =
1345ffd83dbSDimitry Andric object::createBinary(ExePath);
1355ffd83dbSDimitry Andric if (!BinaryFile)
1365ffd83dbSDimitry Andric return BinaryFile.takeError();
1375ffd83dbSDimitry Andric
1385ffd83dbSDimitry Andric const object::COFFObjectFile *ObjFile =
1395ffd83dbSDimitry Andric dyn_cast<object::COFFObjectFile>(BinaryFile->getBinary());
1405ffd83dbSDimitry Andric if (!ObjFile)
1415ffd83dbSDimitry Andric return make_error<RawError>(raw_error_code::invalid_format);
1425ffd83dbSDimitry Andric
1435ffd83dbSDimitry Andric StringRef PdbPath;
1445ffd83dbSDimitry Andric const llvm::codeview::DebugInfo *PdbInfo = nullptr;
1455ffd83dbSDimitry Andric if (Error E = ObjFile->getDebugPDBInfo(PdbInfo, PdbPath))
1465ffd83dbSDimitry Andric return std::move(E);
1475ffd83dbSDimitry Andric
1485ffd83dbSDimitry Andric return std::string(PdbPath);
1495ffd83dbSDimitry Andric }
1505ffd83dbSDimitry Andric
createFromExe(StringRef ExePath,std::unique_ptr<IPDBSession> & Session)1515ffd83dbSDimitry Andric Error NativeSession::createFromExe(StringRef ExePath,
1525ffd83dbSDimitry Andric std::unique_ptr<IPDBSession> &Session) {
1535ffd83dbSDimitry Andric Expected<std::string> PdbPath = getPdbPathFromExe(ExePath);
1545ffd83dbSDimitry Andric if (!PdbPath)
1555ffd83dbSDimitry Andric return PdbPath.takeError();
1565ffd83dbSDimitry Andric
1575ffd83dbSDimitry Andric file_magic Magic;
1585ffd83dbSDimitry Andric auto EC = identify_magic(PdbPath.get(), Magic);
1595ffd83dbSDimitry Andric if (EC || Magic != file_magic::pdb)
1605ffd83dbSDimitry Andric return make_error<RawError>(EC);
1615ffd83dbSDimitry Andric
1625ffd83dbSDimitry Andric auto Allocator = std::make_unique<BumpPtrAllocator>();
1635ffd83dbSDimitry Andric auto File = loadPdbFile(PdbPath.get(), Allocator);
1645ffd83dbSDimitry Andric if (!File)
1655ffd83dbSDimitry Andric return File.takeError();
1665ffd83dbSDimitry Andric
1675ffd83dbSDimitry Andric Session = std::make_unique<NativeSession>(std::move(File.get()),
1685ffd83dbSDimitry Andric std::move(Allocator));
1695ffd83dbSDimitry Andric
1705ffd83dbSDimitry Andric return Error::success();
1715ffd83dbSDimitry Andric }
1725ffd83dbSDimitry Andric
1735ffd83dbSDimitry Andric Expected<std::string>
searchForPdb(const PdbSearchOptions & Opts)1745ffd83dbSDimitry Andric NativeSession::searchForPdb(const PdbSearchOptions &Opts) {
1755ffd83dbSDimitry Andric Expected<std::string> PathOrErr = getPdbPathFromExe(Opts.ExePath);
1765ffd83dbSDimitry Andric if (!PathOrErr)
1775ffd83dbSDimitry Andric return PathOrErr.takeError();
1785ffd83dbSDimitry Andric StringRef PathFromExe = PathOrErr.get();
179*5f757f3fSDimitry Andric sys::path::Style Style = PathFromExe.starts_with("/")
1805ffd83dbSDimitry Andric ? sys::path::Style::posix
1815ffd83dbSDimitry Andric : sys::path::Style::windows;
1825ffd83dbSDimitry Andric StringRef PdbName = sys::path::filename(PathFromExe, Style);
1835ffd83dbSDimitry Andric
1845ffd83dbSDimitry Andric // Check if pdb exists in the executable directory.
1855ffd83dbSDimitry Andric SmallString<128> PdbPath = StringRef(Opts.ExePath);
1865ffd83dbSDimitry Andric sys::path::remove_filename(PdbPath);
1875ffd83dbSDimitry Andric sys::path::append(PdbPath, PdbName);
1885ffd83dbSDimitry Andric
1895ffd83dbSDimitry Andric auto Allocator = std::make_unique<BumpPtrAllocator>();
1905ffd83dbSDimitry Andric
1915ffd83dbSDimitry Andric if (auto File = loadPdbFile(PdbPath, Allocator))
1925ffd83dbSDimitry Andric return std::string(PdbPath);
1935ffd83dbSDimitry Andric else
1945ffd83dbSDimitry Andric consumeError(File.takeError());
1955ffd83dbSDimitry Andric
1965ffd83dbSDimitry Andric // Check path that was in the executable.
1975ffd83dbSDimitry Andric if (auto File = loadPdbFile(PathFromExe, Allocator))
1985ffd83dbSDimitry Andric return std::string(PathFromExe);
1995ffd83dbSDimitry Andric else
2005ffd83dbSDimitry Andric return File.takeError();
2015ffd83dbSDimitry Andric
2025ffd83dbSDimitry Andric return make_error<RawError>("PDB not found");
2035ffd83dbSDimitry Andric }
2045ffd83dbSDimitry Andric
getLoadAddress() const2055ffd83dbSDimitry Andric uint64_t NativeSession::getLoadAddress() const { return LoadAddress; }
2065ffd83dbSDimitry Andric
setLoadAddress(uint64_t Address)2075ffd83dbSDimitry Andric bool NativeSession::setLoadAddress(uint64_t Address) {
2085ffd83dbSDimitry Andric LoadAddress = Address;
2095ffd83dbSDimitry Andric return true;
2105ffd83dbSDimitry Andric }
2110b57cec5SDimitry Andric
getGlobalScope()2120b57cec5SDimitry Andric std::unique_ptr<PDBSymbolExe> NativeSession::getGlobalScope() {
2130b57cec5SDimitry Andric return PDBSymbol::createAs<PDBSymbolExe>(*this, getNativeGlobalScope());
2140b57cec5SDimitry Andric }
2150b57cec5SDimitry Andric
2160b57cec5SDimitry Andric std::unique_ptr<PDBSymbol>
getSymbolById(SymIndexId SymbolId) const2170b57cec5SDimitry Andric NativeSession::getSymbolById(SymIndexId SymbolId) const {
2180b57cec5SDimitry Andric return Cache.getSymbolById(SymbolId);
2190b57cec5SDimitry Andric }
2200b57cec5SDimitry Andric
addressForVA(uint64_t VA,uint32_t & Section,uint32_t & Offset) const2210b57cec5SDimitry Andric bool NativeSession::addressForVA(uint64_t VA, uint32_t &Section,
2220b57cec5SDimitry Andric uint32_t &Offset) const {
2235ffd83dbSDimitry Andric uint32_t RVA = VA - getLoadAddress();
2245ffd83dbSDimitry Andric return addressForRVA(RVA, Section, Offset);
2250b57cec5SDimitry Andric }
2260b57cec5SDimitry Andric
addressForRVA(uint32_t RVA,uint32_t & Section,uint32_t & Offset) const2275ffd83dbSDimitry Andric bool NativeSession::addressForRVA(uint32_t RVA, uint32_t &Section,
2280b57cec5SDimitry Andric uint32_t &Offset) const {
2295ffd83dbSDimitry Andric Section = 0;
2305ffd83dbSDimitry Andric Offset = 0;
2315ffd83dbSDimitry Andric
2325ffd83dbSDimitry Andric auto Dbi = Pdb->getPDBDbiStream();
2335ffd83dbSDimitry Andric if (!Dbi)
2340b57cec5SDimitry Andric return false;
2355ffd83dbSDimitry Andric
2365ffd83dbSDimitry Andric if ((int32_t)RVA < 0)
2375ffd83dbSDimitry Andric return true;
2385ffd83dbSDimitry Andric
2395ffd83dbSDimitry Andric Offset = RVA;
2405ffd83dbSDimitry Andric for (; Section < Dbi->getSectionHeaders().size(); ++Section) {
2415ffd83dbSDimitry Andric auto &Sec = Dbi->getSectionHeaders()[Section];
2425ffd83dbSDimitry Andric if (RVA < Sec.VirtualAddress)
2435ffd83dbSDimitry Andric return true;
2445ffd83dbSDimitry Andric Offset = RVA - Sec.VirtualAddress;
2455ffd83dbSDimitry Andric }
2465ffd83dbSDimitry Andric return true;
2470b57cec5SDimitry Andric }
2480b57cec5SDimitry Andric
2490b57cec5SDimitry Andric std::unique_ptr<PDBSymbol>
findSymbolByAddress(uint64_t Address,PDB_SymType Type)2505ffd83dbSDimitry Andric NativeSession::findSymbolByAddress(uint64_t Address, PDB_SymType Type) {
2515ffd83dbSDimitry Andric uint32_t Section;
2525ffd83dbSDimitry Andric uint32_t Offset;
2535ffd83dbSDimitry Andric addressForVA(Address, Section, Offset);
2545ffd83dbSDimitry Andric return findSymbolBySectOffset(Section, Offset, Type);
2550b57cec5SDimitry Andric }
2560b57cec5SDimitry Andric
findSymbolByRVA(uint32_t RVA,PDB_SymType Type)2575ffd83dbSDimitry Andric std::unique_ptr<PDBSymbol> NativeSession::findSymbolByRVA(uint32_t RVA,
2585ffd83dbSDimitry Andric PDB_SymType Type) {
2595ffd83dbSDimitry Andric uint32_t Section;
2605ffd83dbSDimitry Andric uint32_t Offset;
2615ffd83dbSDimitry Andric addressForRVA(RVA, Section, Offset);
2625ffd83dbSDimitry Andric return findSymbolBySectOffset(Section, Offset, Type);
2630b57cec5SDimitry Andric }
2640b57cec5SDimitry Andric
2650b57cec5SDimitry Andric std::unique_ptr<PDBSymbol>
findSymbolBySectOffset(uint32_t Sect,uint32_t Offset,PDB_SymType Type)2660b57cec5SDimitry Andric NativeSession::findSymbolBySectOffset(uint32_t Sect, uint32_t Offset,
2675ffd83dbSDimitry Andric PDB_SymType Type) {
268e8d8bef9SDimitry Andric if (AddrToModuleIndex.empty())
269e8d8bef9SDimitry Andric parseSectionContribs();
270e8d8bef9SDimitry Andric
2715ffd83dbSDimitry Andric return Cache.findSymbolBySectOffset(Sect, Offset, Type);
2720b57cec5SDimitry Andric }
2730b57cec5SDimitry Andric
2740b57cec5SDimitry Andric std::unique_ptr<IPDBEnumLineNumbers>
findLineNumbers(const PDBSymbolCompiland & Compiland,const IPDBSourceFile & File) const2750b57cec5SDimitry Andric NativeSession::findLineNumbers(const PDBSymbolCompiland &Compiland,
2760b57cec5SDimitry Andric const IPDBSourceFile &File) const {
2770b57cec5SDimitry Andric return nullptr;
2780b57cec5SDimitry Andric }
2790b57cec5SDimitry Andric
2800b57cec5SDimitry Andric std::unique_ptr<IPDBEnumLineNumbers>
findLineNumbersByAddress(uint64_t Address,uint32_t Length) const2810b57cec5SDimitry Andric NativeSession::findLineNumbersByAddress(uint64_t Address,
2820b57cec5SDimitry Andric uint32_t Length) const {
2835ffd83dbSDimitry Andric return Cache.findLineNumbersByVA(Address, Length);
2840b57cec5SDimitry Andric }
2850b57cec5SDimitry Andric
2860b57cec5SDimitry Andric std::unique_ptr<IPDBEnumLineNumbers>
findLineNumbersByRVA(uint32_t RVA,uint32_t Length) const2870b57cec5SDimitry Andric NativeSession::findLineNumbersByRVA(uint32_t RVA, uint32_t Length) const {
288e8d8bef9SDimitry Andric return Cache.findLineNumbersByVA(getLoadAddress() + RVA, Length);
2890b57cec5SDimitry Andric }
2900b57cec5SDimitry Andric
2910b57cec5SDimitry Andric std::unique_ptr<IPDBEnumLineNumbers>
findLineNumbersBySectOffset(uint32_t Section,uint32_t Offset,uint32_t Length) const2920b57cec5SDimitry Andric NativeSession::findLineNumbersBySectOffset(uint32_t Section, uint32_t Offset,
2930b57cec5SDimitry Andric uint32_t Length) const {
2945ffd83dbSDimitry Andric uint64_t VA = getVAFromSectOffset(Section, Offset);
295e8d8bef9SDimitry Andric return Cache.findLineNumbersByVA(VA, Length);
2960b57cec5SDimitry Andric }
2970b57cec5SDimitry Andric
2980b57cec5SDimitry Andric std::unique_ptr<IPDBEnumSourceFiles>
findSourceFiles(const PDBSymbolCompiland * Compiland,StringRef Pattern,PDB_NameSearchFlags Flags) const2990b57cec5SDimitry Andric NativeSession::findSourceFiles(const PDBSymbolCompiland *Compiland,
3000b57cec5SDimitry Andric StringRef Pattern,
3010b57cec5SDimitry Andric PDB_NameSearchFlags Flags) const {
3020b57cec5SDimitry Andric return nullptr;
3030b57cec5SDimitry Andric }
3040b57cec5SDimitry Andric
3050b57cec5SDimitry Andric std::unique_ptr<IPDBSourceFile>
findOneSourceFile(const PDBSymbolCompiland * Compiland,StringRef Pattern,PDB_NameSearchFlags Flags) const3060b57cec5SDimitry Andric NativeSession::findOneSourceFile(const PDBSymbolCompiland *Compiland,
3070b57cec5SDimitry Andric StringRef Pattern,
3080b57cec5SDimitry Andric PDB_NameSearchFlags Flags) const {
3090b57cec5SDimitry Andric return nullptr;
3100b57cec5SDimitry Andric }
3110b57cec5SDimitry Andric
3120b57cec5SDimitry Andric std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
findCompilandsForSourceFile(StringRef Pattern,PDB_NameSearchFlags Flags) const3130b57cec5SDimitry Andric NativeSession::findCompilandsForSourceFile(StringRef Pattern,
3140b57cec5SDimitry Andric PDB_NameSearchFlags Flags) const {
3150b57cec5SDimitry Andric return nullptr;
3160b57cec5SDimitry Andric }
3170b57cec5SDimitry Andric
3180b57cec5SDimitry Andric std::unique_ptr<PDBSymbolCompiland>
findOneCompilandForSourceFile(StringRef Pattern,PDB_NameSearchFlags Flags) const3190b57cec5SDimitry Andric NativeSession::findOneCompilandForSourceFile(StringRef Pattern,
3200b57cec5SDimitry Andric PDB_NameSearchFlags Flags) const {
3210b57cec5SDimitry Andric return nullptr;
3220b57cec5SDimitry Andric }
3230b57cec5SDimitry Andric
getAllSourceFiles() const3240b57cec5SDimitry Andric std::unique_ptr<IPDBEnumSourceFiles> NativeSession::getAllSourceFiles() const {
3250b57cec5SDimitry Andric return nullptr;
3260b57cec5SDimitry Andric }
3270b57cec5SDimitry Andric
getSourceFilesForCompiland(const PDBSymbolCompiland & Compiland) const3280b57cec5SDimitry Andric std::unique_ptr<IPDBEnumSourceFiles> NativeSession::getSourceFilesForCompiland(
3290b57cec5SDimitry Andric const PDBSymbolCompiland &Compiland) const {
3300b57cec5SDimitry Andric return nullptr;
3310b57cec5SDimitry Andric }
3320b57cec5SDimitry Andric
3330b57cec5SDimitry Andric std::unique_ptr<IPDBSourceFile>
getSourceFileById(uint32_t FileId) const3340b57cec5SDimitry Andric NativeSession::getSourceFileById(uint32_t FileId) const {
3355ffd83dbSDimitry Andric return Cache.getSourceFileById(FileId);
3360b57cec5SDimitry Andric }
3370b57cec5SDimitry Andric
getDebugStreams() const3380b57cec5SDimitry Andric std::unique_ptr<IPDBEnumDataStreams> NativeSession::getDebugStreams() const {
3390b57cec5SDimitry Andric return nullptr;
3400b57cec5SDimitry Andric }
3410b57cec5SDimitry Andric
getEnumTables() const3420b57cec5SDimitry Andric std::unique_ptr<IPDBEnumTables> NativeSession::getEnumTables() const {
3430b57cec5SDimitry Andric return nullptr;
3440b57cec5SDimitry Andric }
3450b57cec5SDimitry Andric
3460b57cec5SDimitry Andric std::unique_ptr<IPDBEnumInjectedSources>
getInjectedSources() const3470b57cec5SDimitry Andric NativeSession::getInjectedSources() const {
3480b57cec5SDimitry Andric auto ISS = Pdb->getInjectedSourceStream();
3490b57cec5SDimitry Andric if (!ISS) {
3500b57cec5SDimitry Andric consumeError(ISS.takeError());
3510b57cec5SDimitry Andric return nullptr;
3520b57cec5SDimitry Andric }
3530b57cec5SDimitry Andric auto Strings = Pdb->getStringTable();
3540b57cec5SDimitry Andric if (!Strings) {
3550b57cec5SDimitry Andric consumeError(Strings.takeError());
3560b57cec5SDimitry Andric return nullptr;
3570b57cec5SDimitry Andric }
3588bcb0991SDimitry Andric return std::make_unique<NativeEnumInjectedSources>(*Pdb, *ISS, *Strings);
3590b57cec5SDimitry Andric }
3600b57cec5SDimitry Andric
3610b57cec5SDimitry Andric std::unique_ptr<IPDBEnumSectionContribs>
getSectionContribs() const3620b57cec5SDimitry Andric NativeSession::getSectionContribs() const {
3630b57cec5SDimitry Andric return nullptr;
3640b57cec5SDimitry Andric }
3650b57cec5SDimitry Andric
3660b57cec5SDimitry Andric std::unique_ptr<IPDBEnumFrameData>
getFrameData() const3670b57cec5SDimitry Andric NativeSession::getFrameData() const {
3680b57cec5SDimitry Andric return nullptr;
3690b57cec5SDimitry Andric }
3700b57cec5SDimitry Andric
initializeExeSymbol()3710b57cec5SDimitry Andric void NativeSession::initializeExeSymbol() {
3720b57cec5SDimitry Andric if (ExeSymbol == 0)
3730b57cec5SDimitry Andric ExeSymbol = Cache.createSymbol<NativeExeSymbol>();
3740b57cec5SDimitry Andric }
3750b57cec5SDimitry Andric
getNativeGlobalScope() const3760b57cec5SDimitry Andric NativeExeSymbol &NativeSession::getNativeGlobalScope() const {
3770b57cec5SDimitry Andric const_cast<NativeSession &>(*this).initializeExeSymbol();
3780b57cec5SDimitry Andric
3790b57cec5SDimitry Andric return Cache.getNativeSymbolById<NativeExeSymbol>(ExeSymbol);
3800b57cec5SDimitry Andric }
3815ffd83dbSDimitry Andric
getRVAFromSectOffset(uint32_t Section,uint32_t Offset) const3825ffd83dbSDimitry Andric uint32_t NativeSession::getRVAFromSectOffset(uint32_t Section,
3835ffd83dbSDimitry Andric uint32_t Offset) const {
3845ffd83dbSDimitry Andric if (Section <= 0)
3855ffd83dbSDimitry Andric return 0;
3865ffd83dbSDimitry Andric
3875ffd83dbSDimitry Andric auto Dbi = getDbiStreamPtr(*Pdb);
3885ffd83dbSDimitry Andric if (!Dbi)
3895ffd83dbSDimitry Andric return 0;
3905ffd83dbSDimitry Andric
3915ffd83dbSDimitry Andric uint32_t MaxSection = Dbi->getSectionHeaders().size();
3925ffd83dbSDimitry Andric if (Section > MaxSection + 1)
3935ffd83dbSDimitry Andric Section = MaxSection + 1;
3945ffd83dbSDimitry Andric auto &Sec = Dbi->getSectionHeaders()[Section - 1];
3955ffd83dbSDimitry Andric return Sec.VirtualAddress + Offset;
3965ffd83dbSDimitry Andric }
3975ffd83dbSDimitry Andric
getVAFromSectOffset(uint32_t Section,uint32_t Offset) const3985ffd83dbSDimitry Andric uint64_t NativeSession::getVAFromSectOffset(uint32_t Section,
3995ffd83dbSDimitry Andric uint32_t Offset) const {
4005ffd83dbSDimitry Andric return LoadAddress + getRVAFromSectOffset(Section, Offset);
4015ffd83dbSDimitry Andric }
402e8d8bef9SDimitry Andric
moduleIndexForVA(uint64_t VA,uint16_t & ModuleIndex) const403e8d8bef9SDimitry Andric bool NativeSession::moduleIndexForVA(uint64_t VA, uint16_t &ModuleIndex) const {
404e8d8bef9SDimitry Andric ModuleIndex = 0;
405e8d8bef9SDimitry Andric auto Iter = AddrToModuleIndex.find(VA);
406e8d8bef9SDimitry Andric if (Iter == AddrToModuleIndex.end())
407e8d8bef9SDimitry Andric return false;
408e8d8bef9SDimitry Andric ModuleIndex = Iter.value();
409e8d8bef9SDimitry Andric return true;
410e8d8bef9SDimitry Andric }
411e8d8bef9SDimitry Andric
moduleIndexForSectOffset(uint32_t Sect,uint32_t Offset,uint16_t & ModuleIndex) const412e8d8bef9SDimitry Andric bool NativeSession::moduleIndexForSectOffset(uint32_t Sect, uint32_t Offset,
413e8d8bef9SDimitry Andric uint16_t &ModuleIndex) const {
414e8d8bef9SDimitry Andric ModuleIndex = 0;
415e8d8bef9SDimitry Andric auto Iter = AddrToModuleIndex.find(getVAFromSectOffset(Sect, Offset));
416e8d8bef9SDimitry Andric if (Iter == AddrToModuleIndex.end())
417e8d8bef9SDimitry Andric return false;
418e8d8bef9SDimitry Andric ModuleIndex = Iter.value();
419e8d8bef9SDimitry Andric return true;
420e8d8bef9SDimitry Andric }
421e8d8bef9SDimitry Andric
parseSectionContribs()422e8d8bef9SDimitry Andric void NativeSession::parseSectionContribs() {
423e8d8bef9SDimitry Andric auto Dbi = Pdb->getPDBDbiStream();
424e8d8bef9SDimitry Andric if (!Dbi)
425e8d8bef9SDimitry Andric return;
426e8d8bef9SDimitry Andric
427e8d8bef9SDimitry Andric class Visitor : public ISectionContribVisitor {
428e8d8bef9SDimitry Andric NativeSession &Session;
429e8d8bef9SDimitry Andric IMap &AddrMap;
430e8d8bef9SDimitry Andric
431e8d8bef9SDimitry Andric public:
432e8d8bef9SDimitry Andric Visitor(NativeSession &Session, IMap &AddrMap)
433e8d8bef9SDimitry Andric : Session(Session), AddrMap(AddrMap) {}
434e8d8bef9SDimitry Andric void visit(const SectionContrib &C) override {
435e8d8bef9SDimitry Andric if (C.Size == 0)
436e8d8bef9SDimitry Andric return;
437e8d8bef9SDimitry Andric
438e8d8bef9SDimitry Andric uint64_t VA = Session.getVAFromSectOffset(C.ISect, C.Off);
439e8d8bef9SDimitry Andric uint64_t End = VA + C.Size;
440e8d8bef9SDimitry Andric
441e8d8bef9SDimitry Andric // Ignore overlapping sections based on the assumption that a valid
442e8d8bef9SDimitry Andric // PDB file should not have overlaps.
443e8d8bef9SDimitry Andric if (!AddrMap.overlaps(VA, End))
444e8d8bef9SDimitry Andric AddrMap.insert(VA, End, C.Imod);
445e8d8bef9SDimitry Andric }
446e8d8bef9SDimitry Andric void visit(const SectionContrib2 &C) override { visit(C.Base); }
447e8d8bef9SDimitry Andric };
448e8d8bef9SDimitry Andric
449e8d8bef9SDimitry Andric Visitor V(*this, AddrToModuleIndex);
450e8d8bef9SDimitry Andric Dbi->visitSectionContributions(V);
451e8d8bef9SDimitry Andric }
452e8d8bef9SDimitry Andric
453e8d8bef9SDimitry Andric Expected<ModuleDebugStreamRef>
getModuleDebugStream(uint32_t Index) const454e8d8bef9SDimitry Andric NativeSession::getModuleDebugStream(uint32_t Index) const {
455e8d8bef9SDimitry Andric auto *Dbi = getDbiStreamPtr(*Pdb);
456e8d8bef9SDimitry Andric assert(Dbi && "Dbi stream not present");
457e8d8bef9SDimitry Andric
458e8d8bef9SDimitry Andric DbiModuleDescriptor Modi = Dbi->modules().getModuleDescriptor(Index);
459e8d8bef9SDimitry Andric
460e8d8bef9SDimitry Andric uint16_t ModiStream = Modi.getModuleStreamIndex();
461e8d8bef9SDimitry Andric if (ModiStream == kInvalidStreamIndex)
462e8d8bef9SDimitry Andric return make_error<RawError>("Module stream not present");
463e8d8bef9SDimitry Andric
464e8d8bef9SDimitry Andric std::unique_ptr<msf::MappedBlockStream> ModStreamData =
465e8d8bef9SDimitry Andric Pdb->createIndexedStream(ModiStream);
466e8d8bef9SDimitry Andric
467e8d8bef9SDimitry Andric ModuleDebugStreamRef ModS(Modi, std::move(ModStreamData));
468e8d8bef9SDimitry Andric if (auto EC = ModS.reload())
469e8d8bef9SDimitry Andric return std::move(EC);
470e8d8bef9SDimitry Andric
471e8d8bef9SDimitry Andric return std::move(ModS);
472e8d8bef9SDimitry Andric }
473