1*9880d681SAndroid Build Coastguard Worker //===- LLVMOutputStyle.cpp ------------------------------------ *- C++ --*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Worker #include "LLVMOutputStyle.h"
11*9880d681SAndroid Build Coastguard Worker
12*9880d681SAndroid Build Coastguard Worker #include "llvm-pdbdump.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/CodeView/EnumTables.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/CodeView/SymbolDumper.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/PDBExtras.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/Raw/EnumTables.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/Raw/ISectionContribVisitor.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/Raw/ModInfo.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/Raw/ModStream.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/Raw/PublicsStream.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/Raw/RawError.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/Raw/TpiStream.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/COFF.h"
29*9880d681SAndroid Build Coastguard Worker
30*9880d681SAndroid Build Coastguard Worker #include <unordered_map>
31*9880d681SAndroid Build Coastguard Worker
32*9880d681SAndroid Build Coastguard Worker using namespace llvm;
33*9880d681SAndroid Build Coastguard Worker using namespace llvm::codeview;
34*9880d681SAndroid Build Coastguard Worker using namespace llvm::pdb;
35*9880d681SAndroid Build Coastguard Worker
printSectionOffset(llvm::raw_ostream & OS,const SectionOffset & Off)36*9880d681SAndroid Build Coastguard Worker static void printSectionOffset(llvm::raw_ostream &OS,
37*9880d681SAndroid Build Coastguard Worker const SectionOffset &Off) {
38*9880d681SAndroid Build Coastguard Worker OS << Off.Off << ", " << Off.Isect;
39*9880d681SAndroid Build Coastguard Worker }
40*9880d681SAndroid Build Coastguard Worker
LLVMOutputStyle(PDBFile & File)41*9880d681SAndroid Build Coastguard Worker LLVMOutputStyle::LLVMOutputStyle(PDBFile &File)
42*9880d681SAndroid Build Coastguard Worker : File(File), P(outs()), TD(&P, false) {}
43*9880d681SAndroid Build Coastguard Worker
dump()44*9880d681SAndroid Build Coastguard Worker Error LLVMOutputStyle::dump() {
45*9880d681SAndroid Build Coastguard Worker if (auto EC = dumpFileHeaders())
46*9880d681SAndroid Build Coastguard Worker return EC;
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Worker if (auto EC = dumpStreamSummary())
49*9880d681SAndroid Build Coastguard Worker return EC;
50*9880d681SAndroid Build Coastguard Worker
51*9880d681SAndroid Build Coastguard Worker if (auto EC = dumpStreamBlocks())
52*9880d681SAndroid Build Coastguard Worker return EC;
53*9880d681SAndroid Build Coastguard Worker
54*9880d681SAndroid Build Coastguard Worker if (auto EC = dumpStreamData())
55*9880d681SAndroid Build Coastguard Worker return EC;
56*9880d681SAndroid Build Coastguard Worker
57*9880d681SAndroid Build Coastguard Worker if (auto EC = dumpInfoStream())
58*9880d681SAndroid Build Coastguard Worker return EC;
59*9880d681SAndroid Build Coastguard Worker
60*9880d681SAndroid Build Coastguard Worker if (auto EC = dumpNamedStream())
61*9880d681SAndroid Build Coastguard Worker return EC;
62*9880d681SAndroid Build Coastguard Worker
63*9880d681SAndroid Build Coastguard Worker if (auto EC = dumpTpiStream(StreamTPI))
64*9880d681SAndroid Build Coastguard Worker return EC;
65*9880d681SAndroid Build Coastguard Worker
66*9880d681SAndroid Build Coastguard Worker if (auto EC = dumpTpiStream(StreamIPI))
67*9880d681SAndroid Build Coastguard Worker return EC;
68*9880d681SAndroid Build Coastguard Worker
69*9880d681SAndroid Build Coastguard Worker if (auto EC = dumpDbiStream())
70*9880d681SAndroid Build Coastguard Worker return EC;
71*9880d681SAndroid Build Coastguard Worker
72*9880d681SAndroid Build Coastguard Worker if (auto EC = dumpSectionContribs())
73*9880d681SAndroid Build Coastguard Worker return EC;
74*9880d681SAndroid Build Coastguard Worker
75*9880d681SAndroid Build Coastguard Worker if (auto EC = dumpSectionMap())
76*9880d681SAndroid Build Coastguard Worker return EC;
77*9880d681SAndroid Build Coastguard Worker
78*9880d681SAndroid Build Coastguard Worker if (auto EC = dumpPublicsStream())
79*9880d681SAndroid Build Coastguard Worker return EC;
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Worker if (auto EC = dumpSectionHeaders())
82*9880d681SAndroid Build Coastguard Worker return EC;
83*9880d681SAndroid Build Coastguard Worker
84*9880d681SAndroid Build Coastguard Worker if (auto EC = dumpFpoStream())
85*9880d681SAndroid Build Coastguard Worker return EC;
86*9880d681SAndroid Build Coastguard Worker
87*9880d681SAndroid Build Coastguard Worker flush();
88*9880d681SAndroid Build Coastguard Worker
89*9880d681SAndroid Build Coastguard Worker return Error::success();
90*9880d681SAndroid Build Coastguard Worker }
91*9880d681SAndroid Build Coastguard Worker
dumpFileHeaders()92*9880d681SAndroid Build Coastguard Worker Error LLVMOutputStyle::dumpFileHeaders() {
93*9880d681SAndroid Build Coastguard Worker if (!opts::raw::DumpHeaders)
94*9880d681SAndroid Build Coastguard Worker return Error::success();
95*9880d681SAndroid Build Coastguard Worker
96*9880d681SAndroid Build Coastguard Worker DictScope D(P, "FileHeaders");
97*9880d681SAndroid Build Coastguard Worker P.printNumber("BlockSize", File.getBlockSize());
98*9880d681SAndroid Build Coastguard Worker P.printNumber("Unknown0", File.getUnknown0());
99*9880d681SAndroid Build Coastguard Worker P.printNumber("NumBlocks", File.getBlockCount());
100*9880d681SAndroid Build Coastguard Worker P.printNumber("NumDirectoryBytes", File.getNumDirectoryBytes());
101*9880d681SAndroid Build Coastguard Worker P.printNumber("Unknown1", File.getUnknown1());
102*9880d681SAndroid Build Coastguard Worker P.printNumber("BlockMapAddr", File.getBlockMapIndex());
103*9880d681SAndroid Build Coastguard Worker P.printNumber("NumDirectoryBlocks", File.getNumDirectoryBlocks());
104*9880d681SAndroid Build Coastguard Worker P.printNumber("BlockMapOffset", File.getBlockMapOffset());
105*9880d681SAndroid Build Coastguard Worker
106*9880d681SAndroid Build Coastguard Worker // The directory is not contiguous. Instead, the block map contains a
107*9880d681SAndroid Build Coastguard Worker // contiguous list of block numbers whose contents, when concatenated in
108*9880d681SAndroid Build Coastguard Worker // order, make up the directory.
109*9880d681SAndroid Build Coastguard Worker P.printList("DirectoryBlocks", File.getDirectoryBlockArray());
110*9880d681SAndroid Build Coastguard Worker P.printNumber("NumStreams", File.getNumStreams());
111*9880d681SAndroid Build Coastguard Worker return Error::success();
112*9880d681SAndroid Build Coastguard Worker }
113*9880d681SAndroid Build Coastguard Worker
dumpStreamSummary()114*9880d681SAndroid Build Coastguard Worker Error LLVMOutputStyle::dumpStreamSummary() {
115*9880d681SAndroid Build Coastguard Worker if (!opts::raw::DumpStreamSummary)
116*9880d681SAndroid Build Coastguard Worker return Error::success();
117*9880d681SAndroid Build Coastguard Worker
118*9880d681SAndroid Build Coastguard Worker // It's OK if we fail to load some of these streams, we still attempt to print
119*9880d681SAndroid Build Coastguard Worker // what we can.
120*9880d681SAndroid Build Coastguard Worker auto Dbi = File.getPDBDbiStream();
121*9880d681SAndroid Build Coastguard Worker auto Tpi = File.getPDBTpiStream();
122*9880d681SAndroid Build Coastguard Worker auto Ipi = File.getPDBIpiStream();
123*9880d681SAndroid Build Coastguard Worker auto Info = File.getPDBInfoStream();
124*9880d681SAndroid Build Coastguard Worker
125*9880d681SAndroid Build Coastguard Worker ListScope L(P, "Streams");
126*9880d681SAndroid Build Coastguard Worker uint32_t StreamCount = File.getNumStreams();
127*9880d681SAndroid Build Coastguard Worker std::unordered_map<uint16_t, const ModuleInfoEx *> ModStreams;
128*9880d681SAndroid Build Coastguard Worker std::unordered_map<uint16_t, std::string> NamedStreams;
129*9880d681SAndroid Build Coastguard Worker
130*9880d681SAndroid Build Coastguard Worker if (Dbi) {
131*9880d681SAndroid Build Coastguard Worker for (auto &ModI : Dbi->modules()) {
132*9880d681SAndroid Build Coastguard Worker uint16_t SN = ModI.Info.getModuleStreamIndex();
133*9880d681SAndroid Build Coastguard Worker ModStreams[SN] = &ModI;
134*9880d681SAndroid Build Coastguard Worker }
135*9880d681SAndroid Build Coastguard Worker }
136*9880d681SAndroid Build Coastguard Worker if (Info) {
137*9880d681SAndroid Build Coastguard Worker for (auto &NSE : Info->named_streams()) {
138*9880d681SAndroid Build Coastguard Worker NamedStreams[NSE.second] = NSE.first();
139*9880d681SAndroid Build Coastguard Worker }
140*9880d681SAndroid Build Coastguard Worker }
141*9880d681SAndroid Build Coastguard Worker
142*9880d681SAndroid Build Coastguard Worker for (uint16_t StreamIdx = 0; StreamIdx < StreamCount; ++StreamIdx) {
143*9880d681SAndroid Build Coastguard Worker std::string Label("Stream ");
144*9880d681SAndroid Build Coastguard Worker Label += to_string(StreamIdx);
145*9880d681SAndroid Build Coastguard Worker std::string Value;
146*9880d681SAndroid Build Coastguard Worker if (StreamIdx == OldMSFDirectory)
147*9880d681SAndroid Build Coastguard Worker Value = "Old MSF Directory";
148*9880d681SAndroid Build Coastguard Worker else if (StreamIdx == StreamPDB)
149*9880d681SAndroid Build Coastguard Worker Value = "PDB Stream";
150*9880d681SAndroid Build Coastguard Worker else if (StreamIdx == StreamDBI)
151*9880d681SAndroid Build Coastguard Worker Value = "DBI Stream";
152*9880d681SAndroid Build Coastguard Worker else if (StreamIdx == StreamTPI)
153*9880d681SAndroid Build Coastguard Worker Value = "TPI Stream";
154*9880d681SAndroid Build Coastguard Worker else if (StreamIdx == StreamIPI)
155*9880d681SAndroid Build Coastguard Worker Value = "IPI Stream";
156*9880d681SAndroid Build Coastguard Worker else if (Dbi && StreamIdx == Dbi->getGlobalSymbolStreamIndex())
157*9880d681SAndroid Build Coastguard Worker Value = "Global Symbol Hash";
158*9880d681SAndroid Build Coastguard Worker else if (Dbi && StreamIdx == Dbi->getPublicSymbolStreamIndex())
159*9880d681SAndroid Build Coastguard Worker Value = "Public Symbol Hash";
160*9880d681SAndroid Build Coastguard Worker else if (Dbi && StreamIdx == Dbi->getSymRecordStreamIndex())
161*9880d681SAndroid Build Coastguard Worker Value = "Public Symbol Records";
162*9880d681SAndroid Build Coastguard Worker else if (Tpi && StreamIdx == Tpi->getTypeHashStreamIndex())
163*9880d681SAndroid Build Coastguard Worker Value = "TPI Hash";
164*9880d681SAndroid Build Coastguard Worker else if (Tpi && StreamIdx == Tpi->getTypeHashStreamAuxIndex())
165*9880d681SAndroid Build Coastguard Worker Value = "TPI Aux Hash";
166*9880d681SAndroid Build Coastguard Worker else if (Ipi && StreamIdx == Ipi->getTypeHashStreamIndex())
167*9880d681SAndroid Build Coastguard Worker Value = "IPI Hash";
168*9880d681SAndroid Build Coastguard Worker else if (Ipi && StreamIdx == Ipi->getTypeHashStreamAuxIndex())
169*9880d681SAndroid Build Coastguard Worker Value = "IPI Aux Hash";
170*9880d681SAndroid Build Coastguard Worker else if (Dbi &&
171*9880d681SAndroid Build Coastguard Worker StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::Exception))
172*9880d681SAndroid Build Coastguard Worker Value = "Exception Data";
173*9880d681SAndroid Build Coastguard Worker else if (Dbi && StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::Fixup))
174*9880d681SAndroid Build Coastguard Worker Value = "Fixup Data";
175*9880d681SAndroid Build Coastguard Worker else if (Dbi && StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::FPO))
176*9880d681SAndroid Build Coastguard Worker Value = "FPO Data";
177*9880d681SAndroid Build Coastguard Worker else if (Dbi &&
178*9880d681SAndroid Build Coastguard Worker StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::NewFPO))
179*9880d681SAndroid Build Coastguard Worker Value = "New FPO Data";
180*9880d681SAndroid Build Coastguard Worker else if (Dbi &&
181*9880d681SAndroid Build Coastguard Worker StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::OmapFromSrc))
182*9880d681SAndroid Build Coastguard Worker Value = "Omap From Source Data";
183*9880d681SAndroid Build Coastguard Worker else if (Dbi &&
184*9880d681SAndroid Build Coastguard Worker StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::OmapToSrc))
185*9880d681SAndroid Build Coastguard Worker Value = "Omap To Source Data";
186*9880d681SAndroid Build Coastguard Worker else if (Dbi && StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::Pdata))
187*9880d681SAndroid Build Coastguard Worker Value = "Pdata";
188*9880d681SAndroid Build Coastguard Worker else if (Dbi &&
189*9880d681SAndroid Build Coastguard Worker StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::SectionHdr))
190*9880d681SAndroid Build Coastguard Worker Value = "Section Header Data";
191*9880d681SAndroid Build Coastguard Worker else if (Dbi &&
192*9880d681SAndroid Build Coastguard Worker StreamIdx ==
193*9880d681SAndroid Build Coastguard Worker Dbi->getDebugStreamIndex(DbgHeaderType::SectionHdrOrig))
194*9880d681SAndroid Build Coastguard Worker Value = "Section Header Original Data";
195*9880d681SAndroid Build Coastguard Worker else if (Dbi &&
196*9880d681SAndroid Build Coastguard Worker StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::TokenRidMap))
197*9880d681SAndroid Build Coastguard Worker Value = "Token Rid Data";
198*9880d681SAndroid Build Coastguard Worker else if (Dbi && StreamIdx == Dbi->getDebugStreamIndex(DbgHeaderType::Xdata))
199*9880d681SAndroid Build Coastguard Worker Value = "Xdata";
200*9880d681SAndroid Build Coastguard Worker else {
201*9880d681SAndroid Build Coastguard Worker auto ModIter = ModStreams.find(StreamIdx);
202*9880d681SAndroid Build Coastguard Worker auto NSIter = NamedStreams.find(StreamIdx);
203*9880d681SAndroid Build Coastguard Worker if (ModIter != ModStreams.end()) {
204*9880d681SAndroid Build Coastguard Worker Value = "Module \"";
205*9880d681SAndroid Build Coastguard Worker Value += ModIter->second->Info.getModuleName().str();
206*9880d681SAndroid Build Coastguard Worker Value += "\"";
207*9880d681SAndroid Build Coastguard Worker } else if (NSIter != NamedStreams.end()) {
208*9880d681SAndroid Build Coastguard Worker Value = "Named Stream \"";
209*9880d681SAndroid Build Coastguard Worker Value += NSIter->second;
210*9880d681SAndroid Build Coastguard Worker Value += "\"";
211*9880d681SAndroid Build Coastguard Worker } else {
212*9880d681SAndroid Build Coastguard Worker Value = "???";
213*9880d681SAndroid Build Coastguard Worker }
214*9880d681SAndroid Build Coastguard Worker }
215*9880d681SAndroid Build Coastguard Worker Value = "[" + Value + "]";
216*9880d681SAndroid Build Coastguard Worker Value =
217*9880d681SAndroid Build Coastguard Worker Value + " (" + to_string(File.getStreamByteSize(StreamIdx)) + " bytes)";
218*9880d681SAndroid Build Coastguard Worker
219*9880d681SAndroid Build Coastguard Worker P.printString(Label, Value);
220*9880d681SAndroid Build Coastguard Worker }
221*9880d681SAndroid Build Coastguard Worker
222*9880d681SAndroid Build Coastguard Worker // Consume errors from missing streams.
223*9880d681SAndroid Build Coastguard Worker if (!Dbi)
224*9880d681SAndroid Build Coastguard Worker consumeError(Dbi.takeError());
225*9880d681SAndroid Build Coastguard Worker if (!Tpi)
226*9880d681SAndroid Build Coastguard Worker consumeError(Tpi.takeError());
227*9880d681SAndroid Build Coastguard Worker if (!Ipi)
228*9880d681SAndroid Build Coastguard Worker consumeError(Ipi.takeError());
229*9880d681SAndroid Build Coastguard Worker if (!Info)
230*9880d681SAndroid Build Coastguard Worker consumeError(Info.takeError());
231*9880d681SAndroid Build Coastguard Worker
232*9880d681SAndroid Build Coastguard Worker P.flush();
233*9880d681SAndroid Build Coastguard Worker return Error::success();
234*9880d681SAndroid Build Coastguard Worker }
235*9880d681SAndroid Build Coastguard Worker
dumpStreamBlocks()236*9880d681SAndroid Build Coastguard Worker Error LLVMOutputStyle::dumpStreamBlocks() {
237*9880d681SAndroid Build Coastguard Worker if (!opts::raw::DumpStreamBlocks)
238*9880d681SAndroid Build Coastguard Worker return Error::success();
239*9880d681SAndroid Build Coastguard Worker
240*9880d681SAndroid Build Coastguard Worker ListScope L(P, "StreamBlocks");
241*9880d681SAndroid Build Coastguard Worker uint32_t StreamCount = File.getNumStreams();
242*9880d681SAndroid Build Coastguard Worker for (uint32_t StreamIdx = 0; StreamIdx < StreamCount; ++StreamIdx) {
243*9880d681SAndroid Build Coastguard Worker std::string Name("Stream ");
244*9880d681SAndroid Build Coastguard Worker Name += to_string(StreamIdx);
245*9880d681SAndroid Build Coastguard Worker auto StreamBlocks = File.getStreamBlockList(StreamIdx);
246*9880d681SAndroid Build Coastguard Worker P.printList(Name, StreamBlocks);
247*9880d681SAndroid Build Coastguard Worker }
248*9880d681SAndroid Build Coastguard Worker return Error::success();
249*9880d681SAndroid Build Coastguard Worker }
250*9880d681SAndroid Build Coastguard Worker
dumpStreamData()251*9880d681SAndroid Build Coastguard Worker Error LLVMOutputStyle::dumpStreamData() {
252*9880d681SAndroid Build Coastguard Worker uint32_t StreamCount = File.getNumStreams();
253*9880d681SAndroid Build Coastguard Worker StringRef DumpStreamStr = opts::raw::DumpStreamDataIdx;
254*9880d681SAndroid Build Coastguard Worker uint32_t DumpStreamNum;
255*9880d681SAndroid Build Coastguard Worker if (DumpStreamStr.getAsInteger(/*Radix=*/0U, DumpStreamNum))
256*9880d681SAndroid Build Coastguard Worker return Error::success();
257*9880d681SAndroid Build Coastguard Worker
258*9880d681SAndroid Build Coastguard Worker if (DumpStreamNum >= StreamCount)
259*9880d681SAndroid Build Coastguard Worker return make_error<RawError>(raw_error_code::no_stream);
260*9880d681SAndroid Build Coastguard Worker
261*9880d681SAndroid Build Coastguard Worker auto S = MappedBlockStream::createIndexedStream(DumpStreamNum, File);
262*9880d681SAndroid Build Coastguard Worker if (!S)
263*9880d681SAndroid Build Coastguard Worker return S.takeError();
264*9880d681SAndroid Build Coastguard Worker codeview::StreamReader R(**S);
265*9880d681SAndroid Build Coastguard Worker while (R.bytesRemaining() > 0) {
266*9880d681SAndroid Build Coastguard Worker ArrayRef<uint8_t> Data;
267*9880d681SAndroid Build Coastguard Worker uint32_t BytesToReadInBlock = std::min(
268*9880d681SAndroid Build Coastguard Worker R.bytesRemaining(), static_cast<uint32_t>(File.getBlockSize()));
269*9880d681SAndroid Build Coastguard Worker if (auto EC = R.readBytes(Data, BytesToReadInBlock))
270*9880d681SAndroid Build Coastguard Worker return EC;
271*9880d681SAndroid Build Coastguard Worker P.printBinaryBlock(
272*9880d681SAndroid Build Coastguard Worker "Data",
273*9880d681SAndroid Build Coastguard Worker StringRef(reinterpret_cast<const char *>(Data.begin()), Data.size()));
274*9880d681SAndroid Build Coastguard Worker }
275*9880d681SAndroid Build Coastguard Worker return Error::success();
276*9880d681SAndroid Build Coastguard Worker }
277*9880d681SAndroid Build Coastguard Worker
dumpInfoStream()278*9880d681SAndroid Build Coastguard Worker Error LLVMOutputStyle::dumpInfoStream() {
279*9880d681SAndroid Build Coastguard Worker if (!opts::raw::DumpHeaders)
280*9880d681SAndroid Build Coastguard Worker return Error::success();
281*9880d681SAndroid Build Coastguard Worker auto IS = File.getPDBInfoStream();
282*9880d681SAndroid Build Coastguard Worker if (!IS)
283*9880d681SAndroid Build Coastguard Worker return IS.takeError();
284*9880d681SAndroid Build Coastguard Worker
285*9880d681SAndroid Build Coastguard Worker DictScope D(P, "PDB Stream");
286*9880d681SAndroid Build Coastguard Worker P.printNumber("Version", IS->getVersion());
287*9880d681SAndroid Build Coastguard Worker P.printHex("Signature", IS->getSignature());
288*9880d681SAndroid Build Coastguard Worker P.printNumber("Age", IS->getAge());
289*9880d681SAndroid Build Coastguard Worker P.printObject("Guid", IS->getGuid());
290*9880d681SAndroid Build Coastguard Worker return Error::success();
291*9880d681SAndroid Build Coastguard Worker }
292*9880d681SAndroid Build Coastguard Worker
dumpNamedStream()293*9880d681SAndroid Build Coastguard Worker Error LLVMOutputStyle::dumpNamedStream() {
294*9880d681SAndroid Build Coastguard Worker if (opts::raw::DumpStreamDataName.empty())
295*9880d681SAndroid Build Coastguard Worker return Error::success();
296*9880d681SAndroid Build Coastguard Worker
297*9880d681SAndroid Build Coastguard Worker auto IS = File.getPDBInfoStream();
298*9880d681SAndroid Build Coastguard Worker if (!IS)
299*9880d681SAndroid Build Coastguard Worker return IS.takeError();
300*9880d681SAndroid Build Coastguard Worker
301*9880d681SAndroid Build Coastguard Worker uint32_t NameStreamIndex =
302*9880d681SAndroid Build Coastguard Worker IS->getNamedStreamIndex(opts::raw::DumpStreamDataName);
303*9880d681SAndroid Build Coastguard Worker if (NameStreamIndex == 0 || NameStreamIndex >= File.getNumStreams())
304*9880d681SAndroid Build Coastguard Worker return make_error<RawError>(raw_error_code::no_stream);
305*9880d681SAndroid Build Coastguard Worker
306*9880d681SAndroid Build Coastguard Worker if (NameStreamIndex != 0) {
307*9880d681SAndroid Build Coastguard Worker std::string Name("Stream '");
308*9880d681SAndroid Build Coastguard Worker Name += opts::raw::DumpStreamDataName;
309*9880d681SAndroid Build Coastguard Worker Name += "'";
310*9880d681SAndroid Build Coastguard Worker DictScope D(P, Name);
311*9880d681SAndroid Build Coastguard Worker P.printNumber("Index", NameStreamIndex);
312*9880d681SAndroid Build Coastguard Worker
313*9880d681SAndroid Build Coastguard Worker auto NameStream =
314*9880d681SAndroid Build Coastguard Worker MappedBlockStream::createIndexedStream(NameStreamIndex, File);
315*9880d681SAndroid Build Coastguard Worker if (!NameStream)
316*9880d681SAndroid Build Coastguard Worker return NameStream.takeError();
317*9880d681SAndroid Build Coastguard Worker codeview::StreamReader Reader(**NameStream);
318*9880d681SAndroid Build Coastguard Worker
319*9880d681SAndroid Build Coastguard Worker NameHashTable NameTable;
320*9880d681SAndroid Build Coastguard Worker if (auto EC = NameTable.load(Reader))
321*9880d681SAndroid Build Coastguard Worker return EC;
322*9880d681SAndroid Build Coastguard Worker
323*9880d681SAndroid Build Coastguard Worker P.printHex("Signature", NameTable.getSignature());
324*9880d681SAndroid Build Coastguard Worker P.printNumber("Version", NameTable.getHashVersion());
325*9880d681SAndroid Build Coastguard Worker P.printNumber("Name Count", NameTable.getNameCount());
326*9880d681SAndroid Build Coastguard Worker ListScope L(P, "Names");
327*9880d681SAndroid Build Coastguard Worker for (uint32_t ID : NameTable.name_ids()) {
328*9880d681SAndroid Build Coastguard Worker StringRef Str = NameTable.getStringForID(ID);
329*9880d681SAndroid Build Coastguard Worker if (!Str.empty())
330*9880d681SAndroid Build Coastguard Worker P.printString(to_string(ID), Str);
331*9880d681SAndroid Build Coastguard Worker }
332*9880d681SAndroid Build Coastguard Worker }
333*9880d681SAndroid Build Coastguard Worker return Error::success();
334*9880d681SAndroid Build Coastguard Worker }
335*9880d681SAndroid Build Coastguard Worker
printTypeIndexOffset(raw_ostream & OS,const TypeIndexOffset & TIOff)336*9880d681SAndroid Build Coastguard Worker static void printTypeIndexOffset(raw_ostream &OS,
337*9880d681SAndroid Build Coastguard Worker const TypeIndexOffset &TIOff) {
338*9880d681SAndroid Build Coastguard Worker OS << "{" << TIOff.Type.getIndex() << ", " << TIOff.Offset << "}";
339*9880d681SAndroid Build Coastguard Worker }
340*9880d681SAndroid Build Coastguard Worker
dumpTpiHash(ScopedPrinter & P,TpiStream & Tpi)341*9880d681SAndroid Build Coastguard Worker static void dumpTpiHash(ScopedPrinter &P, TpiStream &Tpi) {
342*9880d681SAndroid Build Coastguard Worker if (!opts::raw::DumpTpiHash)
343*9880d681SAndroid Build Coastguard Worker return;
344*9880d681SAndroid Build Coastguard Worker DictScope DD(P, "Hash");
345*9880d681SAndroid Build Coastguard Worker P.printNumber("Number of Hash Buckets", Tpi.NumHashBuckets());
346*9880d681SAndroid Build Coastguard Worker P.printNumber("Hash Key Size", Tpi.getHashKeySize());
347*9880d681SAndroid Build Coastguard Worker P.printList("Values", Tpi.getHashValues());
348*9880d681SAndroid Build Coastguard Worker P.printList("Type Index Offsets", Tpi.getTypeIndexOffsets(),
349*9880d681SAndroid Build Coastguard Worker printTypeIndexOffset);
350*9880d681SAndroid Build Coastguard Worker P.printList("Hash Adjustments", Tpi.getHashAdjustments(),
351*9880d681SAndroid Build Coastguard Worker printTypeIndexOffset);
352*9880d681SAndroid Build Coastguard Worker }
353*9880d681SAndroid Build Coastguard Worker
dumpTpiStream(uint32_t StreamIdx)354*9880d681SAndroid Build Coastguard Worker Error LLVMOutputStyle::dumpTpiStream(uint32_t StreamIdx) {
355*9880d681SAndroid Build Coastguard Worker assert(StreamIdx == StreamTPI || StreamIdx == StreamIPI);
356*9880d681SAndroid Build Coastguard Worker
357*9880d681SAndroid Build Coastguard Worker bool DumpRecordBytes = false;
358*9880d681SAndroid Build Coastguard Worker bool DumpRecords = false;
359*9880d681SAndroid Build Coastguard Worker StringRef Label;
360*9880d681SAndroid Build Coastguard Worker StringRef VerLabel;
361*9880d681SAndroid Build Coastguard Worker if (StreamIdx == StreamTPI) {
362*9880d681SAndroid Build Coastguard Worker DumpRecordBytes = opts::raw::DumpTpiRecordBytes;
363*9880d681SAndroid Build Coastguard Worker DumpRecords = opts::raw::DumpTpiRecords;
364*9880d681SAndroid Build Coastguard Worker Label = "Type Info Stream (TPI)";
365*9880d681SAndroid Build Coastguard Worker VerLabel = "TPI Version";
366*9880d681SAndroid Build Coastguard Worker } else if (StreamIdx == StreamIPI) {
367*9880d681SAndroid Build Coastguard Worker DumpRecordBytes = opts::raw::DumpIpiRecordBytes;
368*9880d681SAndroid Build Coastguard Worker DumpRecords = opts::raw::DumpIpiRecords;
369*9880d681SAndroid Build Coastguard Worker Label = "Type Info Stream (IPI)";
370*9880d681SAndroid Build Coastguard Worker VerLabel = "IPI Version";
371*9880d681SAndroid Build Coastguard Worker }
372*9880d681SAndroid Build Coastguard Worker if (!DumpRecordBytes && !DumpRecords && !opts::raw::DumpModuleSyms)
373*9880d681SAndroid Build Coastguard Worker return Error::success();
374*9880d681SAndroid Build Coastguard Worker
375*9880d681SAndroid Build Coastguard Worker auto Tpi = (StreamIdx == StreamTPI) ? File.getPDBTpiStream()
376*9880d681SAndroid Build Coastguard Worker : File.getPDBIpiStream();
377*9880d681SAndroid Build Coastguard Worker if (!Tpi)
378*9880d681SAndroid Build Coastguard Worker return Tpi.takeError();
379*9880d681SAndroid Build Coastguard Worker
380*9880d681SAndroid Build Coastguard Worker if (DumpRecords || DumpRecordBytes) {
381*9880d681SAndroid Build Coastguard Worker DictScope D(P, Label);
382*9880d681SAndroid Build Coastguard Worker
383*9880d681SAndroid Build Coastguard Worker P.printNumber(VerLabel, Tpi->getTpiVersion());
384*9880d681SAndroid Build Coastguard Worker P.printNumber("Record count", Tpi->NumTypeRecords());
385*9880d681SAndroid Build Coastguard Worker
386*9880d681SAndroid Build Coastguard Worker ListScope L(P, "Records");
387*9880d681SAndroid Build Coastguard Worker
388*9880d681SAndroid Build Coastguard Worker bool HadError = false;
389*9880d681SAndroid Build Coastguard Worker for (auto &Type : Tpi->types(&HadError)) {
390*9880d681SAndroid Build Coastguard Worker DictScope DD(P, "");
391*9880d681SAndroid Build Coastguard Worker
392*9880d681SAndroid Build Coastguard Worker if (DumpRecords) {
393*9880d681SAndroid Build Coastguard Worker if (auto EC = TD.dump(Type))
394*9880d681SAndroid Build Coastguard Worker return EC;
395*9880d681SAndroid Build Coastguard Worker }
396*9880d681SAndroid Build Coastguard Worker
397*9880d681SAndroid Build Coastguard Worker if (DumpRecordBytes)
398*9880d681SAndroid Build Coastguard Worker P.printBinaryBlock("Bytes", Type.Data);
399*9880d681SAndroid Build Coastguard Worker }
400*9880d681SAndroid Build Coastguard Worker dumpTpiHash(P, *Tpi);
401*9880d681SAndroid Build Coastguard Worker if (HadError)
402*9880d681SAndroid Build Coastguard Worker return make_error<RawError>(raw_error_code::corrupt_file,
403*9880d681SAndroid Build Coastguard Worker "TPI stream contained corrupt record");
404*9880d681SAndroid Build Coastguard Worker } else if (opts::raw::DumpModuleSyms) {
405*9880d681SAndroid Build Coastguard Worker // Even if the user doesn't want to dump type records, we still need to
406*9880d681SAndroid Build Coastguard Worker // iterate them in order to build the list of types so that we can print
407*9880d681SAndroid Build Coastguard Worker // them when dumping module symbols. So when they want to dump symbols
408*9880d681SAndroid Build Coastguard Worker // but not types, use a null output stream.
409*9880d681SAndroid Build Coastguard Worker ScopedPrinter *OldP = TD.getPrinter();
410*9880d681SAndroid Build Coastguard Worker TD.setPrinter(nullptr);
411*9880d681SAndroid Build Coastguard Worker
412*9880d681SAndroid Build Coastguard Worker bool HadError = false;
413*9880d681SAndroid Build Coastguard Worker for (auto &Type : Tpi->types(&HadError)) {
414*9880d681SAndroid Build Coastguard Worker if (auto EC = TD.dump(Type))
415*9880d681SAndroid Build Coastguard Worker return EC;
416*9880d681SAndroid Build Coastguard Worker }
417*9880d681SAndroid Build Coastguard Worker
418*9880d681SAndroid Build Coastguard Worker TD.setPrinter(OldP);
419*9880d681SAndroid Build Coastguard Worker dumpTpiHash(P, *Tpi);
420*9880d681SAndroid Build Coastguard Worker if (HadError)
421*9880d681SAndroid Build Coastguard Worker return make_error<RawError>(raw_error_code::corrupt_file,
422*9880d681SAndroid Build Coastguard Worker "TPI stream contained corrupt record");
423*9880d681SAndroid Build Coastguard Worker }
424*9880d681SAndroid Build Coastguard Worker P.flush();
425*9880d681SAndroid Build Coastguard Worker return Error::success();
426*9880d681SAndroid Build Coastguard Worker }
427*9880d681SAndroid Build Coastguard Worker
dumpDbiStream()428*9880d681SAndroid Build Coastguard Worker Error LLVMOutputStyle::dumpDbiStream() {
429*9880d681SAndroid Build Coastguard Worker bool DumpModules = opts::raw::DumpModules || opts::raw::DumpModuleSyms ||
430*9880d681SAndroid Build Coastguard Worker opts::raw::DumpModuleFiles || opts::raw::DumpLineInfo;
431*9880d681SAndroid Build Coastguard Worker if (!opts::raw::DumpHeaders && !DumpModules)
432*9880d681SAndroid Build Coastguard Worker return Error::success();
433*9880d681SAndroid Build Coastguard Worker
434*9880d681SAndroid Build Coastguard Worker auto DS = File.getPDBDbiStream();
435*9880d681SAndroid Build Coastguard Worker if (!DS)
436*9880d681SAndroid Build Coastguard Worker return DS.takeError();
437*9880d681SAndroid Build Coastguard Worker
438*9880d681SAndroid Build Coastguard Worker DictScope D(P, "DBI Stream");
439*9880d681SAndroid Build Coastguard Worker P.printNumber("Dbi Version", DS->getDbiVersion());
440*9880d681SAndroid Build Coastguard Worker P.printNumber("Age", DS->getAge());
441*9880d681SAndroid Build Coastguard Worker P.printBoolean("Incremental Linking", DS->isIncrementallyLinked());
442*9880d681SAndroid Build Coastguard Worker P.printBoolean("Has CTypes", DS->hasCTypes());
443*9880d681SAndroid Build Coastguard Worker P.printBoolean("Is Stripped", DS->isStripped());
444*9880d681SAndroid Build Coastguard Worker P.printObject("Machine Type", DS->getMachineType());
445*9880d681SAndroid Build Coastguard Worker P.printNumber("Symbol Record Stream Index", DS->getSymRecordStreamIndex());
446*9880d681SAndroid Build Coastguard Worker P.printNumber("Public Symbol Stream Index", DS->getPublicSymbolStreamIndex());
447*9880d681SAndroid Build Coastguard Worker P.printNumber("Global Symbol Stream Index", DS->getGlobalSymbolStreamIndex());
448*9880d681SAndroid Build Coastguard Worker
449*9880d681SAndroid Build Coastguard Worker uint16_t Major = DS->getBuildMajorVersion();
450*9880d681SAndroid Build Coastguard Worker uint16_t Minor = DS->getBuildMinorVersion();
451*9880d681SAndroid Build Coastguard Worker P.printVersion("Toolchain Version", Major, Minor);
452*9880d681SAndroid Build Coastguard Worker
453*9880d681SAndroid Build Coastguard Worker std::string DllName;
454*9880d681SAndroid Build Coastguard Worker raw_string_ostream DllStream(DllName);
455*9880d681SAndroid Build Coastguard Worker DllStream << "mspdb" << Major << Minor << ".dll version";
456*9880d681SAndroid Build Coastguard Worker DllStream.flush();
457*9880d681SAndroid Build Coastguard Worker P.printVersion(DllName, Major, Minor, DS->getPdbDllVersion());
458*9880d681SAndroid Build Coastguard Worker
459*9880d681SAndroid Build Coastguard Worker if (DumpModules) {
460*9880d681SAndroid Build Coastguard Worker ListScope L(P, "Modules");
461*9880d681SAndroid Build Coastguard Worker for (auto &Modi : DS->modules()) {
462*9880d681SAndroid Build Coastguard Worker DictScope DD(P);
463*9880d681SAndroid Build Coastguard Worker P.printString("Name", Modi.Info.getModuleName().str());
464*9880d681SAndroid Build Coastguard Worker P.printNumber("Debug Stream Index", Modi.Info.getModuleStreamIndex());
465*9880d681SAndroid Build Coastguard Worker P.printString("Object File Name", Modi.Info.getObjFileName().str());
466*9880d681SAndroid Build Coastguard Worker P.printNumber("Num Files", Modi.Info.getNumberOfFiles());
467*9880d681SAndroid Build Coastguard Worker P.printNumber("Source File Name Idx", Modi.Info.getSourceFileNameIndex());
468*9880d681SAndroid Build Coastguard Worker P.printNumber("Pdb File Name Idx", Modi.Info.getPdbFilePathNameIndex());
469*9880d681SAndroid Build Coastguard Worker P.printNumber("Line Info Byte Size", Modi.Info.getLineInfoByteSize());
470*9880d681SAndroid Build Coastguard Worker P.printNumber("C13 Line Info Byte Size",
471*9880d681SAndroid Build Coastguard Worker Modi.Info.getC13LineInfoByteSize());
472*9880d681SAndroid Build Coastguard Worker P.printNumber("Symbol Byte Size", Modi.Info.getSymbolDebugInfoByteSize());
473*9880d681SAndroid Build Coastguard Worker P.printNumber("Type Server Index", Modi.Info.getTypeServerIndex());
474*9880d681SAndroid Build Coastguard Worker P.printBoolean("Has EC Info", Modi.Info.hasECInfo());
475*9880d681SAndroid Build Coastguard Worker if (opts::raw::DumpModuleFiles) {
476*9880d681SAndroid Build Coastguard Worker std::string FileListName =
477*9880d681SAndroid Build Coastguard Worker to_string(Modi.SourceFiles.size()) + " Contributing Source Files";
478*9880d681SAndroid Build Coastguard Worker ListScope LL(P, FileListName);
479*9880d681SAndroid Build Coastguard Worker for (auto File : Modi.SourceFiles)
480*9880d681SAndroid Build Coastguard Worker P.printString(File.str());
481*9880d681SAndroid Build Coastguard Worker }
482*9880d681SAndroid Build Coastguard Worker bool HasModuleDI =
483*9880d681SAndroid Build Coastguard Worker (Modi.Info.getModuleStreamIndex() < File.getNumStreams());
484*9880d681SAndroid Build Coastguard Worker bool ShouldDumpSymbols =
485*9880d681SAndroid Build Coastguard Worker (opts::raw::DumpModuleSyms || opts::raw::DumpSymRecordBytes);
486*9880d681SAndroid Build Coastguard Worker if (HasModuleDI && (ShouldDumpSymbols || opts::raw::DumpLineInfo)) {
487*9880d681SAndroid Build Coastguard Worker auto ModStreamData = MappedBlockStream::createIndexedStream(
488*9880d681SAndroid Build Coastguard Worker Modi.Info.getModuleStreamIndex(), File);
489*9880d681SAndroid Build Coastguard Worker if (!ModStreamData)
490*9880d681SAndroid Build Coastguard Worker return ModStreamData.takeError();
491*9880d681SAndroid Build Coastguard Worker ModStream ModS(Modi.Info, std::move(*ModStreamData));
492*9880d681SAndroid Build Coastguard Worker if (auto EC = ModS.reload())
493*9880d681SAndroid Build Coastguard Worker return EC;
494*9880d681SAndroid Build Coastguard Worker
495*9880d681SAndroid Build Coastguard Worker if (ShouldDumpSymbols) {
496*9880d681SAndroid Build Coastguard Worker ListScope SS(P, "Symbols");
497*9880d681SAndroid Build Coastguard Worker codeview::CVSymbolDumper SD(P, TD, nullptr, false);
498*9880d681SAndroid Build Coastguard Worker bool HadError = false;
499*9880d681SAndroid Build Coastguard Worker for (const auto &S : ModS.symbols(&HadError)) {
500*9880d681SAndroid Build Coastguard Worker DictScope DD(P, "");
501*9880d681SAndroid Build Coastguard Worker
502*9880d681SAndroid Build Coastguard Worker if (opts::raw::DumpModuleSyms)
503*9880d681SAndroid Build Coastguard Worker SD.dump(S);
504*9880d681SAndroid Build Coastguard Worker if (opts::raw::DumpSymRecordBytes)
505*9880d681SAndroid Build Coastguard Worker P.printBinaryBlock("Bytes", S.Data);
506*9880d681SAndroid Build Coastguard Worker }
507*9880d681SAndroid Build Coastguard Worker if (HadError)
508*9880d681SAndroid Build Coastguard Worker return make_error<RawError>(
509*9880d681SAndroid Build Coastguard Worker raw_error_code::corrupt_file,
510*9880d681SAndroid Build Coastguard Worker "DBI stream contained corrupt symbol record");
511*9880d681SAndroid Build Coastguard Worker }
512*9880d681SAndroid Build Coastguard Worker if (opts::raw::DumpLineInfo) {
513*9880d681SAndroid Build Coastguard Worker ListScope SS(P, "LineInfo");
514*9880d681SAndroid Build Coastguard Worker bool HadError = false;
515*9880d681SAndroid Build Coastguard Worker // Define a locally scoped visitor to print the different
516*9880d681SAndroid Build Coastguard Worker // substream types types.
517*9880d681SAndroid Build Coastguard Worker class RecordVisitor : public codeview::IModuleSubstreamVisitor {
518*9880d681SAndroid Build Coastguard Worker public:
519*9880d681SAndroid Build Coastguard Worker RecordVisitor(ScopedPrinter &P, PDBFile &F) : P(P), F(F) {}
520*9880d681SAndroid Build Coastguard Worker Error visitUnknown(ModuleSubstreamKind Kind,
521*9880d681SAndroid Build Coastguard Worker StreamRef Stream) override {
522*9880d681SAndroid Build Coastguard Worker DictScope DD(P, "Unknown");
523*9880d681SAndroid Build Coastguard Worker ArrayRef<uint8_t> Data;
524*9880d681SAndroid Build Coastguard Worker StreamReader R(Stream);
525*9880d681SAndroid Build Coastguard Worker if (auto EC = R.readBytes(Data, R.bytesRemaining())) {
526*9880d681SAndroid Build Coastguard Worker return make_error<RawError>(
527*9880d681SAndroid Build Coastguard Worker raw_error_code::corrupt_file,
528*9880d681SAndroid Build Coastguard Worker "DBI stream contained corrupt line info record");
529*9880d681SAndroid Build Coastguard Worker }
530*9880d681SAndroid Build Coastguard Worker P.printBinaryBlock("Data", Data);
531*9880d681SAndroid Build Coastguard Worker return Error::success();
532*9880d681SAndroid Build Coastguard Worker }
533*9880d681SAndroid Build Coastguard Worker Error
534*9880d681SAndroid Build Coastguard Worker visitFileChecksums(StreamRef Data,
535*9880d681SAndroid Build Coastguard Worker const FileChecksumArray &Checksums) override {
536*9880d681SAndroid Build Coastguard Worker DictScope DD(P, "FileChecksums");
537*9880d681SAndroid Build Coastguard Worker for (const auto &C : Checksums) {
538*9880d681SAndroid Build Coastguard Worker DictScope DDD(P, "Checksum");
539*9880d681SAndroid Build Coastguard Worker if (auto Result = getFileNameForOffset(C.FileNameOffset))
540*9880d681SAndroid Build Coastguard Worker P.printString("FileName", Result.get());
541*9880d681SAndroid Build Coastguard Worker else
542*9880d681SAndroid Build Coastguard Worker return Result.takeError();
543*9880d681SAndroid Build Coastguard Worker P.flush();
544*9880d681SAndroid Build Coastguard Worker P.printEnum("Kind", uint8_t(C.Kind), getFileChecksumNames());
545*9880d681SAndroid Build Coastguard Worker P.printBinaryBlock("Checksum", C.Checksum);
546*9880d681SAndroid Build Coastguard Worker }
547*9880d681SAndroid Build Coastguard Worker return Error::success();
548*9880d681SAndroid Build Coastguard Worker }
549*9880d681SAndroid Build Coastguard Worker
550*9880d681SAndroid Build Coastguard Worker Error visitLines(StreamRef Data, const LineSubstreamHeader *Header,
551*9880d681SAndroid Build Coastguard Worker const LineInfoArray &Lines) override {
552*9880d681SAndroid Build Coastguard Worker DictScope DD(P, "Lines");
553*9880d681SAndroid Build Coastguard Worker for (const auto &L : Lines) {
554*9880d681SAndroid Build Coastguard Worker if (auto Result = getFileNameForOffset2(L.NameIndex))
555*9880d681SAndroid Build Coastguard Worker P.printString("FileName", Result.get());
556*9880d681SAndroid Build Coastguard Worker else
557*9880d681SAndroid Build Coastguard Worker return Result.takeError();
558*9880d681SAndroid Build Coastguard Worker P.flush();
559*9880d681SAndroid Build Coastguard Worker for (const auto &N : L.LineNumbers) {
560*9880d681SAndroid Build Coastguard Worker DictScope DDD(P, "Line");
561*9880d681SAndroid Build Coastguard Worker LineInfo LI(N.Flags);
562*9880d681SAndroid Build Coastguard Worker P.printNumber("Offset", N.Offset);
563*9880d681SAndroid Build Coastguard Worker if (LI.isAlwaysStepInto())
564*9880d681SAndroid Build Coastguard Worker P.printString("StepInto", StringRef("Always"));
565*9880d681SAndroid Build Coastguard Worker else if (LI.isNeverStepInto())
566*9880d681SAndroid Build Coastguard Worker P.printString("StepInto", StringRef("Never"));
567*9880d681SAndroid Build Coastguard Worker else
568*9880d681SAndroid Build Coastguard Worker P.printNumber("LineNumberStart", LI.getStartLine());
569*9880d681SAndroid Build Coastguard Worker P.printNumber("EndDelta", LI.getLineDelta());
570*9880d681SAndroid Build Coastguard Worker P.printBoolean("IsStatement", LI.isStatement());
571*9880d681SAndroid Build Coastguard Worker }
572*9880d681SAndroid Build Coastguard Worker for (const auto &C : L.Columns) {
573*9880d681SAndroid Build Coastguard Worker DictScope DDD(P, "Column");
574*9880d681SAndroid Build Coastguard Worker P.printNumber("Start", C.StartColumn);
575*9880d681SAndroid Build Coastguard Worker P.printNumber("End", C.EndColumn);
576*9880d681SAndroid Build Coastguard Worker }
577*9880d681SAndroid Build Coastguard Worker }
578*9880d681SAndroid Build Coastguard Worker return Error::success();
579*9880d681SAndroid Build Coastguard Worker }
580*9880d681SAndroid Build Coastguard Worker
581*9880d681SAndroid Build Coastguard Worker private:
582*9880d681SAndroid Build Coastguard Worker Expected<StringRef> getFileNameForOffset(uint32_t Offset) {
583*9880d681SAndroid Build Coastguard Worker auto ST = F.getStringTable();
584*9880d681SAndroid Build Coastguard Worker if (!ST)
585*9880d681SAndroid Build Coastguard Worker return ST.takeError();
586*9880d681SAndroid Build Coastguard Worker
587*9880d681SAndroid Build Coastguard Worker return ST->getStringForID(Offset);
588*9880d681SAndroid Build Coastguard Worker }
589*9880d681SAndroid Build Coastguard Worker Expected<StringRef> getFileNameForOffset2(uint32_t Offset) {
590*9880d681SAndroid Build Coastguard Worker auto DS = F.getPDBDbiStream();
591*9880d681SAndroid Build Coastguard Worker if (!DS)
592*9880d681SAndroid Build Coastguard Worker return DS.takeError();
593*9880d681SAndroid Build Coastguard Worker return DS->getFileNameForIndex(Offset);
594*9880d681SAndroid Build Coastguard Worker }
595*9880d681SAndroid Build Coastguard Worker ScopedPrinter &P;
596*9880d681SAndroid Build Coastguard Worker PDBFile &F;
597*9880d681SAndroid Build Coastguard Worker };
598*9880d681SAndroid Build Coastguard Worker
599*9880d681SAndroid Build Coastguard Worker RecordVisitor V(P, File);
600*9880d681SAndroid Build Coastguard Worker for (const auto &L : ModS.lines(&HadError)) {
601*9880d681SAndroid Build Coastguard Worker if (auto EC = codeview::visitModuleSubstream(L, V))
602*9880d681SAndroid Build Coastguard Worker return EC;
603*9880d681SAndroid Build Coastguard Worker }
604*9880d681SAndroid Build Coastguard Worker }
605*9880d681SAndroid Build Coastguard Worker }
606*9880d681SAndroid Build Coastguard Worker }
607*9880d681SAndroid Build Coastguard Worker }
608*9880d681SAndroid Build Coastguard Worker return Error::success();
609*9880d681SAndroid Build Coastguard Worker }
610*9880d681SAndroid Build Coastguard Worker
dumpSectionContribs()611*9880d681SAndroid Build Coastguard Worker Error LLVMOutputStyle::dumpSectionContribs() {
612*9880d681SAndroid Build Coastguard Worker if (!opts::raw::DumpSectionContribs)
613*9880d681SAndroid Build Coastguard Worker return Error::success();
614*9880d681SAndroid Build Coastguard Worker
615*9880d681SAndroid Build Coastguard Worker auto Dbi = File.getPDBDbiStream();
616*9880d681SAndroid Build Coastguard Worker if (!Dbi)
617*9880d681SAndroid Build Coastguard Worker return Dbi.takeError();
618*9880d681SAndroid Build Coastguard Worker
619*9880d681SAndroid Build Coastguard Worker ListScope L(P, "Section Contributions");
620*9880d681SAndroid Build Coastguard Worker class Visitor : public ISectionContribVisitor {
621*9880d681SAndroid Build Coastguard Worker public:
622*9880d681SAndroid Build Coastguard Worker Visitor(ScopedPrinter &P, DbiStream &DS) : P(P), DS(DS) {}
623*9880d681SAndroid Build Coastguard Worker void visit(const SectionContrib &SC) override {
624*9880d681SAndroid Build Coastguard Worker DictScope D(P, "Contribution");
625*9880d681SAndroid Build Coastguard Worker P.printNumber("ISect", SC.ISect);
626*9880d681SAndroid Build Coastguard Worker P.printNumber("Off", SC.Off);
627*9880d681SAndroid Build Coastguard Worker P.printNumber("Size", SC.Size);
628*9880d681SAndroid Build Coastguard Worker P.printFlags("Characteristics", SC.Characteristics,
629*9880d681SAndroid Build Coastguard Worker codeview::getImageSectionCharacteristicNames(),
630*9880d681SAndroid Build Coastguard Worker COFF::SectionCharacteristics(0x00F00000));
631*9880d681SAndroid Build Coastguard Worker {
632*9880d681SAndroid Build Coastguard Worker DictScope DD(P, "Module");
633*9880d681SAndroid Build Coastguard Worker P.printNumber("Index", SC.Imod);
634*9880d681SAndroid Build Coastguard Worker auto M = DS.modules();
635*9880d681SAndroid Build Coastguard Worker if (M.size() > SC.Imod) {
636*9880d681SAndroid Build Coastguard Worker P.printString("Name", M[SC.Imod].Info.getModuleName());
637*9880d681SAndroid Build Coastguard Worker }
638*9880d681SAndroid Build Coastguard Worker }
639*9880d681SAndroid Build Coastguard Worker P.printNumber("Data CRC", SC.DataCrc);
640*9880d681SAndroid Build Coastguard Worker P.printNumber("Reloc CRC", SC.RelocCrc);
641*9880d681SAndroid Build Coastguard Worker P.flush();
642*9880d681SAndroid Build Coastguard Worker }
643*9880d681SAndroid Build Coastguard Worker void visit(const SectionContrib2 &SC) override {
644*9880d681SAndroid Build Coastguard Worker visit(SC.Base);
645*9880d681SAndroid Build Coastguard Worker P.printNumber("ISect Coff", SC.ISectCoff);
646*9880d681SAndroid Build Coastguard Worker P.flush();
647*9880d681SAndroid Build Coastguard Worker }
648*9880d681SAndroid Build Coastguard Worker
649*9880d681SAndroid Build Coastguard Worker private:
650*9880d681SAndroid Build Coastguard Worker ScopedPrinter &P;
651*9880d681SAndroid Build Coastguard Worker DbiStream &DS;
652*9880d681SAndroid Build Coastguard Worker };
653*9880d681SAndroid Build Coastguard Worker Visitor V(P, *Dbi);
654*9880d681SAndroid Build Coastguard Worker Dbi->visitSectionContributions(V);
655*9880d681SAndroid Build Coastguard Worker return Error::success();
656*9880d681SAndroid Build Coastguard Worker }
657*9880d681SAndroid Build Coastguard Worker
dumpSectionMap()658*9880d681SAndroid Build Coastguard Worker Error LLVMOutputStyle::dumpSectionMap() {
659*9880d681SAndroid Build Coastguard Worker if (!opts::raw::DumpSectionMap)
660*9880d681SAndroid Build Coastguard Worker return Error::success();
661*9880d681SAndroid Build Coastguard Worker
662*9880d681SAndroid Build Coastguard Worker auto Dbi = File.getPDBDbiStream();
663*9880d681SAndroid Build Coastguard Worker if (!Dbi)
664*9880d681SAndroid Build Coastguard Worker return Dbi.takeError();
665*9880d681SAndroid Build Coastguard Worker
666*9880d681SAndroid Build Coastguard Worker ListScope L(P, "Section Map");
667*9880d681SAndroid Build Coastguard Worker for (auto &M : Dbi->getSectionMap()) {
668*9880d681SAndroid Build Coastguard Worker DictScope D(P, "Entry");
669*9880d681SAndroid Build Coastguard Worker P.printFlags("Flags", M.Flags, getOMFSegMapDescFlagNames());
670*9880d681SAndroid Build Coastguard Worker P.printNumber("Flags", M.Flags);
671*9880d681SAndroid Build Coastguard Worker P.printNumber("Ovl", M.Ovl);
672*9880d681SAndroid Build Coastguard Worker P.printNumber("Group", M.Group);
673*9880d681SAndroid Build Coastguard Worker P.printNumber("Frame", M.Frame);
674*9880d681SAndroid Build Coastguard Worker P.printNumber("SecName", M.SecName);
675*9880d681SAndroid Build Coastguard Worker P.printNumber("ClassName", M.ClassName);
676*9880d681SAndroid Build Coastguard Worker P.printNumber("Offset", M.Offset);
677*9880d681SAndroid Build Coastguard Worker P.printNumber("SecByteLength", M.SecByteLength);
678*9880d681SAndroid Build Coastguard Worker P.flush();
679*9880d681SAndroid Build Coastguard Worker }
680*9880d681SAndroid Build Coastguard Worker return Error::success();
681*9880d681SAndroid Build Coastguard Worker }
682*9880d681SAndroid Build Coastguard Worker
dumpPublicsStream()683*9880d681SAndroid Build Coastguard Worker Error LLVMOutputStyle::dumpPublicsStream() {
684*9880d681SAndroid Build Coastguard Worker if (!opts::raw::DumpPublics)
685*9880d681SAndroid Build Coastguard Worker return Error::success();
686*9880d681SAndroid Build Coastguard Worker
687*9880d681SAndroid Build Coastguard Worker DictScope D(P, "Publics Stream");
688*9880d681SAndroid Build Coastguard Worker auto Publics = File.getPDBPublicsStream();
689*9880d681SAndroid Build Coastguard Worker if (!Publics)
690*9880d681SAndroid Build Coastguard Worker return Publics.takeError();
691*9880d681SAndroid Build Coastguard Worker
692*9880d681SAndroid Build Coastguard Worker auto Dbi = File.getPDBDbiStream();
693*9880d681SAndroid Build Coastguard Worker if (!Dbi)
694*9880d681SAndroid Build Coastguard Worker return Dbi.takeError();
695*9880d681SAndroid Build Coastguard Worker
696*9880d681SAndroid Build Coastguard Worker P.printNumber("Stream number", Dbi->getPublicSymbolStreamIndex());
697*9880d681SAndroid Build Coastguard Worker P.printNumber("SymHash", Publics->getSymHash());
698*9880d681SAndroid Build Coastguard Worker P.printNumber("AddrMap", Publics->getAddrMap());
699*9880d681SAndroid Build Coastguard Worker P.printNumber("Number of buckets", Publics->getNumBuckets());
700*9880d681SAndroid Build Coastguard Worker P.printList("Hash Buckets", Publics->getHashBuckets());
701*9880d681SAndroid Build Coastguard Worker P.printList("Address Map", Publics->getAddressMap());
702*9880d681SAndroid Build Coastguard Worker P.printList("Thunk Map", Publics->getThunkMap());
703*9880d681SAndroid Build Coastguard Worker P.printList("Section Offsets", Publics->getSectionOffsets(),
704*9880d681SAndroid Build Coastguard Worker printSectionOffset);
705*9880d681SAndroid Build Coastguard Worker ListScope L(P, "Symbols");
706*9880d681SAndroid Build Coastguard Worker codeview::CVSymbolDumper SD(P, TD, nullptr, false);
707*9880d681SAndroid Build Coastguard Worker bool HadError = false;
708*9880d681SAndroid Build Coastguard Worker for (auto S : Publics->getSymbols(&HadError)) {
709*9880d681SAndroid Build Coastguard Worker DictScope DD(P, "");
710*9880d681SAndroid Build Coastguard Worker
711*9880d681SAndroid Build Coastguard Worker SD.dump(S);
712*9880d681SAndroid Build Coastguard Worker if (opts::raw::DumpSymRecordBytes)
713*9880d681SAndroid Build Coastguard Worker P.printBinaryBlock("Bytes", S.Data);
714*9880d681SAndroid Build Coastguard Worker }
715*9880d681SAndroid Build Coastguard Worker if (HadError)
716*9880d681SAndroid Build Coastguard Worker return make_error<RawError>(
717*9880d681SAndroid Build Coastguard Worker raw_error_code::corrupt_file,
718*9880d681SAndroid Build Coastguard Worker "Public symbol stream contained corrupt record");
719*9880d681SAndroid Build Coastguard Worker
720*9880d681SAndroid Build Coastguard Worker return Error::success();
721*9880d681SAndroid Build Coastguard Worker }
722*9880d681SAndroid Build Coastguard Worker
dumpSectionHeaders()723*9880d681SAndroid Build Coastguard Worker Error LLVMOutputStyle::dumpSectionHeaders() {
724*9880d681SAndroid Build Coastguard Worker if (!opts::raw::DumpSectionHeaders)
725*9880d681SAndroid Build Coastguard Worker return Error::success();
726*9880d681SAndroid Build Coastguard Worker
727*9880d681SAndroid Build Coastguard Worker auto Dbi = File.getPDBDbiStream();
728*9880d681SAndroid Build Coastguard Worker if (!Dbi)
729*9880d681SAndroid Build Coastguard Worker return Dbi.takeError();
730*9880d681SAndroid Build Coastguard Worker
731*9880d681SAndroid Build Coastguard Worker ListScope D(P, "Section Headers");
732*9880d681SAndroid Build Coastguard Worker for (const object::coff_section &Section : Dbi->getSectionHeaders()) {
733*9880d681SAndroid Build Coastguard Worker DictScope DD(P, "");
734*9880d681SAndroid Build Coastguard Worker
735*9880d681SAndroid Build Coastguard Worker // If a name is 8 characters long, there is no NUL character at end.
736*9880d681SAndroid Build Coastguard Worker StringRef Name(Section.Name, strnlen(Section.Name, sizeof(Section.Name)));
737*9880d681SAndroid Build Coastguard Worker P.printString("Name", Name);
738*9880d681SAndroid Build Coastguard Worker P.printNumber("Virtual Size", Section.VirtualSize);
739*9880d681SAndroid Build Coastguard Worker P.printNumber("Virtual Address", Section.VirtualAddress);
740*9880d681SAndroid Build Coastguard Worker P.printNumber("Size of Raw Data", Section.SizeOfRawData);
741*9880d681SAndroid Build Coastguard Worker P.printNumber("File Pointer to Raw Data", Section.PointerToRawData);
742*9880d681SAndroid Build Coastguard Worker P.printNumber("File Pointer to Relocations", Section.PointerToRelocations);
743*9880d681SAndroid Build Coastguard Worker P.printNumber("File Pointer to Linenumbers", Section.PointerToLinenumbers);
744*9880d681SAndroid Build Coastguard Worker P.printNumber("Number of Relocations", Section.NumberOfRelocations);
745*9880d681SAndroid Build Coastguard Worker P.printNumber("Number of Linenumbers", Section.NumberOfLinenumbers);
746*9880d681SAndroid Build Coastguard Worker P.printFlags("Characteristics", Section.Characteristics,
747*9880d681SAndroid Build Coastguard Worker getImageSectionCharacteristicNames());
748*9880d681SAndroid Build Coastguard Worker }
749*9880d681SAndroid Build Coastguard Worker return Error::success();
750*9880d681SAndroid Build Coastguard Worker }
751*9880d681SAndroid Build Coastguard Worker
dumpFpoStream()752*9880d681SAndroid Build Coastguard Worker Error LLVMOutputStyle::dumpFpoStream() {
753*9880d681SAndroid Build Coastguard Worker if (!opts::raw::DumpFpo)
754*9880d681SAndroid Build Coastguard Worker return Error::success();
755*9880d681SAndroid Build Coastguard Worker
756*9880d681SAndroid Build Coastguard Worker auto Dbi = File.getPDBDbiStream();
757*9880d681SAndroid Build Coastguard Worker if (!Dbi)
758*9880d681SAndroid Build Coastguard Worker return Dbi.takeError();
759*9880d681SAndroid Build Coastguard Worker
760*9880d681SAndroid Build Coastguard Worker ListScope D(P, "New FPO");
761*9880d681SAndroid Build Coastguard Worker for (const object::FpoData &Fpo : Dbi->getFpoRecords()) {
762*9880d681SAndroid Build Coastguard Worker DictScope DD(P, "");
763*9880d681SAndroid Build Coastguard Worker P.printNumber("Offset", Fpo.Offset);
764*9880d681SAndroid Build Coastguard Worker P.printNumber("Size", Fpo.Size);
765*9880d681SAndroid Build Coastguard Worker P.printNumber("Number of locals", Fpo.NumLocals);
766*9880d681SAndroid Build Coastguard Worker P.printNumber("Number of params", Fpo.NumParams);
767*9880d681SAndroid Build Coastguard Worker P.printNumber("Size of Prolog", Fpo.getPrologSize());
768*9880d681SAndroid Build Coastguard Worker P.printNumber("Number of Saved Registers", Fpo.getNumSavedRegs());
769*9880d681SAndroid Build Coastguard Worker P.printBoolean("Has SEH", Fpo.hasSEH());
770*9880d681SAndroid Build Coastguard Worker P.printBoolean("Use BP", Fpo.useBP());
771*9880d681SAndroid Build Coastguard Worker P.printNumber("Frame Pointer", Fpo.getFP());
772*9880d681SAndroid Build Coastguard Worker }
773*9880d681SAndroid Build Coastguard Worker return Error::success();
774*9880d681SAndroid Build Coastguard Worker }
775*9880d681SAndroid Build Coastguard Worker
flush()776*9880d681SAndroid Build Coastguard Worker void LLVMOutputStyle::flush() { P.flush(); }
777