NativeSession.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. //===- NativeSession.cpp - Native implementation of IPDBSession -*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "llvm/DebugInfo/PDB/Native/NativeSession.h"
  9. #include "llvm/ADT/STLExtras.h"
  10. #include "llvm/DebugInfo/CodeView/TypeIndex.h"
  11. #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
  12. #include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
  13. #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
  14. #include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h"
  15. #include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
  16. #include "llvm/DebugInfo/PDB/Native/NativeEnumInjectedSources.h"
  17. #include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
  18. #include "llvm/DebugInfo/PDB/Native/NativeExeSymbol.h"
  19. #include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
  20. #include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
  21. #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
  22. #include "llvm/DebugInfo/PDB/Native/RawError.h"
  23. #include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
  24. #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
  25. #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
  26. #include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
  27. #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
  28. #include "llvm/Object/COFF.h"
  29. #include "llvm/Support/Allocator.h"
  30. #include "llvm/Support/BinaryByteStream.h"
  31. #include "llvm/Support/Error.h"
  32. #include "llvm/Support/ErrorOr.h"
  33. #include "llvm/Support/FileSystem.h"
  34. #include "llvm/Support/MemoryBuffer.h"
  35. #include "llvm/Support/Path.h"
  36. #include <algorithm>
  37. #include <cassert>
  38. #include <memory>
  39. #include <utility>
  40. using namespace llvm;
  41. using namespace llvm::msf;
  42. using namespace llvm::pdb;
  43. static DbiStream *getDbiStreamPtr(PDBFile &File) {
  44. Expected<DbiStream &> DbiS = File.getPDBDbiStream();
  45. if (DbiS)
  46. return &DbiS.get();
  47. consumeError(DbiS.takeError());
  48. return nullptr;
  49. }
  50. NativeSession::NativeSession(std::unique_ptr<PDBFile> PdbFile,
  51. std::unique_ptr<BumpPtrAllocator> Allocator)
  52. : Pdb(std::move(PdbFile)), Allocator(std::move(Allocator)),
  53. Cache(*this, getDbiStreamPtr(*Pdb)), AddrToModuleIndex(IMapAllocator) {}
  54. NativeSession::~NativeSession() = default;
  55. Error NativeSession::createFromPdb(std::unique_ptr<MemoryBuffer> Buffer,
  56. std::unique_ptr<IPDBSession> &Session) {
  57. StringRef Path = Buffer->getBufferIdentifier();
  58. auto Stream = std::make_unique<MemoryBufferByteStream>(
  59. std::move(Buffer), llvm::support::little);
  60. auto Allocator = std::make_unique<BumpPtrAllocator>();
  61. auto File = std::make_unique<PDBFile>(Path, std::move(Stream), *Allocator);
  62. if (auto EC = File->parseFileHeaders())
  63. return EC;
  64. if (auto EC = File->parseStreamData())
  65. return EC;
  66. Session =
  67. std::make_unique<NativeSession>(std::move(File), std::move(Allocator));
  68. return Error::success();
  69. }
  70. static Expected<std::unique_ptr<PDBFile>>
  71. loadPdbFile(StringRef PdbPath, std::unique_ptr<BumpPtrAllocator> &Allocator) {
  72. ErrorOr<std::unique_ptr<MemoryBuffer>> ErrorOrBuffer =
  73. MemoryBuffer::getFile(PdbPath, /*IsText=*/false,
  74. /*RequiresNullTerminator=*/false);
  75. if (!ErrorOrBuffer)
  76. return make_error<RawError>(ErrorOrBuffer.getError());
  77. std::unique_ptr<llvm::MemoryBuffer> Buffer = std::move(*ErrorOrBuffer);
  78. PdbPath = Buffer->getBufferIdentifier();
  79. file_magic Magic;
  80. auto EC = identify_magic(PdbPath, Magic);
  81. if (EC || Magic != file_magic::pdb)
  82. return make_error<RawError>(EC);
  83. auto Stream = std::make_unique<MemoryBufferByteStream>(std::move(Buffer),
  84. llvm::support::little);
  85. auto File = std::make_unique<PDBFile>(PdbPath, std::move(Stream), *Allocator);
  86. if (auto EC = File->parseFileHeaders())
  87. return std::move(EC);
  88. if (auto EC = File->parseStreamData())
  89. return std::move(EC);
  90. return std::move(File);
  91. }
  92. Error NativeSession::createFromPdbPath(StringRef PdbPath,
  93. std::unique_ptr<IPDBSession> &Session) {
  94. auto Allocator = std::make_unique<BumpPtrAllocator>();
  95. auto PdbFile = loadPdbFile(PdbPath, Allocator);
  96. if (!PdbFile)
  97. return PdbFile.takeError();
  98. Session = std::make_unique<NativeSession>(std::move(PdbFile.get()),
  99. std::move(Allocator));
  100. return Error::success();
  101. }
  102. static Expected<std::string> getPdbPathFromExe(StringRef ExePath) {
  103. Expected<object::OwningBinary<object::Binary>> BinaryFile =
  104. object::createBinary(ExePath);
  105. if (!BinaryFile)
  106. return BinaryFile.takeError();
  107. const object::COFFObjectFile *ObjFile =
  108. dyn_cast<object::COFFObjectFile>(BinaryFile->getBinary());
  109. if (!ObjFile)
  110. return make_error<RawError>(raw_error_code::invalid_format);
  111. StringRef PdbPath;
  112. const llvm::codeview::DebugInfo *PdbInfo = nullptr;
  113. if (Error E = ObjFile->getDebugPDBInfo(PdbInfo, PdbPath))
  114. return std::move(E);
  115. return std::string(PdbPath);
  116. }
  117. Error NativeSession::createFromExe(StringRef ExePath,
  118. std::unique_ptr<IPDBSession> &Session) {
  119. Expected<std::string> PdbPath = getPdbPathFromExe(ExePath);
  120. if (!PdbPath)
  121. return PdbPath.takeError();
  122. file_magic Magic;
  123. auto EC = identify_magic(PdbPath.get(), Magic);
  124. if (EC || Magic != file_magic::pdb)
  125. return make_error<RawError>(EC);
  126. auto Allocator = std::make_unique<BumpPtrAllocator>();
  127. auto File = loadPdbFile(PdbPath.get(), Allocator);
  128. if (!File)
  129. return File.takeError();
  130. Session = std::make_unique<NativeSession>(std::move(File.get()),
  131. std::move(Allocator));
  132. return Error::success();
  133. }
  134. Expected<std::string>
  135. NativeSession::searchForPdb(const PdbSearchOptions &Opts) {
  136. Expected<std::string> PathOrErr = getPdbPathFromExe(Opts.ExePath);
  137. if (!PathOrErr)
  138. return PathOrErr.takeError();
  139. StringRef PathFromExe = PathOrErr.get();
  140. sys::path::Style Style = PathFromExe.startswith("/")
  141. ? sys::path::Style::posix
  142. : sys::path::Style::windows;
  143. StringRef PdbName = sys::path::filename(PathFromExe, Style);
  144. // Check if pdb exists in the executable directory.
  145. SmallString<128> PdbPath = StringRef(Opts.ExePath);
  146. sys::path::remove_filename(PdbPath);
  147. sys::path::append(PdbPath, PdbName);
  148. auto Allocator = std::make_unique<BumpPtrAllocator>();
  149. if (auto File = loadPdbFile(PdbPath, Allocator))
  150. return std::string(PdbPath);
  151. else
  152. consumeError(File.takeError());
  153. // Check path that was in the executable.
  154. if (auto File = loadPdbFile(PathFromExe, Allocator))
  155. return std::string(PathFromExe);
  156. else
  157. return File.takeError();
  158. return make_error<RawError>("PDB not found");
  159. }
  160. uint64_t NativeSession::getLoadAddress() const { return LoadAddress; }
  161. bool NativeSession::setLoadAddress(uint64_t Address) {
  162. LoadAddress = Address;
  163. return true;
  164. }
  165. std::unique_ptr<PDBSymbolExe> NativeSession::getGlobalScope() {
  166. return PDBSymbol::createAs<PDBSymbolExe>(*this, getNativeGlobalScope());
  167. }
  168. std::unique_ptr<PDBSymbol>
  169. NativeSession::getSymbolById(SymIndexId SymbolId) const {
  170. return Cache.getSymbolById(SymbolId);
  171. }
  172. bool NativeSession::addressForVA(uint64_t VA, uint32_t &Section,
  173. uint32_t &Offset) const {
  174. uint32_t RVA = VA - getLoadAddress();
  175. return addressForRVA(RVA, Section, Offset);
  176. }
  177. bool NativeSession::addressForRVA(uint32_t RVA, uint32_t &Section,
  178. uint32_t &Offset) const {
  179. Section = 0;
  180. Offset = 0;
  181. auto Dbi = Pdb->getPDBDbiStream();
  182. if (!Dbi)
  183. return false;
  184. if ((int32_t)RVA < 0)
  185. return true;
  186. Offset = RVA;
  187. for (; Section < Dbi->getSectionHeaders().size(); ++Section) {
  188. auto &Sec = Dbi->getSectionHeaders()[Section];
  189. if (RVA < Sec.VirtualAddress)
  190. return true;
  191. Offset = RVA - Sec.VirtualAddress;
  192. }
  193. return true;
  194. }
  195. std::unique_ptr<PDBSymbol>
  196. NativeSession::findSymbolByAddress(uint64_t Address, PDB_SymType Type) {
  197. uint32_t Section;
  198. uint32_t Offset;
  199. addressForVA(Address, Section, Offset);
  200. return findSymbolBySectOffset(Section, Offset, Type);
  201. }
  202. std::unique_ptr<PDBSymbol> NativeSession::findSymbolByRVA(uint32_t RVA,
  203. PDB_SymType Type) {
  204. uint32_t Section;
  205. uint32_t Offset;
  206. addressForRVA(RVA, Section, Offset);
  207. return findSymbolBySectOffset(Section, Offset, Type);
  208. }
  209. std::unique_ptr<PDBSymbol>
  210. NativeSession::findSymbolBySectOffset(uint32_t Sect, uint32_t Offset,
  211. PDB_SymType Type) {
  212. if (AddrToModuleIndex.empty())
  213. parseSectionContribs();
  214. return Cache.findSymbolBySectOffset(Sect, Offset, Type);
  215. }
  216. std::unique_ptr<IPDBEnumLineNumbers>
  217. NativeSession::findLineNumbers(const PDBSymbolCompiland &Compiland,
  218. const IPDBSourceFile &File) const {
  219. return nullptr;
  220. }
  221. std::unique_ptr<IPDBEnumLineNumbers>
  222. NativeSession::findLineNumbersByAddress(uint64_t Address,
  223. uint32_t Length) const {
  224. return Cache.findLineNumbersByVA(Address, Length);
  225. }
  226. std::unique_ptr<IPDBEnumLineNumbers>
  227. NativeSession::findLineNumbersByRVA(uint32_t RVA, uint32_t Length) const {
  228. return Cache.findLineNumbersByVA(getLoadAddress() + RVA, Length);
  229. }
  230. std::unique_ptr<IPDBEnumLineNumbers>
  231. NativeSession::findLineNumbersBySectOffset(uint32_t Section, uint32_t Offset,
  232. uint32_t Length) const {
  233. uint64_t VA = getVAFromSectOffset(Section, Offset);
  234. return Cache.findLineNumbersByVA(VA, Length);
  235. }
  236. std::unique_ptr<IPDBEnumSourceFiles>
  237. NativeSession::findSourceFiles(const PDBSymbolCompiland *Compiland,
  238. StringRef Pattern,
  239. PDB_NameSearchFlags Flags) const {
  240. return nullptr;
  241. }
  242. std::unique_ptr<IPDBSourceFile>
  243. NativeSession::findOneSourceFile(const PDBSymbolCompiland *Compiland,
  244. StringRef Pattern,
  245. PDB_NameSearchFlags Flags) const {
  246. return nullptr;
  247. }
  248. std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
  249. NativeSession::findCompilandsForSourceFile(StringRef Pattern,
  250. PDB_NameSearchFlags Flags) const {
  251. return nullptr;
  252. }
  253. std::unique_ptr<PDBSymbolCompiland>
  254. NativeSession::findOneCompilandForSourceFile(StringRef Pattern,
  255. PDB_NameSearchFlags Flags) const {
  256. return nullptr;
  257. }
  258. std::unique_ptr<IPDBEnumSourceFiles> NativeSession::getAllSourceFiles() const {
  259. return nullptr;
  260. }
  261. std::unique_ptr<IPDBEnumSourceFiles> NativeSession::getSourceFilesForCompiland(
  262. const PDBSymbolCompiland &Compiland) const {
  263. return nullptr;
  264. }
  265. std::unique_ptr<IPDBSourceFile>
  266. NativeSession::getSourceFileById(uint32_t FileId) const {
  267. return Cache.getSourceFileById(FileId);
  268. }
  269. std::unique_ptr<IPDBEnumDataStreams> NativeSession::getDebugStreams() const {
  270. return nullptr;
  271. }
  272. std::unique_ptr<IPDBEnumTables> NativeSession::getEnumTables() const {
  273. return nullptr;
  274. }
  275. std::unique_ptr<IPDBEnumInjectedSources>
  276. NativeSession::getInjectedSources() const {
  277. auto ISS = Pdb->getInjectedSourceStream();
  278. if (!ISS) {
  279. consumeError(ISS.takeError());
  280. return nullptr;
  281. }
  282. auto Strings = Pdb->getStringTable();
  283. if (!Strings) {
  284. consumeError(Strings.takeError());
  285. return nullptr;
  286. }
  287. return std::make_unique<NativeEnumInjectedSources>(*Pdb, *ISS, *Strings);
  288. }
  289. std::unique_ptr<IPDBEnumSectionContribs>
  290. NativeSession::getSectionContribs() const {
  291. return nullptr;
  292. }
  293. std::unique_ptr<IPDBEnumFrameData>
  294. NativeSession::getFrameData() const {
  295. return nullptr;
  296. }
  297. void NativeSession::initializeExeSymbol() {
  298. if (ExeSymbol == 0)
  299. ExeSymbol = Cache.createSymbol<NativeExeSymbol>();
  300. }
  301. NativeExeSymbol &NativeSession::getNativeGlobalScope() const {
  302. const_cast<NativeSession &>(*this).initializeExeSymbol();
  303. return Cache.getNativeSymbolById<NativeExeSymbol>(ExeSymbol);
  304. }
  305. uint32_t NativeSession::getRVAFromSectOffset(uint32_t Section,
  306. uint32_t Offset) const {
  307. if (Section <= 0)
  308. return 0;
  309. auto Dbi = getDbiStreamPtr(*Pdb);
  310. if (!Dbi)
  311. return 0;
  312. uint32_t MaxSection = Dbi->getSectionHeaders().size();
  313. if (Section > MaxSection + 1)
  314. Section = MaxSection + 1;
  315. auto &Sec = Dbi->getSectionHeaders()[Section - 1];
  316. return Sec.VirtualAddress + Offset;
  317. }
  318. uint64_t NativeSession::getVAFromSectOffset(uint32_t Section,
  319. uint32_t Offset) const {
  320. return LoadAddress + getRVAFromSectOffset(Section, Offset);
  321. }
  322. bool NativeSession::moduleIndexForVA(uint64_t VA, uint16_t &ModuleIndex) const {
  323. ModuleIndex = 0;
  324. auto Iter = AddrToModuleIndex.find(VA);
  325. if (Iter == AddrToModuleIndex.end())
  326. return false;
  327. ModuleIndex = Iter.value();
  328. return true;
  329. }
  330. bool NativeSession::moduleIndexForSectOffset(uint32_t Sect, uint32_t Offset,
  331. uint16_t &ModuleIndex) const {
  332. ModuleIndex = 0;
  333. auto Iter = AddrToModuleIndex.find(getVAFromSectOffset(Sect, Offset));
  334. if (Iter == AddrToModuleIndex.end())
  335. return false;
  336. ModuleIndex = Iter.value();
  337. return true;
  338. }
  339. void NativeSession::parseSectionContribs() {
  340. auto Dbi = Pdb->getPDBDbiStream();
  341. if (!Dbi)
  342. return;
  343. class Visitor : public ISectionContribVisitor {
  344. NativeSession &Session;
  345. IMap &AddrMap;
  346. public:
  347. Visitor(NativeSession &Session, IMap &AddrMap)
  348. : Session(Session), AddrMap(AddrMap) {}
  349. void visit(const SectionContrib &C) override {
  350. if (C.Size == 0)
  351. return;
  352. uint64_t VA = Session.getVAFromSectOffset(C.ISect, C.Off);
  353. uint64_t End = VA + C.Size;
  354. // Ignore overlapping sections based on the assumption that a valid
  355. // PDB file should not have overlaps.
  356. if (!AddrMap.overlaps(VA, End))
  357. AddrMap.insert(VA, End, C.Imod);
  358. }
  359. void visit(const SectionContrib2 &C) override { visit(C.Base); }
  360. };
  361. Visitor V(*this, AddrToModuleIndex);
  362. Dbi->visitSectionContributions(V);
  363. }
  364. Expected<ModuleDebugStreamRef>
  365. NativeSession::getModuleDebugStream(uint32_t Index) const {
  366. auto *Dbi = getDbiStreamPtr(*Pdb);
  367. assert(Dbi && "Dbi stream not present");
  368. DbiModuleDescriptor Modi = Dbi->modules().getModuleDescriptor(Index);
  369. uint16_t ModiStream = Modi.getModuleStreamIndex();
  370. if (ModiStream == kInvalidStreamIndex)
  371. return make_error<RawError>("Module stream not present");
  372. std::unique_ptr<msf::MappedBlockStream> ModStreamData =
  373. Pdb->createIndexedStream(ModiStream);
  374. ModuleDebugStreamRef ModS(Modi, std::move(ModStreamData));
  375. if (auto EC = ModS.reload())
  376. return std::move(EC);
  377. return std::move(ModS);
  378. }