llvm-pdbdump.cpp revision 4c5e43da7792f75567b693105cc53e3f1992ad98
1//===- 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 16#include "llvm-pdbdump.h" 17#include "CompilandDumper.h" 18#include "FunctionDumper.h" 19#include "LinePrinter.h" 20#include "TypeDumper.h" 21#include "VariableDumper.h" 22 23#include "llvm/ADT/ArrayRef.h" 24#include "llvm/ADT/StringExtras.h" 25#include "llvm/Config/config.h" 26#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" 27#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h" 28#include "llvm/DebugInfo/PDB/IPDBSession.h" 29#include "llvm/DebugInfo/PDB/PDB.h" 30#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h" 31#include "llvm/DebugInfo/PDB/PDBSymbolData.h" 32#include "llvm/DebugInfo/PDB/PDBSymbolExe.h" 33#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" 34#include "llvm/DebugInfo/PDB/PDBSymbolThunk.h" 35#include "llvm/Support/CommandLine.h" 36#include "llvm/Support/ConvertUTF.h" 37#include "llvm/Support/FileSystem.h" 38#include "llvm/Support/Format.h" 39#include "llvm/Support/ManagedStatic.h" 40#include "llvm/Support/PrettyStackTrace.h" 41#include "llvm/Support/Process.h" 42#include "llvm/Support/raw_ostream.h" 43#include "llvm/Support/Signals.h" 44 45#if defined(HAVE_DIA_SDK) 46#include <Windows.h> 47#endif 48 49using namespace llvm; 50 51namespace opts { 52 53enum class PDB_DumpType { ByType, ByObjFile, Both }; 54 55cl::list<std::string> InputFilenames(cl::Positional, 56 cl::desc("<input PDB files>"), 57 cl::OneOrMore); 58 59cl::OptionCategory TypeCategory("Symbol Type Options"); 60cl::OptionCategory FilterCategory("Filtering Options"); 61 62cl::opt<bool> Compilands("compilands", cl::desc("Display compilands"), 63 cl::cat(TypeCategory)); 64cl::opt<bool> Symbols("symbols", cl::desc("Display symbols for each compiland"), 65 cl::cat(TypeCategory)); 66cl::opt<bool> Globals("globals", cl::desc("Dump global symbols"), 67 cl::cat(TypeCategory)); 68cl::opt<bool> Types("types", cl::desc("Display types"), cl::cat(TypeCategory)); 69cl::opt<bool> 70 All("all", cl::desc("Implies all other options in 'Symbol Types' category"), 71 cl::cat(TypeCategory)); 72 73cl::list<std::string> 74 ExcludeTypes("exclude-types", 75 cl::desc("Exclude types by regular expression"), 76 cl::ZeroOrMore, cl::cat(FilterCategory)); 77cl::list<std::string> 78 ExcludeSymbols("exclude-symbols", 79 cl::desc("Exclude symbols by regular expression"), 80 cl::ZeroOrMore, cl::cat(FilterCategory)); 81cl::list<std::string> 82 ExcludeCompilands("exclude-compilands", 83 cl::desc("Exclude compilands by regular expression"), 84 cl::ZeroOrMore, cl::cat(FilterCategory)); 85cl::opt<bool> ExcludeCompilerGenerated( 86 "no-compiler-generated", 87 cl::desc("Don't show compiler generated types and symbols"), 88 cl::cat(FilterCategory)); 89cl::opt<bool> 90 ExcludeSystemLibraries("no-system-libs", 91 cl::desc("Don't show symbols from system libraries"), 92 cl::cat(FilterCategory)); 93cl::opt<bool> NoClassDefs("no-class-definitions", 94 cl::desc("Don't display full class definitions"), 95 cl::cat(FilterCategory)); 96cl::opt<bool> NoEnumDefs("no-enum-definitions", 97 cl::desc("Don't display full enum definitions"), 98 cl::cat(FilterCategory)); 99} 100 101static void dumpInput(StringRef Path) { 102 std::unique_ptr<IPDBSession> Session; 103 PDB_ErrorCode Error = 104 llvm::createPDBReader(PDB_ReaderType::DIA, Path, Session); 105 switch (Error) { 106 case PDB_ErrorCode::Success: 107 break; 108 case PDB_ErrorCode::NoPdbImpl: 109 outs() << "Reading PDBs is not supported on this platform.\n"; 110 return; 111 case PDB_ErrorCode::InvalidPath: 112 outs() << "Unable to load PDB at '" << Path 113 << "'. Check that the file exists and is readable.\n"; 114 return; 115 case PDB_ErrorCode::InvalidFileFormat: 116 outs() << "Unable to load PDB at '" << Path 117 << "'. The file has an unrecognized format.\n"; 118 return; 119 default: 120 outs() << "Unable to load PDB at '" << Path 121 << "'. An unknown error occured.\n"; 122 return; 123 } 124 125 LinePrinter Printer(2, outs()); 126 127 auto GlobalScope(Session->getGlobalScope()); 128 std::string FileName(GlobalScope->getSymbolsFileName()); 129 130 WithColor(Printer, PDB_ColorItem::None).get() << "Summary for "; 131 WithColor(Printer, PDB_ColorItem::Path).get() << FileName; 132 Printer.Indent(); 133 uint64_t FileSize = 0; 134 135 Printer.NewLine(); 136 WithColor(Printer, PDB_ColorItem::Identifier).get() << "Size"; 137 if (!llvm::sys::fs::file_size(FileName, FileSize)) { 138 Printer << ": " << FileSize << " bytes"; 139 } else { 140 Printer << ": (Unable to obtain file size)"; 141 } 142 143 Printer.NewLine(); 144 WithColor(Printer, PDB_ColorItem::Identifier).get() << "Guid"; 145 Printer << ": " << GlobalScope->getGuid(); 146 147 Printer.NewLine(); 148 WithColor(Printer, PDB_ColorItem::Identifier).get() << "Age"; 149 Printer << ": " << GlobalScope->getAge(); 150 151 Printer.NewLine(); 152 WithColor(Printer, PDB_ColorItem::Identifier).get() << "Attributes"; 153 Printer << ": "; 154 if (GlobalScope->hasCTypes()) 155 outs() << "HasCTypes "; 156 if (GlobalScope->hasPrivateSymbols()) 157 outs() << "HasPrivateSymbols "; 158 Printer.Unindent(); 159 160 if (opts::Compilands) { 161 Printer.NewLine(); 162 WithColor(Printer, PDB_ColorItem::SectionHeader).get() 163 << "---COMPILANDS---"; 164 Printer.Indent(); 165 auto Compilands = GlobalScope->findAllChildren<PDBSymbolCompiland>(); 166 CompilandDumper Dumper(Printer); 167 while (auto Compiland = Compilands->getNext()) 168 Dumper.start(*Compiland, false); 169 Printer.Unindent(); 170 } 171 172 if (opts::Types) { 173 Printer.NewLine(); 174 WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---TYPES---"; 175 Printer.Indent(); 176 TypeDumper Dumper(Printer); 177 Dumper.start(*GlobalScope); 178 Printer.Unindent(); 179 } 180 181 if (opts::Symbols) { 182 Printer.NewLine(); 183 WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---SYMBOLS---"; 184 Printer.Indent(); 185 auto Compilands = GlobalScope->findAllChildren<PDBSymbolCompiland>(); 186 CompilandDumper Dumper(Printer); 187 while (auto Compiland = Compilands->getNext()) 188 Dumper.start(*Compiland, true); 189 Printer.Unindent(); 190 } 191 192 if (opts::Globals) { 193 Printer.NewLine(); 194 WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---GLOBALS---"; 195 Printer.Indent(); 196 { 197 FunctionDumper Dumper(Printer); 198 auto Functions = GlobalScope->findAllChildren<PDBSymbolFunc>(); 199 while (auto Function = Functions->getNext()) { 200 Printer.NewLine(); 201 Dumper.start(*Function, FunctionDumper::PointerType::None); 202 } 203 } 204 { 205 auto Vars = GlobalScope->findAllChildren<PDBSymbolData>(); 206 VariableDumper Dumper(Printer); 207 while (auto Var = Vars->getNext()) 208 Dumper.start(*Var); 209 } 210 { 211 auto Thunks = GlobalScope->findAllChildren<PDBSymbolThunk>(); 212 CompilandDumper Dumper(Printer); 213 while (auto Thunk = Thunks->getNext()) 214 Dumper.dump(*Thunk); 215 } 216 Printer.Unindent(); 217 } 218 outs().flush(); 219} 220 221int main(int argc_, const char *argv_[]) { 222 // Print a stack trace if we signal out. 223 sys::PrintStackTraceOnErrorSignal(); 224 PrettyStackTraceProgram X(argc_, argv_); 225 226 SmallVector<const char *, 256> argv; 227 llvm::SpecificBumpPtrAllocator<char> ArgAllocator; 228 std::error_code EC = llvm::sys::Process::GetArgumentVector( 229 argv, llvm::makeArrayRef(argv_, argc_), ArgAllocator); 230 if (EC) { 231 llvm::errs() << "error: couldn't get arguments: " << EC.message() << '\n'; 232 return 1; 233 } 234 235 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 236 237 cl::ParseCommandLineOptions(argv.size(), argv.data(), "LLVM PDB Dumper\n"); 238 if (opts::All) { 239 opts::Compilands = true; 240 opts::Symbols = true; 241 opts::Globals = true; 242 opts::Types = true; 243 } 244 if (opts::ExcludeCompilerGenerated) { 245 opts::ExcludeTypes.push_back("__vc_attributes"); 246 opts::ExcludeCompilands.push_back("* Linker *"); 247 } 248 if (opts::ExcludeSystemLibraries) { 249 opts::ExcludeCompilands.push_back( 250 "f:\\binaries\\Intermediate\\vctools\\crt_bld"); 251 } 252 253#if defined(HAVE_DIA_SDK) 254 CoInitializeEx(nullptr, COINIT_MULTITHREADED); 255#endif 256 257 std::for_each(opts::InputFilenames.begin(), opts::InputFilenames.end(), 258 dumpInput); 259 260#if defined(HAVE_DIA_SDK) 261 CoUninitialize(); 262#endif 263 264 return 0; 265} 266