]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Commands/CommandObjectTarget.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Commands / CommandObjectTarget.cpp
1 //===-- CommandObjectTarget.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 "CommandObjectTarget.h"
11
12 #include "lldb/Core/Debugger.h"
13 #include "lldb/Core/IOHandler.h"
14 #include "lldb/Core/Module.h"
15 #include "lldb/Core/ModuleSpec.h"
16 #include "lldb/Core/Section.h"
17 #include "lldb/Core/ValueObjectVariable.h"
18 #include "lldb/DataFormatters/ValueObjectPrinter.h"
19 #include "lldb/Host/OptionParser.h"
20 #include "lldb/Host/StringConvert.h"
21 #include "lldb/Host/Symbols.h"
22 #include "lldb/Interpreter/CommandInterpreter.h"
23 #include "lldb/Interpreter/CommandReturnObject.h"
24 #include "lldb/Interpreter/OptionArgParser.h"
25 #include "lldb/Interpreter/OptionGroupArchitecture.h"
26 #include "lldb/Interpreter/OptionGroupBoolean.h"
27 #include "lldb/Interpreter/OptionGroupFile.h"
28 #include "lldb/Interpreter/OptionGroupFormat.h"
29 #include "lldb/Interpreter/OptionGroupPlatform.h"
30 #include "lldb/Interpreter/OptionGroupString.h"
31 #include "lldb/Interpreter/OptionGroupUInt64.h"
32 #include "lldb/Interpreter/OptionGroupUUID.h"
33 #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
34 #include "lldb/Interpreter/OptionGroupVariable.h"
35 #include "lldb/Interpreter/Options.h"
36 #include "lldb/Symbol/CompileUnit.h"
37 #include "lldb/Symbol/FuncUnwinders.h"
38 #include "lldb/Symbol/LineTable.h"
39 #include "lldb/Symbol/ObjectFile.h"
40 #include "lldb/Symbol/SymbolFile.h"
41 #include "lldb/Symbol/SymbolVendor.h"
42 #include "lldb/Symbol/UnwindPlan.h"
43 #include "lldb/Symbol/VariableList.h"
44 #include "lldb/Target/ABI.h"
45 #include "lldb/Target/Process.h"
46 #include "lldb/Target/RegisterContext.h"
47 #include "lldb/Target/SectionLoadList.h"
48 #include "lldb/Target/StackFrame.h"
49 #include "lldb/Target/Thread.h"
50 #include "lldb/Target/ThreadSpec.h"
51 #include "lldb/Utility/Args.h"
52 #include "lldb/Utility/State.h"
53 #include "lldb/Utility/Timer.h"
54
55 #include "llvm/Support/FileSystem.h"
56 #include "llvm/Support/FormatAdapters.h"
57
58 #include <cerrno>
59
60 using namespace lldb;
61 using namespace lldb_private;
62
63 static void DumpTargetInfo(uint32_t target_idx, Target *target,
64                            const char *prefix_cstr,
65                            bool show_stopped_process_status, Stream &strm) {
66   const ArchSpec &target_arch = target->GetArchitecture();
67
68   Module *exe_module = target->GetExecutableModulePointer();
69   char exe_path[PATH_MAX];
70   bool exe_valid = false;
71   if (exe_module)
72     exe_valid = exe_module->GetFileSpec().GetPath(exe_path, sizeof(exe_path));
73
74   if (!exe_valid)
75     ::strcpy(exe_path, "<none>");
76
77   strm.Printf("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx,
78               exe_path);
79
80   uint32_t properties = 0;
81   if (target_arch.IsValid()) {
82     strm.Printf("%sarch=", properties++ > 0 ? ", " : " ( ");
83     target_arch.DumpTriple(strm);
84     properties++;
85   }
86   PlatformSP platform_sp(target->GetPlatform());
87   if (platform_sp)
88     strm.Printf("%splatform=%s", properties++ > 0 ? ", " : " ( ",
89                 platform_sp->GetName().GetCString());
90
91   ProcessSP process_sp(target->GetProcessSP());
92   bool show_process_status = false;
93   if (process_sp) {
94     lldb::pid_t pid = process_sp->GetID();
95     StateType state = process_sp->GetState();
96     if (show_stopped_process_status)
97       show_process_status = StateIsStoppedState(state, true);
98     const char *state_cstr = StateAsCString(state);
99     if (pid != LLDB_INVALID_PROCESS_ID)
100       strm.Printf("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid);
101     strm.Printf("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
102   }
103   if (properties > 0)
104     strm.PutCString(" )\n");
105   else
106     strm.EOL();
107   if (show_process_status) {
108     const bool only_threads_with_stop_reason = true;
109     const uint32_t start_frame = 0;
110     const uint32_t num_frames = 1;
111     const uint32_t num_frames_with_source = 1;
112     const bool     stop_format = false;
113     process_sp->GetStatus(strm);
114     process_sp->GetThreadStatus(strm, only_threads_with_stop_reason,
115                                 start_frame, num_frames,
116                                 num_frames_with_source, stop_format);
117   }
118 }
119
120 static uint32_t DumpTargetList(TargetList &target_list,
121                                bool show_stopped_process_status, Stream &strm) {
122   const uint32_t num_targets = target_list.GetNumTargets();
123   if (num_targets) {
124     TargetSP selected_target_sp(target_list.GetSelectedTarget());
125     strm.PutCString("Current targets:\n");
126     for (uint32_t i = 0; i < num_targets; ++i) {
127       TargetSP target_sp(target_list.GetTargetAtIndex(i));
128       if (target_sp) {
129         bool is_selected = target_sp.get() == selected_target_sp.get();
130         DumpTargetInfo(i, target_sp.get(), is_selected ? "* " : "  ",
131                        show_stopped_process_status, strm);
132       }
133     }
134   }
135   return num_targets;
136 }
137
138 // Note that the negation in the argument name causes a slightly confusing
139 // mapping of the enum values,
140 static constexpr OptionEnumValueElement g_dependents_enumaration[] = {
141     {eLoadDependentsDefault, "default",
142      "Only load dependents when the target is an executable."},
143     {eLoadDependentsNo, "true",
144      "Don't load dependents, even if the target is an executable."},
145     {eLoadDependentsYes, "false",
146      "Load dependents, even if the target is not an executable."}};
147
148 static constexpr OptionDefinition g_dependents_options[] = {
149     {LLDB_OPT_SET_1, false, "no-dependents", 'd',
150      OptionParser::eOptionalArgument, nullptr,
151      OptionEnumValues(g_dependents_enumaration), 0, eArgTypeValue,
152      "Whether or not to load dependents when creating a target. If the option "
153      "is not specified, the value is implicitly 'default'. If the option is "
154      "specified but without a value, the value is implicitly 'true'."}};
155
156 class OptionGroupDependents : public OptionGroup {
157 public:
158   OptionGroupDependents() {}
159
160   ~OptionGroupDependents() override {}
161
162   llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
163     return llvm::makeArrayRef(g_dependents_options);
164   }
165
166   Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
167                         ExecutionContext *execution_context) override {
168     Status error;
169
170     // For compatibility no value means don't load dependents.
171     if (option_value.empty()) {
172       m_load_dependent_files = eLoadDependentsNo;
173       return error;
174     }
175
176     const char short_option = g_dependents_options[option_idx].short_option;
177     if (short_option == 'd') {
178       LoadDependentFiles tmp_load_dependents;
179       tmp_load_dependents = (LoadDependentFiles)OptionArgParser::ToOptionEnum(
180           option_value, g_dependents_options[option_idx].enum_values, 0, error);
181       if (error.Success())
182         m_load_dependent_files = tmp_load_dependents;
183     } else {
184       error.SetErrorStringWithFormat("unrecognized short option '%c'",
185                                      short_option);
186     }
187
188     return error;
189   }
190
191   Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete;
192
193   void OptionParsingStarting(ExecutionContext *execution_context) override {
194     m_load_dependent_files = eLoadDependentsDefault;
195   }
196
197   LoadDependentFiles m_load_dependent_files;
198
199 private:
200   DISALLOW_COPY_AND_ASSIGN(OptionGroupDependents);
201 };
202
203 #pragma mark CommandObjectTargetCreate
204
205 //-------------------------------------------------------------------------
206 // "target create"
207 //-------------------------------------------------------------------------
208
209 class CommandObjectTargetCreate : public CommandObjectParsed {
210 public:
211   CommandObjectTargetCreate(CommandInterpreter &interpreter)
212       : CommandObjectParsed(
213             interpreter, "target create",
214             "Create a target using the argument as the main executable.",
215             nullptr),
216         m_option_group(), m_arch_option(),
217         m_core_file(LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename,
218                     "Fullpath to a core file to use for this target."),
219         m_platform_path(LLDB_OPT_SET_1, false, "platform-path", 'P', 0,
220                         eArgTypePath,
221                         "Path to the remote file to use for this target."),
222         m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
223                       eArgTypeFilename,
224                       "Fullpath to a stand alone debug "
225                       "symbols file for when debug symbols "
226                       "are not in the executable."),
227         m_remote_file(
228             LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename,
229             "Fullpath to the file on the remote host if debugging remotely."),
230         m_add_dependents() {
231     CommandArgumentEntry arg;
232     CommandArgumentData file_arg;
233
234     // Define the first (and only) variant of this arg.
235     file_arg.arg_type = eArgTypeFilename;
236     file_arg.arg_repetition = eArgRepeatPlain;
237
238     // There is only one variant this argument could be; put it into the
239     // argument entry.
240     arg.push_back(file_arg);
241
242     // Push the data for the first argument into the m_arguments vector.
243     m_arguments.push_back(arg);
244
245     m_option_group.Append(&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
246     m_option_group.Append(&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
247     m_option_group.Append(&m_platform_path, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
248     m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
249     m_option_group.Append(&m_remote_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
250     m_option_group.Append(&m_add_dependents, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
251     m_option_group.Finalize();
252   }
253
254   ~CommandObjectTargetCreate() override = default;
255
256   Options *GetOptions() override { return &m_option_group; }
257
258   int HandleArgumentCompletion(
259       CompletionRequest &request,
260       OptionElementVector &opt_element_vector) override {
261     CommandCompletions::InvokeCommonCompletionCallbacks(
262         GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
263         request, nullptr);
264     return request.GetNumberOfMatches();
265   }
266
267 protected:
268   bool DoExecute(Args &command, CommandReturnObject &result) override {
269     const size_t argc = command.GetArgumentCount();
270     FileSpec core_file(m_core_file.GetOptionValue().GetCurrentValue());
271     FileSpec remote_file(m_remote_file.GetOptionValue().GetCurrentValue());
272
273     if (core_file) {
274       if (!FileSystem::Instance().Exists(core_file)) {
275         result.AppendErrorWithFormat("core file '%s' doesn't exist",
276                                      core_file.GetPath().c_str());
277         result.SetStatus(eReturnStatusFailed);
278         return false;
279       }
280       if (!FileSystem::Instance().Readable(core_file)) {
281         result.AppendErrorWithFormat("core file '%s' is not readable",
282                                      core_file.GetPath().c_str());
283         result.SetStatus(eReturnStatusFailed);
284         return false;
285       }
286     }
287
288     if (argc == 1 || core_file || remote_file) {
289       FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue());
290       if (symfile) {
291         if (FileSystem::Instance().Exists(symfile)) {
292           if (!FileSystem::Instance().Readable(symfile)) {
293             result.AppendErrorWithFormat("symbol file '%s' is not readable",
294                                          symfile.GetPath().c_str());
295             result.SetStatus(eReturnStatusFailed);
296             return false;
297           }
298         } else {
299           char symfile_path[PATH_MAX];
300           symfile.GetPath(symfile_path, sizeof(symfile_path));
301           result.AppendErrorWithFormat("invalid symbol file path '%s'",
302                                        symfile_path);
303           result.SetStatus(eReturnStatusFailed);
304           return false;
305         }
306       }
307
308       const char *file_path = command.GetArgumentAtIndex(0);
309       static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
310       Timer scoped_timer(func_cat, "(lldb) target create '%s'", file_path);
311       FileSpec file_spec;
312
313       if (file_path) {
314         file_spec.SetFile(file_path, FileSpec::Style::native);
315         FileSystem::Instance().Resolve(file_spec);
316       }
317
318       bool must_set_platform_path = false;
319
320       Debugger &debugger = m_interpreter.GetDebugger();
321
322       TargetSP target_sp;
323       llvm::StringRef arch_cstr = m_arch_option.GetArchitectureName();
324       Status error(debugger.GetTargetList().CreateTarget(
325           debugger, file_path, arch_cstr,
326           m_add_dependents.m_load_dependent_files, nullptr, target_sp));
327
328       if (target_sp) {
329         // Only get the platform after we create the target because we might
330         // have switched platforms depending on what the arguments were to
331         // CreateTarget() we can't rely on the selected platform.
332
333         PlatformSP platform_sp = target_sp->GetPlatform();
334
335         if (remote_file) {
336           if (platform_sp) {
337             // I have a remote file.. two possible cases
338             if (file_spec && FileSystem::Instance().Exists(file_spec)) {
339               // if the remote file does not exist, push it there
340               if (!platform_sp->GetFileExists(remote_file)) {
341                 Status err = platform_sp->PutFile(file_spec, remote_file);
342                 if (err.Fail()) {
343                   result.AppendError(err.AsCString());
344                   result.SetStatus(eReturnStatusFailed);
345                   return false;
346                 }
347               }
348             } else {
349               // there is no local file and we need one
350               // in order to make the remote ---> local transfer we need a
351               // platform
352               // TODO: if the user has passed in a --platform argument, use it
353               // to fetch the right platform
354               if (!platform_sp) {
355                 result.AppendError(
356                     "unable to perform remote debugging without a platform");
357                 result.SetStatus(eReturnStatusFailed);
358                 return false;
359               }
360               if (file_path) {
361                 // copy the remote file to the local file
362                 Status err = platform_sp->GetFile(remote_file, file_spec);
363                 if (err.Fail()) {
364                   result.AppendError(err.AsCString());
365                   result.SetStatus(eReturnStatusFailed);
366                   return false;
367                 }
368               } else {
369                 // make up a local file
370                 result.AppendError("remote --> local transfer without local "
371                                    "path is not implemented yet");
372                 result.SetStatus(eReturnStatusFailed);
373                 return false;
374               }
375             }
376           } else {
377             result.AppendError("no platform found for target");
378             result.SetStatus(eReturnStatusFailed);
379             return false;
380           }
381         }
382
383         if (symfile || remote_file) {
384           ModuleSP module_sp(target_sp->GetExecutableModule());
385           if (module_sp) {
386             if (symfile)
387               module_sp->SetSymbolFileFileSpec(symfile);
388             if (remote_file) {
389               std::string remote_path = remote_file.GetPath();
390               target_sp->SetArg0(remote_path.c_str());
391               module_sp->SetPlatformFileSpec(remote_file);
392             }
393           }
394         }
395
396         debugger.GetTargetList().SetSelectedTarget(target_sp.get());
397         if (must_set_platform_path) {
398           ModuleSpec main_module_spec(file_spec);
399           ModuleSP module_sp = target_sp->GetSharedModule(main_module_spec);
400           if (module_sp)
401             module_sp->SetPlatformFileSpec(remote_file);
402         }
403         if (core_file) {
404           char core_path[PATH_MAX];
405           core_file.GetPath(core_path, sizeof(core_path));
406           if (FileSystem::Instance().Exists(core_file)) {
407             if (!FileSystem::Instance().Readable(core_file)) {
408               result.AppendMessageWithFormat(
409                   "Core file '%s' is not readable.\n", core_path);
410               result.SetStatus(eReturnStatusFailed);
411               return false;
412             }
413             FileSpec core_file_dir;
414             core_file_dir.GetDirectory() = core_file.GetDirectory();
415             target_sp->GetExecutableSearchPaths().Append(core_file_dir);
416
417             ProcessSP process_sp(target_sp->CreateProcess(
418                 m_interpreter.GetDebugger().GetListener(), llvm::StringRef(),
419                 &core_file));
420
421             if (process_sp) {
422               // Seems weird that we Launch a core file, but that is what we
423               // do!
424               error = process_sp->LoadCore();
425
426               if (error.Fail()) {
427                 result.AppendError(
428                     error.AsCString("can't find plug-in for core file"));
429                 result.SetStatus(eReturnStatusFailed);
430                 return false;
431               } else {
432                 result.AppendMessageWithFormat(
433                     "Core file '%s' (%s) was loaded.\n", core_path,
434                     target_sp->GetArchitecture().GetArchitectureName());
435                 result.SetStatus(eReturnStatusSuccessFinishNoResult);
436               }
437             } else {
438               result.AppendErrorWithFormat(
439                   "Unable to find process plug-in for core file '%s'\n",
440                   core_path);
441               result.SetStatus(eReturnStatusFailed);
442             }
443           } else {
444             result.AppendErrorWithFormat("Core file '%s' does not exist\n",
445                                          core_path);
446             result.SetStatus(eReturnStatusFailed);
447           }
448         } else {
449           result.AppendMessageWithFormat(
450               "Current executable set to '%s' (%s).\n", file_path,
451               target_sp->GetArchitecture().GetArchitectureName());
452           result.SetStatus(eReturnStatusSuccessFinishNoResult);
453         }
454       } else {
455         result.AppendError(error.AsCString());
456         result.SetStatus(eReturnStatusFailed);
457       }
458     } else {
459       result.AppendErrorWithFormat("'%s' takes exactly one executable path "
460                                    "argument, or use the --core option.\n",
461                                    m_cmd_name.c_str());
462       result.SetStatus(eReturnStatusFailed);
463     }
464     return result.Succeeded();
465   }
466
467 private:
468   OptionGroupOptions m_option_group;
469   OptionGroupArchitecture m_arch_option;
470   OptionGroupFile m_core_file;
471   OptionGroupFile m_platform_path;
472   OptionGroupFile m_symbol_file;
473   OptionGroupFile m_remote_file;
474   OptionGroupDependents m_add_dependents;
475 };
476
477 #pragma mark CommandObjectTargetList
478
479 //----------------------------------------------------------------------
480 // "target list"
481 //----------------------------------------------------------------------
482
483 class CommandObjectTargetList : public CommandObjectParsed {
484 public:
485   CommandObjectTargetList(CommandInterpreter &interpreter)
486       : CommandObjectParsed(
487             interpreter, "target list",
488             "List all current targets in the current debug session.", nullptr) {
489   }
490
491   ~CommandObjectTargetList() override = default;
492
493 protected:
494   bool DoExecute(Args &args, CommandReturnObject &result) override {
495     if (args.GetArgumentCount() == 0) {
496       Stream &strm = result.GetOutputStream();
497
498       bool show_stopped_process_status = false;
499       if (DumpTargetList(m_interpreter.GetDebugger().GetTargetList(),
500                          show_stopped_process_status, strm) == 0) {
501         strm.PutCString("No targets.\n");
502       }
503       result.SetStatus(eReturnStatusSuccessFinishResult);
504     } else {
505       result.AppendError("the 'target list' command takes no arguments\n");
506       result.SetStatus(eReturnStatusFailed);
507     }
508     return result.Succeeded();
509   }
510 };
511
512 #pragma mark CommandObjectTargetSelect
513
514 //----------------------------------------------------------------------
515 // "target select"
516 //----------------------------------------------------------------------
517
518 class CommandObjectTargetSelect : public CommandObjectParsed {
519 public:
520   CommandObjectTargetSelect(CommandInterpreter &interpreter)
521       : CommandObjectParsed(
522             interpreter, "target select",
523             "Select a target as the current target by target index.", nullptr) {
524   }
525
526   ~CommandObjectTargetSelect() override = default;
527
528 protected:
529   bool DoExecute(Args &args, CommandReturnObject &result) override {
530     if (args.GetArgumentCount() == 1) {
531       bool success = false;
532       const char *target_idx_arg = args.GetArgumentAtIndex(0);
533       uint32_t target_idx =
534           StringConvert::ToUInt32(target_idx_arg, UINT32_MAX, 0, &success);
535       if (success) {
536         TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
537         const uint32_t num_targets = target_list.GetNumTargets();
538         if (target_idx < num_targets) {
539           TargetSP target_sp(target_list.GetTargetAtIndex(target_idx));
540           if (target_sp) {
541             Stream &strm = result.GetOutputStream();
542             target_list.SetSelectedTarget(target_sp.get());
543             bool show_stopped_process_status = false;
544             DumpTargetList(target_list, show_stopped_process_status, strm);
545             result.SetStatus(eReturnStatusSuccessFinishResult);
546           } else {
547             result.AppendErrorWithFormat("target #%u is NULL in target list\n",
548                                          target_idx);
549             result.SetStatus(eReturnStatusFailed);
550           }
551         } else {
552           if (num_targets > 0) {
553             result.AppendErrorWithFormat(
554                 "index %u is out of range, valid target indexes are 0 - %u\n",
555                 target_idx, num_targets - 1);
556           } else {
557             result.AppendErrorWithFormat(
558                 "index %u is out of range since there are no active targets\n",
559                 target_idx);
560           }
561           result.SetStatus(eReturnStatusFailed);
562         }
563       } else {
564         result.AppendErrorWithFormat("invalid index string value '%s'\n",
565                                      target_idx_arg);
566         result.SetStatus(eReturnStatusFailed);
567       }
568     } else {
569       result.AppendError(
570           "'target select' takes a single argument: a target index\n");
571       result.SetStatus(eReturnStatusFailed);
572     }
573     return result.Succeeded();
574   }
575 };
576
577 #pragma mark CommandObjectTargetSelect
578
579 //----------------------------------------------------------------------
580 // "target delete"
581 //----------------------------------------------------------------------
582
583 class CommandObjectTargetDelete : public CommandObjectParsed {
584 public:
585   CommandObjectTargetDelete(CommandInterpreter &interpreter)
586       : CommandObjectParsed(interpreter, "target delete",
587                             "Delete one or more targets by target index.",
588                             nullptr),
589         m_option_group(), m_all_option(LLDB_OPT_SET_1, false, "all", 'a',
590                                        "Delete all targets.", false, true),
591         m_cleanup_option(
592             LLDB_OPT_SET_1, false, "clean", 'c',
593             "Perform extra cleanup to minimize memory consumption after "
594             "deleting the target.  "
595             "By default, LLDB will keep in memory any modules previously "
596             "loaded by the target as well "
597             "as all of its debug info.  Specifying --clean will unload all of "
598             "these shared modules and "
599             "cause them to be reparsed again the next time the target is run",
600             false, true) {
601     m_option_group.Append(&m_all_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
602     m_option_group.Append(&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
603     m_option_group.Finalize();
604   }
605
606   ~CommandObjectTargetDelete() override = default;
607
608   Options *GetOptions() override { return &m_option_group; }
609
610 protected:
611   bool DoExecute(Args &args, CommandReturnObject &result) override {
612     const size_t argc = args.GetArgumentCount();
613     std::vector<TargetSP> delete_target_list;
614     TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
615     TargetSP target_sp;
616
617     if (m_all_option.GetOptionValue()) {
618       for (int i = 0; i < target_list.GetNumTargets(); ++i)
619         delete_target_list.push_back(target_list.GetTargetAtIndex(i));
620     } else if (argc > 0) {
621       const uint32_t num_targets = target_list.GetNumTargets();
622       // Bail out if don't have any targets.
623       if (num_targets == 0) {
624         result.AppendError("no targets to delete");
625         result.SetStatus(eReturnStatusFailed);
626         return false;
627       }
628
629       for (auto &entry : args.entries()) {
630         uint32_t target_idx;
631         if (entry.ref.getAsInteger(0, target_idx)) {
632           result.AppendErrorWithFormat("invalid target index '%s'\n",
633                                        entry.c_str());
634           result.SetStatus(eReturnStatusFailed);
635           return false;
636         }
637         if (target_idx < num_targets) {
638           target_sp = target_list.GetTargetAtIndex(target_idx);
639           if (target_sp) {
640             delete_target_list.push_back(target_sp);
641             continue;
642           }
643         }
644         if (num_targets > 1)
645           result.AppendErrorWithFormat("target index %u is out of range, valid "
646                                        "target indexes are 0 - %u\n",
647                                        target_idx, num_targets - 1);
648         else
649           result.AppendErrorWithFormat(
650               "target index %u is out of range, the only valid index is 0\n",
651               target_idx);
652
653         result.SetStatus(eReturnStatusFailed);
654         return false;
655       }
656     } else {
657       target_sp = target_list.GetSelectedTarget();
658       if (!target_sp) {
659         result.AppendErrorWithFormat("no target is currently selected\n");
660         result.SetStatus(eReturnStatusFailed);
661         return false;
662       }
663       delete_target_list.push_back(target_sp);
664     }
665
666     const size_t num_targets_to_delete = delete_target_list.size();
667     for (size_t idx = 0; idx < num_targets_to_delete; ++idx) {
668       target_sp = delete_target_list[idx];
669       target_list.DeleteTarget(target_sp);
670       target_sp->Destroy();
671     }
672     // If "--clean" was specified, prune any orphaned shared modules from the
673     // global shared module list
674     if (m_cleanup_option.GetOptionValue()) {
675       const bool mandatory = true;
676       ModuleList::RemoveOrphanSharedModules(mandatory);
677     }
678     result.GetOutputStream().Printf("%u targets deleted.\n",
679                                     (uint32_t)num_targets_to_delete);
680     result.SetStatus(eReturnStatusSuccessFinishResult);
681
682     return true;
683   }
684
685   OptionGroupOptions m_option_group;
686   OptionGroupBoolean m_all_option;
687   OptionGroupBoolean m_cleanup_option;
688 };
689
690 #pragma mark CommandObjectTargetVariable
691
692 //----------------------------------------------------------------------
693 // "target variable"
694 //----------------------------------------------------------------------
695
696 class CommandObjectTargetVariable : public CommandObjectParsed {
697   static const uint32_t SHORT_OPTION_FILE = 0x66696c65; // 'file'
698   static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb'
699
700 public:
701   CommandObjectTargetVariable(CommandInterpreter &interpreter)
702       : CommandObjectParsed(interpreter, "target variable",
703                             "Read global variables for the current target, "
704                             "before or while running a process.",
705                             nullptr, eCommandRequiresTarget),
706         m_option_group(),
707         m_option_variable(false), // Don't include frame options
708         m_option_format(eFormatDefault),
709         m_option_compile_units(LLDB_OPT_SET_1, false, "file", SHORT_OPTION_FILE,
710                                0, eArgTypeFilename,
711                                "A basename or fullpath to a file that contains "
712                                "global variables. This option can be "
713                                "specified multiple times."),
714         m_option_shared_libraries(
715             LLDB_OPT_SET_1, false, "shlib", SHORT_OPTION_SHLB, 0,
716             eArgTypeFilename,
717             "A basename or fullpath to a shared library to use in the search "
718             "for global "
719             "variables. This option can be specified multiple times."),
720         m_varobj_options() {
721     CommandArgumentEntry arg;
722     CommandArgumentData var_name_arg;
723
724     // Define the first (and only) variant of this arg.
725     var_name_arg.arg_type = eArgTypeVarName;
726     var_name_arg.arg_repetition = eArgRepeatPlus;
727
728     // There is only one variant this argument could be; put it into the
729     // argument entry.
730     arg.push_back(var_name_arg);
731
732     // Push the data for the first argument into the m_arguments vector.
733     m_arguments.push_back(arg);
734
735     m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
736     m_option_group.Append(&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
737     m_option_group.Append(&m_option_format,
738                           OptionGroupFormat::OPTION_GROUP_FORMAT |
739                               OptionGroupFormat::OPTION_GROUP_GDB_FMT,
740                           LLDB_OPT_SET_1);
741     m_option_group.Append(&m_option_compile_units, LLDB_OPT_SET_ALL,
742                           LLDB_OPT_SET_1);
743     m_option_group.Append(&m_option_shared_libraries, LLDB_OPT_SET_ALL,
744                           LLDB_OPT_SET_1);
745     m_option_group.Finalize();
746   }
747
748   ~CommandObjectTargetVariable() override = default;
749
750   void DumpValueObject(Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp,
751                        const char *root_name) {
752     DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());
753
754     if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
755         valobj_sp->IsRuntimeSupportValue())
756       return;
757
758     switch (var_sp->GetScope()) {
759     case eValueTypeVariableGlobal:
760       if (m_option_variable.show_scope)
761         s.PutCString("GLOBAL: ");
762       break;
763
764     case eValueTypeVariableStatic:
765       if (m_option_variable.show_scope)
766         s.PutCString("STATIC: ");
767       break;
768
769     case eValueTypeVariableArgument:
770       if (m_option_variable.show_scope)
771         s.PutCString("   ARG: ");
772       break;
773
774     case eValueTypeVariableLocal:
775       if (m_option_variable.show_scope)
776         s.PutCString(" LOCAL: ");
777       break;
778
779     case eValueTypeVariableThreadLocal:
780       if (m_option_variable.show_scope)
781         s.PutCString("THREAD: ");
782       break;
783
784     default:
785       break;
786     }
787
788     if (m_option_variable.show_decl) {
789       bool show_fullpaths = false;
790       bool show_module = true;
791       if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
792         s.PutCString(": ");
793     }
794
795     const Format format = m_option_format.GetFormat();
796     if (format != eFormatDefault)
797       options.SetFormat(format);
798
799     options.SetRootValueObjectName(root_name);
800
801     valobj_sp->Dump(s, options);
802   }
803
804   static size_t GetVariableCallback(void *baton, const char *name,
805                                     VariableList &variable_list) {
806     Target *target = static_cast<Target *>(baton);
807     if (target) {
808       return target->GetImages().FindGlobalVariables(ConstString(name),
809                                                      UINT32_MAX, variable_list);
810     }
811     return 0;
812   }
813
814   Options *GetOptions() override { return &m_option_group; }
815
816 protected:
817   void DumpGlobalVariableList(const ExecutionContext &exe_ctx,
818                               const SymbolContext &sc,
819                               const VariableList &variable_list, Stream &s) {
820     size_t count = variable_list.GetSize();
821     if (count > 0) {
822       if (sc.module_sp) {
823         if (sc.comp_unit) {
824           s.Printf("Global variables for %s in %s:\n",
825                    sc.comp_unit->GetPath().c_str(),
826                    sc.module_sp->GetFileSpec().GetPath().c_str());
827         } else {
828           s.Printf("Global variables for %s\n",
829                    sc.module_sp->GetFileSpec().GetPath().c_str());
830         }
831       } else if (sc.comp_unit) {
832         s.Printf("Global variables for %s\n", sc.comp_unit->GetPath().c_str());
833       }
834
835       for (uint32_t i = 0; i < count; ++i) {
836         VariableSP var_sp(variable_list.GetVariableAtIndex(i));
837         if (var_sp) {
838           ValueObjectSP valobj_sp(ValueObjectVariable::Create(
839               exe_ctx.GetBestExecutionContextScope(), var_sp));
840
841           if (valobj_sp)
842             DumpValueObject(s, var_sp, valobj_sp,
843                             var_sp->GetName().GetCString());
844         }
845       }
846     }
847   }
848
849   bool DoExecute(Args &args, CommandReturnObject &result) override {
850     Target *target = m_exe_ctx.GetTargetPtr();
851     const size_t argc = args.GetArgumentCount();
852     Stream &s = result.GetOutputStream();
853
854     if (argc > 0) {
855
856       // TODO: Convert to entry-based iteration.  Requires converting
857       // DumpValueObject.
858       for (size_t idx = 0; idx < argc; ++idx) {
859         VariableList variable_list;
860         ValueObjectList valobj_list;
861
862         const char *arg = args.GetArgumentAtIndex(idx);
863         size_t matches = 0;
864         bool use_var_name = false;
865         if (m_option_variable.use_regex) {
866           RegularExpression regex(llvm::StringRef::withNullAsEmpty(arg));
867           if (!regex.IsValid()) {
868             result.GetErrorStream().Printf(
869                 "error: invalid regular expression: '%s'\n", arg);
870             result.SetStatus(eReturnStatusFailed);
871             return false;
872           }
873           use_var_name = true;
874           matches = target->GetImages().FindGlobalVariables(regex, UINT32_MAX,
875                                                             variable_list);
876         } else {
877           Status error(Variable::GetValuesForVariableExpressionPath(
878               arg, m_exe_ctx.GetBestExecutionContextScope(),
879               GetVariableCallback, target, variable_list, valobj_list));
880           matches = variable_list.GetSize();
881         }
882
883         if (matches == 0) {
884           result.GetErrorStream().Printf(
885               "error: can't find global variable '%s'\n", arg);
886           result.SetStatus(eReturnStatusFailed);
887           return false;
888         } else {
889           for (uint32_t global_idx = 0; global_idx < matches; ++global_idx) {
890             VariableSP var_sp(variable_list.GetVariableAtIndex(global_idx));
891             if (var_sp) {
892               ValueObjectSP valobj_sp(
893                   valobj_list.GetValueObjectAtIndex(global_idx));
894               if (!valobj_sp)
895                 valobj_sp = ValueObjectVariable::Create(
896                     m_exe_ctx.GetBestExecutionContextScope(), var_sp);
897
898               if (valobj_sp)
899                 DumpValueObject(s, var_sp, valobj_sp,
900                                 use_var_name ? var_sp->GetName().GetCString()
901                                              : arg);
902             }
903           }
904         }
905       }
906     } else {
907       const FileSpecList &compile_units =
908           m_option_compile_units.GetOptionValue().GetCurrentValue();
909       const FileSpecList &shlibs =
910           m_option_shared_libraries.GetOptionValue().GetCurrentValue();
911       SymbolContextList sc_list;
912       const size_t num_compile_units = compile_units.GetSize();
913       const size_t num_shlibs = shlibs.GetSize();
914       if (num_compile_units == 0 && num_shlibs == 0) {
915         bool success = false;
916         StackFrame *frame = m_exe_ctx.GetFramePtr();
917         CompileUnit *comp_unit = nullptr;
918         if (frame) {
919           SymbolContext sc = frame->GetSymbolContext(eSymbolContextCompUnit);
920           if (sc.comp_unit) {
921             const bool can_create = true;
922             VariableListSP comp_unit_varlist_sp(
923                 sc.comp_unit->GetVariableList(can_create));
924             if (comp_unit_varlist_sp) {
925               size_t count = comp_unit_varlist_sp->GetSize();
926               if (count > 0) {
927                 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
928                 success = true;
929               }
930             }
931           }
932         }
933         if (!success) {
934           if (frame) {
935             if (comp_unit)
936               result.AppendErrorWithFormat(
937                   "no global variables in current compile unit: %s\n",
938                   comp_unit->GetPath().c_str());
939             else
940               result.AppendErrorWithFormat(
941                   "no debug information for frame %u\n",
942                   frame->GetFrameIndex());
943           } else
944             result.AppendError("'target variable' takes one or more global "
945                                "variable names as arguments\n");
946           result.SetStatus(eReturnStatusFailed);
947         }
948       } else {
949         SymbolContextList sc_list;
950         const bool append = true;
951         // We have one or more compile unit or shlib
952         if (num_shlibs > 0) {
953           for (size_t shlib_idx = 0; shlib_idx < num_shlibs; ++shlib_idx) {
954             const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));
955             ModuleSpec module_spec(module_file);
956
957             ModuleSP module_sp(
958                 target->GetImages().FindFirstModule(module_spec));
959             if (module_sp) {
960               if (num_compile_units > 0) {
961                 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
962                   module_sp->FindCompileUnits(
963                       compile_units.GetFileSpecAtIndex(cu_idx), append,
964                       sc_list);
965               } else {
966                 SymbolContext sc;
967                 sc.module_sp = module_sp;
968                 sc_list.Append(sc);
969               }
970             } else {
971               // Didn't find matching shlib/module in target...
972               result.AppendErrorWithFormat(
973                   "target doesn't contain the specified shared library: %s\n",
974                   module_file.GetPath().c_str());
975             }
976           }
977         } else {
978           // No shared libraries, we just want to find globals for the compile
979           // units files that were specified
980           for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
981             target->GetImages().FindCompileUnits(
982                 compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list);
983         }
984
985         const uint32_t num_scs = sc_list.GetSize();
986         if (num_scs > 0) {
987           SymbolContext sc;
988           for (uint32_t sc_idx = 0; sc_idx < num_scs; ++sc_idx) {
989             if (sc_list.GetContextAtIndex(sc_idx, sc)) {
990               if (sc.comp_unit) {
991                 const bool can_create = true;
992                 VariableListSP comp_unit_varlist_sp(
993                     sc.comp_unit->GetVariableList(can_create));
994                 if (comp_unit_varlist_sp)
995                   DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,
996                                          s);
997               } else if (sc.module_sp) {
998                 // Get all global variables for this module
999                 lldb_private::RegularExpression all_globals_regex(
1000                     llvm::StringRef(
1001                         ".")); // Any global with at least one character
1002                 VariableList variable_list;
1003                 sc.module_sp->FindGlobalVariables(all_globals_regex, UINT32_MAX,
1004                                                   variable_list);
1005                 DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s);
1006               }
1007             }
1008           }
1009         }
1010       }
1011     }
1012
1013     if (m_interpreter.TruncationWarningNecessary()) {
1014       result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
1015                                       m_cmd_name.c_str());
1016       m_interpreter.TruncationWarningGiven();
1017     }
1018
1019     return result.Succeeded();
1020   }
1021
1022   OptionGroupOptions m_option_group;
1023   OptionGroupVariable m_option_variable;
1024   OptionGroupFormat m_option_format;
1025   OptionGroupFileList m_option_compile_units;
1026   OptionGroupFileList m_option_shared_libraries;
1027   OptionGroupValueObjectDisplay m_varobj_options;
1028 };
1029
1030 #pragma mark CommandObjectTargetModulesSearchPathsAdd
1031
1032 class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed {
1033 public:
1034   CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter &interpreter)
1035       : CommandObjectParsed(interpreter, "target modules search-paths add",
1036                             "Add new image search paths substitution pairs to "
1037                             "the current target.",
1038                             nullptr) {
1039     CommandArgumentEntry arg;
1040     CommandArgumentData old_prefix_arg;
1041     CommandArgumentData new_prefix_arg;
1042
1043     // Define the first variant of this arg pair.
1044     old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1045     old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1046
1047     // Define the first variant of this arg pair.
1048     new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1049     new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1050
1051     // There are two required arguments that must always occur together, i.e.
1052     // an argument "pair".  Because they must always occur together, they are
1053     // treated as two variants of one argument rather than two independent
1054     // arguments.  Push them both into the first argument position for
1055     // m_arguments...
1056
1057     arg.push_back(old_prefix_arg);
1058     arg.push_back(new_prefix_arg);
1059
1060     m_arguments.push_back(arg);
1061   }
1062
1063   ~CommandObjectTargetModulesSearchPathsAdd() override = default;
1064
1065 protected:
1066   bool DoExecute(Args &command, CommandReturnObject &result) override {
1067     Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1068     if (target) {
1069       const size_t argc = command.GetArgumentCount();
1070       if (argc & 1) {
1071         result.AppendError("add requires an even number of arguments\n");
1072         result.SetStatus(eReturnStatusFailed);
1073       } else {
1074         for (size_t i = 0; i < argc; i += 2) {
1075           const char *from = command.GetArgumentAtIndex(i);
1076           const char *to = command.GetArgumentAtIndex(i + 1);
1077
1078           if (from[0] && to[0]) {
1079             Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
1080             if (log) {
1081               log->Printf("target modules search path adding ImageSearchPath "
1082                           "pair: '%s' -> '%s'",
1083                           from, to);
1084             }
1085             bool last_pair = ((argc - i) == 2);
1086             target->GetImageSearchPathList().Append(
1087                 ConstString(from), ConstString(to),
1088                 last_pair); // Notify if this is the last pair
1089             result.SetStatus(eReturnStatusSuccessFinishNoResult);
1090           } else {
1091             if (from[0])
1092               result.AppendError("<path-prefix> can't be empty\n");
1093             else
1094               result.AppendError("<new-path-prefix> can't be empty\n");
1095             result.SetStatus(eReturnStatusFailed);
1096           }
1097         }
1098       }
1099     } else {
1100       result.AppendError("invalid target\n");
1101       result.SetStatus(eReturnStatusFailed);
1102     }
1103     return result.Succeeded();
1104   }
1105 };
1106
1107 #pragma mark CommandObjectTargetModulesSearchPathsClear
1108
1109 class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed {
1110 public:
1111   CommandObjectTargetModulesSearchPathsClear(CommandInterpreter &interpreter)
1112       : CommandObjectParsed(interpreter, "target modules search-paths clear",
1113                             "Clear all current image search path substitution "
1114                             "pairs from the current target.",
1115                             "target modules search-paths clear") {}
1116
1117   ~CommandObjectTargetModulesSearchPathsClear() override = default;
1118
1119 protected:
1120   bool DoExecute(Args &command, CommandReturnObject &result) override {
1121     Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1122     if (target) {
1123       bool notify = true;
1124       target->GetImageSearchPathList().Clear(notify);
1125       result.SetStatus(eReturnStatusSuccessFinishNoResult);
1126     } else {
1127       result.AppendError("invalid target\n");
1128       result.SetStatus(eReturnStatusFailed);
1129     }
1130     return result.Succeeded();
1131   }
1132 };
1133
1134 #pragma mark CommandObjectTargetModulesSearchPathsInsert
1135
1136 class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed {
1137 public:
1138   CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter &interpreter)
1139       : CommandObjectParsed(interpreter, "target modules search-paths insert",
1140                             "Insert a new image search path substitution pair "
1141                             "into the current target at the specified index.",
1142                             nullptr) {
1143     CommandArgumentEntry arg1;
1144     CommandArgumentEntry arg2;
1145     CommandArgumentData index_arg;
1146     CommandArgumentData old_prefix_arg;
1147     CommandArgumentData new_prefix_arg;
1148
1149     // Define the first and only variant of this arg.
1150     index_arg.arg_type = eArgTypeIndex;
1151     index_arg.arg_repetition = eArgRepeatPlain;
1152
1153     // Put the one and only variant into the first arg for m_arguments:
1154     arg1.push_back(index_arg);
1155
1156     // Define the first variant of this arg pair.
1157     old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1158     old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1159
1160     // Define the first variant of this arg pair.
1161     new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1162     new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1163
1164     // There are two required arguments that must always occur together, i.e.
1165     // an argument "pair".  Because they must always occur together, they are
1166     // treated as two variants of one argument rather than two independent
1167     // arguments.  Push them both into the same argument position for
1168     // m_arguments...
1169
1170     arg2.push_back(old_prefix_arg);
1171     arg2.push_back(new_prefix_arg);
1172
1173     // Add arguments to m_arguments.
1174     m_arguments.push_back(arg1);
1175     m_arguments.push_back(arg2);
1176   }
1177
1178   ~CommandObjectTargetModulesSearchPathsInsert() override = default;
1179
1180 protected:
1181   bool DoExecute(Args &command, CommandReturnObject &result) override {
1182     Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1183     if (target) {
1184       size_t argc = command.GetArgumentCount();
1185       // check for at least 3 arguments and an odd number of parameters
1186       if (argc >= 3 && argc & 1) {
1187         bool success = false;
1188
1189         uint32_t insert_idx = StringConvert::ToUInt32(
1190             command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
1191
1192         if (!success) {
1193           result.AppendErrorWithFormat(
1194               "<index> parameter is not an integer: '%s'.\n",
1195               command.GetArgumentAtIndex(0));
1196           result.SetStatus(eReturnStatusFailed);
1197           return result.Succeeded();
1198         }
1199
1200         // shift off the index
1201         command.Shift();
1202         argc = command.GetArgumentCount();
1203
1204         for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) {
1205           const char *from = command.GetArgumentAtIndex(i);
1206           const char *to = command.GetArgumentAtIndex(i + 1);
1207
1208           if (from[0] && to[0]) {
1209             bool last_pair = ((argc - i) == 2);
1210             target->GetImageSearchPathList().Insert(
1211                 ConstString(from), ConstString(to), insert_idx, last_pair);
1212             result.SetStatus(eReturnStatusSuccessFinishNoResult);
1213           } else {
1214             if (from[0])
1215               result.AppendError("<path-prefix> can't be empty\n");
1216             else
1217               result.AppendError("<new-path-prefix> can't be empty\n");
1218             result.SetStatus(eReturnStatusFailed);
1219             return false;
1220           }
1221         }
1222       } else {
1223         result.AppendError("insert requires at least three arguments\n");
1224         result.SetStatus(eReturnStatusFailed);
1225         return result.Succeeded();
1226       }
1227
1228     } else {
1229       result.AppendError("invalid target\n");
1230       result.SetStatus(eReturnStatusFailed);
1231     }
1232     return result.Succeeded();
1233   }
1234 };
1235
1236 #pragma mark CommandObjectTargetModulesSearchPathsList
1237
1238 class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed {
1239 public:
1240   CommandObjectTargetModulesSearchPathsList(CommandInterpreter &interpreter)
1241       : CommandObjectParsed(interpreter, "target modules search-paths list",
1242                             "List all current image search path substitution "
1243                             "pairs in the current target.",
1244                             "target modules search-paths list") {}
1245
1246   ~CommandObjectTargetModulesSearchPathsList() override = default;
1247
1248 protected:
1249   bool DoExecute(Args &command, CommandReturnObject &result) override {
1250     Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1251     if (target) {
1252       if (command.GetArgumentCount() != 0) {
1253         result.AppendError("list takes no arguments\n");
1254         result.SetStatus(eReturnStatusFailed);
1255         return result.Succeeded();
1256       }
1257
1258       target->GetImageSearchPathList().Dump(&result.GetOutputStream());
1259       result.SetStatus(eReturnStatusSuccessFinishResult);
1260     } else {
1261       result.AppendError("invalid target\n");
1262       result.SetStatus(eReturnStatusFailed);
1263     }
1264     return result.Succeeded();
1265   }
1266 };
1267
1268 #pragma mark CommandObjectTargetModulesSearchPathsQuery
1269
1270 class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed {
1271 public:
1272   CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter &interpreter)
1273       : CommandObjectParsed(
1274             interpreter, "target modules search-paths query",
1275             "Transform a path using the first applicable image search path.",
1276             nullptr) {
1277     CommandArgumentEntry arg;
1278     CommandArgumentData path_arg;
1279
1280     // Define the first (and only) variant of this arg.
1281     path_arg.arg_type = eArgTypeDirectoryName;
1282     path_arg.arg_repetition = eArgRepeatPlain;
1283
1284     // There is only one variant this argument could be; put it into the
1285     // argument entry.
1286     arg.push_back(path_arg);
1287
1288     // Push the data for the first argument into the m_arguments vector.
1289     m_arguments.push_back(arg);
1290   }
1291
1292   ~CommandObjectTargetModulesSearchPathsQuery() override = default;
1293
1294 protected:
1295   bool DoExecute(Args &command, CommandReturnObject &result) override {
1296     Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1297     if (target) {
1298       if (command.GetArgumentCount() != 1) {
1299         result.AppendError("query requires one argument\n");
1300         result.SetStatus(eReturnStatusFailed);
1301         return result.Succeeded();
1302       }
1303
1304       ConstString orig(command.GetArgumentAtIndex(0));
1305       ConstString transformed;
1306       if (target->GetImageSearchPathList().RemapPath(orig, transformed))
1307         result.GetOutputStream().Printf("%s\n", transformed.GetCString());
1308       else
1309         result.GetOutputStream().Printf("%s\n", orig.GetCString());
1310
1311       result.SetStatus(eReturnStatusSuccessFinishResult);
1312     } else {
1313       result.AppendError("invalid target\n");
1314       result.SetStatus(eReturnStatusFailed);
1315     }
1316     return result.Succeeded();
1317   }
1318 };
1319
1320 //----------------------------------------------------------------------
1321 // Static Helper functions
1322 //----------------------------------------------------------------------
1323 static void DumpModuleArchitecture(Stream &strm, Module *module,
1324                                    bool full_triple, uint32_t width) {
1325   if (module) {
1326     StreamString arch_strm;
1327
1328     if (full_triple)
1329       module->GetArchitecture().DumpTriple(arch_strm);
1330     else
1331       arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
1332     std::string arch_str = arch_strm.GetString();
1333
1334     if (width)
1335       strm.Printf("%-*s", width, arch_str.c_str());
1336     else
1337       strm.PutCString(arch_str);
1338   }
1339 }
1340
1341 static void DumpModuleUUID(Stream &strm, Module *module) {
1342   if (module && module->GetUUID().IsValid())
1343     module->GetUUID().Dump(&strm);
1344   else
1345     strm.PutCString("                                    ");
1346 }
1347
1348 static uint32_t DumpCompileUnitLineTable(CommandInterpreter &interpreter,
1349                                          Stream &strm, Module *module,
1350                                          const FileSpec &file_spec,
1351                                          bool load_addresses) {
1352   uint32_t num_matches = 0;
1353   if (module) {
1354     SymbolContextList sc_list;
1355     num_matches = module->ResolveSymbolContextsForFileSpec(
1356         file_spec, 0, false, eSymbolContextCompUnit, sc_list);
1357
1358     for (uint32_t i = 0; i < num_matches; ++i) {
1359       SymbolContext sc;
1360       if (sc_list.GetContextAtIndex(i, sc)) {
1361         if (i > 0)
1362           strm << "\n\n";
1363
1364         strm << "Line table for " << *static_cast<FileSpec *>(sc.comp_unit)
1365              << " in `" << module->GetFileSpec().GetFilename() << "\n";
1366         LineTable *line_table = sc.comp_unit->GetLineTable();
1367         if (line_table)
1368           line_table->GetDescription(
1369               &strm, interpreter.GetExecutionContext().GetTargetPtr(),
1370               lldb::eDescriptionLevelBrief);
1371         else
1372           strm << "No line table";
1373       }
1374     }
1375   }
1376   return num_matches;
1377 }
1378
1379 static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr,
1380                          uint32_t width) {
1381   if (file_spec_ptr) {
1382     if (width > 0) {
1383       std::string fullpath = file_spec_ptr->GetPath();
1384       strm.Printf("%-*s", width, fullpath.c_str());
1385       return;
1386     } else {
1387       file_spec_ptr->Dump(&strm);
1388       return;
1389     }
1390   }
1391   // Keep the width spacing correct if things go wrong...
1392   if (width > 0)
1393     strm.Printf("%-*s", width, "");
1394 }
1395
1396 static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr,
1397                           uint32_t width) {
1398   if (file_spec_ptr) {
1399     if (width > 0)
1400       strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
1401     else
1402       file_spec_ptr->GetDirectory().Dump(&strm);
1403     return;
1404   }
1405   // Keep the width spacing correct if things go wrong...
1406   if (width > 0)
1407     strm.Printf("%-*s", width, "");
1408 }
1409
1410 static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,
1411                          uint32_t width) {
1412   if (file_spec_ptr) {
1413     if (width > 0)
1414       strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
1415     else
1416       file_spec_ptr->GetFilename().Dump(&strm);
1417     return;
1418   }
1419   // Keep the width spacing correct if things go wrong...
1420   if (width > 0)
1421     strm.Printf("%-*s", width, "");
1422 }
1423
1424 static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
1425   size_t num_dumped = 0;
1426   std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
1427   const size_t num_modules = module_list.GetSize();
1428   if (num_modules > 0) {
1429     strm.Printf("Dumping headers for %" PRIu64 " module(s).\n",
1430                 static_cast<uint64_t>(num_modules));
1431     strm.IndentMore();
1432     for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1433       Module *module = module_list.GetModulePointerAtIndexUnlocked(image_idx);
1434       if (module) {
1435         if (num_dumped++ > 0) {
1436           strm.EOL();
1437           strm.EOL();
1438         }
1439         ObjectFile *objfile = module->GetObjectFile();
1440         if (objfile)
1441           objfile->Dump(&strm);
1442         else {
1443           strm.Format("No object file for module: {0:F}\n",
1444                       module->GetFileSpec());
1445         }
1446       }
1447     }
1448     strm.IndentLess();
1449   }
1450   return num_dumped;
1451 }
1452
1453 static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm,
1454                              Module *module, SortOrder sort_order) {
1455   if (module) {
1456     SymbolVendor *sym_vendor = module->GetSymbolVendor();
1457     if (sym_vendor) {
1458       Symtab *symtab = sym_vendor->GetSymtab();
1459       if (symtab)
1460         symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),
1461                      sort_order);
1462     }
1463   }
1464 }
1465
1466 static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,
1467                                Module *module) {
1468   if (module) {
1469     SectionList *section_list = module->GetSectionList();
1470     if (section_list) {
1471       strm.Printf("Sections for '%s' (%s):\n",
1472                   module->GetSpecificationDescription().c_str(),
1473                   module->GetArchitecture().GetArchitectureName());
1474       strm.IndentMore();
1475       section_list->Dump(&strm,
1476                          interpreter.GetExecutionContext().GetTargetPtr(), true,
1477                          UINT32_MAX);
1478       strm.IndentLess();
1479     }
1480   }
1481 }
1482
1483 static bool DumpModuleSymbolVendor(Stream &strm, Module *module) {
1484   if (module) {
1485     SymbolVendor *symbol_vendor = module->GetSymbolVendor(true);
1486     if (symbol_vendor) {
1487       symbol_vendor->Dump(&strm);
1488       return true;
1489     }
1490   }
1491   return false;
1492 }
1493
1494 static void DumpAddress(ExecutionContextScope *exe_scope,
1495                         const Address &so_addr, bool verbose, Stream &strm) {
1496   strm.IndentMore();
1497   strm.Indent("    Address: ");
1498   so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1499   strm.PutCString(" (");
1500   so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1501   strm.PutCString(")\n");
1502   strm.Indent("    Summary: ");
1503   const uint32_t save_indent = strm.GetIndentLevel();
1504   strm.SetIndentLevel(save_indent + 13);
1505   so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription);
1506   strm.SetIndentLevel(save_indent);
1507   // Print out detailed address information when verbose is enabled
1508   if (verbose) {
1509     strm.EOL();
1510     so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
1511   }
1512   strm.IndentLess();
1513 }
1514
1515 static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
1516                                   Module *module, uint32_t resolve_mask,
1517                                   lldb::addr_t raw_addr, lldb::addr_t offset,
1518                                   bool verbose) {
1519   if (module) {
1520     lldb::addr_t addr = raw_addr - offset;
1521     Address so_addr;
1522     SymbolContext sc;
1523     Target *target = interpreter.GetExecutionContext().GetTargetPtr();
1524     if (target && !target->GetSectionLoadList().IsEmpty()) {
1525       if (!target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
1526         return false;
1527       else if (so_addr.GetModule().get() != module)
1528         return false;
1529     } else {
1530       if (!module->ResolveFileAddress(addr, so_addr))
1531         return false;
1532     }
1533
1534     ExecutionContextScope *exe_scope =
1535         interpreter.GetExecutionContext().GetBestExecutionContextScope();
1536     DumpAddress(exe_scope, so_addr, verbose, strm);
1537     //        strm.IndentMore();
1538     //        strm.Indent ("    Address: ");
1539     //        so_addr.Dump (&strm, exe_scope,
1540     //        Address::DumpStyleModuleWithFileAddress);
1541     //        strm.PutCString (" (");
1542     //        so_addr.Dump (&strm, exe_scope,
1543     //        Address::DumpStyleSectionNameOffset);
1544     //        strm.PutCString (")\n");
1545     //        strm.Indent ("    Summary: ");
1546     //        const uint32_t save_indent = strm.GetIndentLevel ();
1547     //        strm.SetIndentLevel (save_indent + 13);
1548     //        so_addr.Dump (&strm, exe_scope,
1549     //        Address::DumpStyleResolvedDescription);
1550     //        strm.SetIndentLevel (save_indent);
1551     //        // Print out detailed address information when verbose is enabled
1552     //        if (verbose)
1553     //        {
1554     //            strm.EOL();
1555     //            so_addr.Dump (&strm, exe_scope,
1556     //            Address::DumpStyleDetailedSymbolContext);
1557     //        }
1558     //        strm.IndentLess();
1559     return true;
1560   }
1561
1562   return false;
1563 }
1564
1565 static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
1566                                      Stream &strm, Module *module,
1567                                      const char *name, bool name_is_regex,
1568                                      bool verbose) {
1569   if (module) {
1570     SymbolContext sc;
1571
1572     SymbolVendor *sym_vendor = module->GetSymbolVendor();
1573     if (sym_vendor) {
1574       Symtab *symtab = sym_vendor->GetSymtab();
1575       if (symtab) {
1576         std::vector<uint32_t> match_indexes;
1577         ConstString symbol_name(name);
1578         uint32_t num_matches = 0;
1579         if (name_is_regex) {
1580           RegularExpression name_regexp(symbol_name.GetStringRef());
1581           num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType(
1582               name_regexp, eSymbolTypeAny, match_indexes);
1583         } else {
1584           num_matches =
1585               symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes);
1586         }
1587
1588         if (num_matches > 0) {
1589           strm.Indent();
1590           strm.Printf("%u symbols match %s'%s' in ", num_matches,
1591                       name_is_regex ? "the regular expression " : "", name);
1592           DumpFullpath(strm, &module->GetFileSpec(), 0);
1593           strm.PutCString(":\n");
1594           strm.IndentMore();
1595           for (uint32_t i = 0; i < num_matches; ++i) {
1596             Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
1597             if (symbol && symbol->ValueIsAddress()) {
1598               DumpAddress(interpreter.GetExecutionContext()
1599                               .GetBestExecutionContextScope(),
1600                           symbol->GetAddressRef(), verbose, strm);
1601             }
1602           }
1603           strm.IndentLess();
1604           return num_matches;
1605         }
1606       }
1607     }
1608   }
1609   return 0;
1610 }
1611
1612 static void DumpSymbolContextList(ExecutionContextScope *exe_scope,
1613                                   Stream &strm, SymbolContextList &sc_list,
1614                                   bool verbose) {
1615   strm.IndentMore();
1616
1617   const uint32_t num_matches = sc_list.GetSize();
1618
1619   for (uint32_t i = 0; i < num_matches; ++i) {
1620     SymbolContext sc;
1621     if (sc_list.GetContextAtIndex(i, sc)) {
1622       AddressRange range;
1623
1624       sc.GetAddressRange(eSymbolContextEverything, 0, true, range);
1625
1626       DumpAddress(exe_scope, range.GetBaseAddress(), verbose, strm);
1627     }
1628   }
1629   strm.IndentLess();
1630 }
1631
1632 static size_t LookupFunctionInModule(CommandInterpreter &interpreter,
1633                                      Stream &strm, Module *module,
1634                                      const char *name, bool name_is_regex,
1635                                      bool include_inlines, bool include_symbols,
1636                                      bool verbose) {
1637   if (module && name && name[0]) {
1638     SymbolContextList sc_list;
1639     const bool append = true;
1640     size_t num_matches = 0;
1641     if (name_is_regex) {
1642       RegularExpression function_name_regex((llvm::StringRef(name)));
1643       num_matches = module->FindFunctions(function_name_regex, include_symbols,
1644                                           include_inlines, append, sc_list);
1645     } else {
1646       ConstString function_name(name);
1647       num_matches = module->FindFunctions(
1648           function_name, nullptr, eFunctionNameTypeAuto, include_symbols,
1649           include_inlines, append, sc_list);
1650     }
1651
1652     if (num_matches) {
1653       strm.Indent();
1654       strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1655                   num_matches > 1 ? "es" : "");
1656       DumpFullpath(strm, &module->GetFileSpec(), 0);
1657       strm.PutCString(":\n");
1658       DumpSymbolContextList(
1659           interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1660           strm, sc_list, verbose);
1661     }
1662     return num_matches;
1663   }
1664   return 0;
1665 }
1666
1667 static size_t LookupTypeInModule(CommandInterpreter &interpreter, Stream &strm,
1668                                  Module *module, const char *name_cstr,
1669                                  bool name_is_regex) {
1670   if (module && name_cstr && name_cstr[0]) {
1671     TypeList type_list;
1672     const uint32_t max_num_matches = UINT32_MAX;
1673     size_t num_matches = 0;
1674     bool name_is_fully_qualified = false;
1675
1676     ConstString name(name_cstr);
1677     llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
1678     num_matches =
1679         module->FindTypes(name, name_is_fully_qualified, max_num_matches,
1680                           searched_symbol_files, type_list);
1681
1682     if (num_matches) {
1683       strm.Indent();
1684       strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1685                   num_matches > 1 ? "es" : "");
1686       DumpFullpath(strm, &module->GetFileSpec(), 0);
1687       strm.PutCString(":\n");
1688       for (TypeSP type_sp : type_list.Types()) {
1689         if (type_sp) {
1690           // Resolve the clang type so that any forward references to types
1691           // that haven't yet been parsed will get parsed.
1692           type_sp->GetFullCompilerType();
1693           type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1694           // Print all typedef chains
1695           TypeSP typedef_type_sp(type_sp);
1696           TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1697           while (typedefed_type_sp) {
1698             strm.EOL();
1699             strm.Printf("     typedef '%s': ",
1700                         typedef_type_sp->GetName().GetCString());
1701             typedefed_type_sp->GetFullCompilerType();
1702             typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull,
1703                                               true);
1704             typedef_type_sp = typedefed_type_sp;
1705             typedefed_type_sp = typedef_type_sp->GetTypedefType();
1706           }
1707         }
1708         strm.EOL();
1709       }
1710     }
1711     return num_matches;
1712   }
1713   return 0;
1714 }
1715
1716 static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm,
1717                              Module &module, const char *name_cstr,
1718                              bool name_is_regex) {
1719   TypeList type_list;
1720   const uint32_t max_num_matches = UINT32_MAX;
1721   size_t num_matches = 1;
1722   bool name_is_fully_qualified = false;
1723
1724   ConstString name(name_cstr);
1725   llvm::DenseSet<SymbolFile *> searched_symbol_files;
1726   num_matches = module.FindTypes(name, name_is_fully_qualified, max_num_matches,
1727                                  searched_symbol_files, type_list);
1728
1729   if (num_matches) {
1730     strm.Indent();
1731     strm.PutCString("Best match found in ");
1732     DumpFullpath(strm, &module.GetFileSpec(), 0);
1733     strm.PutCString(":\n");
1734
1735     TypeSP type_sp(type_list.GetTypeAtIndex(0));
1736     if (type_sp) {
1737       // Resolve the clang type so that any forward references to types that
1738       // haven't yet been parsed will get parsed.
1739       type_sp->GetFullCompilerType();
1740       type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1741       // Print all typedef chains
1742       TypeSP typedef_type_sp(type_sp);
1743       TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1744       while (typedefed_type_sp) {
1745         strm.EOL();
1746         strm.Printf("     typedef '%s': ",
1747                     typedef_type_sp->GetName().GetCString());
1748         typedefed_type_sp->GetFullCompilerType();
1749         typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1750         typedef_type_sp = typedefed_type_sp;
1751         typedefed_type_sp = typedef_type_sp->GetTypedefType();
1752       }
1753     }
1754     strm.EOL();
1755   }
1756   return num_matches;
1757 }
1758
1759 static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter,
1760                                           Stream &strm, Module *module,
1761                                           const FileSpec &file_spec,
1762                                           uint32_t line, bool check_inlines,
1763                                           bool verbose) {
1764   if (module && file_spec) {
1765     SymbolContextList sc_list;
1766     const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(
1767         file_spec, line, check_inlines, eSymbolContextEverything, sc_list);
1768     if (num_matches > 0) {
1769       strm.Indent();
1770       strm.Printf("%u match%s found in ", num_matches,
1771                   num_matches > 1 ? "es" : "");
1772       strm << file_spec;
1773       if (line > 0)
1774         strm.Printf(":%u", line);
1775       strm << " in ";
1776       DumpFullpath(strm, &module->GetFileSpec(), 0);
1777       strm.PutCString(":\n");
1778       DumpSymbolContextList(
1779           interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1780           strm, sc_list, verbose);
1781       return num_matches;
1782     }
1783   }
1784   return 0;
1785 }
1786
1787 static size_t FindModulesByName(Target *target, const char *module_name,
1788                                 ModuleList &module_list,
1789                                 bool check_global_list) {
1790   FileSpec module_file_spec(module_name);
1791   ModuleSpec module_spec(module_file_spec);
1792
1793   const size_t initial_size = module_list.GetSize();
1794
1795   if (check_global_list) {
1796     // Check the global list
1797     std::lock_guard<std::recursive_mutex> guard(
1798         Module::GetAllocationModuleCollectionMutex());
1799     const size_t num_modules = Module::GetNumberAllocatedModules();
1800     ModuleSP module_sp;
1801     for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1802       Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
1803
1804       if (module) {
1805         if (module->MatchesModuleSpec(module_spec)) {
1806           module_sp = module->shared_from_this();
1807           module_list.AppendIfNeeded(module_sp);
1808         }
1809       }
1810     }
1811   } else {
1812     if (target) {
1813       const size_t num_matches =
1814           target->GetImages().FindModules(module_spec, module_list);
1815
1816       // Not found in our module list for our target, check the main shared
1817       // module list in case it is a extra file used somewhere else
1818       if (num_matches == 0) {
1819         module_spec.GetArchitecture() = target->GetArchitecture();
1820         ModuleList::FindSharedModules(module_spec, module_list);
1821       }
1822     } else {
1823       ModuleList::FindSharedModules(module_spec, module_list);
1824     }
1825   }
1826
1827   return module_list.GetSize() - initial_size;
1828 }
1829
1830 #pragma mark CommandObjectTargetModulesModuleAutoComplete
1831
1832 //----------------------------------------------------------------------
1833 // A base command object class that can auto complete with module file
1834 // paths
1835 //----------------------------------------------------------------------
1836
1837 class CommandObjectTargetModulesModuleAutoComplete
1838     : public CommandObjectParsed {
1839 public:
1840   CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter,
1841                                                const char *name,
1842                                                const char *help,
1843                                                const char *syntax)
1844       : CommandObjectParsed(interpreter, name, help, syntax) {
1845     CommandArgumentEntry arg;
1846     CommandArgumentData file_arg;
1847
1848     // Define the first (and only) variant of this arg.
1849     file_arg.arg_type = eArgTypeFilename;
1850     file_arg.arg_repetition = eArgRepeatStar;
1851
1852     // There is only one variant this argument could be; put it into the
1853     // argument entry.
1854     arg.push_back(file_arg);
1855
1856     // Push the data for the first argument into the m_arguments vector.
1857     m_arguments.push_back(arg);
1858   }
1859
1860   ~CommandObjectTargetModulesModuleAutoComplete() override = default;
1861
1862   int HandleArgumentCompletion(
1863       CompletionRequest &request,
1864       OptionElementVector &opt_element_vector) override {
1865     CommandCompletions::InvokeCommonCompletionCallbacks(
1866         GetCommandInterpreter(), CommandCompletions::eModuleCompletion, request,
1867         nullptr);
1868     return request.GetNumberOfMatches();
1869   }
1870 };
1871
1872 #pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1873
1874 //----------------------------------------------------------------------
1875 // A base command object class that can auto complete with module source
1876 // file paths
1877 //----------------------------------------------------------------------
1878
1879 class CommandObjectTargetModulesSourceFileAutoComplete
1880     : public CommandObjectParsed {
1881 public:
1882   CommandObjectTargetModulesSourceFileAutoComplete(
1883       CommandInterpreter &interpreter, const char *name, const char *help,
1884       const char *syntax, uint32_t flags)
1885       : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1886     CommandArgumentEntry arg;
1887     CommandArgumentData source_file_arg;
1888
1889     // Define the first (and only) variant of this arg.
1890     source_file_arg.arg_type = eArgTypeSourceFile;
1891     source_file_arg.arg_repetition = eArgRepeatPlus;
1892
1893     // There is only one variant this argument could be; put it into the
1894     // argument entry.
1895     arg.push_back(source_file_arg);
1896
1897     // Push the data for the first argument into the m_arguments vector.
1898     m_arguments.push_back(arg);
1899   }
1900
1901   ~CommandObjectTargetModulesSourceFileAutoComplete() override = default;
1902
1903   int HandleArgumentCompletion(
1904       CompletionRequest &request,
1905       OptionElementVector &opt_element_vector) override {
1906     CommandCompletions::InvokeCommonCompletionCallbacks(
1907         GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion,
1908         request, nullptr);
1909     return request.GetNumberOfMatches();
1910   }
1911 };
1912
1913 #pragma mark CommandObjectTargetModulesDumpObjfile
1914
1915 class CommandObjectTargetModulesDumpObjfile
1916     : public CommandObjectTargetModulesModuleAutoComplete {
1917 public:
1918   CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter)
1919       : CommandObjectTargetModulesModuleAutoComplete(
1920             interpreter, "target modules dump objfile",
1921             "Dump the object file headers from one or more target modules.",
1922             nullptr) {}
1923
1924   ~CommandObjectTargetModulesDumpObjfile() override = default;
1925
1926 protected:
1927   bool DoExecute(Args &command, CommandReturnObject &result) override {
1928     Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1929     if (target == nullptr) {
1930       result.AppendError("invalid target, create a debug target using the "
1931                          "'target create' command");
1932       result.SetStatus(eReturnStatusFailed);
1933       return false;
1934     }
1935
1936     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1937     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1938     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1939
1940     size_t num_dumped = 0;
1941     if (command.GetArgumentCount() == 0) {
1942       // Dump all headers for all modules images
1943       num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(),
1944                                             target->GetImages());
1945       if (num_dumped == 0) {
1946         result.AppendError("the target has no associated executable images");
1947         result.SetStatus(eReturnStatusFailed);
1948       }
1949     } else {
1950       // Find the modules that match the basename or full path.
1951       ModuleList module_list;
1952       const char *arg_cstr;
1953       for (int arg_idx = 0;
1954            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
1955            ++arg_idx) {
1956         size_t num_matched =
1957             FindModulesByName(target, arg_cstr, module_list, true);
1958         if (num_matched == 0) {
1959           result.AppendWarningWithFormat(
1960               "Unable to find an image that matches '%s'.\n", arg_cstr);
1961         }
1962       }
1963       // Dump all the modules we found.
1964       num_dumped =
1965           DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
1966     }
1967
1968     if (num_dumped > 0) {
1969       result.SetStatus(eReturnStatusSuccessFinishResult);
1970     } else {
1971       result.AppendError("no matching executable images found");
1972       result.SetStatus(eReturnStatusFailed);
1973     }
1974     return result.Succeeded();
1975   }
1976 };
1977
1978 #pragma mark CommandObjectTargetModulesDumpSymtab
1979
1980 static constexpr OptionEnumValueElement g_sort_option_enumeration[] = {
1981     {eSortOrderNone, "none",
1982      "No sorting, use the original symbol table order."},
1983     {eSortOrderByAddress, "address", "Sort output by symbol address."},
1984     {eSortOrderByName, "name", "Sort output by symbol name."} };
1985
1986 static constexpr OptionDefinition g_target_modules_dump_symtab_options[] = {
1987     // clang-format off
1988   { LLDB_OPT_SET_1, false, "sort", 's', OptionParser::eRequiredArgument, nullptr, OptionEnumValues(g_sort_option_enumeration), 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table." }
1989     // clang-format on
1990 };
1991
1992 class CommandObjectTargetModulesDumpSymtab
1993     : public CommandObjectTargetModulesModuleAutoComplete {
1994 public:
1995   CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter)
1996       : CommandObjectTargetModulesModuleAutoComplete(
1997             interpreter, "target modules dump symtab",
1998             "Dump the symbol table from one or more target modules.", nullptr),
1999         m_options() {}
2000
2001   ~CommandObjectTargetModulesDumpSymtab() override = default;
2002
2003   Options *GetOptions() override { return &m_options; }
2004
2005   class CommandOptions : public Options {
2006   public:
2007     CommandOptions() : Options(), m_sort_order(eSortOrderNone) {}
2008
2009     ~CommandOptions() override = default;
2010
2011     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2012                           ExecutionContext *execution_context) override {
2013       Status error;
2014       const int short_option = m_getopt_table[option_idx].val;
2015
2016       switch (short_option) {
2017       case 's':
2018         m_sort_order = (SortOrder)OptionArgParser::ToOptionEnum(
2019             option_arg, GetDefinitions()[option_idx].enum_values,
2020             eSortOrderNone, error);
2021         break;
2022
2023       default:
2024         error.SetErrorStringWithFormat("invalid short option character '%c'",
2025                                        short_option);
2026         break;
2027       }
2028       return error;
2029     }
2030
2031     void OptionParsingStarting(ExecutionContext *execution_context) override {
2032       m_sort_order = eSortOrderNone;
2033     }
2034
2035     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2036       return llvm::makeArrayRef(g_target_modules_dump_symtab_options);
2037     }
2038
2039     SortOrder m_sort_order;
2040   };
2041
2042 protected:
2043   bool DoExecute(Args &command, CommandReturnObject &result) override {
2044     Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2045     if (target == nullptr) {
2046       result.AppendError("invalid target, create a debug target using the "
2047                          "'target create' command");
2048       result.SetStatus(eReturnStatusFailed);
2049       return false;
2050     } else {
2051       uint32_t num_dumped = 0;
2052
2053       uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2054       result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2055       result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2056
2057       if (command.GetArgumentCount() == 0) {
2058         // Dump all sections for all modules images
2059         std::lock_guard<std::recursive_mutex> guard(
2060             target->GetImages().GetMutex());
2061         const size_t num_modules = target->GetImages().GetSize();
2062         if (num_modules > 0) {
2063           result.GetOutputStream().Printf("Dumping symbol table for %" PRIu64
2064                                           " modules.\n",
2065                                           (uint64_t)num_modules);
2066           for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2067             if (num_dumped > 0) {
2068               result.GetOutputStream().EOL();
2069               result.GetOutputStream().EOL();
2070             }
2071             if (m_interpreter.WasInterrupted())
2072               break;
2073             num_dumped++;
2074             DumpModuleSymtab(
2075                 m_interpreter, result.GetOutputStream(),
2076                 target->GetImages().GetModulePointerAtIndexUnlocked(image_idx),
2077                 m_options.m_sort_order);
2078           }
2079         } else {
2080           result.AppendError("the target has no associated executable images");
2081           result.SetStatus(eReturnStatusFailed);
2082           return false;
2083         }
2084       } else {
2085         // Dump specified images (by basename or fullpath)
2086         const char *arg_cstr;
2087         for (int arg_idx = 0;
2088              (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2089              ++arg_idx) {
2090           ModuleList module_list;
2091           const size_t num_matches =
2092               FindModulesByName(target, arg_cstr, module_list, true);
2093           if (num_matches > 0) {
2094             for (size_t i = 0; i < num_matches; ++i) {
2095               Module *module = module_list.GetModulePointerAtIndex(i);
2096               if (module) {
2097                 if (num_dumped > 0) {
2098                   result.GetOutputStream().EOL();
2099                   result.GetOutputStream().EOL();
2100                 }
2101                 if (m_interpreter.WasInterrupted())
2102                   break;
2103                 num_dumped++;
2104                 DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
2105                                  module, m_options.m_sort_order);
2106               }
2107             }
2108           } else
2109             result.AppendWarningWithFormat(
2110                 "Unable to find an image that matches '%s'.\n", arg_cstr);
2111         }
2112       }
2113
2114       if (num_dumped > 0)
2115         result.SetStatus(eReturnStatusSuccessFinishResult);
2116       else {
2117         result.AppendError("no matching executable images found");
2118         result.SetStatus(eReturnStatusFailed);
2119       }
2120     }
2121     return result.Succeeded();
2122   }
2123
2124   CommandOptions m_options;
2125 };
2126
2127 #pragma mark CommandObjectTargetModulesDumpSections
2128
2129 //----------------------------------------------------------------------
2130 // Image section dumping command
2131 //----------------------------------------------------------------------
2132
2133 class CommandObjectTargetModulesDumpSections
2134     : public CommandObjectTargetModulesModuleAutoComplete {
2135 public:
2136   CommandObjectTargetModulesDumpSections(CommandInterpreter &interpreter)
2137       : CommandObjectTargetModulesModuleAutoComplete(
2138             interpreter, "target modules dump sections",
2139             "Dump the sections from one or more target modules.",
2140             //"target modules dump sections [<file1> ...]")
2141             nullptr) {}
2142
2143   ~CommandObjectTargetModulesDumpSections() override = default;
2144
2145 protected:
2146   bool DoExecute(Args &command, CommandReturnObject &result) override {
2147     Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2148     if (target == nullptr) {
2149       result.AppendError("invalid target, create a debug target using the "
2150                          "'target create' command");
2151       result.SetStatus(eReturnStatusFailed);
2152       return false;
2153     } else {
2154       uint32_t num_dumped = 0;
2155
2156       uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2157       result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2158       result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2159
2160       if (command.GetArgumentCount() == 0) {
2161         // Dump all sections for all modules images
2162         const size_t num_modules = target->GetImages().GetSize();
2163         if (num_modules > 0) {
2164           result.GetOutputStream().Printf("Dumping sections for %" PRIu64
2165                                           " modules.\n",
2166                                           (uint64_t)num_modules);
2167           for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2168             if (m_interpreter.WasInterrupted())
2169               break;
2170             num_dumped++;
2171             DumpModuleSections(
2172                 m_interpreter, result.GetOutputStream(),
2173                 target->GetImages().GetModulePointerAtIndex(image_idx));
2174           }
2175         } else {
2176           result.AppendError("the target has no associated executable images");
2177           result.SetStatus(eReturnStatusFailed);
2178           return false;
2179         }
2180       } else {
2181         // Dump specified images (by basename or fullpath)
2182         const char *arg_cstr;
2183         for (int arg_idx = 0;
2184              (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2185              ++arg_idx) {
2186           ModuleList module_list;
2187           const size_t num_matches =
2188               FindModulesByName(target, arg_cstr, module_list, true);
2189           if (num_matches > 0) {
2190             for (size_t i = 0; i < num_matches; ++i) {
2191               if (m_interpreter.WasInterrupted())
2192                 break;
2193               Module *module = module_list.GetModulePointerAtIndex(i);
2194               if (module) {
2195                 num_dumped++;
2196                 DumpModuleSections(m_interpreter, result.GetOutputStream(),
2197                                    module);
2198               }
2199             }
2200           } else {
2201             // Check the global list
2202             std::lock_guard<std::recursive_mutex> guard(
2203                 Module::GetAllocationModuleCollectionMutex());
2204
2205             result.AppendWarningWithFormat(
2206                 "Unable to find an image that matches '%s'.\n", arg_cstr);
2207           }
2208         }
2209       }
2210
2211       if (num_dumped > 0)
2212         result.SetStatus(eReturnStatusSuccessFinishResult);
2213       else {
2214         result.AppendError("no matching executable images found");
2215         result.SetStatus(eReturnStatusFailed);
2216       }
2217     }
2218     return result.Succeeded();
2219   }
2220 };
2221
2222 #pragma mark CommandObjectTargetModulesDumpSections
2223
2224 //----------------------------------------------------------------------
2225 // Clang AST dumping command
2226 //----------------------------------------------------------------------
2227
2228 class CommandObjectTargetModulesDumpClangAST
2229     : public CommandObjectTargetModulesModuleAutoComplete {
2230 public:
2231   CommandObjectTargetModulesDumpClangAST(CommandInterpreter &interpreter)
2232       : CommandObjectTargetModulesModuleAutoComplete(
2233             interpreter, "target modules dump ast",
2234             "Dump the clang ast for a given module's symbol file.",
2235             //"target modules dump ast [<file1> ...]")
2236             nullptr) {}
2237
2238   ~CommandObjectTargetModulesDumpClangAST() override = default;
2239
2240 protected:
2241   bool DoExecute(Args &command, CommandReturnObject &result) override {
2242     Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2243     if (target == nullptr) {
2244       result.AppendError("invalid target, create a debug target using the "
2245                          "'target create' command");
2246       result.SetStatus(eReturnStatusFailed);
2247       return false;
2248     }
2249
2250     const size_t num_modules = target->GetImages().GetSize();
2251     if (num_modules == 0) {
2252       result.AppendError("the target has no associated executable images");
2253       result.SetStatus(eReturnStatusFailed);
2254       return false;
2255     }
2256
2257     if (command.GetArgumentCount() == 0) {
2258       // Dump all ASTs for all modules images
2259       result.GetOutputStream().Printf("Dumping clang ast for %" PRIu64
2260                                       " modules.\n",
2261                                       (uint64_t)num_modules);
2262       for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2263         if (m_interpreter.WasInterrupted())
2264           break;
2265         Module *m = target->GetImages().GetModulePointerAtIndex(image_idx);
2266         SymbolFile *sf = m->GetSymbolVendor()->GetSymbolFile();
2267         sf->DumpClangAST(result.GetOutputStream());
2268       }
2269       result.SetStatus(eReturnStatusSuccessFinishResult);
2270       return true;
2271     }
2272
2273     // Dump specified ASTs (by basename or fullpath)
2274     for (const Args::ArgEntry &arg : command.entries()) {
2275       ModuleList module_list;
2276       const size_t num_matches =
2277           FindModulesByName(target, arg.c_str(), module_list, true);
2278       if (num_matches == 0) {
2279         // Check the global list
2280         std::lock_guard<std::recursive_mutex> guard(
2281             Module::GetAllocationModuleCollectionMutex());
2282
2283         result.AppendWarningWithFormat(
2284             "Unable to find an image that matches '%s'.\n", arg.c_str());
2285         continue;
2286       }
2287
2288       for (size_t i = 0; i < num_matches; ++i) {
2289         if (m_interpreter.WasInterrupted())
2290           break;
2291         Module *m = module_list.GetModulePointerAtIndex(i);
2292         SymbolFile *sf = m->GetSymbolVendor()->GetSymbolFile();
2293         sf->DumpClangAST(result.GetOutputStream());
2294       }
2295     }
2296     result.SetStatus(eReturnStatusSuccessFinishResult);
2297     return true;
2298   }
2299 };
2300
2301 #pragma mark CommandObjectTargetModulesDumpSymfile
2302
2303 //----------------------------------------------------------------------
2304 // Image debug symbol dumping command
2305 //----------------------------------------------------------------------
2306
2307 class CommandObjectTargetModulesDumpSymfile
2308     : public CommandObjectTargetModulesModuleAutoComplete {
2309 public:
2310   CommandObjectTargetModulesDumpSymfile(CommandInterpreter &interpreter)
2311       : CommandObjectTargetModulesModuleAutoComplete(
2312             interpreter, "target modules dump symfile",
2313             "Dump the debug symbol file for one or more target modules.",
2314             //"target modules dump symfile [<file1> ...]")
2315             nullptr) {}
2316
2317   ~CommandObjectTargetModulesDumpSymfile() override = default;
2318
2319 protected:
2320   bool DoExecute(Args &command, CommandReturnObject &result) override {
2321     Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2322     if (target == nullptr) {
2323       result.AppendError("invalid target, create a debug target using the "
2324                          "'target create' command");
2325       result.SetStatus(eReturnStatusFailed);
2326       return false;
2327     } else {
2328       uint32_t num_dumped = 0;
2329
2330       uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2331       result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2332       result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2333
2334       if (command.GetArgumentCount() == 0) {
2335         // Dump all sections for all modules images
2336         const ModuleList &target_modules = target->GetImages();
2337         std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2338         const size_t num_modules = target_modules.GetSize();
2339         if (num_modules > 0) {
2340           result.GetOutputStream().Printf("Dumping debug symbols for %" PRIu64
2341                                           " modules.\n",
2342                                           (uint64_t)num_modules);
2343           for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2344             if (m_interpreter.WasInterrupted())
2345               break;
2346             if (DumpModuleSymbolVendor(
2347                     result.GetOutputStream(),
2348                     target_modules.GetModulePointerAtIndexUnlocked(image_idx)))
2349               num_dumped++;
2350           }
2351         } else {
2352           result.AppendError("the target has no associated executable images");
2353           result.SetStatus(eReturnStatusFailed);
2354           return false;
2355         }
2356       } else {
2357         // Dump specified images (by basename or fullpath)
2358         const char *arg_cstr;
2359         for (int arg_idx = 0;
2360              (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2361              ++arg_idx) {
2362           ModuleList module_list;
2363           const size_t num_matches =
2364               FindModulesByName(target, arg_cstr, module_list, true);
2365           if (num_matches > 0) {
2366             for (size_t i = 0; i < num_matches; ++i) {
2367               if (m_interpreter.WasInterrupted())
2368                 break;
2369               Module *module = module_list.GetModulePointerAtIndex(i);
2370               if (module) {
2371                 if (DumpModuleSymbolVendor(result.GetOutputStream(), module))
2372                   num_dumped++;
2373               }
2374             }
2375           } else
2376             result.AppendWarningWithFormat(
2377                 "Unable to find an image that matches '%s'.\n", arg_cstr);
2378         }
2379       }
2380
2381       if (num_dumped > 0)
2382         result.SetStatus(eReturnStatusSuccessFinishResult);
2383       else {
2384         result.AppendError("no matching executable images found");
2385         result.SetStatus(eReturnStatusFailed);
2386       }
2387     }
2388     return result.Succeeded();
2389   }
2390 };
2391
2392 #pragma mark CommandObjectTargetModulesDumpLineTable
2393
2394 //----------------------------------------------------------------------
2395 // Image debug line table dumping command
2396 //----------------------------------------------------------------------
2397
2398 class CommandObjectTargetModulesDumpLineTable
2399     : public CommandObjectTargetModulesSourceFileAutoComplete {
2400 public:
2401   CommandObjectTargetModulesDumpLineTable(CommandInterpreter &interpreter)
2402       : CommandObjectTargetModulesSourceFileAutoComplete(
2403             interpreter, "target modules dump line-table",
2404             "Dump the line table for one or more compilation units.", nullptr,
2405             eCommandRequiresTarget) {}
2406
2407   ~CommandObjectTargetModulesDumpLineTable() override = default;
2408
2409 protected:
2410   bool DoExecute(Args &command, CommandReturnObject &result) override {
2411     Target *target = m_exe_ctx.GetTargetPtr();
2412     uint32_t total_num_dumped = 0;
2413
2414     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2415     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2416     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2417
2418     if (command.GetArgumentCount() == 0) {
2419       result.AppendError("file option must be specified.");
2420       result.SetStatus(eReturnStatusFailed);
2421       return result.Succeeded();
2422     } else {
2423       // Dump specified images (by basename or fullpath)
2424       const char *arg_cstr;
2425       for (int arg_idx = 0;
2426            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2427            ++arg_idx) {
2428         FileSpec file_spec(arg_cstr);
2429
2430         const ModuleList &target_modules = target->GetImages();
2431         std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2432         const size_t num_modules = target_modules.GetSize();
2433         if (num_modules > 0) {
2434           uint32_t num_dumped = 0;
2435           for (uint32_t i = 0; i < num_modules; ++i) {
2436             if (m_interpreter.WasInterrupted())
2437               break;
2438             if (DumpCompileUnitLineTable(
2439                     m_interpreter, result.GetOutputStream(),
2440                     target_modules.GetModulePointerAtIndexUnlocked(i),
2441                     file_spec, m_exe_ctx.GetProcessPtr() &&
2442                                    m_exe_ctx.GetProcessRef().IsAlive()))
2443               num_dumped++;
2444           }
2445           if (num_dumped == 0)
2446             result.AppendWarningWithFormat(
2447                 "No source filenames matched '%s'.\n", arg_cstr);
2448           else
2449             total_num_dumped += num_dumped;
2450         }
2451       }
2452     }
2453
2454     if (total_num_dumped > 0)
2455       result.SetStatus(eReturnStatusSuccessFinishResult);
2456     else {
2457       result.AppendError("no source filenames matched any command arguments");
2458       result.SetStatus(eReturnStatusFailed);
2459     }
2460     return result.Succeeded();
2461   }
2462 };
2463
2464 #pragma mark CommandObjectTargetModulesDump
2465
2466 //----------------------------------------------------------------------
2467 // Dump multi-word command for target modules
2468 //----------------------------------------------------------------------
2469
2470 class CommandObjectTargetModulesDump : public CommandObjectMultiword {
2471 public:
2472   //------------------------------------------------------------------
2473   // Constructors and Destructors
2474   //------------------------------------------------------------------
2475   CommandObjectTargetModulesDump(CommandInterpreter &interpreter)
2476       : CommandObjectMultiword(
2477             interpreter, "target modules dump",
2478             "Commands for dumping information about one or "
2479             "more target modules.",
2480             "target modules dump "
2481             "[headers|symtab|sections|ast|symfile|line-table] "
2482             "[<file1> <file2> ...]") {
2483     LoadSubCommand("objfile",
2484                    CommandObjectSP(
2485                        new CommandObjectTargetModulesDumpObjfile(interpreter)));
2486     LoadSubCommand(
2487         "symtab",
2488         CommandObjectSP(new CommandObjectTargetModulesDumpSymtab(interpreter)));
2489     LoadSubCommand("sections",
2490                    CommandObjectSP(new CommandObjectTargetModulesDumpSections(
2491                        interpreter)));
2492     LoadSubCommand("symfile",
2493                    CommandObjectSP(
2494                        new CommandObjectTargetModulesDumpSymfile(interpreter)));
2495     LoadSubCommand(
2496         "ast", CommandObjectSP(
2497                    new CommandObjectTargetModulesDumpClangAST(interpreter)));
2498     LoadSubCommand("line-table",
2499                    CommandObjectSP(new CommandObjectTargetModulesDumpLineTable(
2500                        interpreter)));
2501   }
2502
2503   ~CommandObjectTargetModulesDump() override = default;
2504 };
2505
2506 class CommandObjectTargetModulesAdd : public CommandObjectParsed {
2507 public:
2508   CommandObjectTargetModulesAdd(CommandInterpreter &interpreter)
2509       : CommandObjectParsed(interpreter, "target modules add",
2510                             "Add a new module to the current target's modules.",
2511                             "target modules add [<module>]"),
2512         m_option_group(),
2513         m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
2514                       eArgTypeFilename, "Fullpath to a stand alone debug "
2515                                         "symbols file for when debug symbols "
2516                                         "are not in the executable.") {
2517     m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2518                           LLDB_OPT_SET_1);
2519     m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2520     m_option_group.Finalize();
2521   }
2522
2523   ~CommandObjectTargetModulesAdd() override = default;
2524
2525   Options *GetOptions() override { return &m_option_group; }
2526
2527   int HandleArgumentCompletion(
2528       CompletionRequest &request,
2529       OptionElementVector &opt_element_vector) override {
2530     CommandCompletions::InvokeCommonCompletionCallbacks(
2531         GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
2532         request, nullptr);
2533     return request.GetNumberOfMatches();
2534   }
2535
2536 protected:
2537   OptionGroupOptions m_option_group;
2538   OptionGroupUUID m_uuid_option_group;
2539   OptionGroupFile m_symbol_file;
2540
2541   bool DoExecute(Args &args, CommandReturnObject &result) override {
2542     Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2543     if (target == nullptr) {
2544       result.AppendError("invalid target, create a debug target using the "
2545                          "'target create' command");
2546       result.SetStatus(eReturnStatusFailed);
2547       return false;
2548     } else {
2549       bool flush = false;
2550
2551       const size_t argc = args.GetArgumentCount();
2552       if (argc == 0) {
2553         if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2554           // We are given a UUID only, go locate the file
2555           ModuleSpec module_spec;
2556           module_spec.GetUUID() =
2557               m_uuid_option_group.GetOptionValue().GetCurrentValue();
2558           if (m_symbol_file.GetOptionValue().OptionWasSet())
2559             module_spec.GetSymbolFileSpec() =
2560                 m_symbol_file.GetOptionValue().GetCurrentValue();
2561           if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
2562             ModuleSP module_sp(target->GetSharedModule(module_spec));
2563             if (module_sp) {
2564               result.SetStatus(eReturnStatusSuccessFinishResult);
2565               return true;
2566             } else {
2567               StreamString strm;
2568               module_spec.GetUUID().Dump(&strm);
2569               if (module_spec.GetFileSpec()) {
2570                 if (module_spec.GetSymbolFileSpec()) {
2571                   result.AppendErrorWithFormat(
2572                       "Unable to create the executable or symbol file with "
2573                       "UUID %s with path %s and symbol file %s",
2574                       strm.GetData(),
2575                       module_spec.GetFileSpec().GetPath().c_str(),
2576                       module_spec.GetSymbolFileSpec().GetPath().c_str());
2577                 } else {
2578                   result.AppendErrorWithFormat(
2579                       "Unable to create the executable or symbol file with "
2580                       "UUID %s with path %s",
2581                       strm.GetData(),
2582                       module_spec.GetFileSpec().GetPath().c_str());
2583                 }
2584               } else {
2585                 result.AppendErrorWithFormat("Unable to create the executable "
2586                                              "or symbol file with UUID %s",
2587                                              strm.GetData());
2588               }
2589               result.SetStatus(eReturnStatusFailed);
2590               return false;
2591             }
2592           } else {
2593             StreamString strm;
2594             module_spec.GetUUID().Dump(&strm);
2595             result.AppendErrorWithFormat(
2596                 "Unable to locate the executable or symbol file with UUID %s",
2597                 strm.GetData());
2598             result.SetStatus(eReturnStatusFailed);
2599             return false;
2600           }
2601         } else {
2602           result.AppendError(
2603               "one or more executable image paths must be specified");
2604           result.SetStatus(eReturnStatusFailed);
2605           return false;
2606         }
2607       } else {
2608         for (auto &entry : args.entries()) {
2609           if (entry.ref.empty())
2610             continue;
2611
2612           FileSpec file_spec(entry.ref);
2613           if (FileSystem::Instance().Exists(file_spec)) {
2614             ModuleSpec module_spec(file_spec);
2615             if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2616               module_spec.GetUUID() =
2617                   m_uuid_option_group.GetOptionValue().GetCurrentValue();
2618             if (m_symbol_file.GetOptionValue().OptionWasSet())
2619               module_spec.GetSymbolFileSpec() =
2620                   m_symbol_file.GetOptionValue().GetCurrentValue();
2621             if (!module_spec.GetArchitecture().IsValid())
2622               module_spec.GetArchitecture() = target->GetArchitecture();
2623             Status error;
2624             ModuleSP module_sp(target->GetSharedModule(module_spec, &error));
2625             if (!module_sp) {
2626               const char *error_cstr = error.AsCString();
2627               if (error_cstr)
2628                 result.AppendError(error_cstr);
2629               else
2630                 result.AppendErrorWithFormat("unsupported module: %s",
2631                                              entry.c_str());
2632               result.SetStatus(eReturnStatusFailed);
2633               return false;
2634             } else {
2635               flush = true;
2636             }
2637             result.SetStatus(eReturnStatusSuccessFinishResult);
2638           } else {
2639             std::string resolved_path = file_spec.GetPath();
2640             result.SetStatus(eReturnStatusFailed);
2641             if (resolved_path != entry.ref) {
2642               result.AppendErrorWithFormat(
2643                   "invalid module path '%s' with resolved path '%s'\n",
2644                   entry.ref.str().c_str(), resolved_path.c_str());
2645               break;
2646             }
2647             result.AppendErrorWithFormat("invalid module path '%s'\n",
2648                                          entry.c_str());
2649             break;
2650           }
2651         }
2652       }
2653
2654       if (flush) {
2655         ProcessSP process = target->GetProcessSP();
2656         if (process)
2657           process->Flush();
2658       }
2659     }
2660
2661     return result.Succeeded();
2662   }
2663 };
2664
2665 class CommandObjectTargetModulesLoad
2666     : public CommandObjectTargetModulesModuleAutoComplete {
2667 public:
2668   CommandObjectTargetModulesLoad(CommandInterpreter &interpreter)
2669       : CommandObjectTargetModulesModuleAutoComplete(
2670             interpreter, "target modules load", "Set the load addresses for "
2671                                                 "one or more sections in a "
2672                                                 "target module.",
2673             "target modules load [--file <module> --uuid <uuid>] <sect-name> "
2674             "<address> [<sect-name> <address> ....]"),
2675         m_option_group(),
2676         m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,
2677                       "Fullpath or basename for module to load.", ""),
2678         m_load_option(LLDB_OPT_SET_1, false, "load", 'l',
2679                       "Write file contents to the memory.", false, true),
2680         m_pc_option(LLDB_OPT_SET_1, false, "set-pc-to-entry", 'p',
2681                     "Set PC to the entry point."
2682                     " Only applicable with '--load' option.",
2683                     false, true),
2684         m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,
2685                        "Set the load address for all sections to be the "
2686                        "virtual address in the file plus the offset.",
2687                        0) {
2688     m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2689                           LLDB_OPT_SET_1);
2690     m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2691     m_option_group.Append(&m_load_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2692     m_option_group.Append(&m_pc_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2693     m_option_group.Append(&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2694     m_option_group.Finalize();
2695   }
2696
2697   ~CommandObjectTargetModulesLoad() override = default;
2698
2699   Options *GetOptions() override { return &m_option_group; }
2700
2701 protected:
2702   bool DoExecute(Args &args, CommandReturnObject &result) override {
2703     Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2704     const bool load = m_load_option.GetOptionValue().GetCurrentValue();
2705     const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue();
2706     if (target == nullptr) {
2707       result.AppendError("invalid target, create a debug target using the "
2708                          "'target create' command");
2709       result.SetStatus(eReturnStatusFailed);
2710       return false;
2711     } else {
2712       const size_t argc = args.GetArgumentCount();
2713       ModuleSpec module_spec;
2714       bool search_using_module_spec = false;
2715
2716       // Allow "load" option to work without --file or --uuid option.
2717       if (load) {
2718         if (!m_file_option.GetOptionValue().OptionWasSet() &&
2719             !m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2720           ModuleList &module_list = target->GetImages();
2721           if (module_list.GetSize() == 1) {
2722             search_using_module_spec = true;
2723             module_spec.GetFileSpec() =
2724                 module_list.GetModuleAtIndex(0)->GetFileSpec();
2725           }
2726         }
2727       }
2728
2729       if (m_file_option.GetOptionValue().OptionWasSet()) {
2730         search_using_module_spec = true;
2731         const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
2732         const bool use_global_module_list = true;
2733         ModuleList module_list;
2734         const size_t num_matches = FindModulesByName(
2735             target, arg_cstr, module_list, use_global_module_list);
2736         if (num_matches == 1) {
2737           module_spec.GetFileSpec() =
2738               module_list.GetModuleAtIndex(0)->GetFileSpec();
2739         } else if (num_matches > 1) {
2740           search_using_module_spec = false;
2741           result.AppendErrorWithFormat(
2742               "more than 1 module matched by name '%s'\n", arg_cstr);
2743           result.SetStatus(eReturnStatusFailed);
2744         } else {
2745           search_using_module_spec = false;
2746           result.AppendErrorWithFormat("no object file for module '%s'\n",
2747                                        arg_cstr);
2748           result.SetStatus(eReturnStatusFailed);
2749         }
2750       }
2751
2752       if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2753         search_using_module_spec = true;
2754         module_spec.GetUUID() =
2755             m_uuid_option_group.GetOptionValue().GetCurrentValue();
2756       }
2757
2758       if (search_using_module_spec) {
2759         ModuleList matching_modules;
2760         const size_t num_matches =
2761             target->GetImages().FindModules(module_spec, matching_modules);
2762
2763         char path[PATH_MAX];
2764         if (num_matches == 1) {
2765           Module *module = matching_modules.GetModulePointerAtIndex(0);
2766           if (module) {
2767             ObjectFile *objfile = module->GetObjectFile();
2768             if (objfile) {
2769               SectionList *section_list = module->GetSectionList();
2770               if (section_list) {
2771                 bool changed = false;
2772                 if (argc == 0) {
2773                   if (m_slide_option.GetOptionValue().OptionWasSet()) {
2774                     const addr_t slide =
2775                         m_slide_option.GetOptionValue().GetCurrentValue();
2776                     const bool slide_is_offset = true;
2777                     module->SetLoadAddress(*target, slide, slide_is_offset,
2778                                            changed);
2779                   } else {
2780                     result.AppendError("one or more section name + load "
2781                                        "address pair must be specified");
2782                     result.SetStatus(eReturnStatusFailed);
2783                     return false;
2784                   }
2785                 } else {
2786                   if (m_slide_option.GetOptionValue().OptionWasSet()) {
2787                     result.AppendError("The \"--slide <offset>\" option can't "
2788                                        "be used in conjunction with setting "
2789                                        "section load addresses.\n");
2790                     result.SetStatus(eReturnStatusFailed);
2791                     return false;
2792                   }
2793
2794                   for (size_t i = 0; i < argc; i += 2) {
2795                     const char *sect_name = args.GetArgumentAtIndex(i);
2796                     const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
2797                     if (sect_name && load_addr_cstr) {
2798                       ConstString const_sect_name(sect_name);
2799                       bool success = false;
2800                       addr_t load_addr = StringConvert::ToUInt64(
2801                           load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
2802                       if (success) {
2803                         SectionSP section_sp(
2804                             section_list->FindSectionByName(const_sect_name));
2805                         if (section_sp) {
2806                           if (section_sp->IsThreadSpecific()) {
2807                             result.AppendErrorWithFormat(
2808                                 "thread specific sections are not yet "
2809                                 "supported (section '%s')\n",
2810                                 sect_name);
2811                             result.SetStatus(eReturnStatusFailed);
2812                             break;
2813                           } else {
2814                             if (target->GetSectionLoadList()
2815                                     .SetSectionLoadAddress(section_sp,
2816                                                            load_addr))
2817                               changed = true;
2818                             result.AppendMessageWithFormat(
2819                                 "section '%s' loaded at 0x%" PRIx64 "\n",
2820                                 sect_name, load_addr);
2821                           }
2822                         } else {
2823                           result.AppendErrorWithFormat("no section found that "
2824                                                        "matches the section "
2825                                                        "name '%s'\n",
2826                                                        sect_name);
2827                           result.SetStatus(eReturnStatusFailed);
2828                           break;
2829                         }
2830                       } else {
2831                         result.AppendErrorWithFormat(
2832                             "invalid load address string '%s'\n",
2833                             load_addr_cstr);
2834                         result.SetStatus(eReturnStatusFailed);
2835                         break;
2836                       }
2837                     } else {
2838                       if (sect_name)
2839                         result.AppendError("section names must be followed by "
2840                                            "a load address.\n");
2841                       else
2842                         result.AppendError("one or more section name + load "
2843                                            "address pair must be specified.\n");
2844                       result.SetStatus(eReturnStatusFailed);
2845                       break;
2846                     }
2847                   }
2848                 }
2849
2850                 if (changed) {
2851                   target->ModulesDidLoad(matching_modules);
2852                   Process *process = m_exe_ctx.GetProcessPtr();
2853                   if (process)
2854                     process->Flush();
2855                 }
2856                 if (load) {
2857                   ProcessSP process = target->CalculateProcess();
2858                   Address file_entry = objfile->GetEntryPointAddress();
2859                   if (!process) {
2860                     result.AppendError("No process");
2861                     return false;
2862                   }
2863                   if (set_pc && !file_entry.IsValid()) {
2864                     result.AppendError("No entry address in object file");
2865                     return false;
2866                   }
2867                   std::vector<ObjectFile::LoadableData> loadables(
2868                       objfile->GetLoadableData(*target));
2869                   if (loadables.size() == 0) {
2870                     result.AppendError("No loadable sections");
2871                     return false;
2872                   }
2873                   Status error = process->WriteObjectFile(std::move(loadables));
2874                   if (error.Fail()) {
2875                     result.AppendError(error.AsCString());
2876                     return false;
2877                   }
2878                   if (set_pc) {
2879                     ThreadList &thread_list = process->GetThreadList();
2880                     RegisterContextSP reg_context(
2881                         thread_list.GetSelectedThread()->GetRegisterContext());
2882                     addr_t file_entry_addr = file_entry.GetLoadAddress(target);
2883                     if (!reg_context->SetPC(file_entry_addr)) {
2884                       result.AppendErrorWithFormat("failed to set PC value to "
2885                                                    "0x%" PRIx64 "\n",
2886                                                    file_entry_addr);
2887                       result.SetStatus(eReturnStatusFailed);
2888                     }
2889                   }
2890                 }
2891               } else {
2892                 module->GetFileSpec().GetPath(path, sizeof(path));
2893                 result.AppendErrorWithFormat(
2894                     "no sections in object file '%s'\n", path);
2895                 result.SetStatus(eReturnStatusFailed);
2896               }
2897             } else {
2898               module->GetFileSpec().GetPath(path, sizeof(path));
2899               result.AppendErrorWithFormat("no object file for module '%s'\n",
2900                                            path);
2901               result.SetStatus(eReturnStatusFailed);
2902             }
2903           } else {
2904             FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
2905             if (module_spec_file) {
2906               module_spec_file->GetPath(path, sizeof(path));
2907               result.AppendErrorWithFormat("invalid module '%s'.\n", path);
2908             } else
2909               result.AppendError("no module spec");
2910             result.SetStatus(eReturnStatusFailed);
2911           }
2912         } else {
2913           std::string uuid_str;
2914
2915           if (module_spec.GetFileSpec())
2916             module_spec.GetFileSpec().GetPath(path, sizeof(path));
2917           else
2918             path[0] = '\0';
2919
2920           if (module_spec.GetUUIDPtr())
2921             uuid_str = module_spec.GetUUID().GetAsString();
2922           if (num_matches > 1) {
2923             result.AppendErrorWithFormat(
2924                 "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "",
2925                 path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
2926             for (size_t i = 0; i < num_matches; ++i) {
2927               if (matching_modules.GetModulePointerAtIndex(i)
2928                       ->GetFileSpec()
2929                       .GetPath(path, sizeof(path)))
2930                 result.AppendMessageWithFormat("%s\n", path);
2931             }
2932           } else {
2933             result.AppendErrorWithFormat(
2934                 "no modules were found  that match%s%s%s%s.\n",
2935                 path[0] ? " file=" : "", path,
2936                 !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
2937           }
2938           result.SetStatus(eReturnStatusFailed);
2939         }
2940       } else {
2941         result.AppendError("either the \"--file <module>\" or the \"--uuid "
2942                            "<uuid>\" option must be specified.\n");
2943         result.SetStatus(eReturnStatusFailed);
2944         return false;
2945       }
2946     }
2947     return result.Succeeded();
2948   }
2949
2950   OptionGroupOptions m_option_group;
2951   OptionGroupUUID m_uuid_option_group;
2952   OptionGroupString m_file_option;
2953   OptionGroupBoolean m_load_option;
2954   OptionGroupBoolean m_pc_option;
2955   OptionGroupUInt64 m_slide_option;
2956 };
2957
2958 //----------------------------------------------------------------------
2959 // List images with associated information
2960 //----------------------------------------------------------------------
2961
2962 static constexpr OptionDefinition g_target_modules_list_options[] = {
2963     // clang-format off
2964   { LLDB_OPT_SET_1, false, "address",        'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Display the image at this address." },
2965   { LLDB_OPT_SET_1, false, "arch",           'A', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth,               "Display the architecture when listing images." },
2966   { LLDB_OPT_SET_1, false, "triple",         't', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth,               "Display the triple when listing images." },
2967   { LLDB_OPT_SET_1, false, "header",         'h', OptionParser::eNoArgument,       nullptr, {}, 0, eArgTypeNone,                "Display the image base address as a load address if debugging, a file address otherwise." },
2968   { LLDB_OPT_SET_1, false, "offset",         'o', OptionParser::eNoArgument,       nullptr, {}, 0, eArgTypeNone,                "Display the image load address offset from the base file address (the slide amount)." },
2969   { LLDB_OPT_SET_1, false, "uuid",           'u', OptionParser::eNoArgument,       nullptr, {}, 0, eArgTypeNone,                "Display the UUID when listing images." },
2970   { LLDB_OPT_SET_1, false, "fullpath",       'f', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth,               "Display the fullpath to the image object file." },
2971   { LLDB_OPT_SET_1, false, "directory",      'd', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth,               "Display the directory with optional width for the image object file." },
2972   { LLDB_OPT_SET_1, false, "basename",       'b', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth,               "Display the basename with optional width for the image object file." },
2973   { LLDB_OPT_SET_1, false, "symfile",        's', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth,               "Display the fullpath to the image symbol file with optional width." },
2974   { LLDB_OPT_SET_1, false, "symfile-unique", 'S', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth,               "Display the symbol file with optional width only if it is different from the executable object file." },
2975   { LLDB_OPT_SET_1, false, "mod-time",       'm', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth,               "Display the modification time with optional width of the module." },
2976   { LLDB_OPT_SET_1, false, "ref-count",      'r', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth,               "Display the reference count if the module is still in the shared module cache." },
2977   { LLDB_OPT_SET_1, false, "pointer",        'p', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeNone,                "Display the module pointer." },
2978   { LLDB_OPT_SET_1, false, "global",         'g', OptionParser::eNoArgument,       nullptr, {}, 0, eArgTypeNone,                "Display the modules from the global module list, not just the current target." }
2979     // clang-format on
2980 };
2981
2982 class CommandObjectTargetModulesList : public CommandObjectParsed {
2983 public:
2984   class CommandOptions : public Options {
2985   public:
2986     CommandOptions()
2987         : Options(), m_format_array(), m_use_global_module_list(false),
2988           m_module_addr(LLDB_INVALID_ADDRESS) {}
2989
2990     ~CommandOptions() override = default;
2991
2992     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2993                           ExecutionContext *execution_context) override {
2994       Status error;
2995
2996       const int short_option = m_getopt_table[option_idx].val;
2997       if (short_option == 'g') {
2998         m_use_global_module_list = true;
2999       } else if (short_option == 'a') {
3000         m_module_addr = OptionArgParser::ToAddress(
3001             execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);
3002       } else {
3003         unsigned long width = 0;
3004         option_arg.getAsInteger(0, width);
3005         m_format_array.push_back(std::make_pair(short_option, width));
3006       }
3007       return error;
3008     }
3009
3010     void OptionParsingStarting(ExecutionContext *execution_context) override {
3011       m_format_array.clear();
3012       m_use_global_module_list = false;
3013       m_module_addr = LLDB_INVALID_ADDRESS;
3014     }
3015
3016     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3017       return llvm::makeArrayRef(g_target_modules_list_options);
3018     }
3019
3020     // Instance variables to hold the values for command options.
3021     typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection;
3022     FormatWidthCollection m_format_array;
3023     bool m_use_global_module_list;
3024     lldb::addr_t m_module_addr;
3025   };
3026
3027   CommandObjectTargetModulesList(CommandInterpreter &interpreter)
3028       : CommandObjectParsed(
3029             interpreter, "target modules list",
3030             "List current executable and dependent shared library images.",
3031             "target modules list [<cmd-options>]"),
3032         m_options() {}
3033
3034   ~CommandObjectTargetModulesList() override = default;
3035
3036   Options *GetOptions() override { return &m_options; }
3037
3038 protected:
3039   bool DoExecute(Args &command, CommandReturnObject &result) override {
3040     Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3041     const bool use_global_module_list = m_options.m_use_global_module_list;
3042     // Define a local module list here to ensure it lives longer than any
3043     // "locker" object which might lock its contents below (through the
3044     // "module_list_ptr" variable).
3045     ModuleList module_list;
3046     if (target == nullptr && !use_global_module_list) {
3047       result.AppendError("invalid target, create a debug target using the "
3048                          "'target create' command");
3049       result.SetStatus(eReturnStatusFailed);
3050       return false;
3051     } else {
3052       if (target) {
3053         uint32_t addr_byte_size =
3054             target->GetArchitecture().GetAddressByteSize();
3055         result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3056         result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3057       }
3058       // Dump all sections for all modules images
3059       Stream &strm = result.GetOutputStream();
3060
3061       if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) {
3062         if (target) {
3063           Address module_address;
3064           if (module_address.SetLoadAddress(m_options.m_module_addr, target)) {
3065             ModuleSP module_sp(module_address.GetModule());
3066             if (module_sp) {
3067               PrintModule(target, module_sp.get(), 0, strm);
3068               result.SetStatus(eReturnStatusSuccessFinishResult);
3069             } else {
3070               result.AppendErrorWithFormat(
3071                   "Couldn't find module matching address: 0x%" PRIx64 ".",
3072                   m_options.m_module_addr);
3073               result.SetStatus(eReturnStatusFailed);
3074             }
3075           } else {
3076             result.AppendErrorWithFormat(
3077                 "Couldn't find module containing address: 0x%" PRIx64 ".",
3078                 m_options.m_module_addr);
3079             result.SetStatus(eReturnStatusFailed);
3080           }
3081         } else {
3082           result.AppendError(
3083               "Can only look up modules by address with a valid target.");
3084           result.SetStatus(eReturnStatusFailed);
3085         }
3086         return result.Succeeded();
3087       }
3088
3089       size_t num_modules = 0;
3090
3091       // This locker will be locked on the mutex in module_list_ptr if it is
3092       // non-nullptr. Otherwise it will lock the
3093       // AllocationModuleCollectionMutex when accessing the global module list
3094       // directly.
3095       std::unique_lock<std::recursive_mutex> guard(
3096           Module::GetAllocationModuleCollectionMutex(), std::defer_lock);
3097
3098       const ModuleList *module_list_ptr = nullptr;
3099       const size_t argc = command.GetArgumentCount();
3100       if (argc == 0) {
3101         if (use_global_module_list) {
3102           guard.lock();
3103           num_modules = Module::GetNumberAllocatedModules();
3104         } else {
3105           module_list_ptr = &target->GetImages();
3106         }
3107       } else {
3108         // TODO: Convert to entry based iteration.  Requires converting
3109         // FindModulesByName.
3110         for (size_t i = 0; i < argc; ++i) {
3111           // Dump specified images (by basename or fullpath)
3112           const char *arg_cstr = command.GetArgumentAtIndex(i);
3113           const size_t num_matches = FindModulesByName(
3114               target, arg_cstr, module_list, use_global_module_list);
3115           if (num_matches == 0) {
3116             if (argc == 1) {
3117               result.AppendErrorWithFormat("no modules found that match '%s'",
3118                                            arg_cstr);
3119               result.SetStatus(eReturnStatusFailed);
3120               return false;
3121             }
3122           }
3123         }
3124
3125         module_list_ptr = &module_list;
3126       }
3127
3128       std::unique_lock<std::recursive_mutex> lock;
3129       if (module_list_ptr != nullptr) {
3130         lock =
3131             std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
3132
3133         num_modules = module_list_ptr->GetSize();
3134       }
3135
3136       if (num_modules > 0) {
3137         for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
3138           ModuleSP module_sp;
3139           Module *module;
3140           if (module_list_ptr) {
3141             module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
3142             module = module_sp.get();
3143           } else {
3144             module = Module::GetAllocatedModuleAtIndex(image_idx);
3145             module_sp = module->shared_from_this();
3146           }
3147
3148           const size_t indent = strm.Printf("[%3u] ", image_idx);
3149           PrintModule(target, module, indent, strm);
3150         }
3151         result.SetStatus(eReturnStatusSuccessFinishResult);
3152       } else {
3153         if (argc) {
3154           if (use_global_module_list)
3155             result.AppendError(
3156                 "the global module list has no matching modules");
3157           else
3158             result.AppendError("the target has no matching modules");
3159         } else {
3160           if (use_global_module_list)
3161             result.AppendError("the global module list is empty");
3162           else
3163             result.AppendError(
3164                 "the target has no associated executable images");
3165         }
3166         result.SetStatus(eReturnStatusFailed);
3167         return false;
3168       }
3169     }
3170     return result.Succeeded();
3171   }
3172
3173   void PrintModule(Target *target, Module *module, int indent, Stream &strm) {
3174     if (module == nullptr) {
3175       strm.PutCString("Null module");
3176       return;
3177     }
3178
3179     bool dump_object_name = false;
3180     if (m_options.m_format_array.empty()) {
3181       m_options.m_format_array.push_back(std::make_pair('u', 0));
3182       m_options.m_format_array.push_back(std::make_pair('h', 0));
3183       m_options.m_format_array.push_back(std::make_pair('f', 0));
3184       m_options.m_format_array.push_back(std::make_pair('S', 0));
3185     }
3186     const size_t num_entries = m_options.m_format_array.size();
3187     bool print_space = false;
3188     for (size_t i = 0; i < num_entries; ++i) {
3189       if (print_space)
3190         strm.PutChar(' ');
3191       print_space = true;
3192       const char format_char = m_options.m_format_array[i].first;
3193       uint32_t width = m_options.m_format_array[i].second;
3194       switch (format_char) {
3195       case 'A':
3196         DumpModuleArchitecture(strm, module, false, width);
3197         break;
3198
3199       case 't':
3200         DumpModuleArchitecture(strm, module, true, width);
3201         break;
3202
3203       case 'f':
3204         DumpFullpath(strm, &module->GetFileSpec(), width);
3205         dump_object_name = true;
3206         break;
3207
3208       case 'd':
3209         DumpDirectory(strm, &module->GetFileSpec(), width);
3210         break;
3211
3212       case 'b':
3213         DumpBasename(strm, &module->GetFileSpec(), width);
3214         dump_object_name = true;
3215         break;
3216
3217       case 'h':
3218       case 'o':
3219         // Image header address
3220         {
3221           uint32_t addr_nibble_width =
3222               target ? (target->GetArchitecture().GetAddressByteSize() * 2)
3223                      : 16;
3224
3225           ObjectFile *objfile = module->GetObjectFile();
3226           if (objfile) {
3227             Address base_addr(objfile->GetBaseAddress());
3228             if (base_addr.IsValid()) {
3229               if (target && !target->GetSectionLoadList().IsEmpty()) {
3230                 lldb::addr_t load_addr =
3231                     base_addr.GetLoadAddress(target);
3232                 if (load_addr == LLDB_INVALID_ADDRESS) {
3233                   base_addr.Dump(&strm, target,
3234                                    Address::DumpStyleModuleWithFileAddress,
3235                                    Address::DumpStyleFileAddress);
3236                 } else {
3237                   if (format_char == 'o') {
3238                     // Show the offset of slide for the image
3239                     strm.Printf(
3240                         "0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width,
3241                         load_addr - base_addr.GetFileAddress());
3242                   } else {
3243                     // Show the load address of the image
3244                     strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3245                                 addr_nibble_width, load_addr);
3246                   }
3247                 }
3248                 break;
3249               }
3250               // The address was valid, but the image isn't loaded, output the
3251               // address in an appropriate format
3252               base_addr.Dump(&strm, target, Address::DumpStyleFileAddress);
3253               break;
3254             }
3255           }
3256           strm.Printf("%*s", addr_nibble_width + 2, "");
3257         }
3258         break;
3259
3260       case 'r': {
3261         size_t ref_count = 0;
3262         ModuleSP module_sp(module->shared_from_this());
3263         if (module_sp) {
3264           // Take one away to make sure we don't count our local "module_sp"
3265           ref_count = module_sp.use_count() - 1;
3266         }
3267         if (width)
3268           strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count);
3269         else
3270           strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count);
3271       } break;
3272
3273       case 's':
3274       case 'S': {
3275         const SymbolVendor *symbol_vendor = module->GetSymbolVendor();
3276         if (symbol_vendor) {
3277           const FileSpec symfile_spec = symbol_vendor->GetMainFileSpec();
3278           if (format_char == 'S') {
3279             // Dump symbol file only if different from module file
3280             if (!symfile_spec || symfile_spec == module->GetFileSpec()) {
3281               print_space = false;
3282               break;
3283             }
3284             // Add a newline and indent past the index
3285             strm.Printf("\n%*s", indent, "");
3286           }
3287           DumpFullpath(strm, &symfile_spec, width);
3288           dump_object_name = true;
3289           break;
3290         }
3291         strm.Printf("%.*s", width, "<NONE>");
3292       } break;
3293
3294       case 'm':
3295         strm.Format("{0:%c}", llvm::fmt_align(module->GetModificationTime(),
3296                                               llvm::AlignStyle::Left, width));
3297         break;
3298
3299       case 'p':
3300         strm.Printf("%p", static_cast<void *>(module));
3301         break;
3302
3303       case 'u':
3304         DumpModuleUUID(strm, module);
3305         break;
3306
3307       default:
3308         break;
3309       }
3310     }
3311     if (dump_object_name) {
3312       const char *object_name = module->GetObjectName().GetCString();
3313       if (object_name)
3314         strm.Printf("(%s)", object_name);
3315     }
3316     strm.EOL();
3317   }
3318
3319   CommandOptions m_options;
3320 };
3321
3322 #pragma mark CommandObjectTargetModulesShowUnwind
3323
3324 //----------------------------------------------------------------------
3325 // Lookup unwind information in images
3326 //----------------------------------------------------------------------
3327
3328 static constexpr OptionDefinition g_target_modules_show_unwind_options[] = {
3329     // clang-format off
3330   { LLDB_OPT_SET_1, false, "name",    'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFunctionName,        "Show unwind instructions for a function or symbol name." },
3331   { LLDB_OPT_SET_2, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address" }
3332     // clang-format on
3333 };
3334
3335 class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
3336 public:
3337   enum {
3338     eLookupTypeInvalid = -1,
3339     eLookupTypeAddress = 0,
3340     eLookupTypeSymbol,
3341     eLookupTypeFunction,
3342     eLookupTypeFunctionOrSymbol,
3343     kNumLookupTypes
3344   };
3345
3346   class CommandOptions : public Options {
3347   public:
3348     CommandOptions()
3349         : Options(), m_type(eLookupTypeInvalid), m_str(),
3350           m_addr(LLDB_INVALID_ADDRESS) {}
3351
3352     ~CommandOptions() override = default;
3353
3354     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3355                           ExecutionContext *execution_context) override {
3356       Status error;
3357
3358       const int short_option = m_getopt_table[option_idx].val;
3359
3360       switch (short_option) {
3361       case 'a': {
3362         m_str = option_arg;
3363         m_type = eLookupTypeAddress;
3364         m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
3365                                             LLDB_INVALID_ADDRESS, &error);
3366         if (m_addr == LLDB_INVALID_ADDRESS)
3367           error.SetErrorStringWithFormat("invalid address string '%s'",
3368                                          option_arg.str().c_str());
3369         break;
3370       }
3371
3372       case 'n':
3373         m_str = option_arg;
3374         m_type = eLookupTypeFunctionOrSymbol;
3375         break;
3376
3377       default:
3378         error.SetErrorStringWithFormat("unrecognized option %c.", short_option);
3379         break;
3380       }
3381
3382       return error;
3383     }
3384
3385     void OptionParsingStarting(ExecutionContext *execution_context) override {
3386       m_type = eLookupTypeInvalid;
3387       m_str.clear();
3388       m_addr = LLDB_INVALID_ADDRESS;
3389     }
3390
3391     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3392       return llvm::makeArrayRef(g_target_modules_show_unwind_options);
3393     }
3394
3395     // Instance variables to hold the values for command options.
3396
3397     int m_type;        // Should be a eLookupTypeXXX enum after parsing options
3398     std::string m_str; // Holds name lookup
3399     lldb::addr_t m_addr; // Holds the address to lookup
3400   };
3401
3402   CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter)
3403       : CommandObjectParsed(
3404             interpreter, "target modules show-unwind",
3405             "Show synthesized unwind instructions for a function.", nullptr,
3406             eCommandRequiresTarget | eCommandRequiresProcess |
3407                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
3408         m_options() {}
3409
3410   ~CommandObjectTargetModulesShowUnwind() override = default;
3411
3412   Options *GetOptions() override { return &m_options; }
3413
3414 protected:
3415   bool DoExecute(Args &command, CommandReturnObject &result) override {
3416     Target *target = m_exe_ctx.GetTargetPtr();
3417     Process *process = m_exe_ctx.GetProcessPtr();
3418     ABI *abi = nullptr;
3419     if (process)
3420       abi = process->GetABI().get();
3421
3422     if (process == nullptr) {
3423       result.AppendError(
3424           "You must have a process running to use this command.");
3425       result.SetStatus(eReturnStatusFailed);
3426       return false;
3427     }
3428
3429     ThreadList threads(process->GetThreadList());
3430     if (threads.GetSize() == 0) {
3431       result.AppendError("The process must be paused to use this command.");
3432       result.SetStatus(eReturnStatusFailed);
3433       return false;
3434     }
3435
3436     ThreadSP thread(threads.GetThreadAtIndex(0));
3437     if (!thread) {
3438       result.AppendError("The process must be paused to use this command.");
3439       result.SetStatus(eReturnStatusFailed);
3440       return false;
3441     }
3442
3443     SymbolContextList sc_list;
3444
3445     if (m_options.m_type == eLookupTypeFunctionOrSymbol) {
3446       ConstString function_name(m_options.m_str.c_str());
3447       target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,
3448                                         true, false, true, sc_list);
3449     } else if (m_options.m_type == eLookupTypeAddress && target) {
3450       Address addr;
3451       if (target->GetSectionLoadList().ResolveLoadAddress(m_options.m_addr,
3452                                                           addr)) {
3453         SymbolContext sc;
3454         ModuleSP module_sp(addr.GetModule());
3455         module_sp->ResolveSymbolContextForAddress(addr,
3456                                                   eSymbolContextEverything, sc);
3457         if (sc.function || sc.symbol) {
3458           sc_list.Append(sc);
3459         }
3460       }
3461     } else {
3462       result.AppendError(
3463           "address-expression or function name option must be specified.");
3464       result.SetStatus(eReturnStatusFailed);
3465       return false;
3466     }
3467
3468     size_t num_matches = sc_list.GetSize();
3469     if (num_matches == 0) {
3470       result.AppendErrorWithFormat("no unwind data found that matches '%s'.",
3471                                    m_options.m_str.c_str());
3472       result.SetStatus(eReturnStatusFailed);
3473       return false;
3474     }
3475
3476     for (uint32_t idx = 0; idx < num_matches; idx++) {
3477       SymbolContext sc;
3478       sc_list.GetContextAtIndex(idx, sc);
3479       if (sc.symbol == nullptr && sc.function == nullptr)
3480         continue;
3481       if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
3482         continue;
3483       AddressRange range;
3484       if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
3485                               false, range))
3486         continue;
3487       if (!range.GetBaseAddress().IsValid())
3488         continue;
3489       ConstString funcname(sc.GetFunctionName());
3490       if (funcname.IsEmpty())
3491         continue;
3492       addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
3493       if (abi)
3494         start_addr = abi->FixCodeAddress(start_addr);
3495
3496       FuncUnwindersSP func_unwinders_sp(
3497           sc.module_sp->GetObjectFile()
3498               ->GetUnwindTable()
3499               .GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
3500       if (!func_unwinders_sp)
3501         continue;
3502
3503       result.GetOutputStream().Printf(
3504           "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n\n",
3505           sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(),
3506           funcname.AsCString(), start_addr);
3507
3508       UnwindPlanSP non_callsite_unwind_plan =
3509           func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread, -1);
3510       if (non_callsite_unwind_plan) {
3511         result.GetOutputStream().Printf(
3512             "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
3513             non_callsite_unwind_plan->GetSourceName().AsCString());
3514       }
3515       UnwindPlanSP callsite_unwind_plan =
3516           func_unwinders_sp->GetUnwindPlanAtCallSite(*target, -1);
3517       if (callsite_unwind_plan) {
3518         result.GetOutputStream().Printf(
3519             "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
3520             callsite_unwind_plan->GetSourceName().AsCString());
3521       }
3522       UnwindPlanSP fast_unwind_plan =
3523           func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
3524       if (fast_unwind_plan) {
3525         result.GetOutputStream().Printf(
3526             "Fast UnwindPlan is '%s'\n",
3527             fast_unwind_plan->GetSourceName().AsCString());
3528       }
3529
3530       result.GetOutputStream().Printf("\n");
3531
3532       UnwindPlanSP assembly_sp =
3533           func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread, 0);
3534       if (assembly_sp) {
3535         result.GetOutputStream().Printf(
3536             "Assembly language inspection UnwindPlan:\n");
3537         assembly_sp->Dump(result.GetOutputStream(), thread.get(),
3538                           LLDB_INVALID_ADDRESS);
3539         result.GetOutputStream().Printf("\n");
3540       }
3541
3542       UnwindPlanSP ehframe_sp =
3543           func_unwinders_sp->GetEHFrameUnwindPlan(*target, 0);
3544       if (ehframe_sp) {
3545         result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3546         ehframe_sp->Dump(result.GetOutputStream(), thread.get(),
3547                          LLDB_INVALID_ADDRESS);
3548         result.GetOutputStream().Printf("\n");
3549       }
3550
3551       UnwindPlanSP ehframe_augmented_sp =
3552           func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread, 0);
3553       if (ehframe_augmented_sp) {
3554         result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3555         ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
3556                                    LLDB_INVALID_ADDRESS);
3557         result.GetOutputStream().Printf("\n");
3558       }
3559
3560       if (UnwindPlanSP plan_sp =
3561               func_unwinders_sp->GetDebugFrameUnwindPlan(*target, 0)) {
3562         result.GetOutputStream().Printf("debug_frame UnwindPlan:\n");
3563         plan_sp->Dump(result.GetOutputStream(), thread.get(),
3564                       LLDB_INVALID_ADDRESS);
3565         result.GetOutputStream().Printf("\n");
3566       }
3567
3568       if (UnwindPlanSP plan_sp =
3569               func_unwinders_sp->GetDebugFrameAugmentedUnwindPlan(*target,
3570                                                                   *thread, 0)) {
3571         result.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n");
3572         plan_sp->Dump(result.GetOutputStream(), thread.get(),
3573                       LLDB_INVALID_ADDRESS);
3574         result.GetOutputStream().Printf("\n");
3575       }
3576
3577       UnwindPlanSP arm_unwind_sp =
3578           func_unwinders_sp->GetArmUnwindUnwindPlan(*target, 0);
3579       if (arm_unwind_sp) {
3580         result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
3581         arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3582                             LLDB_INVALID_ADDRESS);
3583         result.GetOutputStream().Printf("\n");
3584       }
3585
3586       UnwindPlanSP compact_unwind_sp =
3587           func_unwinders_sp->GetCompactUnwindUnwindPlan(*target, 0);
3588       if (compact_unwind_sp) {
3589         result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3590         compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3591                                 LLDB_INVALID_ADDRESS);
3592         result.GetOutputStream().Printf("\n");
3593       }
3594
3595       if (fast_unwind_plan) {
3596         result.GetOutputStream().Printf("Fast UnwindPlan:\n");
3597         fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(),
3598                                LLDB_INVALID_ADDRESS);
3599         result.GetOutputStream().Printf("\n");
3600       }
3601
3602       ABISP abi_sp = process->GetABI();
3603       if (abi_sp) {
3604         UnwindPlan arch_default(lldb::eRegisterKindGeneric);
3605         if (abi_sp->CreateDefaultUnwindPlan(arch_default)) {
3606           result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3607           arch_default.Dump(result.GetOutputStream(), thread.get(),
3608                             LLDB_INVALID_ADDRESS);
3609           result.GetOutputStream().Printf("\n");
3610         }
3611
3612         UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
3613         if (abi_sp->CreateFunctionEntryUnwindPlan(arch_entry)) {
3614           result.GetOutputStream().Printf(
3615               "Arch default at entry point UnwindPlan:\n");
3616           arch_entry.Dump(result.GetOutputStream(), thread.get(),
3617                           LLDB_INVALID_ADDRESS);
3618           result.GetOutputStream().Printf("\n");
3619         }
3620       }
3621
3622       result.GetOutputStream().Printf("\n");
3623     }
3624     return result.Succeeded();
3625   }
3626
3627   CommandOptions m_options;
3628 };
3629
3630 //----------------------------------------------------------------------
3631 // Lookup information in images
3632 //----------------------------------------------------------------------
3633
3634 static constexpr OptionDefinition g_target_modules_lookup_options[] = {
3635     // clang-format off
3636   { LLDB_OPT_SET_1,                                  true,  "address",    'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules." },
3637   { LLDB_OPT_SET_1,                                  false, "offset",     'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOffset,              "When looking up an address subtract <offset> from any addresses before doing the lookup." },
3638   /* FIXME: re-enable regex for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */
3639   { LLDB_OPT_SET_2 | LLDB_OPT_SET_4 | LLDB_OPT_SET_5, false, "regex",      'r', OptionParser::eNoArgument,      nullptr, {}, 0, eArgTypeNone,                "The <name> argument for name lookups are regular expressions." },
3640   { LLDB_OPT_SET_2,                                  true,  "symbol",     's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeSymbol,              "Lookup a symbol by name in the symbol tables in one or more target modules." },
3641   { LLDB_OPT_SET_3,                                  true,  "file",       'f', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFilename,            "Lookup a file by fullpath or basename in one or more target modules." },
3642   { LLDB_OPT_SET_3,                                  false, "line",       'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum,             "Lookup a line number in a file (must be used in conjunction with --file)." },
3643   { LLDB_OPT_SET_FROM_TO(3,5),                       false, "no-inlines", 'i', OptionParser::eNoArgument,       nullptr, {}, 0, eArgTypeNone,                "Ignore inline entries (must be used in conjunction with --file or --function)." },
3644   { LLDB_OPT_SET_4,                                  true,  "function",   'F', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFunctionName,        "Lookup a function by name in the debug symbols in one or more target modules." },
3645   { LLDB_OPT_SET_5,                                  true,  "name",       'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFunctionOrSymbol,    "Lookup a function or symbol by name in one or more target modules." },
3646   { LLDB_OPT_SET_6,                                  true,  "type",       't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName,                "Lookup a type by name in the debug symbols in one or more target modules." },
3647   { LLDB_OPT_SET_ALL,                                false, "verbose",    'v', OptionParser::eNoArgument,       nullptr, {}, 0, eArgTypeNone,                "Enable verbose lookup information." },
3648   { LLDB_OPT_SET_ALL,                                false, "all",        'A', OptionParser::eNoArgument,       nullptr, {}, 0, eArgTypeNone,                "Print all matches, not just the best match, if a best match is available." },
3649     // clang-format on
3650 };
3651
3652 class CommandObjectTargetModulesLookup : public CommandObjectParsed {
3653 public:
3654   enum {
3655     eLookupTypeInvalid = -1,
3656     eLookupTypeAddress = 0,
3657     eLookupTypeSymbol,
3658     eLookupTypeFileLine, // Line is optional
3659     eLookupTypeFunction,
3660     eLookupTypeFunctionOrSymbol,
3661     eLookupTypeType,
3662     kNumLookupTypes
3663   };
3664
3665   class CommandOptions : public Options {
3666   public:
3667     CommandOptions() : Options() { OptionParsingStarting(nullptr); }
3668
3669     ~CommandOptions() override = default;
3670
3671     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3672                           ExecutionContext *execution_context) override {
3673       Status error;
3674
3675       const int short_option = m_getopt_table[option_idx].val;
3676
3677       switch (short_option) {
3678       case 'a': {
3679         m_type = eLookupTypeAddress;
3680         m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
3681                                             LLDB_INVALID_ADDRESS, &error);
3682       } break;
3683
3684       case 'o':
3685         if (option_arg.getAsInteger(0, m_offset))
3686           error.SetErrorStringWithFormat("invalid offset string '%s'",
3687                                          option_arg.str().c_str());
3688         break;
3689
3690       case 's':
3691         m_str = option_arg;
3692         m_type = eLookupTypeSymbol;
3693         break;
3694
3695       case 'f':
3696         m_file.SetFile(option_arg, FileSpec::Style::native);
3697         m_type = eLookupTypeFileLine;
3698         break;
3699
3700       case 'i':
3701         m_include_inlines = false;
3702         break;
3703
3704       case 'l':
3705         if (option_arg.getAsInteger(0, m_line_number))
3706           error.SetErrorStringWithFormat("invalid line number string '%s'",
3707                                          option_arg.str().c_str());
3708         else if (m_line_number == 0)
3709           error.SetErrorString("zero is an invalid line number");
3710         m_type = eLookupTypeFileLine;
3711         break;
3712
3713       case 'F':
3714         m_str = option_arg;
3715         m_type = eLookupTypeFunction;
3716         break;
3717
3718       case 'n':
3719         m_str = option_arg;
3720         m_type = eLookupTypeFunctionOrSymbol;
3721         break;
3722
3723       case 't':
3724         m_str = option_arg;
3725         m_type = eLookupTypeType;
3726         break;
3727
3728       case 'v':
3729         m_verbose = 1;
3730         break;
3731
3732       case 'A':
3733         m_print_all = true;
3734         break;
3735
3736       case 'r':
3737         m_use_regex = true;
3738         break;
3739       }
3740
3741       return error;
3742     }
3743
3744     void OptionParsingStarting(ExecutionContext *execution_context) override {
3745       m_type = eLookupTypeInvalid;
3746       m_str.clear();
3747       m_file.Clear();
3748       m_addr = LLDB_INVALID_ADDRESS;
3749       m_offset = 0;
3750       m_line_number = 0;
3751       m_use_regex = false;
3752       m_include_inlines = true;
3753       m_verbose = false;
3754       m_print_all = false;
3755     }
3756
3757     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3758       return llvm::makeArrayRef(g_target_modules_lookup_options);
3759     }
3760
3761     int m_type;        // Should be a eLookupTypeXXX enum after parsing options
3762     std::string m_str; // Holds name lookup
3763     FileSpec m_file;   // Files for file lookups
3764     lldb::addr_t m_addr; // Holds the address to lookup
3765     lldb::addr_t
3766         m_offset; // Subtract this offset from m_addr before doing lookups.
3767     uint32_t m_line_number; // Line number for file+line lookups
3768     bool m_use_regex;       // Name lookups in m_str are regular expressions.
3769     bool m_include_inlines; // Check for inline entries when looking up by
3770                             // file/line.
3771     bool m_verbose;         // Enable verbose lookup info
3772     bool m_print_all; // Print all matches, even in cases where there's a best
3773                       // match.
3774   };
3775
3776   CommandObjectTargetModulesLookup(CommandInterpreter &interpreter)
3777       : CommandObjectParsed(interpreter, "target modules lookup",
3778                             "Look up information within executable and "
3779                             "dependent shared library images.",
3780                             nullptr, eCommandRequiresTarget),
3781         m_options() {
3782     CommandArgumentEntry arg;
3783     CommandArgumentData file_arg;
3784
3785     // Define the first (and only) variant of this arg.
3786     file_arg.arg_type = eArgTypeFilename;
3787     file_arg.arg_repetition = eArgRepeatStar;
3788
3789     // There is only one variant this argument could be; put it into the
3790     // argument entry.
3791     arg.push_back(file_arg);
3792
3793     // Push the data for the first argument into the m_arguments vector.
3794     m_arguments.push_back(arg);
3795   }
3796
3797   ~CommandObjectTargetModulesLookup() override = default;
3798
3799   Options *GetOptions() override { return &m_options; }
3800
3801   bool LookupHere(CommandInterpreter &interpreter, CommandReturnObject &result,
3802                   bool &syntax_error) {
3803     switch (m_options.m_type) {
3804     case eLookupTypeAddress:
3805     case eLookupTypeFileLine:
3806     case eLookupTypeFunction:
3807     case eLookupTypeFunctionOrSymbol:
3808     case eLookupTypeSymbol:
3809     default:
3810       return false;
3811     case eLookupTypeType:
3812       break;
3813     }
3814
3815     StackFrameSP frame = m_exe_ctx.GetFrameSP();
3816
3817     if (!frame)
3818       return false;
3819
3820     const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
3821
3822     if (!sym_ctx.module_sp)
3823       return false;
3824
3825     switch (m_options.m_type) {
3826     default:
3827       return false;
3828     case eLookupTypeType:
3829       if (!m_options.m_str.empty()) {
3830         if (LookupTypeHere(m_interpreter, result.GetOutputStream(),
3831                            *sym_ctx.module_sp, m_options.m_str.c_str(),
3832                            m_options.m_use_regex)) {
3833           result.SetStatus(eReturnStatusSuccessFinishResult);
3834           return true;
3835         }
3836       }
3837       break;
3838     }
3839
3840     return true;
3841   }
3842
3843   bool LookupInModule(CommandInterpreter &interpreter, Module *module,
3844                       CommandReturnObject &result, bool &syntax_error) {
3845     switch (m_options.m_type) {
3846     case eLookupTypeAddress:
3847       if (m_options.m_addr != LLDB_INVALID_ADDRESS) {
3848         if (LookupAddressInModule(
3849                 m_interpreter, result.GetOutputStream(), module,
3850                 eSymbolContextEverything |
3851                     (m_options.m_verbose
3852                          ? static_cast<int>(eSymbolContextVariable)
3853                          : 0),
3854                 m_options.m_addr, m_options.m_offset, m_options.m_verbose)) {
3855           result.SetStatus(eReturnStatusSuccessFinishResult);
3856           return true;
3857         }
3858       }
3859       break;
3860
3861     case eLookupTypeSymbol:
3862       if (!m_options.m_str.empty()) {
3863         if (LookupSymbolInModule(m_interpreter, result.GetOutputStream(),
3864                                  module, m_options.m_str.c_str(),
3865                                  m_options.m_use_regex, m_options.m_verbose)) {
3866           result.SetStatus(eReturnStatusSuccessFinishResult);
3867           return true;
3868         }
3869       }
3870       break;
3871
3872     case eLookupTypeFileLine:
3873       if (m_options.m_file) {
3874         if (LookupFileAndLineInModule(
3875                 m_interpreter, result.GetOutputStream(), module,
3876                 m_options.m_file, m_options.m_line_number,
3877                 m_options.m_include_inlines, m_options.m_verbose)) {
3878           result.SetStatus(eReturnStatusSuccessFinishResult);
3879           return true;
3880         }
3881       }
3882       break;
3883
3884     case eLookupTypeFunctionOrSymbol:
3885     case eLookupTypeFunction:
3886       if (!m_options.m_str.empty()) {
3887         if (LookupFunctionInModule(
3888                 m_interpreter, result.GetOutputStream(), module,
3889                 m_options.m_str.c_str(), m_options.m_use_regex,
3890                 m_options.m_include_inlines,
3891                 m_options.m_type ==
3892                     eLookupTypeFunctionOrSymbol, // include symbols
3893                 m_options.m_verbose)) {
3894           result.SetStatus(eReturnStatusSuccessFinishResult);
3895           return true;
3896         }
3897       }
3898       break;
3899
3900     case eLookupTypeType:
3901       if (!m_options.m_str.empty()) {
3902         if (LookupTypeInModule(m_interpreter, result.GetOutputStream(), module,
3903                                m_options.m_str.c_str(),
3904                                m_options.m_use_regex)) {
3905           result.SetStatus(eReturnStatusSuccessFinishResult);
3906           return true;
3907         }
3908       }
3909       break;
3910
3911     default:
3912       m_options.GenerateOptionUsage(
3913           result.GetErrorStream(), this,
3914           GetCommandInterpreter().GetDebugger().GetTerminalWidth());
3915       syntax_error = true;
3916       break;
3917     }
3918
3919     result.SetStatus(eReturnStatusFailed);
3920     return false;
3921   }
3922
3923 protected:
3924   bool DoExecute(Args &command, CommandReturnObject &result) override {
3925     Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3926     if (target == nullptr) {
3927       result.AppendError("invalid target, create a debug target using the "
3928                          "'target create' command");
3929       result.SetStatus(eReturnStatusFailed);
3930       return false;
3931     } else {
3932       bool syntax_error = false;
3933       uint32_t i;
3934       uint32_t num_successful_lookups = 0;
3935       uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3936       result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3937       result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3938       // Dump all sections for all modules images
3939
3940       if (command.GetArgumentCount() == 0) {
3941         ModuleSP current_module;
3942
3943         // Where it is possible to look in the current symbol context first,
3944         // try that.  If this search was successful and --all was not passed,
3945         // don't print anything else.
3946         if (LookupHere(m_interpreter, result, syntax_error)) {
3947           result.GetOutputStream().EOL();
3948           num_successful_lookups++;
3949           if (!m_options.m_print_all) {
3950             result.SetStatus(eReturnStatusSuccessFinishResult);
3951             return result.Succeeded();
3952           }
3953         }
3954
3955         // Dump all sections for all other modules
3956
3957         const ModuleList &target_modules = target->GetImages();
3958         std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
3959         const size_t num_modules = target_modules.GetSize();
3960         if (num_modules > 0) {
3961           for (i = 0; i < num_modules && !syntax_error; ++i) {
3962             Module *module_pointer =
3963                 target_modules.GetModulePointerAtIndexUnlocked(i);
3964
3965             if (module_pointer != current_module.get() &&
3966                 LookupInModule(
3967                     m_interpreter,
3968                     target_modules.GetModulePointerAtIndexUnlocked(i), result,
3969                     syntax_error)) {
3970               result.GetOutputStream().EOL();
3971               num_successful_lookups++;
3972             }
3973           }
3974         } else {
3975           result.AppendError("the target has no associated executable images");
3976           result.SetStatus(eReturnStatusFailed);
3977           return false;
3978         }
3979       } else {
3980         // Dump specified images (by basename or fullpath)
3981         const char *arg_cstr;
3982         for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
3983                     !syntax_error;
3984              ++i) {
3985           ModuleList module_list;
3986           const size_t num_matches =
3987               FindModulesByName(target, arg_cstr, module_list, false);
3988           if (num_matches > 0) {
3989             for (size_t j = 0; j < num_matches; ++j) {
3990               Module *module = module_list.GetModulePointerAtIndex(j);
3991               if (module) {
3992                 if (LookupInModule(m_interpreter, module, result,
3993                                    syntax_error)) {
3994                   result.GetOutputStream().EOL();
3995                   num_successful_lookups++;
3996                 }
3997               }
3998             }
3999           } else
4000             result.AppendWarningWithFormat(
4001                 "Unable to find an image that matches '%s'.\n", arg_cstr);
4002         }
4003       }
4004
4005       if (num_successful_lookups > 0)
4006         result.SetStatus(eReturnStatusSuccessFinishResult);
4007       else
4008         result.SetStatus(eReturnStatusFailed);
4009     }
4010     return result.Succeeded();
4011   }
4012
4013   CommandOptions m_options;
4014 };
4015
4016 #pragma mark CommandObjectMultiwordImageSearchPaths
4017
4018 //-------------------------------------------------------------------------
4019 // CommandObjectMultiwordImageSearchPaths
4020 //-------------------------------------------------------------------------
4021
4022 class CommandObjectTargetModulesImageSearchPaths
4023     : public CommandObjectMultiword {
4024 public:
4025   CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
4026       : CommandObjectMultiword(
4027             interpreter, "target modules search-paths",
4028             "Commands for managing module search paths for a target.",
4029             "target modules search-paths <subcommand> [<subcommand-options>]") {
4030     LoadSubCommand(
4031         "add", CommandObjectSP(
4032                    new CommandObjectTargetModulesSearchPathsAdd(interpreter)));
4033     LoadSubCommand(
4034         "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear(
4035                      interpreter)));
4036     LoadSubCommand(
4037         "insert",
4038         CommandObjectSP(
4039             new CommandObjectTargetModulesSearchPathsInsert(interpreter)));
4040     LoadSubCommand(
4041         "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList(
4042                     interpreter)));
4043     LoadSubCommand(
4044         "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery(
4045                      interpreter)));
4046   }
4047
4048   ~CommandObjectTargetModulesImageSearchPaths() override = default;
4049 };
4050
4051 #pragma mark CommandObjectTargetModules
4052
4053 //-------------------------------------------------------------------------
4054 // CommandObjectTargetModules
4055 //-------------------------------------------------------------------------
4056
4057 class CommandObjectTargetModules : public CommandObjectMultiword {
4058 public:
4059   //------------------------------------------------------------------
4060   // Constructors and Destructors
4061   //------------------------------------------------------------------
4062   CommandObjectTargetModules(CommandInterpreter &interpreter)
4063       : CommandObjectMultiword(interpreter, "target modules",
4064                                "Commands for accessing information for one or "
4065                                "more target modules.",
4066                                "target modules <sub-command> ...") {
4067     LoadSubCommand(
4068         "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter)));
4069     LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad(
4070                                interpreter)));
4071     LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump(
4072                                interpreter)));
4073     LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList(
4074                                interpreter)));
4075     LoadSubCommand(
4076         "lookup",
4077         CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter)));
4078     LoadSubCommand(
4079         "search-paths",
4080         CommandObjectSP(
4081             new CommandObjectTargetModulesImageSearchPaths(interpreter)));
4082     LoadSubCommand(
4083         "show-unwind",
4084         CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter)));
4085   }
4086
4087   ~CommandObjectTargetModules() override = default;
4088
4089 private:
4090   //------------------------------------------------------------------
4091   // For CommandObjectTargetModules only
4092   //------------------------------------------------------------------
4093   DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetModules);
4094 };
4095
4096 class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
4097 public:
4098   CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter)
4099       : CommandObjectParsed(
4100             interpreter, "target symbols add",
4101             "Add a debug symbol file to one of the target's current modules by "
4102             "specifying a path to a debug symbols file, or using the options "
4103             "to specify a module to download symbols for.",
4104             "target symbols add <cmd-options> [<symfile>]",
4105             eCommandRequiresTarget),
4106         m_option_group(),
4107         m_file_option(
4108             LLDB_OPT_SET_1, false, "shlib", 's',
4109             CommandCompletions::eModuleCompletion, eArgTypeShlibName,
4110             "Fullpath or basename for module to find debug symbols for."),
4111         m_current_frame_option(
4112             LLDB_OPT_SET_2, false, "frame", 'F',
4113             "Locate the debug symbols the currently selected frame.", false,
4114             true)
4115
4116   {
4117     m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
4118                           LLDB_OPT_SET_1);
4119     m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
4120     m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2,
4121                           LLDB_OPT_SET_2);
4122     m_option_group.Finalize();
4123   }
4124
4125   ~CommandObjectTargetSymbolsAdd() override = default;
4126
4127   int HandleArgumentCompletion(
4128       CompletionRequest &request,
4129       OptionElementVector &opt_element_vector) override {
4130     CommandCompletions::InvokeCommonCompletionCallbacks(
4131         GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
4132         request, nullptr);
4133     return request.GetNumberOfMatches();
4134   }
4135
4136   Options *GetOptions() override { return &m_option_group; }
4137
4138 protected:
4139   bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,
4140                         CommandReturnObject &result) {
4141     const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
4142     if (symbol_fspec) {
4143       char symfile_path[PATH_MAX];
4144       symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));
4145
4146       if (!module_spec.GetUUID().IsValid()) {
4147         if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
4148           module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
4149       }
4150       // We now have a module that represents a symbol file that can be used
4151       // for a module that might exist in the current target, so we need to
4152       // find that module in the target
4153       ModuleList matching_module_list;
4154
4155       size_t num_matches = 0;
4156       // First extract all module specs from the symbol file
4157       lldb_private::ModuleSpecList symfile_module_specs;
4158       if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(),
4159                                               0, 0, symfile_module_specs)) {
4160         // Now extract the module spec that matches the target architecture
4161         ModuleSpec target_arch_module_spec;
4162         ModuleSpec symfile_module_spec;
4163         target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
4164         if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,
4165                                                         symfile_module_spec)) {
4166           // See if it has a UUID?
4167           if (symfile_module_spec.GetUUID().IsValid()) {
4168             // It has a UUID, look for this UUID in the target modules
4169             ModuleSpec symfile_uuid_module_spec;
4170             symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4171             num_matches = target->GetImages().FindModules(
4172                 symfile_uuid_module_spec, matching_module_list);
4173           }
4174         }
4175
4176         if (num_matches == 0) {
4177           // No matches yet, iterate through the module specs to find a UUID
4178           // value that we can match up to an image in our target
4179           const size_t num_symfile_module_specs =
4180               symfile_module_specs.GetSize();
4181           for (size_t i = 0; i < num_symfile_module_specs && num_matches == 0;
4182                ++i) {
4183             if (symfile_module_specs.GetModuleSpecAtIndex(
4184                     i, symfile_module_spec)) {
4185               if (symfile_module_spec.GetUUID().IsValid()) {
4186                 // It has a UUID, look for this UUID in the target modules
4187                 ModuleSpec symfile_uuid_module_spec;
4188                 symfile_uuid_module_spec.GetUUID() =
4189                     symfile_module_spec.GetUUID();
4190                 num_matches = target->GetImages().FindModules(
4191                     symfile_uuid_module_spec, matching_module_list);
4192               }
4193             }
4194           }
4195         }
4196       }
4197
4198       // Just try to match up the file by basename if we have no matches at
4199       // this point
4200       if (num_matches == 0)
4201         num_matches =
4202             target->GetImages().FindModules(module_spec, matching_module_list);
4203
4204       while (num_matches == 0) {
4205         ConstString filename_no_extension(
4206             module_spec.GetFileSpec().GetFileNameStrippingExtension());
4207         // Empty string returned, lets bail
4208         if (!filename_no_extension)
4209           break;
4210
4211         // Check if there was no extension to strip and the basename is the
4212         // same
4213         if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
4214           break;
4215
4216         // Replace basename with one less extension
4217         module_spec.GetFileSpec().GetFilename() = filename_no_extension;
4218
4219         num_matches =
4220             target->GetImages().FindModules(module_spec, matching_module_list);
4221       }
4222
4223       if (num_matches > 1) {
4224         result.AppendErrorWithFormat("multiple modules match symbol file '%s', "
4225                                      "use the --uuid option to resolve the "
4226                                      "ambiguity.\n",
4227                                      symfile_path);
4228       } else if (num_matches == 1) {
4229         ModuleSP module_sp(matching_module_list.GetModuleAtIndex(0));
4230
4231         // The module has not yet created its symbol vendor, we can just give
4232         // the existing target module the symfile path to use for when it
4233         // decides to create it!
4234         module_sp->SetSymbolFileFileSpec(symbol_fspec);
4235
4236         SymbolVendor *symbol_vendor =
4237             module_sp->GetSymbolVendor(true, &result.GetErrorStream());
4238         if (symbol_vendor) {
4239           SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
4240
4241           if (symbol_file) {
4242             ObjectFile *object_file = symbol_file->GetObjectFile();
4243
4244             if (object_file && object_file->GetFileSpec() == symbol_fspec) {
4245               // Provide feedback that the symfile has been successfully added.
4246               const FileSpec &module_fs = module_sp->GetFileSpec();
4247               result.AppendMessageWithFormat(
4248                   "symbol file '%s' has been added to '%s'\n", symfile_path,
4249                   module_fs.GetPath().c_str());
4250
4251               // Let clients know something changed in the module if it is
4252               // currently loaded
4253               ModuleList module_list;
4254               module_list.Append(module_sp);
4255               target->SymbolsDidLoad(module_list);
4256
4257               // Make sure we load any scripting resources that may be embedded
4258               // in the debug info files in case the platform supports that.
4259               Status error;
4260               StreamString feedback_stream;
4261               module_sp->LoadScriptingResourceInTarget(target, error,
4262                                                        &feedback_stream);
4263               if (error.Fail() && error.AsCString())
4264                 result.AppendWarningWithFormat(
4265                     "unable to load scripting data for module %s - error "
4266                     "reported was %s",
4267                     module_sp->GetFileSpec()
4268                         .GetFileNameStrippingExtension()
4269                         .GetCString(),
4270                     error.AsCString());
4271               else if (feedback_stream.GetSize())
4272                 result.AppendWarningWithFormat("%s", feedback_stream.GetData());
4273
4274               flush = true;
4275               result.SetStatus(eReturnStatusSuccessFinishResult);
4276               return true;
4277             }
4278           }
4279         }
4280         // Clear the symbol file spec if anything went wrong
4281         module_sp->SetSymbolFileFileSpec(FileSpec());
4282       }
4283
4284       namespace fs = llvm::sys::fs;
4285       if (module_spec.GetUUID().IsValid()) {
4286         StreamString ss_symfile_uuid;
4287         module_spec.GetUUID().Dump(&ss_symfile_uuid);
4288         result.AppendErrorWithFormat(
4289             "symbol file '%s' (%s) does not match any existing module%s\n",
4290             symfile_path, ss_symfile_uuid.GetData(),
4291             !fs::is_regular_file(symbol_fspec.GetPath())
4292                 ? "\n       please specify the full path to the symbol file"
4293                 : "");
4294       } else {
4295         result.AppendErrorWithFormat(
4296             "symbol file '%s' does not match any existing module%s\n",
4297             symfile_path,
4298             !fs::is_regular_file(symbol_fspec.GetPath())
4299                 ? "\n       please specify the full path to the symbol file"
4300                 : "");
4301       }
4302     } else {
4303       result.AppendError(
4304           "one or more executable image paths must be specified");
4305     }
4306     result.SetStatus(eReturnStatusFailed);
4307     return false;
4308   }
4309
4310   bool DoExecute(Args &args, CommandReturnObject &result) override {
4311     Target *target = m_exe_ctx.GetTargetPtr();
4312     result.SetStatus(eReturnStatusFailed);
4313     bool flush = false;
4314     ModuleSpec module_spec;
4315     const bool uuid_option_set =
4316         m_uuid_option_group.GetOptionValue().OptionWasSet();
4317     const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4318     const bool frame_option_set =
4319         m_current_frame_option.GetOptionValue().OptionWasSet();
4320     const size_t argc = args.GetArgumentCount();
4321
4322     if (argc == 0) {
4323       if (uuid_option_set || file_option_set || frame_option_set) {
4324         bool success = false;
4325         bool error_set = false;
4326         if (frame_option_set) {
4327           Process *process = m_exe_ctx.GetProcessPtr();
4328           if (process) {
4329             const StateType process_state = process->GetState();
4330             if (StateIsStoppedState(process_state, true)) {
4331               StackFrame *frame = m_exe_ctx.GetFramePtr();
4332               if (frame) {
4333                 ModuleSP frame_module_sp(
4334                     frame->GetSymbolContext(eSymbolContextModule).module_sp);
4335                 if (frame_module_sp) {
4336                   if (FileSystem::Instance().Exists(
4337                           frame_module_sp->GetPlatformFileSpec())) {
4338                     module_spec.GetArchitecture() =
4339                         frame_module_sp->GetArchitecture();
4340                     module_spec.GetFileSpec() =
4341                         frame_module_sp->GetPlatformFileSpec();
4342                   }
4343                   module_spec.GetUUID() = frame_module_sp->GetUUID();
4344                   success = module_spec.GetUUID().IsValid() ||
4345                             module_spec.GetFileSpec();
4346                 } else {
4347                   result.AppendError("frame has no module");
4348                   error_set = true;
4349                 }
4350               } else {
4351                 result.AppendError("invalid current frame");
4352                 error_set = true;
4353               }
4354             } else {
4355               result.AppendErrorWithFormat("process is not stopped: %s",
4356                                            StateAsCString(process_state));
4357               error_set = true;
4358             }
4359           } else {
4360             result.AppendError(
4361                 "a process must exist in order to use the --frame option");
4362             error_set = true;
4363           }
4364         } else {
4365           if (uuid_option_set) {
4366             module_spec.GetUUID() =
4367                 m_uuid_option_group.GetOptionValue().GetCurrentValue();
4368             success |= module_spec.GetUUID().IsValid();
4369           } else if (file_option_set) {
4370             module_spec.GetFileSpec() =
4371                 m_file_option.GetOptionValue().GetCurrentValue();
4372             ModuleSP module_sp(
4373                 target->GetImages().FindFirstModule(module_spec));
4374             if (module_sp) {
4375               module_spec.GetFileSpec() = module_sp->GetFileSpec();
4376               module_spec.GetPlatformFileSpec() =
4377                   module_sp->GetPlatformFileSpec();
4378               module_spec.GetUUID() = module_sp->GetUUID();
4379               module_spec.GetArchitecture() = module_sp->GetArchitecture();
4380             } else {
4381               module_spec.GetArchitecture() = target->GetArchitecture();
4382             }
4383             success |= module_spec.GetUUID().IsValid() ||
4384                        FileSystem::Instance().Exists(module_spec.GetFileSpec());
4385           }
4386         }
4387
4388         if (success) {
4389           if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
4390             if (module_spec.GetSymbolFileSpec())
4391               success = AddModuleSymbols(target, module_spec, flush, result);
4392           }
4393         }
4394
4395         if (!success && !error_set) {
4396           StreamString error_strm;
4397           if (uuid_option_set) {
4398             error_strm.PutCString("unable to find debug symbols for UUID ");
4399             module_spec.GetUUID().Dump(&error_strm);
4400           } else if (file_option_set) {
4401             error_strm.PutCString(
4402                 "unable to find debug symbols for the executable file ");
4403             error_strm << module_spec.GetFileSpec();
4404           } else if (frame_option_set) {
4405             error_strm.PutCString(
4406                 "unable to find debug symbols for the current frame");
4407           }
4408           result.AppendError(error_strm.GetString());
4409         }
4410       } else {
4411         result.AppendError("one or more symbol file paths must be specified, "
4412                            "or options must be specified");
4413       }
4414     } else {
4415       if (uuid_option_set) {
4416         result.AppendError("specify either one or more paths to symbol files "
4417                            "or use the --uuid option without arguments");
4418       } else if (frame_option_set) {
4419         result.AppendError("specify either one or more paths to symbol files "
4420                            "or use the --frame option without arguments");
4421       } else if (file_option_set && argc > 1) {
4422         result.AppendError("specify at most one symbol file path when "
4423                            "--shlib option is set");
4424       } else {
4425         PlatformSP platform_sp(target->GetPlatform());
4426
4427         for (auto &entry : args.entries()) {
4428           if (!entry.ref.empty()) {
4429             auto &symbol_file_spec = module_spec.GetSymbolFileSpec();
4430             symbol_file_spec.SetFile(entry.ref, FileSpec::Style::native);
4431             FileSystem::Instance().Resolve(symbol_file_spec);
4432             if (file_option_set) {
4433               module_spec.GetFileSpec() =
4434                   m_file_option.GetOptionValue().GetCurrentValue();
4435             }
4436             if (platform_sp) {
4437               FileSpec symfile_spec;
4438               if (platform_sp
4439                       ->ResolveSymbolFile(*target, module_spec, symfile_spec)
4440                       .Success())
4441                 module_spec.GetSymbolFileSpec() = symfile_spec;
4442             }
4443
4444             ArchSpec arch;
4445             bool symfile_exists =
4446                 FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec());
4447
4448             if (symfile_exists) {
4449               if (!AddModuleSymbols(target, module_spec, flush, result))
4450                 break;
4451             } else {
4452               std::string resolved_symfile_path =
4453                   module_spec.GetSymbolFileSpec().GetPath();
4454               if (resolved_symfile_path != entry.ref) {
4455                 result.AppendErrorWithFormat(
4456                     "invalid module path '%s' with resolved path '%s'\n",
4457                     entry.c_str(), resolved_symfile_path.c_str());
4458                 break;
4459               }
4460               result.AppendErrorWithFormat("invalid module path '%s'\n",
4461                                            entry.c_str());
4462               break;
4463             }
4464           }
4465         }
4466       }
4467     }
4468
4469     if (flush) {
4470       Process *process = m_exe_ctx.GetProcessPtr();
4471       if (process)
4472         process->Flush();
4473     }
4474     return result.Succeeded();
4475   }
4476
4477   OptionGroupOptions m_option_group;
4478   OptionGroupUUID m_uuid_option_group;
4479   OptionGroupFile m_file_option;
4480   OptionGroupBoolean m_current_frame_option;
4481 };
4482
4483 #pragma mark CommandObjectTargetSymbols
4484
4485 //-------------------------------------------------------------------------
4486 // CommandObjectTargetSymbols
4487 //-------------------------------------------------------------------------
4488
4489 class CommandObjectTargetSymbols : public CommandObjectMultiword {
4490 public:
4491   //------------------------------------------------------------------
4492   // Constructors and Destructors
4493   //------------------------------------------------------------------
4494   CommandObjectTargetSymbols(CommandInterpreter &interpreter)
4495       : CommandObjectMultiword(
4496             interpreter, "target symbols",
4497             "Commands for adding and managing debug symbol files.",
4498             "target symbols <sub-command> ...") {
4499     LoadSubCommand(
4500         "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));
4501   }
4502
4503   ~CommandObjectTargetSymbols() override = default;
4504
4505 private:
4506   //------------------------------------------------------------------
4507   // For CommandObjectTargetModules only
4508   //------------------------------------------------------------------
4509   DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetSymbols);
4510 };
4511
4512 #pragma mark CommandObjectTargetStopHookAdd
4513
4514 //-------------------------------------------------------------------------
4515 // CommandObjectTargetStopHookAdd
4516 //-------------------------------------------------------------------------
4517
4518 static constexpr OptionDefinition g_target_stop_hook_add_options[] = {
4519     // clang-format off
4520   { LLDB_OPT_SET_ALL, false, "one-liner",    'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOneLiner,                                         "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
4521   { LLDB_OPT_SET_ALL, false, "shlib",        's', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eModuleCompletion, eArgTypeShlibName,    "Set the module within which the stop-hook is to be run." },
4522   { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadIndex,                                      "The stop hook is run only for the thread whose index matches this argument." },
4523   { LLDB_OPT_SET_ALL, false, "thread-id",    't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadID,                                         "The stop hook is run only for the thread whose TID matches this argument." },
4524   { LLDB_OPT_SET_ALL, false, "thread-name",  'T', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadName,                                       "The stop hook is run only for the thread whose thread name matches this argument." },
4525   { LLDB_OPT_SET_ALL, false, "queue-name",   'q', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeQueueName,                                        "The stop hook is run only for threads in the queue whose name is given by this argument." },
4526   { LLDB_OPT_SET_1,   false, "file",         'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specify the source file within which the stop-hook is to be run." },
4527   { LLDB_OPT_SET_1,   false, "start-line",   'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum,                                          "Set the start of the line range for which the stop-hook is to be run." },
4528   { LLDB_OPT_SET_1,   false, "end-line",     'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum,                                          "Set the end of the line range for which the stop-hook is to be run." },
4529   { LLDB_OPT_SET_2,   false, "classname",    'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeClassName,                                        "Specify the class within which the stop-hook is to be run." },
4530   { LLDB_OPT_SET_3,   false, "name",         'n', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the function name within which the stop hook will be run." },
4531     // clang-format on
4532 };
4533
4534 class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
4535                                        public IOHandlerDelegateMultiline {
4536 public:
4537   class CommandOptions : public Options {
4538   public:
4539     CommandOptions()
4540         : Options(), m_line_start(0), m_line_end(UINT_MAX),
4541           m_func_name_type_mask(eFunctionNameTypeAuto),
4542           m_sym_ctx_specified(false), m_thread_specified(false),
4543           m_use_one_liner(false), m_one_liner() {}
4544
4545     ~CommandOptions() override = default;
4546
4547     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
4548       return llvm::makeArrayRef(g_target_stop_hook_add_options);
4549     }
4550
4551     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
4552                           ExecutionContext *execution_context) override {
4553       Status error;
4554       const int short_option = m_getopt_table[option_idx].val;
4555
4556       switch (short_option) {
4557       case 'c':
4558         m_class_name = option_arg;
4559         m_sym_ctx_specified = true;
4560         break;
4561
4562       case 'e':
4563         if (option_arg.getAsInteger(0, m_line_end)) {
4564           error.SetErrorStringWithFormat("invalid end line number: \"%s\"",
4565                                          option_arg.str().c_str());
4566           break;
4567         }
4568         m_sym_ctx_specified = true;
4569         break;
4570
4571       case 'l':
4572         if (option_arg.getAsInteger(0, m_line_start)) {
4573           error.SetErrorStringWithFormat("invalid start line number: \"%s\"",
4574                                          option_arg.str().c_str());
4575           break;
4576         }
4577         m_sym_ctx_specified = true;
4578         break;
4579
4580       case 'i':
4581         m_no_inlines = true;
4582         break;
4583
4584       case 'n':
4585         m_function_name = option_arg;
4586         m_func_name_type_mask |= eFunctionNameTypeAuto;
4587         m_sym_ctx_specified = true;
4588         break;
4589
4590       case 'f':
4591         m_file_name = option_arg;
4592         m_sym_ctx_specified = true;
4593         break;
4594
4595       case 's':
4596         m_module_name = option_arg;
4597         m_sym_ctx_specified = true;
4598         break;
4599
4600       case 't':
4601         if (option_arg.getAsInteger(0, m_thread_id))
4602           error.SetErrorStringWithFormat("invalid thread id string '%s'",
4603                                          option_arg.str().c_str());
4604         m_thread_specified = true;
4605         break;
4606
4607       case 'T':
4608         m_thread_name = option_arg;
4609         m_thread_specified = true;
4610         break;
4611
4612       case 'q':
4613         m_queue_name = option_arg;
4614         m_thread_specified = true;
4615         break;
4616
4617       case 'x':
4618         if (option_arg.getAsInteger(0, m_thread_index))
4619           error.SetErrorStringWithFormat("invalid thread index string '%s'",
4620                                          option_arg.str().c_str());
4621         m_thread_specified = true;
4622         break;
4623
4624       case 'o':
4625         m_use_one_liner = true;
4626         m_one_liner = option_arg;
4627         break;
4628
4629       default:
4630         error.SetErrorStringWithFormat("unrecognized option %c.", short_option);
4631         break;
4632       }
4633       return error;
4634     }
4635
4636     void OptionParsingStarting(ExecutionContext *execution_context) override {
4637       m_class_name.clear();
4638       m_function_name.clear();
4639       m_line_start = 0;
4640       m_line_end = UINT_MAX;
4641       m_file_name.clear();
4642       m_module_name.clear();
4643       m_func_name_type_mask = eFunctionNameTypeAuto;
4644       m_thread_id = LLDB_INVALID_THREAD_ID;
4645       m_thread_index = UINT32_MAX;
4646       m_thread_name.clear();
4647       m_queue_name.clear();
4648
4649       m_no_inlines = false;
4650       m_sym_ctx_specified = false;
4651       m_thread_specified = false;
4652
4653       m_use_one_liner = false;
4654       m_one_liner.clear();
4655     }
4656
4657     std::string m_class_name;
4658     std::string m_function_name;
4659     uint32_t m_line_start;
4660     uint32_t m_line_end;
4661     std::string m_file_name;
4662     std::string m_module_name;
4663     uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType.
4664     lldb::tid_t m_thread_id;
4665     uint32_t m_thread_index;
4666     std::string m_thread_name;
4667     std::string m_queue_name;
4668     bool m_sym_ctx_specified;
4669     bool m_no_inlines;
4670     bool m_thread_specified;
4671     // Instance variables to hold the values for one_liner options.
4672     bool m_use_one_liner;
4673     std::string m_one_liner;
4674   };
4675
4676   CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
4677       : CommandObjectParsed(interpreter, "target stop-hook add",
4678                             "Add a hook to be executed when the target stops.",
4679                             "target stop-hook add"),
4680         IOHandlerDelegateMultiline("DONE",
4681                                    IOHandlerDelegate::Completion::LLDBCommand),
4682         m_options() {}
4683
4684   ~CommandObjectTargetStopHookAdd() override = default;
4685
4686   Options *GetOptions() override { return &m_options; }
4687
4688 protected:
4689   void IOHandlerActivated(IOHandler &io_handler) override {
4690     StreamFileSP output_sp(io_handler.GetOutputStreamFile());
4691     if (output_sp) {
4692       output_sp->PutCString(
4693           "Enter your stop hook command(s).  Type 'DONE' to end.\n");
4694       output_sp->Flush();
4695     }
4696   }
4697
4698   void IOHandlerInputComplete(IOHandler &io_handler,
4699                               std::string &line) override {
4700     if (m_stop_hook_sp) {
4701       if (line.empty()) {
4702         StreamFileSP error_sp(io_handler.GetErrorStreamFile());
4703         if (error_sp) {
4704           error_sp->Printf("error: stop hook #%" PRIu64
4705                            " aborted, no commands.\n",
4706                            m_stop_hook_sp->GetID());
4707           error_sp->Flush();
4708         }
4709         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
4710         if (target)
4711           target->RemoveStopHookByID(m_stop_hook_sp->GetID());
4712       } else {
4713         m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
4714         StreamFileSP output_sp(io_handler.GetOutputStreamFile());
4715         if (output_sp) {
4716           output_sp->Printf("Stop hook #%" PRIu64 " added.\n",
4717                             m_stop_hook_sp->GetID());
4718           output_sp->Flush();
4719         }
4720       }
4721       m_stop_hook_sp.reset();
4722     }
4723     io_handler.SetIsDone(true);
4724   }
4725
4726   bool DoExecute(Args &command, CommandReturnObject &result) override {
4727     m_stop_hook_sp.reset();
4728
4729     Target *target = GetSelectedOrDummyTarget();
4730     if (target) {
4731       Target::StopHookSP new_hook_sp = target->CreateStopHook();
4732
4733       //  First step, make the specifier.
4734       std::unique_ptr<SymbolContextSpecifier> specifier_ap;
4735       if (m_options.m_sym_ctx_specified) {
4736         specifier_ap.reset(new SymbolContextSpecifier(
4737             m_interpreter.GetDebugger().GetSelectedTarget()));
4738
4739         if (!m_options.m_module_name.empty()) {
4740           specifier_ap->AddSpecification(
4741               m_options.m_module_name.c_str(),
4742               SymbolContextSpecifier::eModuleSpecified);
4743         }
4744
4745         if (!m_options.m_class_name.empty()) {
4746           specifier_ap->AddSpecification(
4747               m_options.m_class_name.c_str(),
4748               SymbolContextSpecifier::eClassOrNamespaceSpecified);
4749         }
4750
4751         if (!m_options.m_file_name.empty()) {
4752           specifier_ap->AddSpecification(
4753               m_options.m_file_name.c_str(),
4754               SymbolContextSpecifier::eFileSpecified);
4755         }
4756
4757         if (m_options.m_line_start != 0) {
4758           specifier_ap->AddLineSpecification(
4759               m_options.m_line_start,
4760               SymbolContextSpecifier::eLineStartSpecified);
4761         }
4762
4763         if (m_options.m_line_end != UINT_MAX) {
4764           specifier_ap->AddLineSpecification(
4765               m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
4766         }
4767
4768         if (!m_options.m_function_name.empty()) {
4769           specifier_ap->AddSpecification(
4770               m_options.m_function_name.c_str(),
4771               SymbolContextSpecifier::eFunctionSpecified);
4772         }
4773       }
4774
4775       if (specifier_ap)
4776         new_hook_sp->SetSpecifier(specifier_ap.release());
4777
4778       // Next see if any of the thread options have been entered:
4779
4780       if (m_options.m_thread_specified) {
4781         ThreadSpec *thread_spec = new ThreadSpec();
4782
4783         if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) {
4784           thread_spec->SetTID(m_options.m_thread_id);
4785         }
4786
4787         if (m_options.m_thread_index != UINT32_MAX)
4788           thread_spec->SetIndex(m_options.m_thread_index);
4789
4790         if (!m_options.m_thread_name.empty())
4791           thread_spec->SetName(m_options.m_thread_name.c_str());
4792
4793         if (!m_options.m_queue_name.empty())
4794           thread_spec->SetQueueName(m_options.m_queue_name.c_str());
4795
4796         new_hook_sp->SetThreadSpecifier(thread_spec);
4797       }
4798       if (m_options.m_use_one_liner) {
4799         // Use one-liner.
4800         new_hook_sp->GetCommandPointer()->AppendString(
4801             m_options.m_one_liner.c_str());
4802         result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
4803                                        new_hook_sp->GetID());
4804       } else {
4805         m_stop_hook_sp = new_hook_sp;
4806         m_interpreter.GetLLDBCommandsFromIOHandler(
4807             "> ",     // Prompt
4808             *this,    // IOHandlerDelegate
4809             true,     // Run IOHandler in async mode
4810             nullptr); // Baton for the "io_handler" that will be passed back
4811                       // into our IOHandlerDelegate functions
4812       }
4813       result.SetStatus(eReturnStatusSuccessFinishNoResult);
4814     } else {
4815       result.AppendError("invalid target\n");
4816       result.SetStatus(eReturnStatusFailed);
4817     }
4818
4819     return result.Succeeded();
4820   }
4821
4822 private:
4823   CommandOptions m_options;
4824   Target::StopHookSP m_stop_hook_sp;
4825 };
4826
4827 #pragma mark CommandObjectTargetStopHookDelete
4828
4829 //-------------------------------------------------------------------------
4830 // CommandObjectTargetStopHookDelete
4831 //-------------------------------------------------------------------------
4832
4833 class CommandObjectTargetStopHookDelete : public CommandObjectParsed {
4834 public:
4835   CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter)
4836       : CommandObjectParsed(interpreter, "target stop-hook delete",
4837                             "Delete a stop-hook.",
4838                             "target stop-hook delete [<idx>]") {}
4839
4840   ~CommandObjectTargetStopHookDelete() override = default;
4841
4842 protected:
4843   bool DoExecute(Args &command, CommandReturnObject &result) override {
4844     Target *target = GetSelectedOrDummyTarget();
4845     if (target) {
4846       // FIXME: see if we can use the breakpoint id style parser?
4847       size_t num_args = command.GetArgumentCount();
4848       if (num_args == 0) {
4849         if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
4850           result.SetStatus(eReturnStatusFailed);
4851           return false;
4852         } else {
4853           target->RemoveAllStopHooks();
4854         }
4855       } else {
4856         bool success;
4857         for (size_t i = 0; i < num_args; i++) {
4858           lldb::user_id_t user_id = StringConvert::ToUInt32(
4859               command.GetArgumentAtIndex(i), 0, 0, &success);
4860           if (!success) {
4861             result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4862                                          command.GetArgumentAtIndex(i));
4863             result.SetStatus(eReturnStatusFailed);
4864             return false;
4865           }
4866           success = target->RemoveStopHookByID(user_id);
4867           if (!success) {
4868             result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4869                                          command.GetArgumentAtIndex(i));
4870             result.SetStatus(eReturnStatusFailed);
4871             return false;
4872           }
4873         }
4874       }
4875       result.SetStatus(eReturnStatusSuccessFinishNoResult);
4876     } else {
4877       result.AppendError("invalid target\n");
4878       result.SetStatus(eReturnStatusFailed);
4879     }
4880
4881     return result.Succeeded();
4882   }
4883 };
4884
4885 #pragma mark CommandObjectTargetStopHookEnableDisable
4886
4887 //-------------------------------------------------------------------------
4888 // CommandObjectTargetStopHookEnableDisable
4889 //-------------------------------------------------------------------------
4890
4891 class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed {
4892 public:
4893   CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter,
4894                                            bool enable, const char *name,
4895                                            const char *help, const char *syntax)
4896       : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) {
4897   }
4898
4899   ~CommandObjectTargetStopHookEnableDisable() override = default;
4900
4901 protected:
4902   bool DoExecute(Args &command, CommandReturnObject &result) override {
4903     Target *target = GetSelectedOrDummyTarget();
4904     if (target) {
4905       // FIXME: see if we can use the breakpoint id style parser?
4906       size_t num_args = command.GetArgumentCount();
4907       bool success;
4908
4909       if (num_args == 0) {
4910         target->SetAllStopHooksActiveState(m_enable);
4911       } else {
4912         for (size_t i = 0; i < num_args; i++) {
4913           lldb::user_id_t user_id = StringConvert::ToUInt32(
4914               command.GetArgumentAtIndex(i), 0, 0, &success);
4915           if (!success) {
4916             result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4917                                          command.GetArgumentAtIndex(i));
4918             result.SetStatus(eReturnStatusFailed);
4919             return false;
4920           }
4921           success = target->SetStopHookActiveStateByID(user_id, m_enable);
4922           if (!success) {
4923             result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4924                                          command.GetArgumentAtIndex(i));
4925             result.SetStatus(eReturnStatusFailed);
4926             return false;
4927           }
4928         }
4929       }
4930       result.SetStatus(eReturnStatusSuccessFinishNoResult);
4931     } else {
4932       result.AppendError("invalid target\n");
4933       result.SetStatus(eReturnStatusFailed);
4934     }
4935     return result.Succeeded();
4936   }
4937
4938 private:
4939   bool m_enable;
4940 };
4941
4942 #pragma mark CommandObjectTargetStopHookList
4943
4944 //-------------------------------------------------------------------------
4945 // CommandObjectTargetStopHookList
4946 //-------------------------------------------------------------------------
4947
4948 class CommandObjectTargetStopHookList : public CommandObjectParsed {
4949 public:
4950   CommandObjectTargetStopHookList(CommandInterpreter &interpreter)
4951       : CommandObjectParsed(interpreter, "target stop-hook list",
4952                             "List all stop-hooks.",
4953                             "target stop-hook list [<type>]") {}
4954
4955   ~CommandObjectTargetStopHookList() override = default;
4956
4957 protected:
4958   bool DoExecute(Args &command, CommandReturnObject &result) override {
4959     Target *target = GetSelectedOrDummyTarget();
4960     if (!target) {
4961       result.AppendError("invalid target\n");
4962       result.SetStatus(eReturnStatusFailed);
4963       return result.Succeeded();
4964     }
4965
4966     size_t num_hooks = target->GetNumStopHooks();
4967     if (num_hooks == 0) {
4968       result.GetOutputStream().PutCString("No stop hooks.\n");
4969     } else {
4970       for (size_t i = 0; i < num_hooks; i++) {
4971         Target::StopHookSP this_hook = target->GetStopHookAtIndex(i);
4972         if (i > 0)
4973           result.GetOutputStream().PutCString("\n");
4974         this_hook->GetDescription(&(result.GetOutputStream()),
4975                                   eDescriptionLevelFull);
4976       }
4977     }
4978     result.SetStatus(eReturnStatusSuccessFinishResult);
4979     return result.Succeeded();
4980   }
4981 };
4982
4983 #pragma mark CommandObjectMultiwordTargetStopHooks
4984
4985 //-------------------------------------------------------------------------
4986 // CommandObjectMultiwordTargetStopHooks
4987 //-------------------------------------------------------------------------
4988
4989 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword {
4990 public:
4991   CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
4992       : CommandObjectMultiword(
4993             interpreter, "target stop-hook",
4994             "Commands for operating on debugger target stop-hooks.",
4995             "target stop-hook <subcommand> [<subcommand-options>]") {
4996     LoadSubCommand("add", CommandObjectSP(
4997                               new CommandObjectTargetStopHookAdd(interpreter)));
4998     LoadSubCommand(
4999         "delete",
5000         CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter)));
5001     LoadSubCommand("disable",
5002                    CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
5003                        interpreter, false, "target stop-hook disable [<id>]",
5004                        "Disable a stop-hook.", "target stop-hook disable")));
5005     LoadSubCommand("enable",
5006                    CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
5007                        interpreter, true, "target stop-hook enable [<id>]",
5008                        "Enable a stop-hook.", "target stop-hook enable")));
5009     LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList(
5010                                interpreter)));
5011   }
5012
5013   ~CommandObjectMultiwordTargetStopHooks() override = default;
5014 };
5015
5016 #pragma mark CommandObjectMultiwordTarget
5017
5018 //-------------------------------------------------------------------------
5019 // CommandObjectMultiwordTarget
5020 //-------------------------------------------------------------------------
5021
5022 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(
5023     CommandInterpreter &interpreter)
5024     : CommandObjectMultiword(interpreter, "target",
5025                              "Commands for operating on debugger targets.",
5026                              "target <subcommand> [<subcommand-options>]") {
5027   LoadSubCommand("create",
5028                  CommandObjectSP(new CommandObjectTargetCreate(interpreter)));
5029   LoadSubCommand("delete",
5030                  CommandObjectSP(new CommandObjectTargetDelete(interpreter)));
5031   LoadSubCommand("list",
5032                  CommandObjectSP(new CommandObjectTargetList(interpreter)));
5033   LoadSubCommand("select",
5034                  CommandObjectSP(new CommandObjectTargetSelect(interpreter)));
5035   LoadSubCommand(
5036       "stop-hook",
5037       CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter)));
5038   LoadSubCommand("modules",
5039                  CommandObjectSP(new CommandObjectTargetModules(interpreter)));
5040   LoadSubCommand("symbols",
5041                  CommandObjectSP(new CommandObjectTargetSymbols(interpreter)));
5042   LoadSubCommand("variable",
5043                  CommandObjectSP(new CommandObjectTargetVariable(interpreter)));
5044 }
5045
5046 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;