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