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