1 //===- lldb-test.cpp ------------------------------------------ *- 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 #include "FormatUtil.h" 11 #include "SystemInitializerTest.h" 12 13 #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" 14 #include "lldb/Core/Debugger.h" 15 #include "lldb/Core/Module.h" 16 #include "lldb/Core/Section.h" 17 #include "lldb/Initialization/SystemLifetimeManager.h" 18 #include "lldb/Symbol/ClangASTContext.h" 19 #include "lldb/Symbol/ClangASTImporter.h" 20 #include "lldb/Utility/DataExtractor.h" 21 #include "lldb/Utility/StreamString.h" 22 23 #include "llvm/ADT/StringRef.h" 24 #include "llvm/Support/CommandLine.h" 25 #include "llvm/Support/ManagedStatic.h" 26 #include "llvm/Support/PrettyStackTrace.h" 27 #include "llvm/Support/Signals.h" 28 #include <thread> 29 30 using namespace lldb; 31 using namespace lldb_private; 32 using namespace llvm; 33 34 namespace opts { 35 cl::SubCommand ModuleSubcommand("module-sections", 36 "Display LLDB Module Information"); 37 cl::SubCommand SymbolsSubcommand("symbols", "Dump symbols for an object file"); 38 39 namespace module { 40 cl::opt<bool> SectionContents("contents", 41 cl::desc("Dump each section's contents"), 42 cl::sub(ModuleSubcommand)); 43 cl::list<std::string> InputFilenames(cl::Positional, cl::desc("<input files>"), 44 cl::OneOrMore, cl::sub(ModuleSubcommand)); 45 } // namespace module 46 47 namespace symbols { 48 cl::list<std::string> InputFilenames(cl::Positional, cl::desc("<input files>"), 49 cl::OneOrMore, cl::sub(SymbolsSubcommand)); 50 } 51 } // namespace opts 52 53 static llvm::ManagedStatic<SystemLifetimeManager> DebuggerLifetime; 54 55 static void dumpSymbols(Debugger &Dbg) { 56 for (const auto &File : opts::symbols::InputFilenames) { 57 ModuleSpec Spec{FileSpec(File, false)}; 58 Spec.GetSymbolFileSpec().SetFile(File, false); 59 60 auto ModulePtr = std::make_shared<lldb_private::Module>(Spec); 61 62 StreamString Stream; 63 ModulePtr->ParseAllDebugSymbols(); 64 ModulePtr->Dump(&Stream); 65 llvm::outs() << Stream.GetData() << "\n"; 66 llvm::outs().flush(); 67 } 68 } 69 70 static void dumpModules(Debugger &Dbg) { 71 LinePrinter Printer(4, llvm::outs()); 72 73 for (const auto &File : opts::module::InputFilenames) { 74 ModuleSpec Spec{FileSpec(File, false)}; 75 Spec.GetSymbolFileSpec().SetFile(File, false); 76 77 auto ModulePtr = std::make_shared<lldb_private::Module>(Spec); 78 SectionList *Sections = ModulePtr->GetSectionList(); 79 if (!Sections) { 80 llvm::errs() << "Could not load sections for module " << File << "\n"; 81 continue; 82 } 83 84 size_t Count = Sections->GetNumSections(0); 85 Printer.formatLine("Showing {0} sections", Count); 86 for (size_t I = 0; I < Count; ++I) { 87 AutoIndent Indent(Printer, 2); 88 auto S = Sections->GetSectionAtIndex(I); 89 assert(S); 90 Printer.formatLine("Index: {0}", I); 91 Printer.formatLine("Name: {0}", S->GetName().GetStringRef()); 92 Printer.formatLine("VM size: {0}", S->GetByteSize()); 93 Printer.formatLine("File size: {0}", S->GetFileSize()); 94 95 if (opts::module::SectionContents) { 96 DataExtractor Data; 97 S->GetSectionData(Data); 98 ArrayRef<uint8_t> Bytes = {Data.GetDataStart(), Data.GetDataEnd()}; 99 Printer.formatBinary("Data: ", Bytes, 0); 100 } 101 Printer.NewLine(); 102 } 103 } 104 } 105 106 int main(int argc, const char *argv[]) { 107 StringRef ToolName = argv[0]; 108 sys::PrintStackTraceOnErrorSignal(ToolName); 109 PrettyStackTraceProgram X(argc, argv); 110 llvm_shutdown_obj Y; 111 112 cl::ParseCommandLineOptions(argc, argv, "LLDB Testing Utility\n"); 113 114 DebuggerLifetime->Initialize(llvm::make_unique<SystemInitializerTest>(), 115 nullptr); 116 117 auto Dbg = lldb_private::Debugger::CreateInstance(); 118 119 if (opts::ModuleSubcommand) 120 dumpModules(*Dbg); 121 else if (opts::SymbolsSubcommand) 122 dumpSymbols(*Dbg); 123 124 DebuggerLifetime->Terminate(); 125 return 0; 126 } 127