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