From 4afda8f7b68be1098d191017ef04967aadde1099 Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Sun, 14 May 2017 01:13:40 +0000 Subject: [PATCH] [llvm-pdbdump] Add the option to sort functions and data. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302998 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../PDB/DIA/pdbdump-symbol-format.test | 4 +- test/tools/llvm-pdbdump/Inputs/FilterTest.cpp | 18 ++++ test/tools/llvm-pdbdump/Inputs/FilterTest.pdb | Bin 44032 -> 44032 bytes test/tools/llvm-pdbdump/regex-filter.test | 8 +- test/tools/llvm-pdbdump/symbol-filters.test | 74 +++++++++++++ tools/llvm-pdbdump/PrettyCompilandDumper.cpp | 12 +++ tools/llvm-pdbdump/PrettyFunctionDumper.cpp | 10 +- tools/llvm-pdbdump/llvm-pdbdump.cpp | 102 ++++++++++++++++-- tools/llvm-pdbdump/llvm-pdbdump.h | 23 ++++ 9 files changed, 234 insertions(+), 17 deletions(-) create mode 100644 test/tools/llvm-pdbdump/symbol-filters.test diff --git a/test/DebugInfo/PDB/DIA/pdbdump-symbol-format.test b/test/DebugInfo/PDB/DIA/pdbdump-symbol-format.test index 0bb3e001d3a..997cdd9f6ba 100644 --- a/test/DebugInfo/PDB/DIA/pdbdump-symbol-format.test +++ b/test/DebugInfo/PDB/DIA/pdbdump-symbol-format.test @@ -1,5 +1,5 @@ -; RUN: llvm-pdbdump pretty -symbols %p/../Inputs/symbolformat.pdb | FileCheck --check-prefix=SYM_FORMAT_FPO %s -; RUN: llvm-pdbdump pretty -symbols %p/../Inputs/symbolformat.pdb | FileCheck --check-prefix=SYM_FORMAT %s +; RUN: llvm-pdbdump pretty -module-syms %p/../Inputs/symbolformat.pdb | FileCheck --check-prefix=SYM_FORMAT_FPO %s +; RUN: llvm-pdbdump pretty -module-syms %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 diff --git a/test/tools/llvm-pdbdump/Inputs/FilterTest.cpp b/test/tools/llvm-pdbdump/Inputs/FilterTest.cpp index bcf9360d4a9..4dd5581e2fc 100644 --- a/test/tools/llvm-pdbdump/Inputs/FilterTest.cpp +++ b/test/tools/llvm-pdbdump/Inputs/FilterTest.cpp @@ -10,6 +10,8 @@ public: void MemberFunc() {} + int foo() const { return IntMemberVar; } + private: int IntMemberVar; double DoubleMemberVar; @@ -18,10 +20,26 @@ private: int IntGlobalVar; double DoubleGlobalVar; typedef int GlobalTypedef; +char OneByte; +char TwoBytes[2]; +char ThreeBytes[3]; + enum GlobalEnum { GlobalEnumVal1 } GlobalEnumVar; +int CFunc() { + return (int)OneByte * 2; +} +int BFunc() { + return 42; +} +int AFunc() { + static FilterTestClass FC; + + return (CFunc() + BFunc()) * IntGlobalVar + FC.foo(); +} + int main(int argc, char **argv) { FilterTestClass TestClass; GlobalTypedef v1; diff --git a/test/tools/llvm-pdbdump/Inputs/FilterTest.pdb b/test/tools/llvm-pdbdump/Inputs/FilterTest.pdb index 5f01ec701b815d525033084ad530f4ecc4cb5b0f..ce7e017f915174c7e497c422d7cc91df7b64639b 100644 GIT binary patch delta 4605 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 delta 1120 zcmb`GK}ge49LL}LzrXFj+Uh^IWIACJrp~F;$qI=Mn+&lsm?E@GmZhMuY73JQ9v1A- zLCNhG;h}@=(#690I*G&%9y$aSL3oP1bP9q_9;EudIU@)mq96P0_ul)x_j~X6zVDyg z)^gk0lHZ{*#yY_=P}VA2vaf{@xn1edzY6l{_PX6KQA_2ZYb)9eY2Q++#zcslU-?oMF*bGU+`s;QXbcZ(JJI4a!|NMIRY zT-8E}=1z*5W)ov)*jWensSWE9u#fVZr)kqK^X_>p3(8>ghksa3dH1U9ZF#Hhr}!v% z16h6Tyh368J1N@cu}2xJgl3 zeX@`^O+UIuxLJrblDD;|kl3M~HVj8-A!IAZH+eBIWUXh%tKyq9(c#qcjMh7b=vvTC zT42x`LJ%pLPUS$m``6U!E>~_$%-nCBWG*r)0+ORlDkH zH7p5KbLGNA)m3(&CT*nm@NSk7cG0_2P9fNwe4pvoN?Cn9y4O&S>AW~;s~f`u%aUW> zX-{CP!a$a!3@6_RYiM>VJB#jLNF`TtDN$#t=Sq&eQ)$T*D%+3@PkKZl_F{cH!8K-< zW6!l>Dq3y5R00PBn5DjrLj^`$6*|IcsoQmk(i9CTsm*eHjTa+E1o{5o6@R+;#}&(s S^q|n()) { uint64_t Prologue = DebugStart->getVirtualAddress() - FuncStart; - WithColor(Printer, PDB_ColorItem::Offset).get() << "+" << Prologue; + WithColor(Printer, PDB_ColorItem::Offset).get() + << formatv("+{0,2}", Prologue); } Printer << " - "; WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(FuncEnd, 10); if (auto DebugEnd = Symbol.findOneChild()) { uint64_t Epilogue = FuncEnd - DebugEnd->getVirtualAddress(); - WithColor(Printer, PDB_ColorItem::Offset).get() << "-" << Epilogue; + WithColor(Printer, PDB_ColorItem::Offset).get() + << formatv("-{0,2}", Epilogue); } + + WithColor(Printer, PDB_ColorItem::Comment).get() + << formatv(" | sizeof={0,3}", Symbol.getLength()); Printer << "] ("; if (Symbol.hasFramePointer()) { diff --git a/tools/llvm-pdbdump/llvm-pdbdump.cpp b/tools/llvm-pdbdump/llvm-pdbdump.cpp index 4cdd87620c8..0e5913fa3c9 100644 --- a/tools/llvm-pdbdump/llvm-pdbdump.cpp +++ b/tools/llvm-pdbdump/llvm-pdbdump.cpp @@ -110,12 +110,22 @@ cl::list InputFilenames(cl::Positional, cl::opt Compilands("compilands", cl::desc("Display compilands"), cl::cat(TypeCategory), cl::sub(PrettySubcommand)); -cl::opt Symbols("symbols", cl::desc("Display symbols for each compiland"), +cl::opt Symbols("module-syms", + cl::desc("Display symbols for each compiland"), cl::cat(TypeCategory), cl::sub(PrettySubcommand)); cl::opt Globals("globals", cl::desc("Dump global symbols"), cl::cat(TypeCategory), cl::sub(PrettySubcommand)); cl::opt Externals("externals", cl::desc("Dump external symbols"), cl::cat(TypeCategory), cl::sub(PrettySubcommand)); +cl::list SymTypes( + "sym-types", cl::desc("Type of symbols to dump (default all)"), + cl::cat(TypeCategory), cl::sub(PrettySubcommand), cl::ZeroOrMore, + cl::values( + clEnumValN(SymLevel::Thunks, "thunks", "Display thunk symbols"), + clEnumValN(SymLevel::Data, "data", "Display data symbols"), + clEnumValN(SymLevel::Functions, "funcs", "Display function symbols"), + clEnumValN(SymLevel::All, "all", "Display all symbols (default)"))); + cl::opt Types("types", cl::desc("Display all types (implies -classes, -enums, -typedefs)"), @@ -126,6 +136,16 @@ cl::opt Enums("enums", cl::desc("Display enum types"), cl::cat(TypeCategory), cl::sub(PrettySubcommand)); cl::opt Typedefs("typedefs", cl::desc("Display typedef types"), cl::cat(TypeCategory), cl::sub(PrettySubcommand)); +cl::opt SymbolOrder( + "symbol-order", cl::desc("symbol sort order"), + cl::init(SymbolSortMode::None), + cl::values(clEnumValN(SymbolSortMode::None, "none", + "Undefined / no particular sort order"), + clEnumValN(SymbolSortMode::Name, "name", "Sort symbols by name"), + clEnumValN(SymbolSortMode::Size, "size", + "Sort symbols by size")), + cl::cat(TypeCategory), cl::sub(PrettySubcommand)); + cl::opt ClassOrder( "class-order", cl::desc("Class sort order"), cl::init(ClassSortMode::None), cl::values( @@ -620,6 +640,49 @@ static void diff(StringRef Path1, StringRef Path2) { ExitOnErr(O->dump()); } +bool opts::pretty::shouldDumpSymLevel(SymLevel Search) { + if (SymTypes.empty()) + return true; + if (llvm::find(SymTypes, Search) != SymTypes.end()) + return true; + if (llvm::find(SymTypes, SymLevel::All) != SymTypes.end()) + return true; + return false; +} + +uint32_t llvm::pdb::getTypeLength(const PDBSymbolData &Symbol) { + auto SymbolType = Symbol.getType(); + const IPDBRawSymbol &RawType = SymbolType->getRawSymbol(); + + return RawType.getLength(); +} + +bool opts::pretty::compareFunctionSymbols( + const std::unique_ptr &F1, + const std::unique_ptr &F2) { + assert(opts::pretty::SymbolOrder != opts::pretty::SymbolSortMode::None); + + if (opts::pretty::SymbolOrder == opts::pretty::SymbolSortMode::Name) + return F1->getName() < F2->getName(); + + // Note that we intentionally sort in descending order on length, since + // long functions are more interesting than short functions. + return F1->getLength() > F2->getLength(); +} + +bool opts::pretty::compareDataSymbols( + const std::unique_ptr &F1, + const std::unique_ptr &F2) { + assert(opts::pretty::SymbolOrder != opts::pretty::SymbolSortMode::None); + + if (opts::pretty::SymbolOrder == opts::pretty::SymbolSortMode::Name) + return F1->getName() < F2->getName(); + + // Note that we intentionally sort in descending order on length, since + // large types are more interesting than short ones. + return getTypeLength(*F1) > getTypeLength(*F2); +} + static void dumpPretty(StringRef Path) { std::unique_ptr Session; @@ -708,21 +771,42 @@ static void dumpPretty(StringRef Path) { Printer.NewLine(); WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---GLOBALS---"; Printer.Indent(); - { + if (shouldDumpSymLevel(opts::pretty::SymLevel::Functions)) { FunctionDumper Dumper(Printer); auto Functions = GlobalScope->findAllChildren(); - while (auto Function = Functions->getNext()) { - Printer.NewLine(); - Dumper.start(*Function, FunctionDumper::PointerType::None); + if (opts::pretty::SymbolOrder == opts::pretty::SymbolSortMode::None) { + while (auto Function = Functions->getNext()) { + Printer.NewLine(); + Dumper.start(*Function, FunctionDumper::PointerType::None); + } + } else { + std::vector> Funcs; + while (auto Func = Functions->getNext()) + Funcs.push_back(std::move(Func)); + std::sort(Funcs.begin(), Funcs.end(), + opts::pretty::compareFunctionSymbols); + for (const auto &Func : Funcs) { + Printer.NewLine(); + Dumper.start(*Func, FunctionDumper::PointerType::None); + } } } - { + if (shouldDumpSymLevel(opts::pretty::SymLevel::Data)) { auto Vars = GlobalScope->findAllChildren(); VariableDumper Dumper(Printer); - while (auto Var = Vars->getNext()) - Dumper.start(*Var); + if (opts::pretty::SymbolOrder == opts::pretty::SymbolSortMode::None) { + while (auto Var = Vars->getNext()) + Dumper.start(*Var); + } else { + std::vector> Datas; + while (auto Var = Vars->getNext()) + Datas.push_back(std::move(Var)); + std::sort(Datas.begin(), Datas.end(), opts::pretty::compareDataSymbols); + for (const auto &Var : Datas) + Dumper.start(*Var); + } } - { + if (shouldDumpSymLevel(opts::pretty::SymLevel::Thunks)) { auto Thunks = GlobalScope->findAllChildren(); CompilandDumper Dumper(Printer); while (auto Thunk = Thunks->getNext()) diff --git a/tools/llvm-pdbdump/llvm-pdbdump.h b/tools/llvm-pdbdump/llvm-pdbdump.h index 8b1dde9399b..e38b32c6a34 100644 --- a/tools/llvm-pdbdump/llvm-pdbdump.h +++ b/tools/llvm-pdbdump/llvm-pdbdump.h @@ -14,6 +14,17 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/raw_ostream.h" +#include +#include + +namespace llvm { +namespace pdb { +class PDBSymbolData; +class PDBSymbolFunc; +uint32_t getTypeLength(const PDBSymbolData &Symbol); +} +} + namespace opts { namespace pretty { @@ -29,6 +40,17 @@ enum class ClassSortMode { PaddingPctImmediate }; +enum class SymbolSortMode { None, Name, Size }; + +enum class SymLevel { Functions, Data, Thunks, All }; + +bool shouldDumpSymLevel(SymLevel Level); +bool compareFunctionSymbols( + const std::unique_ptr &F1, + const std::unique_ptr &F2); +bool compareDataSymbols(const std::unique_ptr &F1, + const std::unique_ptr &F2); + extern llvm::cl::opt Compilands; extern llvm::cl::opt Symbols; extern llvm::cl::opt Globals; @@ -45,6 +67,7 @@ extern llvm::cl::list ExcludeCompilands; extern llvm::cl::list IncludeTypes; extern llvm::cl::list IncludeSymbols; extern llvm::cl::list IncludeCompilands; +extern llvm::cl::opt SymbolOrder; extern llvm::cl::opt ClassOrder; extern llvm::cl::opt SizeThreshold; extern llvm::cl::opt PaddingThreshold;