16b6b8c4fSAdrian McCarthy //===- InfoStream.cpp - PDB Info Stream (Stream 1) Access -------*- C++ -*-===// 26b6b8c4fSAdrian McCarthy // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 66b6b8c4fSAdrian McCarthy // 76b6b8c4fSAdrian McCarthy //===----------------------------------------------------------------------===// 86b6b8c4fSAdrian McCarthy 96b6b8c4fSAdrian McCarthy #include "llvm/DebugInfo/PDB/Native/InfoStream.h" 106b6b8c4fSAdrian McCarthy #include "llvm/DebugInfo/PDB/Native/RawConstants.h" 116b6b8c4fSAdrian McCarthy #include "llvm/DebugInfo/PDB/Native/RawError.h" 126b6b8c4fSAdrian McCarthy #include "llvm/DebugInfo/PDB/Native/RawTypes.h" 13d9dc2829SZachary Turner #include "llvm/Support/BinaryStreamReader.h" 146b6b8c4fSAdrian McCarthy 156b6b8c4fSAdrian McCarthy using namespace llvm; 166b6b8c4fSAdrian McCarthy using namespace llvm::codeview; 17*ed98c1b3Sserge-sans-paille // using namespace llvm::msf; 186b6b8c4fSAdrian McCarthy using namespace llvm::pdb; 196b6b8c4fSAdrian McCarthy InfoStream(std::unique_ptr<BinaryStream> Stream)2015b2bdfdSZachary TurnerInfoStream::InfoStream(std::unique_ptr<BinaryStream> Stream) 21d5cf5cf6SZachary Turner : Stream(std::move(Stream)), Header(nullptr) {} 226b6b8c4fSAdrian McCarthy reload()236b6b8c4fSAdrian McCarthyError InfoStream::reload() { 24120faca4SZachary Turner BinaryStreamReader Reader(*Stream); 256b6b8c4fSAdrian McCarthy 26d5cf5cf6SZachary Turner if (auto EC = Reader.readObject(Header)) 276b6b8c4fSAdrian McCarthy return joinErrors( 286b6b8c4fSAdrian McCarthy std::move(EC), 296b6b8c4fSAdrian McCarthy make_error<RawError>(raw_error_code::corrupt_file, 306b6b8c4fSAdrian McCarthy "PDB Stream does not contain a header.")); 316b6b8c4fSAdrian McCarthy 32d5cf5cf6SZachary Turner switch (Header->Version) { 336b6b8c4fSAdrian McCarthy case PdbImplVC70: 346b6b8c4fSAdrian McCarthy case PdbImplVC80: 356b6b8c4fSAdrian McCarthy case PdbImplVC110: 366b6b8c4fSAdrian McCarthy case PdbImplVC140: 376b6b8c4fSAdrian McCarthy break; 386b6b8c4fSAdrian McCarthy default: 396b6b8c4fSAdrian McCarthy return make_error<RawError>(raw_error_code::corrupt_file, 406b6b8c4fSAdrian McCarthy "Unsupported PDB stream version."); 416b6b8c4fSAdrian McCarthy } 426b6b8c4fSAdrian McCarthy 4302278ce0SZachary Turner uint32_t Offset = Reader.getOffset(); 4402278ce0SZachary Turner if (auto EC = NamedStreams.load(Reader)) 4502278ce0SZachary Turner return EC; 4602278ce0SZachary Turner uint32_t NewOffset = Reader.getOffset(); 4702278ce0SZachary Turner NamedStreamMapByteSize = NewOffset - Offset; 4805d5e613SZachary Turner 496c3e41bbSZachary Turner Reader.setOffset(Offset); 506c3e41bbSZachary Turner if (auto EC = Reader.readSubstream(SubNamedStreams, NamedStreamMapByteSize)) 516c3e41bbSZachary Turner return EC; 526c3e41bbSZachary Turner 5305d5e613SZachary Turner bool Stop = false; 5405d5e613SZachary Turner while (!Stop && !Reader.empty()) { 5505d5e613SZachary Turner PdbRaw_FeatureSig Sig; 5605d5e613SZachary Turner if (auto EC = Reader.readEnum(Sig)) 5705d5e613SZachary Turner return EC; 58c9500616SZachary Turner // Since this value comes from a file, it's possible we have some strange 59c9500616SZachary Turner // value which doesn't correspond to any value. We don't want to warn on 60c9500616SZachary Turner // -Wcovered-switch-default in this case, so switch on the integral value 61c9500616SZachary Turner // instead of the enumeration value. 62c9500616SZachary Turner switch (uint32_t(Sig)) { 63c9500616SZachary Turner case uint32_t(PdbRaw_FeatureSig::VC110): 6405d5e613SZachary Turner // No other flags for VC110 PDB. 6505d5e613SZachary Turner Stop = true; 6605d5e613SZachary Turner LLVM_FALLTHROUGH; 67c9500616SZachary Turner case uint32_t(PdbRaw_FeatureSig::VC140): 6805d5e613SZachary Turner Features |= PdbFeatureContainsIdStream; 6905d5e613SZachary Turner break; 70c9500616SZachary Turner case uint32_t(PdbRaw_FeatureSig::NoTypeMerge): 7105d5e613SZachary Turner Features |= PdbFeatureNoTypeMerging; 7205d5e613SZachary Turner break; 73c9500616SZachary Turner case uint32_t(PdbRaw_FeatureSig::MinimalDebugInfo): 7405d5e613SZachary Turner Features |= PdbFeatureMinimalDebugInfo; 758c1e2f91SGalina Kistanova break; 7605d5e613SZachary Turner default: 7705d5e613SZachary Turner continue; 7805d5e613SZachary Turner } 7905d5e613SZachary Turner FeatureSignatures.push_back(Sig); 8005d5e613SZachary Turner } 8102278ce0SZachary Turner return Error::success(); 826b6b8c4fSAdrian McCarthy } 836b6b8c4fSAdrian McCarthy getStreamSize() const8402278ce0SZachary Turneruint32_t InfoStream::getStreamSize() const { return Stream->getLength(); } 8502278ce0SZachary Turner getNamedStreamIndex(llvm::StringRef Name) const86d11328a1SZachary TurnerExpected<uint32_t> InfoStream::getNamedStreamIndex(llvm::StringRef Name) const { 876b6b8c4fSAdrian McCarthy uint32_t Result; 886b6b8c4fSAdrian McCarthy if (!NamedStreams.get(Name, Result)) 89d11328a1SZachary Turner return make_error<RawError>(raw_error_code::no_stream); 906b6b8c4fSAdrian McCarthy return Result; 916b6b8c4fSAdrian McCarthy } 926b6b8c4fSAdrian McCarthy named_streams() const93cafd4768SZachary TurnerStringMap<uint32_t> InfoStream::named_streams() const { 946b6b8c4fSAdrian McCarthy return NamedStreams.entries(); 956b6b8c4fSAdrian McCarthy } 966b6b8c4fSAdrian McCarthy containsIdStream() const97990d0c81SZachary Turnerbool InfoStream::containsIdStream() const { 98990d0c81SZachary Turner return !!(Features & PdbFeatureContainsIdStream); 99990d0c81SZachary Turner } 100990d0c81SZachary Turner getVersion() const1016b6b8c4fSAdrian McCarthyPdbRaw_ImplVer InfoStream::getVersion() const { 102d5cf5cf6SZachary Turner return static_cast<PdbRaw_ImplVer>(uint32_t(Header->Version)); 1036b6b8c4fSAdrian McCarthy } 1046b6b8c4fSAdrian McCarthy getSignature() const105d5cf5cf6SZachary Turneruint32_t InfoStream::getSignature() const { 106d5cf5cf6SZachary Turner return uint32_t(Header->Signature); 107d5cf5cf6SZachary Turner } 1086b6b8c4fSAdrian McCarthy getAge() const109d5cf5cf6SZachary Turneruint32_t InfoStream::getAge() const { return uint32_t(Header->Age); } 1106b6b8c4fSAdrian McCarthy getGuid() const111d5cf5cf6SZachary TurnerGUID InfoStream::getGuid() const { return Header->Guid; } 1126b6b8c4fSAdrian McCarthy getNamedStreamMapByteSize() const11302278ce0SZachary Turneruint32_t InfoStream::getNamedStreamMapByteSize() const { 11402278ce0SZachary Turner return NamedStreamMapByteSize; 11502278ce0SZachary Turner } 11602278ce0SZachary Turner getFeatures() const11705d5e613SZachary TurnerPdbRaw_Features InfoStream::getFeatures() const { return Features; } 11805d5e613SZachary Turner getFeatureSignatures() const11905d5e613SZachary TurnerArrayRef<PdbRaw_FeatureSig> InfoStream::getFeatureSignatures() const { 12005d5e613SZachary Turner return FeatureSignatures; 12105d5e613SZachary Turner } 12205d5e613SZachary Turner getNamedStreams() const1236b6b8c4fSAdrian McCarthyconst NamedStreamMap &InfoStream::getNamedStreams() const { 1246b6b8c4fSAdrian McCarthy return NamedStreams; 1256b6b8c4fSAdrian McCarthy } 1266c3e41bbSZachary Turner getNamedStreamsBuffer() const1276c3e41bbSZachary TurnerBinarySubstreamRef InfoStream::getNamedStreamsBuffer() const { 1286c3e41bbSZachary Turner return SubNamedStreams; 1296c3e41bbSZachary Turner } 130