xref: /freebsd-src/contrib/llvm-project/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
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