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