1 //===- StreamUtil.cpp - PDB stream utilities --------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "StreamUtil.h"
11 #include "FormatUtil.h"
13 #include "llvm/ADT/DenseMap.h"
14 #include "llvm/ADT/DenseMapInfo.h"
15 #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
16 #include "llvm/DebugInfo/PDB/Native/DbiModuleList.h"
17 #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
18 #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
19 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
20 #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
23 using namespace llvm::pdb
;
25 std::string
StreamInfo::getLongName() const {
26 if (Purpose
== StreamPurpose::NamedStream
)
27 return formatv("Named Stream \"{0}\"", Name
).str();
28 if (Purpose
== StreamPurpose::ModuleStream
)
29 return formatv("Module \"{0}\"", Name
).str();
33 StreamInfo
StreamInfo::createStream(StreamPurpose Purpose
, StringRef Name
,
34 uint32_t StreamIndex
) {
37 Result
.StreamIndex
= StreamIndex
;
38 Result
.Purpose
= Purpose
;
42 StreamInfo
StreamInfo::createModuleStream(StringRef Module
,
43 uint32_t StreamIndex
, uint32_t Modi
) {
46 Result
.StreamIndex
= StreamIndex
;
47 Result
.ModuleIndex
= Modi
;
48 Result
.Purpose
= StreamPurpose::ModuleStream
;
52 static inline StreamInfo
stream(StreamPurpose Purpose
, StringRef Label
,
54 return StreamInfo::createStream(Purpose
, Label
, Idx
);
57 static inline StreamInfo
moduleStream(StringRef Label
, uint32_t StreamIdx
,
59 return StreamInfo::createModuleStream(Label
, StreamIdx
, Modi
);
62 struct IndexedModuleDescriptor
{
64 DbiModuleDescriptor Descriptor
;
67 void llvm::pdb::discoverStreamPurposes(PDBFile
&File
,
68 SmallVectorImpl
<StreamInfo
> &Streams
) {
69 // It's OK if we fail to load some of these streams, we still attempt to print
71 auto Dbi
= File
.getPDBDbiStream();
72 auto Tpi
= File
.getPDBTpiStream();
73 auto Ipi
= File
.getPDBIpiStream();
74 auto Info
= File
.getPDBInfoStream();
76 uint32_t StreamCount
= File
.getNumStreams();
77 DenseMap
<uint16_t, IndexedModuleDescriptor
> ModStreams
;
78 DenseMap
<uint16_t, std::string
> NamedStreams
;
81 const DbiModuleList
&Modules
= Dbi
->modules();
82 for (uint32_t I
= 0; I
< Modules
.getModuleCount(); ++I
) {
83 IndexedModuleDescriptor IMD
;
85 IMD
.Descriptor
= Modules
.getModuleDescriptor(I
);
86 uint16_t SN
= IMD
.Descriptor
.getModuleStreamIndex();
87 if (SN
!= kInvalidStreamIndex
)
92 for (auto &NSE
: Info
->named_streams()) {
93 if (NSE
.second
!= kInvalidStreamIndex
)
94 NamedStreams
[NSE
.second
] = NSE
.first();
98 Streams
.resize(StreamCount
);
99 for (uint16_t StreamIdx
= 0; StreamIdx
< StreamCount
; ++StreamIdx
) {
100 if (StreamIdx
== OldMSFDirectory
)
102 stream(StreamPurpose::Other
, "Old MSF Directory", StreamIdx
);
103 else if (StreamIdx
== StreamPDB
)
104 Streams
[StreamIdx
] = stream(StreamPurpose::PDB
, "PDB Stream", StreamIdx
);
105 else if (StreamIdx
== StreamDBI
)
106 Streams
[StreamIdx
] = stream(StreamPurpose::DBI
, "DBI Stream", StreamIdx
);
107 else if (StreamIdx
== StreamTPI
)
108 Streams
[StreamIdx
] = stream(StreamPurpose::TPI
, "TPI Stream", StreamIdx
);
109 else if (StreamIdx
== StreamIPI
)
110 Streams
[StreamIdx
] = stream(StreamPurpose::IPI
, "IPI Stream", StreamIdx
);
111 else if (Dbi
&& StreamIdx
== Dbi
->getGlobalSymbolStreamIndex())
113 stream(StreamPurpose::GlobalHash
, "Global Symbol Hash", StreamIdx
);
114 else if (Dbi
&& StreamIdx
== Dbi
->getPublicSymbolStreamIndex())
116 stream(StreamPurpose::PublicHash
, "Public Symbol Hash", StreamIdx
);
117 else if (Dbi
&& StreamIdx
== Dbi
->getSymRecordStreamIndex())
119 stream(StreamPurpose::Symbols
, "Symbol Records", StreamIdx
);
120 else if (Tpi
&& StreamIdx
== Tpi
->getTypeHashStreamIndex())
122 stream(StreamPurpose::TpiHash
, "TPI Hash", StreamIdx
);
123 else if (Tpi
&& StreamIdx
== Tpi
->getTypeHashStreamAuxIndex())
125 stream(StreamPurpose::Other
, "TPI Aux Hash", StreamIdx
);
126 else if (Ipi
&& StreamIdx
== Ipi
->getTypeHashStreamIndex())
128 stream(StreamPurpose::IpiHash
, "IPI Hash", StreamIdx
);
129 else if (Ipi
&& StreamIdx
== Ipi
->getTypeHashStreamAuxIndex())
131 stream(StreamPurpose::Other
, "IPI Aux Hash", StreamIdx
);
133 StreamIdx
== Dbi
->getDebugStreamIndex(DbgHeaderType::Exception
))
135 stream(StreamPurpose::Other
, "Exception Data", StreamIdx
);
136 else if (Dbi
&& StreamIdx
== Dbi
->getDebugStreamIndex(DbgHeaderType::Fixup
))
138 stream(StreamPurpose::Other
, "Fixup Data", StreamIdx
);
139 else if (Dbi
&& StreamIdx
== Dbi
->getDebugStreamIndex(DbgHeaderType::FPO
))
140 Streams
[StreamIdx
] = stream(StreamPurpose::Other
, "FPO Data", StreamIdx
);
142 StreamIdx
== Dbi
->getDebugStreamIndex(DbgHeaderType::NewFPO
))
144 stream(StreamPurpose::Other
, "New FPO Data", StreamIdx
);
146 StreamIdx
== Dbi
->getDebugStreamIndex(DbgHeaderType::OmapFromSrc
))
148 stream(StreamPurpose::Other
, "Omap From Source Data", StreamIdx
);
150 StreamIdx
== Dbi
->getDebugStreamIndex(DbgHeaderType::OmapToSrc
))
152 stream(StreamPurpose::Other
, "Omap To Source Data", StreamIdx
);
153 else if (Dbi
&& StreamIdx
== Dbi
->getDebugStreamIndex(DbgHeaderType::Pdata
))
154 Streams
[StreamIdx
] = stream(StreamPurpose::Other
, "Pdata", StreamIdx
);
156 StreamIdx
== Dbi
->getDebugStreamIndex(DbgHeaderType::SectionHdr
))
158 stream(StreamPurpose::Other
, "Section Header Data", StreamIdx
);
161 Dbi
->getDebugStreamIndex(DbgHeaderType::SectionHdrOrig
))
162 Streams
[StreamIdx
] = stream(StreamPurpose::Other
,
163 "Section Header Original Data", StreamIdx
);
165 StreamIdx
== Dbi
->getDebugStreamIndex(DbgHeaderType::TokenRidMap
))
167 stream(StreamPurpose::Other
, "Token Rid Data", StreamIdx
);
168 else if (Dbi
&& StreamIdx
== Dbi
->getDebugStreamIndex(DbgHeaderType::Xdata
))
169 Streams
[StreamIdx
] = stream(StreamPurpose::Other
, "Xdata", StreamIdx
);
171 auto ModIter
= ModStreams
.find(StreamIdx
);
172 auto NSIter
= NamedStreams
.find(StreamIdx
);
173 if (ModIter
!= ModStreams
.end()) {
175 moduleStream(ModIter
->second
.Descriptor
.getModuleName(), StreamIdx
,
176 ModIter
->second
.Modi
);
177 } else if (NSIter
!= NamedStreams
.end()) {
179 stream(StreamPurpose::NamedStream
, NSIter
->second
, StreamIdx
);
181 Streams
[StreamIdx
] = stream(StreamPurpose::Other
, "???", StreamIdx
);
186 // Consume errors from missing streams.
188 consumeError(Dbi
.takeError());
190 consumeError(Tpi
.takeError());
192 consumeError(Ipi
.takeError());
194 consumeError(Info
.takeError());