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