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() {}
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 = eSortOrderNone;
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() : Options(), m_format_array() {}
2906 
2907     ~CommandOptions() override = default;
2908 
2909     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2910                           ExecutionContext *execution_context) override {
2911       Status error;
2912 
2913       const int short_option = m_getopt_table[option_idx].val;
2914       if (short_option == 'g') {
2915         m_use_global_module_list = true;
2916       } else if (short_option == 'a') {
2917         m_module_addr = OptionArgParser::ToAddress(
2918             execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);
2919       } else {
2920         unsigned long width = 0;
2921         option_arg.getAsInteger(0, width);
2922         m_format_array.push_back(std::make_pair(short_option, width));
2923       }
2924       return error;
2925     }
2926 
2927     void OptionParsingStarting(ExecutionContext *execution_context) override {
2928       m_format_array.clear();
2929       m_use_global_module_list = false;
2930       m_module_addr = LLDB_INVALID_ADDRESS;
2931     }
2932 
2933     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2934       return llvm::makeArrayRef(g_target_modules_list_options);
2935     }
2936 
2937     // Instance variables to hold the values for command options.
2938     typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection;
2939     FormatWidthCollection m_format_array;
2940     bool m_use_global_module_list = false;
2941     lldb::addr_t m_module_addr = LLDB_INVALID_ADDRESS;
2942   };
2943 
2944   CommandObjectTargetModulesList(CommandInterpreter &interpreter)
2945       : CommandObjectParsed(
2946             interpreter, "target modules list",
2947             "List current executable and dependent shared library images.",
2948             "target modules list [<cmd-options>]"),
2949         m_options() {}
2950 
2951   ~CommandObjectTargetModulesList() override = default;
2952 
2953   Options *GetOptions() override { return &m_options; }
2954 
2955 protected:
2956   bool DoExecute(Args &command, CommandReturnObject &result) override {
2957     Target *target = GetDebugger().GetSelectedTarget().get();
2958     const bool use_global_module_list = m_options.m_use_global_module_list;
2959     // Define a local module list here to ensure it lives longer than any
2960     // "locker" object which might lock its contents below (through the
2961     // "module_list_ptr" variable).
2962     ModuleList module_list;
2963     if (target == nullptr && !use_global_module_list) {
2964       result.AppendError("invalid target, create a debug target using the "
2965                          "'target create' command");
2966       result.SetStatus(eReturnStatusFailed);
2967       return false;
2968     } else {
2969       if (target) {
2970         uint32_t addr_byte_size =
2971             target->GetArchitecture().GetAddressByteSize();
2972         result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2973         result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2974       }
2975       // Dump all sections for all modules images
2976       Stream &strm = result.GetOutputStream();
2977 
2978       if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) {
2979         if (target) {
2980           Address module_address;
2981           if (module_address.SetLoadAddress(m_options.m_module_addr, target)) {
2982             ModuleSP module_sp(module_address.GetModule());
2983             if (module_sp) {
2984               PrintModule(target, module_sp.get(), 0, strm);
2985               result.SetStatus(eReturnStatusSuccessFinishResult);
2986             } else {
2987               result.AppendErrorWithFormat(
2988                   "Couldn't find module matching address: 0x%" PRIx64 ".",
2989                   m_options.m_module_addr);
2990               result.SetStatus(eReturnStatusFailed);
2991             }
2992           } else {
2993             result.AppendErrorWithFormat(
2994                 "Couldn't find module containing address: 0x%" PRIx64 ".",
2995                 m_options.m_module_addr);
2996             result.SetStatus(eReturnStatusFailed);
2997           }
2998         } else {
2999           result.AppendError(
3000               "Can only look up modules by address with a valid target.");
3001           result.SetStatus(eReturnStatusFailed);
3002         }
3003         return result.Succeeded();
3004       }
3005 
3006       size_t num_modules = 0;
3007 
3008       // This locker will be locked on the mutex in module_list_ptr if it is
3009       // non-nullptr. Otherwise it will lock the
3010       // AllocationModuleCollectionMutex when accessing the global module list
3011       // directly.
3012       std::unique_lock<std::recursive_mutex> guard(
3013           Module::GetAllocationModuleCollectionMutex(), std::defer_lock);
3014 
3015       const ModuleList *module_list_ptr = nullptr;
3016       const size_t argc = command.GetArgumentCount();
3017       if (argc == 0) {
3018         if (use_global_module_list) {
3019           guard.lock();
3020           num_modules = Module::GetNumberAllocatedModules();
3021         } else {
3022           module_list_ptr = &target->GetImages();
3023         }
3024       } else {
3025         for (const Args::ArgEntry &arg : command) {
3026           // Dump specified images (by basename or fullpath)
3027           const size_t num_matches = FindModulesByName(
3028               target, arg.c_str(), module_list, use_global_module_list);
3029           if (num_matches == 0) {
3030             if (argc == 1) {
3031               result.AppendErrorWithFormat("no modules found that match '%s'",
3032                                            arg.c_str());
3033               result.SetStatus(eReturnStatusFailed);
3034               return false;
3035             }
3036           }
3037         }
3038 
3039         module_list_ptr = &module_list;
3040       }
3041 
3042       std::unique_lock<std::recursive_mutex> lock;
3043       if (module_list_ptr != nullptr) {
3044         lock =
3045             std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
3046 
3047         num_modules = module_list_ptr->GetSize();
3048       }
3049 
3050       if (num_modules > 0) {
3051         for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
3052           ModuleSP module_sp;
3053           Module *module;
3054           if (module_list_ptr) {
3055             module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
3056             module = module_sp.get();
3057           } else {
3058             module = Module::GetAllocatedModuleAtIndex(image_idx);
3059             module_sp = module->shared_from_this();
3060           }
3061 
3062           const size_t indent = strm.Printf("[%3u] ", image_idx);
3063           PrintModule(target, module, indent, strm);
3064         }
3065         result.SetStatus(eReturnStatusSuccessFinishResult);
3066       } else {
3067         if (argc) {
3068           if (use_global_module_list)
3069             result.AppendError(
3070                 "the global module list has no matching modules");
3071           else
3072             result.AppendError("the target has no matching modules");
3073         } else {
3074           if (use_global_module_list)
3075             result.AppendError("the global module list is empty");
3076           else
3077             result.AppendError(
3078                 "the target has no associated executable images");
3079         }
3080         result.SetStatus(eReturnStatusFailed);
3081         return false;
3082       }
3083     }
3084     return result.Succeeded();
3085   }
3086 
3087   void PrintModule(Target *target, Module *module, int indent, Stream &strm) {
3088     if (module == nullptr) {
3089       strm.PutCString("Null module");
3090       return;
3091     }
3092 
3093     bool dump_object_name = false;
3094     if (m_options.m_format_array.empty()) {
3095       m_options.m_format_array.push_back(std::make_pair('u', 0));
3096       m_options.m_format_array.push_back(std::make_pair('h', 0));
3097       m_options.m_format_array.push_back(std::make_pair('f', 0));
3098       m_options.m_format_array.push_back(std::make_pair('S', 0));
3099     }
3100     const size_t num_entries = m_options.m_format_array.size();
3101     bool print_space = false;
3102     for (size_t i = 0; i < num_entries; ++i) {
3103       if (print_space)
3104         strm.PutChar(' ');
3105       print_space = true;
3106       const char format_char = m_options.m_format_array[i].first;
3107       uint32_t width = m_options.m_format_array[i].second;
3108       switch (format_char) {
3109       case 'A':
3110         DumpModuleArchitecture(strm, module, false, width);
3111         break;
3112 
3113       case 't':
3114         DumpModuleArchitecture(strm, module, true, width);
3115         break;
3116 
3117       case 'f':
3118         DumpFullpath(strm, &module->GetFileSpec(), width);
3119         dump_object_name = true;
3120         break;
3121 
3122       case 'd':
3123         DumpDirectory(strm, &module->GetFileSpec(), width);
3124         break;
3125 
3126       case 'b':
3127         DumpBasename(strm, &module->GetFileSpec(), width);
3128         dump_object_name = true;
3129         break;
3130 
3131       case 'h':
3132       case 'o':
3133         // Image header address
3134         {
3135           uint32_t addr_nibble_width =
3136               target ? (target->GetArchitecture().GetAddressByteSize() * 2)
3137                      : 16;
3138 
3139           ObjectFile *objfile = module->GetObjectFile();
3140           if (objfile) {
3141             Address base_addr(objfile->GetBaseAddress());
3142             if (base_addr.IsValid()) {
3143               if (target && !target->GetSectionLoadList().IsEmpty()) {
3144                 lldb::addr_t load_addr = base_addr.GetLoadAddress(target);
3145                 if (load_addr == LLDB_INVALID_ADDRESS) {
3146                   base_addr.Dump(&strm, target,
3147                                  Address::DumpStyleModuleWithFileAddress,
3148                                  Address::DumpStyleFileAddress);
3149                 } else {
3150                   if (format_char == 'o') {
3151                     // Show the offset of slide for the image
3152                     strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3153                                 addr_nibble_width,
3154                                 load_addr - base_addr.GetFileAddress());
3155                   } else {
3156                     // Show the load address of the image
3157                     strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3158                                 addr_nibble_width, load_addr);
3159                   }
3160                 }
3161                 break;
3162               }
3163               // The address was valid, but the image isn't loaded, output the
3164               // address in an appropriate format
3165               base_addr.Dump(&strm, target, Address::DumpStyleFileAddress);
3166               break;
3167             }
3168           }
3169           strm.Printf("%*s", addr_nibble_width + 2, "");
3170         }
3171         break;
3172 
3173       case 'r': {
3174         size_t ref_count = 0;
3175         ModuleSP module_sp(module->shared_from_this());
3176         if (module_sp) {
3177           // Take one away to make sure we don't count our local "module_sp"
3178           ref_count = module_sp.use_count() - 1;
3179         }
3180         if (width)
3181           strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count);
3182         else
3183           strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count);
3184       } break;
3185 
3186       case 's':
3187       case 'S': {
3188         if (const SymbolFile *symbol_file = module->GetSymbolFile()) {
3189           const FileSpec symfile_spec =
3190               symbol_file->GetObjectFile()->GetFileSpec();
3191           if (format_char == 'S') {
3192             // Dump symbol file only if different from module file
3193             if (!symfile_spec || symfile_spec == module->GetFileSpec()) {
3194               print_space = false;
3195               break;
3196             }
3197             // Add a newline and indent past the index
3198             strm.Printf("\n%*s", indent, "");
3199           }
3200           DumpFullpath(strm, &symfile_spec, width);
3201           dump_object_name = true;
3202           break;
3203         }
3204         strm.Printf("%.*s", width, "<NONE>");
3205       } break;
3206 
3207       case 'm':
3208         strm.Format("{0:%c}", llvm::fmt_align(module->GetModificationTime(),
3209                                               llvm::AlignStyle::Left, width));
3210         break;
3211 
3212       case 'p':
3213         strm.Printf("%p", static_cast<void *>(module));
3214         break;
3215 
3216       case 'u':
3217         DumpModuleUUID(strm, module);
3218         break;
3219 
3220       default:
3221         break;
3222       }
3223     }
3224     if (dump_object_name) {
3225       const char *object_name = module->GetObjectName().GetCString();
3226       if (object_name)
3227         strm.Printf("(%s)", object_name);
3228     }
3229     strm.EOL();
3230   }
3231 
3232   CommandOptions m_options;
3233 };
3234 
3235 #pragma mark CommandObjectTargetModulesShowUnwind
3236 
3237 // Lookup unwind information in images
3238 #define LLDB_OPTIONS_target_modules_show_unwind
3239 #include "CommandOptions.inc"
3240 
3241 class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
3242 public:
3243   enum {
3244     eLookupTypeInvalid = -1,
3245     eLookupTypeAddress = 0,
3246     eLookupTypeSymbol,
3247     eLookupTypeFunction,
3248     eLookupTypeFunctionOrSymbol,
3249     kNumLookupTypes
3250   };
3251 
3252   class CommandOptions : public Options {
3253   public:
3254     CommandOptions() : Options(), m_str() {}
3255 
3256     ~CommandOptions() override = default;
3257 
3258     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3259                           ExecutionContext *execution_context) override {
3260       Status error;
3261 
3262       const int short_option = m_getopt_table[option_idx].val;
3263 
3264       switch (short_option) {
3265       case 'a': {
3266         m_str = std::string(option_arg);
3267         m_type = eLookupTypeAddress;
3268         m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
3269                                             LLDB_INVALID_ADDRESS, &error);
3270         if (m_addr == LLDB_INVALID_ADDRESS)
3271           error.SetErrorStringWithFormat("invalid address string '%s'",
3272                                          option_arg.str().c_str());
3273         break;
3274       }
3275 
3276       case 'n':
3277         m_str = std::string(option_arg);
3278         m_type = eLookupTypeFunctionOrSymbol;
3279         break;
3280 
3281       default:
3282         llvm_unreachable("Unimplemented option");
3283       }
3284 
3285       return error;
3286     }
3287 
3288     void OptionParsingStarting(ExecutionContext *execution_context) override {
3289       m_type = eLookupTypeInvalid;
3290       m_str.clear();
3291       m_addr = LLDB_INVALID_ADDRESS;
3292     }
3293 
3294     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3295       return llvm::makeArrayRef(g_target_modules_show_unwind_options);
3296     }
3297 
3298     // Instance variables to hold the values for command options.
3299 
3300     int m_type = eLookupTypeInvalid; // Should be a eLookupTypeXXX enum after
3301                                      // parsing options
3302     std::string m_str; // Holds name lookup
3303     lldb::addr_t m_addr = LLDB_INVALID_ADDRESS; // Holds the address to lookup
3304   };
3305 
3306   CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter)
3307       : CommandObjectParsed(
3308             interpreter, "target modules show-unwind",
3309             "Show synthesized unwind instructions for a function.", nullptr,
3310             eCommandRequiresTarget | eCommandRequiresProcess |
3311                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
3312         m_options() {}
3313 
3314   ~CommandObjectTargetModulesShowUnwind() override = default;
3315 
3316   Options *GetOptions() override { return &m_options; }
3317 
3318 protected:
3319   bool DoExecute(Args &command, CommandReturnObject &result) override {
3320     Target *target = m_exe_ctx.GetTargetPtr();
3321     Process *process = m_exe_ctx.GetProcessPtr();
3322     ABI *abi = nullptr;
3323     if (process)
3324       abi = process->GetABI().get();
3325 
3326     if (process == nullptr) {
3327       result.AppendError(
3328           "You must have a process running to use this command.");
3329       result.SetStatus(eReturnStatusFailed);
3330       return false;
3331     }
3332 
3333     ThreadList threads(process->GetThreadList());
3334     if (threads.GetSize() == 0) {
3335       result.AppendError("The process must be paused to use this command.");
3336       result.SetStatus(eReturnStatusFailed);
3337       return false;
3338     }
3339 
3340     ThreadSP thread(threads.GetThreadAtIndex(0));
3341     if (!thread) {
3342       result.AppendError("The process must be paused to use this command.");
3343       result.SetStatus(eReturnStatusFailed);
3344       return false;
3345     }
3346 
3347     SymbolContextList sc_list;
3348 
3349     if (m_options.m_type == eLookupTypeFunctionOrSymbol) {
3350       ConstString function_name(m_options.m_str.c_str());
3351       target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,
3352                                         true, false, sc_list);
3353     } else if (m_options.m_type == eLookupTypeAddress && target) {
3354       Address addr;
3355       if (target->GetSectionLoadList().ResolveLoadAddress(m_options.m_addr,
3356                                                           addr)) {
3357         SymbolContext sc;
3358         ModuleSP module_sp(addr.GetModule());
3359         module_sp->ResolveSymbolContextForAddress(addr,
3360                                                   eSymbolContextEverything, sc);
3361         if (sc.function || sc.symbol) {
3362           sc_list.Append(sc);
3363         }
3364       }
3365     } else {
3366       result.AppendError(
3367           "address-expression or function name option must be specified.");
3368       result.SetStatus(eReturnStatusFailed);
3369       return false;
3370     }
3371 
3372     size_t num_matches = sc_list.GetSize();
3373     if (num_matches == 0) {
3374       result.AppendErrorWithFormat("no unwind data found that matches '%s'.",
3375                                    m_options.m_str.c_str());
3376       result.SetStatus(eReturnStatusFailed);
3377       return false;
3378     }
3379 
3380     for (uint32_t idx = 0; idx < num_matches; idx++) {
3381       SymbolContext sc;
3382       sc_list.GetContextAtIndex(idx, sc);
3383       if (sc.symbol == nullptr && sc.function == nullptr)
3384         continue;
3385       if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
3386         continue;
3387       AddressRange range;
3388       if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
3389                               false, range))
3390         continue;
3391       if (!range.GetBaseAddress().IsValid())
3392         continue;
3393       ConstString funcname(sc.GetFunctionName());
3394       if (funcname.IsEmpty())
3395         continue;
3396       addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
3397       if (abi)
3398         start_addr = abi->FixCodeAddress(start_addr);
3399 
3400       FuncUnwindersSP func_unwinders_sp(
3401           sc.module_sp->GetUnwindTable()
3402               .GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
3403       if (!func_unwinders_sp)
3404         continue;
3405 
3406       result.GetOutputStream().Printf(
3407           "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n",
3408           sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(),
3409           funcname.AsCString(), start_addr);
3410 
3411       Args args;
3412       target->GetUserSpecifiedTrapHandlerNames(args);
3413       size_t count = args.GetArgumentCount();
3414       for (size_t i = 0; i < count; i++) {
3415         const char *trap_func_name = args.GetArgumentAtIndex(i);
3416         if (strcmp(funcname.GetCString(), trap_func_name) == 0)
3417           result.GetOutputStream().Printf(
3418               "This function is "
3419               "treated as a trap handler function via user setting.\n");
3420       }
3421       PlatformSP platform_sp(target->GetPlatform());
3422       if (platform_sp) {
3423         const std::vector<ConstString> trap_handler_names(
3424             platform_sp->GetTrapHandlerSymbolNames());
3425         for (ConstString trap_name : trap_handler_names) {
3426           if (trap_name == funcname) {
3427             result.GetOutputStream().Printf(
3428                 "This function's "
3429                 "name is listed by the platform as a trap handler.\n");
3430           }
3431         }
3432       }
3433 
3434       result.GetOutputStream().Printf("\n");
3435 
3436       UnwindPlanSP non_callsite_unwind_plan =
3437           func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread);
3438       if (non_callsite_unwind_plan) {
3439         result.GetOutputStream().Printf(
3440             "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
3441             non_callsite_unwind_plan->GetSourceName().AsCString());
3442       }
3443       UnwindPlanSP callsite_unwind_plan =
3444           func_unwinders_sp->GetUnwindPlanAtCallSite(*target, *thread);
3445       if (callsite_unwind_plan) {
3446         result.GetOutputStream().Printf(
3447             "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
3448             callsite_unwind_plan->GetSourceName().AsCString());
3449       }
3450       UnwindPlanSP fast_unwind_plan =
3451           func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
3452       if (fast_unwind_plan) {
3453         result.GetOutputStream().Printf(
3454             "Fast UnwindPlan is '%s'\n",
3455             fast_unwind_plan->GetSourceName().AsCString());
3456       }
3457 
3458       result.GetOutputStream().Printf("\n");
3459 
3460       UnwindPlanSP assembly_sp =
3461           func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread);
3462       if (assembly_sp) {
3463         result.GetOutputStream().Printf(
3464             "Assembly language inspection UnwindPlan:\n");
3465         assembly_sp->Dump(result.GetOutputStream(), thread.get(),
3466                           LLDB_INVALID_ADDRESS);
3467         result.GetOutputStream().Printf("\n");
3468       }
3469 
3470       UnwindPlanSP of_unwind_sp =
3471           func_unwinders_sp->GetObjectFileUnwindPlan(*target);
3472       if (of_unwind_sp) {
3473         result.GetOutputStream().Printf("object file UnwindPlan:\n");
3474         of_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3475                            LLDB_INVALID_ADDRESS);
3476         result.GetOutputStream().Printf("\n");
3477       }
3478 
3479       UnwindPlanSP of_unwind_augmented_sp =
3480           func_unwinders_sp->GetObjectFileAugmentedUnwindPlan(*target, *thread);
3481       if (of_unwind_augmented_sp) {
3482         result.GetOutputStream().Printf("object file augmented UnwindPlan:\n");
3483         of_unwind_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
3484                                      LLDB_INVALID_ADDRESS);
3485         result.GetOutputStream().Printf("\n");
3486       }
3487 
3488       UnwindPlanSP ehframe_sp =
3489           func_unwinders_sp->GetEHFrameUnwindPlan(*target);
3490       if (ehframe_sp) {
3491         result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3492         ehframe_sp->Dump(result.GetOutputStream(), thread.get(),
3493                          LLDB_INVALID_ADDRESS);
3494         result.GetOutputStream().Printf("\n");
3495       }
3496 
3497       UnwindPlanSP ehframe_augmented_sp =
3498           func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread);
3499       if (ehframe_augmented_sp) {
3500         result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3501         ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
3502                                    LLDB_INVALID_ADDRESS);
3503         result.GetOutputStream().Printf("\n");
3504       }
3505 
3506       if (UnwindPlanSP plan_sp =
3507               func_unwinders_sp->GetDebugFrameUnwindPlan(*target)) {
3508         result.GetOutputStream().Printf("debug_frame UnwindPlan:\n");
3509         plan_sp->Dump(result.GetOutputStream(), thread.get(),
3510                       LLDB_INVALID_ADDRESS);
3511         result.GetOutputStream().Printf("\n");
3512       }
3513 
3514       if (UnwindPlanSP plan_sp =
3515               func_unwinders_sp->GetDebugFrameAugmentedUnwindPlan(*target,
3516                                                                   *thread)) {
3517         result.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n");
3518         plan_sp->Dump(result.GetOutputStream(), thread.get(),
3519                       LLDB_INVALID_ADDRESS);
3520         result.GetOutputStream().Printf("\n");
3521       }
3522 
3523       UnwindPlanSP arm_unwind_sp =
3524           func_unwinders_sp->GetArmUnwindUnwindPlan(*target);
3525       if (arm_unwind_sp) {
3526         result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
3527         arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3528                             LLDB_INVALID_ADDRESS);
3529         result.GetOutputStream().Printf("\n");
3530       }
3531 
3532       if (UnwindPlanSP symfile_plan_sp =
3533               func_unwinders_sp->GetSymbolFileUnwindPlan(*thread)) {
3534         result.GetOutputStream().Printf("Symbol file UnwindPlan:\n");
3535         symfile_plan_sp->Dump(result.GetOutputStream(), thread.get(),
3536                               LLDB_INVALID_ADDRESS);
3537         result.GetOutputStream().Printf("\n");
3538       }
3539 
3540       UnwindPlanSP compact_unwind_sp =
3541           func_unwinders_sp->GetCompactUnwindUnwindPlan(*target);
3542       if (compact_unwind_sp) {
3543         result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3544         compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3545                                 LLDB_INVALID_ADDRESS);
3546         result.GetOutputStream().Printf("\n");
3547       }
3548 
3549       if (fast_unwind_plan) {
3550         result.GetOutputStream().Printf("Fast UnwindPlan:\n");
3551         fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(),
3552                                LLDB_INVALID_ADDRESS);
3553         result.GetOutputStream().Printf("\n");
3554       }
3555 
3556       ABISP abi_sp = process->GetABI();
3557       if (abi_sp) {
3558         UnwindPlan arch_default(lldb::eRegisterKindGeneric);
3559         if (abi_sp->CreateDefaultUnwindPlan(arch_default)) {
3560           result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3561           arch_default.Dump(result.GetOutputStream(), thread.get(),
3562                             LLDB_INVALID_ADDRESS);
3563           result.GetOutputStream().Printf("\n");
3564         }
3565 
3566         UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
3567         if (abi_sp->CreateFunctionEntryUnwindPlan(arch_entry)) {
3568           result.GetOutputStream().Printf(
3569               "Arch default at entry point UnwindPlan:\n");
3570           arch_entry.Dump(result.GetOutputStream(), thread.get(),
3571                           LLDB_INVALID_ADDRESS);
3572           result.GetOutputStream().Printf("\n");
3573         }
3574       }
3575 
3576       result.GetOutputStream().Printf("\n");
3577     }
3578     return result.Succeeded();
3579   }
3580 
3581   CommandOptions m_options;
3582 };
3583 
3584 // Lookup information in images
3585 #define LLDB_OPTIONS_target_modules_lookup
3586 #include "CommandOptions.inc"
3587 
3588 class CommandObjectTargetModulesLookup : public CommandObjectParsed {
3589 public:
3590   enum {
3591     eLookupTypeInvalid = -1,
3592     eLookupTypeAddress = 0,
3593     eLookupTypeSymbol,
3594     eLookupTypeFileLine, // Line is optional
3595     eLookupTypeFunction,
3596     eLookupTypeFunctionOrSymbol,
3597     eLookupTypeType,
3598     kNumLookupTypes
3599   };
3600 
3601   class CommandOptions : public Options {
3602   public:
3603     CommandOptions() : Options() { OptionParsingStarting(nullptr); }
3604 
3605     ~CommandOptions() override = default;
3606 
3607     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3608                           ExecutionContext *execution_context) override {
3609       Status error;
3610 
3611       const int short_option = m_getopt_table[option_idx].val;
3612 
3613       switch (short_option) {
3614       case 'a': {
3615         m_type = eLookupTypeAddress;
3616         m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
3617                                             LLDB_INVALID_ADDRESS, &error);
3618       } break;
3619 
3620       case 'o':
3621         if (option_arg.getAsInteger(0, m_offset))
3622           error.SetErrorStringWithFormat("invalid offset string '%s'",
3623                                          option_arg.str().c_str());
3624         break;
3625 
3626       case 's':
3627         m_str = std::string(option_arg);
3628         m_type = eLookupTypeSymbol;
3629         break;
3630 
3631       case 'f':
3632         m_file.SetFile(option_arg, FileSpec::Style::native);
3633         m_type = eLookupTypeFileLine;
3634         break;
3635 
3636       case 'i':
3637         m_include_inlines = false;
3638         break;
3639 
3640       case 'l':
3641         if (option_arg.getAsInteger(0, m_line_number))
3642           error.SetErrorStringWithFormat("invalid line number string '%s'",
3643                                          option_arg.str().c_str());
3644         else if (m_line_number == 0)
3645           error.SetErrorString("zero is an invalid line number");
3646         m_type = eLookupTypeFileLine;
3647         break;
3648 
3649       case 'F':
3650         m_str = std::string(option_arg);
3651         m_type = eLookupTypeFunction;
3652         break;
3653 
3654       case 'n':
3655         m_str = std::string(option_arg);
3656         m_type = eLookupTypeFunctionOrSymbol;
3657         break;
3658 
3659       case 't':
3660         m_str = std::string(option_arg);
3661         m_type = eLookupTypeType;
3662         break;
3663 
3664       case 'v':
3665         m_verbose = true;
3666         break;
3667 
3668       case 'A':
3669         m_print_all = true;
3670         break;
3671 
3672       case 'r':
3673         m_use_regex = true;
3674         break;
3675       default:
3676         llvm_unreachable("Unimplemented option");
3677       }
3678 
3679       return error;
3680     }
3681 
3682     void OptionParsingStarting(ExecutionContext *execution_context) override {
3683       m_type = eLookupTypeInvalid;
3684       m_str.clear();
3685       m_file.Clear();
3686       m_addr = LLDB_INVALID_ADDRESS;
3687       m_offset = 0;
3688       m_line_number = 0;
3689       m_use_regex = false;
3690       m_include_inlines = true;
3691       m_verbose = false;
3692       m_print_all = false;
3693     }
3694 
3695     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3696       return llvm::makeArrayRef(g_target_modules_lookup_options);
3697     }
3698 
3699     int m_type;        // Should be a eLookupTypeXXX enum after parsing options
3700     std::string m_str; // Holds name lookup
3701     FileSpec m_file;   // Files for file lookups
3702     lldb::addr_t m_addr; // Holds the address to lookup
3703     lldb::addr_t
3704         m_offset; // Subtract this offset from m_addr before doing lookups.
3705     uint32_t m_line_number; // Line number for file+line lookups
3706     bool m_use_regex;       // Name lookups in m_str are regular expressions.
3707     bool m_include_inlines; // Check for inline entries when looking up by
3708                             // file/line.
3709     bool m_verbose;         // Enable verbose lookup info
3710     bool m_print_all; // Print all matches, even in cases where there's a best
3711                       // match.
3712   };
3713 
3714   CommandObjectTargetModulesLookup(CommandInterpreter &interpreter)
3715       : CommandObjectParsed(interpreter, "target modules lookup",
3716                             "Look up information within executable and "
3717                             "dependent shared library images.",
3718                             nullptr, eCommandRequiresTarget),
3719         m_options() {
3720     CommandArgumentEntry arg;
3721     CommandArgumentData file_arg;
3722 
3723     // Define the first (and only) variant of this arg.
3724     file_arg.arg_type = eArgTypeFilename;
3725     file_arg.arg_repetition = eArgRepeatStar;
3726 
3727     // There is only one variant this argument could be; put it into the
3728     // argument entry.
3729     arg.push_back(file_arg);
3730 
3731     // Push the data for the first argument into the m_arguments vector.
3732     m_arguments.push_back(arg);
3733   }
3734 
3735   ~CommandObjectTargetModulesLookup() override = default;
3736 
3737   Options *GetOptions() override { return &m_options; }
3738 
3739   bool LookupHere(CommandInterpreter &interpreter, CommandReturnObject &result,
3740                   bool &syntax_error) {
3741     switch (m_options.m_type) {
3742     case eLookupTypeAddress:
3743     case eLookupTypeFileLine:
3744     case eLookupTypeFunction:
3745     case eLookupTypeFunctionOrSymbol:
3746     case eLookupTypeSymbol:
3747     default:
3748       return false;
3749     case eLookupTypeType:
3750       break;
3751     }
3752 
3753     StackFrameSP frame = m_exe_ctx.GetFrameSP();
3754 
3755     if (!frame)
3756       return false;
3757 
3758     const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
3759 
3760     if (!sym_ctx.module_sp)
3761       return false;
3762 
3763     switch (m_options.m_type) {
3764     default:
3765       return false;
3766     case eLookupTypeType:
3767       if (!m_options.m_str.empty()) {
3768         if (LookupTypeHere(&GetSelectedTarget(), m_interpreter,
3769                            result.GetOutputStream(), *sym_ctx.module_sp,
3770                            m_options.m_str.c_str(), m_options.m_use_regex)) {
3771           result.SetStatus(eReturnStatusSuccessFinishResult);
3772           return true;
3773         }
3774       }
3775       break;
3776     }
3777 
3778     return false;
3779   }
3780 
3781   bool LookupInModule(CommandInterpreter &interpreter, Module *module,
3782                       CommandReturnObject &result, bool &syntax_error) {
3783     switch (m_options.m_type) {
3784     case eLookupTypeAddress:
3785       if (m_options.m_addr != LLDB_INVALID_ADDRESS) {
3786         if (LookupAddressInModule(
3787                 m_interpreter, result.GetOutputStream(), module,
3788                 eSymbolContextEverything |
3789                     (m_options.m_verbose
3790                          ? static_cast<int>(eSymbolContextVariable)
3791                          : 0),
3792                 m_options.m_addr, m_options.m_offset, m_options.m_verbose)) {
3793           result.SetStatus(eReturnStatusSuccessFinishResult);
3794           return true;
3795         }
3796       }
3797       break;
3798 
3799     case eLookupTypeSymbol:
3800       if (!m_options.m_str.empty()) {
3801         if (LookupSymbolInModule(m_interpreter, result.GetOutputStream(),
3802                                  module, m_options.m_str.c_str(),
3803                                  m_options.m_use_regex, m_options.m_verbose)) {
3804           result.SetStatus(eReturnStatusSuccessFinishResult);
3805           return true;
3806         }
3807       }
3808       break;
3809 
3810     case eLookupTypeFileLine:
3811       if (m_options.m_file) {
3812         if (LookupFileAndLineInModule(
3813                 m_interpreter, result.GetOutputStream(), module,
3814                 m_options.m_file, m_options.m_line_number,
3815                 m_options.m_include_inlines, m_options.m_verbose)) {
3816           result.SetStatus(eReturnStatusSuccessFinishResult);
3817           return true;
3818         }
3819       }
3820       break;
3821 
3822     case eLookupTypeFunctionOrSymbol:
3823     case eLookupTypeFunction:
3824       if (!m_options.m_str.empty()) {
3825         if (LookupFunctionInModule(
3826                 m_interpreter, result.GetOutputStream(), module,
3827                 m_options.m_str.c_str(), m_options.m_use_regex,
3828                 m_options.m_include_inlines,
3829                 m_options.m_type ==
3830                     eLookupTypeFunctionOrSymbol, // include symbols
3831                 m_options.m_verbose)) {
3832           result.SetStatus(eReturnStatusSuccessFinishResult);
3833           return true;
3834         }
3835       }
3836       break;
3837 
3838     case eLookupTypeType:
3839       if (!m_options.m_str.empty()) {
3840         if (LookupTypeInModule(
3841                 &GetSelectedTarget(), m_interpreter, result.GetOutputStream(),
3842                 module, m_options.m_str.c_str(), m_options.m_use_regex)) {
3843           result.SetStatus(eReturnStatusSuccessFinishResult);
3844           return true;
3845         }
3846       }
3847       break;
3848 
3849     default:
3850       m_options.GenerateOptionUsage(
3851           result.GetErrorStream(), this,
3852           GetCommandInterpreter().GetDebugger().GetTerminalWidth());
3853       syntax_error = true;
3854       break;
3855     }
3856 
3857     result.SetStatus(eReturnStatusFailed);
3858     return false;
3859   }
3860 
3861 protected:
3862   bool DoExecute(Args &command, CommandReturnObject &result) override {
3863     Target *target = &GetSelectedTarget();
3864     bool syntax_error = false;
3865     uint32_t i;
3866     uint32_t num_successful_lookups = 0;
3867     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3868     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3869     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3870     // Dump all sections for all modules images
3871 
3872     if (command.GetArgumentCount() == 0) {
3873       ModuleSP current_module;
3874 
3875       // Where it is possible to look in the current symbol context first,
3876       // try that.  If this search was successful and --all was not passed,
3877       // don't print anything else.
3878       if (LookupHere(m_interpreter, result, syntax_error)) {
3879         result.GetOutputStream().EOL();
3880         num_successful_lookups++;
3881         if (!m_options.m_print_all) {
3882           result.SetStatus(eReturnStatusSuccessFinishResult);
3883           return result.Succeeded();
3884         }
3885       }
3886 
3887       // Dump all sections for all other modules
3888 
3889       const ModuleList &target_modules = target->GetImages();
3890       std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
3891       if (target_modules.GetSize() == 0) {
3892         result.AppendError("the target has no associated executable images");
3893         result.SetStatus(eReturnStatusFailed);
3894         return false;
3895       }
3896 
3897       for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
3898         if (module_sp != current_module &&
3899             LookupInModule(m_interpreter, module_sp.get(), result,
3900                            syntax_error)) {
3901           result.GetOutputStream().EOL();
3902           num_successful_lookups++;
3903         }
3904       }
3905     } else {
3906       // Dump specified images (by basename or fullpath)
3907       const char *arg_cstr;
3908       for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
3909                   !syntax_error;
3910            ++i) {
3911         ModuleList module_list;
3912         const size_t num_matches =
3913             FindModulesByName(target, arg_cstr, module_list, false);
3914         if (num_matches > 0) {
3915           for (size_t j = 0; j < num_matches; ++j) {
3916             Module *module = module_list.GetModulePointerAtIndex(j);
3917             if (module) {
3918               if (LookupInModule(m_interpreter, module, result, syntax_error)) {
3919                 result.GetOutputStream().EOL();
3920                 num_successful_lookups++;
3921               }
3922             }
3923           }
3924         } else
3925           result.AppendWarningWithFormat(
3926               "Unable to find an image that matches '%s'.\n", arg_cstr);
3927       }
3928     }
3929 
3930     if (num_successful_lookups > 0)
3931       result.SetStatus(eReturnStatusSuccessFinishResult);
3932     else
3933       result.SetStatus(eReturnStatusFailed);
3934     return result.Succeeded();
3935   }
3936 
3937   CommandOptions m_options;
3938 };
3939 
3940 #pragma mark CommandObjectMultiwordImageSearchPaths
3941 
3942 // CommandObjectMultiwordImageSearchPaths
3943 
3944 class CommandObjectTargetModulesImageSearchPaths
3945     : public CommandObjectMultiword {
3946 public:
3947   CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
3948       : CommandObjectMultiword(
3949             interpreter, "target modules search-paths",
3950             "Commands for managing module search paths for a target.",
3951             "target modules search-paths <subcommand> [<subcommand-options>]") {
3952     LoadSubCommand(
3953         "add", CommandObjectSP(
3954                    new CommandObjectTargetModulesSearchPathsAdd(interpreter)));
3955     LoadSubCommand(
3956         "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear(
3957                      interpreter)));
3958     LoadSubCommand(
3959         "insert",
3960         CommandObjectSP(
3961             new CommandObjectTargetModulesSearchPathsInsert(interpreter)));
3962     LoadSubCommand(
3963         "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList(
3964                     interpreter)));
3965     LoadSubCommand(
3966         "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery(
3967                      interpreter)));
3968   }
3969 
3970   ~CommandObjectTargetModulesImageSearchPaths() override = default;
3971 };
3972 
3973 #pragma mark CommandObjectTargetModules
3974 
3975 // CommandObjectTargetModules
3976 
3977 class CommandObjectTargetModules : public CommandObjectMultiword {
3978 public:
3979   // Constructors and Destructors
3980   CommandObjectTargetModules(CommandInterpreter &interpreter)
3981       : CommandObjectMultiword(interpreter, "target modules",
3982                                "Commands for accessing information for one or "
3983                                "more target modules.",
3984                                "target modules <sub-command> ...") {
3985     LoadSubCommand(
3986         "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter)));
3987     LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad(
3988                                interpreter)));
3989     LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump(
3990                                interpreter)));
3991     LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList(
3992                                interpreter)));
3993     LoadSubCommand(
3994         "lookup",
3995         CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter)));
3996     LoadSubCommand(
3997         "search-paths",
3998         CommandObjectSP(
3999             new CommandObjectTargetModulesImageSearchPaths(interpreter)));
4000     LoadSubCommand(
4001         "show-unwind",
4002         CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter)));
4003   }
4004 
4005   ~CommandObjectTargetModules() override = default;
4006 
4007 private:
4008   // For CommandObjectTargetModules only
4009   CommandObjectTargetModules(const CommandObjectTargetModules &) = delete;
4010   const CommandObjectTargetModules &
4011   operator=(const CommandObjectTargetModules &) = delete;
4012 };
4013 
4014 class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
4015 public:
4016   CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter)
4017       : CommandObjectParsed(
4018             interpreter, "target symbols add",
4019             "Add a debug symbol file to one of the target's current modules by "
4020             "specifying a path to a debug symbols file or by using the options "
4021             "to specify a module.",
4022             "target symbols add <cmd-options> [<symfile>]",
4023             eCommandRequiresTarget),
4024         m_option_group(),
4025         m_file_option(
4026             LLDB_OPT_SET_1, false, "shlib", 's',
4027             CommandCompletions::eModuleCompletion, eArgTypeShlibName,
4028             "Locate the debug symbols for the shared library specified by "
4029             "name."),
4030         m_current_frame_option(
4031             LLDB_OPT_SET_2, false, "frame", 'F',
4032             "Locate the debug symbols for the currently selected frame.",
4033             false, true)
4034 
4035   {
4036     m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
4037                           LLDB_OPT_SET_1);
4038     m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
4039     m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2,
4040                           LLDB_OPT_SET_2);
4041     m_option_group.Finalize();
4042   }
4043 
4044   ~CommandObjectTargetSymbolsAdd() override = default;
4045 
4046   void
4047   HandleArgumentCompletion(CompletionRequest &request,
4048                            OptionElementVector &opt_element_vector) override {
4049     CommandCompletions::InvokeCommonCompletionCallbacks(
4050         GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
4051         request, nullptr);
4052   }
4053 
4054   Options *GetOptions() override { return &m_option_group; }
4055 
4056 protected:
4057   bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,
4058                         CommandReturnObject &result) {
4059     const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
4060     if (!symbol_fspec) {
4061       result.AppendError(
4062           "one or more executable image paths must be specified");
4063       result.SetStatus(eReturnStatusFailed);
4064       return false;
4065     }
4066 
4067     char symfile_path[PATH_MAX];
4068     symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));
4069 
4070     if (!module_spec.GetUUID().IsValid()) {
4071       if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
4072         module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
4073     }
4074 
4075     // Now module_spec represents a symbol file for a module that might exist
4076     // in the current target.  Let's find possible matches.
4077     ModuleList matching_modules;
4078 
4079     // First extract all module specs from the symbol file
4080     lldb_private::ModuleSpecList symfile_module_specs;
4081     if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(),
4082                                             0, 0, symfile_module_specs)) {
4083       // Now extract the module spec that matches the target architecture
4084       ModuleSpec target_arch_module_spec;
4085       ModuleSpec symfile_module_spec;
4086       target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
4087       if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,
4088                                                       symfile_module_spec)) {
4089         if (symfile_module_spec.GetUUID().IsValid()) {
4090           // It has a UUID, look for this UUID in the target modules
4091           ModuleSpec symfile_uuid_module_spec;
4092           symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4093           target->GetImages().FindModules(symfile_uuid_module_spec,
4094                                           matching_modules);
4095         }
4096       }
4097 
4098       if (matching_modules.IsEmpty()) {
4099         // No matches yet.  Iterate through the module specs to find a UUID
4100         // value that we can match up to an image in our target.
4101         const size_t num_symfile_module_specs = symfile_module_specs.GetSize();
4102         for (size_t i = 0;
4103              i < num_symfile_module_specs && matching_modules.IsEmpty(); ++i) {
4104           if (symfile_module_specs.GetModuleSpecAtIndex(
4105                   i, symfile_module_spec)) {
4106             if (symfile_module_spec.GetUUID().IsValid()) {
4107               // It has a UUID.  Look for this UUID in the target modules.
4108               ModuleSpec symfile_uuid_module_spec;
4109               symfile_uuid_module_spec.GetUUID() =
4110                   symfile_module_spec.GetUUID();
4111               target->GetImages().FindModules(symfile_uuid_module_spec,
4112                                               matching_modules);
4113             }
4114           }
4115         }
4116       }
4117     }
4118 
4119     // Just try to match up the file by basename if we have no matches at
4120     // this point.  For example, module foo might have symbols in foo.debug.
4121     if (matching_modules.IsEmpty())
4122       target->GetImages().FindModules(module_spec, matching_modules);
4123 
4124     while (matching_modules.IsEmpty()) {
4125       ConstString filename_no_extension(
4126           module_spec.GetFileSpec().GetFileNameStrippingExtension());
4127       // Empty string returned, let's bail
4128       if (!filename_no_extension)
4129         break;
4130 
4131       // Check if there was no extension to strip and the basename is the same
4132       if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
4133         break;
4134 
4135       // Replace basename with one fewer extension
4136       module_spec.GetFileSpec().GetFilename() = filename_no_extension;
4137       target->GetImages().FindModules(module_spec, matching_modules);
4138     }
4139 
4140     if (matching_modules.GetSize() > 1) {
4141       result.AppendErrorWithFormat("multiple modules match symbol file '%s', "
4142                                    "use the --uuid option to resolve the "
4143                                    "ambiguity.\n",
4144                                    symfile_path);
4145       result.SetStatus(eReturnStatusFailed);
4146       return false;
4147     }
4148 
4149     if (matching_modules.GetSize() == 1) {
4150       ModuleSP module_sp(matching_modules.GetModuleAtIndex(0));
4151 
4152       // The module has not yet created its symbol vendor, we can just give
4153       // the existing target module the symfile path to use for when it
4154       // decides to create it!
4155       module_sp->SetSymbolFileFileSpec(symbol_fspec);
4156 
4157       SymbolFile *symbol_file =
4158           module_sp->GetSymbolFile(true, &result.GetErrorStream());
4159       if (symbol_file) {
4160         ObjectFile *object_file = symbol_file->GetObjectFile();
4161         if (object_file && object_file->GetFileSpec() == symbol_fspec) {
4162           // Provide feedback that the symfile has been successfully added.
4163           const FileSpec &module_fs = module_sp->GetFileSpec();
4164           result.AppendMessageWithFormat(
4165               "symbol file '%s' has been added to '%s'\n", symfile_path,
4166               module_fs.GetPath().c_str());
4167 
4168           // Let clients know something changed in the module if it is
4169           // currently loaded
4170           ModuleList module_list;
4171           module_list.Append(module_sp);
4172           target->SymbolsDidLoad(module_list);
4173 
4174           // Make sure we load any scripting resources that may be embedded
4175           // in the debug info files in case the platform supports that.
4176           Status error;
4177           StreamString feedback_stream;
4178           module_sp->LoadScriptingResourceInTarget(target, error,
4179                                                    &feedback_stream);
4180           if (error.Fail() && error.AsCString())
4181             result.AppendWarningWithFormat(
4182                 "unable to load scripting data for module %s - error "
4183                 "reported was %s",
4184                 module_sp->GetFileSpec()
4185                     .GetFileNameStrippingExtension()
4186                     .GetCString(),
4187                 error.AsCString());
4188           else if (feedback_stream.GetSize())
4189             result.AppendWarning(feedback_stream.GetData());
4190 
4191           flush = true;
4192           result.SetStatus(eReturnStatusSuccessFinishResult);
4193           return true;
4194         }
4195       }
4196       // Clear the symbol file spec if anything went wrong
4197       module_sp->SetSymbolFileFileSpec(FileSpec());
4198     }
4199 
4200     StreamString ss_symfile_uuid;
4201     if (module_spec.GetUUID().IsValid()) {
4202       ss_symfile_uuid << " (";
4203       module_spec.GetUUID().Dump(&ss_symfile_uuid);
4204       ss_symfile_uuid << ')';
4205     }
4206     result.AppendErrorWithFormat(
4207         "symbol file '%s'%s does not match any existing module%s\n",
4208         symfile_path, ss_symfile_uuid.GetData(),
4209         !llvm::sys::fs::is_regular_file(symbol_fspec.GetPath())
4210             ? "\n       please specify the full path to the symbol file"
4211             : "");
4212     result.SetStatus(eReturnStatusFailed);
4213     return false;
4214   }
4215 
4216   bool DoExecute(Args &args, CommandReturnObject &result) override {
4217     Target *target = m_exe_ctx.GetTargetPtr();
4218     result.SetStatus(eReturnStatusFailed);
4219     bool flush = false;
4220     ModuleSpec module_spec;
4221     const bool uuid_option_set =
4222         m_uuid_option_group.GetOptionValue().OptionWasSet();
4223     const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4224     const bool frame_option_set =
4225         m_current_frame_option.GetOptionValue().OptionWasSet();
4226     const size_t argc = args.GetArgumentCount();
4227 
4228     if (argc == 0) {
4229       if (uuid_option_set || file_option_set || frame_option_set) {
4230         bool success = false;
4231         bool error_set = false;
4232         if (frame_option_set) {
4233           Process *process = m_exe_ctx.GetProcessPtr();
4234           if (process) {
4235             const StateType process_state = process->GetState();
4236             if (StateIsStoppedState(process_state, true)) {
4237               StackFrame *frame = m_exe_ctx.GetFramePtr();
4238               if (frame) {
4239                 ModuleSP frame_module_sp(
4240                     frame->GetSymbolContext(eSymbolContextModule).module_sp);
4241                 if (frame_module_sp) {
4242                   if (FileSystem::Instance().Exists(
4243                           frame_module_sp->GetPlatformFileSpec())) {
4244                     module_spec.GetArchitecture() =
4245                         frame_module_sp->GetArchitecture();
4246                     module_spec.GetFileSpec() =
4247                         frame_module_sp->GetPlatformFileSpec();
4248                   }
4249                   module_spec.GetUUID() = frame_module_sp->GetUUID();
4250                   success = module_spec.GetUUID().IsValid() ||
4251                             module_spec.GetFileSpec();
4252                 } else {
4253                   result.AppendError("frame has no module");
4254                   error_set = true;
4255                 }
4256               } else {
4257                 result.AppendError("invalid current frame");
4258                 error_set = true;
4259               }
4260             } else {
4261               result.AppendErrorWithFormat("process is not stopped: %s",
4262                                            StateAsCString(process_state));
4263               error_set = true;
4264             }
4265           } else {
4266             result.AppendError(
4267                 "a process must exist in order to use the --frame option");
4268             error_set = true;
4269           }
4270         } else {
4271           if (uuid_option_set) {
4272             module_spec.GetUUID() =
4273                 m_uuid_option_group.GetOptionValue().GetCurrentValue();
4274             success |= module_spec.GetUUID().IsValid();
4275           } else if (file_option_set) {
4276             module_spec.GetFileSpec() =
4277                 m_file_option.GetOptionValue().GetCurrentValue();
4278             ModuleSP module_sp(
4279                 target->GetImages().FindFirstModule(module_spec));
4280             if (module_sp) {
4281               module_spec.GetFileSpec() = module_sp->GetFileSpec();
4282               module_spec.GetPlatformFileSpec() =
4283                   module_sp->GetPlatformFileSpec();
4284               module_spec.GetUUID() = module_sp->GetUUID();
4285               module_spec.GetArchitecture() = module_sp->GetArchitecture();
4286             } else {
4287               module_spec.GetArchitecture() = target->GetArchitecture();
4288             }
4289             success |= module_spec.GetUUID().IsValid() ||
4290                        FileSystem::Instance().Exists(module_spec.GetFileSpec());
4291           }
4292         }
4293 
4294         if (success) {
4295           if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
4296             if (module_spec.GetSymbolFileSpec())
4297               success = AddModuleSymbols(target, module_spec, flush, result);
4298           }
4299         }
4300 
4301         if (!success && !error_set) {
4302           StreamString error_strm;
4303           if (uuid_option_set) {
4304             error_strm.PutCString("unable to find debug symbols for UUID ");
4305             module_spec.GetUUID().Dump(&error_strm);
4306           } else if (file_option_set) {
4307             error_strm.PutCString(
4308                 "unable to find debug symbols for the executable file ");
4309             error_strm << module_spec.GetFileSpec();
4310           } else if (frame_option_set) {
4311             error_strm.PutCString(
4312                 "unable to find debug symbols for the current frame");
4313           }
4314           result.AppendError(error_strm.GetString());
4315         }
4316       } else {
4317         result.AppendError("one or more symbol file paths must be specified, "
4318                            "or options must be specified");
4319       }
4320     } else {
4321       if (uuid_option_set) {
4322         result.AppendError("specify either one or more paths to symbol files "
4323                            "or use the --uuid option without arguments");
4324       } else if (frame_option_set) {
4325         result.AppendError("specify either one or more paths to symbol files "
4326                            "or use the --frame option without arguments");
4327       } else if (file_option_set && argc > 1) {
4328         result.AppendError("specify at most one symbol file path when "
4329                            "--shlib option is set");
4330       } else {
4331         PlatformSP platform_sp(target->GetPlatform());
4332 
4333         for (auto &entry : args.entries()) {
4334           if (!entry.ref().empty()) {
4335             auto &symbol_file_spec = module_spec.GetSymbolFileSpec();
4336             symbol_file_spec.SetFile(entry.ref(), FileSpec::Style::native);
4337             FileSystem::Instance().Resolve(symbol_file_spec);
4338             if (file_option_set) {
4339               module_spec.GetFileSpec() =
4340                   m_file_option.GetOptionValue().GetCurrentValue();
4341             }
4342             if (platform_sp) {
4343               FileSpec symfile_spec;
4344               if (platform_sp
4345                       ->ResolveSymbolFile(*target, module_spec, symfile_spec)
4346                       .Success())
4347                 module_spec.GetSymbolFileSpec() = symfile_spec;
4348             }
4349 
4350             bool symfile_exists =
4351                 FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec());
4352 
4353             if (symfile_exists) {
4354               if (!AddModuleSymbols(target, module_spec, flush, result))
4355                 break;
4356             } else {
4357               std::string resolved_symfile_path =
4358                   module_spec.GetSymbolFileSpec().GetPath();
4359               if (resolved_symfile_path != entry.ref()) {
4360                 result.AppendErrorWithFormat(
4361                     "invalid module path '%s' with resolved path '%s'\n",
4362                     entry.c_str(), resolved_symfile_path.c_str());
4363                 break;
4364               }
4365               result.AppendErrorWithFormat("invalid module path '%s'\n",
4366                                            entry.c_str());
4367               break;
4368             }
4369           }
4370         }
4371       }
4372     }
4373 
4374     if (flush) {
4375       Process *process = m_exe_ctx.GetProcessPtr();
4376       if (process)
4377         process->Flush();
4378     }
4379     return result.Succeeded();
4380   }
4381 
4382   OptionGroupOptions m_option_group;
4383   OptionGroupUUID m_uuid_option_group;
4384   OptionGroupFile m_file_option;
4385   OptionGroupBoolean m_current_frame_option;
4386 };
4387 
4388 #pragma mark CommandObjectTargetSymbols
4389 
4390 // CommandObjectTargetSymbols
4391 
4392 class CommandObjectTargetSymbols : public CommandObjectMultiword {
4393 public:
4394   // Constructors and Destructors
4395   CommandObjectTargetSymbols(CommandInterpreter &interpreter)
4396       : CommandObjectMultiword(
4397             interpreter, "target symbols",
4398             "Commands for adding and managing debug symbol files.",
4399             "target symbols <sub-command> ...") {
4400     LoadSubCommand(
4401         "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));
4402   }
4403 
4404   ~CommandObjectTargetSymbols() override = default;
4405 
4406 private:
4407   // For CommandObjectTargetModules only
4408   CommandObjectTargetSymbols(const CommandObjectTargetSymbols &) = delete;
4409   const CommandObjectTargetSymbols &
4410   operator=(const CommandObjectTargetSymbols &) = delete;
4411 };
4412 
4413 #pragma mark CommandObjectTargetStopHookAdd
4414 
4415 // CommandObjectTargetStopHookAdd
4416 #define LLDB_OPTIONS_target_stop_hook_add
4417 #include "CommandOptions.inc"
4418 
4419 class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
4420                                        public IOHandlerDelegateMultiline {
4421 public:
4422   class CommandOptions : public OptionGroup {
4423   public:
4424     CommandOptions() : OptionGroup(), m_line_end(UINT_MAX), m_one_liner() {}
4425 
4426     ~CommandOptions() override = default;
4427 
4428     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
4429       return llvm::makeArrayRef(g_target_stop_hook_add_options);
4430     }
4431 
4432     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
4433                           ExecutionContext *execution_context) override {
4434       Status error;
4435       const int short_option =
4436           g_target_stop_hook_add_options[option_idx].short_option;
4437 
4438       switch (short_option) {
4439       case 'c':
4440         m_class_name = std::string(option_arg);
4441         m_sym_ctx_specified = true;
4442         break;
4443 
4444       case 'e':
4445         if (option_arg.getAsInteger(0, m_line_end)) {
4446           error.SetErrorStringWithFormat("invalid end line number: \"%s\"",
4447                                          option_arg.str().c_str());
4448           break;
4449         }
4450         m_sym_ctx_specified = true;
4451         break;
4452 
4453       case 'G': {
4454         bool value, success;
4455         value = OptionArgParser::ToBoolean(option_arg, false, &success);
4456         if (success) {
4457           m_auto_continue = value;
4458         } else
4459           error.SetErrorStringWithFormat(
4460               "invalid boolean value '%s' passed for -G option",
4461               option_arg.str().c_str());
4462       } break;
4463       case 'l':
4464         if (option_arg.getAsInteger(0, m_line_start)) {
4465           error.SetErrorStringWithFormat("invalid start line number: \"%s\"",
4466                                          option_arg.str().c_str());
4467           break;
4468         }
4469         m_sym_ctx_specified = true;
4470         break;
4471 
4472       case 'i':
4473         m_no_inlines = true;
4474         break;
4475 
4476       case 'n':
4477         m_function_name = std::string(option_arg);
4478         m_func_name_type_mask |= eFunctionNameTypeAuto;
4479         m_sym_ctx_specified = true;
4480         break;
4481 
4482       case 'f':
4483         m_file_name = std::string(option_arg);
4484         m_sym_ctx_specified = true;
4485         break;
4486 
4487       case 's':
4488         m_module_name = std::string(option_arg);
4489         m_sym_ctx_specified = true;
4490         break;
4491 
4492       case 't':
4493         if (option_arg.getAsInteger(0, m_thread_id))
4494           error.SetErrorStringWithFormat("invalid thread id string '%s'",
4495                                          option_arg.str().c_str());
4496         m_thread_specified = true;
4497         break;
4498 
4499       case 'T':
4500         m_thread_name = std::string(option_arg);
4501         m_thread_specified = true;
4502         break;
4503 
4504       case 'q':
4505         m_queue_name = std::string(option_arg);
4506         m_thread_specified = true;
4507         break;
4508 
4509       case 'x':
4510         if (option_arg.getAsInteger(0, m_thread_index))
4511           error.SetErrorStringWithFormat("invalid thread index string '%s'",
4512                                          option_arg.str().c_str());
4513         m_thread_specified = true;
4514         break;
4515 
4516       case 'o':
4517         m_use_one_liner = true;
4518         m_one_liner.push_back(std::string(option_arg));
4519         break;
4520 
4521       default:
4522         llvm_unreachable("Unimplemented option");
4523       }
4524       return error;
4525     }
4526 
4527     void OptionParsingStarting(ExecutionContext *execution_context) override {
4528       m_class_name.clear();
4529       m_function_name.clear();
4530       m_line_start = 0;
4531       m_line_end = UINT_MAX;
4532       m_file_name.clear();
4533       m_module_name.clear();
4534       m_func_name_type_mask = eFunctionNameTypeAuto;
4535       m_thread_id = LLDB_INVALID_THREAD_ID;
4536       m_thread_index = UINT32_MAX;
4537       m_thread_name.clear();
4538       m_queue_name.clear();
4539 
4540       m_no_inlines = false;
4541       m_sym_ctx_specified = false;
4542       m_thread_specified = false;
4543 
4544       m_use_one_liner = false;
4545       m_one_liner.clear();
4546       m_auto_continue = false;
4547     }
4548 
4549     std::string m_class_name;
4550     std::string m_function_name;
4551     uint32_t m_line_start = 0;
4552     uint32_t m_line_end;
4553     std::string m_file_name;
4554     std::string m_module_name;
4555     uint32_t m_func_name_type_mask =
4556         eFunctionNameTypeAuto; // A pick from lldb::FunctionNameType.
4557     lldb::tid_t m_thread_id;
4558     uint32_t m_thread_index;
4559     std::string m_thread_name;
4560     std::string m_queue_name;
4561     bool m_sym_ctx_specified = false;
4562     bool m_no_inlines;
4563     bool m_thread_specified = false;
4564     // Instance variables to hold the values for one_liner options.
4565     bool m_use_one_liner = false;
4566     std::vector<std::string> m_one_liner;
4567 
4568     bool m_auto_continue;
4569   };
4570 
4571   CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
4572       : CommandObjectParsed(interpreter, "target stop-hook add",
4573                             "Add a hook to be executed when the target stops."
4574                             "The hook can either be a list of commands or an "
4575                             "appropriately defined Python class.  You can also "
4576                             "add filters so the hook only runs a certain stop "
4577                             "points.",
4578                             "target stop-hook add"),
4579         IOHandlerDelegateMultiline("DONE",
4580                                    IOHandlerDelegate::Completion::LLDBCommand),
4581         m_options(), m_python_class_options("scripted stop-hook", true, 'P') {
4582     SetHelpLong(
4583         R"(
4584 Command Based stop-hooks:
4585 -------------------------
4586   Stop hooks can run a list of lldb commands by providing one or more
4587   --one-line-command options.  The commands will get run in the order they are
4588   added.  Or you can provide no commands, in which case you will enter a
4589   command editor where you can enter the commands to be run.
4590 
4591 Python Based Stop Hooks:
4592 ------------------------
4593   Stop hooks can be implemented with a suitably defined Python class, whose name
4594   is passed in the --python-class option.
4595 
4596   When the stop hook is added, the class is initialized by calling:
4597 
4598     def __init__(self, target, extra_args, internal_dict):
4599 
4600     target: The target that the stop hook is being added to.
4601     extra_args: An SBStructuredData Dictionary filled with the -key -value
4602                 option pairs passed to the command.
4603     dict: An implementation detail provided by lldb.
4604 
4605   Then when the stop-hook triggers, lldb will run the 'handle_stop' method.
4606   The method has the signature:
4607 
4608     def handle_stop(self, exe_ctx, stream):
4609 
4610     exe_ctx: An SBExecutionContext for the thread that has stopped.
4611     stream: An SBStream, anything written to this stream will be printed in the
4612             the stop message when the process stops.
4613 
4614     Return Value: The method returns "should_stop".  If should_stop is false
4615                   from all the stop hook executions on threads that stopped
4616                   with a reason, then the process will continue.  Note that this
4617                   will happen only after all the stop hooks are run.
4618 
4619 Filter Options:
4620 ---------------
4621   Stop hooks can be set to always run, or to only run when the stopped thread
4622   matches the filter options passed on the command line.  The available filter
4623   options include a shared library or a thread or queue specification,
4624   a line range in a source file, a function name or a class name.
4625             )");
4626     m_all_options.Append(&m_python_class_options,
4627                          LLDB_OPT_SET_1 | LLDB_OPT_SET_2,
4628                          LLDB_OPT_SET_FROM_TO(4, 6));
4629     m_all_options.Append(&m_options);
4630     m_all_options.Finalize();
4631   }
4632 
4633   ~CommandObjectTargetStopHookAdd() override = default;
4634 
4635   Options *GetOptions() override { return &m_all_options; }
4636 
4637 protected:
4638   void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
4639     StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
4640     if (output_sp && interactive) {
4641       output_sp->PutCString(
4642           "Enter your stop hook command(s).  Type 'DONE' to end.\n");
4643       output_sp->Flush();
4644     }
4645   }
4646 
4647   void IOHandlerInputComplete(IOHandler &io_handler,
4648                               std::string &line) override {
4649     if (m_stop_hook_sp) {
4650       if (line.empty()) {
4651         StreamFileSP error_sp(io_handler.GetErrorStreamFileSP());
4652         if (error_sp) {
4653           error_sp->Printf("error: stop hook #%" PRIu64
4654                            " aborted, no commands.\n",
4655                            m_stop_hook_sp->GetID());
4656           error_sp->Flush();
4657         }
4658         Target *target = GetDebugger().GetSelectedTarget().get();
4659         if (target) {
4660           target->UndoCreateStopHook(m_stop_hook_sp->GetID());
4661         }
4662       } else {
4663         // The IOHandler editor is only for command lines stop hooks:
4664         Target::StopHookCommandLine *hook_ptr =
4665             static_cast<Target::StopHookCommandLine *>(m_stop_hook_sp.get());
4666 
4667         hook_ptr->SetActionFromString(line);
4668         StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
4669         if (output_sp) {
4670           output_sp->Printf("Stop hook #%" PRIu64 " added.\n",
4671                             m_stop_hook_sp->GetID());
4672           output_sp->Flush();
4673         }
4674       }
4675       m_stop_hook_sp.reset();
4676     }
4677     io_handler.SetIsDone(true);
4678   }
4679 
4680   bool DoExecute(Args &command, CommandReturnObject &result) override {
4681     m_stop_hook_sp.reset();
4682 
4683     Target &target = GetSelectedOrDummyTarget();
4684     Target::StopHookSP new_hook_sp =
4685         target.CreateStopHook(m_python_class_options.GetName().empty() ?
4686                                Target::StopHook::StopHookKind::CommandBased
4687                                : Target::StopHook::StopHookKind::ScriptBased);
4688 
4689     //  First step, make the specifier.
4690     std::unique_ptr<SymbolContextSpecifier> specifier_up;
4691     if (m_options.m_sym_ctx_specified) {
4692       specifier_up = std::make_unique<SymbolContextSpecifier>(
4693           GetDebugger().GetSelectedTarget());
4694 
4695       if (!m_options.m_module_name.empty()) {
4696         specifier_up->AddSpecification(
4697             m_options.m_module_name.c_str(),
4698             SymbolContextSpecifier::eModuleSpecified);
4699       }
4700 
4701       if (!m_options.m_class_name.empty()) {
4702         specifier_up->AddSpecification(
4703             m_options.m_class_name.c_str(),
4704             SymbolContextSpecifier::eClassOrNamespaceSpecified);
4705       }
4706 
4707       if (!m_options.m_file_name.empty()) {
4708         specifier_up->AddSpecification(m_options.m_file_name.c_str(),
4709                                        SymbolContextSpecifier::eFileSpecified);
4710       }
4711 
4712       if (m_options.m_line_start != 0) {
4713         specifier_up->AddLineSpecification(
4714             m_options.m_line_start,
4715             SymbolContextSpecifier::eLineStartSpecified);
4716       }
4717 
4718       if (m_options.m_line_end != UINT_MAX) {
4719         specifier_up->AddLineSpecification(
4720             m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
4721       }
4722 
4723       if (!m_options.m_function_name.empty()) {
4724         specifier_up->AddSpecification(
4725             m_options.m_function_name.c_str(),
4726             SymbolContextSpecifier::eFunctionSpecified);
4727       }
4728     }
4729 
4730     if (specifier_up)
4731       new_hook_sp->SetSpecifier(specifier_up.release());
4732 
4733     // Next see if any of the thread options have been entered:
4734 
4735     if (m_options.m_thread_specified) {
4736       ThreadSpec *thread_spec = new ThreadSpec();
4737 
4738       if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) {
4739         thread_spec->SetTID(m_options.m_thread_id);
4740       }
4741 
4742       if (m_options.m_thread_index != UINT32_MAX)
4743         thread_spec->SetIndex(m_options.m_thread_index);
4744 
4745       if (!m_options.m_thread_name.empty())
4746         thread_spec->SetName(m_options.m_thread_name.c_str());
4747 
4748       if (!m_options.m_queue_name.empty())
4749         thread_spec->SetQueueName(m_options.m_queue_name.c_str());
4750 
4751       new_hook_sp->SetThreadSpecifier(thread_spec);
4752     }
4753 
4754     new_hook_sp->SetAutoContinue(m_options.m_auto_continue);
4755     if (m_options.m_use_one_liner) {
4756       // This is a command line stop hook:
4757       Target::StopHookCommandLine *hook_ptr =
4758           static_cast<Target::StopHookCommandLine *>(new_hook_sp.get());
4759       hook_ptr->SetActionFromStrings(m_options.m_one_liner);
4760       result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
4761                                      new_hook_sp->GetID());
4762     } else if (!m_python_class_options.GetName().empty()) {
4763       // This is a scripted stop hook:
4764       Target::StopHookScripted *hook_ptr =
4765           static_cast<Target::StopHookScripted *>(new_hook_sp.get());
4766       Status error = hook_ptr->SetScriptCallback(
4767           m_python_class_options.GetName(),
4768           m_python_class_options.GetStructuredData());
4769       if (error.Success())
4770         result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
4771                                        new_hook_sp->GetID());
4772       else {
4773         // FIXME: Set the stop hook ID counter back.
4774         result.AppendErrorWithFormat("Couldn't add stop hook: %s",
4775                                      error.AsCString());
4776         result.SetStatus(eReturnStatusFailed);
4777         target.UndoCreateStopHook(new_hook_sp->GetID());
4778         return false;
4779       }
4780     } else {
4781       m_stop_hook_sp = new_hook_sp;
4782       m_interpreter.GetLLDBCommandsFromIOHandler("> ",   // Prompt
4783                                                  *this); // IOHandlerDelegate
4784     }
4785     result.SetStatus(eReturnStatusSuccessFinishNoResult);
4786 
4787     return result.Succeeded();
4788   }
4789 
4790 private:
4791   CommandOptions m_options;
4792   OptionGroupPythonClassWithDict m_python_class_options;
4793   OptionGroupOptions m_all_options;
4794 
4795   Target::StopHookSP m_stop_hook_sp;
4796 };
4797 
4798 #pragma mark CommandObjectTargetStopHookDelete
4799 
4800 // CommandObjectTargetStopHookDelete
4801 
4802 class CommandObjectTargetStopHookDelete : public CommandObjectParsed {
4803 public:
4804   CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter)
4805       : CommandObjectParsed(interpreter, "target stop-hook delete",
4806                             "Delete a stop-hook.",
4807                             "target stop-hook delete [<idx>]") {}
4808 
4809   ~CommandObjectTargetStopHookDelete() override = default;
4810 
4811   void
4812   HandleArgumentCompletion(CompletionRequest &request,
4813                            OptionElementVector &opt_element_vector) override {
4814     CommandCompletions::InvokeCommonCompletionCallbacks(
4815         GetCommandInterpreter(), CommandCompletions::eStopHookIDCompletion,
4816         request, nullptr);
4817   }
4818 
4819 protected:
4820   bool DoExecute(Args &command, CommandReturnObject &result) override {
4821     Target &target = GetSelectedOrDummyTarget();
4822     // FIXME: see if we can use the breakpoint id style parser?
4823     size_t num_args = command.GetArgumentCount();
4824     if (num_args == 0) {
4825       if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
4826         result.SetStatus(eReturnStatusFailed);
4827         return false;
4828       } else {
4829         target.RemoveAllStopHooks();
4830       }
4831     } else {
4832       for (size_t i = 0; i < num_args; i++) {
4833         lldb::user_id_t user_id;
4834         if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
4835           result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4836                                        command.GetArgumentAtIndex(i));
4837           result.SetStatus(eReturnStatusFailed);
4838           return false;
4839         }
4840         if (!target.RemoveStopHookByID(user_id)) {
4841           result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4842                                        command.GetArgumentAtIndex(i));
4843           result.SetStatus(eReturnStatusFailed);
4844           return false;
4845         }
4846       }
4847     }
4848     result.SetStatus(eReturnStatusSuccessFinishNoResult);
4849     return result.Succeeded();
4850   }
4851 };
4852 
4853 #pragma mark CommandObjectTargetStopHookEnableDisable
4854 
4855 // CommandObjectTargetStopHookEnableDisable
4856 
4857 class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed {
4858 public:
4859   CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter,
4860                                            bool enable, const char *name,
4861                                            const char *help, const char *syntax)
4862       : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) {
4863   }
4864 
4865   ~CommandObjectTargetStopHookEnableDisable() override = default;
4866 
4867   void
4868   HandleArgumentCompletion(CompletionRequest &request,
4869                            OptionElementVector &opt_element_vector) override {
4870     if (request.GetCursorIndex())
4871       return;
4872     CommandCompletions::InvokeCommonCompletionCallbacks(
4873         GetCommandInterpreter(), CommandCompletions::eStopHookIDCompletion,
4874         request, nullptr);
4875   }
4876 
4877 protected:
4878   bool DoExecute(Args &command, CommandReturnObject &result) override {
4879     Target &target = GetSelectedOrDummyTarget();
4880     // FIXME: see if we can use the breakpoint id style parser?
4881     size_t num_args = command.GetArgumentCount();
4882     bool success;
4883 
4884     if (num_args == 0) {
4885       target.SetAllStopHooksActiveState(m_enable);
4886     } else {
4887       for (size_t i = 0; i < num_args; i++) {
4888         lldb::user_id_t user_id;
4889         if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
4890           result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4891                                        command.GetArgumentAtIndex(i));
4892           result.SetStatus(eReturnStatusFailed);
4893           return false;
4894         }
4895         success = target.SetStopHookActiveStateByID(user_id, m_enable);
4896         if (!success) {
4897           result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4898                                        command.GetArgumentAtIndex(i));
4899           result.SetStatus(eReturnStatusFailed);
4900           return false;
4901         }
4902       }
4903     }
4904     result.SetStatus(eReturnStatusSuccessFinishNoResult);
4905     return result.Succeeded();
4906   }
4907 
4908 private:
4909   bool m_enable;
4910 };
4911 
4912 #pragma mark CommandObjectTargetStopHookList
4913 
4914 // CommandObjectTargetStopHookList
4915 
4916 class CommandObjectTargetStopHookList : public CommandObjectParsed {
4917 public:
4918   CommandObjectTargetStopHookList(CommandInterpreter &interpreter)
4919       : CommandObjectParsed(interpreter, "target stop-hook list",
4920                             "List all stop-hooks.",
4921                             "target stop-hook list [<type>]") {}
4922 
4923   ~CommandObjectTargetStopHookList() override = default;
4924 
4925 protected:
4926   bool DoExecute(Args &command, CommandReturnObject &result) override {
4927     Target &target = GetSelectedOrDummyTarget();
4928 
4929     size_t num_hooks = target.GetNumStopHooks();
4930     if (num_hooks == 0) {
4931       result.GetOutputStream().PutCString("No stop hooks.\n");
4932     } else {
4933       for (size_t i = 0; i < num_hooks; i++) {
4934         Target::StopHookSP this_hook = target.GetStopHookAtIndex(i);
4935         if (i > 0)
4936           result.GetOutputStream().PutCString("\n");
4937         this_hook->GetDescription(&(result.GetOutputStream()),
4938                                   eDescriptionLevelFull);
4939       }
4940     }
4941     result.SetStatus(eReturnStatusSuccessFinishResult);
4942     return result.Succeeded();
4943   }
4944 };
4945 
4946 #pragma mark CommandObjectMultiwordTargetStopHooks
4947 
4948 // CommandObjectMultiwordTargetStopHooks
4949 
4950 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword {
4951 public:
4952   CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
4953       : CommandObjectMultiword(
4954             interpreter, "target stop-hook",
4955             "Commands for operating on debugger target stop-hooks.",
4956             "target stop-hook <subcommand> [<subcommand-options>]") {
4957     LoadSubCommand("add", CommandObjectSP(
4958                               new CommandObjectTargetStopHookAdd(interpreter)));
4959     LoadSubCommand(
4960         "delete",
4961         CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter)));
4962     LoadSubCommand("disable",
4963                    CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
4964                        interpreter, false, "target stop-hook disable [<id>]",
4965                        "Disable a stop-hook.", "target stop-hook disable")));
4966     LoadSubCommand("enable",
4967                    CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
4968                        interpreter, true, "target stop-hook enable [<id>]",
4969                        "Enable a stop-hook.", "target stop-hook enable")));
4970     LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList(
4971                                interpreter)));
4972   }
4973 
4974   ~CommandObjectMultiwordTargetStopHooks() override = default;
4975 };
4976 
4977 #pragma mark CommandObjectMultiwordTarget
4978 
4979 // CommandObjectMultiwordTarget
4980 
4981 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(
4982     CommandInterpreter &interpreter)
4983     : CommandObjectMultiword(interpreter, "target",
4984                              "Commands for operating on debugger targets.",
4985                              "target <subcommand> [<subcommand-options>]") {
4986   LoadSubCommand("create",
4987                  CommandObjectSP(new CommandObjectTargetCreate(interpreter)));
4988   LoadSubCommand("delete",
4989                  CommandObjectSP(new CommandObjectTargetDelete(interpreter)));
4990   LoadSubCommand("list",
4991                  CommandObjectSP(new CommandObjectTargetList(interpreter)));
4992   LoadSubCommand("select",
4993                  CommandObjectSP(new CommandObjectTargetSelect(interpreter)));
4994   LoadSubCommand("show-launch-environment",
4995                  CommandObjectSP(new CommandObjectTargetShowLaunchEnvironment(
4996                      interpreter)));
4997   LoadSubCommand(
4998       "stop-hook",
4999       CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter)));
5000   LoadSubCommand("modules",
5001                  CommandObjectSP(new CommandObjectTargetModules(interpreter)));
5002   LoadSubCommand("symbols",
5003                  CommandObjectSP(new CommandObjectTargetSymbols(interpreter)));
5004   LoadSubCommand("variable",
5005                  CommandObjectSP(new CommandObjectTargetVariable(interpreter)));
5006 }
5007 
5008 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;
5009