xref: /openbsd-src/gnu/llvm/llvm/lib/DebugInfo/PDB/Native/DbiStream.cpp (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
1*09467b48Spatrick //===- DbiStream.cpp - PDB Dbi Stream (Stream 3) Access -------------------===//
2*09467b48Spatrick //
3*09467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*09467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
5*09467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*09467b48Spatrick //
7*09467b48Spatrick //===----------------------------------------------------------------------===//
8*09467b48Spatrick 
9*09467b48Spatrick #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
10*09467b48Spatrick #include "llvm/ADT/StringRef.h"
11*09467b48Spatrick #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
12*09467b48Spatrick #include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h"
13*09467b48Spatrick #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
14*09467b48Spatrick #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
15*09467b48Spatrick #include "llvm/DebugInfo/PDB/Native/RawError.h"
16*09467b48Spatrick #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
17*09467b48Spatrick #include "llvm/DebugInfo/PDB/PDBTypes.h"
18*09467b48Spatrick #include "llvm/Object/COFF.h"
19*09467b48Spatrick #include "llvm/Support/BinaryStreamArray.h"
20*09467b48Spatrick #include "llvm/Support/BinaryStreamReader.h"
21*09467b48Spatrick #include "llvm/Support/Error.h"
22*09467b48Spatrick #include <cstddef>
23*09467b48Spatrick #include <cstdint>
24*09467b48Spatrick 
25*09467b48Spatrick using namespace llvm;
26*09467b48Spatrick using namespace llvm::codeview;
27*09467b48Spatrick using namespace llvm::msf;
28*09467b48Spatrick using namespace llvm::pdb;
29*09467b48Spatrick using namespace llvm::support;
30*09467b48Spatrick 
31*09467b48Spatrick template <typename ContribType>
loadSectionContribs(FixedStreamArray<ContribType> & Output,BinaryStreamReader & Reader)32*09467b48Spatrick static Error loadSectionContribs(FixedStreamArray<ContribType> &Output,
33*09467b48Spatrick                                  BinaryStreamReader &Reader) {
34*09467b48Spatrick   if (Reader.bytesRemaining() % sizeof(ContribType) != 0)
35*09467b48Spatrick     return make_error<RawError>(
36*09467b48Spatrick         raw_error_code::corrupt_file,
37*09467b48Spatrick         "Invalid number of bytes of section contributions");
38*09467b48Spatrick 
39*09467b48Spatrick   uint32_t Count = Reader.bytesRemaining() / sizeof(ContribType);
40*09467b48Spatrick   if (auto EC = Reader.readArray(Output, Count))
41*09467b48Spatrick     return EC;
42*09467b48Spatrick   return Error::success();
43*09467b48Spatrick }
44*09467b48Spatrick 
DbiStream(std::unique_ptr<BinaryStream> Stream)45*09467b48Spatrick DbiStream::DbiStream(std::unique_ptr<BinaryStream> Stream)
46*09467b48Spatrick     : Stream(std::move(Stream)), Header(nullptr) {}
47*09467b48Spatrick 
48*09467b48Spatrick DbiStream::~DbiStream() = default;
49*09467b48Spatrick 
reload(PDBFile * Pdb)50*09467b48Spatrick Error DbiStream::reload(PDBFile *Pdb) {
51*09467b48Spatrick   BinaryStreamReader Reader(*Stream);
52*09467b48Spatrick 
53*09467b48Spatrick   if (Stream->getLength() < sizeof(DbiStreamHeader))
54*09467b48Spatrick     return make_error<RawError>(raw_error_code::corrupt_file,
55*09467b48Spatrick                                 "DBI Stream does not contain a header.");
56*09467b48Spatrick   if (auto EC = Reader.readObject(Header))
57*09467b48Spatrick     return make_error<RawError>(raw_error_code::corrupt_file,
58*09467b48Spatrick                                 "DBI Stream does not contain a header.");
59*09467b48Spatrick 
60*09467b48Spatrick   if (Header->VersionSignature != -1)
61*09467b48Spatrick     return make_error<RawError>(raw_error_code::corrupt_file,
62*09467b48Spatrick                                 "Invalid DBI version signature.");
63*09467b48Spatrick 
64*09467b48Spatrick   // Require at least version 7, which should be present in all PDBs
65*09467b48Spatrick   // produced in the last decade and allows us to avoid having to
66*09467b48Spatrick   // special case all kinds of complicated arcane formats.
67*09467b48Spatrick   if (Header->VersionHeader < PdbDbiV70)
68*09467b48Spatrick     return make_error<RawError>(raw_error_code::feature_unsupported,
69*09467b48Spatrick                                 "Unsupported DBI version.");
70*09467b48Spatrick 
71*09467b48Spatrick   if (Stream->getLength() !=
72*09467b48Spatrick       sizeof(DbiStreamHeader) + Header->ModiSubstreamSize +
73*09467b48Spatrick           Header->SecContrSubstreamSize + Header->SectionMapSize +
74*09467b48Spatrick           Header->FileInfoSize + Header->TypeServerSize +
75*09467b48Spatrick           Header->OptionalDbgHdrSize + Header->ECSubstreamSize)
76*09467b48Spatrick     return make_error<RawError>(raw_error_code::corrupt_file,
77*09467b48Spatrick                                 "DBI Length does not equal sum of substreams.");
78*09467b48Spatrick 
79*09467b48Spatrick   // Only certain substreams are guaranteed to be aligned.  Validate
80*09467b48Spatrick   // them here.
81*09467b48Spatrick   if (Header->ModiSubstreamSize % sizeof(uint32_t) != 0)
82*09467b48Spatrick     return make_error<RawError>(raw_error_code::corrupt_file,
83*09467b48Spatrick                                 "DBI MODI substream not aligned.");
84*09467b48Spatrick   if (Header->SecContrSubstreamSize % sizeof(uint32_t) != 0)
85*09467b48Spatrick     return make_error<RawError>(
86*09467b48Spatrick         raw_error_code::corrupt_file,
87*09467b48Spatrick         "DBI section contribution substream not aligned.");
88*09467b48Spatrick   if (Header->SectionMapSize % sizeof(uint32_t) != 0)
89*09467b48Spatrick     return make_error<RawError>(raw_error_code::corrupt_file,
90*09467b48Spatrick                                 "DBI section map substream not aligned.");
91*09467b48Spatrick   if (Header->FileInfoSize % sizeof(uint32_t) != 0)
92*09467b48Spatrick     return make_error<RawError>(raw_error_code::corrupt_file,
93*09467b48Spatrick                                 "DBI file info substream not aligned.");
94*09467b48Spatrick   if (Header->TypeServerSize % sizeof(uint32_t) != 0)
95*09467b48Spatrick     return make_error<RawError>(raw_error_code::corrupt_file,
96*09467b48Spatrick                                 "DBI type server substream not aligned.");
97*09467b48Spatrick 
98*09467b48Spatrick   if (auto EC = Reader.readSubstream(ModiSubstream, Header->ModiSubstreamSize))
99*09467b48Spatrick     return EC;
100*09467b48Spatrick 
101*09467b48Spatrick   if (auto EC = Reader.readSubstream(SecContrSubstream,
102*09467b48Spatrick                                      Header->SecContrSubstreamSize))
103*09467b48Spatrick     return EC;
104*09467b48Spatrick   if (auto EC = Reader.readSubstream(SecMapSubstream, Header->SectionMapSize))
105*09467b48Spatrick     return EC;
106*09467b48Spatrick   if (auto EC = Reader.readSubstream(FileInfoSubstream, Header->FileInfoSize))
107*09467b48Spatrick     return EC;
108*09467b48Spatrick   if (auto EC =
109*09467b48Spatrick           Reader.readSubstream(TypeServerMapSubstream, Header->TypeServerSize))
110*09467b48Spatrick     return EC;
111*09467b48Spatrick   if (auto EC = Reader.readSubstream(ECSubstream, Header->ECSubstreamSize))
112*09467b48Spatrick     return EC;
113*09467b48Spatrick   if (auto EC = Reader.readArray(
114*09467b48Spatrick           DbgStreams, Header->OptionalDbgHdrSize / sizeof(ulittle16_t)))
115*09467b48Spatrick     return EC;
116*09467b48Spatrick 
117*09467b48Spatrick   if (auto EC = Modules.initialize(ModiSubstream.StreamData,
118*09467b48Spatrick                                    FileInfoSubstream.StreamData))
119*09467b48Spatrick     return EC;
120*09467b48Spatrick 
121*09467b48Spatrick   if (auto EC = initializeSectionContributionData())
122*09467b48Spatrick     return EC;
123*09467b48Spatrick   if (auto EC = initializeSectionHeadersData(Pdb))
124*09467b48Spatrick     return EC;
125*09467b48Spatrick   if (auto EC = initializeSectionMapData())
126*09467b48Spatrick     return EC;
127*09467b48Spatrick   if (auto EC = initializeOldFpoRecords(Pdb))
128*09467b48Spatrick     return EC;
129*09467b48Spatrick   if (auto EC = initializeNewFpoRecords(Pdb))
130*09467b48Spatrick      return EC;
131*09467b48Spatrick 
132*09467b48Spatrick   if (Reader.bytesRemaining() > 0)
133*09467b48Spatrick     return make_error<RawError>(raw_error_code::corrupt_file,
134*09467b48Spatrick                                 "Found unexpected bytes in DBI Stream.");
135*09467b48Spatrick 
136*09467b48Spatrick   if (!ECSubstream.empty()) {
137*09467b48Spatrick     BinaryStreamReader ECReader(ECSubstream.StreamData);
138*09467b48Spatrick     if (auto EC = ECNames.reload(ECReader))
139*09467b48Spatrick       return EC;
140*09467b48Spatrick   }
141*09467b48Spatrick 
142*09467b48Spatrick   return Error::success();
143*09467b48Spatrick }
144*09467b48Spatrick 
getDbiVersion() const145*09467b48Spatrick PdbRaw_DbiVer DbiStream::getDbiVersion() const {
146*09467b48Spatrick   uint32_t Value = Header->VersionHeader;
147*09467b48Spatrick   return static_cast<PdbRaw_DbiVer>(Value);
148*09467b48Spatrick }
149*09467b48Spatrick 
getAge() const150*09467b48Spatrick uint32_t DbiStream::getAge() const { return Header->Age; }
151*09467b48Spatrick 
getPublicSymbolStreamIndex() const152*09467b48Spatrick uint16_t DbiStream::getPublicSymbolStreamIndex() const {
153*09467b48Spatrick   return Header->PublicSymbolStreamIndex;
154*09467b48Spatrick }
155*09467b48Spatrick 
getGlobalSymbolStreamIndex() const156*09467b48Spatrick uint16_t DbiStream::getGlobalSymbolStreamIndex() const {
157*09467b48Spatrick   return Header->GlobalSymbolStreamIndex;
158*09467b48Spatrick }
159*09467b48Spatrick 
getFlags() const160*09467b48Spatrick uint16_t DbiStream::getFlags() const { return Header->Flags; }
161*09467b48Spatrick 
isIncrementallyLinked() const162*09467b48Spatrick bool DbiStream::isIncrementallyLinked() const {
163*09467b48Spatrick   return (Header->Flags & DbiFlags::FlagIncrementalMask) != 0;
164*09467b48Spatrick }
165*09467b48Spatrick 
hasCTypes() const166*09467b48Spatrick bool DbiStream::hasCTypes() const {
167*09467b48Spatrick   return (Header->Flags & DbiFlags::FlagHasCTypesMask) != 0;
168*09467b48Spatrick }
169*09467b48Spatrick 
isStripped() const170*09467b48Spatrick bool DbiStream::isStripped() const {
171*09467b48Spatrick   return (Header->Flags & DbiFlags::FlagStrippedMask) != 0;
172*09467b48Spatrick }
173*09467b48Spatrick 
getBuildNumber() const174*09467b48Spatrick uint16_t DbiStream::getBuildNumber() const { return Header->BuildNumber; }
175*09467b48Spatrick 
getBuildMajorVersion() const176*09467b48Spatrick uint16_t DbiStream::getBuildMajorVersion() const {
177*09467b48Spatrick   return (Header->BuildNumber & DbiBuildNo::BuildMajorMask) >>
178*09467b48Spatrick          DbiBuildNo::BuildMajorShift;
179*09467b48Spatrick }
180*09467b48Spatrick 
getBuildMinorVersion() const181*09467b48Spatrick uint16_t DbiStream::getBuildMinorVersion() const {
182*09467b48Spatrick   return (Header->BuildNumber & DbiBuildNo::BuildMinorMask) >>
183*09467b48Spatrick          DbiBuildNo::BuildMinorShift;
184*09467b48Spatrick }
185*09467b48Spatrick 
getPdbDllRbld() const186*09467b48Spatrick uint16_t DbiStream::getPdbDllRbld() const { return Header->PdbDllRbld; }
187*09467b48Spatrick 
getPdbDllVersion() const188*09467b48Spatrick uint32_t DbiStream::getPdbDllVersion() const { return Header->PdbDllVersion; }
189*09467b48Spatrick 
getSymRecordStreamIndex() const190*09467b48Spatrick uint32_t DbiStream::getSymRecordStreamIndex() const {
191*09467b48Spatrick   return Header->SymRecordStreamIndex;
192*09467b48Spatrick }
193*09467b48Spatrick 
getMachineType() const194*09467b48Spatrick PDB_Machine DbiStream::getMachineType() const {
195*09467b48Spatrick   uint16_t Machine = Header->MachineType;
196*09467b48Spatrick   return static_cast<PDB_Machine>(Machine);
197*09467b48Spatrick }
198*09467b48Spatrick 
getSectionHeaders() const199*09467b48Spatrick FixedStreamArray<object::coff_section> DbiStream::getSectionHeaders() const {
200*09467b48Spatrick   return SectionHeaders;
201*09467b48Spatrick }
202*09467b48Spatrick 
hasOldFpoRecords() const203*09467b48Spatrick bool DbiStream::hasOldFpoRecords() const { return OldFpoStream != nullptr; }
204*09467b48Spatrick 
getOldFpoRecords() const205*09467b48Spatrick FixedStreamArray<object::FpoData> DbiStream::getOldFpoRecords() const {
206*09467b48Spatrick   return OldFpoRecords;
207*09467b48Spatrick }
208*09467b48Spatrick 
hasNewFpoRecords() const209*09467b48Spatrick bool DbiStream::hasNewFpoRecords() const { return NewFpoStream != nullptr; }
210*09467b48Spatrick 
getNewFpoRecords() const211*09467b48Spatrick const DebugFrameDataSubsectionRef &DbiStream::getNewFpoRecords() const {
212*09467b48Spatrick   return NewFpoRecords;
213*09467b48Spatrick }
214*09467b48Spatrick 
modules() const215*09467b48Spatrick const DbiModuleList &DbiStream::modules() const { return Modules; }
216*09467b48Spatrick 
getSectionMap() const217*09467b48Spatrick FixedStreamArray<SecMapEntry> DbiStream::getSectionMap() const {
218*09467b48Spatrick   return SectionMap;
219*09467b48Spatrick }
220*09467b48Spatrick 
visitSectionContributions(ISectionContribVisitor & Visitor) const221*09467b48Spatrick void DbiStream::visitSectionContributions(
222*09467b48Spatrick     ISectionContribVisitor &Visitor) const {
223*09467b48Spatrick   if (!SectionContribs.empty()) {
224*09467b48Spatrick     assert(SectionContribVersion == DbiSecContribVer60);
225*09467b48Spatrick     for (auto &SC : SectionContribs)
226*09467b48Spatrick       Visitor.visit(SC);
227*09467b48Spatrick   } else if (!SectionContribs2.empty()) {
228*09467b48Spatrick     assert(SectionContribVersion == DbiSecContribV2);
229*09467b48Spatrick     for (auto &SC : SectionContribs2)
230*09467b48Spatrick       Visitor.visit(SC);
231*09467b48Spatrick   }
232*09467b48Spatrick }
233*09467b48Spatrick 
getECName(uint32_t NI) const234*09467b48Spatrick Expected<StringRef> DbiStream::getECName(uint32_t NI) const {
235*09467b48Spatrick   return ECNames.getStringForID(NI);
236*09467b48Spatrick }
237*09467b48Spatrick 
initializeSectionContributionData()238*09467b48Spatrick Error DbiStream::initializeSectionContributionData() {
239*09467b48Spatrick   if (SecContrSubstream.empty())
240*09467b48Spatrick     return Error::success();
241*09467b48Spatrick 
242*09467b48Spatrick   BinaryStreamReader SCReader(SecContrSubstream.StreamData);
243*09467b48Spatrick   if (auto EC = SCReader.readEnum(SectionContribVersion))
244*09467b48Spatrick     return EC;
245*09467b48Spatrick 
246*09467b48Spatrick   if (SectionContribVersion == DbiSecContribVer60)
247*09467b48Spatrick     return loadSectionContribs<SectionContrib>(SectionContribs, SCReader);
248*09467b48Spatrick   if (SectionContribVersion == DbiSecContribV2)
249*09467b48Spatrick     return loadSectionContribs<SectionContrib2>(SectionContribs2, SCReader);
250*09467b48Spatrick 
251*09467b48Spatrick   return make_error<RawError>(raw_error_code::feature_unsupported,
252*09467b48Spatrick                               "Unsupported DBI Section Contribution version");
253*09467b48Spatrick }
254*09467b48Spatrick 
255*09467b48Spatrick // Initializes this->SectionHeaders.
initializeSectionHeadersData(PDBFile * Pdb)256*09467b48Spatrick Error DbiStream::initializeSectionHeadersData(PDBFile *Pdb) {
257*09467b48Spatrick   Expected<std::unique_ptr<msf::MappedBlockStream>> ExpectedStream =
258*09467b48Spatrick       createIndexedStreamForHeaderType(Pdb, DbgHeaderType::SectionHdr);
259*09467b48Spatrick   if (auto EC = ExpectedStream.takeError())
260*09467b48Spatrick     return EC;
261*09467b48Spatrick 
262*09467b48Spatrick   auto &SHS = *ExpectedStream;
263*09467b48Spatrick   if (!SHS)
264*09467b48Spatrick     return Error::success();
265*09467b48Spatrick 
266*09467b48Spatrick   size_t StreamLen = SHS->getLength();
267*09467b48Spatrick   if (StreamLen % sizeof(object::coff_section))
268*09467b48Spatrick     return make_error<RawError>(raw_error_code::corrupt_file,
269*09467b48Spatrick                                 "Corrupted section header stream.");
270*09467b48Spatrick 
271*09467b48Spatrick   size_t NumSections = StreamLen / sizeof(object::coff_section);
272*09467b48Spatrick   BinaryStreamReader Reader(*SHS);
273*09467b48Spatrick   if (auto EC = Reader.readArray(SectionHeaders, NumSections))
274*09467b48Spatrick     return make_error<RawError>(raw_error_code::corrupt_file,
275*09467b48Spatrick                                 "Could not read a bitmap.");
276*09467b48Spatrick 
277*09467b48Spatrick   SectionHeaderStream = std::move(SHS);
278*09467b48Spatrick   return Error::success();
279*09467b48Spatrick }
280*09467b48Spatrick 
281*09467b48Spatrick // Initializes this->Fpos.
initializeOldFpoRecords(PDBFile * Pdb)282*09467b48Spatrick Error DbiStream::initializeOldFpoRecords(PDBFile *Pdb) {
283*09467b48Spatrick   Expected<std::unique_ptr<msf::MappedBlockStream>> ExpectedStream =
284*09467b48Spatrick       createIndexedStreamForHeaderType(Pdb, DbgHeaderType::FPO);
285*09467b48Spatrick   if (auto EC = ExpectedStream.takeError())
286*09467b48Spatrick     return EC;
287*09467b48Spatrick 
288*09467b48Spatrick   auto &FS = *ExpectedStream;
289*09467b48Spatrick   if (!FS)
290*09467b48Spatrick     return Error::success();
291*09467b48Spatrick 
292*09467b48Spatrick   size_t StreamLen = FS->getLength();
293*09467b48Spatrick   if (StreamLen % sizeof(object::FpoData))
294*09467b48Spatrick     return make_error<RawError>(raw_error_code::corrupt_file,
295*09467b48Spatrick                                 "Corrupted Old FPO stream.");
296*09467b48Spatrick 
297*09467b48Spatrick   size_t NumRecords = StreamLen / sizeof(object::FpoData);
298*09467b48Spatrick   BinaryStreamReader Reader(*FS);
299*09467b48Spatrick   if (auto EC = Reader.readArray(OldFpoRecords, NumRecords))
300*09467b48Spatrick     return make_error<RawError>(raw_error_code::corrupt_file,
301*09467b48Spatrick                                 "Corrupted Old FPO stream.");
302*09467b48Spatrick   OldFpoStream = std::move(FS);
303*09467b48Spatrick   return Error::success();
304*09467b48Spatrick }
305*09467b48Spatrick 
initializeNewFpoRecords(PDBFile * Pdb)306*09467b48Spatrick Error DbiStream::initializeNewFpoRecords(PDBFile *Pdb) {
307*09467b48Spatrick   Expected<std::unique_ptr<msf::MappedBlockStream>> ExpectedStream =
308*09467b48Spatrick       createIndexedStreamForHeaderType(Pdb, DbgHeaderType::NewFPO);
309*09467b48Spatrick   if (auto EC = ExpectedStream.takeError())
310*09467b48Spatrick     return EC;
311*09467b48Spatrick 
312*09467b48Spatrick   auto &FS = *ExpectedStream;
313*09467b48Spatrick   if (!FS)
314*09467b48Spatrick     return Error::success();
315*09467b48Spatrick 
316*09467b48Spatrick   if (auto EC = NewFpoRecords.initialize(*FS))
317*09467b48Spatrick     return EC;
318*09467b48Spatrick 
319*09467b48Spatrick   NewFpoStream = std::move(FS);
320*09467b48Spatrick   return Error::success();
321*09467b48Spatrick }
322*09467b48Spatrick 
323*09467b48Spatrick Expected<std::unique_ptr<msf::MappedBlockStream>>
createIndexedStreamForHeaderType(PDBFile * Pdb,DbgHeaderType Type) const324*09467b48Spatrick DbiStream::createIndexedStreamForHeaderType(PDBFile *Pdb,
325*09467b48Spatrick                                             DbgHeaderType Type) const {
326*09467b48Spatrick   if (!Pdb)
327*09467b48Spatrick     return nullptr;
328*09467b48Spatrick 
329*09467b48Spatrick   if (DbgStreams.empty())
330*09467b48Spatrick     return nullptr;
331*09467b48Spatrick 
332*09467b48Spatrick   uint32_t StreamNum = getDebugStreamIndex(Type);
333*09467b48Spatrick 
334*09467b48Spatrick   // This means there is no such stream.
335*09467b48Spatrick   if (StreamNum == kInvalidStreamIndex)
336*09467b48Spatrick     return nullptr;
337*09467b48Spatrick 
338*09467b48Spatrick   return Pdb->safelyCreateIndexedStream(StreamNum);
339*09467b48Spatrick }
340*09467b48Spatrick 
getSectionContributionData() const341*09467b48Spatrick BinarySubstreamRef DbiStream::getSectionContributionData() const {
342*09467b48Spatrick   return SecContrSubstream;
343*09467b48Spatrick }
344*09467b48Spatrick 
getSecMapSubstreamData() const345*09467b48Spatrick BinarySubstreamRef DbiStream::getSecMapSubstreamData() const {
346*09467b48Spatrick   return SecMapSubstream;
347*09467b48Spatrick }
348*09467b48Spatrick 
getModiSubstreamData() const349*09467b48Spatrick BinarySubstreamRef DbiStream::getModiSubstreamData() const {
350*09467b48Spatrick   return ModiSubstream;
351*09467b48Spatrick }
352*09467b48Spatrick 
getFileInfoSubstreamData() const353*09467b48Spatrick BinarySubstreamRef DbiStream::getFileInfoSubstreamData() const {
354*09467b48Spatrick   return FileInfoSubstream;
355*09467b48Spatrick }
356*09467b48Spatrick 
getTypeServerMapSubstreamData() const357*09467b48Spatrick BinarySubstreamRef DbiStream::getTypeServerMapSubstreamData() const {
358*09467b48Spatrick   return TypeServerMapSubstream;
359*09467b48Spatrick }
360*09467b48Spatrick 
getECSubstreamData() const361*09467b48Spatrick BinarySubstreamRef DbiStream::getECSubstreamData() const { return ECSubstream; }
362*09467b48Spatrick 
initializeSectionMapData()363*09467b48Spatrick Error DbiStream::initializeSectionMapData() {
364*09467b48Spatrick   if (SecMapSubstream.empty())
365*09467b48Spatrick     return Error::success();
366*09467b48Spatrick 
367*09467b48Spatrick   BinaryStreamReader SMReader(SecMapSubstream.StreamData);
368*09467b48Spatrick   const SecMapHeader *Header;
369*09467b48Spatrick   if (auto EC = SMReader.readObject(Header))
370*09467b48Spatrick     return EC;
371*09467b48Spatrick   if (auto EC = SMReader.readArray(SectionMap, Header->SecCount))
372*09467b48Spatrick     return EC;
373*09467b48Spatrick   return Error::success();
374*09467b48Spatrick }
375*09467b48Spatrick 
getDebugStreamIndex(DbgHeaderType Type) const376*09467b48Spatrick uint32_t DbiStream::getDebugStreamIndex(DbgHeaderType Type) const {
377*09467b48Spatrick   uint16_t T = static_cast<uint16_t>(Type);
378*09467b48Spatrick   if (T >= DbgStreams.size())
379*09467b48Spatrick     return kInvalidStreamIndex;
380*09467b48Spatrick   return DbgStreams[T];
381*09467b48Spatrick }
382