StreamUtil.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. //===- StreamUtil.cpp - PDB stream utilities --------------------*- 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 "StreamUtil.h"
  9. #include "llvm/ADT/DenseMap.h"
  10. #include "llvm/ADT/DenseMapInfo.h"
  11. #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
  12. #include "llvm/DebugInfo/PDB/Native/DbiModuleList.h"
  13. #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
  14. #include "llvm/DebugInfo/PDB/Native/FormatUtil.h"
  15. #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
  16. #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
  17. #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
  18. using namespace llvm;
  19. using namespace llvm::pdb;
  20. std::string StreamInfo::getLongName() const {
  21. if (Purpose == StreamPurpose::NamedStream)
  22. return formatv("Named Stream \"{0}\"", Name).str();
  23. if (Purpose == StreamPurpose::ModuleStream)
  24. return formatv("Module \"{0}\"", Name).str();
  25. return Name;
  26. }
  27. StreamInfo StreamInfo::createStream(StreamPurpose Purpose, StringRef Name,
  28. uint32_t StreamIndex) {
  29. StreamInfo Result;
  30. Result.Name = std::string(Name);
  31. Result.StreamIndex = StreamIndex;
  32. Result.Purpose = Purpose;
  33. return Result;
  34. }
  35. StreamInfo StreamInfo::createModuleStream(StringRef Module,
  36. uint32_t StreamIndex, uint32_t Modi) {
  37. StreamInfo Result;
  38. Result.Name = std::string(Module);
  39. Result.StreamIndex = StreamIndex;
  40. Result.ModuleIndex = Modi;
  41. Result.Purpose = StreamPurpose::ModuleStream;
  42. return Result;
  43. }
  44. static inline StreamInfo stream(StreamPurpose Purpose, StringRef Label,
  45. uint32_t Idx) {
  46. return StreamInfo::createStream(Purpose, Label, Idx);
  47. }
  48. static inline StreamInfo moduleStream(StringRef Label, uint32_t StreamIdx,
  49. uint32_t Modi) {
  50. return StreamInfo::createModuleStream(Label, StreamIdx, Modi);
  51. }
  52. struct IndexedModuleDescriptor {
  53. uint32_t Modi;
  54. DbiModuleDescriptor Descriptor;
  55. };
  56. void llvm::pdb::discoverStreamPurposes(PDBFile &File,
  57. SmallVectorImpl<StreamInfo> &Streams) {
  58. // It's OK if we fail to load some of these streams, we still attempt to print
  59. // what we can.
  60. auto Dbi = File.getPDBDbiStream();
  61. auto Tpi = File.getPDBTpiStream();
  62. auto Ipi = File.getPDBIpiStream();
  63. auto Info = File.getPDBInfoStream();
  64. uint32_t StreamCount = File.getNumStreams();
  65. DenseMap<uint16_t, IndexedModuleDescriptor> ModStreams;
  66. DenseMap<uint16_t, std::string> NamedStreams;
  67. if (Dbi) {
  68. const DbiModuleList &Modules = Dbi->modules();
  69. for (uint32_t I = 0; I < Modules.getModuleCount(); ++I) {
  70. IndexedModuleDescriptor IMD;
  71. IMD.Modi = I;
  72. IMD.Descriptor = Modules.getModuleDescriptor(I);
  73. uint16_t SN = IMD.Descriptor.getModuleStreamIndex();
  74. if (SN != kInvalidStreamIndex)
  75. ModStreams[SN] = IMD;
  76. }
  77. }
  78. if (Info) {
  79. for (auto &NSE : Info->named_streams()) {
  80. if (NSE.second != kInvalidStreamIndex)
  81. NamedStreams[NSE.second] = std::string(NSE.first());
  82. }
  83. }
  84. Streams.resize(StreamCount);
  85. for (uint32_t StreamIdx = 0; StreamIdx < StreamCount; ++StreamIdx) {
  86. if (StreamIdx == OldMSFDirectory)
  87. Streams[StreamIdx] =
  88. stream(StreamPurpose::Other, "Old MSF Directory", StreamIdx);
  89. else if (StreamIdx == StreamPDB)
  90. Streams[StreamIdx] = stream(StreamPurpose::PDB, "PDB Stream", StreamIdx);
  91. else if (StreamIdx == StreamDBI)
  92. Streams[StreamIdx] = stream(StreamPurpose::DBI, "DBI Stream", StreamIdx);
  93. else if (StreamIdx == StreamTPI)
  94. Streams[StreamIdx] = stream(StreamPurpose::TPI, "TPI Stream", StreamIdx);
  95. else if (StreamIdx == StreamIPI)
  96. Streams[StreamIdx] = stream(StreamPurpose::IPI, "IPI Stream", StreamIdx);
  97. else if (Dbi && StreamIdx == Dbi->getGlobalSymbolStreamIndex())
  98. Streams[StreamIdx] =
  99. stream(StreamPurpose::GlobalHash, "Global Symbol Hash", StreamIdx);
  100. else if (Dbi && StreamIdx == Dbi->getPublicSymbolStreamIndex())
  101. Streams[StreamIdx] =
  102. stream(StreamPurpose::PublicHash, "Public Symbol Hash", StreamIdx);
  103. else if (Dbi && StreamIdx == Dbi->getSymRecordStreamIndex())
  104. Streams[StreamIdx] =
  105. stream(StreamPurpose::Symbols, "Symbol Records", StreamIdx);
  106. else if (Tpi && StreamIdx == Tpi->getTypeHashStreamIndex())
  107. Streams[StreamIdx] =
  108. stream(StreamPurpose::TpiHash, "TPI Hash", StreamIdx);
  109. else if (Tpi && StreamIdx == Tpi->getTypeHashStreamAuxIndex())
  110. Streams[StreamIdx] =
  111. stream(StreamPurpose::Other, "TPI Aux Hash", StreamIdx);
  112. else if (Ipi && StreamIdx == Ipi->getTypeHashStreamIndex())
  113. Streams[StreamIdx] =
  114. stream(StreamPurpose::IpiHash, "IPI Hash", StreamIdx);
  115. else if (Ipi && StreamIdx == Ipi->getTypeHashStreamAuxIndex())
  116. Streams[StreamIdx] =
  117. stream(StreamPurpose::Other, "IPI Aux Hash", StreamIdx);
  118. else if (Dbi &&
  119. StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::Exception))
  120. Streams[StreamIdx] =
  121. stream(StreamPurpose::Other, "Exception Data", StreamIdx);
  122. else if (Dbi && StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::Fixup))
  123. Streams[StreamIdx] =
  124. stream(StreamPurpose::Other, "Fixup Data", StreamIdx);
  125. else if (Dbi && StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::FPO))
  126. Streams[StreamIdx] = stream(StreamPurpose::Other, "FPO Data", StreamIdx);
  127. else if (Dbi &&
  128. StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::NewFPO))
  129. Streams[StreamIdx] =
  130. stream(StreamPurpose::Other, "New FPO Data", StreamIdx);
  131. else if (Dbi &&
  132. StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::OmapFromSrc))
  133. Streams[StreamIdx] =
  134. stream(StreamPurpose::Other, "Omap From Source Data", StreamIdx);
  135. else if (Dbi &&
  136. StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::OmapToSrc))
  137. Streams[StreamIdx] =
  138. stream(StreamPurpose::Other, "Omap To Source Data", StreamIdx);
  139. else if (Dbi && StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::Pdata))
  140. Streams[StreamIdx] = stream(StreamPurpose::Other, "Pdata", StreamIdx);
  141. else if (Dbi &&
  142. StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::SectionHdr))
  143. Streams[StreamIdx] =
  144. stream(StreamPurpose::Other, "Section Header Data", StreamIdx);
  145. else if (Dbi &&
  146. StreamIdx ==
  147. Dbi->getDebugStreamIndex(DbgHeaderType::SectionHdrOrig))
  148. Streams[StreamIdx] = stream(StreamPurpose::Other,
  149. "Section Header Original Data", StreamIdx);
  150. else if (Dbi &&
  151. StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::TokenRidMap))
  152. Streams[StreamIdx] =
  153. stream(StreamPurpose::Other, "Token Rid Data", StreamIdx);
  154. else if (Dbi && StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::Xdata))
  155. Streams[StreamIdx] = stream(StreamPurpose::Other, "Xdata", StreamIdx);
  156. else {
  157. auto ModIter = ModStreams.find(StreamIdx);
  158. auto NSIter = NamedStreams.find(StreamIdx);
  159. if (ModIter != ModStreams.end()) {
  160. Streams[StreamIdx] =
  161. moduleStream(ModIter->second.Descriptor.getModuleName(), StreamIdx,
  162. ModIter->second.Modi);
  163. } else if (NSIter != NamedStreams.end()) {
  164. Streams[StreamIdx] =
  165. stream(StreamPurpose::NamedStream, NSIter->second, StreamIdx);
  166. } else {
  167. Streams[StreamIdx] = stream(StreamPurpose::Other, "???", StreamIdx);
  168. }
  169. }
  170. }
  171. // Consume errors from missing streams.
  172. if (!Dbi)
  173. consumeError(Dbi.takeError());
  174. if (!Tpi)
  175. consumeError(Tpi.takeError());
  176. if (!Ipi)
  177. consumeError(Ipi.takeError());
  178. if (!Info)
  179. consumeError(Info.takeError());
  180. }