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