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