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 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 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 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>> 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 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 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 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> 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 2055ffd83dbSDimitry Andric uint64_t NativeSession::getLoadAddress() const { return LoadAddress; } 2065ffd83dbSDimitry Andric 2075ffd83dbSDimitry Andric bool NativeSession::setLoadAddress(uint64_t Address) { 2085ffd83dbSDimitry Andric LoadAddress = Address; 2095ffd83dbSDimitry Andric return true; 2105ffd83dbSDimitry Andric } 2110b57cec5SDimitry Andric 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> 2170b57cec5SDimitry Andric NativeSession::getSymbolById(SymIndexId SymbolId) const { 2180b57cec5SDimitry Andric return Cache.getSymbolById(SymbolId); 2190b57cec5SDimitry Andric } 2200b57cec5SDimitry Andric 2210b57cec5SDimitry 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 2275ffd83dbSDimitry 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> 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 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> 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> 2750b57cec5SDimitry 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> 2810b57cec5SDimitry 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> 2870b57cec5SDimitry 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> 2920b57cec5SDimitry 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> 2990b57cec5SDimitry 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> 3060b57cec5SDimitry 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>> 3130b57cec5SDimitry 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> 3190b57cec5SDimitry Andric NativeSession::findOneCompilandForSourceFile(StringRef Pattern, 3200b57cec5SDimitry Andric PDB_NameSearchFlags Flags) const { 3210b57cec5SDimitry Andric return nullptr; 3220b57cec5SDimitry Andric } 3230b57cec5SDimitry Andric 3240b57cec5SDimitry Andric std::unique_ptr<IPDBEnumSourceFiles> NativeSession::getAllSourceFiles() const { 3250b57cec5SDimitry Andric return nullptr; 3260b57cec5SDimitry Andric } 3270b57cec5SDimitry Andric 3280b57cec5SDimitry 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> 3340b57cec5SDimitry Andric NativeSession::getSourceFileById(uint32_t FileId) const { 3355ffd83dbSDimitry Andric return Cache.getSourceFileById(FileId); 3360b57cec5SDimitry Andric } 3370b57cec5SDimitry Andric 3380b57cec5SDimitry Andric std::unique_ptr<IPDBEnumDataStreams> NativeSession::getDebugStreams() const { 3390b57cec5SDimitry Andric return nullptr; 3400b57cec5SDimitry Andric } 3410b57cec5SDimitry Andric 3420b57cec5SDimitry Andric std::unique_ptr<IPDBEnumTables> NativeSession::getEnumTables() const { 3430b57cec5SDimitry Andric return nullptr; 3440b57cec5SDimitry Andric } 3450b57cec5SDimitry Andric 3460b57cec5SDimitry Andric std::unique_ptr<IPDBEnumInjectedSources> 3470b57cec5SDimitry 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> 3620b57cec5SDimitry Andric NativeSession::getSectionContribs() const { 3630b57cec5SDimitry Andric return nullptr; 3640b57cec5SDimitry Andric } 3650b57cec5SDimitry Andric 3660b57cec5SDimitry Andric std::unique_ptr<IPDBEnumFrameData> 3670b57cec5SDimitry Andric NativeSession::getFrameData() const { 3680b57cec5SDimitry Andric return nullptr; 3690b57cec5SDimitry Andric } 3700b57cec5SDimitry Andric 3710b57cec5SDimitry Andric void NativeSession::initializeExeSymbol() { 3720b57cec5SDimitry Andric if (ExeSymbol == 0) 3730b57cec5SDimitry Andric ExeSymbol = Cache.createSymbol<NativeExeSymbol>(); 3740b57cec5SDimitry Andric } 3750b57cec5SDimitry Andric 3760b57cec5SDimitry 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 3825ffd83dbSDimitry 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 3985ffd83dbSDimitry 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 403e8d8bef9SDimitry 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 412e8d8bef9SDimitry 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 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> 454e8d8bef9SDimitry 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