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