NativeSession.cpp 15 KB

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