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