19940203aSZachary Turner //===- BytesOutputStyle.cpp ----------------------------------- *- C++ --*-===//
29940203aSZachary Turner //
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
69940203aSZachary Turner //
79940203aSZachary Turner //===----------------------------------------------------------------------===//
89940203aSZachary Turner
99940203aSZachary Turner #include "BytesOutputStyle.h"
109940203aSZachary Turner
119940203aSZachary Turner #include "StreamUtil.h"
129940203aSZachary Turner #include "llvm-pdbutil.h"
139940203aSZachary Turner
14c2f5b4bfSZachary Turner #include "llvm/DebugInfo/CodeView/Formatters.h"
15c2f5b4bfSZachary Turner #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
16c3d8eec9SZachary Turner #include "llvm/DebugInfo/MSF/MSFCommon.h"
179940203aSZachary Turner #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
18dd739682SZachary Turner #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
1975112133SCarlos Alberto Enciso #include "llvm/DebugInfo/PDB/Native/FormatUtil.h"
206c3e41bbSZachary Turner #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
21fa332827SZachary Turner #include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
229940203aSZachary Turner #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
239940203aSZachary Turner #include "llvm/DebugInfo/PDB/Native/RawError.h"
24c2f5b4bfSZachary Turner #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
259940203aSZachary Turner #include "llvm/Support/BinaryStreamReader.h"
269940203aSZachary Turner #include "llvm/Support/FormatAdapters.h"
279940203aSZachary Turner #include "llvm/Support/FormatVariadic.h"
289940203aSZachary Turner
299940203aSZachary Turner using namespace llvm;
30c2f5b4bfSZachary Turner using namespace llvm::codeview;
319940203aSZachary Turner using namespace llvm::msf;
329940203aSZachary Turner using namespace llvm::pdb;
339940203aSZachary Turner
349940203aSZachary Turner namespace {
359940203aSZachary Turner struct StreamSpec {
369940203aSZachary Turner uint32_t SI = 0;
379940203aSZachary Turner uint32_t Begin = 0;
389940203aSZachary Turner uint32_t Size = 0;
399940203aSZachary Turner };
409940203aSZachary Turner } // namespace
419940203aSZachary Turner
parseStreamSpec(StringRef Str)429940203aSZachary Turner static Expected<StreamSpec> parseStreamSpec(StringRef Str) {
439940203aSZachary Turner StreamSpec Result;
449940203aSZachary Turner if (Str.consumeInteger(0, Result.SI))
459940203aSZachary Turner return make_error<RawError>(raw_error_code::invalid_format,
469940203aSZachary Turner "Invalid Stream Specification");
479940203aSZachary Turner if (Str.consume_front(":")) {
489940203aSZachary Turner if (Str.consumeInteger(0, Result.Begin))
499940203aSZachary Turner return make_error<RawError>(raw_error_code::invalid_format,
509940203aSZachary Turner "Invalid Stream Specification");
519940203aSZachary Turner }
529940203aSZachary Turner if (Str.consume_front("@")) {
539940203aSZachary Turner if (Str.consumeInteger(0, Result.Size))
549940203aSZachary Turner return make_error<RawError>(raw_error_code::invalid_format,
559940203aSZachary Turner "Invalid Stream Specification");
569940203aSZachary Turner }
579940203aSZachary Turner
589940203aSZachary Turner if (!Str.empty())
599940203aSZachary Turner return make_error<RawError>(raw_error_code::invalid_format,
609940203aSZachary Turner "Invalid Stream Specification");
619940203aSZachary Turner return Result;
629940203aSZachary Turner }
639940203aSZachary Turner
parseStreamSpecs(LinePrinter & P)649940203aSZachary Turner static SmallVector<StreamSpec, 2> parseStreamSpecs(LinePrinter &P) {
659940203aSZachary Turner SmallVector<StreamSpec, 2> Result;
669940203aSZachary Turner
679940203aSZachary Turner for (auto &Str : opts::bytes::DumpStreamData) {
689940203aSZachary Turner auto ESS = parseStreamSpec(Str);
699940203aSZachary Turner if (!ESS) {
709940203aSZachary Turner P.formatLine("Error parsing stream spec {0}: {1}", Str,
719940203aSZachary Turner toString(ESS.takeError()));
729940203aSZachary Turner continue;
739940203aSZachary Turner }
749940203aSZachary Turner Result.push_back(*ESS);
759940203aSZachary Turner }
769940203aSZachary Turner return Result;
779940203aSZachary Turner }
789940203aSZachary Turner
printHeader(LinePrinter & P,const Twine & S)799940203aSZachary Turner static void printHeader(LinePrinter &P, const Twine &S) {
809940203aSZachary Turner P.NewLine();
819940203aSZachary Turner P.formatLine("{0,=60}", S);
829940203aSZachary Turner P.formatLine("{0}", fmt_repeat('=', 60));
839940203aSZachary Turner }
849940203aSZachary Turner
BytesOutputStyle(PDBFile & File)859940203aSZachary Turner BytesOutputStyle::BytesOutputStyle(PDBFile &File)
8675112133SCarlos Alberto Enciso : File(File), P(2, false, outs(), opts::Filters) {}
879940203aSZachary Turner
dump()889940203aSZachary Turner Error BytesOutputStyle::dump() {
899940203aSZachary Turner
90*e0e687a6SKazu Hirata if (opts::bytes::DumpBlockRange) {
919940203aSZachary Turner auto &R = *opts::bytes::DumpBlockRange;
92129b531cSKazu Hirata uint32_t Max = R.Max.value_or(R.Min);
939940203aSZachary Turner
949940203aSZachary Turner if (Max < R.Min)
959940203aSZachary Turner return make_error<StringError>(
969940203aSZachary Turner "Invalid block range specified. Max < Min",
979940203aSZachary Turner inconvertibleErrorCode());
989940203aSZachary Turner if (Max >= File.getBlockCount())
999940203aSZachary Turner return make_error<StringError>(
1009940203aSZachary Turner "Invalid block range specified. Requested block out of bounds",
1019940203aSZachary Turner inconvertibleErrorCode());
1029940203aSZachary Turner
1039940203aSZachary Turner dumpBlockRanges(R.Min, Max);
1049940203aSZachary Turner P.NewLine();
1059940203aSZachary Turner }
1069940203aSZachary Turner
107*e0e687a6SKazu Hirata if (opts::bytes::DumpByteRange) {
1086b124f29SZachary Turner auto &R = *opts::bytes::DumpByteRange;
109129b531cSKazu Hirata uint32_t Max = R.Max.value_or(File.getFileSize());
1106b124f29SZachary Turner
1116b124f29SZachary Turner if (Max < R.Min)
1126b124f29SZachary Turner return make_error<StringError>("Invalid byte range specified. Max < Min",
1136b124f29SZachary Turner inconvertibleErrorCode());
1146b124f29SZachary Turner if (Max >= File.getFileSize())
1156b124f29SZachary Turner return make_error<StringError>(
1166b124f29SZachary Turner "Invalid byte range specified. Requested byte larger than file size",
1176b124f29SZachary Turner inconvertibleErrorCode());
1186b124f29SZachary Turner
1196b124f29SZachary Turner dumpByteRanges(R.Min, Max);
1206b124f29SZachary Turner P.NewLine();
1216b124f29SZachary Turner }
1226b124f29SZachary Turner
123c3d8eec9SZachary Turner if (opts::bytes::Fpm) {
124c3d8eec9SZachary Turner dumpFpm();
125c3d8eec9SZachary Turner P.NewLine();
126c3d8eec9SZachary Turner }
127c3d8eec9SZachary Turner
1289940203aSZachary Turner if (!opts::bytes::DumpStreamData.empty()) {
1299940203aSZachary Turner dumpStreamBytes();
1309940203aSZachary Turner P.NewLine();
1319940203aSZachary Turner }
1326c3e41bbSZachary Turner
1336c3e41bbSZachary Turner if (opts::bytes::NameMap) {
1346c3e41bbSZachary Turner dumpNameMap();
1356c3e41bbSZachary Turner P.NewLine();
1366c3e41bbSZachary Turner }
137dd739682SZachary Turner
138dd739682SZachary Turner if (opts::bytes::SectionContributions) {
139dd739682SZachary Turner dumpSectionContributions();
140dd739682SZachary Turner P.NewLine();
141dd739682SZachary Turner }
142dd739682SZachary Turner
143dd739682SZachary Turner if (opts::bytes::SectionMap) {
144dd739682SZachary Turner dumpSectionMap();
145dd739682SZachary Turner P.NewLine();
146dd739682SZachary Turner }
147dd739682SZachary Turner
148dd739682SZachary Turner if (opts::bytes::ModuleInfos) {
149dd739682SZachary Turner dumpModuleInfos();
150dd739682SZachary Turner P.NewLine();
151dd739682SZachary Turner }
152dd739682SZachary Turner
153dd739682SZachary Turner if (opts::bytes::FileInfo) {
154dd739682SZachary Turner dumpFileInfo();
155dd739682SZachary Turner P.NewLine();
156dd739682SZachary Turner }
157dd739682SZachary Turner
158dd739682SZachary Turner if (opts::bytes::TypeServerMap) {
159dd739682SZachary Turner dumpTypeServerMap();
160dd739682SZachary Turner P.NewLine();
161dd739682SZachary Turner }
162dd739682SZachary Turner
163dd739682SZachary Turner if (opts::bytes::ECData) {
164dd739682SZachary Turner dumpECData();
165dd739682SZachary Turner P.NewLine();
166dd739682SZachary Turner }
167dd739682SZachary Turner
168c2f5b4bfSZachary Turner if (!opts::bytes::TypeIndex.empty()) {
169c2f5b4bfSZachary Turner dumpTypeIndex(StreamTPI, opts::bytes::TypeIndex);
170c2f5b4bfSZachary Turner P.NewLine();
171c2f5b4bfSZachary Turner }
172c2f5b4bfSZachary Turner
173c2f5b4bfSZachary Turner if (!opts::bytes::IdIndex.empty()) {
174c2f5b4bfSZachary Turner dumpTypeIndex(StreamIPI, opts::bytes::IdIndex);
175c2f5b4bfSZachary Turner P.NewLine();
176c2f5b4bfSZachary Turner }
177c2f5b4bfSZachary Turner
178fa332827SZachary Turner if (opts::bytes::ModuleSyms) {
179fa332827SZachary Turner dumpModuleSyms();
180fa332827SZachary Turner P.NewLine();
181fa332827SZachary Turner }
182fa332827SZachary Turner
183fa332827SZachary Turner if (opts::bytes::ModuleC11) {
184fa332827SZachary Turner dumpModuleC11();
185fa332827SZachary Turner P.NewLine();
186fa332827SZachary Turner }
187fa332827SZachary Turner
188fa332827SZachary Turner if (opts::bytes::ModuleC13) {
189fa332827SZachary Turner dumpModuleC13();
190fa332827SZachary Turner P.NewLine();
191fa332827SZachary Turner }
192fa332827SZachary Turner
1939940203aSZachary Turner return Error::success();
1949940203aSZachary Turner }
1959940203aSZachary Turner
dumpNameMap()1966c3e41bbSZachary Turner void BytesOutputStyle::dumpNameMap() {
1976c3e41bbSZachary Turner printHeader(P, "Named Stream Map");
1986c3e41bbSZachary Turner
1996c3e41bbSZachary Turner AutoIndent Indent(P);
2006c3e41bbSZachary Turner
2016c3e41bbSZachary Turner auto &InfoS = Err(File.getPDBInfoStream());
2026c3e41bbSZachary Turner BinarySubstreamRef NS = InfoS.getNamedStreamsBuffer();
2036c3e41bbSZachary Turner auto Layout = File.getStreamLayout(StreamPDB);
2046c3e41bbSZachary Turner P.formatMsfStreamData("Named Stream Map", File, Layout, NS);
2056c3e41bbSZachary Turner }
2066c3e41bbSZachary Turner
dumpBlockRanges(uint32_t Min,uint32_t Max)2079940203aSZachary Turner void BytesOutputStyle::dumpBlockRanges(uint32_t Min, uint32_t Max) {
2089940203aSZachary Turner printHeader(P, "MSF Blocks");
2099940203aSZachary Turner
2109940203aSZachary Turner AutoIndent Indent(P);
2119940203aSZachary Turner for (uint32_t I = Min; I <= Max; ++I) {
2129940203aSZachary Turner uint64_t Base = I;
2139940203aSZachary Turner Base *= File.getBlockSize();
2149940203aSZachary Turner
2159940203aSZachary Turner auto ExpectedData = File.getBlockData(I, File.getBlockSize());
2169940203aSZachary Turner if (!ExpectedData) {
2179940203aSZachary Turner P.formatLine("Could not get block {0}. Reason = {1}", I,
2189940203aSZachary Turner toString(ExpectedData.takeError()));
2199940203aSZachary Turner continue;
2209940203aSZachary Turner }
2219940203aSZachary Turner std::string Label = formatv("Block {0}", I).str();
2229940203aSZachary Turner P.formatBinary(Label, *ExpectedData, Base, 0);
2239940203aSZachary Turner }
2249940203aSZachary Turner }
2259940203aSZachary Turner
dumpSectionContributions()226dd739682SZachary Turner void BytesOutputStyle::dumpSectionContributions() {
227dd739682SZachary Turner printHeader(P, "Section Contributions");
228dd739682SZachary Turner
229dd739682SZachary Turner AutoIndent Indent(P);
230dd739682SZachary Turner
231dd739682SZachary Turner auto &DbiS = Err(File.getPDBDbiStream());
232dd739682SZachary Turner BinarySubstreamRef NS = DbiS.getSectionContributionData();
233dd739682SZachary Turner auto Layout = File.getStreamLayout(StreamDBI);
234dd739682SZachary Turner P.formatMsfStreamData("Section Contributions", File, Layout, NS);
235dd739682SZachary Turner }
236dd739682SZachary Turner
dumpSectionMap()237dd739682SZachary Turner void BytesOutputStyle::dumpSectionMap() {
238dd739682SZachary Turner printHeader(P, "Section Map");
239dd739682SZachary Turner
240dd739682SZachary Turner AutoIndent Indent(P);
241dd739682SZachary Turner
242dd739682SZachary Turner auto &DbiS = Err(File.getPDBDbiStream());
243dd739682SZachary Turner BinarySubstreamRef NS = DbiS.getSecMapSubstreamData();
244dd739682SZachary Turner auto Layout = File.getStreamLayout(StreamDBI);
245dd739682SZachary Turner P.formatMsfStreamData("Section Map", File, Layout, NS);
246dd739682SZachary Turner }
247dd739682SZachary Turner
dumpModuleInfos()248dd739682SZachary Turner void BytesOutputStyle::dumpModuleInfos() {
249dd739682SZachary Turner printHeader(P, "Module Infos");
250dd739682SZachary Turner
251dd739682SZachary Turner AutoIndent Indent(P);
252dd739682SZachary Turner
253dd739682SZachary Turner auto &DbiS = Err(File.getPDBDbiStream());
254dd739682SZachary Turner BinarySubstreamRef NS = DbiS.getModiSubstreamData();
255dd739682SZachary Turner auto Layout = File.getStreamLayout(StreamDBI);
256dd739682SZachary Turner P.formatMsfStreamData("Module Infos", File, Layout, NS);
257dd739682SZachary Turner }
258dd739682SZachary Turner
dumpFileInfo()259dd739682SZachary Turner void BytesOutputStyle::dumpFileInfo() {
260dd739682SZachary Turner printHeader(P, "File Info");
261dd739682SZachary Turner
262dd739682SZachary Turner AutoIndent Indent(P);
263dd739682SZachary Turner
264dd739682SZachary Turner auto &DbiS = Err(File.getPDBDbiStream());
265dd739682SZachary Turner BinarySubstreamRef NS = DbiS.getFileInfoSubstreamData();
266dd739682SZachary Turner auto Layout = File.getStreamLayout(StreamDBI);
267dd739682SZachary Turner P.formatMsfStreamData("File Info", File, Layout, NS);
268dd739682SZachary Turner }
269dd739682SZachary Turner
dumpTypeServerMap()270dd739682SZachary Turner void BytesOutputStyle::dumpTypeServerMap() {
271dd739682SZachary Turner printHeader(P, "Type Server Map");
272dd739682SZachary Turner
273dd739682SZachary Turner AutoIndent Indent(P);
274dd739682SZachary Turner
275dd739682SZachary Turner auto &DbiS = Err(File.getPDBDbiStream());
276dd739682SZachary Turner BinarySubstreamRef NS = DbiS.getTypeServerMapSubstreamData();
277dd739682SZachary Turner auto Layout = File.getStreamLayout(StreamDBI);
278dd739682SZachary Turner P.formatMsfStreamData("Type Server Map", File, Layout, NS);
279dd739682SZachary Turner }
280dd739682SZachary Turner
dumpECData()281dd739682SZachary Turner void BytesOutputStyle::dumpECData() {
282dd739682SZachary Turner printHeader(P, "Edit and Continue Data");
283dd739682SZachary Turner
284dd739682SZachary Turner AutoIndent Indent(P);
285dd739682SZachary Turner
286dd739682SZachary Turner auto &DbiS = Err(File.getPDBDbiStream());
287dd739682SZachary Turner BinarySubstreamRef NS = DbiS.getECSubstreamData();
288dd739682SZachary Turner auto Layout = File.getStreamLayout(StreamDBI);
289dd739682SZachary Turner P.formatMsfStreamData("Edit and Continue Data", File, Layout, NS);
290dd739682SZachary Turner }
291dd739682SZachary Turner
dumpTypeIndex(uint32_t StreamIdx,ArrayRef<uint32_t> Indices)292c2f5b4bfSZachary Turner void BytesOutputStyle::dumpTypeIndex(uint32_t StreamIdx,
293c2f5b4bfSZachary Turner ArrayRef<uint32_t> Indices) {
294c2f5b4bfSZachary Turner assert(StreamIdx == StreamTPI || StreamIdx == StreamIPI);
295c2f5b4bfSZachary Turner assert(!Indices.empty());
296c2f5b4bfSZachary Turner
297c2f5b4bfSZachary Turner bool IsTpi = (StreamIdx == StreamTPI);
298c2f5b4bfSZachary Turner
299c2f5b4bfSZachary Turner StringRef Label = IsTpi ? "Type (TPI) Records" : "Index (IPI) Records";
300c2f5b4bfSZachary Turner printHeader(P, Label);
301c2f5b4bfSZachary Turner auto &Stream = Err(IsTpi ? File.getPDBTpiStream() : File.getPDBIpiStream());
302c2f5b4bfSZachary Turner
303c2f5b4bfSZachary Turner AutoIndent Indent(P);
304c2f5b4bfSZachary Turner
305c2f5b4bfSZachary Turner auto Substream = Stream.getTypeRecordsSubstream();
306c2f5b4bfSZachary Turner auto &Types = Err(initializeTypes(StreamIdx));
307c2f5b4bfSZachary Turner auto Layout = File.getStreamLayout(StreamIdx);
308c2f5b4bfSZachary Turner for (const auto &Id : Indices) {
309c2f5b4bfSZachary Turner TypeIndex TI(Id);
310c2f5b4bfSZachary Turner if (TI.toArrayIndex() >= Types.capacity()) {
311c2f5b4bfSZachary Turner P.formatLine("Error: TypeIndex {0} does not exist", TI);
312c2f5b4bfSZachary Turner continue;
313c2f5b4bfSZachary Turner }
314c2f5b4bfSZachary Turner
315c2f5b4bfSZachary Turner auto Type = Types.getType(TI);
316c2f5b4bfSZachary Turner uint32_t Offset = Types.getOffsetOfType(TI);
317c2f5b4bfSZachary Turner auto OneType = Substream.slice(Offset, Type.length());
318c2f5b4bfSZachary Turner P.formatMsfStreamData(formatv("Type {0}", TI).str(), File, Layout, OneType);
319c2f5b4bfSZachary Turner }
320c2f5b4bfSZachary Turner }
321c2f5b4bfSZachary Turner
322fa332827SZachary Turner template <typename CallbackT>
iterateOneModule(PDBFile & File,LinePrinter & P,const DbiModuleList & Modules,uint32_t I,uint32_t Digits,uint32_t IndentLevel,CallbackT Callback)323fa332827SZachary Turner static void iterateOneModule(PDBFile &File, LinePrinter &P,
324fa332827SZachary Turner const DbiModuleList &Modules, uint32_t I,
325fa332827SZachary Turner uint32_t Digits, uint32_t IndentLevel,
326fa332827SZachary Turner CallbackT Callback) {
327e79b07e4SZachary Turner if (I >= Modules.getModuleCount()) {
328e79b07e4SZachary Turner P.formatLine("Mod {0:4} | Invalid module index ",
329e79b07e4SZachary Turner fmt_align(I, AlignStyle::Right, std::max(Digits, 4U)));
330e79b07e4SZachary Turner return;
331e79b07e4SZachary Turner }
332e79b07e4SZachary Turner
333fa332827SZachary Turner auto Modi = Modules.getModuleDescriptor(I);
334fa332827SZachary Turner P.formatLine("Mod {0:4} | `{1}`: ",
335fa332827SZachary Turner fmt_align(I, AlignStyle::Right, std::max(Digits, 4U)),
336fa332827SZachary Turner Modi.getModuleName());
337fa332827SZachary Turner
338fa332827SZachary Turner uint16_t ModiStream = Modi.getModuleStreamIndex();
339fa332827SZachary Turner AutoIndent Indent2(P, IndentLevel);
340e79b07e4SZachary Turner if (ModiStream == kInvalidStreamIndex)
341e79b07e4SZachary Turner return;
342e79b07e4SZachary Turner
34313f7ddffSNico Weber auto ModStreamData = File.createIndexedStream(ModiStream);
344fa332827SZachary Turner ModuleDebugStreamRef ModStream(Modi, std::move(ModStreamData));
345fa332827SZachary Turner if (auto EC = ModStream.reload()) {
346fa332827SZachary Turner P.formatLine("Could not parse debug information.");
347fa332827SZachary Turner return;
348fa332827SZachary Turner }
349fa332827SZachary Turner auto Layout = File.getStreamLayout(ModiStream);
350fa332827SZachary Turner Callback(I, ModStream, Layout);
351fa332827SZachary Turner }
352fa332827SZachary Turner
353fa332827SZachary Turner template <typename CallbackT>
iterateModules(PDBFile & File,LinePrinter & P,uint32_t IndentLevel,CallbackT Callback)354fa332827SZachary Turner static void iterateModules(PDBFile &File, LinePrinter &P, uint32_t IndentLevel,
355fa332827SZachary Turner CallbackT Callback) {
356fa332827SZachary Turner AutoIndent Indent(P);
357fa332827SZachary Turner if (!File.hasPDBDbiStream()) {
358fa332827SZachary Turner P.formatLine("DBI Stream not present");
359fa332827SZachary Turner return;
360fa332827SZachary Turner }
361fa332827SZachary Turner
362fa332827SZachary Turner ExitOnError Err("Unexpected error processing modules");
363fa332827SZachary Turner
364fa332827SZachary Turner auto &Stream = Err(File.getPDBDbiStream());
365fa332827SZachary Turner
366fa332827SZachary Turner const DbiModuleList &Modules = Stream.modules();
367fa332827SZachary Turner
368fa332827SZachary Turner if (opts::bytes::ModuleIndex.getNumOccurrences() > 0) {
369fa332827SZachary Turner iterateOneModule(File, P, Modules, opts::bytes::ModuleIndex, 1, IndentLevel,
370fa332827SZachary Turner Callback);
371fa332827SZachary Turner } else {
372fa332827SZachary Turner uint32_t Count = Modules.getModuleCount();
373fa332827SZachary Turner uint32_t Digits = NumDigits(Count);
374fa332827SZachary Turner for (uint32_t I = 0; I < Count; ++I) {
375fa332827SZachary Turner iterateOneModule(File, P, Modules, I, Digits, IndentLevel, Callback);
376fa332827SZachary Turner }
377fa332827SZachary Turner }
378fa332827SZachary Turner }
379fa332827SZachary Turner
dumpModuleSyms()380fa332827SZachary Turner void BytesOutputStyle::dumpModuleSyms() {
381fa332827SZachary Turner printHeader(P, "Module Symbols");
382fa332827SZachary Turner
383fa332827SZachary Turner AutoIndent Indent(P);
384fa332827SZachary Turner
385fa332827SZachary Turner iterateModules(File, P, 2,
386fa332827SZachary Turner [this](uint32_t Modi, const ModuleDebugStreamRef &Stream,
387fa332827SZachary Turner const MSFStreamLayout &Layout) {
388fa332827SZachary Turner auto Symbols = Stream.getSymbolsSubstream();
389fa332827SZachary Turner P.formatMsfStreamData("Symbols", File, Layout, Symbols);
390fa332827SZachary Turner });
391fa332827SZachary Turner }
392fa332827SZachary Turner
dumpModuleC11()393fa332827SZachary Turner void BytesOutputStyle::dumpModuleC11() {
394fa332827SZachary Turner printHeader(P, "C11 Debug Chunks");
395fa332827SZachary Turner
396fa332827SZachary Turner AutoIndent Indent(P);
397fa332827SZachary Turner
398fa332827SZachary Turner iterateModules(File, P, 2,
399fa332827SZachary Turner [this](uint32_t Modi, const ModuleDebugStreamRef &Stream,
400fa332827SZachary Turner const MSFStreamLayout &Layout) {
401fa332827SZachary Turner auto Chunks = Stream.getC11LinesSubstream();
402fa332827SZachary Turner P.formatMsfStreamData("C11 Debug Chunks", File, Layout,
403fa332827SZachary Turner Chunks);
404fa332827SZachary Turner });
405fa332827SZachary Turner }
406fa332827SZachary Turner
dumpModuleC13()407fa332827SZachary Turner void BytesOutputStyle::dumpModuleC13() {
408fa332827SZachary Turner printHeader(P, "Debug Chunks");
409fa332827SZachary Turner
410fa332827SZachary Turner AutoIndent Indent(P);
411fa332827SZachary Turner
412e79b07e4SZachary Turner iterateModules(
413e79b07e4SZachary Turner File, P, 2,
414fa332827SZachary Turner [this](uint32_t Modi, const ModuleDebugStreamRef &Stream,
415fa332827SZachary Turner const MSFStreamLayout &Layout) {
416fa332827SZachary Turner auto Chunks = Stream.getC13LinesSubstream();
417e79b07e4SZachary Turner if (opts::bytes::SplitChunks) {
418e79b07e4SZachary Turner for (const auto &SS : Stream.subsections()) {
419e79b07e4SZachary Turner BinarySubstreamRef ThisChunk;
420e79b07e4SZachary Turner std::tie(ThisChunk, Chunks) = Chunks.split(SS.getRecordLength());
421e79b07e4SZachary Turner P.formatMsfStreamData(formatChunkKind(SS.kind()), File, Layout,
422e79b07e4SZachary Turner ThisChunk);
423e79b07e4SZachary Turner }
424e79b07e4SZachary Turner } else {
425fa332827SZachary Turner P.formatMsfStreamData("Debug Chunks", File, Layout, Chunks);
426e79b07e4SZachary Turner }
427fa332827SZachary Turner });
428fa332827SZachary Turner }
429fa332827SZachary Turner
dumpByteRanges(uint32_t Min,uint32_t Max)4306b124f29SZachary Turner void BytesOutputStyle::dumpByteRanges(uint32_t Min, uint32_t Max) {
4316b124f29SZachary Turner printHeader(P, "MSF Bytes");
4326b124f29SZachary Turner
4336b124f29SZachary Turner AutoIndent Indent(P);
4346b124f29SZachary Turner
4356b124f29SZachary Turner BinaryStreamReader Reader(File.getMsfBuffer());
4366b124f29SZachary Turner ArrayRef<uint8_t> Data;
4376b124f29SZachary Turner consumeError(Reader.skip(Min));
4386b124f29SZachary Turner uint32_t Size = Max - Min + 1;
4396b124f29SZachary Turner auto EC = Reader.readBytes(Data, Size);
4406b124f29SZachary Turner assert(!EC);
4416b124f29SZachary Turner consumeError(std::move(EC));
4426b124f29SZachary Turner P.formatBinary("Bytes", Data, Min);
4436b124f29SZachary Turner }
4446b124f29SZachary Turner
445c2f5b4bfSZachary Turner Expected<codeview::LazyRandomTypeCollection &>
initializeTypes(uint32_t StreamIdx)446c2f5b4bfSZachary Turner BytesOutputStyle::initializeTypes(uint32_t StreamIdx) {
447c2f5b4bfSZachary Turner auto &TypeCollection = (StreamIdx == StreamTPI) ? TpiTypes : IpiTypes;
448c2f5b4bfSZachary Turner if (TypeCollection)
449c2f5b4bfSZachary Turner return *TypeCollection;
450c2f5b4bfSZachary Turner
451c2f5b4bfSZachary Turner auto Tpi = (StreamIdx == StreamTPI) ? File.getPDBTpiStream()
452c2f5b4bfSZachary Turner : File.getPDBIpiStream();
453c2f5b4bfSZachary Turner if (!Tpi)
454c2f5b4bfSZachary Turner return Tpi.takeError();
455c2f5b4bfSZachary Turner
456c2f5b4bfSZachary Turner auto &Types = Tpi->typeArray();
457c2f5b4bfSZachary Turner uint32_t Count = Tpi->getNumTypeRecords();
458c2f5b4bfSZachary Turner auto Offsets = Tpi->getTypeIndexOffsets();
459c2f5b4bfSZachary Turner TypeCollection =
4600eaee545SJonas Devlieghere std::make_unique<LazyRandomTypeCollection>(Types, Count, Offsets);
461c2f5b4bfSZachary Turner
462c2f5b4bfSZachary Turner return *TypeCollection;
463c2f5b4bfSZachary Turner }
464c2f5b4bfSZachary Turner
dumpFpm()465c3d8eec9SZachary Turner void BytesOutputStyle::dumpFpm() {
466c3d8eec9SZachary Turner printHeader(P, "Free Page Map");
467c3d8eec9SZachary Turner
468c3d8eec9SZachary Turner msf::MSFStreamLayout FpmLayout = File.getFpmStreamLayout();
469c3d8eec9SZachary Turner P.formatMsfStreamBlocks(File, FpmLayout);
470c3d8eec9SZachary Turner }
471c3d8eec9SZachary Turner
dumpStreamBytes()4729940203aSZachary Turner void BytesOutputStyle::dumpStreamBytes() {
4739940203aSZachary Turner if (StreamPurposes.empty())
4749940203aSZachary Turner discoverStreamPurposes(File, StreamPurposes);
4759940203aSZachary Turner
4769940203aSZachary Turner printHeader(P, "Stream Data");
4779940203aSZachary Turner ExitOnError Err("Unexpected error reading stream data");
4789940203aSZachary Turner
4799940203aSZachary Turner auto Specs = parseStreamSpecs(P);
4809940203aSZachary Turner
4819940203aSZachary Turner for (const auto &Spec : Specs) {
4829940203aSZachary Turner AutoIndent Indent(P);
4830b36c3ebSZachary Turner if (Spec.SI >= StreamPurposes.size()) {
4849940203aSZachary Turner P.formatLine("Stream {0}: Not present", Spec.SI);
4859940203aSZachary Turner continue;
4869940203aSZachary Turner }
487d1de2f4fSZachary Turner P.formatMsfStreamData("Data", File, Spec.SI,
488d1de2f4fSZachary Turner StreamPurposes[Spec.SI].getShortName(), Spec.Begin,
489d1de2f4fSZachary Turner Spec.Size);
4909940203aSZachary Turner }
4919940203aSZachary Turner }
492