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