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