NativeEnumInjectedSources.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. //==- NativeEnumInjectedSources.cpp - Native Injected Source Enumerator --*-==//
  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/NativeEnumInjectedSources.h"
  9. #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
  10. #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
  11. #include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
  12. namespace llvm {
  13. namespace pdb {
  14. namespace {
  15. Expected<std::string> readStreamData(BinaryStream &Stream, uint64_t Limit) {
  16. uint64_t Offset = 0, DataLength = std::min(Limit, Stream.getLength());
  17. std::string Result;
  18. Result.reserve(DataLength);
  19. while (Offset < DataLength) {
  20. ArrayRef<uint8_t> Data;
  21. if (auto E = Stream.readLongestContiguousChunk(Offset, Data))
  22. return std::move(E);
  23. Data = Data.take_front(DataLength - Offset);
  24. Offset += Data.size();
  25. Result += toStringRef(Data);
  26. }
  27. return Result;
  28. }
  29. class NativeInjectedSource final : public IPDBInjectedSource {
  30. const SrcHeaderBlockEntry &Entry;
  31. const PDBStringTable &Strings;
  32. PDBFile &File;
  33. public:
  34. NativeInjectedSource(const SrcHeaderBlockEntry &Entry,
  35. PDBFile &File, const PDBStringTable &Strings)
  36. : Entry(Entry), Strings(Strings), File(File) {}
  37. uint32_t getCrc32() const override { return Entry.CRC; }
  38. uint64_t getCodeByteSize() const override { return Entry.FileSize; }
  39. std::string getFileName() const override {
  40. StringRef Ret = cantFail(Strings.getStringForID(Entry.FileNI),
  41. "InjectedSourceStream should have rejected this");
  42. return std::string(Ret);
  43. }
  44. std::string getObjectFileName() const override {
  45. StringRef Ret = cantFail(Strings.getStringForID(Entry.ObjNI),
  46. "InjectedSourceStream should have rejected this");
  47. return std::string(Ret);
  48. }
  49. std::string getVirtualFileName() const override {
  50. StringRef Ret = cantFail(Strings.getStringForID(Entry.VFileNI),
  51. "InjectedSourceStream should have rejected this");
  52. return std::string(Ret);
  53. }
  54. uint32_t getCompression() const override { return Entry.Compression; }
  55. std::string getCode() const override {
  56. // Get name of stream storing the data.
  57. StringRef VName =
  58. cantFail(Strings.getStringForID(Entry.VFileNI),
  59. "InjectedSourceStream should have rejected this");
  60. std::string StreamName = ("/src/files/" + VName).str();
  61. // Find stream with that name and read its data.
  62. // FIXME: Consider validating (or even loading) all this in
  63. // InjectedSourceStream so that no error can happen here.
  64. auto ExpectedFileStream = File.safelyCreateNamedStream(StreamName);
  65. if (!ExpectedFileStream) {
  66. consumeError(ExpectedFileStream.takeError());
  67. return "(failed to open data stream)";
  68. }
  69. auto Data = readStreamData(**ExpectedFileStream, Entry.FileSize);
  70. if (!Data) {
  71. consumeError(Data.takeError());
  72. return "(failed to read data)";
  73. }
  74. return *Data;
  75. }
  76. };
  77. } // namespace
  78. NativeEnumInjectedSources::NativeEnumInjectedSources(
  79. PDBFile &File, const InjectedSourceStream &IJS,
  80. const PDBStringTable &Strings)
  81. : File(File), Stream(IJS), Strings(Strings), Cur(Stream.begin()) {}
  82. uint32_t NativeEnumInjectedSources::getChildCount() const {
  83. return static_cast<uint32_t>(Stream.size());
  84. }
  85. std::unique_ptr<IPDBInjectedSource>
  86. NativeEnumInjectedSources::getChildAtIndex(uint32_t N) const {
  87. if (N >= getChildCount())
  88. return nullptr;
  89. return std::make_unique<NativeInjectedSource>(std::next(Stream.begin(), N)->second,
  90. File, Strings);
  91. }
  92. std::unique_ptr<IPDBInjectedSource> NativeEnumInjectedSources::getNext() {
  93. if (Cur == Stream.end())
  94. return nullptr;
  95. return std::make_unique<NativeInjectedSource>((Cur++)->second, File, Strings);
  96. }
  97. void NativeEnumInjectedSources::reset() { Cur = Stream.begin(); }
  98. }
  99. }