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