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