From 994fc75000ca83f0f7d385317fad519b96bb1d1f Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Thu, 30 Jun 2016 17:42:48 +0000 Subject: [PATCH] Update llvm-pdbdump to use subcommands. llvm-svn: 274247 --- test/DebugInfo/PDB/DIA/pdbdump-flags.test | 8 +- .../PDB/DIA/pdbdump-linenumbers.test | 2 +- .../PDB/DIA/pdbdump-symbol-format.test | 8 +- test/DebugInfo/PDB/pdbdump-headers.test | 16 +- test/DebugInfo/PDB/pdbdump-yaml.test | 5 +- test/tools/llvm-pdbdump/class-layout.test | 2 +- test/tools/llvm-pdbdump/enum-layout.test | 2 +- test/tools/llvm-pdbdump/load-address.test | 4 +- test/tools/llvm-pdbdump/regex-filter.test | 16 +- tools/llvm-pdbdump/ClassDefinitionDumper.cpp | 2 +- tools/llvm-pdbdump/EnumDumper.cpp | 2 +- tools/llvm-pdbdump/LLVMOutputStyle.cpp | 110 +++- tools/llvm-pdbdump/LLVMOutputStyle.h | 32 +- tools/llvm-pdbdump/LinePrinter.cpp | 24 +- tools/llvm-pdbdump/OutputStyle.h | 15 +- tools/llvm-pdbdump/TypeDumper.cpp | 2 +- tools/llvm-pdbdump/VariableDumper.cpp | 2 +- tools/llvm-pdbdump/YAMLOutputStyle.cpp | 93 +--- tools/llvm-pdbdump/YAMLOutputStyle.h | 23 +- tools/llvm-pdbdump/llvm-pdbdump.cpp | 513 ++++++++---------- tools/llvm-pdbdump/llvm-pdbdump.h | 32 +- 21 files changed, 424 insertions(+), 489 deletions(-) diff --git a/test/DebugInfo/PDB/DIA/pdbdump-flags.test b/test/DebugInfo/PDB/DIA/pdbdump-flags.test index c2fffcb5062..9233e20ee82 100644 --- a/test/DebugInfo/PDB/DIA/pdbdump-flags.test +++ b/test/DebugInfo/PDB/DIA/pdbdump-flags.test @@ -1,7 +1,7 @@ -; RUN: llvm-pdbdump %p/../Inputs/empty.pdb | FileCheck %s -check-prefix=NO_ARGS -; RUN: llvm-pdbdump -types %p/../Inputs/empty.pdb | FileCheck %s -check-prefix=TYPES -; RUN: llvm-pdbdump -compilands %p/../Inputs/empty.pdb | FileCheck %s -check-prefix=COMPILANDS -; RUN: llvm-pdbdump -types -compilands %p/../Inputs/empty.pdb | FileCheck %s -check-prefix=MULTIPLE +; RUN: llvm-pdbdump pretty %p/../Inputs/empty.pdb | FileCheck %s -check-prefix=NO_ARGS +; RUN: llvm-pdbdump pretty -types %p/../Inputs/empty.pdb | FileCheck %s -check-prefix=TYPES +; RUN: llvm-pdbdump pretty -compilands %p/../Inputs/empty.pdb | FileCheck %s -check-prefix=COMPILANDS +; RUN: llvm-pdbdump pretty -types -compilands %p/../Inputs/empty.pdb | FileCheck %s -check-prefix=MULTIPLE ; Check that neither symbols nor compilands are dumped when neither argument specified. ; NO_ARGS: empty.pdb diff --git a/test/DebugInfo/PDB/DIA/pdbdump-linenumbers.test b/test/DebugInfo/PDB/DIA/pdbdump-linenumbers.test index 322660a62b1..780e0db8466 100644 --- a/test/DebugInfo/PDB/DIA/pdbdump-linenumbers.test +++ b/test/DebugInfo/PDB/DIA/pdbdump-linenumbers.test @@ -1,4 +1,4 @@ -; RUN: llvm-pdbdump -lines %p/../Inputs/symbolformat.pdb | FileCheck --check-prefix=LINE_NUMS %s +; RUN: llvm-pdbdump pretty -lines %p/../Inputs/symbolformat.pdb | FileCheck --check-prefix=LINE_NUMS %s ; LINE_NUMS: llvm\test\debuginfo\pdb\inputs\symbolformat-fpo.cpp ; LINE_NUMS: Line 5, Address: [0x000011a0 - 0x000011a5] (6 bytes) diff --git a/test/DebugInfo/PDB/DIA/pdbdump-symbol-format.test b/test/DebugInfo/PDB/DIA/pdbdump-symbol-format.test index 3761f789f59..e729e8bc894 100644 --- a/test/DebugInfo/PDB/DIA/pdbdump-symbol-format.test +++ b/test/DebugInfo/PDB/DIA/pdbdump-symbol-format.test @@ -1,10 +1,10 @@ -; RUN: llvm-pdbdump -symbols %p/../Inputs/symbolformat.pdb | FileCheck --check-prefix=SYM_FORMAT %s -; RUN: llvm-pdbdump -types %p/../Inputs/symbolformat.pdb > %t.types +; RUN: llvm-pdbdump pretty -symbols %p/../Inputs/symbolformat.pdb | FileCheck --check-prefix=SYM_FORMAT %s +; RUN: llvm-pdbdump pretty -types %p/../Inputs/symbolformat.pdb > %t.types ; RUN: FileCheck --check-prefix=TYPES_FORMAT %s < %t.types ; RUN: FileCheck --check-prefix=TYPES_1 %s < %t.types ; RUN: FileCheck --check-prefix=TYPES_2 %s < %t.types -; RUN: llvm-pdbdump -types %p/../Inputs/symbolformat.pdb | FileCheck --check-prefix=TYPES_FORMAT %s -; RUN: llvm-pdbdump -globals %p/../Inputs/symbolformat.pdb | FileCheck --check-prefix=GLOBALS %s +; RUN: llvm-pdbdump pretty -types %p/../Inputs/symbolformat.pdb | FileCheck --check-prefix=TYPES_FORMAT %s +; RUN: llvm-pdbdump pretty -globals %p/../Inputs/symbolformat.pdb | FileCheck --check-prefix=GLOBALS %s ; The format is func [0x+ - 0x-] ; SYM_FORMAT: ---SYMBOLS--- diff --git a/test/DebugInfo/PDB/pdbdump-headers.test b/test/DebugInfo/PDB/pdbdump-headers.test index c9c8d13eb36..6b7097368c5 100644 --- a/test/DebugInfo/PDB/pdbdump-headers.test +++ b/test/DebugInfo/PDB/pdbdump-headers.test @@ -1,12 +1,12 @@ -; RUN: llvm-pdbdump -raw-headers -raw-tpi-records -raw-tpi-record-bytes -raw-module-syms \ -; RUN: -raw-sym-record-bytes -raw-publics -raw-module-files -raw-stream-name=/names \ -; RUN: -raw-stream-summary -raw-stream-blocks -raw-ipi-records -raw-ipi-record-bytes \ -; RUN: -raw-section-contribs -raw-section-map -raw-section-headers -raw-line-info \ -; RUN: -raw-tpi-hash -raw-fpo %p/Inputs/empty.pdb | FileCheck -check-prefix=EMPTY %s -; RUN: llvm-pdbdump -raw-all %p/Inputs/empty.pdb | FileCheck -check-prefix=ALL %s -; RUN: llvm-pdbdump -raw-headers -raw-stream-name=/names -raw-modules -raw-module-files \ +; RUN: llvm-pdbdump raw -headers -tpi-records -tpi-record-bytes -module-syms \ +; RUN: -sym-record-bytes -publics -module-files -stream-name=/names \ +; RUN: -stream-summary -stream-blocks -ipi-records -ipi-record-bytes \ +; RUN: -section-contribs -section-map -section-headers -line-info \ +; RUN: -tpi-hash -fpo %p/Inputs/empty.pdb | FileCheck -check-prefix=EMPTY %s +; RUN: llvm-pdbdump raw -all %p/Inputs/empty.pdb | FileCheck -check-prefix=ALL %s +; RUN: llvm-pdbdump raw -headers -stream-name=/names -modules -module-files \ ; RUN: %p/Inputs/big-read.pdb | FileCheck -check-prefix=BIG %s -; RUN: not llvm-pdbdump -raw-headers %p/Inputs/bad-block-size.pdb 2>&1 | FileCheck -check-prefix=BAD-BLOCK-SIZE %s +; RUN: not llvm-pdbdump raw -headers %p/Inputs/bad-block-size.pdb 2>&1 | FileCheck -check-prefix=BAD-BLOCK-SIZE %s ; EMPTY: FileHeaders { ; EMPTY-NEXT: BlockSize: 4096 diff --git a/test/DebugInfo/PDB/pdbdump-yaml.test b/test/DebugInfo/PDB/pdbdump-yaml.test index 99df5dd92b1..38e1121baec 100644 --- a/test/DebugInfo/PDB/pdbdump-yaml.test +++ b/test/DebugInfo/PDB/pdbdump-yaml.test @@ -1,5 +1,4 @@ -; RUN: llvm-pdbdump -raw-headers -raw-output-style=YAML %p/Inputs/empty.pdb \ -; RUN: | FileCheck -check-prefix=YAML %s +; RUN: llvm-pdbdump pdb2yaml -stream-metadata %p/Inputs/empty.pdb | FileCheck -check-prefix=YAML %s ; YAML: --- ; YAML-NEXT: MSF: @@ -16,4 +15,4 @@ ; YAML-NEXT: - 23 ; YAML-NEXT: NumStreams: 17 ; YAML-NEXT: FileSize: 102400 -; YAML-NEXT: ... +; YAML: ... diff --git a/test/tools/llvm-pdbdump/class-layout.test b/test/tools/llvm-pdbdump/class-layout.test index a92145e59e7..d2e98de2a20 100644 --- a/test/tools/llvm-pdbdump/class-layout.test +++ b/test/tools/llvm-pdbdump/class-layout.test @@ -1,4 +1,4 @@ -; RUN: llvm-pdbdump -all %p/Inputs/ClassLayoutTest.pdb > %t +; RUN: llvm-pdbdump pretty -all %p/Inputs/ClassLayoutTest.pdb > %t ; RUN: FileCheck -input-file=%t %s -check-prefix=GLOBALS_TEST ; RUN: FileCheck -input-file=%t %s -check-prefix=MEMBERS_TEST ; RUN: FileCheck -input-file=%t %s -check-prefix=BASE_CLASS_A diff --git a/test/tools/llvm-pdbdump/enum-layout.test b/test/tools/llvm-pdbdump/enum-layout.test index f6ebb20b8c5..21e1867175f 100644 --- a/test/tools/llvm-pdbdump/enum-layout.test +++ b/test/tools/llvm-pdbdump/enum-layout.test @@ -1,4 +1,4 @@ -; RUN: llvm-pdbdump -types %p/Inputs/ClassLayoutTest.pdb > %t +; RUN: llvm-pdbdump pretty -types %p/Inputs/ClassLayoutTest.pdb > %t ; RUN: FileCheck -input-file=%t %s -check-prefix=GLOBAL_ENUM ; RUN: FileCheck -input-file=%t %s -check-prefix=MEMBER_ENUM diff --git a/test/tools/llvm-pdbdump/load-address.test b/test/tools/llvm-pdbdump/load-address.test index c559b5c7dcd..5791637d3a7 100644 --- a/test/tools/llvm-pdbdump/load-address.test +++ b/test/tools/llvm-pdbdump/load-address.test @@ -1,6 +1,6 @@ -; RUN: llvm-pdbdump -externals %p/Inputs/LoadAddressTest.pdb \ +; RUN: llvm-pdbdump pretty -externals %p/Inputs/LoadAddressTest.pdb \ ; RUN: | FileCheck --check-prefix=RVA %s -; RUN: llvm-pdbdump -externals -load-address=0x40000000 \ +; RUN: llvm-pdbdump pretty -externals -load-address=0x40000000 \ ; RUN: %p/Inputs/LoadAddressTest.pdb | FileCheck --check-prefix=VA %s ; RVA: ---EXTERNALS--- diff --git a/test/tools/llvm-pdbdump/regex-filter.test b/test/tools/llvm-pdbdump/regex-filter.test index cfc910e0717..b845f5a28cf 100644 --- a/test/tools/llvm-pdbdump/regex-filter.test +++ b/test/tools/llvm-pdbdump/regex-filter.test @@ -1,18 +1,18 @@ -; RUN: llvm-pdbdump -symbols -globals -types %p/Inputs/FilterTest.pdb \ +; RUN: llvm-pdbdump pretty -symbols -globals -types %p/Inputs/FilterTest.pdb \ ; RUN: | FileCheck --check-prefix=NO_FILTER %s -; RUN: llvm-pdbdump -types -exclude-types="GlobalTypedef|NestedTypedef" \ +; RUN: llvm-pdbdump pretty -types -exclude-types="GlobalTypedef|NestedTypedef" \ ; RUN: %p/Inputs/FilterTest.pdb | FileCheck --check-prefix=EXCLUDE_TYPEDEFS %s -; RUN: llvm-pdbdump -types -exclude-types="GlobalEnum|NestedEnum" \ +; RUN: llvm-pdbdump pretty -types -exclude-types="GlobalEnum|NestedEnum" \ ; RUN: %p/Inputs/FilterTest.pdb | FileCheck --check-prefix=EXCLUDE_ENUMS %s -; RUN: llvm-pdbdump -types -symbols -globals -exclude-symbols="MemberVar|GlobalVar" \ +; RUN: llvm-pdbdump pretty -types -symbols -globals -exclude-symbols="MemberVar|GlobalVar" \ ; RUN: %p/Inputs/FilterTest.pdb | FileCheck --check-prefix=EXCLUDE_VARS %s -; RUN: llvm-pdbdump -types -exclude-types="FilterTestClass" \ +; RUN: llvm-pdbdump pretty -types -exclude-types="FilterTestClass" \ ; RUN: %p/Inputs/FilterTest.pdb | FileCheck --check-prefix=EXCLUDE_WHOLE_CLASS %s -; RUN: llvm-pdbdump -symbols -globals -exclude-compilands="FilterTest.obj" \ +; RUN: llvm-pdbdump pretty -symbols -globals -exclude-compilands="FilterTest.obj" \ ; RUN: %p/Inputs/FilterTest.pdb | FileCheck --check-prefix=EXCLUDE_COMPILAND %s -; RUN: llvm-pdbdump -types -include-types="FilterTestClass" \ +; RUN: llvm-pdbdump pretty -types -include-types="FilterTestClass" \ ; RUN: %p/Inputs/FilterTest.pdb | FileCheck --check-prefix=INCLUDE_ONLY_TYPES %s -; RUN: llvm-pdbdump -types -symbols -globals -include-symbols="[[:<:]](IntGlobalVar|DoubleGlobalVar)[[:>:]]" \ +; RUN: llvm-pdbdump pretty -types -symbols -globals -include-symbols="[[:<:]](IntGlobalVar|DoubleGlobalVar)[[:>:]]" \ ; RUN: %p/Inputs/FilterTest.pdb | FileCheck --check-prefix=INCLUDE_ONLY_VARS %s ; NO_FILTER: ---TYPES--- diff --git a/tools/llvm-pdbdump/ClassDefinitionDumper.cpp b/tools/llvm-pdbdump/ClassDefinitionDumper.cpp index 1dfd879eb82..553bc0b267c 100644 --- a/tools/llvm-pdbdump/ClassDefinitionDumper.cpp +++ b/tools/llvm-pdbdump/ClassDefinitionDumper.cpp @@ -85,7 +85,7 @@ void ClassDefinitionDumper::start(const PDBSymbolTypeUDT &Class) { auto &AccessGroup = Groups.find((int)Access)->second; if (auto Func = dyn_cast(Child.get())) { - if (Func->isCompilerGenerated() && opts::ExcludeCompilerGenerated) + if (Func->isCompilerGenerated() && opts::pretty::ExcludeCompilerGenerated) continue; if (Func->getLength() == 0 && !Func->isPureVirtual() && !Func->isIntroVirtualFunction()) diff --git a/tools/llvm-pdbdump/EnumDumper.cpp b/tools/llvm-pdbdump/EnumDumper.cpp index 02c3df748be..43b6018ffed 100644 --- a/tools/llvm-pdbdump/EnumDumper.cpp +++ b/tools/llvm-pdbdump/EnumDumper.cpp @@ -25,7 +25,7 @@ EnumDumper::EnumDumper(LinePrinter &P) : PDBSymDumper(true), Printer(P) {} void EnumDumper::start(const PDBSymbolTypeEnum &Symbol) { WithColor(Printer, PDB_ColorItem::Keyword).get() << "enum "; WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName(); - if (!opts::NoEnumDefs) { + if (!opts::pretty::NoEnumDefs) { auto BuiltinType = Symbol.getUnderlyingType(); if (BuiltinType->getBuiltinType() != PDB_BuiltinType::Int || BuiltinType->getLength() != 4) { diff --git a/tools/llvm-pdbdump/LLVMOutputStyle.cpp b/tools/llvm-pdbdump/LLVMOutputStyle.cpp index f030fa8ca80..c24d364885d 100644 --- a/tools/llvm-pdbdump/LLVMOutputStyle.cpp +++ b/tools/llvm-pdbdump/LLVMOutputStyle.cpp @@ -41,8 +41,56 @@ static void printSectionOffset(llvm::raw_ostream &OS, LLVMOutputStyle::LLVMOutputStyle(PDBFile &File) : File(File), P(outs()), TD(&P, false) {} +Error LLVMOutputStyle::dump() { + if (auto EC = dumpFileHeaders()) + return EC; + + if (auto EC = dumpStreamSummary()) + return EC; + + if (auto EC = dumpStreamBlocks()) + return EC; + + if (auto EC = dumpStreamData()) + return EC; + + if (auto EC = dumpInfoStream()) + return EC; + + if (auto EC = dumpNamedStream()) + return EC; + + if (auto EC = dumpTpiStream(StreamTPI)) + return EC; + + if (auto EC = dumpTpiStream(StreamIPI)) + return EC; + + if (auto EC = dumpDbiStream()) + return EC; + + if (auto EC = dumpSectionContribs()) + return EC; + + if (auto EC = dumpSectionMap()) + return EC; + + if (auto EC = dumpPublicsStream()) + return EC; + + if (auto EC = dumpSectionHeaders()) + return EC; + + if (auto EC = dumpFpoStream()) + return EC; + + flush(); + + return Error::success(); +} + Error LLVMOutputStyle::dumpFileHeaders() { - if (!opts::DumpHeaders) + if (!opts::raw::DumpHeaders) return Error::success(); DictScope D(P, "FileHeaders"); @@ -64,7 +112,7 @@ Error LLVMOutputStyle::dumpFileHeaders() { } Error LLVMOutputStyle::dumpStreamSummary() { - if (!opts::DumpStreamSummary) + if (!opts::raw::DumpStreamSummary) return Error::success(); // It's OK if we fail to load some of these streams, we still attempt to print @@ -186,7 +234,7 @@ Error LLVMOutputStyle::dumpStreamSummary() { } Error LLVMOutputStyle::dumpStreamBlocks() { - if (!opts::DumpStreamBlocks) + if (!opts::raw::DumpStreamBlocks) return Error::success(); ListScope L(P, "StreamBlocks"); @@ -202,7 +250,7 @@ Error LLVMOutputStyle::dumpStreamBlocks() { Error LLVMOutputStyle::dumpStreamData() { uint32_t StreamCount = File.getNumStreams(); - StringRef DumpStreamStr = opts::DumpStreamDataIdx; + StringRef DumpStreamStr = opts::raw::DumpStreamDataIdx; uint32_t DumpStreamNum; if (DumpStreamStr.getAsInteger(/*Radix=*/0U, DumpStreamNum)) return Error::success(); @@ -228,7 +276,7 @@ Error LLVMOutputStyle::dumpStreamData() { } Error LLVMOutputStyle::dumpInfoStream() { - if (!opts::DumpHeaders) + if (!opts::raw::DumpHeaders) return Error::success(); auto IS = File.getPDBInfoStream(); if (!IS) @@ -243,20 +291,21 @@ Error LLVMOutputStyle::dumpInfoStream() { } Error LLVMOutputStyle::dumpNamedStream() { - if (opts::DumpStreamDataName.empty()) + if (opts::raw::DumpStreamDataName.empty()) return Error::success(); auto IS = File.getPDBInfoStream(); if (!IS) return IS.takeError(); - uint32_t NameStreamIndex = IS->getNamedStreamIndex(opts::DumpStreamDataName); + uint32_t NameStreamIndex = + IS->getNamedStreamIndex(opts::raw::DumpStreamDataName); if (NameStreamIndex == 0 || NameStreamIndex >= File.getNumStreams()) return make_error(raw_error_code::no_stream); if (NameStreamIndex != 0) { std::string Name("Stream '"); - Name += opts::DumpStreamDataName; + Name += opts::raw::DumpStreamDataName; Name += "'"; DictScope D(P, Name); P.printNumber("Index", NameStreamIndex); @@ -290,7 +339,7 @@ static void printTypeIndexOffset(raw_ostream &OS, } static void dumpTpiHash(ScopedPrinter &P, TpiStream &Tpi) { - if (!opts::DumpTpiHash) + if (!opts::raw::DumpTpiHash) return; DictScope DD(P, "Hash"); P.printNumber("Number of Hash Buckets", Tpi.NumHashBuckets()); @@ -311,17 +360,17 @@ Error LLVMOutputStyle::dumpTpiStream(uint32_t StreamIdx) { StringRef Label; StringRef VerLabel; if (StreamIdx == StreamTPI) { - DumpRecordBytes = opts::DumpTpiRecordBytes; - DumpRecords = opts::DumpTpiRecords; + DumpRecordBytes = opts::raw::DumpTpiRecordBytes; + DumpRecords = opts::raw::DumpTpiRecords; Label = "Type Info Stream (TPI)"; VerLabel = "TPI Version"; } else if (StreamIdx == StreamIPI) { - DumpRecordBytes = opts::DumpIpiRecordBytes; - DumpRecords = opts::DumpIpiRecords; + DumpRecordBytes = opts::raw::DumpIpiRecordBytes; + DumpRecords = opts::raw::DumpIpiRecords; Label = "Type Info Stream (IPI)"; VerLabel = "IPI Version"; } - if (!DumpRecordBytes && !DumpRecords && !opts::DumpModuleSyms) + if (!DumpRecordBytes && !DumpRecords && !opts::raw::DumpModuleSyms) return Error::success(); auto Tpi = (StreamIdx == StreamTPI) ? File.getPDBTpiStream() @@ -353,7 +402,7 @@ Error LLVMOutputStyle::dumpTpiStream(uint32_t StreamIdx) { if (HadError) return make_error(raw_error_code::corrupt_file, "TPI stream contained corrupt record"); - } else if (opts::DumpModuleSyms) { + } else if (opts::raw::DumpModuleSyms) { // Even if the user doesn't want to dump type records, we still need to // iterate them in order to build the list of types so that we can print // them when dumping module symbols. So when they want to dump symbols @@ -378,9 +427,9 @@ Error LLVMOutputStyle::dumpTpiStream(uint32_t StreamIdx) { } Error LLVMOutputStyle::dumpDbiStream() { - bool DumpModules = opts::DumpModules || opts::DumpModuleSyms || - opts::DumpModuleFiles || opts::DumpLineInfo; - if (!opts::DumpHeaders && !DumpModules) + bool DumpModules = opts::raw::DumpModules || opts::raw::DumpModuleSyms || + opts::raw::DumpModuleFiles || opts::raw::DumpLineInfo; + if (!opts::raw::DumpHeaders && !DumpModules) return Error::success(); auto DS = File.getPDBDbiStream(); @@ -424,7 +473,7 @@ Error LLVMOutputStyle::dumpDbiStream() { P.printNumber("Symbol Byte Size", Modi.Info.getSymbolDebugInfoByteSize()); P.printNumber("Type Server Index", Modi.Info.getTypeServerIndex()); P.printBoolean("Has EC Info", Modi.Info.hasECInfo()); - if (opts::DumpModuleFiles) { + if (opts::raw::DumpModuleFiles) { std::string FileListName = to_string(Modi.SourceFiles.size()) + " Contributing Source Files"; ListScope LL(P, FileListName); @@ -434,8 +483,8 @@ Error LLVMOutputStyle::dumpDbiStream() { bool HasModuleDI = (Modi.Info.getModuleStreamIndex() < File.getNumStreams()); bool ShouldDumpSymbols = - (opts::DumpModuleSyms || opts::DumpSymRecordBytes); - if (HasModuleDI && (ShouldDumpSymbols || opts::DumpLineInfo)) { + (opts::raw::DumpModuleSyms || opts::raw::DumpSymRecordBytes); + if (HasModuleDI && (ShouldDumpSymbols || opts::raw::DumpLineInfo)) { auto ModStreamData = MappedBlockStream::createIndexedStream( Modi.Info.getModuleStreamIndex(), File); if (!ModStreamData) @@ -451,9 +500,9 @@ Error LLVMOutputStyle::dumpDbiStream() { for (const auto &S : ModS.symbols(&HadError)) { DictScope DD(P, ""); - if (opts::DumpModuleSyms) + if (opts::raw::DumpModuleSyms) SD.dump(S); - if (opts::DumpSymRecordBytes) + if (opts::raw::DumpSymRecordBytes) P.printBinaryBlock("Bytes", S.Data); } if (HadError) @@ -461,7 +510,7 @@ Error LLVMOutputStyle::dumpDbiStream() { raw_error_code::corrupt_file, "DBI stream contained corrupt symbol record"); } - if (opts::DumpLineInfo) { + if (opts::raw::DumpLineInfo) { ListScope SS(P, "LineInfo"); bool HadError = false; // Define a locally scoped visitor to print the different @@ -561,7 +610,7 @@ Error LLVMOutputStyle::dumpDbiStream() { } Error LLVMOutputStyle::dumpSectionContribs() { - if (!opts::DumpSectionContribs) + if (!opts::raw::DumpSectionContribs) return Error::success(); auto Dbi = File.getPDBDbiStream(); @@ -608,7 +657,7 @@ Error LLVMOutputStyle::dumpSectionContribs() { } Error LLVMOutputStyle::dumpSectionMap() { - if (!opts::DumpSectionMap) + if (!opts::raw::DumpSectionMap) return Error::success(); auto Dbi = File.getPDBDbiStream(); @@ -633,7 +682,7 @@ Error LLVMOutputStyle::dumpSectionMap() { } Error LLVMOutputStyle::dumpPublicsStream() { - if (!opts::DumpPublics) + if (!opts::raw::DumpPublics) return Error::success(); DictScope D(P, "Publics Stream"); @@ -661,7 +710,7 @@ Error LLVMOutputStyle::dumpPublicsStream() { DictScope DD(P, ""); SD.dump(S); - if (opts::DumpSymRecordBytes) + if (opts::raw::DumpSymRecordBytes) P.printBinaryBlock("Bytes", S.Data); } if (HadError) @@ -673,7 +722,7 @@ Error LLVMOutputStyle::dumpPublicsStream() { } Error LLVMOutputStyle::dumpSectionHeaders() { - if (!opts::DumpSectionHeaders) + if (!opts::raw::DumpSectionHeaders) return Error::success(); auto Dbi = File.getPDBDbiStream(); @@ -702,7 +751,7 @@ Error LLVMOutputStyle::dumpSectionHeaders() { } Error LLVMOutputStyle::dumpFpoStream() { - if (!opts::DumpFpo) + if (!opts::raw::DumpFpo) return Error::success(); auto Dbi = File.getPDBDbiStream(); @@ -724,4 +773,5 @@ Error LLVMOutputStyle::dumpFpoStream() { } return Error::success(); } + void LLVMOutputStyle::flush() { P.flush(); } diff --git a/tools/llvm-pdbdump/LLVMOutputStyle.h b/tools/llvm-pdbdump/LLVMOutputStyle.h index 9fcfb6e986e..77935d10220 100644 --- a/tools/llvm-pdbdump/LLVMOutputStyle.h +++ b/tools/llvm-pdbdump/LLVMOutputStyle.h @@ -21,23 +21,25 @@ class LLVMOutputStyle : public OutputStyle { public: LLVMOutputStyle(PDBFile &File); - Error dumpFileHeaders() override; - Error dumpStreamSummary() override; - Error dumpStreamBlocks() override; - Error dumpStreamData() override; - Error dumpInfoStream() override; - Error dumpNamedStream() override; - Error dumpTpiStream(uint32_t StreamIdx) override; - Error dumpDbiStream() override; - Error dumpSectionContribs() override; - Error dumpSectionMap() override; - Error dumpPublicsStream() override; - Error dumpSectionHeaders() override; - Error dumpFpoStream() override; - - void flush() override; + Error dump() override; private: + Error dumpFileHeaders(); + Error dumpStreamSummary(); + Error dumpStreamBlocks(); + Error dumpStreamData(); + Error dumpInfoStream(); + Error dumpNamedStream(); + Error dumpTpiStream(uint32_t StreamIdx); + Error dumpDbiStream(); + Error dumpSectionContribs(); + Error dumpSectionMap(); + Error dumpPublicsStream(); + Error dumpSectionHeaders(); + Error dumpFpoStream(); + + void flush(); + PDBFile &File; ScopedPrinter P; codeview::CVTypeDumper TD; diff --git a/tools/llvm-pdbdump/LinePrinter.cpp b/tools/llvm-pdbdump/LinePrinter.cpp index db1180902cc..47c7d3e3c0e 100644 --- a/tools/llvm-pdbdump/LinePrinter.cpp +++ b/tools/llvm-pdbdump/LinePrinter.cpp @@ -44,19 +44,19 @@ using namespace llvm; LinePrinter::LinePrinter(int Indent, llvm::raw_ostream &Stream) : OS(Stream), IndentSpaces(Indent), CurrentIndent(0) { - SetFilters(ExcludeTypeFilters, opts::ExcludeTypes.begin(), - opts::ExcludeTypes.end()); - SetFilters(ExcludeSymbolFilters, opts::ExcludeSymbols.begin(), - opts::ExcludeSymbols.end()); - SetFilters(ExcludeCompilandFilters, opts::ExcludeCompilands.begin(), - opts::ExcludeCompilands.end()); + SetFilters(ExcludeTypeFilters, opts::pretty::ExcludeTypes.begin(), + opts::pretty::ExcludeTypes.end()); + SetFilters(ExcludeSymbolFilters, opts::pretty::ExcludeSymbols.begin(), + opts::pretty::ExcludeSymbols.end()); + SetFilters(ExcludeCompilandFilters, opts::pretty::ExcludeCompilands.begin(), + opts::pretty::ExcludeCompilands.end()); - SetFilters(IncludeTypeFilters, opts::IncludeTypes.begin(), - opts::IncludeTypes.end()); - SetFilters(IncludeSymbolFilters, opts::IncludeSymbols.begin(), - opts::IncludeSymbols.end()); - SetFilters(IncludeCompilandFilters, opts::IncludeCompilands.begin(), - opts::IncludeCompilands.end()); + SetFilters(IncludeTypeFilters, opts::pretty::IncludeTypes.begin(), + opts::pretty::IncludeTypes.end()); + SetFilters(IncludeSymbolFilters, opts::pretty::IncludeSymbols.begin(), + opts::pretty::IncludeSymbols.end()); + SetFilters(IncludeCompilandFilters, opts::pretty::IncludeCompilands.begin(), + opts::pretty::IncludeCompilands.end()); } void LinePrinter::Indent() { CurrentIndent += IndentSpaces; } diff --git a/tools/llvm-pdbdump/OutputStyle.h b/tools/llvm-pdbdump/OutputStyle.h index 34dd0965b89..dfefc25a215 100644 --- a/tools/llvm-pdbdump/OutputStyle.h +++ b/tools/llvm-pdbdump/OutputStyle.h @@ -19,21 +19,8 @@ class PDBFile; class OutputStyle { public: virtual ~OutputStyle() {} - virtual Error dumpFileHeaders() = 0; - virtual Error dumpStreamSummary() = 0; - virtual Error dumpStreamBlocks() = 0; - virtual Error dumpStreamData() = 0; - virtual Error dumpInfoStream() = 0; - virtual Error dumpNamedStream() = 0; - virtual Error dumpTpiStream(uint32_t StreamIdx) = 0; - virtual Error dumpDbiStream() = 0; - virtual Error dumpSectionContribs() = 0; - virtual Error dumpSectionMap() = 0; - virtual Error dumpPublicsStream() = 0; - virtual Error dumpSectionHeaders() = 0; - virtual Error dumpFpoStream() = 0; - virtual void flush() = 0; + virtual Error dump() = 0; }; } } diff --git a/tools/llvm-pdbdump/TypeDumper.cpp b/tools/llvm-pdbdump/TypeDumper.cpp index f6ec9637cf3..a49d6404555 100644 --- a/tools/llvm-pdbdump/TypeDumper.cpp +++ b/tools/llvm-pdbdump/TypeDumper.cpp @@ -88,7 +88,7 @@ void TypeDumper::dump(const PDBSymbolTypeUDT &Symbol) { Printer.NewLine(); - if (opts::NoClassDefs) { + if (opts::pretty::NoClassDefs) { WithColor(Printer, PDB_ColorItem::Keyword).get() << "class "; WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName(); } else { diff --git a/tools/llvm-pdbdump/VariableDumper.cpp b/tools/llvm-pdbdump/VariableDumper.cpp index d8b66a6737c..284d7e9b731 100644 --- a/tools/llvm-pdbdump/VariableDumper.cpp +++ b/tools/llvm-pdbdump/VariableDumper.cpp @@ -33,7 +33,7 @@ VariableDumper::VariableDumper(LinePrinter &P) : PDBSymDumper(true), Printer(P) {} void VariableDumper::start(const PDBSymbolData &Var) { - if (Var.isCompilerGenerated() && opts::ExcludeCompilerGenerated) + if (Var.isCompilerGenerated() && opts::pretty::ExcludeCompilerGenerated) return; if (Printer.IsSymbolExcluded(Var.getName())) return; diff --git a/tools/llvm-pdbdump/YAMLOutputStyle.cpp b/tools/llvm-pdbdump/YAMLOutputStyle.cpp index a0cabb7a366..cf386bf5486 100644 --- a/tools/llvm-pdbdump/YAMLOutputStyle.cpp +++ b/tools/llvm-pdbdump/YAMLOutputStyle.cpp @@ -12,6 +12,7 @@ #include "PdbYaml.h" #include "llvm-pdbdump.h" +#include "llvm/DebugInfo/PDB/Raw/RawConstants.h" #include "llvm/DebugInfo/PDB/Raw/PDBFile.h" using namespace llvm; @@ -19,10 +20,21 @@ using namespace llvm::pdb; YAMLOutputStyle::YAMLOutputStyle(PDBFile &File) : File(File), Out(outs()) {} -Error YAMLOutputStyle::dumpFileHeaders() { - if (!opts::DumpHeaders) - return Error::success(); +Error YAMLOutputStyle::dump() { + if (auto EC = dumpFileHeaders()) + return EC; + if (auto EC = dumpStreamMetadata()) + return EC; + + if (auto EC = dumpStreamDirectory()) + return EC; + + flush(); + return Error::success(); +} + +Error YAMLOutputStyle::dumpFileHeaders() { yaml::MsfHeaders Headers; Obj.Headers.SuperBlock.NumBlocks = File.getBlockCount(); Obj.Headers.SuperBlock.BlockMapAddr = File.getBlockMapIndex(); @@ -32,7 +44,7 @@ Error YAMLOutputStyle::dumpFileHeaders() { Obj.Headers.DirectoryBlocks.assign(Blocks.begin(), Blocks.end()); Obj.Headers.NumDirectoryBlocks = File.getNumDirectoryBlocks(); Obj.Headers.SuperBlock.NumDirectoryBytes = File.getNumDirectoryBytes(); - Obj.Headers.NumStreams = File.getNumStreams(); + Obj.Headers.NumStreams = opts::pdb2yaml::StreamMetadata ? File.getNumStreams() : 0; Obj.Headers.SuperBlock.Unknown0 = File.getUnknown0(); Obj.Headers.SuperBlock.Unknown1 = File.getUnknown1(); Obj.Headers.FileSize = File.getFileSize(); @@ -40,16 +52,16 @@ Error YAMLOutputStyle::dumpFileHeaders() { return Error::success(); } -Error YAMLOutputStyle::dumpStreamSummary() { - if (!opts::DumpStreamSummary) +Error YAMLOutputStyle::dumpStreamMetadata() { + if (!opts::pdb2yaml::StreamMetadata) return Error::success(); Obj.StreamSizes = File.getStreamSizes(); return Error::success(); } -Error YAMLOutputStyle::dumpStreamBlocks() { - if (!opts::DumpStreamBlocks) +Error YAMLOutputStyle::dumpStreamDirectory() { + if (!opts::pdb2yaml::StreamDirectory) return Error::success(); auto StreamMap = File.getStreamMap(); @@ -63,71 +75,6 @@ Error YAMLOutputStyle::dumpStreamBlocks() { return Error::success(); } -Error YAMLOutputStyle::dumpStreamData() { - uint32_t StreamCount = File.getNumStreams(); - StringRef DumpStreamStr = opts::DumpStreamDataIdx; - uint32_t DumpStreamNum; - if (DumpStreamStr.getAsInteger(/*Radix=*/0U, DumpStreamNum) || - DumpStreamNum >= StreamCount) - return Error::success(); - - return Error::success(); -} - -Error YAMLOutputStyle::dumpInfoStream() { - if (!opts::DumpHeaders) - return Error::success(); - return Error::success(); -} - -Error YAMLOutputStyle::dumpNamedStream() { - if (opts::DumpStreamDataName.empty()) - return Error::success(); - - return Error::success(); -} - -Error YAMLOutputStyle::dumpTpiStream(uint32_t StreamIdx) { - return Error::success(); -} - -Error YAMLOutputStyle::dumpDbiStream() { return Error::success(); } - -Error YAMLOutputStyle::dumpSectionContribs() { - if (!opts::DumpSectionContribs) - return Error::success(); - - return Error::success(); -} - -Error YAMLOutputStyle::dumpSectionMap() { - if (!opts::DumpSectionMap) - return Error::success(); - - return Error::success(); -} - -Error YAMLOutputStyle::dumpPublicsStream() { - if (!opts::DumpPublics) - return Error::success(); - - return Error::success(); -} - -Error YAMLOutputStyle::dumpSectionHeaders() { - if (!opts::DumpSectionHeaders) - return Error::success(); - - return Error::success(); -} - -Error YAMLOutputStyle::dumpFpoStream() { - if (!opts::DumpFpo) - return Error::success(); - - return Error::success(); -} - void YAMLOutputStyle::flush() { Out << Obj; outs().flush(); diff --git a/tools/llvm-pdbdump/YAMLOutputStyle.h b/tools/llvm-pdbdump/YAMLOutputStyle.h index cbd1817773c..a2c208d03f1 100644 --- a/tools/llvm-pdbdump/YAMLOutputStyle.h +++ b/tools/llvm-pdbdump/YAMLOutputStyle.h @@ -23,23 +23,16 @@ class YAMLOutputStyle : public OutputStyle { public: YAMLOutputStyle(PDBFile &File); - Error dumpFileHeaders() override; - Error dumpStreamSummary() override; - Error dumpStreamBlocks() override; - Error dumpStreamData() override; - Error dumpInfoStream() override; - Error dumpNamedStream() override; - Error dumpTpiStream(uint32_t StreamIdx) override; - Error dumpDbiStream() override; - Error dumpSectionContribs() override; - Error dumpSectionMap() override; - Error dumpPublicsStream() override; - Error dumpSectionHeaders() override; - Error dumpFpoStream() override; - - void flush() override; + Error dump() override; private: + + Error dumpFileHeaders(); + Error dumpStreamMetadata(); + Error dumpStreamDirectory(); + + void flush(); + PDBFile &File; llvm::yaml::Output Out; diff --git a/tools/llvm-pdbdump/llvm-pdbdump.cpp b/tools/llvm-pdbdump/llvm-pdbdump.cpp index a7d43ed064c..a92e59bc811 100644 --- a/tools/llvm-pdbdump/llvm-pdbdump.cpp +++ b/tools/llvm-pdbdump/llvm-pdbdump.cpp @@ -79,259 +79,194 @@ private: namespace opts { -enum class PDB_DumpType { ByType, ByObjFile, Both }; - -cl::list InputFilenames(cl::Positional, - cl::desc(""), - cl::OneOrMore); +cl::SubCommand RawSubcommand("raw", "Dump raw structure of the PDB file"); +cl::SubCommand + PrettySubcommand("pretty", + "Dump semantic information about types and symbols"); +cl::SubCommand YamlToPdbSubcommand("yaml2pdb", "Generate a PDB file from a YAML description"); +cl::SubCommand + PdbToYamlSubcommand("pdb2yaml", + "Generate a detailed YAML description of a PDB File"); cl::OptionCategory TypeCategory("Symbol Type Options"); cl::OptionCategory FilterCategory("Filtering Options"); cl::OptionCategory OtherOptions("Other Options"); -cl::OptionCategory NativeOptions("Native Options"); + +namespace pretty { +cl::list InputFilenames(cl::Positional, + cl::desc(""), + cl::OneOrMore, cl::sub(PrettySubcommand)); cl::opt Compilands("compilands", cl::desc("Display compilands"), - cl::cat(TypeCategory)); + cl::cat(TypeCategory), cl::sub(PrettySubcommand)); cl::opt Symbols("symbols", cl::desc("Display symbols for each compiland"), - cl::cat(TypeCategory)); + cl::cat(TypeCategory), cl::sub(PrettySubcommand)); cl::opt Globals("globals", cl::desc("Dump global symbols"), - cl::cat(TypeCategory)); + cl::cat(TypeCategory), cl::sub(PrettySubcommand)); cl::opt Externals("externals", cl::desc("Dump external symbols"), - cl::cat(TypeCategory)); -cl::opt Types("types", cl::desc("Display types"), cl::cat(TypeCategory)); -cl::opt Lines("lines", cl::desc("Line tables"), cl::cat(TypeCategory)); + cl::cat(TypeCategory), cl::sub(PrettySubcommand)); +cl::opt Types("types", cl::desc("Display types"), cl::cat(TypeCategory), + cl::sub(PrettySubcommand)); +cl::opt Lines("lines", cl::desc("Line tables"), cl::cat(TypeCategory), + cl::sub(PrettySubcommand)); cl::opt All("all", cl::desc("Implies all other options in 'Symbol Types' category"), - cl::cat(TypeCategory)); + cl::cat(TypeCategory), cl::sub(PrettySubcommand)); cl::opt LoadAddress( "load-address", cl::desc("Assume the module is loaded at the specified address"), - cl::cat(OtherOptions)); - -cl::opt - RawOutputStyle("raw-output-style", cl::desc("Specify dump outpout style"), - cl::values(clEnumVal(LLVM, "LLVM default style"), - clEnumVal(YAML, "YAML style"), clEnumValEnd), - cl::init(LLVM), cl::cat(NativeOptions)); - -cl::opt DumpHeaders("raw-headers", cl::desc("dump PDB headers"), - cl::cat(NativeOptions)); -cl::opt DumpStreamBlocks("raw-stream-blocks", - cl::desc("dump PDB stream blocks"), - cl::cat(NativeOptions)); -cl::opt DumpStreamSummary("raw-stream-summary", - cl::desc("dump summary of the PDB streams"), - cl::cat(NativeOptions)); -cl::opt - DumpTpiRecords("raw-tpi-records", - cl::desc("dump CodeView type records from TPI stream"), - cl::cat(NativeOptions)); -cl::opt DumpTpiRecordBytes( - "raw-tpi-record-bytes", - cl::desc("dump CodeView type record raw bytes from TPI stream"), - cl::cat(NativeOptions)); -cl::opt DumpTpiHash("raw-tpi-hash", - cl::desc("dump CodeView TPI hash stream"), - cl::cat(NativeOptions)); -cl::opt - DumpIpiRecords("raw-ipi-records", - cl::desc("dump CodeView type records from IPI stream"), - cl::cat(NativeOptions)); -cl::opt DumpIpiRecordBytes( - "raw-ipi-record-bytes", - cl::desc("dump CodeView type record raw bytes from IPI stream"), - cl::cat(NativeOptions)); -cl::opt DumpStreamDataIdx("raw-stream", - cl::desc("dump stream data"), - cl::cat(NativeOptions)); -cl::opt DumpStreamDataName("raw-stream-name", - cl::desc("dump stream data"), - cl::cat(NativeOptions)); -cl::opt DumpModules("raw-modules", cl::desc("dump compiland information"), - cl::cat(NativeOptions)); -cl::opt DumpModuleFiles("raw-module-files", - cl::desc("dump file information"), - cl::cat(NativeOptions)); -cl::opt DumpModuleSyms("raw-module-syms", cl::desc("dump module symbols"), - cl::cat(NativeOptions)); -cl::opt DumpPublics("raw-publics", cl::desc("dump Publics stream data"), - cl::cat(NativeOptions)); -cl::opt DumpSectionContribs("raw-section-contribs", - cl::desc("dump section contributions"), - cl::cat(NativeOptions)); -cl::opt DumpLineInfo("raw-line-info", - cl::desc("dump file and line information"), - cl::cat(NativeOptions)); -cl::opt DumpSectionMap("raw-section-map", cl::desc("dump section map"), - cl::cat(NativeOptions)); -cl::opt - DumpSymRecordBytes("raw-sym-record-bytes", - cl::desc("dump CodeView symbol record raw bytes"), - cl::cat(NativeOptions)); -cl::opt DumpSectionHeaders("raw-section-headers", - cl::desc("dump section headers"), - cl::cat(NativeOptions)); -cl::opt DumpFpo("raw-fpo", cl::desc("dump FPO records"), - cl::cat(NativeOptions)); - -cl::opt - RawAll("raw-all", - cl::desc("Implies most other options in 'Native Options' category"), - cl::cat(NativeOptions)); - -cl::opt - YamlToPdb("yaml-to-pdb", - cl::desc("The input file is yaml, and the tool outputs a pdb"), - cl::cat(NativeOptions)); -cl::opt YamlPdbOutputFile( - "pdb-output", cl::desc("When yaml-to-pdb is specified, the output file"), - cl::cat(NativeOptions)); - -cl::list - ExcludeTypes("exclude-types", - cl::desc("Exclude types by regular expression"), - cl::ZeroOrMore, cl::cat(FilterCategory)); -cl::list - ExcludeSymbols("exclude-symbols", - cl::desc("Exclude symbols by regular expression"), - cl::ZeroOrMore, cl::cat(FilterCategory)); -cl::list - ExcludeCompilands("exclude-compilands", - cl::desc("Exclude compilands by regular expression"), - cl::ZeroOrMore, cl::cat(FilterCategory)); + cl::cat(OtherOptions), cl::sub(PrettySubcommand)); +cl::list ExcludeTypes( + "exclude-types", cl::desc("Exclude types by regular expression"), + cl::ZeroOrMore, cl::cat(FilterCategory), cl::sub(PrettySubcommand)); +cl::list ExcludeSymbols( + "exclude-symbols", cl::desc("Exclude symbols by regular expression"), + cl::ZeroOrMore, cl::cat(FilterCategory), cl::sub(PrettySubcommand)); +cl::list ExcludeCompilands( + "exclude-compilands", cl::desc("Exclude compilands by regular expression"), + cl::ZeroOrMore, cl::cat(FilterCategory), cl::sub(PrettySubcommand)); cl::list IncludeTypes( "include-types", cl::desc("Include only types which match a regular expression"), - cl::ZeroOrMore, cl::cat(FilterCategory)); + cl::ZeroOrMore, cl::cat(FilterCategory), cl::sub(PrettySubcommand)); cl::list IncludeSymbols( "include-symbols", cl::desc("Include only symbols which match a regular expression"), - cl::ZeroOrMore, cl::cat(FilterCategory)); + cl::ZeroOrMore, cl::cat(FilterCategory), cl::sub(PrettySubcommand)); cl::list IncludeCompilands( "include-compilands", cl::desc("Include only compilands those which match a regular expression"), - cl::ZeroOrMore, cl::cat(FilterCategory)); + cl::ZeroOrMore, cl::cat(FilterCategory), cl::sub(PrettySubcommand)); cl::opt ExcludeCompilerGenerated( "no-compiler-generated", cl::desc("Don't show compiler generated types and symbols"), - cl::cat(FilterCategory)); + cl::cat(FilterCategory), cl::sub(PrettySubcommand)); cl::opt ExcludeSystemLibraries("no-system-libs", cl::desc("Don't show symbols from system libraries"), - cl::cat(FilterCategory)); + cl::cat(FilterCategory), cl::sub(PrettySubcommand)); cl::opt NoClassDefs("no-class-definitions", cl::desc("Don't display full class definitions"), - cl::cat(FilterCategory)); + cl::cat(FilterCategory), cl::sub(PrettySubcommand)); cl::opt NoEnumDefs("no-enum-definitions", cl::desc("Don't display full enum definitions"), - cl::cat(FilterCategory)); + cl::cat(FilterCategory), cl::sub(PrettySubcommand)); +} + +namespace raw { + +cl::OptionCategory MsfOptions("MSF Container Options"); +cl::OptionCategory TypeOptions("Type Record Options"); +cl::OptionCategory FileOptions("Module & File Options"); +cl::OptionCategory SymbolOptions("Symbol Options"); +cl::OptionCategory MiscOptions("Miscellaneous Options"); + +// MSF OPTIONS +cl::opt DumpHeaders("headers", cl::desc("dump PDB headers"), + cl::cat(MsfOptions), cl::sub(RawSubcommand)); +cl::opt DumpStreamBlocks("stream-blocks", + cl::desc("dump PDB stream blocks"), + cl::cat(MsfOptions), cl::sub(RawSubcommand)); +cl::opt DumpStreamSummary("stream-summary", + cl::desc("dump summary of the PDB streams"), + cl::cat(MsfOptions), cl::sub(RawSubcommand)); + +// TYPE OPTIONS +cl::opt + DumpTpiRecords("tpi-records", + cl::desc("dump CodeView type records from TPI stream"), + cl::cat(TypeOptions), cl::sub(RawSubcommand)); +cl::opt DumpTpiRecordBytes( + "tpi-record-bytes", + cl::desc("dump CodeView type record raw bytes from TPI stream"), + cl::cat(TypeOptions), cl::sub(RawSubcommand)); +cl::opt DumpTpiHash("tpi-hash", cl::desc("dump CodeView TPI hash stream"), + cl::cat(TypeOptions), cl::sub(RawSubcommand)); +cl::opt + DumpIpiRecords("ipi-records", + cl::desc("dump CodeView type records from IPI stream"), + cl::cat(TypeOptions), cl::sub(RawSubcommand)); +cl::opt DumpIpiRecordBytes( + "ipi-record-bytes", + cl::desc("dump CodeView type record raw bytes from IPI stream"), + cl::cat(TypeOptions), cl::sub(RawSubcommand)); + +// MODULE & FILE OPTIONS +cl::opt DumpModules("modules", cl::desc("dump compiland information"), + cl::cat(FileOptions), cl::sub(RawSubcommand)); +cl::opt DumpModuleFiles("module-files", cl::desc("dump file information"), + cl::cat(FileOptions), cl::sub(RawSubcommand)); +cl::opt DumpLineInfo("line-info", + cl::desc("dump file and line information"), + cl::cat(FileOptions), cl::sub(RawSubcommand)); + +// SYMBOL OPTIONS +cl::opt DumpModuleSyms("module-syms", cl::desc("dump module symbols"), + cl::cat(SymbolOptions), cl::sub(RawSubcommand)); +cl::opt DumpPublics("publics", cl::desc("dump Publics stream data"), + cl::cat(SymbolOptions), cl::sub(RawSubcommand)); +cl::opt + DumpSymRecordBytes("sym-record-bytes", + cl::desc("dump CodeView symbol record raw bytes"), + cl::cat(SymbolOptions), cl::sub(RawSubcommand)); + +// MISCELLANEOUS OPTIONS +cl::opt DumpSectionContribs("section-contribs", + cl::desc("dump section contributions"), + cl::cat(MiscOptions), + cl::sub(RawSubcommand)); +cl::opt DumpSectionMap("section-map", cl::desc("dump section map"), + cl::cat(MiscOptions), cl::sub(RawSubcommand)); +cl::opt DumpSectionHeaders("section-headers", + cl::desc("dump section headers"), + cl::cat(MiscOptions), + cl::sub(RawSubcommand)); +cl::opt DumpFpo("fpo", cl::desc("dump FPO records"), + cl::cat(MiscOptions), cl::sub(RawSubcommand)); + +cl::opt DumpStreamDataIdx("stream", cl::desc("dump stream data"), + cl::cat(MiscOptions), + cl::sub(RawSubcommand)); +cl::opt DumpStreamDataName("stream-name", + cl::desc("dump stream data"), + cl::cat(MiscOptions), + cl::sub(RawSubcommand)); + +cl::opt + RawAll("all", + cl::desc("Implies most other options."), + cl::cat(MiscOptions), cl::sub(RawSubcommand)); + +cl::list InputFilenames(cl::Positional, + cl::desc(""), + cl::OneOrMore, cl::sub(RawSubcommand)); +} + +namespace yaml2pdb { +cl::opt + YamlPdbOutputFile("pdb", cl::desc("the name of the PDB file to write"), + cl::sub(YamlToPdbSubcommand)); + +cl::list InputFilename(cl::Positional, + cl::desc(""), cl::Required, + cl::sub(YamlToPdbSubcommand)); +} + +namespace pdb2yaml { + cl::opt StreamMetadata("stream-metadata", cl::desc("Dump the number of streams and each stream's size"), cl::sub(PdbToYamlSubcommand)); + cl::opt StreamDirectory("stream-directory", cl::desc("Dump each stream's block map (implies -stream-metadata)"), cl::sub(PdbToYamlSubcommand)); + +cl::list InputFilename(cl::Positional, + cl::desc(""), cl::Required, + cl::sub(PdbToYamlSubcommand)); +} } static ExitOnError ExitOnErr; -static Error dumpStructure(RawSession &RS) { - PDBFile &File = RS.getPDBFile(); - std::unique_ptr O; - if (opts::RawOutputStyle == opts::OutputStyleTy::LLVM) - O = llvm::make_unique(File); - else if (opts::RawOutputStyle == opts::OutputStyleTy::YAML) - O = llvm::make_unique(File); - else - return make_error(raw_error_code::feature_unsupported, - "Requested output style unsupported"); - - if (auto EC = O->dumpFileHeaders()) - return EC; - - if (auto EC = O->dumpStreamSummary()) - return EC; - - if (auto EC = O->dumpStreamBlocks()) - return EC; - - if (auto EC = O->dumpStreamData()) - return EC; - - if (auto EC = O->dumpInfoStream()) - return EC; - - if (auto EC = O->dumpNamedStream()) - return EC; - - if (auto EC = O->dumpTpiStream(StreamTPI)) - return EC; - - if (auto EC = O->dumpTpiStream(StreamIPI)) - return EC; - - if (auto EC = O->dumpDbiStream()) - return EC; - - if (auto EC = O->dumpSectionContribs()) - return EC; - - if (auto EC = O->dumpSectionMap()) - return EC; - - if (auto EC = O->dumpPublicsStream()) - return EC; - - if (auto EC = O->dumpSectionHeaders()) - return EC; - - if (auto EC = O->dumpFpoStream()) - return EC; - O->flush(); - return Error::success(); -} - -bool isRawDumpEnabled() { - if (opts::DumpHeaders) - return true; - if (opts::DumpModules) - return true; - if (opts::DumpModuleFiles) - return true; - if (opts::DumpModuleSyms) - return true; - if (!opts::DumpStreamDataIdx.empty()) - return true; - if (!opts::DumpStreamDataName.empty()) - return true; - if (opts::DumpPublics) - return true; - if (opts::DumpStreamSummary) - return true; - if (opts::DumpStreamBlocks) - return true; - if (opts::DumpSymRecordBytes) - return true; - if (opts::DumpTpiRecordBytes) - return true; - if (opts::DumpTpiRecords) - return true; - if (opts::DumpTpiHash) - return true; - if (opts::DumpIpiRecords) - return true; - if (opts::DumpIpiRecordBytes) - return true; - if (opts::DumpSectionHeaders) - return true; - if (opts::DumpSectionContribs) - return true; - if (opts::DumpSectionMap) - return true; - if (opts::DumpLineInfo) - return true; - if (opts::DumpFpo) - return true; - return false; -} - static void yamlToPdb(StringRef Path) { ErrorOr> ErrorOrBuffer = MemoryBuffer::getFileOrSTDIN(Path, /*FileSize=*/-1, @@ -347,11 +282,11 @@ static void yamlToPdb(StringRef Path) { pdb::yaml::PdbObject YamlObj; In >> YamlObj; - auto OutFileOrError = FileOutputBuffer::create(opts::YamlPdbOutputFile, - YamlObj.Headers.FileSize); + auto OutFileOrError = FileOutputBuffer::create( + opts::yaml2pdb::YamlPdbOutputFile, YamlObj.Headers.FileSize); if (OutFileOrError.getError()) ExitOnErr(make_error(generic_error_code::invalid_path, - opts::YamlPdbOutputFile)); + opts::yaml2pdb::YamlPdbOutputFile)); auto FileByteStream = llvm::make_unique(std::move(*OutFileOrError)); @@ -371,20 +306,28 @@ static void yamlToPdb(StringRef Path) { Pdb.commit(); } -static void dumpInput(StringRef Path) { +static void dumpRaw(StringRef Path) { std::unique_ptr Session; - if (isRawDumpEnabled()) { - ExitOnErr(loadDataForPDB(PDB_ReaderType::Raw, Path, Session)); + ExitOnErr(loadDataForPDB(PDB_ReaderType::Raw, Path, Session)); - RawSession *RS = static_cast(Session.get()); - ExitOnErr(dumpStructure(*RS)); - return; - } + RawSession *RS = static_cast(Session.get()); + PDBFile &File = RS->getPDBFile(); + std::unique_ptr O; + if (opts::PdbToYamlSubcommand) + O = llvm::make_unique(File); + else + O = llvm::make_unique(File); + + ExitOnErr(O->dump()); +} + +static void dumpPretty(StringRef Path) { + std::unique_ptr Session; ExitOnErr(loadDataForPDB(PDB_ReaderType::DIA, Path, Session)); - if (opts::LoadAddress) - Session->setLoadAddress(opts::LoadAddress); + if (opts::pretty::LoadAddress) + Session->setLoadAddress(opts::pretty::LoadAddress); LinePrinter Printer(2, outs()); @@ -421,7 +364,7 @@ static void dumpInput(StringRef Path) { outs() << "HasPrivateSymbols "; Printer.Unindent(); - if (opts::Compilands) { + if (opts::pretty::Compilands) { Printer.NewLine(); WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---COMPILANDS---"; @@ -429,14 +372,14 @@ static void dumpInput(StringRef Path) { auto Compilands = GlobalScope->findAllChildren(); CompilandDumper Dumper(Printer); CompilandDumpFlags options = CompilandDumper::Flags::None; - if (opts::Lines) + if (opts::pretty::Lines) options = options | CompilandDumper::Flags::Lines; while (auto Compiland = Compilands->getNext()) Dumper.start(*Compiland, options); Printer.Unindent(); } - if (opts::Types) { + if (opts::pretty::Types) { Printer.NewLine(); WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---TYPES---"; Printer.Indent(); @@ -445,7 +388,7 @@ static void dumpInput(StringRef Path) { Printer.Unindent(); } - if (opts::Symbols) { + if (opts::pretty::Symbols) { Printer.NewLine(); WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---SYMBOLS---"; Printer.Indent(); @@ -456,7 +399,7 @@ static void dumpInput(StringRef Path) { Printer.Unindent(); } - if (opts::Globals) { + if (opts::pretty::Globals) { Printer.NewLine(); WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---GLOBALS---"; Printer.Indent(); @@ -482,14 +425,14 @@ static void dumpInput(StringRef Path) { } Printer.Unindent(); } - if (opts::Externals) { + if (opts::pretty::Externals) { Printer.NewLine(); WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---EXTERNALS---"; Printer.Indent(); ExternalSymbolDumper Dumper(Printer); Dumper.start(*GlobalScope); } - if (opts::Lines) { + if (opts::pretty::Lines) { Printer.NewLine(); } outs().flush(); @@ -510,60 +453,68 @@ int main(int argc_, const char *argv_[]) { llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. cl::ParseCommandLineOptions(argv.size(), argv.data(), "LLVM PDB Dumper\n"); - if (opts::Lines) - opts::Compilands = true; - if (opts::All) { - opts::Compilands = true; - opts::Symbols = true; - opts::Globals = true; - opts::Types = true; - opts::Externals = true; - opts::Lines = true; - } - - if (opts::RawAll) { - opts::DumpHeaders = true; - opts::DumpModules = true; - opts::DumpModuleFiles = true; - opts::DumpModuleSyms = true; - opts::DumpPublics = true; - opts::DumpSectionHeaders = true; - opts::DumpStreamSummary = true; - opts::DumpStreamBlocks = true; - opts::DumpTpiRecords = true; - opts::DumpTpiHash = true; - opts::DumpIpiRecords = true; - opts::DumpSectionMap = true; - opts::DumpSectionContribs = true; - opts::DumpLineInfo = true; - opts::DumpFpo = true; - } - - // When adding filters for excluded compilands and types, we need to remember - // that these are regexes. So special characters such as * and \ need to be - // escaped in the regex. In the case of a literal \, this means it needs to - // be escaped again in the C++. So matching a single \ in the input requires - // 4 \es in the C++. - if (opts::ExcludeCompilerGenerated) { - opts::ExcludeTypes.push_back("__vc_attributes"); - opts::ExcludeCompilands.push_back("\\* Linker \\*"); - } - if (opts::ExcludeSystemLibraries) { - opts::ExcludeCompilands.push_back( - "f:\\\\binaries\\\\Intermediate\\\\vctools\\\\crt_bld"); - opts::ExcludeCompilands.push_back("f:\\\\dd\\\\vctools\\\\crt"); - opts::ExcludeCompilands.push_back("d:\\\\th.obj.x86fre\\\\minkernel"); + // These options are shared by two subcommands. + if ((opts::PdbToYamlSubcommand || opts::RawSubcommand) && opts::raw::RawAll) { + opts::raw::DumpHeaders = true; + opts::raw::DumpModules = true; + opts::raw::DumpModuleFiles = true; + opts::raw::DumpModuleSyms = true; + opts::raw::DumpPublics = true; + opts::raw::DumpSectionHeaders = true; + opts::raw::DumpStreamSummary = true; + opts::raw::DumpStreamBlocks = true; + opts::raw::DumpTpiRecords = true; + opts::raw::DumpTpiHash = true; + opts::raw::DumpIpiRecords = true; + opts::raw::DumpSectionMap = true; + opts::raw::DumpSectionContribs = true; + opts::raw::DumpLineInfo = true; + opts::raw::DumpFpo = true; } llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::MultiThreaded); - if (opts::YamlToPdb) { - std::for_each(opts::InputFilenames.begin(), opts::InputFilenames.end(), - yamlToPdb); - } else { - std::for_each(opts::InputFilenames.begin(), opts::InputFilenames.end(), - dumpInput); + if (opts::PdbToYamlSubcommand) { + dumpRaw(opts::pdb2yaml::InputFilename.front()); + } else if (opts::YamlToPdbSubcommand) { + yamlToPdb(opts::yaml2pdb::InputFilename.front()); + } else if (opts::PrettySubcommand) { + if (opts::pretty::Lines) + opts::pretty::Compilands = true; + + if (opts::pretty::All) { + opts::pretty::Compilands = true; + opts::pretty::Symbols = true; + opts::pretty::Globals = true; + opts::pretty::Types = true; + opts::pretty::Externals = true; + opts::pretty::Lines = true; + } + + // When adding filters for excluded compilands and types, we need to + // remember + // that these are regexes. So special characters such as * and \ need to be + // escaped in the regex. In the case of a literal \, this means it needs to + // be escaped again in the C++. So matching a single \ in the input + // requires + // 4 \es in the C++. + if (opts::pretty::ExcludeCompilerGenerated) { + opts::pretty::ExcludeTypes.push_back("__vc_attributes"); + opts::pretty::ExcludeCompilands.push_back("\\* Linker \\*"); + } + if (opts::pretty::ExcludeSystemLibraries) { + opts::pretty::ExcludeCompilands.push_back( + "f:\\\\binaries\\\\Intermediate\\\\vctools\\\\crt_bld"); + opts::pretty::ExcludeCompilands.push_back("f:\\\\dd\\\\vctools\\\\crt"); + opts::pretty::ExcludeCompilands.push_back( + "d:\\\\th.obj.x86fre\\\\minkernel"); + } + std::for_each(opts::pretty::InputFilenames.begin(), + opts::pretty::InputFilenames.end(), dumpPretty); + } else if (opts::RawSubcommand) { + std::for_each(opts::raw::InputFilenames.begin(), + opts::raw::InputFilenames.end(), dumpRaw); } outs().flush(); diff --git a/tools/llvm-pdbdump/llvm-pdbdump.h b/tools/llvm-pdbdump/llvm-pdbdump.h index 4a6afaeb14e..b6b85c074f9 100644 --- a/tools/llvm-pdbdump/llvm-pdbdump.h +++ b/tools/llvm-pdbdump/llvm-pdbdump.h @@ -15,15 +15,25 @@ namespace opts { -enum OutputStyleTy { LLVM, YAML }; - +namespace pretty { extern llvm::cl::opt Compilands; extern llvm::cl::opt Symbols; extern llvm::cl::opt Globals; extern llvm::cl::opt Types; extern llvm::cl::opt All; +extern llvm::cl::opt ExcludeCompilerGenerated; -extern llvm::cl::opt RawOutputStyle; +extern llvm::cl::opt NoClassDefs; +extern llvm::cl::opt NoEnumDefs; +extern llvm::cl::list ExcludeTypes; +extern llvm::cl::list ExcludeSymbols; +extern llvm::cl::list ExcludeCompilands; +extern llvm::cl::list IncludeTypes; +extern llvm::cl::list IncludeSymbols; +extern llvm::cl::list IncludeCompilands; +} + +namespace raw { extern llvm::cl::opt DumpHeaders; extern llvm::cl::opt DumpStreamBlocks; extern llvm::cl::opt DumpStreamSummary; @@ -44,17 +54,13 @@ extern llvm::cl::opt DumpSectionMap; extern llvm::cl::opt DumpSymRecordBytes; extern llvm::cl::opt DumpSectionHeaders; extern llvm::cl::opt DumpFpo; +} -extern llvm::cl::opt ExcludeCompilerGenerated; - -extern llvm::cl::opt NoClassDefs; -extern llvm::cl::opt NoEnumDefs; -extern llvm::cl::list ExcludeTypes; -extern llvm::cl::list ExcludeSymbols; -extern llvm::cl::list ExcludeCompilands; -extern llvm::cl::list IncludeTypes; -extern llvm::cl::list IncludeSymbols; -extern llvm::cl::list IncludeCompilands; +namespace pdb2yaml { +extern llvm::cl::opt StreamMetadata; +extern llvm::cl::opt StreamDirectory; +extern llvm::cl::list InputFilename; +} } #endif