1 //===- InfoStream.cpp - PDB Info Stream (Stream 1) Access -------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/DebugInfo/PDB/Native/InfoStream.h" 11 #include "llvm/ADT/BitVector.h" 12 #include "llvm/ADT/SmallVector.h" 13 #include "llvm/DebugInfo/PDB/Native/PDBFile.h" 14 #include "llvm/DebugInfo/PDB/Native/RawConstants.h" 15 #include "llvm/DebugInfo/PDB/Native/RawError.h" 16 #include "llvm/DebugInfo/PDB/Native/RawTypes.h" 17 #include "llvm/Support/BinaryStreamReader.h" 18 #include "llvm/Support/BinaryStreamWriter.h" 19 20 using namespace llvm; 21 using namespace llvm::codeview; 22 using namespace llvm::msf; 23 using namespace llvm::pdb; 24 25 InfoStream::InfoStream(std::unique_ptr<MappedBlockStream> Stream) 26 : Stream(std::move(Stream)) {} 27 28 Error InfoStream::reload() { 29 BinaryStreamReader Reader(*Stream); 30 31 const InfoStreamHeader *H; 32 if (auto EC = Reader.readObject(H)) 33 return joinErrors( 34 std::move(EC), 35 make_error<RawError>(raw_error_code::corrupt_file, 36 "PDB Stream does not contain a header.")); 37 38 switch (H->Version) { 39 case PdbImplVC70: 40 case PdbImplVC80: 41 case PdbImplVC110: 42 case PdbImplVC140: 43 break; 44 default: 45 return make_error<RawError>(raw_error_code::corrupt_file, 46 "Unsupported PDB stream version."); 47 } 48 49 Version = H->Version; 50 Signature = H->Signature; 51 Age = H->Age; 52 Guid = H->Guid; 53 54 uint32_t Offset = Reader.getOffset(); 55 if (auto EC = NamedStreams.load(Reader)) 56 return EC; 57 uint32_t NewOffset = Reader.getOffset(); 58 NamedStreamMapByteSize = NewOffset - Offset; 59 60 Reader.setOffset(Offset); 61 if (auto EC = Reader.readSubstream(SubNamedStreams, NamedStreamMapByteSize)) 62 return EC; 63 64 bool Stop = false; 65 while (!Stop && !Reader.empty()) { 66 PdbRaw_FeatureSig Sig; 67 if (auto EC = Reader.readEnum(Sig)) 68 return EC; 69 // Since this value comes from a file, it's possible we have some strange 70 // value which doesn't correspond to any value. We don't want to warn on 71 // -Wcovered-switch-default in this case, so switch on the integral value 72 // instead of the enumeration value. 73 switch (uint32_t(Sig)) { 74 case uint32_t(PdbRaw_FeatureSig::VC110): 75 // No other flags for VC110 PDB. 76 Stop = true; 77 LLVM_FALLTHROUGH; 78 case uint32_t(PdbRaw_FeatureSig::VC140): 79 Features |= PdbFeatureContainsIdStream; 80 break; 81 case uint32_t(PdbRaw_FeatureSig::NoTypeMerge): 82 Features |= PdbFeatureNoTypeMerging; 83 break; 84 case uint32_t(PdbRaw_FeatureSig::MinimalDebugInfo): 85 Features |= PdbFeatureMinimalDebugInfo; 86 break; 87 default: 88 continue; 89 } 90 FeatureSignatures.push_back(Sig); 91 } 92 return Error::success(); 93 } 94 95 uint32_t InfoStream::getStreamSize() const { return Stream->getLength(); } 96 97 uint32_t InfoStream::getNamedStreamIndex(llvm::StringRef Name) const { 98 uint32_t Result; 99 if (!NamedStreams.get(Name, Result)) 100 return 0; 101 return Result; 102 } 103 104 iterator_range<StringMapConstIterator<uint32_t>> 105 InfoStream::named_streams() const { 106 return NamedStreams.entries(); 107 } 108 109 bool InfoStream::containsIdStream() const { 110 return !!(Features & PdbFeatureContainsIdStream); 111 } 112 113 PdbRaw_ImplVer InfoStream::getVersion() const { 114 return static_cast<PdbRaw_ImplVer>(Version); 115 } 116 117 uint32_t InfoStream::getSignature() const { return Signature; } 118 119 uint32_t InfoStream::getAge() const { return Age; } 120 121 GUID InfoStream::getGuid() const { return Guid; } 122 123 uint32_t InfoStream::getNamedStreamMapByteSize() const { 124 return NamedStreamMapByteSize; 125 } 126 127 PdbRaw_Features InfoStream::getFeatures() const { return Features; } 128 129 ArrayRef<PdbRaw_FeatureSig> InfoStream::getFeatureSignatures() const { 130 return FeatureSignatures; 131 } 132 133 const NamedStreamMap &InfoStream::getNamedStreams() const { 134 return NamedStreams; 135 } 136 137 BinarySubstreamRef InfoStream::getNamedStreamsBuffer() const { 138 return SubNamedStreams; 139 } 140