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