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