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