[RISCV] Add addu.w and slliu.w test that uses getelementptr with zero extended indices.
[lldb.git] / lldb / tools / lldb-test / lldb-test.cpp
1 //===- lldb-test.cpp ------------------------------------------ *- C++ --*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "FormatUtil.h"
10 #include "SystemInitializerTest.h"
11
12 #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
13 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
14 #include "lldb/Breakpoint/BreakpointLocation.h"
15 #include "lldb/Core/Debugger.h"
16 #include "lldb/Core/Module.h"
17 #include "lldb/Core/Section.h"
18 #include "lldb/Expression/IRMemoryMap.h"
19 #include "lldb/Initialization/SystemLifetimeManager.h"
20 #include "lldb/Interpreter/CommandInterpreter.h"
21 #include "lldb/Interpreter/CommandReturnObject.h"
22 #include "lldb/Symbol/CompileUnit.h"
23 #include "lldb/Symbol/LineTable.h"
24 #include "lldb/Symbol/SymbolFile.h"
25 #include "lldb/Symbol/TypeList.h"
26 #include "lldb/Symbol/TypeMap.h"
27 #include "lldb/Symbol/VariableList.h"
28 #include "lldb/Target/Language.h"
29 #include "lldb/Target/Process.h"
30 #include "lldb/Target/Target.h"
31 #include "lldb/Utility/DataExtractor.h"
32 #include "lldb/Utility/State.h"
33 #include "lldb/Utility/StreamString.h"
34
35 #include "llvm/ADT/IntervalMap.h"
36 #include "llvm/ADT/ScopeExit.h"
37 #include "llvm/ADT/StringRef.h"
38 #include "llvm/Support/CommandLine.h"
39 #include "llvm/Support/ManagedStatic.h"
40 #include "llvm/Support/MathExtras.h"
41 #include "llvm/Support/Path.h"
42 #include "llvm/Support/PrettyStackTrace.h"
43 #include "llvm/Support/Signals.h"
44 #include "llvm/Support/WithColor.h"
45
46 #include <cstdio>
47 #include <thread>
48
49 using namespace lldb;
50 using namespace lldb_private;
51 using namespace llvm;
52
53 namespace opts {
54 static cl::SubCommand BreakpointSubcommand("breakpoints",
55                                            "Test breakpoint resolution");
56 cl::SubCommand ObjectFileSubcommand("object-file",
57                                     "Display LLDB object file information");
58 cl::SubCommand SymbolsSubcommand("symbols", "Dump symbols for an object file");
59 cl::SubCommand IRMemoryMapSubcommand("ir-memory-map", "Test IRMemoryMap");
60
61 cl::opt<std::string> Log("log", cl::desc("Path to a log file"), cl::init(""),
62                          cl::sub(BreakpointSubcommand),
63                          cl::sub(ObjectFileSubcommand),
64                          cl::sub(SymbolsSubcommand),
65                          cl::sub(IRMemoryMapSubcommand));
66
67 /// Create a target using the file pointed to by \p Filename, or abort.
68 TargetSP createTarget(Debugger &Dbg, const std::string &Filename);
69
70 /// Read \p Filename into a null-terminated buffer, or abort.
71 std::unique_ptr<MemoryBuffer> openFile(const std::string &Filename);
72
73 namespace breakpoint {
74 static cl::opt<std::string> Target(cl::Positional, cl::desc("<target>"),
75                                    cl::Required, cl::sub(BreakpointSubcommand));
76 static cl::opt<std::string> CommandFile(cl::Positional,
77                                         cl::desc("<command-file>"),
78                                         cl::init("-"),
79                                         cl::sub(BreakpointSubcommand));
80 static cl::opt<bool> Persistent(
81     "persistent",
82     cl::desc("Don't automatically remove all breakpoints before each command"),
83     cl::sub(BreakpointSubcommand));
84
85 static llvm::StringRef plural(uintmax_t value) { return value == 1 ? "" : "s"; }
86 static void dumpState(const BreakpointList &List, LinePrinter &P);
87 static std::string substitute(StringRef Cmd);
88 static int evaluateBreakpoints(Debugger &Dbg);
89 } // namespace breakpoint
90
91 namespace object {
92 cl::opt<bool> SectionContents("contents",
93                               cl::desc("Dump each section's contents"),
94                               cl::sub(ObjectFileSubcommand));
95 cl::opt<bool> SectionDependentModules("dep-modules",
96                                       cl::desc("Dump each dependent module"),
97                                       cl::sub(ObjectFileSubcommand));
98 cl::list<std::string> InputFilenames(cl::Positional, cl::desc("<input files>"),
99                                      cl::OneOrMore,
100                                      cl::sub(ObjectFileSubcommand));
101 } // namespace object
102
103 namespace symbols {
104 static cl::opt<std::string> InputFile(cl::Positional, cl::desc("<input file>"),
105                                       cl::Required, cl::sub(SymbolsSubcommand));
106
107 static cl::opt<std::string>
108     SymbolPath("symbol-file",
109                cl::desc("The file from which to fetch symbol information."),
110                cl::value_desc("file"), cl::sub(SymbolsSubcommand));
111
112 enum class FindType {
113   None,
114   Function,
115   Block,
116   Namespace,
117   Type,
118   Variable,
119 };
120 static cl::opt<FindType> Find(
121     "find", cl::desc("Choose search type:"),
122     cl::values(
123         clEnumValN(FindType::None, "none", "No search, just dump the module."),
124         clEnumValN(FindType::Function, "function", "Find functions."),
125         clEnumValN(FindType::Block, "block", "Find blocks."),
126         clEnumValN(FindType::Namespace, "namespace", "Find namespaces."),
127         clEnumValN(FindType::Type, "type", "Find types."),
128         clEnumValN(FindType::Variable, "variable", "Find global variables.")),
129     cl::sub(SymbolsSubcommand));
130
131 static cl::opt<std::string> Name("name", cl::desc("Name to find."),
132                                  cl::sub(SymbolsSubcommand));
133 static cl::opt<bool>
134     Regex("regex",
135           cl::desc("Search using regular expressions (available for variables "
136                    "and functions only)."),
137           cl::sub(SymbolsSubcommand));
138 static cl::opt<std::string>
139     Context("context",
140             cl::desc("Restrict search to the context of the given variable."),
141             cl::value_desc("variable"), cl::sub(SymbolsSubcommand));
142
143 static cl::opt<std::string> CompilerContext(
144     "compiler-context",
145     cl::desc("Specify a compiler context as \"kind:name,...\"."),
146     cl::value_desc("context"), cl::sub(SymbolsSubcommand));
147
148 static cl::opt<std::string>
149     Language("language", cl::desc("Specify a language type, like C99."),
150              cl::value_desc("language"), cl::sub(SymbolsSubcommand));
151
152 static cl::list<FunctionNameType> FunctionNameFlags(
153     "function-flags", cl::desc("Function search flags:"),
154     cl::values(clEnumValN(eFunctionNameTypeAuto, "auto",
155                           "Automatically deduce flags based on name."),
156                clEnumValN(eFunctionNameTypeFull, "full", "Full function name."),
157                clEnumValN(eFunctionNameTypeBase, "base", "Base name."),
158                clEnumValN(eFunctionNameTypeMethod, "method", "Method name."),
159                clEnumValN(eFunctionNameTypeSelector, "selector",
160                           "Selector name.")),
161     cl::sub(SymbolsSubcommand));
162 static FunctionNameType getFunctionNameFlags() {
163   FunctionNameType Result = FunctionNameType(0);
164   for (FunctionNameType Flag : FunctionNameFlags)
165     Result = FunctionNameType(Result | Flag);
166   return Result;
167 }
168
169 static cl::opt<bool> DumpAST("dump-ast",
170                              cl::desc("Dump AST restored from symbols."),
171                              cl::sub(SymbolsSubcommand));
172 static cl::opt<bool> DumpClangAST(
173     "dump-clang-ast",
174     cl::desc("Dump clang AST restored from symbols. When used on its own this "
175              "will dump the entire AST of all loaded symbols. When combined "
176              "with -find, it changes the presentation of the search results "
177              "from pretty-printing the types to an AST dump."),
178     cl::sub(SymbolsSubcommand));
179
180 static cl::opt<bool> Verify("verify", cl::desc("Verify symbol information."),
181                             cl::sub(SymbolsSubcommand));
182
183 static cl::opt<std::string> File("file",
184                                  cl::desc("File (compile unit) to search."),
185                                  cl::sub(SymbolsSubcommand));
186 static cl::opt<int> Line("line", cl::desc("Line to search."),
187                          cl::sub(SymbolsSubcommand));
188
189 static Expected<CompilerDeclContext> getDeclContext(SymbolFile &Symfile);
190
191 static Error findFunctions(lldb_private::Module &Module);
192 static Error findBlocks(lldb_private::Module &Module);
193 static Error findNamespaces(lldb_private::Module &Module);
194 static Error findTypes(lldb_private::Module &Module);
195 static Error findVariables(lldb_private::Module &Module);
196 static Error dumpModule(lldb_private::Module &Module);
197 static Error dumpAST(lldb_private::Module &Module);
198 static Error dumpEntireClangAST(lldb_private::Module &Module);
199 static Error verify(lldb_private::Module &Module);
200
201 static Expected<Error (*)(lldb_private::Module &)> getAction();
202 static int dumpSymbols(Debugger &Dbg);
203 } // namespace symbols
204
205 namespace irmemorymap {
206 static cl::opt<std::string> Target(cl::Positional, cl::desc("<target>"),
207                                    cl::Required,
208                                    cl::sub(IRMemoryMapSubcommand));
209 static cl::opt<std::string> CommandFile(cl::Positional,
210                                         cl::desc("<command-file>"),
211                                         cl::init("-"),
212                                         cl::sub(IRMemoryMapSubcommand));
213 static cl::opt<bool> UseHostOnlyAllocationPolicy(
214     "host-only", cl::desc("Use the host-only allocation policy"),
215     cl::init(false), cl::sub(IRMemoryMapSubcommand));
216
217 using AllocationT = std::pair<addr_t, addr_t>;
218 using AddrIntervalMap =
219     IntervalMap<addr_t, unsigned, 8, IntervalMapHalfOpenInfo<addr_t>>;
220
221 struct IRMemoryMapTestState {
222   TargetSP Target;
223   IRMemoryMap Map;
224
225   AddrIntervalMap::Allocator IntervalMapAllocator;
226   AddrIntervalMap Allocations;
227
228   StringMap<addr_t> Label2AddrMap;
229
230   IRMemoryMapTestState(TargetSP Target)
231       : Target(Target), Map(Target), Allocations(IntervalMapAllocator) {}
232 };
233
234 bool evalMalloc(StringRef Line, IRMemoryMapTestState &State);
235 bool evalFree(StringRef Line, IRMemoryMapTestState &State);
236 int evaluateMemoryMapCommands(Debugger &Dbg);
237 } // namespace irmemorymap
238
239 } // namespace opts
240
241 std::vector<CompilerContext> parseCompilerContext() {
242   std::vector<CompilerContext> result;
243   if (opts::symbols::CompilerContext.empty())
244     return result;
245
246   StringRef str{opts::symbols::CompilerContext};
247   SmallVector<StringRef, 8> entries_str;
248   str.split(entries_str, ',', /*maxSplit*/-1, /*keepEmpty=*/false);
249   for (auto entry_str : entries_str) {
250     StringRef key, value;
251     std::tie(key, value) = entry_str.split(':');
252     auto kind =
253         StringSwitch<CompilerContextKind>(key)
254             .Case("TranslationUnit", CompilerContextKind::TranslationUnit)
255             .Case("Module", CompilerContextKind::Module)
256             .Case("Namespace", CompilerContextKind::Namespace)
257             .Case("Class", CompilerContextKind::Class)
258             .Case("Struct", CompilerContextKind::Struct)
259             .Case("Union", CompilerContextKind::Union)
260             .Case("Function", CompilerContextKind::Function)
261             .Case("Variable", CompilerContextKind::Variable)
262             .Case("Enum", CompilerContextKind::Enum)
263             .Case("Typedef", CompilerContextKind::Typedef)
264             .Case("AnyModule", CompilerContextKind::AnyModule)
265             .Case("AnyType", CompilerContextKind::AnyType)
266             .Default(CompilerContextKind::Invalid);
267     if (value.empty()) {
268       WithColor::error() << "compiler context entry has no \"name\"\n";
269       exit(1);
270     }
271     result.push_back({kind, ConstString{value}});
272   }
273   outs() << "Search context: {\n";
274   for (auto entry: result)
275     entry.Dump();
276   outs() << "}\n";
277
278   return result;
279 }
280
281 template <typename... Args>
282 static Error make_string_error(const char *Format, Args &&... args) {
283   return llvm::make_error<llvm::StringError>(
284       llvm::formatv(Format, std::forward<Args>(args)...).str(),
285       llvm::inconvertibleErrorCode());
286 }
287
288 TargetSP opts::createTarget(Debugger &Dbg, const std::string &Filename) {
289   TargetSP Target;
290   Status ST = Dbg.GetTargetList().CreateTarget(
291       Dbg, Filename, /*triple*/ "", eLoadDependentsNo,
292       /*platform_options*/ nullptr, Target);
293   if (ST.Fail()) {
294     errs() << formatv("Failed to create target '{0}: {1}\n", Filename, ST);
295     exit(1);
296   }
297   return Target;
298 }
299
300 std::unique_ptr<MemoryBuffer> opts::openFile(const std::string &Filename) {
301   auto MB = MemoryBuffer::getFileOrSTDIN(Filename);
302   if (!MB) {
303     errs() << formatv("Could not open file '{0}: {1}\n", Filename,
304                       MB.getError().message());
305     exit(1);
306   }
307   return std::move(*MB);
308 }
309
310 void opts::breakpoint::dumpState(const BreakpointList &List, LinePrinter &P) {
311   P.formatLine("{0} breakpoint{1}", List.GetSize(), plural(List.GetSize()));
312   if (List.GetSize() > 0)
313     P.formatLine("At least one breakpoint.");
314   for (size_t i = 0, e = List.GetSize(); i < e; ++i) {
315     BreakpointSP BP = List.GetBreakpointAtIndex(i);
316     P.formatLine("Breakpoint ID {0}:", BP->GetID());
317     AutoIndent Indent(P, 2);
318     P.formatLine("{0} location{1}.", BP->GetNumLocations(),
319                  plural(BP->GetNumLocations()));
320     if (BP->GetNumLocations() > 0)
321       P.formatLine("At least one location.");
322     P.formatLine("{0} resolved location{1}.", BP->GetNumResolvedLocations(),
323                  plural(BP->GetNumResolvedLocations()));
324     if (BP->GetNumResolvedLocations() > 0)
325       P.formatLine("At least one resolved location.");
326     for (size_t l = 0, le = BP->GetNumLocations(); l < le; ++l) {
327       BreakpointLocationSP Loc = BP->GetLocationAtIndex(l);
328       P.formatLine("Location ID {0}:", Loc->GetID());
329       AutoIndent Indent(P, 2);
330       P.formatLine("Enabled: {0}", Loc->IsEnabled());
331       P.formatLine("Resolved: {0}", Loc->IsResolved());
332       SymbolContext sc;
333       Loc->GetAddress().CalculateSymbolContext(&sc);
334       lldb_private::StreamString S;
335       sc.DumpStopContext(&S, BP->GetTarget().GetProcessSP().get(),
336                          Loc->GetAddress(), false, true, false, true, true);
337       P.formatLine("Address: {0}", S.GetString());
338     }
339   }
340   P.NewLine();
341 }
342
343 std::string opts::breakpoint::substitute(StringRef Cmd) {
344   std::string Result;
345   raw_string_ostream OS(Result);
346   while (!Cmd.empty()) {
347     switch (Cmd[0]) {
348     case '%':
349       if (Cmd.consume_front("%p") && (Cmd.empty() || !isalnum(Cmd[0]))) {
350         OS << sys::path::parent_path(breakpoint::CommandFile);
351         break;
352       }
353       LLVM_FALLTHROUGH;
354     default:
355       size_t pos = Cmd.find('%');
356       OS << Cmd.substr(0, pos);
357       Cmd = Cmd.substr(pos);
358       break;
359     }
360   }
361   return std::move(OS.str());
362 }
363
364 int opts::breakpoint::evaluateBreakpoints(Debugger &Dbg) {
365   TargetSP Target = opts::createTarget(Dbg, breakpoint::Target);
366   std::unique_ptr<MemoryBuffer> MB = opts::openFile(breakpoint::CommandFile);
367
368   LinePrinter P(4, outs());
369   StringRef Rest = MB->getBuffer();
370   int HadErrors = 0;
371   while (!Rest.empty()) {
372     StringRef Line;
373     std::tie(Line, Rest) = Rest.split('\n');
374     Line = Line.ltrim().rtrim();
375     if (Line.empty() || Line[0] == '#')
376       continue;
377
378     if (!Persistent)
379       Target->RemoveAllBreakpoints(/*internal_also*/ true);
380
381     std::string Command = substitute(Line);
382     P.formatLine("Command: {0}", Command);
383     CommandReturnObject Result(/*colors*/ false);
384     if (!Dbg.GetCommandInterpreter().HandleCommand(
385             Command.c_str(), /*add_to_history*/ eLazyBoolNo, Result)) {
386       P.formatLine("Failed: {0}", Result.GetErrorData());
387       HadErrors = 1;
388       continue;
389     }
390
391     dumpState(Target->GetBreakpointList(/*internal*/ false), P);
392   }
393   return HadErrors;
394 }
395
396 Expected<CompilerDeclContext>
397 opts::symbols::getDeclContext(SymbolFile &Symfile) {
398   if (Context.empty())
399     return CompilerDeclContext();
400   VariableList List;
401   Symfile.FindGlobalVariables(ConstString(Context), CompilerDeclContext(),
402                               UINT32_MAX, List);
403   if (List.Empty())
404     return make_string_error("Context search didn't find a match.");
405   if (List.GetSize() > 1)
406     return make_string_error("Context search found multiple matches.");
407   return List.GetVariableAtIndex(0)->GetDeclContext();
408 }
409
410 static lldb::DescriptionLevel GetDescriptionLevel() {
411   return opts::symbols::DumpClangAST ? eDescriptionLevelVerbose : eDescriptionLevelFull;
412 }
413
414 Error opts::symbols::findFunctions(lldb_private::Module &Module) {
415   SymbolFile &Symfile = *Module.GetSymbolFile();
416   SymbolContextList List;
417   if (!File.empty()) {
418     assert(Line != 0);
419
420     FileSpec src_file(File);
421     size_t cu_count = Module.GetNumCompileUnits();
422     for (size_t i = 0; i < cu_count; i++) {
423       lldb::CompUnitSP cu_sp = Module.GetCompileUnitAtIndex(i);
424       if (!cu_sp)
425         continue;
426
427       LineEntry le;
428       cu_sp->FindLineEntry(0, Line, &src_file, false, &le);
429       if (!le.IsValid())
430         continue;
431       const bool include_inlined_functions = false;
432       auto addr =
433           le.GetSameLineContiguousAddressRange(include_inlined_functions)
434               .GetBaseAddress();
435       if (!addr.IsValid())
436         continue;
437
438       SymbolContext sc;
439       uint32_t resolved =
440           addr.CalculateSymbolContext(&sc, eSymbolContextFunction);
441       if (resolved & eSymbolContextFunction)
442         List.Append(sc);
443     }
444   } else if (Regex) {
445     RegularExpression RE(Name);
446     assert(RE.IsValid());
447     List.Clear();
448     Symfile.FindFunctions(RE, true, List);
449   } else {
450     Expected<CompilerDeclContext> ContextOr = getDeclContext(Symfile);
451     if (!ContextOr)
452       return ContextOr.takeError();
453     const CompilerDeclContext &ContextPtr =
454         ContextOr->IsValid() ? *ContextOr : CompilerDeclContext();
455
456     List.Clear();
457     Symfile.FindFunctions(ConstString(Name), ContextPtr, getFunctionNameFlags(),
458                          true, List);
459   }
460   outs() << formatv("Found {0} functions:\n", List.GetSize());
461   StreamString Stream;
462   List.Dump(&Stream, nullptr);
463   outs() << Stream.GetData() << "\n";
464   return Error::success();
465 }
466
467 Error opts::symbols::findBlocks(lldb_private::Module &Module) {
468   assert(!Regex);
469   assert(!File.empty());
470   assert(Line != 0);
471
472   SymbolContextList List;
473
474   FileSpec src_file(File);
475   size_t cu_count = Module.GetNumCompileUnits();
476   for (size_t i = 0; i < cu_count; i++) {
477     lldb::CompUnitSP cu_sp = Module.GetCompileUnitAtIndex(i);
478     if (!cu_sp)
479       continue;
480
481     LineEntry le;
482     cu_sp->FindLineEntry(0, Line, &src_file, false, &le);
483     if (!le.IsValid())
484       continue;
485     const bool include_inlined_functions = false;
486     auto addr = le.GetSameLineContiguousAddressRange(include_inlined_functions)
487                     .GetBaseAddress();
488     if (!addr.IsValid())
489       continue;
490
491     SymbolContext sc;
492     uint32_t resolved = addr.CalculateSymbolContext(&sc, eSymbolContextBlock);
493     if (resolved & eSymbolContextBlock)
494       List.Append(sc);
495   }
496
497   outs() << formatv("Found {0} blocks:\n", List.GetSize());
498   StreamString Stream;
499   List.Dump(&Stream, nullptr);
500   outs() << Stream.GetData() << "\n";
501   return Error::success();
502 }
503
504 Error opts::symbols::findNamespaces(lldb_private::Module &Module) {
505   SymbolFile &Symfile = *Module.GetSymbolFile();
506   Expected<CompilerDeclContext> ContextOr = getDeclContext(Symfile);
507   if (!ContextOr)
508     return ContextOr.takeError();
509   const CompilerDeclContext &ContextPtr =
510       ContextOr->IsValid() ? *ContextOr : CompilerDeclContext();
511
512   CompilerDeclContext Result =
513       Symfile.FindNamespace(ConstString(Name), ContextPtr);
514   if (Result)
515     outs() << "Found namespace: "
516            << Result.GetScopeQualifiedName().GetStringRef() << "\n";
517   else
518     outs() << "Namespace not found.\n";
519   return Error::success();
520 }
521
522 Error opts::symbols::findTypes(lldb_private::Module &Module) {
523   SymbolFile &Symfile = *Module.GetSymbolFile();
524   Expected<CompilerDeclContext> ContextOr = getDeclContext(Symfile);
525   if (!ContextOr)
526     return ContextOr.takeError();
527   const CompilerDeclContext &ContextPtr =
528       ContextOr->IsValid() ? *ContextOr : CompilerDeclContext();
529
530   LanguageSet languages;
531   if (!Language.empty())
532     languages.Insert(Language::GetLanguageTypeFromString(Language));
533
534   DenseSet<SymbolFile *> SearchedFiles;
535   TypeMap Map;
536   if (!Name.empty())
537     Symfile.FindTypes(ConstString(Name), ContextPtr, UINT32_MAX, SearchedFiles,
538                       Map);
539   else
540     Module.FindTypes(parseCompilerContext(), languages, SearchedFiles, Map);
541
542   outs() << formatv("Found {0} types:\n", Map.GetSize());
543   StreamString Stream;
544   // Resolve types to force-materialize typedef types.
545   Map.ForEach([&](TypeSP &type) {
546     type->GetFullCompilerType();
547     return false;
548   });
549   Map.Dump(&Stream, false, GetDescriptionLevel());
550   outs() << Stream.GetData() << "\n";
551   return Error::success();
552 }
553
554 Error opts::symbols::findVariables(lldb_private::Module &Module) {
555   SymbolFile &Symfile = *Module.GetSymbolFile();
556   VariableList List;
557   if (Regex) {
558     RegularExpression RE(Name);
559     assert(RE.IsValid());
560     Symfile.FindGlobalVariables(RE, UINT32_MAX, List);
561   } else if (!File.empty()) {
562     CompUnitSP CU;
563     for (size_t Ind = 0; !CU && Ind < Module.GetNumCompileUnits(); ++Ind) {
564       CompUnitSP Candidate = Module.GetCompileUnitAtIndex(Ind);
565       if (!Candidate ||
566           Candidate->GetPrimaryFile().GetFilename().GetStringRef() != File)
567         continue;
568       if (CU)
569         return make_string_error("Multiple compile units for file `{0}` found.",
570                                  File);
571       CU = std::move(Candidate);
572     }
573
574     if (!CU)
575       return make_string_error("Compile unit `{0}` not found.", File);
576
577     List.AddVariables(CU->GetVariableList(true).get());
578   } else {
579     Expected<CompilerDeclContext> ContextOr = getDeclContext(Symfile);
580     if (!ContextOr)
581       return ContextOr.takeError();
582     const CompilerDeclContext &ContextPtr =
583         ContextOr->IsValid() ? *ContextOr : CompilerDeclContext();
584
585     Symfile.FindGlobalVariables(ConstString(Name), ContextPtr, UINT32_MAX, List);
586   }
587   outs() << formatv("Found {0} variables:\n", List.GetSize());
588   StreamString Stream;
589   List.Dump(&Stream, false);
590   outs() << Stream.GetData() << "\n";
591   return Error::success();
592 }
593
594 Error opts::symbols::dumpModule(lldb_private::Module &Module) {
595   StreamString Stream;
596   Module.ParseAllDebugSymbols();
597   Module.Dump(&Stream);
598   outs() << Stream.GetData() << "\n";
599   return Error::success();
600 }
601
602 Error opts::symbols::dumpAST(lldb_private::Module &Module) {
603   Module.ParseAllDebugSymbols();
604
605   SymbolFile *symfile = Module.GetSymbolFile();
606   if (!symfile)
607     return make_string_error("Module has no symbol file.");
608
609   llvm::Expected<TypeSystem &> type_system_or_err =
610       symfile->GetTypeSystemForLanguage(eLanguageTypeC_plus_plus);
611   if (!type_system_or_err)
612     return make_string_error("Can't retrieve TypeSystemClang");
613
614   auto *clang_ast_ctx =
615       llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
616   if (!clang_ast_ctx)
617     return make_string_error("Retrieved TypeSystem was not a TypeSystemClang");
618
619   clang::ASTContext &ast_ctx = clang_ast_ctx->getASTContext();
620
621   clang::TranslationUnitDecl *tu = ast_ctx.getTranslationUnitDecl();
622   if (!tu)
623     return make_string_error("Can't retrieve translation unit declaration.");
624
625   tu->print(outs());
626
627   return Error::success();
628 }
629
630 Error opts::symbols::dumpEntireClangAST(lldb_private::Module &Module) {
631   Module.ParseAllDebugSymbols();
632
633   SymbolFile *symfile = Module.GetSymbolFile();
634   if (!symfile)
635     return make_string_error("Module has no symbol file.");
636
637   llvm::Expected<TypeSystem &> type_system_or_err =
638       symfile->GetTypeSystemForLanguage(eLanguageTypeObjC_plus_plus);
639   if (!type_system_or_err)
640     return make_string_error("Can't retrieve TypeSystemClang");
641
642   auto *clang_ast_ctx =
643       llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
644   if (!clang_ast_ctx)
645     return make_string_error("Retrieved TypeSystem was not a TypeSystemClang");
646
647   StreamString Stream;
648   clang_ast_ctx->DumpFromSymbolFile(Stream, Name);
649   outs() << Stream.GetData() << "\n";
650
651   return Error::success();
652 }
653
654 Error opts::symbols::verify(lldb_private::Module &Module) {
655   SymbolFile *symfile = Module.GetSymbolFile();
656   if (!symfile)
657     return make_string_error("Module has no symbol file.");
658
659   uint32_t comp_units_count = symfile->GetNumCompileUnits();
660
661   outs() << "Found " << comp_units_count << " compile units.\n";
662
663   for (uint32_t i = 0; i < comp_units_count; i++) {
664     lldb::CompUnitSP comp_unit = symfile->GetCompileUnitAtIndex(i);
665     if (!comp_unit)
666       return make_string_error("Cannot parse compile unit {0}.", i);
667
668     outs() << "Processing '"
669            << comp_unit->GetPrimaryFile().GetFilename().AsCString()
670            << "' compile unit.\n";
671
672     LineTable *lt = comp_unit->GetLineTable();
673     if (!lt)
674       return make_string_error("Can't get a line table of a compile unit.");
675
676     uint32_t count = lt->GetSize();
677
678     outs() << "The line table contains " << count << " entries.\n";
679
680     if (count == 0)
681       continue;
682
683     LineEntry le;
684     if (!lt->GetLineEntryAtIndex(0, le))
685       return make_string_error("Can't get a line entry of a compile unit.");
686
687     for (uint32_t i = 1; i < count; i++) {
688       lldb::addr_t curr_end =
689           le.range.GetBaseAddress().GetFileAddress() + le.range.GetByteSize();
690
691       if (!lt->GetLineEntryAtIndex(i, le))
692         return make_string_error("Can't get a line entry of a compile unit");
693
694       if (curr_end > le.range.GetBaseAddress().GetFileAddress())
695         return make_string_error(
696             "Line table of a compile unit is inconsistent.");
697     }
698   }
699
700   outs() << "The symbol information is verified.\n";
701
702   return Error::success();
703 }
704
705 Expected<Error (*)(lldb_private::Module &)> opts::symbols::getAction() {
706   if (Verify && DumpAST)
707     return make_string_error(
708         "Cannot both verify symbol information and dump AST.");
709
710   if (Verify) {
711     if (Find != FindType::None)
712       return make_string_error(
713           "Cannot both search and verify symbol information.");
714     if (Regex || !Context.empty() || !Name.empty() || !File.empty() ||
715         Line != 0)
716       return make_string_error(
717           "-regex, -context, -name, -file and -line options are not "
718           "applicable for symbol verification.");
719     return verify;
720   }
721
722   if (DumpAST) {
723     if (Find != FindType::None)
724       return make_string_error("Cannot both search and dump AST.");
725     if (Regex || !Context.empty() || !Name.empty() || !File.empty() ||
726         Line != 0)
727       return make_string_error(
728           "-regex, -context, -name, -file and -line options are not "
729           "applicable for dumping AST.");
730     return dumpAST;
731   }
732
733   if (DumpClangAST) {
734     if (Find == FindType::None) {
735       if (Regex || !Context.empty() || !File.empty() || Line != 0)
736         return make_string_error(
737             "-regex, -context, -name, -file and -line options are not "
738             "applicable for dumping the entire clang AST. Either combine with "
739             "-find, or use -dump-clang-ast as a standalone option.");
740       return dumpEntireClangAST;
741     }
742     if (Find != FindType::Type)
743       return make_string_error("This combination of -dump-clang-ast and -find "
744                                "<kind> is not yet implemented.");
745   }
746
747   if (Regex && !Context.empty())
748     return make_string_error(
749         "Cannot search using both regular expressions and context.");
750
751   if (Regex && !RegularExpression(Name).IsValid())
752     return make_string_error("`{0}` is not a valid regular expression.", Name);
753
754   if (Regex + !Context.empty() + !File.empty() >= 2)
755     return make_string_error(
756         "Only one of -regex, -context and -file may be used simultaneously.");
757   if (Regex && Name.empty())
758     return make_string_error("-regex used without a -name");
759
760   switch (Find) {
761   case FindType::None:
762     if (!Context.empty() || !Name.empty() || !File.empty() || Line != 0)
763       return make_string_error(
764           "Specify search type (-find) to use search options.");
765     return dumpModule;
766
767   case FindType::Function:
768     if (!File.empty() + (Line != 0) == 1)
769       return make_string_error("Both file name and line number must be "
770                                "specified when searching a function "
771                                "by file position.");
772     if (Regex + (getFunctionNameFlags() != 0) + !File.empty() >= 2)
773       return make_string_error("Only one of regular expression, function-flags "
774                                "and file position may be used simultaneously "
775                                "when searching a function.");
776     return findFunctions;
777
778   case FindType::Block:
779     if (File.empty() || Line == 0)
780       return make_string_error("Both file name and line number must be "
781                                "specified when searching a block.");
782     if (Regex || getFunctionNameFlags() != 0)
783       return make_string_error("Cannot use regular expression or "
784                                "function-flags for searching a block.");
785     return findBlocks;
786
787   case FindType::Namespace:
788     if (Regex || !File.empty() || Line != 0)
789       return make_string_error("Cannot search for namespaces using regular "
790                                "expressions, file names or line numbers.");
791     return findNamespaces;
792
793   case FindType::Type:
794     if (Regex || !File.empty() || Line != 0)
795       return make_string_error("Cannot search for types using regular "
796                                "expressions, file names or line numbers.");
797     if (!Name.empty() && !CompilerContext.empty())
798       return make_string_error("Name is ignored if compiler context present.");
799
800     return findTypes;
801
802   case FindType::Variable:
803     if (Line != 0)
804       return make_string_error("Cannot search for variables "
805                                "using line numbers.");
806     return findVariables;
807   }
808
809   llvm_unreachable("Unsupported symbol action.");
810 }
811
812 int opts::symbols::dumpSymbols(Debugger &Dbg) {
813   auto ActionOr = getAction();
814   if (!ActionOr) {
815     logAllUnhandledErrors(ActionOr.takeError(), WithColor::error(), "");
816     return 1;
817   }
818   auto Action = *ActionOr;
819
820   outs() << "Module: " << InputFile << "\n";
821   ModuleSpec Spec{FileSpec(InputFile)};
822   StringRef Symbols = SymbolPath.empty() ? InputFile : SymbolPath;
823   Spec.GetSymbolFileSpec().SetFile(Symbols, FileSpec::Style::native);
824
825   auto ModulePtr = std::make_shared<lldb_private::Module>(Spec);
826   SymbolFile *Symfile = ModulePtr->GetSymbolFile();
827   if (!Symfile) {
828     WithColor::error() << "Module has no symbol vendor.\n";
829     return 1;
830   }
831
832   if (Error E = Action(*ModulePtr)) {
833     WithColor::error() << toString(std::move(E)) << "\n";
834     return 1;
835   }
836
837   return 0;
838 }
839
840 static void dumpSectionList(LinePrinter &Printer, const SectionList &List, bool is_subsection) {
841   size_t Count = List.GetNumSections(0);
842   if (Count == 0) {
843     Printer.formatLine("There are no {0}sections", is_subsection ? "sub" : "");
844     return;
845   }
846   Printer.formatLine("Showing {0} {1}sections", Count,
847                      is_subsection ? "sub" : "");
848   for (size_t I = 0; I < Count; ++I) {
849     auto S = List.GetSectionAtIndex(I);
850     assert(S);
851     AutoIndent Indent(Printer, 2);
852     Printer.formatLine("Index: {0}", I);
853     Printer.formatLine("ID: {0:x}", S->GetID());
854     Printer.formatLine("Name: {0}", S->GetName().GetStringRef());
855     Printer.formatLine("Type: {0}", S->GetTypeAsCString());
856     Printer.formatLine("Permissions: {0}", GetPermissionsAsCString(S->GetPermissions()));
857     Printer.formatLine("Thread specific: {0:y}", S->IsThreadSpecific());
858     Printer.formatLine("VM address: {0:x}", S->GetFileAddress());
859     Printer.formatLine("VM size: {0}", S->GetByteSize());
860     Printer.formatLine("File size: {0}", S->GetFileSize());
861
862     if (opts::object::SectionContents) {
863       lldb_private::DataExtractor Data;
864       S->GetSectionData(Data);
865       ArrayRef<uint8_t> Bytes(Data.GetDataStart(), Data.GetDataEnd());
866       Printer.formatBinary("Data: ", Bytes, 0);
867     }
868
869     if (S->GetType() == eSectionTypeContainer)
870       dumpSectionList(Printer, S->GetChildren(), true);
871     Printer.NewLine();
872   }
873 }
874
875 static int dumpObjectFiles(Debugger &Dbg) {
876   LinePrinter Printer(4, llvm::outs());
877
878   int HadErrors = 0;
879   for (const auto &File : opts::object::InputFilenames) {
880     ModuleSpec Spec{FileSpec(File)};
881
882     auto ModulePtr = std::make_shared<lldb_private::Module>(Spec);
883
884     ObjectFile *ObjectPtr = ModulePtr->GetObjectFile();
885     if (!ObjectPtr) {
886       WithColor::error() << File << " not recognised as an object file\n";
887       HadErrors = 1;
888       continue;
889     }
890
891     // Fetch symbol vendor before we get the section list to give the symbol
892     // vendor a chance to populate it.
893     ModulePtr->GetSymbolFile();
894     SectionList *Sections = ModulePtr->GetSectionList();
895     if (!Sections) {
896       llvm::errs() << "Could not load sections for module " << File << "\n";
897       HadErrors = 1;
898       continue;
899     }
900
901     Printer.formatLine("Plugin name: {0}", ObjectPtr->GetPluginName());
902     Printer.formatLine("Architecture: {0}",
903                        ModulePtr->GetArchitecture().GetTriple().getTriple());
904     Printer.formatLine("UUID: {0}", ModulePtr->GetUUID().GetAsString());
905     Printer.formatLine("Executable: {0}", ObjectPtr->IsExecutable());
906     Printer.formatLine("Stripped: {0}", ObjectPtr->IsStripped());
907     Printer.formatLine("Type: {0}", ObjectPtr->GetType());
908     Printer.formatLine("Strata: {0}", ObjectPtr->GetStrata());
909     Printer.formatLine("Base VM address: {0:x}",
910                        ObjectPtr->GetBaseAddress().GetFileAddress());
911
912     dumpSectionList(Printer, *Sections, /*is_subsection*/ false);
913
914     if (opts::object::SectionDependentModules) {
915       // A non-empty section list ensures a valid object file.
916       auto Obj = ModulePtr->GetObjectFile();
917       FileSpecList Files;
918       auto Count = Obj->GetDependentModules(Files);
919       Printer.formatLine("Showing {0} dependent module(s)", Count);
920       for (size_t I = 0; I < Files.GetSize(); ++I) {
921         AutoIndent Indent(Printer, 2);
922         Printer.formatLine("Name: {0}",
923                            Files.GetFileSpecAtIndex(I).GetCString());
924       }
925       Printer.NewLine();
926     }
927   }
928   return HadErrors;
929 }
930
931 bool opts::irmemorymap::evalMalloc(StringRef Line,
932                                    IRMemoryMapTestState &State) {
933   // ::= <label> = malloc <size> <alignment>
934   StringRef Label;
935   std::tie(Label, Line) = Line.split('=');
936   if (Line.empty())
937     return false;
938   Label = Label.trim();
939   Line = Line.trim();
940   size_t Size;
941   uint8_t Alignment;
942   int Matches = sscanf(Line.data(), "malloc %zu %hhu", &Size, &Alignment);
943   if (Matches != 2)
944     return false;
945
946   outs() << formatv("Command: {0} = malloc(size={1}, alignment={2})\n", Label,
947                     Size, Alignment);
948   if (!isPowerOf2_32(Alignment)) {
949     outs() << "Malloc error: alignment is not a power of 2\n";
950     exit(1);
951   }
952
953   IRMemoryMap::AllocationPolicy AP =
954       UseHostOnlyAllocationPolicy ? IRMemoryMap::eAllocationPolicyHostOnly
955                                   : IRMemoryMap::eAllocationPolicyProcessOnly;
956
957   // Issue the malloc in the target process with "-rw" permissions.
958   const uint32_t Permissions = 0x3;
959   const bool ZeroMemory = false;
960   Status ST;
961   addr_t Addr =
962       State.Map.Malloc(Size, Alignment, Permissions, AP, ZeroMemory, ST);
963   if (ST.Fail()) {
964     outs() << formatv("Malloc error: {0}\n", ST);
965     return true;
966   }
967
968   // Print the result of the allocation before checking its validity.
969   outs() << formatv("Malloc: address = {0:x}\n", Addr);
970
971   // Check that the allocation is aligned.
972   if (!Addr || Addr % Alignment != 0) {
973     outs() << "Malloc error: zero or unaligned allocation detected\n";
974     exit(1);
975   }
976
977   // In case of Size == 0, we still expect the returned address to be unique and
978   // non-overlapping.
979   addr_t EndOfRegion = Addr + std::max<size_t>(Size, 1);
980   if (State.Allocations.overlaps(Addr, EndOfRegion)) {
981     auto I = State.Allocations.find(Addr);
982     outs() << "Malloc error: overlapping allocation detected"
983            << formatv(", previous allocation at [{0:x}, {1:x})\n", I.start(),
984                       I.stop());
985     exit(1);
986   }
987
988   // Insert the new allocation into the interval map. Use unique allocation
989   // IDs to inhibit interval coalescing.
990   static unsigned AllocationID = 0;
991   State.Allocations.insert(Addr, EndOfRegion, AllocationID++);
992
993   // Store the label -> address mapping.
994   State.Label2AddrMap[Label] = Addr;
995
996   return true;
997 }
998
999 bool opts::irmemorymap::evalFree(StringRef Line, IRMemoryMapTestState &State) {
1000   // ::= free <label>
1001   if (!Line.consume_front("free"))
1002     return false;
1003   StringRef Label = Line.trim();
1004
1005   outs() << formatv("Command: free({0})\n", Label);
1006   auto LabelIt = State.Label2AddrMap.find(Label);
1007   if (LabelIt == State.Label2AddrMap.end()) {
1008     outs() << "Free error: Invalid allocation label\n";
1009     exit(1);
1010   }
1011
1012   Status ST;
1013   addr_t Addr = LabelIt->getValue();
1014   State.Map.Free(Addr, ST);
1015   if (ST.Fail()) {
1016     outs() << formatv("Free error: {0}\n", ST);
1017     exit(1);
1018   }
1019
1020   // Erase the allocation from the live interval map.
1021   auto Interval = State.Allocations.find(Addr);
1022   if (Interval != State.Allocations.end()) {
1023     outs() << formatv("Free: [{0:x}, {1:x})\n", Interval.start(),
1024                       Interval.stop());
1025     Interval.erase();
1026   }
1027
1028   return true;
1029 }
1030
1031 int opts::irmemorymap::evaluateMemoryMapCommands(Debugger &Dbg) {
1032   // Set up a Target.
1033   TargetSP Target = opts::createTarget(Dbg, irmemorymap::Target);
1034
1035   // Set up a Process. In order to allocate memory within a target, this
1036   // process must be alive and must support JIT'ing.
1037   CommandReturnObject Result(/*colors*/ false);
1038   Dbg.SetAsyncExecution(false);
1039   CommandInterpreter &CI = Dbg.GetCommandInterpreter();
1040   auto IssueCmd = [&](const char *Cmd) -> bool {
1041     return CI.HandleCommand(Cmd, eLazyBoolNo, Result);
1042   };
1043   if (!IssueCmd("b main") || !IssueCmd("run")) {
1044     outs() << formatv("Failed: {0}\n", Result.GetErrorData());
1045     exit(1);
1046   }
1047
1048   ProcessSP Process = Target->GetProcessSP();
1049   if (!Process || !Process->IsAlive() || !Process->CanJIT()) {
1050     outs() << "Cannot use process to test IRMemoryMap\n";
1051     exit(1);
1052   }
1053
1054   // Set up an IRMemoryMap and associated testing state.
1055   IRMemoryMapTestState State(Target);
1056
1057   // Parse and apply commands from the command file.
1058   std::unique_ptr<MemoryBuffer> MB = opts::openFile(irmemorymap::CommandFile);
1059   StringRef Rest = MB->getBuffer();
1060   while (!Rest.empty()) {
1061     StringRef Line;
1062     std::tie(Line, Rest) = Rest.split('\n');
1063     Line = Line.ltrim().rtrim();
1064
1065     if (Line.empty() || Line[0] == '#')
1066       continue;
1067
1068     if (evalMalloc(Line, State))
1069       continue;
1070
1071     if (evalFree(Line, State))
1072       continue;
1073
1074     errs() << "Could not parse line: " << Line << "\n";
1075     exit(1);
1076   }
1077   return 0;
1078 }
1079
1080 int main(int argc, const char *argv[]) {
1081   StringRef ToolName = argv[0];
1082   sys::PrintStackTraceOnErrorSignal(ToolName);
1083   PrettyStackTraceProgram X(argc, argv);
1084   llvm_shutdown_obj Y;
1085
1086   cl::ParseCommandLineOptions(argc, argv, "LLDB Testing Utility\n");
1087
1088   SystemLifetimeManager DebuggerLifetime;
1089   if (auto e = DebuggerLifetime.Initialize(
1090           std::make_unique<SystemInitializerTest>(), nullptr)) {
1091     WithColor::error() << "initialization failed: " << toString(std::move(e))
1092                        << '\n';
1093     return 1;
1094   }
1095
1096   auto TerminateDebugger =
1097       llvm::make_scope_exit([&] { DebuggerLifetime.Terminate(); });
1098
1099   auto Dbg = lldb_private::Debugger::CreateInstance();
1100   ModuleList::GetGlobalModuleListProperties().SetEnableExternalLookup(false);
1101   CommandReturnObject Result(/*colors*/ false);
1102   Dbg->GetCommandInterpreter().HandleCommand(
1103       "settings set plugin.process.gdb-remote.packet-timeout 60",
1104       /*add_to_history*/ eLazyBoolNo, Result);
1105   Dbg->GetCommandInterpreter().HandleCommand(
1106       "settings set target.inherit-tcc true",
1107       /*add_to_history*/ eLazyBoolNo, Result);
1108   Dbg->GetCommandInterpreter().HandleCommand(
1109       "settings set target.detach-on-error false",
1110       /*add_to_history*/ eLazyBoolNo, Result);
1111
1112   if (!opts::Log.empty())
1113     Dbg->EnableLog("lldb", {"all"}, opts::Log, 0, errs());
1114
1115   if (opts::BreakpointSubcommand)
1116     return opts::breakpoint::evaluateBreakpoints(*Dbg);
1117   if (opts::ObjectFileSubcommand)
1118     return dumpObjectFiles(*Dbg);
1119   if (opts::SymbolsSubcommand)
1120     return opts::symbols::dumpSymbols(*Dbg);
1121   if (opts::IRMemoryMapSubcommand)
1122     return opts::irmemorymap::evaluateMemoryMapCommands(*Dbg);
1123
1124   WithColor::error() << "No command specified.\n";
1125   return 1;
1126 }