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