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