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 Turner InfoStream::InfoStream(std::unique_ptr<BinaryStream> Stream)
21d5cf5cf6SZachary Turner     : Stream(std::move(Stream)), Header(nullptr) {}
226b6b8c4fSAdrian McCarthy 
reload()236b6b8c4fSAdrian McCarthy Error 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 Turner uint32_t InfoStream::getStreamSize() const { return Stream->getLength(); }
8502278ce0SZachary Turner 
getNamedStreamIndex(llvm::StringRef Name) const86d11328a1SZachary Turner Expected<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 Turner StringMap<uint32_t> InfoStream::named_streams() const {
946b6b8c4fSAdrian McCarthy   return NamedStreams.entries();
956b6b8c4fSAdrian McCarthy }
966b6b8c4fSAdrian McCarthy 
containsIdStream() const97990d0c81SZachary Turner bool InfoStream::containsIdStream() const {
98990d0c81SZachary Turner   return !!(Features & PdbFeatureContainsIdStream);
99990d0c81SZachary Turner }
100990d0c81SZachary Turner 
getVersion() const1016b6b8c4fSAdrian McCarthy PdbRaw_ImplVer InfoStream::getVersion() const {
102d5cf5cf6SZachary Turner   return static_cast<PdbRaw_ImplVer>(uint32_t(Header->Version));
1036b6b8c4fSAdrian McCarthy }
1046b6b8c4fSAdrian McCarthy 
getSignature() const105d5cf5cf6SZachary Turner uint32_t InfoStream::getSignature() const {
106d5cf5cf6SZachary Turner   return uint32_t(Header->Signature);
107d5cf5cf6SZachary Turner }
1086b6b8c4fSAdrian McCarthy 
getAge() const109d5cf5cf6SZachary Turner uint32_t InfoStream::getAge() const { return uint32_t(Header->Age); }
1106b6b8c4fSAdrian McCarthy 
getGuid() const111d5cf5cf6SZachary Turner GUID InfoStream::getGuid() const { return Header->Guid; }
1126b6b8c4fSAdrian McCarthy 
getNamedStreamMapByteSize() const11302278ce0SZachary Turner uint32_t InfoStream::getNamedStreamMapByteSize() const {
11402278ce0SZachary Turner   return NamedStreamMapByteSize;
11502278ce0SZachary Turner }
11602278ce0SZachary Turner 
getFeatures() const11705d5e613SZachary Turner PdbRaw_Features InfoStream::getFeatures() const { return Features; }
11805d5e613SZachary Turner 
getFeatureSignatures() const11905d5e613SZachary Turner ArrayRef<PdbRaw_FeatureSig> InfoStream::getFeatureSignatures() const {
12005d5e613SZachary Turner   return FeatureSignatures;
12105d5e613SZachary Turner }
12205d5e613SZachary Turner 
getNamedStreams() const1236b6b8c4fSAdrian McCarthy const NamedStreamMap &InfoStream::getNamedStreams() const {
1246b6b8c4fSAdrian McCarthy   return NamedStreams;
1256b6b8c4fSAdrian McCarthy }
1266c3e41bbSZachary Turner 
getNamedStreamsBuffer() const1276c3e41bbSZachary Turner BinarySubstreamRef InfoStream::getNamedStreamsBuffer() const {
1286c3e41bbSZachary Turner   return SubNamedStreams;
1296c3e41bbSZachary Turner }
130