blob: fe5a6863809225cc8b4a17821cac848f79b9cdee [file] [log] [blame]
Zachary Turnerfcb14ad2015-01-27 20:46:21 +00001//===- llvm-pdbdump.cpp - Dump debug info from a PDB file -------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Dumps debug information present in PDB files. This utility makes use of
11// the Microsoft Windows SDK, so will not compile or run on non-Windows
12// platforms.
13//
14//===----------------------------------------------------------------------===//
15
Zachary Turner9a818ad2015-02-22 22:03:38 +000016#include "llvm-pdbdump.h"
17#include "CompilandDumper.h"
Zachary Turnere5cb2692015-05-01 20:24:26 +000018#include "ExternalSymbolDumper.h"
Zachary Turnerdb18f5c2015-02-27 09:15:18 +000019#include "FunctionDumper.h"
Zachary Turner2d11c202015-02-27 09:15:59 +000020#include "LinePrinter.h"
Zachary Turner9a818ad2015-02-22 22:03:38 +000021#include "TypeDumper.h"
Zachary Turnerdb18f5c2015-02-27 09:15:18 +000022#include "VariableDumper.h"
Zachary Turner9a818ad2015-02-22 22:03:38 +000023
Zachary Turnerfcb14ad2015-01-27 20:46:21 +000024#include "llvm/ADT/ArrayRef.h"
David Majnemer6e081262015-10-15 01:27:19 +000025#include "llvm/ADT/BitVector.h"
26#include "llvm/ADT/DenseMap.h"
Zachary Turnerfcb14ad2015-01-27 20:46:21 +000027#include "llvm/ADT/StringExtras.h"
Zachary Turner8d7fa9b2015-02-10 22:47:14 +000028#include "llvm/Config/config.h"
Zachary Turnercac29ae2016-05-24 17:30:25 +000029#include "llvm/DebugInfo/CodeView/SymbolDumper.h"
Zachary Turner5a1b5ef2016-05-06 22:15:42 +000030#include "llvm/DebugInfo/CodeView/TypeDumper.h"
Zachary Turner819e77d2016-05-06 20:51:57 +000031#include "llvm/DebugInfo/PDB/GenericError.h"
Zachary Turnera5549172015-02-10 22:43:25 +000032#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
Zachary Turnera5549172015-02-10 22:43:25 +000033#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
Chandler Carruth71f308a2015-02-13 09:09:03 +000034#include "llvm/DebugInfo/PDB/IPDBSession.h"
35#include "llvm/DebugInfo/PDB/PDB.h"
Zachary Turnera5549172015-02-10 22:43:25 +000036#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
Zachary Turnerdb18f5c2015-02-27 09:15:18 +000037#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
Chandler Carruth71f308a2015-02-13 09:09:03 +000038#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
Zachary Turnerdb18f5c2015-02-27 09:15:18 +000039#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
40#include "llvm/DebugInfo/PDB/PDBSymbolThunk.h"
Zachary Turner2f09b502016-04-29 17:28:47 +000041#include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
42#include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
Zachary Turner6ba65de2016-04-29 17:22:58 +000043#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
Zachary Turner1822af542016-04-27 23:41:42 +000044#include "llvm/DebugInfo/PDB/Raw/ModInfo.h"
Zachary Turner06c2b4b2016-05-09 17:45:21 +000045#include "llvm/DebugInfo/PDB/Raw/ModStream.h"
Zachary Turner0eace0b2016-05-02 18:09:14 +000046#include "llvm/DebugInfo/PDB/Raw/NameHashTable.h"
Zachary Turner0a43efe2016-04-25 17:38:08 +000047#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
Rui Ueyama1f6b6e22016-05-13 21:21:53 +000048#include "llvm/DebugInfo/PDB/Raw/PublicsStream.h"
Reid Klecknerce5196e2016-05-12 23:26:23 +000049#include "llvm/DebugInfo/PDB/Raw/RawError.h"
Zachary Turner0a43efe2016-04-25 17:38:08 +000050#include "llvm/DebugInfo/PDB/Raw/RawSession.h"
Zachary Turner6ba65de2016-04-29 17:22:58 +000051#include "llvm/DebugInfo/PDB/Raw/StreamReader.h"
Zachary Turnerf5c59652016-05-03 00:28:21 +000052#include "llvm/DebugInfo/PDB/Raw/TpiStream.h"
Zachary Turnerfcb14ad2015-01-27 20:46:21 +000053#include "llvm/Support/CommandLine.h"
54#include "llvm/Support/ConvertUTF.h"
Zachary Turner9a818ad2015-02-22 22:03:38 +000055#include "llvm/Support/FileSystem.h"
Zachary Turnerfcb14ad2015-01-27 20:46:21 +000056#include "llvm/Support/Format.h"
57#include "llvm/Support/ManagedStatic.h"
David Majnemer6e081262015-10-15 01:27:19 +000058#include "llvm/Support/MemoryBuffer.h"
Zachary Turnerfcb14ad2015-01-27 20:46:21 +000059#include "llvm/Support/PrettyStackTrace.h"
Chandler Carruth71f308a2015-02-13 09:09:03 +000060#include "llvm/Support/Process.h"
Reid Klecknerb0345262016-05-04 16:09:04 +000061#include "llvm/Support/ScopedPrinter.h"
Daniel Sandersd41718e2016-04-22 12:04:42 +000062#include "llvm/Support/Signals.h"
Zachary Turner0a43efe2016-04-25 17:38:08 +000063#include "llvm/Support/raw_ostream.h"
Zachary Turnerfcb14ad2015-01-27 20:46:21 +000064
Zachary Turner8d7fa9b2015-02-10 22:47:14 +000065#if defined(HAVE_DIA_SDK)
Benjamin Kramer4b4a9362015-10-15 09:38:45 +000066#ifndef NOMINMAX
67#define NOMINMAX
68#endif
Zachary Turnera5549172015-02-10 22:43:25 +000069#include <Windows.h>
Zachary Turner8d7fa9b2015-02-10 22:47:14 +000070#endif
Zachary Turnerfcb14ad2015-01-27 20:46:21 +000071
72using namespace llvm;
Zachary Turner2f09b502016-04-29 17:28:47 +000073using namespace llvm::pdb;
Zachary Turnerfcb14ad2015-01-27 20:46:21 +000074
75namespace opts {
Zachary Turnerc0acf682015-02-15 20:27:53 +000076
77enum class PDB_DumpType { ByType, ByObjFile, Both };
78
Zachary Turnerfcb14ad2015-01-27 20:46:21 +000079cl::list<std::string> InputFilenames(cl::Positional,
80 cl::desc("<input PDB files>"),
81 cl::OneOrMore);
82
Zachary Turner7797c722015-03-02 04:39:56 +000083cl::OptionCategory TypeCategory("Symbol Type Options");
84cl::OptionCategory FilterCategory("Filtering Options");
Zachary Turnere5cb2692015-05-01 20:24:26 +000085cl::OptionCategory OtherOptions("Other Options");
Zachary Turner06c2b4b2016-05-09 17:45:21 +000086cl::OptionCategory NativeOtions("Native Options");
Zachary Turner7797c722015-03-02 04:39:56 +000087
88cl::opt<bool> Compilands("compilands", cl::desc("Display compilands"),
89 cl::cat(TypeCategory));
90cl::opt<bool> Symbols("symbols", cl::desc("Display symbols for each compiland"),
91 cl::cat(TypeCategory));
92cl::opt<bool> Globals("globals", cl::desc("Dump global symbols"),
93 cl::cat(TypeCategory));
Zachary Turnere5cb2692015-05-01 20:24:26 +000094cl::opt<bool> Externals("externals", cl::desc("Dump external symbols"),
95 cl::cat(TypeCategory));
Zachary Turner7797c722015-03-02 04:39:56 +000096cl::opt<bool> Types("types", cl::desc("Display types"), cl::cat(TypeCategory));
Zachary Turnera99000d2016-03-08 21:42:24 +000097cl::opt<bool> Lines("lines", cl::desc("Line tables"), cl::cat(TypeCategory));
Zachary Turner7797c722015-03-02 04:39:56 +000098cl::opt<bool>
Zachary Turner7797c722015-03-02 04:39:56 +000099 All("all", cl::desc("Implies all other options in 'Symbol Types' category"),
100 cl::cat(TypeCategory));
Zachary Turnerf5abda22015-03-01 06:49:49 +0000101
Zachary Turnere5cb2692015-05-01 20:24:26 +0000102cl::opt<uint64_t> LoadAddress(
103 "load-address",
104 cl::desc("Assume the module is loaded at the specified address"),
105 cl::cat(OtherOptions));
106
Zachary Turner96e60f72016-05-24 20:31:48 +0000107cl::opt<bool> DumpHeaders("raw-headers", cl::desc("dump PDB headers"),
Zachary Turner06c2b4b2016-05-09 17:45:21 +0000108 cl::cat(NativeOtions));
Zachary Turner96e60f72016-05-24 20:31:48 +0000109cl::opt<bool> DumpStreamBlocks("raw-stream-blocks",
David Majnemer6e081262015-10-15 01:27:19 +0000110 cl::desc("dump PDB stream blocks"),
Zachary Turner06c2b4b2016-05-09 17:45:21 +0000111 cl::cat(NativeOtions));
Zachary Turner85ed80b2016-05-25 03:43:17 +0000112cl::opt<bool> DumpStreamSummary("raw-stream-summary",
113 cl::desc("dump summary of the PDB streams"),
114 cl::cat(NativeOtions));
Zachary Turner96e60f72016-05-24 20:31:48 +0000115cl::opt<bool> DumpTpiRecords("raw-tpi-records",
Zachary Turner5a1b5ef2016-05-06 22:15:42 +0000116 cl::desc("dump CodeView type records"),
Zachary Turner06c2b4b2016-05-09 17:45:21 +0000117 cl::cat(NativeOtions));
Reid Klecknerb0345262016-05-04 16:09:04 +0000118cl::opt<bool>
Zachary Turner96e60f72016-05-24 20:31:48 +0000119 DumpTpiRecordBytes("raw-tpi-record-bytes",
Reid Klecknerb0345262016-05-04 16:09:04 +0000120 cl::desc("dump CodeView type record raw bytes"),
Zachary Turner06c2b4b2016-05-09 17:45:21 +0000121 cl::cat(NativeOtions));
Zachary Turner96e60f72016-05-24 20:31:48 +0000122cl::opt<std::string> DumpStreamDataIdx("raw-stream",
123 cl::desc("dump stream data"),
124 cl::cat(NativeOtions));
125cl::opt<std::string> DumpStreamDataName("raw-stream-name",
126 cl::desc("dump stream data"),
127 cl::cat(NativeOtions));
128cl::opt<bool> DumpModules("raw-modules", cl::desc("dump compiland information"),
129 cl::cat(NativeOtions));
130cl::opt<bool> DumpModuleFiles("raw-module-files",
131 cl::desc("dump file information"),
132 cl::cat(NativeOtions));
133cl::opt<bool> DumpModuleSyms("raw-module-syms", cl::desc("dump module symbols"),
Zachary Turner06c2b4b2016-05-09 17:45:21 +0000134 cl::cat(NativeOtions));
Zachary Turner96e60f72016-05-24 20:31:48 +0000135cl::opt<bool> DumpPublics("raw-publics", cl::desc("dump Publics stream data"),
Rui Ueyama1f6b6e22016-05-13 21:21:53 +0000136 cl::cat(NativeOtions));
Zachary Turnercac29ae2016-05-24 17:30:25 +0000137cl::opt<bool>
Zachary Turner96e60f72016-05-24 20:31:48 +0000138 DumpSymRecordBytes("raw-sym-record-bytes",
Zachary Turnercac29ae2016-05-24 17:30:25 +0000139 cl::desc("dump CodeView symbol record raw bytes"),
140 cl::cat(NativeOtions));
David Majnemer6e081262015-10-15 01:27:19 +0000141
Zachary Turnerf5abda22015-03-01 06:49:49 +0000142cl::list<std::string>
143 ExcludeTypes("exclude-types",
144 cl::desc("Exclude types by regular expression"),
Zachary Turner7797c722015-03-02 04:39:56 +0000145 cl::ZeroOrMore, cl::cat(FilterCategory));
Zachary Turnerf5abda22015-03-01 06:49:49 +0000146cl::list<std::string>
147 ExcludeSymbols("exclude-symbols",
148 cl::desc("Exclude symbols by regular expression"),
Zachary Turner7797c722015-03-02 04:39:56 +0000149 cl::ZeroOrMore, cl::cat(FilterCategory));
Zachary Turnerf5abda22015-03-01 06:49:49 +0000150cl::list<std::string>
151 ExcludeCompilands("exclude-compilands",
152 cl::desc("Exclude compilands by regular expression"),
Zachary Turner7797c722015-03-02 04:39:56 +0000153 cl::ZeroOrMore, cl::cat(FilterCategory));
Zachary Turner4dddcc62015-09-29 19:49:06 +0000154
155cl::list<std::string> IncludeTypes(
156 "include-types",
157 cl::desc("Include only types which match a regular expression"),
158 cl::ZeroOrMore, cl::cat(FilterCategory));
159cl::list<std::string> IncludeSymbols(
160 "include-symbols",
161 cl::desc("Include only symbols which match a regular expression"),
162 cl::ZeroOrMore, cl::cat(FilterCategory));
163cl::list<std::string> IncludeCompilands(
164 "include-compilands",
165 cl::desc("Include only compilands those which match a regular expression"),
166 cl::ZeroOrMore, cl::cat(FilterCategory));
167
Zachary Turner7797c722015-03-02 04:39:56 +0000168cl::opt<bool> ExcludeCompilerGenerated(
169 "no-compiler-generated",
170 cl::desc("Don't show compiler generated types and symbols"),
171 cl::cat(FilterCategory));
172cl::opt<bool>
173 ExcludeSystemLibraries("no-system-libs",
174 cl::desc("Don't show symbols from system libraries"),
175 cl::cat(FilterCategory));
Zachary Turner65323652015-03-04 06:09:53 +0000176cl::opt<bool> NoClassDefs("no-class-definitions",
177 cl::desc("Don't display full class definitions"),
178 cl::cat(FilterCategory));
179cl::opt<bool> NoEnumDefs("no-enum-definitions",
180 cl::desc("Don't display full enum definitions"),
181 cl::cat(FilterCategory));
Zachary Turner49693b42015-01-28 01:22:33 +0000182}
183
Zachary Turner819e77d2016-05-06 20:51:57 +0000184static Error dumpFileHeaders(ScopedPrinter &P, PDBFile &File) {
Reid Klecknerb0345262016-05-04 16:09:04 +0000185 if (!opts::DumpHeaders)
Zachary Turner819e77d2016-05-06 20:51:57 +0000186 return Error::success();
187
Reid Klecknerb0345262016-05-04 16:09:04 +0000188 DictScope D(P, "FileHeaders");
189 P.printNumber("BlockSize", File.getBlockSize());
190 P.printNumber("Unknown0", File.getUnknown0());
191 P.printNumber("NumBlocks", File.getBlockCount());
192 P.printNumber("NumDirectoryBytes", File.getNumDirectoryBytes());
193 P.printNumber("Unknown1", File.getUnknown1());
194 P.printNumber("BlockMapAddr", File.getBlockMapIndex());
195 P.printNumber("NumDirectoryBlocks", File.getNumDirectoryBlocks());
196 P.printNumber("BlockMapOffset", File.getBlockMapOffset());
Zachary Turnercdd313c2016-05-04 15:05:12 +0000197
Chad Rosier20dbbf32016-05-04 15:25:06 +0000198 // The directory is not contiguous. Instead, the block map contains a
199 // contiguous list of block numbers whose contents, when concatenated in
200 // order, make up the directory.
Reid Klecknerb0345262016-05-04 16:09:04 +0000201 P.printList("DirectoryBlocks", File.getDirectoryBlockArray());
202 P.printNumber("NumStreams", File.getNumStreams());
Zachary Turner819e77d2016-05-06 20:51:57 +0000203 return Error::success();
Reid Klecknerb0345262016-05-04 16:09:04 +0000204}
Zachary Turnercdd313c2016-05-04 15:05:12 +0000205
Zachary Turner85ed80b2016-05-25 03:43:17 +0000206static Error dumpStreamSummary(ScopedPrinter &P, PDBFile &File) {
207 if (!opts::DumpStreamSummary)
Zachary Turner819e77d2016-05-06 20:51:57 +0000208 return Error::success();
Zachary Turnercdd313c2016-05-04 15:05:12 +0000209
Zachary Turner85ed80b2016-05-25 03:43:17 +0000210 auto DbiS = File.getPDBDbiStream();
211 if (auto EC = DbiS.takeError())
212 return EC;
213 auto TpiS = File.getPDBTpiStream();
214 if (auto EC = TpiS.takeError())
215 return EC;
216 auto InfoS = File.getPDBInfoStream();
217 if (auto EC = InfoS.takeError())
218 return EC;
219 DbiStream &DS = DbiS.get();
220 TpiStream &TS = TpiS.get();
221 InfoStream &IS = InfoS.get();
222
223 ListScope L(P, "Streams");
Chad Rosier20dbbf32016-05-04 15:25:06 +0000224 uint32_t StreamCount = File.getNumStreams();
Zachary Turner85ed80b2016-05-25 03:43:17 +0000225 std::unordered_map<uint16_t, const ModuleInfoEx *> ModStreams;
226 std::unordered_map<uint16_t, std::string> NamedStreams;
227
228 for (auto &ModI : DS.modules()) {
229 uint16_t SN = ModI.Info.getModuleStreamIndex();
230 ModStreams[SN] = &ModI;
Chad Rosier20dbbf32016-05-04 15:25:06 +0000231 }
Zachary Turner85ed80b2016-05-25 03:43:17 +0000232 for (auto &NSE : IS.named_streams()) {
233 NamedStreams[NSE.second] = NSE.first();
234 }
235
236 for (uint16_t StreamIdx = 0; StreamIdx < StreamCount; ++StreamIdx) {
237 std::string Label("Stream ");
238 Label += to_string(StreamIdx);
239 std::string Value;
Zachary Turnerc59261c2016-05-25 03:53:16 +0000240 if (StreamIdx == StreamPDB)
Zachary Turner85ed80b2016-05-25 03:43:17 +0000241 Value = "PDB Stream";
242 else if (StreamIdx == StreamDBI)
243 Value = "DBI Stream";
244 else if (StreamIdx == StreamTPI)
245 Value = "TPI Stream";
246 else if (StreamIdx == StreamIPI)
247 Value = "IPI Stream";
248 else if (StreamIdx == DS.getGlobalSymbolStreamIndex())
249 Value = "Global Symbol Hash";
250 else if (StreamIdx == DS.getPublicSymbolStreamIndex())
251 Value = "Public Symbol Hash";
252 else if (StreamIdx == DS.getSymRecordStreamIndex())
253 Value = "Public Symbol Records";
254 else if (StreamIdx == TS.getTypeHashStreamIndex())
255 Value = "TPI Hash";
256 else if (StreamIdx == TS.getTypeHashStreamAuxIndex())
257 Value = "TPI Aux Hash";
258 else {
259 auto ModIter = ModStreams.find(StreamIdx);
260 auto NSIter = NamedStreams.find(StreamIdx);
261 if (ModIter != ModStreams.end()) {
262 Value = "Module \"";
263 Value += ModIter->second->Info.getModuleName();
264 Value += "\"";
265 } else if (NSIter != NamedStreams.end()) {
266 Value = "Named Stream \"";
267 Value += NSIter->second;
268 Value += "\"";
269 } else {
270 Value = "???";
271 }
272 }
273 Value = "[" + Value + "]";
274 Value =
275 Value + " (" + to_string(File.getStreamByteSize(StreamIdx)) + " bytes)";
276
277 P.printString(Label, Value);
278 }
279 P.flush();
Zachary Turner819e77d2016-05-06 20:51:57 +0000280 return Error::success();
Reid Klecknerb0345262016-05-04 16:09:04 +0000281}
Zachary Turnercdd313c2016-05-04 15:05:12 +0000282
Zachary Turner819e77d2016-05-06 20:51:57 +0000283static Error dumpStreamBlocks(ScopedPrinter &P, PDBFile &File) {
Reid Klecknerb0345262016-05-04 16:09:04 +0000284 if (!opts::DumpStreamBlocks)
Zachary Turner819e77d2016-05-06 20:51:57 +0000285 return Error::success();
Reid Klecknerb0345262016-05-04 16:09:04 +0000286
287 ListScope L(P, "StreamBlocks");
288 uint32_t StreamCount = File.getNumStreams();
289 for (uint32_t StreamIdx = 0; StreamIdx < StreamCount; ++StreamIdx) {
290 std::string Name("Stream ");
291 Name += to_string(StreamIdx);
292 auto StreamBlocks = File.getStreamBlockList(StreamIdx);
293 P.printList(Name, StreamBlocks);
Chad Rosier20dbbf32016-05-04 15:25:06 +0000294 }
Zachary Turner819e77d2016-05-06 20:51:57 +0000295 return Error::success();
Reid Klecknerb0345262016-05-04 16:09:04 +0000296}
Zachary Turnercdd313c2016-05-04 15:05:12 +0000297
Zachary Turner819e77d2016-05-06 20:51:57 +0000298static Error dumpStreamData(ScopedPrinter &P, PDBFile &File) {
Reid Klecknerb0345262016-05-04 16:09:04 +0000299 uint32_t StreamCount = File.getNumStreams();
Zachary Turner96e60f72016-05-24 20:31:48 +0000300 StringRef DumpStreamStr = opts::DumpStreamDataIdx;
Chad Rosier20dbbf32016-05-04 15:25:06 +0000301 uint32_t DumpStreamNum;
Reid Klecknerb0345262016-05-04 16:09:04 +0000302 if (DumpStreamStr.getAsInteger(/*Radix=*/0U, DumpStreamNum) ||
303 DumpStreamNum >= StreamCount)
Zachary Turner819e77d2016-05-06 20:51:57 +0000304 return Error::success();
Chad Rosier20dbbf32016-05-04 15:25:06 +0000305
Zachary Turner96e60f72016-05-24 20:31:48 +0000306 MappedBlockStream S(DumpStreamNum, File);
307 StreamReader R(S);
308 while (R.bytesRemaining() > 0) {
309 ArrayRef<uint8_t> Data;
Reid Klecknerb0345262016-05-04 16:09:04 +0000310 uint32_t BytesToReadInBlock = std::min(
Zachary Turner96e60f72016-05-24 20:31:48 +0000311 R.bytesRemaining(), static_cast<uint32_t>(File.getBlockSize()));
312 if (auto EC = R.getArrayRef(Data, BytesToReadInBlock))
313 return EC;
314 outs() << StringRef(reinterpret_cast<const char *>(Data.begin()),
315 Data.size());
Chad Rosier20dbbf32016-05-04 15:25:06 +0000316 }
Zachary Turner819e77d2016-05-06 20:51:57 +0000317 return Error::success();
Reid Klecknerb0345262016-05-04 16:09:04 +0000318}
Chad Rosier20dbbf32016-05-04 15:25:06 +0000319
Zachary Turner819e77d2016-05-06 20:51:57 +0000320static Error dumpInfoStream(ScopedPrinter &P, PDBFile &File) {
Zachary Turnerc59261c2016-05-25 03:53:16 +0000321 if (!opts::DumpHeaders)
322 return Error::success();
Zachary Turner819e77d2016-05-06 20:51:57 +0000323 auto InfoS = File.getPDBInfoStream();
324 if (auto EC = InfoS.takeError())
325 return EC;
326
327 InfoStream &IS = InfoS.get();
Chad Rosier20dbbf32016-05-04 15:25:06 +0000328
Reid Klecknerb0345262016-05-04 16:09:04 +0000329 DictScope D(P, "PDB Stream");
330 P.printNumber("Version", IS.getVersion());
331 P.printHex("Signature", IS.getSignature());
332 P.printNumber("Age", IS.getAge());
333 P.printObject("Guid", IS.getGuid());
Zachary Turner819e77d2016-05-06 20:51:57 +0000334 return Error::success();
Reid Klecknerb0345262016-05-04 16:09:04 +0000335}
336
Zachary Turner96e60f72016-05-24 20:31:48 +0000337static Error dumpNamedStream(ScopedPrinter &P, PDBFile &File) {
338 if (opts::DumpStreamDataName.empty())
339 return Error::success();
340
Zachary Turner819e77d2016-05-06 20:51:57 +0000341 auto InfoS = File.getPDBInfoStream();
342 if (auto EC = InfoS.takeError())
343 return EC;
344 InfoStream &IS = InfoS.get();
345
Zachary Turner96e60f72016-05-24 20:31:48 +0000346 uint32_t NameStreamIndex = IS.getNamedStreamIndex(opts::DumpStreamDataName);
Reid Klecknerb0345262016-05-04 16:09:04 +0000347
Chad Rosier20dbbf32016-05-04 15:25:06 +0000348 if (NameStreamIndex != 0) {
Reid Klecknerb0345262016-05-04 16:09:04 +0000349 std::string Name("Stream '");
Zachary Turner96e60f72016-05-24 20:31:48 +0000350 Name += opts::DumpStreamDataName;
Reid Klecknerb0345262016-05-04 16:09:04 +0000351 Name += "'";
352 DictScope D(P, Name);
353 P.printNumber("Index", NameStreamIndex);
354
Chad Rosier20dbbf32016-05-04 15:25:06 +0000355 MappedBlockStream NameStream(NameStreamIndex, File);
356 StreamReader Reader(NameStream);
357
Chad Rosier20dbbf32016-05-04 15:25:06 +0000358 NameHashTable NameTable;
Zachary Turner819e77d2016-05-06 20:51:57 +0000359 if (auto EC = NameTable.load(Reader))
360 return EC;
361
Reid Klecknerb0345262016-05-04 16:09:04 +0000362 P.printHex("Signature", NameTable.getSignature());
363 P.printNumber("Version", NameTable.getHashVersion());
364 P.printNumber("Name Count", NameTable.getNameCount());
365 ListScope L(P, "Names");
Chad Rosier20dbbf32016-05-04 15:25:06 +0000366 for (uint32_t ID : NameTable.name_ids()) {
Reid Klecknerb0345262016-05-04 16:09:04 +0000367 StringRef Str = NameTable.getStringForID(ID);
368 if (!Str.empty())
369 P.printString(Str);
Chad Rosier20dbbf32016-05-04 15:25:06 +0000370 }
371 }
Zachary Turner819e77d2016-05-06 20:51:57 +0000372 return Error::success();
Reid Klecknerb0345262016-05-04 16:09:04 +0000373}
Chad Rosier20dbbf32016-05-04 15:25:06 +0000374
Zachary Turnercac29ae2016-05-24 17:30:25 +0000375static Error dumpDbiStream(ScopedPrinter &P, PDBFile &File,
376 codeview::CVTypeDumper &TD) {
Zachary Turnerc59261c2016-05-25 03:53:16 +0000377 bool DumpModules =
378 opts::DumpModules || opts::DumpModuleSyms || opts::DumpModuleFiles;
379 if (!opts::DumpHeaders && !DumpModules)
380 return Error::success();
381
Zachary Turner819e77d2016-05-06 20:51:57 +0000382 auto DbiS = File.getPDBDbiStream();
383 if (auto EC = DbiS.takeError())
384 return EC;
385 DbiStream &DS = DbiS.get();
Reid Klecknerb0345262016-05-04 16:09:04 +0000386
387 DictScope D(P, "DBI Stream");
388 P.printNumber("Dbi Version", DS.getDbiVersion());
389 P.printNumber("Age", DS.getAge());
390 P.printBoolean("Incremental Linking", DS.isIncrementallyLinked());
391 P.printBoolean("Has CTypes", DS.hasCTypes());
392 P.printBoolean("Is Stripped", DS.isStripped());
393 P.printObject("Machine Type", DS.getMachineType());
Rui Ueyama0376b1a2016-05-19 18:05:58 +0000394 P.printNumber("Symbol Record Stream Index", DS.getSymRecordStreamIndex());
Zachary Turner96e60f72016-05-24 20:31:48 +0000395 P.printNumber("Public Symbol Stream Index", DS.getPublicSymbolStreamIndex());
396 P.printNumber("Global Symbol Stream Index", DS.getGlobalSymbolStreamIndex());
Chad Rosier20dbbf32016-05-04 15:25:06 +0000397
398 uint16_t Major = DS.getBuildMajorVersion();
399 uint16_t Minor = DS.getBuildMinorVersion();
Reid Klecknerb0345262016-05-04 16:09:04 +0000400 P.printVersion("Toolchain Version", Major, Minor);
Chad Rosier20dbbf32016-05-04 15:25:06 +0000401
Reid Klecknerb0345262016-05-04 16:09:04 +0000402 std::string DllName;
403 raw_string_ostream DllStream(DllName);
404 DllStream << "mspdb" << Major << Minor << ".dll version";
405 DllStream.flush();
406 P.printVersion(DllName, Major, Minor, DS.getPdbDllVersion());
407
Zachary Turnerc59261c2016-05-25 03:53:16 +0000408 if (DumpModules) {
Zachary Turner96e60f72016-05-24 20:31:48 +0000409 ListScope L(P, "Modules");
410 for (auto &Modi : DS.modules()) {
411 DictScope DD(P);
412 P.printString("Name", Modi.Info.getModuleName());
413 P.printNumber("Debug Stream Index", Modi.Info.getModuleStreamIndex());
414 P.printString("Object File Name", Modi.Info.getObjFileName());
415 P.printNumber("Num Files", Modi.Info.getNumberOfFiles());
416 P.printNumber("Source File Name Idx", Modi.Info.getSourceFileNameIndex());
417 P.printNumber("Pdb File Name Idx", Modi.Info.getPdbFilePathNameIndex());
418 P.printNumber("Line Info Byte Size", Modi.Info.getLineInfoByteSize());
419 P.printNumber("C13 Line Info Byte Size",
420 Modi.Info.getC13LineInfoByteSize());
421 P.printNumber("Symbol Byte Size", Modi.Info.getSymbolDebugInfoByteSize());
422 P.printNumber("Type Server Index", Modi.Info.getTypeServerIndex());
423 P.printBoolean("Has EC Info", Modi.Info.hasECInfo());
424 if (opts::DumpModuleFiles) {
425 std::string FileListName =
426 to_string(Modi.SourceFiles.size()) + " Contributing Source Files";
427 ListScope LL(P, FileListName);
428 for (auto File : Modi.SourceFiles)
429 P.printString(File);
430 }
431 bool HasModuleDI =
432 (Modi.Info.getModuleStreamIndex() < File.getNumStreams());
433 bool ShouldDumpSymbols =
434 (opts::DumpModuleSyms || opts::DumpSymRecordBytes);
435 if (HasModuleDI && ShouldDumpSymbols) {
436 ListScope SS(P, "Symbols");
437 ModStream ModS(File, Modi.Info);
438 if (auto EC = ModS.reload())
439 return EC;
Zachary Turner06c2b4b2016-05-09 17:45:21 +0000440
Zachary Turner96e60f72016-05-24 20:31:48 +0000441 codeview::CVSymbolDumper SD(P, TD, nullptr, false);
442 for (auto &S : ModS.symbols()) {
443 DictScope DD(P, "");
Zachary Turnercac29ae2016-05-24 17:30:25 +0000444
Zachary Turner96e60f72016-05-24 20:31:48 +0000445 if (opts::DumpModuleSyms)
446 SD.dump(S);
447 if (opts::DumpSymRecordBytes)
448 P.printBinaryBlock("Bytes", S.Data);
449 }
Zachary Turner06c2b4b2016-05-09 17:45:21 +0000450 }
451 }
Chad Rosier20dbbf32016-05-04 15:25:06 +0000452 }
Zachary Turner819e77d2016-05-06 20:51:57 +0000453 return Error::success();
Reid Klecknerb0345262016-05-04 16:09:04 +0000454}
455
Zachary Turnercac29ae2016-05-24 17:30:25 +0000456static Error dumpTpiStream(ScopedPrinter &P, PDBFile &File,
457 codeview::CVTypeDumper &TD) {
Reid Klecknerb0345262016-05-04 16:09:04 +0000458
Zachary Turner5a1b5ef2016-05-06 22:15:42 +0000459 if (opts::DumpTpiRecordBytes || opts::DumpTpiRecords) {
Zachary Turnercac29ae2016-05-24 17:30:25 +0000460 DictScope D(P, "Type Info Stream");
461
462 auto TpiS = File.getPDBTpiStream();
463 if (auto EC = TpiS.takeError())
464 return EC;
465 TpiStream &Tpi = TpiS.get();
466
467 P.printNumber("TPI Version", Tpi.getTpiVersion());
468 P.printNumber("Record count", Tpi.NumTypeRecords());
469
Zachary Turner5a1b5ef2016-05-06 22:15:42 +0000470 ListScope L(P, "Records");
Reid Klecknerb0345262016-05-04 16:09:04 +0000471
Reid Klecknerce5196e2016-05-12 23:26:23 +0000472 bool HadError = false;
473 for (auto &Type : Tpi.types(&HadError)) {
Zachary Turner5a1b5ef2016-05-06 22:15:42 +0000474 DictScope DD(P, "");
475
476 if (opts::DumpTpiRecords)
477 TD.dump(Type);
478
479 if (opts::DumpTpiRecordBytes)
Zachary Turner9073ed62016-05-09 17:44:58 +0000480 P.printBinaryBlock("Bytes", Type.Data);
Zachary Turner5a1b5ef2016-05-06 22:15:42 +0000481 }
Reid Klecknerce5196e2016-05-12 23:26:23 +0000482 if (HadError)
483 return make_error<RawError>(raw_error_code::corrupt_file,
484 "TPI stream contained corrupt record");
Zachary Turnercac29ae2016-05-24 17:30:25 +0000485 } else if (opts::DumpModuleSyms) {
486 // Even if the user doesn't want to dump type records, we still need to
487 // iterate them in order to build the list of types so that we can print
488 // them when dumping module symbols. So when they want to dump symbols
489 // but not types, use a null output stream.
490 ScopedPrinter *OldP = TD.getPrinter();
491 TD.setPrinter(nullptr);
492 auto TpiS = File.getPDBTpiStream();
493 if (auto EC = TpiS.takeError())
494 return EC;
495 TpiStream &Tpi = TpiS.get();
496 bool HadError = false;
497 for (auto &Type : Tpi.types(&HadError))
498 TD.dump(Type);
499
500 TD.setPrinter(OldP);
501 if (HadError)
502 return make_error<RawError>(raw_error_code::corrupt_file,
503 "TPI stream contained corrupt record");
Chad Rosier20dbbf32016-05-04 15:25:06 +0000504 }
Zachary Turnercac29ae2016-05-24 17:30:25 +0000505
Zachary Turner819e77d2016-05-06 20:51:57 +0000506 return Error::success();
Zachary Turnercdd313c2016-05-04 15:05:12 +0000507}
508
Zachary Turner9e33e6f2016-05-24 18:55:14 +0000509static Error dumpPublicsStream(ScopedPrinter &P, PDBFile &File,
510 codeview::CVTypeDumper &TD) {
Rui Ueyama1f6b6e22016-05-13 21:21:53 +0000511 if (!opts::DumpPublics)
512 return Error::success();
513
514 DictScope D(P, "Publics Stream");
515 auto PublicsS = File.getPDBPublicsStream();
516 if (auto EC = PublicsS.takeError())
517 return EC;
518 PublicsStream &Publics = PublicsS.get();
519 P.printNumber("Stream number", Publics.getStreamNum());
520 P.printNumber("SymHash", Publics.getSymHash());
521 P.printNumber("AddrMap", Publics.getAddrMap());
522 P.printNumber("Number of buckets", Publics.getNumBuckets());
Rui Ueyama8dc18c52016-05-17 23:07:48 +0000523 P.printList("Hash Buckets", Publics.getHashBuckets());
524 P.printList("Address Map", Publics.getAddressMap());
525 P.printList("Thunk Map", Publics.getThunkMap());
Rui Ueyama350b2982016-05-18 16:24:16 +0000526 P.printList("Section Offsets", Publics.getSectionOffsets());
Zachary Turner9e33e6f2016-05-24 18:55:14 +0000527 ListScope L(P, "Symbols");
528 codeview::CVSymbolDumper SD(P, TD, nullptr, false);
529 for (auto S : Publics.getSymbols()) {
530 DictScope DD(P, "");
531
532 SD.dump(S);
533 if (opts::DumpSymRecordBytes)
534 P.printBinaryBlock("Bytes", S.Data);
535 }
Rui Ueyama1f6b6e22016-05-13 21:21:53 +0000536 return Error::success();
537}
538
Zachary Turner819e77d2016-05-06 20:51:57 +0000539static Error dumpStructure(RawSession &RS) {
Reid Klecknerb0345262016-05-04 16:09:04 +0000540 PDBFile &File = RS.getPDBFile();
541 ScopedPrinter P(outs());
542
Zachary Turner819e77d2016-05-06 20:51:57 +0000543 if (auto EC = dumpFileHeaders(P, File))
544 return EC;
Reid Klecknerb0345262016-05-04 16:09:04 +0000545
Zachary Turner85ed80b2016-05-25 03:43:17 +0000546 if (auto EC = dumpStreamSummary(P, File))
Zachary Turner819e77d2016-05-06 20:51:57 +0000547 return EC;
Reid Klecknerb0345262016-05-04 16:09:04 +0000548
Zachary Turner819e77d2016-05-06 20:51:57 +0000549 if (auto EC = dumpStreamBlocks(P, File))
550 return EC;
Reid Klecknerb0345262016-05-04 16:09:04 +0000551
Zachary Turner819e77d2016-05-06 20:51:57 +0000552 if (auto EC = dumpStreamData(P, File))
553 return EC;
Reid Klecknerb0345262016-05-04 16:09:04 +0000554
Zachary Turner819e77d2016-05-06 20:51:57 +0000555 if (auto EC = dumpInfoStream(P, File))
556 return EC;
Reid Klecknerb0345262016-05-04 16:09:04 +0000557
Zachary Turner96e60f72016-05-24 20:31:48 +0000558 if (auto EC = dumpNamedStream(P, File))
Zachary Turner819e77d2016-05-06 20:51:57 +0000559 return EC;
Reid Klecknerb0345262016-05-04 16:09:04 +0000560
Zachary Turnercac29ae2016-05-24 17:30:25 +0000561 codeview::CVTypeDumper TD(P, false);
562 if (auto EC = dumpTpiStream(P, File, TD))
Zachary Turner819e77d2016-05-06 20:51:57 +0000563 return EC;
Reid Klecknerb0345262016-05-04 16:09:04 +0000564
Zachary Turnercac29ae2016-05-24 17:30:25 +0000565 if (auto EC = dumpDbiStream(P, File, TD))
Zachary Turner819e77d2016-05-06 20:51:57 +0000566 return EC;
Rui Ueyama1f6b6e22016-05-13 21:21:53 +0000567
Zachary Turner9e33e6f2016-05-24 18:55:14 +0000568 if (auto EC = dumpPublicsStream(P, File, TD))
Rui Ueyama1f6b6e22016-05-13 21:21:53 +0000569 return EC;
Zachary Turner96e60f72016-05-24 20:31:48 +0000570 return Error::success();
571}
572
573bool isRawDumpEnabled() {
574 if (opts::DumpHeaders)
575 return true;
576 if (opts::DumpModules)
577 return true;
578 if (opts::DumpModuleFiles)
579 return true;
580 if (opts::DumpModuleSyms)
581 return true;
582 if (!opts::DumpStreamDataIdx.empty())
583 return true;
584 if (!opts::DumpStreamDataName.empty())
585 return true;
586 if (opts::DumpPublics)
587 return true;
Zachary Turner85ed80b2016-05-25 03:43:17 +0000588 if (opts::DumpStreamSummary)
Zachary Turner96e60f72016-05-24 20:31:48 +0000589 return true;
Zachary Turner85ed80b2016-05-25 03:43:17 +0000590 if (opts::DumpStreamBlocks)
Zachary Turner96e60f72016-05-24 20:31:48 +0000591 return true;
592 if (opts::DumpSymRecordBytes)
593 return true;
594 if (opts::DumpTpiRecordBytes)
595 return true;
596 if (opts::DumpTpiRecords)
597 return true;
598 return false;
David Majnemer1573b242016-04-28 23:47:27 +0000599}
600
601static void dumpInput(StringRef Path) {
602 std::unique_ptr<IPDBSession> Session;
Zachary Turner96e60f72016-05-24 20:31:48 +0000603 if (isRawDumpEnabled()) {
Zachary Turner819e77d2016-05-06 20:51:57 +0000604 auto E = loadDataForPDB(PDB_ReaderType::Raw, Path, Session);
605 if (!E) {
David Majnemer1573b242016-04-28 23:47:27 +0000606 RawSession *RS = static_cast<RawSession *>(Session.get());
Zachary Turner819e77d2016-05-06 20:51:57 +0000607 E = dumpStructure(*RS);
David Majnemer1573b242016-04-28 23:47:27 +0000608 }
609
Zachary Turner819e77d2016-05-06 20:51:57 +0000610 if (E)
611 logAllUnhandledErrors(std::move(E), outs(), "");
612
David Majnemer1573b242016-04-28 23:47:27 +0000613 return;
614 }
615
Zachary Turner819e77d2016-05-06 20:51:57 +0000616 Error E = loadDataForPDB(PDB_ReaderType::DIA, Path, Session);
617 if (E) {
618 logAllUnhandledErrors(std::move(E), outs(), "");
David Majnemer1573b242016-04-28 23:47:27 +0000619 return;
620 }
621
Zachary Turnere5cb2692015-05-01 20:24:26 +0000622 if (opts::LoadAddress)
623 Session->setLoadAddress(opts::LoadAddress);
Zachary Turner7058dfc2015-01-27 22:40:14 +0000624
Zachary Turner2d11c202015-02-27 09:15:59 +0000625 LinePrinter Printer(2, outs());
626
Zachary Turnera5549172015-02-10 22:43:25 +0000627 auto GlobalScope(Session->getGlobalScope());
Zachary Turner9a818ad2015-02-22 22:03:38 +0000628 std::string FileName(GlobalScope->getSymbolsFileName());
629
Zachary Turner2d11c202015-02-27 09:15:59 +0000630 WithColor(Printer, PDB_ColorItem::None).get() << "Summary for ";
631 WithColor(Printer, PDB_ColorItem::Path).get() << FileName;
632 Printer.Indent();
Zachary Turner9a818ad2015-02-22 22:03:38 +0000633 uint64_t FileSize = 0;
Zachary Turner9a818ad2015-02-22 22:03:38 +0000634
Zachary Turner2d11c202015-02-27 09:15:59 +0000635 Printer.NewLine();
636 WithColor(Printer, PDB_ColorItem::Identifier).get() << "Size";
David Majnemer6e081262015-10-15 01:27:19 +0000637 if (!sys::fs::file_size(FileName, FileSize)) {
Zachary Turner2d11c202015-02-27 09:15:59 +0000638 Printer << ": " << FileSize << " bytes";
639 } else {
640 Printer << ": (Unable to obtain file size)";
641 }
642
643 Printer.NewLine();
644 WithColor(Printer, PDB_ColorItem::Identifier).get() << "Guid";
645 Printer << ": " << GlobalScope->getGuid();
646
647 Printer.NewLine();
648 WithColor(Printer, PDB_ColorItem::Identifier).get() << "Age";
649 Printer << ": " << GlobalScope->getAge();
650
651 Printer.NewLine();
652 WithColor(Printer, PDB_ColorItem::Identifier).get() << "Attributes";
653 Printer << ": ";
Zachary Turner9a818ad2015-02-22 22:03:38 +0000654 if (GlobalScope->hasCTypes())
655 outs() << "HasCTypes ";
656 if (GlobalScope->hasPrivateSymbols())
657 outs() << "HasPrivateSymbols ";
Zachary Turner2d11c202015-02-27 09:15:59 +0000658 Printer.Unindent();
Zachary Turner9a818ad2015-02-22 22:03:38 +0000659
Zachary Turnerdb18f5c2015-02-27 09:15:18 +0000660 if (opts::Compilands) {
Zachary Turner2d11c202015-02-27 09:15:59 +0000661 Printer.NewLine();
662 WithColor(Printer, PDB_ColorItem::SectionHeader).get()
663 << "---COMPILANDS---";
664 Printer.Indent();
Zachary Turnerc074de02015-02-12 21:09:24 +0000665 auto Compilands = GlobalScope->findAllChildren<PDBSymbolCompiland>();
Zachary Turner2d11c202015-02-27 09:15:59 +0000666 CompilandDumper Dumper(Printer);
Zachary Turnera99000d2016-03-08 21:42:24 +0000667 CompilandDumpFlags options = CompilandDumper::Flags::None;
668 if (opts::Lines)
669 options = options | CompilandDumper::Flags::Lines;
Zachary Turner9a818ad2015-02-22 22:03:38 +0000670 while (auto Compiland = Compilands->getNext())
Zachary Turnera99000d2016-03-08 21:42:24 +0000671 Dumper.start(*Compiland, options);
Zachary Turner2d11c202015-02-27 09:15:59 +0000672 Printer.Unindent();
Zachary Turnerdb18f5c2015-02-27 09:15:18 +0000673 }
674
675 if (opts::Types) {
Zachary Turner2d11c202015-02-27 09:15:59 +0000676 Printer.NewLine();
677 WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---TYPES---";
678 Printer.Indent();
Zachary Turner65323652015-03-04 06:09:53 +0000679 TypeDumper Dumper(Printer);
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000680 Dumper.start(*GlobalScope);
Zachary Turner2d11c202015-02-27 09:15:59 +0000681 Printer.Unindent();
Zachary Turnerdb18f5c2015-02-27 09:15:18 +0000682 }
683
684 if (opts::Symbols) {
Zachary Turner2d11c202015-02-27 09:15:59 +0000685 Printer.NewLine();
686 WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---SYMBOLS---";
687 Printer.Indent();
Zachary Turnerdb18f5c2015-02-27 09:15:18 +0000688 auto Compilands = GlobalScope->findAllChildren<PDBSymbolCompiland>();
Zachary Turner2d11c202015-02-27 09:15:59 +0000689 CompilandDumper Dumper(Printer);
Zachary Turnerdb18f5c2015-02-27 09:15:18 +0000690 while (auto Compiland = Compilands->getNext())
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000691 Dumper.start(*Compiland, true);
Zachary Turner2d11c202015-02-27 09:15:59 +0000692 Printer.Unindent();
Zachary Turnerdb18f5c2015-02-27 09:15:18 +0000693 }
694
695 if (opts::Globals) {
Zachary Turner2d11c202015-02-27 09:15:59 +0000696 Printer.NewLine();
697 WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---GLOBALS---";
698 Printer.Indent();
Zachary Turnerdb18f5c2015-02-27 09:15:18 +0000699 {
Zachary Turner2d11c202015-02-27 09:15:59 +0000700 FunctionDumper Dumper(Printer);
Zachary Turnerdb18f5c2015-02-27 09:15:18 +0000701 auto Functions = GlobalScope->findAllChildren<PDBSymbolFunc>();
Zachary Turner2d11c202015-02-27 09:15:59 +0000702 while (auto Function = Functions->getNext()) {
703 Printer.NewLine();
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000704 Dumper.start(*Function, FunctionDumper::PointerType::None);
Zachary Turner2d11c202015-02-27 09:15:59 +0000705 }
Zachary Turnerdb18f5c2015-02-27 09:15:18 +0000706 }
707 {
708 auto Vars = GlobalScope->findAllChildren<PDBSymbolData>();
Zachary Turner2d11c202015-02-27 09:15:59 +0000709 VariableDumper Dumper(Printer);
Zachary Turnerdb18f5c2015-02-27 09:15:18 +0000710 while (auto Var = Vars->getNext())
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000711 Dumper.start(*Var);
Zachary Turnerdb18f5c2015-02-27 09:15:18 +0000712 }
713 {
714 auto Thunks = GlobalScope->findAllChildren<PDBSymbolThunk>();
Zachary Turner2d11c202015-02-27 09:15:59 +0000715 CompilandDumper Dumper(Printer);
Zachary Turnerdb18f5c2015-02-27 09:15:18 +0000716 while (auto Thunk = Thunks->getNext())
Zachary Turnerb52d08d2015-03-01 06:51:29 +0000717 Dumper.dump(*Thunk);
Zachary Turnerdb18f5c2015-02-27 09:15:18 +0000718 }
Zachary Turner2d11c202015-02-27 09:15:59 +0000719 Printer.Unindent();
Zachary Turner7058dfc2015-01-27 22:40:14 +0000720 }
Zachary Turnere5cb2692015-05-01 20:24:26 +0000721 if (opts::Externals) {
722 Printer.NewLine();
723 WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---EXTERNALS---";
724 Printer.Indent();
725 ExternalSymbolDumper Dumper(Printer);
726 Dumper.start(*GlobalScope);
727 }
Zachary Turnera99000d2016-03-08 21:42:24 +0000728 if (opts::Lines) {
729 Printer.NewLine();
730 }
Zachary Turnera5549172015-02-10 22:43:25 +0000731 outs().flush();
Zachary Turnerfcb14ad2015-01-27 20:46:21 +0000732}
733
734int main(int argc_, const char *argv_[]) {
735 // Print a stack trace if we signal out.
736 sys::PrintStackTraceOnErrorSignal();
737 PrettyStackTraceProgram X(argc_, argv_);
738
739 SmallVector<const char *, 256> argv;
David Majnemer6e081262015-10-15 01:27:19 +0000740 SpecificBumpPtrAllocator<char> ArgAllocator;
741 std::error_code EC = sys::Process::GetArgumentVector(
742 argv, makeArrayRef(argv_, argc_), ArgAllocator);
Zachary Turnerfcb14ad2015-01-27 20:46:21 +0000743 if (EC) {
David Majnemer6e081262015-10-15 01:27:19 +0000744 errs() << "error: couldn't get arguments: " << EC.message() << '\n';
Zachary Turnerfcb14ad2015-01-27 20:46:21 +0000745 return 1;
746 }
747
748 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
749
750 cl::ParseCommandLineOptions(argv.size(), argv.data(), "LLVM PDB Dumper\n");
Zachary Turnera99000d2016-03-08 21:42:24 +0000751 if (opts::Lines)
752 opts::Compilands = true;
753
Zachary Turner7797c722015-03-02 04:39:56 +0000754 if (opts::All) {
755 opts::Compilands = true;
756 opts::Symbols = true;
757 opts::Globals = true;
758 opts::Types = true;
Zachary Turnere5cb2692015-05-01 20:24:26 +0000759 opts::Externals = true;
Zachary Turnera99000d2016-03-08 21:42:24 +0000760 opts::Lines = true;
Zachary Turner7797c722015-03-02 04:39:56 +0000761 }
Zachary Turnera99000d2016-03-08 21:42:24 +0000762
763 // When adding filters for excluded compilands and types, we need to remember
764 // that these are regexes. So special characters such as * and \ need to be
765 // escaped in the regex. In the case of a literal \, this means it needs to
766 // be escaped again in the C++. So matching a single \ in the input requires
767 // 4 \es in the C++.
Zachary Turner7797c722015-03-02 04:39:56 +0000768 if (opts::ExcludeCompilerGenerated) {
769 opts::ExcludeTypes.push_back("__vc_attributes");
Zachary Turnera99000d2016-03-08 21:42:24 +0000770 opts::ExcludeCompilands.push_back("\\* Linker \\*");
Zachary Turner7797c722015-03-02 04:39:56 +0000771 }
772 if (opts::ExcludeSystemLibraries) {
773 opts::ExcludeCompilands.push_back(
Zachary Turnera99000d2016-03-08 21:42:24 +0000774 "f:\\\\binaries\\\\Intermediate\\\\vctools\\\\crt_bld");
775 opts::ExcludeCompilands.push_back("f:\\\\dd\\\\vctools\\\\crt");
776 opts::ExcludeCompilands.push_back("d:\\\\th.obj.x86fre\\\\minkernel");
Zachary Turner7797c722015-03-02 04:39:56 +0000777 }
Zachary Turnerfcb14ad2015-01-27 20:46:21 +0000778
Zachary Turner8d7fa9b2015-02-10 22:47:14 +0000779#if defined(HAVE_DIA_SDK)
Zachary Turnerfcb14ad2015-01-27 20:46:21 +0000780 CoInitializeEx(nullptr, COINIT_MULTITHREADED);
Zachary Turner8d7fa9b2015-02-10 22:47:14 +0000781#endif
Zachary Turnerfcb14ad2015-01-27 20:46:21 +0000782
783 std::for_each(opts::InputFilenames.begin(), opts::InputFilenames.end(),
784 dumpInput);
785
Zachary Turner8d7fa9b2015-02-10 22:47:14 +0000786#if defined(HAVE_DIA_SDK)
Zachary Turnerfcb14ad2015-01-27 20:46:21 +0000787 CoUninitialize();
Zachary Turner8d7fa9b2015-02-10 22:47:14 +0000788#endif
Zachary Turner819e77d2016-05-06 20:51:57 +0000789 outs().flush();
Zachary Turnerfcb14ad2015-01-27 20:46:21 +0000790 return 0;
791}