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