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