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