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     Stream &strm = result.GetOutputStream();
491 
492     bool show_stopped_process_status = false;
493     if (DumpTargetList(GetDebugger().GetTargetList(),
494                        show_stopped_process_status, strm) == 0) {
495       strm.PutCString("No targets.\n");
496     }
497     result.SetStatus(eReturnStatusSuccessFinishResult);
498     return result.Succeeded();
499   }
500 };
501 
502 #pragma mark CommandObjectTargetSelect
503 
504 class CommandObjectTargetSelect : public CommandObjectParsed {
505 public:
506   CommandObjectTargetSelect(CommandInterpreter &interpreter)
507       : CommandObjectParsed(
508             interpreter, "target select",
509             "Select a target as the current target by target index.", nullptr) {
510     CommandArgumentData target_arg{eArgTypeTargetID, eArgRepeatPlain};
511     m_arguments.push_back({target_arg});
512   }
513 
514   ~CommandObjectTargetSelect() override = default;
515 
516 protected:
517   bool DoExecute(Args &args, CommandReturnObject &result) override {
518     if (args.GetArgumentCount() == 1) {
519       const char *target_idx_arg = args.GetArgumentAtIndex(0);
520       uint32_t target_idx;
521       if (llvm::to_integer(target_idx_arg, target_idx)) {
522         TargetList &target_list = GetDebugger().GetTargetList();
523         const uint32_t num_targets = target_list.GetNumTargets();
524         if (target_idx < num_targets) {
525           target_list.SetSelectedTarget(target_idx);
526           Stream &strm = result.GetOutputStream();
527           bool show_stopped_process_status = false;
528           DumpTargetList(target_list, show_stopped_process_status, strm);
529           result.SetStatus(eReturnStatusSuccessFinishResult);
530         } else {
531           if (num_targets > 0) {
532             result.AppendErrorWithFormat(
533                 "index %u is out of range, valid target indexes are 0 - %u\n",
534                 target_idx, num_targets - 1);
535           } else {
536             result.AppendErrorWithFormat(
537                 "index %u is out of range since there are no active targets\n",
538                 target_idx);
539           }
540         }
541       } else {
542         result.AppendErrorWithFormat("invalid index string value '%s'\n",
543                                      target_idx_arg);
544       }
545     } else {
546       result.AppendError(
547           "'target select' takes a single argument: a target index\n");
548     }
549     return result.Succeeded();
550   }
551 };
552 
553 #pragma mark CommandObjectTargetDelete
554 
555 class CommandObjectTargetDelete : public CommandObjectParsed {
556 public:
557   CommandObjectTargetDelete(CommandInterpreter &interpreter)
558       : CommandObjectParsed(interpreter, "target delete",
559                             "Delete one or more targets by target index.",
560                             nullptr),
561         m_all_option(LLDB_OPT_SET_1, false, "all", 'a', "Delete all targets.",
562                      false, true),
563         m_cleanup_option(
564             LLDB_OPT_SET_1, false, "clean", 'c',
565             "Perform extra cleanup to minimize memory consumption after "
566             "deleting the target.  "
567             "By default, LLDB will keep in memory any modules previously "
568             "loaded by the target as well "
569             "as all of its debug info.  Specifying --clean will unload all of "
570             "these shared modules and "
571             "cause them to be reparsed again the next time the target is run",
572             false, true) {
573     m_option_group.Append(&m_all_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
574     m_option_group.Append(&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
575     m_option_group.Finalize();
576     CommandArgumentData target_arg{eArgTypeTargetID, eArgRepeatStar};
577     m_arguments.push_back({target_arg});
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 
1234     target->GetImageSearchPathList().Dump(&result.GetOutputStream());
1235     result.SetStatus(eReturnStatusSuccessFinishResult);
1236     return result.Succeeded();
1237   }
1238 };
1239 
1240 #pragma mark CommandObjectTargetModulesSearchPathsQuery
1241 
1242 class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed {
1243 public:
1244   CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter &interpreter)
1245       : CommandObjectParsed(
1246             interpreter, "target modules search-paths query",
1247             "Transform a path using the first applicable image search path.",
1248             nullptr, eCommandRequiresTarget) {
1249     CommandArgumentEntry arg;
1250     CommandArgumentData path_arg;
1251 
1252     // Define the first (and only) variant of this arg.
1253     path_arg.arg_type = eArgTypeDirectoryName;
1254     path_arg.arg_repetition = eArgRepeatPlain;
1255 
1256     // There is only one variant this argument could be; put it into the
1257     // argument entry.
1258     arg.push_back(path_arg);
1259 
1260     // Push the data for the first argument into the m_arguments vector.
1261     m_arguments.push_back(arg);
1262   }
1263 
1264   ~CommandObjectTargetModulesSearchPathsQuery() override = default;
1265 
1266 protected:
1267   bool DoExecute(Args &command, CommandReturnObject &result) override {
1268     Target *target = &GetSelectedTarget();
1269     if (command.GetArgumentCount() != 1) {
1270       result.AppendError("query requires one argument\n");
1271       return result.Succeeded();
1272     }
1273 
1274     ConstString orig(command.GetArgumentAtIndex(0));
1275     ConstString transformed;
1276     if (target->GetImageSearchPathList().RemapPath(orig, transformed))
1277       result.GetOutputStream().Printf("%s\n", transformed.GetCString());
1278     else
1279       result.GetOutputStream().Printf("%s\n", orig.GetCString());
1280 
1281     result.SetStatus(eReturnStatusSuccessFinishResult);
1282     return result.Succeeded();
1283   }
1284 };
1285 
1286 // Static Helper functions
1287 static void DumpModuleArchitecture(Stream &strm, Module *module,
1288                                    bool full_triple, uint32_t width) {
1289   if (module) {
1290     StreamString arch_strm;
1291 
1292     if (full_triple)
1293       module->GetArchitecture().DumpTriple(arch_strm.AsRawOstream());
1294     else
1295       arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
1296     std::string arch_str = std::string(arch_strm.GetString());
1297 
1298     if (width)
1299       strm.Printf("%-*s", width, arch_str.c_str());
1300     else
1301       strm.PutCString(arch_str);
1302   }
1303 }
1304 
1305 static void DumpModuleUUID(Stream &strm, Module *module) {
1306   if (module && module->GetUUID().IsValid())
1307     module->GetUUID().Dump(&strm);
1308   else
1309     strm.PutCString("                                    ");
1310 }
1311 
1312 static uint32_t DumpCompileUnitLineTable(CommandInterpreter &interpreter,
1313                                          Stream &strm, Module *module,
1314                                          const FileSpec &file_spec,
1315                                          lldb::DescriptionLevel desc_level) {
1316   uint32_t num_matches = 0;
1317   if (module) {
1318     SymbolContextList sc_list;
1319     num_matches = module->ResolveSymbolContextsForFileSpec(
1320         file_spec, 0, false, eSymbolContextCompUnit, sc_list);
1321 
1322     for (uint32_t i = 0; i < num_matches; ++i) {
1323       SymbolContext sc;
1324       if (sc_list.GetContextAtIndex(i, sc)) {
1325         if (i > 0)
1326           strm << "\n\n";
1327 
1328         strm << "Line table for " << sc.comp_unit->GetPrimaryFile() << " in `"
1329              << module->GetFileSpec().GetFilename() << "\n";
1330         LineTable *line_table = sc.comp_unit->GetLineTable();
1331         if (line_table)
1332           line_table->GetDescription(
1333               &strm, interpreter.GetExecutionContext().GetTargetPtr(),
1334               desc_level);
1335         else
1336           strm << "No line table";
1337       }
1338     }
1339   }
1340   return num_matches;
1341 }
1342 
1343 static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr,
1344                          uint32_t width) {
1345   if (file_spec_ptr) {
1346     if (width > 0) {
1347       std::string fullpath = file_spec_ptr->GetPath();
1348       strm.Printf("%-*s", width, fullpath.c_str());
1349       return;
1350     } else {
1351       file_spec_ptr->Dump(strm.AsRawOstream());
1352       return;
1353     }
1354   }
1355   // Keep the width spacing correct if things go wrong...
1356   if (width > 0)
1357     strm.Printf("%-*s", width, "");
1358 }
1359 
1360 static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr,
1361                           uint32_t width) {
1362   if (file_spec_ptr) {
1363     if (width > 0)
1364       strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
1365     else
1366       file_spec_ptr->GetDirectory().Dump(&strm);
1367     return;
1368   }
1369   // Keep the width spacing correct if things go wrong...
1370   if (width > 0)
1371     strm.Printf("%-*s", width, "");
1372 }
1373 
1374 static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,
1375                          uint32_t width) {
1376   if (file_spec_ptr) {
1377     if (width > 0)
1378       strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
1379     else
1380       file_spec_ptr->GetFilename().Dump(&strm);
1381     return;
1382   }
1383   // Keep the width spacing correct if things go wrong...
1384   if (width > 0)
1385     strm.Printf("%-*s", width, "");
1386 }
1387 
1388 static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
1389   std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
1390   const size_t num_modules = module_list.GetSize();
1391   if (num_modules == 0)
1392     return 0;
1393 
1394   size_t num_dumped = 0;
1395   strm.Format("Dumping headers for {0} module(s).\n", num_modules);
1396   strm.IndentMore();
1397   for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
1398     if (module_sp) {
1399       if (num_dumped++ > 0) {
1400         strm.EOL();
1401         strm.EOL();
1402       }
1403       ObjectFile *objfile = module_sp->GetObjectFile();
1404       if (objfile)
1405         objfile->Dump(&strm);
1406       else {
1407         strm.Format("No object file for module: {0:F}\n",
1408                     module_sp->GetFileSpec());
1409       }
1410     }
1411   }
1412   strm.IndentLess();
1413   return num_dumped;
1414 }
1415 
1416 static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm,
1417                              Module *module, SortOrder sort_order,
1418                              Mangled::NamePreference name_preference) {
1419   if (!module)
1420     return;
1421   if (Symtab *symtab = module->GetSymtab())
1422     symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),
1423                  sort_order, name_preference);
1424 }
1425 
1426 static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,
1427                                Module *module) {
1428   if (module) {
1429     SectionList *section_list = module->GetSectionList();
1430     if (section_list) {
1431       strm.Printf("Sections for '%s' (%s):\n",
1432                   module->GetSpecificationDescription().c_str(),
1433                   module->GetArchitecture().GetArchitectureName());
1434       section_list->Dump(strm.AsRawOstream(), strm.GetIndentLevel() + 2,
1435                          interpreter.GetExecutionContext().GetTargetPtr(), true,
1436                          UINT32_MAX);
1437     }
1438   }
1439 }
1440 
1441 static bool DumpModuleSymbolFile(Stream &strm, Module *module) {
1442   if (module) {
1443     if (SymbolFile *symbol_file = module->GetSymbolFile(true)) {
1444       symbol_file->Dump(strm);
1445       return true;
1446     }
1447   }
1448   return false;
1449 }
1450 
1451 static void DumpAddress(ExecutionContextScope *exe_scope,
1452                         const Address &so_addr, bool verbose, bool all_ranges,
1453                         Stream &strm) {
1454   strm.IndentMore();
1455   strm.Indent("    Address: ");
1456   so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1457   strm.PutCString(" (");
1458   so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1459   strm.PutCString(")\n");
1460   strm.Indent("    Summary: ");
1461   const uint32_t save_indent = strm.GetIndentLevel();
1462   strm.SetIndentLevel(save_indent + 13);
1463   so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription);
1464   strm.SetIndentLevel(save_indent);
1465   // Print out detailed address information when verbose is enabled
1466   if (verbose) {
1467     strm.EOL();
1468     so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext,
1469                  Address::DumpStyleInvalid, UINT32_MAX, all_ranges);
1470   }
1471   strm.IndentLess();
1472 }
1473 
1474 static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
1475                                   Module *module, uint32_t resolve_mask,
1476                                   lldb::addr_t raw_addr, lldb::addr_t offset,
1477                                   bool verbose, bool all_ranges) {
1478   if (module) {
1479     lldb::addr_t addr = raw_addr - offset;
1480     Address so_addr;
1481     SymbolContext sc;
1482     Target *target = interpreter.GetExecutionContext().GetTargetPtr();
1483     if (target && !target->GetSectionLoadList().IsEmpty()) {
1484       if (!target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
1485         return false;
1486       else if (so_addr.GetModule().get() != module)
1487         return false;
1488     } else {
1489       if (!module->ResolveFileAddress(addr, so_addr))
1490         return false;
1491     }
1492 
1493     ExecutionContextScope *exe_scope =
1494         interpreter.GetExecutionContext().GetBestExecutionContextScope();
1495     DumpAddress(exe_scope, so_addr, verbose, all_ranges, strm);
1496     //        strm.IndentMore();
1497     //        strm.Indent ("    Address: ");
1498     //        so_addr.Dump (&strm, exe_scope,
1499     //        Address::DumpStyleModuleWithFileAddress);
1500     //        strm.PutCString (" (");
1501     //        so_addr.Dump (&strm, exe_scope,
1502     //        Address::DumpStyleSectionNameOffset);
1503     //        strm.PutCString (")\n");
1504     //        strm.Indent ("    Summary: ");
1505     //        const uint32_t save_indent = strm.GetIndentLevel ();
1506     //        strm.SetIndentLevel (save_indent + 13);
1507     //        so_addr.Dump (&strm, exe_scope,
1508     //        Address::DumpStyleResolvedDescription);
1509     //        strm.SetIndentLevel (save_indent);
1510     //        // Print out detailed address information when verbose is enabled
1511     //        if (verbose)
1512     //        {
1513     //            strm.EOL();
1514     //            so_addr.Dump (&strm, exe_scope,
1515     //            Address::DumpStyleDetailedSymbolContext);
1516     //        }
1517     //        strm.IndentLess();
1518     return true;
1519   }
1520 
1521   return false;
1522 }
1523 
1524 static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
1525                                      Stream &strm, Module *module,
1526                                      const char *name, bool name_is_regex,
1527                                      bool verbose, bool all_ranges) {
1528   if (!module)
1529     return 0;
1530 
1531   Symtab *symtab = module->GetSymtab();
1532   if (!symtab)
1533     return 0;
1534 
1535   SymbolContext sc;
1536   std::vector<uint32_t> match_indexes;
1537   ConstString symbol_name(name);
1538   uint32_t num_matches = 0;
1539   if (name_is_regex) {
1540     RegularExpression name_regexp(symbol_name.GetStringRef());
1541     num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType(
1542         name_regexp, eSymbolTypeAny, match_indexes);
1543   } else {
1544     num_matches =
1545         symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes);
1546   }
1547 
1548   if (num_matches > 0) {
1549     strm.Indent();
1550     strm.Printf("%u symbols match %s'%s' in ", num_matches,
1551                 name_is_regex ? "the regular expression " : "", name);
1552     DumpFullpath(strm, &module->GetFileSpec(), 0);
1553     strm.PutCString(":\n");
1554     strm.IndentMore();
1555     for (uint32_t i = 0; i < num_matches; ++i) {
1556       Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
1557       if (symbol && symbol->ValueIsAddress()) {
1558         DumpAddress(
1559             interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1560             symbol->GetAddressRef(), verbose, all_ranges, strm);
1561       }
1562     }
1563     strm.IndentLess();
1564   }
1565   return num_matches;
1566 }
1567 
1568 static void DumpSymbolContextList(ExecutionContextScope *exe_scope,
1569                                   Stream &strm, SymbolContextList &sc_list,
1570                                   bool verbose, bool all_ranges) {
1571   strm.IndentMore();
1572 
1573   const uint32_t num_matches = sc_list.GetSize();
1574 
1575   for (uint32_t i = 0; i < num_matches; ++i) {
1576     SymbolContext sc;
1577     if (sc_list.GetContextAtIndex(i, sc)) {
1578       AddressRange range;
1579 
1580       sc.GetAddressRange(eSymbolContextEverything, 0, true, range);
1581 
1582       DumpAddress(exe_scope, range.GetBaseAddress(), verbose, all_ranges, strm);
1583     }
1584   }
1585   strm.IndentLess();
1586 }
1587 
1588 static size_t LookupFunctionInModule(CommandInterpreter &interpreter,
1589                                      Stream &strm, Module *module,
1590                                      const char *name, bool name_is_regex,
1591                                      const ModuleFunctionSearchOptions &options,
1592                                      bool verbose, bool all_ranges) {
1593   if (module && name && name[0]) {
1594     SymbolContextList sc_list;
1595     size_t num_matches = 0;
1596     if (name_is_regex) {
1597       RegularExpression function_name_regex((llvm::StringRef(name)));
1598       module->FindFunctions(function_name_regex, options, sc_list);
1599     } else {
1600       ConstString function_name(name);
1601       module->FindFunctions(function_name, CompilerDeclContext(),
1602                             eFunctionNameTypeAuto, options, sc_list);
1603     }
1604     num_matches = sc_list.GetSize();
1605     if (num_matches) {
1606       strm.Indent();
1607       strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1608                   num_matches > 1 ? "es" : "");
1609       DumpFullpath(strm, &module->GetFileSpec(), 0);
1610       strm.PutCString(":\n");
1611       DumpSymbolContextList(
1612           interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1613           strm, sc_list, verbose, all_ranges);
1614     }
1615     return num_matches;
1616   }
1617   return 0;
1618 }
1619 
1620 static size_t LookupTypeInModule(Target *target,
1621                                  CommandInterpreter &interpreter, Stream &strm,
1622                                  Module *module, const char *name_cstr,
1623                                  bool name_is_regex) {
1624   TypeList type_list;
1625   if (module && name_cstr && name_cstr[0]) {
1626     const uint32_t max_num_matches = UINT32_MAX;
1627     bool name_is_fully_qualified = false;
1628 
1629     ConstString name(name_cstr);
1630     llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
1631     module->FindTypes(name, name_is_fully_qualified, max_num_matches,
1632                       searched_symbol_files, type_list);
1633 
1634     if (type_list.Empty())
1635       return 0;
1636 
1637     const uint64_t num_matches = type_list.GetSize();
1638 
1639     strm.Indent();
1640     strm.Printf("%" PRIu64 " match%s found in ", num_matches,
1641                 num_matches > 1 ? "es" : "");
1642     DumpFullpath(strm, &module->GetFileSpec(), 0);
1643     strm.PutCString(":\n");
1644     for (TypeSP type_sp : type_list.Types()) {
1645       if (!type_sp)
1646         continue;
1647       // Resolve the clang type so that any forward references to types
1648       // that haven't yet been parsed will get parsed.
1649       type_sp->GetFullCompilerType();
1650       type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
1651       // Print all typedef chains
1652       TypeSP typedef_type_sp(type_sp);
1653       TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1654       while (typedefed_type_sp) {
1655         strm.EOL();
1656         strm.Printf("     typedef '%s': ",
1657                     typedef_type_sp->GetName().GetCString());
1658         typedefed_type_sp->GetFullCompilerType();
1659         typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
1660                                           target);
1661         typedef_type_sp = typedefed_type_sp;
1662         typedefed_type_sp = typedef_type_sp->GetTypedefType();
1663       }
1664     }
1665     strm.EOL();
1666   }
1667   return type_list.GetSize();
1668 }
1669 
1670 static size_t LookupTypeHere(Target *target, CommandInterpreter &interpreter,
1671                              Stream &strm, Module &module,
1672                              const char *name_cstr, bool name_is_regex) {
1673   TypeList type_list;
1674   const uint32_t max_num_matches = UINT32_MAX;
1675   bool name_is_fully_qualified = false;
1676 
1677   ConstString name(name_cstr);
1678   llvm::DenseSet<SymbolFile *> searched_symbol_files;
1679   module.FindTypes(name, name_is_fully_qualified, max_num_matches,
1680                    searched_symbol_files, type_list);
1681 
1682   if (type_list.Empty())
1683     return 0;
1684 
1685   strm.Indent();
1686   strm.PutCString("Best match found in ");
1687   DumpFullpath(strm, &module.GetFileSpec(), 0);
1688   strm.PutCString(":\n");
1689 
1690   TypeSP type_sp(type_list.GetTypeAtIndex(0));
1691   if (type_sp) {
1692     // Resolve the clang type so that any forward references to types that
1693     // haven't yet been parsed will get parsed.
1694     type_sp->GetFullCompilerType();
1695     type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
1696     // Print all typedef chains.
1697     TypeSP typedef_type_sp(type_sp);
1698     TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1699     while (typedefed_type_sp) {
1700       strm.EOL();
1701       strm.Printf("     typedef '%s': ",
1702                   typedef_type_sp->GetName().GetCString());
1703       typedefed_type_sp->GetFullCompilerType();
1704       typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
1705                                         target);
1706       typedef_type_sp = typedefed_type_sp;
1707       typedefed_type_sp = typedef_type_sp->GetTypedefType();
1708     }
1709   }
1710   strm.EOL();
1711   return type_list.GetSize();
1712 }
1713 
1714 static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter,
1715                                           Stream &strm, Module *module,
1716                                           const FileSpec &file_spec,
1717                                           uint32_t line, bool check_inlines,
1718                                           bool verbose, bool all_ranges) {
1719   if (module && file_spec) {
1720     SymbolContextList sc_list;
1721     const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(
1722         file_spec, line, check_inlines, eSymbolContextEverything, sc_list);
1723     if (num_matches > 0) {
1724       strm.Indent();
1725       strm.Printf("%u match%s found in ", num_matches,
1726                   num_matches > 1 ? "es" : "");
1727       strm << file_spec;
1728       if (line > 0)
1729         strm.Printf(":%u", line);
1730       strm << " in ";
1731       DumpFullpath(strm, &module->GetFileSpec(), 0);
1732       strm.PutCString(":\n");
1733       DumpSymbolContextList(
1734           interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1735           strm, sc_list, verbose, all_ranges);
1736       return num_matches;
1737     }
1738   }
1739   return 0;
1740 }
1741 
1742 static size_t FindModulesByName(Target *target, const char *module_name,
1743                                 ModuleList &module_list,
1744                                 bool check_global_list) {
1745   FileSpec module_file_spec(module_name);
1746   ModuleSpec module_spec(module_file_spec);
1747 
1748   const size_t initial_size = module_list.GetSize();
1749 
1750   if (check_global_list) {
1751     // Check the global list
1752     std::lock_guard<std::recursive_mutex> guard(
1753         Module::GetAllocationModuleCollectionMutex());
1754     const size_t num_modules = Module::GetNumberAllocatedModules();
1755     ModuleSP module_sp;
1756     for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1757       Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
1758 
1759       if (module) {
1760         if (module->MatchesModuleSpec(module_spec)) {
1761           module_sp = module->shared_from_this();
1762           module_list.AppendIfNeeded(module_sp);
1763         }
1764       }
1765     }
1766   } else {
1767     if (target) {
1768       target->GetImages().FindModules(module_spec, module_list);
1769       const size_t num_matches = module_list.GetSize();
1770 
1771       // Not found in our module list for our target, check the main shared
1772       // module list in case it is a extra file used somewhere else
1773       if (num_matches == 0) {
1774         module_spec.GetArchitecture() = target->GetArchitecture();
1775         ModuleList::FindSharedModules(module_spec, module_list);
1776       }
1777     } else {
1778       ModuleList::FindSharedModules(module_spec, module_list);
1779     }
1780   }
1781 
1782   return module_list.GetSize() - initial_size;
1783 }
1784 
1785 #pragma mark CommandObjectTargetModulesModuleAutoComplete
1786 
1787 // A base command object class that can auto complete with module file
1788 // paths
1789 
1790 class CommandObjectTargetModulesModuleAutoComplete
1791     : public CommandObjectParsed {
1792 public:
1793   CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter,
1794                                                const char *name,
1795                                                const char *help,
1796                                                const char *syntax,
1797                                                uint32_t flags = 0)
1798       : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1799     CommandArgumentEntry arg;
1800     CommandArgumentData file_arg;
1801 
1802     // Define the first (and only) variant of this arg.
1803     file_arg.arg_type = eArgTypeFilename;
1804     file_arg.arg_repetition = eArgRepeatStar;
1805 
1806     // There is only one variant this argument could be; put it into the
1807     // argument entry.
1808     arg.push_back(file_arg);
1809 
1810     // Push the data for the first argument into the m_arguments vector.
1811     m_arguments.push_back(arg);
1812   }
1813 
1814   ~CommandObjectTargetModulesModuleAutoComplete() override = default;
1815 
1816   void
1817   HandleArgumentCompletion(CompletionRequest &request,
1818                            OptionElementVector &opt_element_vector) override {
1819     CommandCompletions::InvokeCommonCompletionCallbacks(
1820         GetCommandInterpreter(), CommandCompletions::eModuleCompletion, request,
1821         nullptr);
1822   }
1823 };
1824 
1825 #pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1826 
1827 // A base command object class that can auto complete with module source
1828 // file paths
1829 
1830 class CommandObjectTargetModulesSourceFileAutoComplete
1831     : public CommandObjectParsed {
1832 public:
1833   CommandObjectTargetModulesSourceFileAutoComplete(
1834       CommandInterpreter &interpreter, const char *name, const char *help,
1835       const char *syntax, uint32_t flags)
1836       : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1837     CommandArgumentEntry arg;
1838     CommandArgumentData source_file_arg;
1839 
1840     // Define the first (and only) variant of this arg.
1841     source_file_arg.arg_type = eArgTypeSourceFile;
1842     source_file_arg.arg_repetition = eArgRepeatPlus;
1843 
1844     // There is only one variant this argument could be; put it into the
1845     // argument entry.
1846     arg.push_back(source_file_arg);
1847 
1848     // Push the data for the first argument into the m_arguments vector.
1849     m_arguments.push_back(arg);
1850   }
1851 
1852   ~CommandObjectTargetModulesSourceFileAutoComplete() override = default;
1853 
1854   void
1855   HandleArgumentCompletion(CompletionRequest &request,
1856                            OptionElementVector &opt_element_vector) override {
1857     CommandCompletions::InvokeCommonCompletionCallbacks(
1858         GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion,
1859         request, nullptr);
1860   }
1861 };
1862 
1863 #pragma mark CommandObjectTargetModulesDumpObjfile
1864 
1865 class CommandObjectTargetModulesDumpObjfile
1866     : public CommandObjectTargetModulesModuleAutoComplete {
1867 public:
1868   CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter)
1869       : CommandObjectTargetModulesModuleAutoComplete(
1870             interpreter, "target modules dump objfile",
1871             "Dump the object file headers from one or more target modules.",
1872             nullptr, eCommandRequiresTarget) {}
1873 
1874   ~CommandObjectTargetModulesDumpObjfile() override = default;
1875 
1876 protected:
1877   bool DoExecute(Args &command, CommandReturnObject &result) override {
1878     Target *target = &GetSelectedTarget();
1879 
1880     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1881     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1882     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1883 
1884     size_t num_dumped = 0;
1885     if (command.GetArgumentCount() == 0) {
1886       // Dump all headers for all modules images
1887       num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(),
1888                                             target->GetImages());
1889       if (num_dumped == 0) {
1890         result.AppendError("the target has no associated executable images");
1891       }
1892     } else {
1893       // Find the modules that match the basename or full path.
1894       ModuleList module_list;
1895       const char *arg_cstr;
1896       for (int arg_idx = 0;
1897            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
1898            ++arg_idx) {
1899         size_t num_matched =
1900             FindModulesByName(target, arg_cstr, module_list, true);
1901         if (num_matched == 0) {
1902           result.AppendWarningWithFormat(
1903               "Unable to find an image that matches '%s'.\n", arg_cstr);
1904         }
1905       }
1906       // Dump all the modules we found.
1907       num_dumped =
1908           DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
1909     }
1910 
1911     if (num_dumped > 0) {
1912       result.SetStatus(eReturnStatusSuccessFinishResult);
1913     } else {
1914       result.AppendError("no matching executable images found");
1915     }
1916     return result.Succeeded();
1917   }
1918 };
1919 
1920 #pragma mark CommandObjectTargetModulesDumpSymtab
1921 
1922 static constexpr OptionEnumValueElement g_sort_option_enumeration[] = {
1923     {
1924         eSortOrderNone,
1925         "none",
1926         "No sorting, use the original symbol table order.",
1927     },
1928     {
1929         eSortOrderByAddress,
1930         "address",
1931         "Sort output by symbol address.",
1932     },
1933     {
1934         eSortOrderByName,
1935         "name",
1936         "Sort output by symbol name.",
1937     },
1938 };
1939 
1940 #define LLDB_OPTIONS_target_modules_dump_symtab
1941 #include "CommandOptions.inc"
1942 
1943 class CommandObjectTargetModulesDumpSymtab
1944     : public CommandObjectTargetModulesModuleAutoComplete {
1945 public:
1946   CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter)
1947       : CommandObjectTargetModulesModuleAutoComplete(
1948             interpreter, "target modules dump symtab",
1949             "Dump the symbol table from one or more target modules.", nullptr,
1950             eCommandRequiresTarget) {}
1951 
1952   ~CommandObjectTargetModulesDumpSymtab() override = default;
1953 
1954   Options *GetOptions() override { return &m_options; }
1955 
1956   class CommandOptions : public Options {
1957   public:
1958     CommandOptions() = default;
1959 
1960     ~CommandOptions() override = default;
1961 
1962     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1963                           ExecutionContext *execution_context) override {
1964       Status error;
1965       const int short_option = m_getopt_table[option_idx].val;
1966 
1967       switch (short_option) {
1968       case 'm':
1969         m_prefer_mangled.SetCurrentValue(true);
1970         m_prefer_mangled.SetOptionWasSet();
1971         break;
1972 
1973       case 's':
1974         m_sort_order = (SortOrder)OptionArgParser::ToOptionEnum(
1975             option_arg, GetDefinitions()[option_idx].enum_values,
1976             eSortOrderNone, error);
1977         break;
1978 
1979       default:
1980         llvm_unreachable("Unimplemented option");
1981       }
1982       return error;
1983     }
1984 
1985     void OptionParsingStarting(ExecutionContext *execution_context) override {
1986       m_sort_order = eSortOrderNone;
1987       m_prefer_mangled.Clear();
1988     }
1989 
1990     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1991       return llvm::makeArrayRef(g_target_modules_dump_symtab_options);
1992     }
1993 
1994     SortOrder m_sort_order = eSortOrderNone;
1995     OptionValueBoolean m_prefer_mangled = {false, false};
1996   };
1997 
1998 protected:
1999   bool DoExecute(Args &command, CommandReturnObject &result) override {
2000     Target *target = &GetSelectedTarget();
2001     uint32_t num_dumped = 0;
2002     Mangled::NamePreference name_preference =
2003         (m_options.m_prefer_mangled ? Mangled::ePreferMangled
2004                                     : Mangled::ePreferDemangled);
2005 
2006     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2007     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2008     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2009 
2010     if (command.GetArgumentCount() == 0) {
2011       // Dump all sections for all modules images
2012       const ModuleList &module_list = target->GetImages();
2013       std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
2014       const size_t num_modules = module_list.GetSize();
2015       if (num_modules > 0) {
2016         result.GetOutputStream().Format(
2017             "Dumping symbol table for {0} modules.\n", num_modules);
2018         for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
2019           if (num_dumped > 0) {
2020             result.GetOutputStream().EOL();
2021             result.GetOutputStream().EOL();
2022           }
2023           if (m_interpreter.WasInterrupted())
2024             break;
2025           num_dumped++;
2026           DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
2027                            module_sp.get(), m_options.m_sort_order,
2028                            name_preference);
2029         }
2030       } else {
2031         result.AppendError("the target has no associated executable images");
2032         return false;
2033       }
2034     } else {
2035       // Dump specified images (by basename or fullpath)
2036       const char *arg_cstr;
2037       for (int arg_idx = 0;
2038            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2039            ++arg_idx) {
2040         ModuleList module_list;
2041         const size_t num_matches =
2042             FindModulesByName(target, arg_cstr, module_list, true);
2043         if (num_matches > 0) {
2044           for (ModuleSP module_sp : module_list.Modules()) {
2045             if (module_sp) {
2046               if (num_dumped > 0) {
2047                 result.GetOutputStream().EOL();
2048                 result.GetOutputStream().EOL();
2049               }
2050               if (m_interpreter.WasInterrupted())
2051                 break;
2052               num_dumped++;
2053               DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
2054                                module_sp.get(), m_options.m_sort_order,
2055                                name_preference);
2056             }
2057           }
2058         } else
2059           result.AppendWarningWithFormat(
2060               "Unable to find an image that matches '%s'.\n", arg_cstr);
2061       }
2062     }
2063 
2064     if (num_dumped > 0)
2065       result.SetStatus(eReturnStatusSuccessFinishResult);
2066     else {
2067       result.AppendError("no matching executable images found");
2068     }
2069     return result.Succeeded();
2070   }
2071 
2072   CommandOptions m_options;
2073 };
2074 
2075 #pragma mark CommandObjectTargetModulesDumpSections
2076 
2077 // Image section dumping command
2078 
2079 class CommandObjectTargetModulesDumpSections
2080     : public CommandObjectTargetModulesModuleAutoComplete {
2081 public:
2082   CommandObjectTargetModulesDumpSections(CommandInterpreter &interpreter)
2083       : CommandObjectTargetModulesModuleAutoComplete(
2084             interpreter, "target modules dump sections",
2085             "Dump the sections from one or more target modules.",
2086             //"target modules dump sections [<file1> ...]")
2087             nullptr, eCommandRequiresTarget) {}
2088 
2089   ~CommandObjectTargetModulesDumpSections() override = default;
2090 
2091 protected:
2092   bool DoExecute(Args &command, CommandReturnObject &result) override {
2093     Target *target = &GetSelectedTarget();
2094     uint32_t num_dumped = 0;
2095 
2096     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2097     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2098     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2099 
2100     if (command.GetArgumentCount() == 0) {
2101       // Dump all sections for all modules images
2102       const size_t num_modules = target->GetImages().GetSize();
2103       if (num_modules == 0) {
2104         result.AppendError("the target has no associated executable images");
2105         return false;
2106       }
2107 
2108       result.GetOutputStream().Format("Dumping sections for {0} modules.\n",
2109                                       num_modules);
2110       for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2111         if (m_interpreter.WasInterrupted())
2112           break;
2113         num_dumped++;
2114         DumpModuleSections(
2115             m_interpreter, result.GetOutputStream(),
2116             target->GetImages().GetModulePointerAtIndex(image_idx));
2117       }
2118     } else {
2119       // Dump specified images (by basename or fullpath)
2120       const char *arg_cstr;
2121       for (int arg_idx = 0;
2122            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2123            ++arg_idx) {
2124         ModuleList module_list;
2125         const size_t num_matches =
2126             FindModulesByName(target, arg_cstr, module_list, true);
2127         if (num_matches > 0) {
2128           for (size_t i = 0; i < num_matches; ++i) {
2129             if (m_interpreter.WasInterrupted())
2130               break;
2131             Module *module = module_list.GetModulePointerAtIndex(i);
2132             if (module) {
2133               num_dumped++;
2134               DumpModuleSections(m_interpreter, result.GetOutputStream(),
2135                                  module);
2136             }
2137           }
2138         } else {
2139           // Check the global list
2140           std::lock_guard<std::recursive_mutex> guard(
2141               Module::GetAllocationModuleCollectionMutex());
2142 
2143           result.AppendWarningWithFormat(
2144               "Unable to find an image that matches '%s'.\n", arg_cstr);
2145         }
2146       }
2147     }
2148 
2149     if (num_dumped > 0)
2150       result.SetStatus(eReturnStatusSuccessFinishResult);
2151     else {
2152       result.AppendError("no matching executable images found");
2153     }
2154     return result.Succeeded();
2155   }
2156 };
2157 
2158 #pragma mark CommandObjectTargetModulesDumpClangAST
2159 
2160 // Clang AST dumping command
2161 
2162 class CommandObjectTargetModulesDumpClangAST
2163     : public CommandObjectTargetModulesModuleAutoComplete {
2164 public:
2165   CommandObjectTargetModulesDumpClangAST(CommandInterpreter &interpreter)
2166       : CommandObjectTargetModulesModuleAutoComplete(
2167             interpreter, "target modules dump ast",
2168             "Dump the clang ast for a given module's symbol file.",
2169             //"target modules dump ast [<file1> ...]")
2170             nullptr, eCommandRequiresTarget) {}
2171 
2172   ~CommandObjectTargetModulesDumpClangAST() override = default;
2173 
2174 protected:
2175   bool DoExecute(Args &command, CommandReturnObject &result) override {
2176     Target *target = &GetSelectedTarget();
2177 
2178     const ModuleList &module_list = target->GetImages();
2179     const size_t num_modules = module_list.GetSize();
2180     if (num_modules == 0) {
2181       result.AppendError("the target has no associated executable images");
2182       return false;
2183     }
2184 
2185     if (command.GetArgumentCount() == 0) {
2186       // Dump all ASTs for all modules images
2187       result.GetOutputStream().Format("Dumping clang ast for {0} modules.\n",
2188                                       num_modules);
2189       for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
2190         if (m_interpreter.WasInterrupted())
2191           break;
2192         if (SymbolFile *sf = module_sp->GetSymbolFile())
2193           sf->DumpClangAST(result.GetOutputStream());
2194       }
2195       result.SetStatus(eReturnStatusSuccessFinishResult);
2196       return true;
2197     }
2198 
2199     // Dump specified ASTs (by basename or fullpath)
2200     for (const Args::ArgEntry &arg : command.entries()) {
2201       ModuleList module_list;
2202       const size_t num_matches =
2203           FindModulesByName(target, arg.c_str(), module_list, true);
2204       if (num_matches == 0) {
2205         // Check the global list
2206         std::lock_guard<std::recursive_mutex> guard(
2207             Module::GetAllocationModuleCollectionMutex());
2208 
2209         result.AppendWarningWithFormat(
2210             "Unable to find an image that matches '%s'.\n", arg.c_str());
2211         continue;
2212       }
2213 
2214       for (size_t i = 0; i < num_matches; ++i) {
2215         if (m_interpreter.WasInterrupted())
2216           break;
2217         Module *m = module_list.GetModulePointerAtIndex(i);
2218         if (SymbolFile *sf = m->GetSymbolFile())
2219           sf->DumpClangAST(result.GetOutputStream());
2220       }
2221     }
2222     result.SetStatus(eReturnStatusSuccessFinishResult);
2223     return true;
2224   }
2225 };
2226 
2227 #pragma mark CommandObjectTargetModulesDumpSymfile
2228 
2229 // Image debug symbol dumping command
2230 
2231 class CommandObjectTargetModulesDumpSymfile
2232     : public CommandObjectTargetModulesModuleAutoComplete {
2233 public:
2234   CommandObjectTargetModulesDumpSymfile(CommandInterpreter &interpreter)
2235       : CommandObjectTargetModulesModuleAutoComplete(
2236             interpreter, "target modules dump symfile",
2237             "Dump the debug symbol file for one or more target modules.",
2238             //"target modules dump symfile [<file1> ...]")
2239             nullptr, eCommandRequiresTarget) {}
2240 
2241   ~CommandObjectTargetModulesDumpSymfile() override = default;
2242 
2243 protected:
2244   bool DoExecute(Args &command, CommandReturnObject &result) override {
2245     Target *target = &GetSelectedTarget();
2246     uint32_t num_dumped = 0;
2247 
2248     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2249     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2250     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2251 
2252     if (command.GetArgumentCount() == 0) {
2253       // Dump all sections for all modules images
2254       const ModuleList &target_modules = target->GetImages();
2255       std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2256       const size_t num_modules = target_modules.GetSize();
2257       if (num_modules == 0) {
2258         result.AppendError("the target has no associated executable images");
2259         return false;
2260       }
2261       result.GetOutputStream().Format(
2262           "Dumping debug symbols for {0} modules.\n", num_modules);
2263       for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
2264         if (m_interpreter.WasInterrupted())
2265           break;
2266         if (DumpModuleSymbolFile(result.GetOutputStream(), module_sp.get()))
2267           num_dumped++;
2268       }
2269     } else {
2270       // Dump specified images (by basename or fullpath)
2271       const char *arg_cstr;
2272       for (int arg_idx = 0;
2273            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2274            ++arg_idx) {
2275         ModuleList module_list;
2276         const size_t num_matches =
2277             FindModulesByName(target, arg_cstr, module_list, true);
2278         if (num_matches > 0) {
2279           for (size_t i = 0; i < num_matches; ++i) {
2280             if (m_interpreter.WasInterrupted())
2281               break;
2282             Module *module = module_list.GetModulePointerAtIndex(i);
2283             if (module) {
2284               if (DumpModuleSymbolFile(result.GetOutputStream(), module))
2285                 num_dumped++;
2286             }
2287           }
2288         } else
2289           result.AppendWarningWithFormat(
2290               "Unable to find an image that matches '%s'.\n", arg_cstr);
2291       }
2292     }
2293 
2294     if (num_dumped > 0)
2295       result.SetStatus(eReturnStatusSuccessFinishResult);
2296     else {
2297       result.AppendError("no matching executable images found");
2298     }
2299     return result.Succeeded();
2300   }
2301 };
2302 
2303 #pragma mark CommandObjectTargetModulesDumpLineTable
2304 #define LLDB_OPTIONS_target_modules_dump
2305 #include "CommandOptions.inc"
2306 
2307 // Image debug line table dumping command
2308 
2309 class CommandObjectTargetModulesDumpLineTable
2310     : public CommandObjectTargetModulesSourceFileAutoComplete {
2311 public:
2312   CommandObjectTargetModulesDumpLineTable(CommandInterpreter &interpreter)
2313       : CommandObjectTargetModulesSourceFileAutoComplete(
2314             interpreter, "target modules dump line-table",
2315             "Dump the line table for one or more compilation units.", nullptr,
2316             eCommandRequiresTarget) {}
2317 
2318   ~CommandObjectTargetModulesDumpLineTable() override = default;
2319 
2320   Options *GetOptions() override { return &m_options; }
2321 
2322 protected:
2323   bool DoExecute(Args &command, CommandReturnObject &result) override {
2324     Target *target = m_exe_ctx.GetTargetPtr();
2325     uint32_t total_num_dumped = 0;
2326 
2327     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2328     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2329     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2330 
2331     if (command.GetArgumentCount() == 0) {
2332       result.AppendError("file option must be specified.");
2333       return result.Succeeded();
2334     } else {
2335       // Dump specified images (by basename or fullpath)
2336       const char *arg_cstr;
2337       for (int arg_idx = 0;
2338            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2339            ++arg_idx) {
2340         FileSpec file_spec(arg_cstr);
2341 
2342         const ModuleList &target_modules = target->GetImages();
2343         std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2344         if (target_modules.GetSize() > 0) {
2345           uint32_t num_dumped = 0;
2346           for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
2347             if (m_interpreter.WasInterrupted())
2348               break;
2349             if (DumpCompileUnitLineTable(
2350                     m_interpreter, result.GetOutputStream(), module_sp.get(),
2351                     file_spec,
2352                     m_options.m_verbose ? eDescriptionLevelFull
2353                                         : eDescriptionLevelBrief))
2354               num_dumped++;
2355           }
2356           if (num_dumped == 0)
2357             result.AppendWarningWithFormat(
2358                 "No source filenames matched '%s'.\n", arg_cstr);
2359           else
2360             total_num_dumped += num_dumped;
2361         }
2362       }
2363     }
2364 
2365     if (total_num_dumped > 0)
2366       result.SetStatus(eReturnStatusSuccessFinishResult);
2367     else {
2368       result.AppendError("no source filenames matched any command arguments");
2369     }
2370     return result.Succeeded();
2371   }
2372 
2373   class CommandOptions : public Options {
2374   public:
2375     CommandOptions() { OptionParsingStarting(nullptr); }
2376 
2377     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2378                           ExecutionContext *execution_context) override {
2379       assert(option_idx == 0 && "We only have one option.");
2380       m_verbose = true;
2381 
2382       return Status();
2383     }
2384 
2385     void OptionParsingStarting(ExecutionContext *execution_context) override {
2386       m_verbose = false;
2387     }
2388 
2389     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2390       return llvm::makeArrayRef(g_target_modules_dump_options);
2391     }
2392 
2393     bool m_verbose;
2394   };
2395 
2396   CommandOptions m_options;
2397 };
2398 
2399 #pragma mark CommandObjectTargetModulesDump
2400 
2401 // Dump multi-word command for target modules
2402 
2403 class CommandObjectTargetModulesDump : public CommandObjectMultiword {
2404 public:
2405   // Constructors and Destructors
2406   CommandObjectTargetModulesDump(CommandInterpreter &interpreter)
2407       : CommandObjectMultiword(
2408             interpreter, "target modules dump",
2409             "Commands for dumping information about one or "
2410             "more target modules.",
2411             "target modules dump "
2412             "[headers|symtab|sections|ast|symfile|line-table] "
2413             "[<file1> <file2> ...]") {
2414     LoadSubCommand("objfile",
2415                    CommandObjectSP(
2416                        new CommandObjectTargetModulesDumpObjfile(interpreter)));
2417     LoadSubCommand(
2418         "symtab",
2419         CommandObjectSP(new CommandObjectTargetModulesDumpSymtab(interpreter)));
2420     LoadSubCommand("sections",
2421                    CommandObjectSP(new CommandObjectTargetModulesDumpSections(
2422                        interpreter)));
2423     LoadSubCommand("symfile",
2424                    CommandObjectSP(
2425                        new CommandObjectTargetModulesDumpSymfile(interpreter)));
2426     LoadSubCommand(
2427         "ast", CommandObjectSP(
2428                    new CommandObjectTargetModulesDumpClangAST(interpreter)));
2429     LoadSubCommand("line-table",
2430                    CommandObjectSP(new CommandObjectTargetModulesDumpLineTable(
2431                        interpreter)));
2432   }
2433 
2434   ~CommandObjectTargetModulesDump() override = default;
2435 };
2436 
2437 class CommandObjectTargetModulesAdd : public CommandObjectParsed {
2438 public:
2439   CommandObjectTargetModulesAdd(CommandInterpreter &interpreter)
2440       : CommandObjectParsed(interpreter, "target modules add",
2441                             "Add a new module to the current target's modules.",
2442                             "target modules add [<module>]",
2443                             eCommandRequiresTarget),
2444         m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
2445                       eArgTypeFilename,
2446                       "Fullpath to a stand alone debug "
2447                       "symbols file for when debug symbols "
2448                       "are not in the executable.") {
2449     m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2450                           LLDB_OPT_SET_1);
2451     m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2452     m_option_group.Finalize();
2453     CommandArgumentData module_arg{eArgTypePath, eArgRepeatStar};
2454     m_arguments.push_back({module_arg});
2455   }
2456 
2457   ~CommandObjectTargetModulesAdd() override = default;
2458 
2459   Options *GetOptions() override { return &m_option_group; }
2460 
2461   void
2462   HandleArgumentCompletion(CompletionRequest &request,
2463                            OptionElementVector &opt_element_vector) override {
2464     CommandCompletions::InvokeCommonCompletionCallbacks(
2465         GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
2466         request, nullptr);
2467   }
2468 
2469 protected:
2470   OptionGroupOptions m_option_group;
2471   OptionGroupUUID m_uuid_option_group;
2472   OptionGroupFile m_symbol_file;
2473 
2474   bool DoExecute(Args &args, CommandReturnObject &result) override {
2475     Target *target = &GetSelectedTarget();
2476     bool flush = false;
2477 
2478     const size_t argc = args.GetArgumentCount();
2479     if (argc == 0) {
2480       if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2481         // We are given a UUID only, go locate the file
2482         ModuleSpec module_spec;
2483         module_spec.GetUUID() =
2484             m_uuid_option_group.GetOptionValue().GetCurrentValue();
2485         if (m_symbol_file.GetOptionValue().OptionWasSet())
2486           module_spec.GetSymbolFileSpec() =
2487               m_symbol_file.GetOptionValue().GetCurrentValue();
2488         Status error;
2489         if (Symbols::DownloadObjectAndSymbolFile(module_spec, error)) {
2490           ModuleSP module_sp(
2491               target->GetOrCreateModule(module_spec, true /* notify */));
2492           if (module_sp) {
2493             result.SetStatus(eReturnStatusSuccessFinishResult);
2494             return true;
2495           } else {
2496             StreamString strm;
2497             module_spec.GetUUID().Dump(&strm);
2498             if (module_spec.GetFileSpec()) {
2499               if (module_spec.GetSymbolFileSpec()) {
2500                 result.AppendErrorWithFormat(
2501                     "Unable to create the executable or symbol file with "
2502                     "UUID %s with path %s and symbol file %s",
2503                     strm.GetData(), module_spec.GetFileSpec().GetPath().c_str(),
2504                     module_spec.GetSymbolFileSpec().GetPath().c_str());
2505               } else {
2506                 result.AppendErrorWithFormat(
2507                     "Unable to create the executable or symbol file with "
2508                     "UUID %s with path %s",
2509                     strm.GetData(),
2510                     module_spec.GetFileSpec().GetPath().c_str());
2511               }
2512             } else {
2513               result.AppendErrorWithFormat("Unable to create the executable "
2514                                            "or symbol file with UUID %s",
2515                                            strm.GetData());
2516             }
2517             return false;
2518           }
2519         } else {
2520           StreamString strm;
2521           module_spec.GetUUID().Dump(&strm);
2522           result.AppendErrorWithFormat(
2523               "Unable to locate the executable or symbol file with UUID %s",
2524               strm.GetData());
2525           result.SetError(error);
2526           return false;
2527         }
2528       } else {
2529         result.AppendError(
2530             "one or more executable image paths must be specified");
2531         return false;
2532       }
2533     } else {
2534       for (auto &entry : args.entries()) {
2535         if (entry.ref().empty())
2536           continue;
2537 
2538         FileSpec file_spec(entry.ref());
2539         if (FileSystem::Instance().Exists(file_spec)) {
2540           ModuleSpec module_spec(file_spec);
2541           if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2542             module_spec.GetUUID() =
2543                 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2544           if (m_symbol_file.GetOptionValue().OptionWasSet())
2545             module_spec.GetSymbolFileSpec() =
2546                 m_symbol_file.GetOptionValue().GetCurrentValue();
2547           if (!module_spec.GetArchitecture().IsValid())
2548             module_spec.GetArchitecture() = target->GetArchitecture();
2549           Status error;
2550           ModuleSP module_sp(target->GetOrCreateModule(
2551               module_spec, true /* notify */, &error));
2552           if (!module_sp) {
2553             const char *error_cstr = error.AsCString();
2554             if (error_cstr)
2555               result.AppendError(error_cstr);
2556             else
2557               result.AppendErrorWithFormat("unsupported module: %s",
2558                                            entry.c_str());
2559             return false;
2560           } else {
2561             flush = true;
2562           }
2563           result.SetStatus(eReturnStatusSuccessFinishResult);
2564         } else {
2565           std::string resolved_path = file_spec.GetPath();
2566           if (resolved_path != entry.ref()) {
2567             result.AppendErrorWithFormat(
2568                 "invalid module path '%s' with resolved path '%s'\n",
2569                 entry.ref().str().c_str(), resolved_path.c_str());
2570             break;
2571           }
2572           result.AppendErrorWithFormat("invalid module path '%s'\n",
2573                                        entry.c_str());
2574           break;
2575         }
2576       }
2577     }
2578 
2579     if (flush) {
2580       ProcessSP process = target->GetProcessSP();
2581       if (process)
2582         process->Flush();
2583     }
2584 
2585     return result.Succeeded();
2586   }
2587 };
2588 
2589 class CommandObjectTargetModulesLoad
2590     : public CommandObjectTargetModulesModuleAutoComplete {
2591 public:
2592   CommandObjectTargetModulesLoad(CommandInterpreter &interpreter)
2593       : CommandObjectTargetModulesModuleAutoComplete(
2594             interpreter, "target modules load",
2595             "Set the load addresses for one or more sections in a target "
2596             "module.",
2597             "target modules load [--file <module> --uuid <uuid>] <sect-name> "
2598             "<address> [<sect-name> <address> ....]",
2599             eCommandRequiresTarget),
2600         m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,
2601                       "Fullpath or basename for module to load.", ""),
2602         m_load_option(LLDB_OPT_SET_1, false, "load", 'l',
2603                       "Write file contents to the memory.", false, true),
2604         m_pc_option(LLDB_OPT_SET_1, false, "set-pc-to-entry", 'p',
2605                     "Set PC to the entry point."
2606                     " Only applicable with '--load' option.",
2607                     false, true),
2608         m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,
2609                        "Set the load address for all sections to be the "
2610                        "virtual address in the file plus the offset.",
2611                        0) {
2612     m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2613                           LLDB_OPT_SET_1);
2614     m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2615     m_option_group.Append(&m_load_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2616     m_option_group.Append(&m_pc_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2617     m_option_group.Append(&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2618     m_option_group.Finalize();
2619   }
2620 
2621   ~CommandObjectTargetModulesLoad() override = default;
2622 
2623   Options *GetOptions() override { return &m_option_group; }
2624 
2625 protected:
2626   bool DoExecute(Args &args, CommandReturnObject &result) override {
2627     Target *target = &GetSelectedTarget();
2628     const bool load = m_load_option.GetOptionValue().GetCurrentValue();
2629     const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue();
2630 
2631     const size_t argc = args.GetArgumentCount();
2632     ModuleSpec module_spec;
2633     bool search_using_module_spec = false;
2634 
2635     // Allow "load" option to work without --file or --uuid option.
2636     if (load) {
2637       if (!m_file_option.GetOptionValue().OptionWasSet() &&
2638           !m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2639         ModuleList &module_list = target->GetImages();
2640         if (module_list.GetSize() == 1) {
2641           search_using_module_spec = true;
2642           module_spec.GetFileSpec() =
2643               module_list.GetModuleAtIndex(0)->GetFileSpec();
2644         }
2645       }
2646     }
2647 
2648     if (m_file_option.GetOptionValue().OptionWasSet()) {
2649       search_using_module_spec = true;
2650       const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
2651       const bool use_global_module_list = true;
2652       ModuleList module_list;
2653       const size_t num_matches = FindModulesByName(
2654           target, arg_cstr, module_list, use_global_module_list);
2655       if (num_matches == 1) {
2656         module_spec.GetFileSpec() =
2657             module_list.GetModuleAtIndex(0)->GetFileSpec();
2658       } else if (num_matches > 1) {
2659         search_using_module_spec = false;
2660         result.AppendErrorWithFormat(
2661             "more than 1 module matched by name '%s'\n", arg_cstr);
2662       } else {
2663         search_using_module_spec = false;
2664         result.AppendErrorWithFormat("no object file for module '%s'\n",
2665                                      arg_cstr);
2666       }
2667     }
2668 
2669     if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2670       search_using_module_spec = true;
2671       module_spec.GetUUID() =
2672           m_uuid_option_group.GetOptionValue().GetCurrentValue();
2673     }
2674 
2675     if (search_using_module_spec) {
2676       ModuleList matching_modules;
2677       target->GetImages().FindModules(module_spec, matching_modules);
2678       const size_t num_matches = matching_modules.GetSize();
2679 
2680       char path[PATH_MAX];
2681       if (num_matches == 1) {
2682         Module *module = matching_modules.GetModulePointerAtIndex(0);
2683         if (module) {
2684           ObjectFile *objfile = module->GetObjectFile();
2685           if (objfile) {
2686             SectionList *section_list = module->GetSectionList();
2687             if (section_list) {
2688               bool changed = false;
2689               if (argc == 0) {
2690                 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2691                   const addr_t slide =
2692                       m_slide_option.GetOptionValue().GetCurrentValue();
2693                   const bool slide_is_offset = true;
2694                   module->SetLoadAddress(*target, slide, slide_is_offset,
2695                                          changed);
2696                 } else {
2697                   result.AppendError("one or more section name + load "
2698                                      "address pair must be specified");
2699                   return false;
2700                 }
2701               } else {
2702                 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2703                   result.AppendError("The \"--slide <offset>\" option can't "
2704                                      "be used in conjunction with setting "
2705                                      "section load addresses.\n");
2706                   return false;
2707                 }
2708 
2709                 for (size_t i = 0; i < argc; i += 2) {
2710                   const char *sect_name = args.GetArgumentAtIndex(i);
2711                   const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
2712                   if (sect_name && load_addr_cstr) {
2713                     ConstString const_sect_name(sect_name);
2714                     addr_t load_addr;
2715                     if (llvm::to_integer(load_addr_cstr, load_addr)) {
2716                       SectionSP section_sp(
2717                           section_list->FindSectionByName(const_sect_name));
2718                       if (section_sp) {
2719                         if (section_sp->IsThreadSpecific()) {
2720                           result.AppendErrorWithFormat(
2721                               "thread specific sections are not yet "
2722                               "supported (section '%s')\n",
2723                               sect_name);
2724                           break;
2725                         } else {
2726                           if (target->GetSectionLoadList()
2727                                   .SetSectionLoadAddress(section_sp, load_addr))
2728                             changed = true;
2729                           result.AppendMessageWithFormat(
2730                               "section '%s' loaded at 0x%" PRIx64 "\n",
2731                               sect_name, load_addr);
2732                         }
2733                       } else {
2734                         result.AppendErrorWithFormat("no section found that "
2735                                                      "matches the section "
2736                                                      "name '%s'\n",
2737                                                      sect_name);
2738                         break;
2739                       }
2740                     } else {
2741                       result.AppendErrorWithFormat(
2742                           "invalid load address string '%s'\n", load_addr_cstr);
2743                       break;
2744                     }
2745                   } else {
2746                     if (sect_name)
2747                       result.AppendError("section names must be followed by "
2748                                          "a load address.\n");
2749                     else
2750                       result.AppendError("one or more section name + load "
2751                                          "address pair must be specified.\n");
2752                     break;
2753                   }
2754                 }
2755               }
2756 
2757               if (changed) {
2758                 target->ModulesDidLoad(matching_modules);
2759                 Process *process = m_exe_ctx.GetProcessPtr();
2760                 if (process)
2761                   process->Flush();
2762               }
2763               if (load) {
2764                 ProcessSP process = target->CalculateProcess();
2765                 Address file_entry = objfile->GetEntryPointAddress();
2766                 if (!process) {
2767                   result.AppendError("No process");
2768                   return false;
2769                 }
2770                 if (set_pc && !file_entry.IsValid()) {
2771                   result.AppendError("No entry address in object file");
2772                   return false;
2773                 }
2774                 std::vector<ObjectFile::LoadableData> loadables(
2775                     objfile->GetLoadableData(*target));
2776                 if (loadables.size() == 0) {
2777                   result.AppendError("No loadable sections");
2778                   return false;
2779                 }
2780                 Status error = process->WriteObjectFile(std::move(loadables));
2781                 if (error.Fail()) {
2782                   result.AppendError(error.AsCString());
2783                   return false;
2784                 }
2785                 if (set_pc) {
2786                   ThreadList &thread_list = process->GetThreadList();
2787                   RegisterContextSP reg_context(
2788                       thread_list.GetSelectedThread()->GetRegisterContext());
2789                   addr_t file_entry_addr = file_entry.GetLoadAddress(target);
2790                   if (!reg_context->SetPC(file_entry_addr)) {
2791                     result.AppendErrorWithFormat("failed to set PC value to "
2792                                                  "0x%" PRIx64 "\n",
2793                                                  file_entry_addr);
2794                   }
2795                 }
2796               }
2797             } else {
2798               module->GetFileSpec().GetPath(path, sizeof(path));
2799               result.AppendErrorWithFormat("no sections in object file '%s'\n",
2800                                            path);
2801             }
2802           } else {
2803             module->GetFileSpec().GetPath(path, sizeof(path));
2804             result.AppendErrorWithFormat("no object file for module '%s'\n",
2805                                          path);
2806           }
2807         } else {
2808           FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
2809           if (module_spec_file) {
2810             module_spec_file->GetPath(path, sizeof(path));
2811             result.AppendErrorWithFormat("invalid module '%s'.\n", path);
2812           } else
2813             result.AppendError("no module spec");
2814         }
2815       } else {
2816         std::string uuid_str;
2817 
2818         if (module_spec.GetFileSpec())
2819           module_spec.GetFileSpec().GetPath(path, sizeof(path));
2820         else
2821           path[0] = '\0';
2822 
2823         if (module_spec.GetUUIDPtr())
2824           uuid_str = module_spec.GetUUID().GetAsString();
2825         if (num_matches > 1) {
2826           result.AppendErrorWithFormat(
2827               "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "",
2828               path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
2829           for (size_t i = 0; i < num_matches; ++i) {
2830             if (matching_modules.GetModulePointerAtIndex(i)
2831                     ->GetFileSpec()
2832                     .GetPath(path, sizeof(path)))
2833               result.AppendMessageWithFormat("%s\n", path);
2834           }
2835         } else {
2836           result.AppendErrorWithFormat(
2837               "no modules were found  that match%s%s%s%s.\n",
2838               path[0] ? " file=" : "", path, !uuid_str.empty() ? " uuid=" : "",
2839               uuid_str.c_str());
2840         }
2841       }
2842     } else {
2843       result.AppendError("either the \"--file <module>\" or the \"--uuid "
2844                          "<uuid>\" option must be specified.\n");
2845       return false;
2846     }
2847     return result.Succeeded();
2848   }
2849 
2850   OptionGroupOptions m_option_group;
2851   OptionGroupUUID m_uuid_option_group;
2852   OptionGroupString m_file_option;
2853   OptionGroupBoolean m_load_option;
2854   OptionGroupBoolean m_pc_option;
2855   OptionGroupUInt64 m_slide_option;
2856 };
2857 
2858 #pragma mark CommandObjectTargetModulesList
2859 // List images with associated information
2860 #define LLDB_OPTIONS_target_modules_list
2861 #include "CommandOptions.inc"
2862 
2863 class CommandObjectTargetModulesList : public CommandObjectParsed {
2864 public:
2865   class CommandOptions : public Options {
2866   public:
2867     CommandOptions() = default;
2868 
2869     ~CommandOptions() override = default;
2870 
2871     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2872                           ExecutionContext *execution_context) override {
2873       Status error;
2874 
2875       const int short_option = m_getopt_table[option_idx].val;
2876       if (short_option == 'g') {
2877         m_use_global_module_list = true;
2878       } else if (short_option == 'a') {
2879         m_module_addr = OptionArgParser::ToAddress(
2880             execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);
2881       } else {
2882         unsigned long width = 0;
2883         option_arg.getAsInteger(0, width);
2884         m_format_array.push_back(std::make_pair(short_option, width));
2885       }
2886       return error;
2887     }
2888 
2889     void OptionParsingStarting(ExecutionContext *execution_context) override {
2890       m_format_array.clear();
2891       m_use_global_module_list = false;
2892       m_module_addr = LLDB_INVALID_ADDRESS;
2893     }
2894 
2895     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2896       return llvm::makeArrayRef(g_target_modules_list_options);
2897     }
2898 
2899     // Instance variables to hold the values for command options.
2900     typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection;
2901     FormatWidthCollection m_format_array;
2902     bool m_use_global_module_list = false;
2903     lldb::addr_t m_module_addr = LLDB_INVALID_ADDRESS;
2904   };
2905 
2906   CommandObjectTargetModulesList(CommandInterpreter &interpreter)
2907       : CommandObjectParsed(
2908             interpreter, "target modules list",
2909             "List current executable and dependent shared library images.") {
2910     CommandArgumentData module_arg{eArgTypeShlibName, eArgRepeatStar};
2911     m_arguments.push_back({module_arg});
2912   }
2913 
2914   ~CommandObjectTargetModulesList() override = default;
2915 
2916   Options *GetOptions() override { return &m_options; }
2917 
2918 protected:
2919   bool DoExecute(Args &command, CommandReturnObject &result) override {
2920     Target *target = GetDebugger().GetSelectedTarget().get();
2921     const bool use_global_module_list = m_options.m_use_global_module_list;
2922     // Define a local module list here to ensure it lives longer than any
2923     // "locker" object which might lock its contents below (through the
2924     // "module_list_ptr" variable).
2925     ModuleList module_list;
2926     if (target == nullptr && !use_global_module_list) {
2927       result.AppendError("invalid target, create a debug target using the "
2928                          "'target create' command");
2929       return false;
2930     } else {
2931       if (target) {
2932         uint32_t addr_byte_size =
2933             target->GetArchitecture().GetAddressByteSize();
2934         result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2935         result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2936       }
2937       // Dump all sections for all modules images
2938       Stream &strm = result.GetOutputStream();
2939 
2940       if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) {
2941         if (target) {
2942           Address module_address;
2943           if (module_address.SetLoadAddress(m_options.m_module_addr, target)) {
2944             ModuleSP module_sp(module_address.GetModule());
2945             if (module_sp) {
2946               PrintModule(target, module_sp.get(), 0, strm);
2947               result.SetStatus(eReturnStatusSuccessFinishResult);
2948             } else {
2949               result.AppendErrorWithFormat(
2950                   "Couldn't find module matching address: 0x%" PRIx64 ".",
2951                   m_options.m_module_addr);
2952             }
2953           } else {
2954             result.AppendErrorWithFormat(
2955                 "Couldn't find module containing address: 0x%" PRIx64 ".",
2956                 m_options.m_module_addr);
2957           }
2958         } else {
2959           result.AppendError(
2960               "Can only look up modules by address with a valid target.");
2961         }
2962         return result.Succeeded();
2963       }
2964 
2965       size_t num_modules = 0;
2966 
2967       // This locker will be locked on the mutex in module_list_ptr if it is
2968       // non-nullptr. Otherwise it will lock the
2969       // AllocationModuleCollectionMutex when accessing the global module list
2970       // directly.
2971       std::unique_lock<std::recursive_mutex> guard(
2972           Module::GetAllocationModuleCollectionMutex(), std::defer_lock);
2973 
2974       const ModuleList *module_list_ptr = nullptr;
2975       const size_t argc = command.GetArgumentCount();
2976       if (argc == 0) {
2977         if (use_global_module_list) {
2978           guard.lock();
2979           num_modules = Module::GetNumberAllocatedModules();
2980         } else {
2981           module_list_ptr = &target->GetImages();
2982         }
2983       } else {
2984         for (const Args::ArgEntry &arg : command) {
2985           // Dump specified images (by basename or fullpath)
2986           const size_t num_matches = FindModulesByName(
2987               target, arg.c_str(), module_list, use_global_module_list);
2988           if (num_matches == 0) {
2989             if (argc == 1) {
2990               result.AppendErrorWithFormat("no modules found that match '%s'",
2991                                            arg.c_str());
2992               return false;
2993             }
2994           }
2995         }
2996 
2997         module_list_ptr = &module_list;
2998       }
2999 
3000       std::unique_lock<std::recursive_mutex> lock;
3001       if (module_list_ptr != nullptr) {
3002         lock =
3003             std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
3004 
3005         num_modules = module_list_ptr->GetSize();
3006       }
3007 
3008       if (num_modules > 0) {
3009         for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
3010           ModuleSP module_sp;
3011           Module *module;
3012           if (module_list_ptr) {
3013             module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
3014             module = module_sp.get();
3015           } else {
3016             module = Module::GetAllocatedModuleAtIndex(image_idx);
3017             module_sp = module->shared_from_this();
3018           }
3019 
3020           const size_t indent = strm.Printf("[%3u] ", image_idx);
3021           PrintModule(target, module, indent, strm);
3022         }
3023         result.SetStatus(eReturnStatusSuccessFinishResult);
3024       } else {
3025         if (argc) {
3026           if (use_global_module_list)
3027             result.AppendError(
3028                 "the global module list has no matching modules");
3029           else
3030             result.AppendError("the target has no matching modules");
3031         } else {
3032           if (use_global_module_list)
3033             result.AppendError("the global module list is empty");
3034           else
3035             result.AppendError(
3036                 "the target has no associated executable images");
3037         }
3038         return false;
3039       }
3040     }
3041     return result.Succeeded();
3042   }
3043 
3044   void PrintModule(Target *target, Module *module, int indent, Stream &strm) {
3045     if (module == nullptr) {
3046       strm.PutCString("Null module");
3047       return;
3048     }
3049 
3050     bool dump_object_name = false;
3051     if (m_options.m_format_array.empty()) {
3052       m_options.m_format_array.push_back(std::make_pair('u', 0));
3053       m_options.m_format_array.push_back(std::make_pair('h', 0));
3054       m_options.m_format_array.push_back(std::make_pair('f', 0));
3055       m_options.m_format_array.push_back(std::make_pair('S', 0));
3056     }
3057     const size_t num_entries = m_options.m_format_array.size();
3058     bool print_space = false;
3059     for (size_t i = 0; i < num_entries; ++i) {
3060       if (print_space)
3061         strm.PutChar(' ');
3062       print_space = true;
3063       const char format_char = m_options.m_format_array[i].first;
3064       uint32_t width = m_options.m_format_array[i].second;
3065       switch (format_char) {
3066       case 'A':
3067         DumpModuleArchitecture(strm, module, false, width);
3068         break;
3069 
3070       case 't':
3071         DumpModuleArchitecture(strm, module, true, width);
3072         break;
3073 
3074       case 'f':
3075         DumpFullpath(strm, &module->GetFileSpec(), width);
3076         dump_object_name = true;
3077         break;
3078 
3079       case 'd':
3080         DumpDirectory(strm, &module->GetFileSpec(), width);
3081         break;
3082 
3083       case 'b':
3084         DumpBasename(strm, &module->GetFileSpec(), width);
3085         dump_object_name = true;
3086         break;
3087 
3088       case 'h':
3089       case 'o':
3090         // Image header address
3091         {
3092           uint32_t addr_nibble_width =
3093               target ? (target->GetArchitecture().GetAddressByteSize() * 2)
3094                      : 16;
3095 
3096           ObjectFile *objfile = module->GetObjectFile();
3097           if (objfile) {
3098             Address base_addr(objfile->GetBaseAddress());
3099             if (base_addr.IsValid()) {
3100               if (target && !target->GetSectionLoadList().IsEmpty()) {
3101                 lldb::addr_t load_addr = base_addr.GetLoadAddress(target);
3102                 if (load_addr == LLDB_INVALID_ADDRESS) {
3103                   base_addr.Dump(&strm, target,
3104                                  Address::DumpStyleModuleWithFileAddress,
3105                                  Address::DumpStyleFileAddress);
3106                 } else {
3107                   if (format_char == 'o') {
3108                     // Show the offset of slide for the image
3109                     strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3110                                 addr_nibble_width,
3111                                 load_addr - base_addr.GetFileAddress());
3112                   } else {
3113                     // Show the load address of the image
3114                     strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3115                                 addr_nibble_width, load_addr);
3116                   }
3117                 }
3118                 break;
3119               }
3120               // The address was valid, but the image isn't loaded, output the
3121               // address in an appropriate format
3122               base_addr.Dump(&strm, target, Address::DumpStyleFileAddress);
3123               break;
3124             }
3125           }
3126           strm.Printf("%*s", addr_nibble_width + 2, "");
3127         }
3128         break;
3129 
3130       case 'r': {
3131         size_t ref_count = 0;
3132         ModuleSP module_sp(module->shared_from_this());
3133         if (module_sp) {
3134           // Take one away to make sure we don't count our local "module_sp"
3135           ref_count = module_sp.use_count() - 1;
3136         }
3137         if (width)
3138           strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count);
3139         else
3140           strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count);
3141       } break;
3142 
3143       case 's':
3144       case 'S': {
3145         if (const SymbolFile *symbol_file = module->GetSymbolFile()) {
3146           const FileSpec symfile_spec =
3147               symbol_file->GetObjectFile()->GetFileSpec();
3148           if (format_char == 'S') {
3149             // Dump symbol file only if different from module file
3150             if (!symfile_spec || symfile_spec == module->GetFileSpec()) {
3151               print_space = false;
3152               break;
3153             }
3154             // Add a newline and indent past the index
3155             strm.Printf("\n%*s", indent, "");
3156           }
3157           DumpFullpath(strm, &symfile_spec, width);
3158           dump_object_name = true;
3159           break;
3160         }
3161         strm.Printf("%.*s", width, "<NONE>");
3162       } break;
3163 
3164       case 'm':
3165         strm.Format("{0:%c}", llvm::fmt_align(module->GetModificationTime(),
3166                                               llvm::AlignStyle::Left, width));
3167         break;
3168 
3169       case 'p':
3170         strm.Printf("%p", static_cast<void *>(module));
3171         break;
3172 
3173       case 'u':
3174         DumpModuleUUID(strm, module);
3175         break;
3176 
3177       default:
3178         break;
3179       }
3180     }
3181     if (dump_object_name) {
3182       const char *object_name = module->GetObjectName().GetCString();
3183       if (object_name)
3184         strm.Printf("(%s)", object_name);
3185     }
3186     strm.EOL();
3187   }
3188 
3189   CommandOptions m_options;
3190 };
3191 
3192 #pragma mark CommandObjectTargetModulesShowUnwind
3193 
3194 // Lookup unwind information in images
3195 #define LLDB_OPTIONS_target_modules_show_unwind
3196 #include "CommandOptions.inc"
3197 
3198 class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
3199 public:
3200   enum {
3201     eLookupTypeInvalid = -1,
3202     eLookupTypeAddress = 0,
3203     eLookupTypeSymbol,
3204     eLookupTypeFunction,
3205     eLookupTypeFunctionOrSymbol,
3206     kNumLookupTypes
3207   };
3208 
3209   class CommandOptions : public Options {
3210   public:
3211     CommandOptions() = default;
3212 
3213     ~CommandOptions() override = default;
3214 
3215     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3216                           ExecutionContext *execution_context) override {
3217       Status error;
3218 
3219       const int short_option = m_getopt_table[option_idx].val;
3220 
3221       switch (short_option) {
3222       case 'a': {
3223         m_str = std::string(option_arg);
3224         m_type = eLookupTypeAddress;
3225         m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
3226                                             LLDB_INVALID_ADDRESS, &error);
3227         if (m_addr == LLDB_INVALID_ADDRESS)
3228           error.SetErrorStringWithFormat("invalid address string '%s'",
3229                                          option_arg.str().c_str());
3230         break;
3231       }
3232 
3233       case 'n':
3234         m_str = std::string(option_arg);
3235         m_type = eLookupTypeFunctionOrSymbol;
3236         break;
3237 
3238       default:
3239         llvm_unreachable("Unimplemented option");
3240       }
3241 
3242       return error;
3243     }
3244 
3245     void OptionParsingStarting(ExecutionContext *execution_context) override {
3246       m_type = eLookupTypeInvalid;
3247       m_str.clear();
3248       m_addr = LLDB_INVALID_ADDRESS;
3249     }
3250 
3251     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3252       return llvm::makeArrayRef(g_target_modules_show_unwind_options);
3253     }
3254 
3255     // Instance variables to hold the values for command options.
3256 
3257     int m_type = eLookupTypeInvalid; // Should be a eLookupTypeXXX enum after
3258                                      // parsing options
3259     std::string m_str; // Holds name lookup
3260     lldb::addr_t m_addr = LLDB_INVALID_ADDRESS; // Holds the address to lookup
3261   };
3262 
3263   CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter)
3264       : CommandObjectParsed(
3265             interpreter, "target modules show-unwind",
3266             "Show synthesized unwind instructions for a function.", nullptr,
3267             eCommandRequiresTarget | eCommandRequiresProcess |
3268                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
3269 
3270   ~CommandObjectTargetModulesShowUnwind() override = default;
3271 
3272   Options *GetOptions() override { return &m_options; }
3273 
3274 protected:
3275   bool DoExecute(Args &command, CommandReturnObject &result) override {
3276     Target *target = m_exe_ctx.GetTargetPtr();
3277     Process *process = m_exe_ctx.GetProcessPtr();
3278     ABI *abi = nullptr;
3279     if (process)
3280       abi = process->GetABI().get();
3281 
3282     if (process == nullptr) {
3283       result.AppendError(
3284           "You must have a process running to use this command.");
3285       return false;
3286     }
3287 
3288     ThreadList threads(process->GetThreadList());
3289     if (threads.GetSize() == 0) {
3290       result.AppendError("The process must be paused to use this command.");
3291       return false;
3292     }
3293 
3294     ThreadSP thread(threads.GetThreadAtIndex(0));
3295     if (!thread) {
3296       result.AppendError("The process must be paused to use this command.");
3297       return false;
3298     }
3299 
3300     SymbolContextList sc_list;
3301 
3302     if (m_options.m_type == eLookupTypeFunctionOrSymbol) {
3303       ConstString function_name(m_options.m_str.c_str());
3304       ModuleFunctionSearchOptions function_options;
3305       function_options.include_symbols = true;
3306       function_options.include_inlines = false;
3307       target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,
3308                                         function_options, sc_list);
3309     } else if (m_options.m_type == eLookupTypeAddress && target) {
3310       Address addr;
3311       if (target->GetSectionLoadList().ResolveLoadAddress(m_options.m_addr,
3312                                                           addr)) {
3313         SymbolContext sc;
3314         ModuleSP module_sp(addr.GetModule());
3315         module_sp->ResolveSymbolContextForAddress(addr,
3316                                                   eSymbolContextEverything, sc);
3317         if (sc.function || sc.symbol) {
3318           sc_list.Append(sc);
3319         }
3320       }
3321     } else {
3322       result.AppendError(
3323           "address-expression or function name option must be specified.");
3324       return false;
3325     }
3326 
3327     size_t num_matches = sc_list.GetSize();
3328     if (num_matches == 0) {
3329       result.AppendErrorWithFormat("no unwind data found that matches '%s'.",
3330                                    m_options.m_str.c_str());
3331       return false;
3332     }
3333 
3334     for (uint32_t idx = 0; idx < num_matches; idx++) {
3335       SymbolContext sc;
3336       sc_list.GetContextAtIndex(idx, sc);
3337       if (sc.symbol == nullptr && sc.function == nullptr)
3338         continue;
3339       if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
3340         continue;
3341       AddressRange range;
3342       if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
3343                               false, range))
3344         continue;
3345       if (!range.GetBaseAddress().IsValid())
3346         continue;
3347       ConstString funcname(sc.GetFunctionName());
3348       if (funcname.IsEmpty())
3349         continue;
3350       addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
3351       if (abi)
3352         start_addr = abi->FixCodeAddress(start_addr);
3353 
3354       FuncUnwindersSP func_unwinders_sp(
3355           sc.module_sp->GetUnwindTable()
3356               .GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
3357       if (!func_unwinders_sp)
3358         continue;
3359 
3360       result.GetOutputStream().Printf(
3361           "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n",
3362           sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(),
3363           funcname.AsCString(), start_addr);
3364 
3365       Args args;
3366       target->GetUserSpecifiedTrapHandlerNames(args);
3367       size_t count = args.GetArgumentCount();
3368       for (size_t i = 0; i < count; i++) {
3369         const char *trap_func_name = args.GetArgumentAtIndex(i);
3370         if (strcmp(funcname.GetCString(), trap_func_name) == 0)
3371           result.GetOutputStream().Printf(
3372               "This function is "
3373               "treated as a trap handler function via user setting.\n");
3374       }
3375       PlatformSP platform_sp(target->GetPlatform());
3376       if (platform_sp) {
3377         const std::vector<ConstString> trap_handler_names(
3378             platform_sp->GetTrapHandlerSymbolNames());
3379         for (ConstString trap_name : trap_handler_names) {
3380           if (trap_name == funcname) {
3381             result.GetOutputStream().Printf(
3382                 "This function's "
3383                 "name is listed by the platform as a trap handler.\n");
3384           }
3385         }
3386       }
3387 
3388       result.GetOutputStream().Printf("\n");
3389 
3390       UnwindPlanSP non_callsite_unwind_plan =
3391           func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread);
3392       if (non_callsite_unwind_plan) {
3393         result.GetOutputStream().Printf(
3394             "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
3395             non_callsite_unwind_plan->GetSourceName().AsCString());
3396       }
3397       UnwindPlanSP callsite_unwind_plan =
3398           func_unwinders_sp->GetUnwindPlanAtCallSite(*target, *thread);
3399       if (callsite_unwind_plan) {
3400         result.GetOutputStream().Printf(
3401             "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
3402             callsite_unwind_plan->GetSourceName().AsCString());
3403       }
3404       UnwindPlanSP fast_unwind_plan =
3405           func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
3406       if (fast_unwind_plan) {
3407         result.GetOutputStream().Printf(
3408             "Fast UnwindPlan is '%s'\n",
3409             fast_unwind_plan->GetSourceName().AsCString());
3410       }
3411 
3412       result.GetOutputStream().Printf("\n");
3413 
3414       UnwindPlanSP assembly_sp =
3415           func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread);
3416       if (assembly_sp) {
3417         result.GetOutputStream().Printf(
3418             "Assembly language inspection UnwindPlan:\n");
3419         assembly_sp->Dump(result.GetOutputStream(), thread.get(),
3420                           LLDB_INVALID_ADDRESS);
3421         result.GetOutputStream().Printf("\n");
3422       }
3423 
3424       UnwindPlanSP of_unwind_sp =
3425           func_unwinders_sp->GetObjectFileUnwindPlan(*target);
3426       if (of_unwind_sp) {
3427         result.GetOutputStream().Printf("object file UnwindPlan:\n");
3428         of_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3429                            LLDB_INVALID_ADDRESS);
3430         result.GetOutputStream().Printf("\n");
3431       }
3432 
3433       UnwindPlanSP of_unwind_augmented_sp =
3434           func_unwinders_sp->GetObjectFileAugmentedUnwindPlan(*target, *thread);
3435       if (of_unwind_augmented_sp) {
3436         result.GetOutputStream().Printf("object file augmented UnwindPlan:\n");
3437         of_unwind_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
3438                                      LLDB_INVALID_ADDRESS);
3439         result.GetOutputStream().Printf("\n");
3440       }
3441 
3442       UnwindPlanSP ehframe_sp =
3443           func_unwinders_sp->GetEHFrameUnwindPlan(*target);
3444       if (ehframe_sp) {
3445         result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3446         ehframe_sp->Dump(result.GetOutputStream(), thread.get(),
3447                          LLDB_INVALID_ADDRESS);
3448         result.GetOutputStream().Printf("\n");
3449       }
3450 
3451       UnwindPlanSP ehframe_augmented_sp =
3452           func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread);
3453       if (ehframe_augmented_sp) {
3454         result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3455         ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
3456                                    LLDB_INVALID_ADDRESS);
3457         result.GetOutputStream().Printf("\n");
3458       }
3459 
3460       if (UnwindPlanSP plan_sp =
3461               func_unwinders_sp->GetDebugFrameUnwindPlan(*target)) {
3462         result.GetOutputStream().Printf("debug_frame UnwindPlan:\n");
3463         plan_sp->Dump(result.GetOutputStream(), thread.get(),
3464                       LLDB_INVALID_ADDRESS);
3465         result.GetOutputStream().Printf("\n");
3466       }
3467 
3468       if (UnwindPlanSP plan_sp =
3469               func_unwinders_sp->GetDebugFrameAugmentedUnwindPlan(*target,
3470                                                                   *thread)) {
3471         result.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n");
3472         plan_sp->Dump(result.GetOutputStream(), thread.get(),
3473                       LLDB_INVALID_ADDRESS);
3474         result.GetOutputStream().Printf("\n");
3475       }
3476 
3477       UnwindPlanSP arm_unwind_sp =
3478           func_unwinders_sp->GetArmUnwindUnwindPlan(*target);
3479       if (arm_unwind_sp) {
3480         result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
3481         arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3482                             LLDB_INVALID_ADDRESS);
3483         result.GetOutputStream().Printf("\n");
3484       }
3485 
3486       if (UnwindPlanSP symfile_plan_sp =
3487               func_unwinders_sp->GetSymbolFileUnwindPlan(*thread)) {
3488         result.GetOutputStream().Printf("Symbol file UnwindPlan:\n");
3489         symfile_plan_sp->Dump(result.GetOutputStream(), thread.get(),
3490                               LLDB_INVALID_ADDRESS);
3491         result.GetOutputStream().Printf("\n");
3492       }
3493 
3494       UnwindPlanSP compact_unwind_sp =
3495           func_unwinders_sp->GetCompactUnwindUnwindPlan(*target);
3496       if (compact_unwind_sp) {
3497         result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3498         compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3499                                 LLDB_INVALID_ADDRESS);
3500         result.GetOutputStream().Printf("\n");
3501       }
3502 
3503       if (fast_unwind_plan) {
3504         result.GetOutputStream().Printf("Fast UnwindPlan:\n");
3505         fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(),
3506                                LLDB_INVALID_ADDRESS);
3507         result.GetOutputStream().Printf("\n");
3508       }
3509 
3510       ABISP abi_sp = process->GetABI();
3511       if (abi_sp) {
3512         UnwindPlan arch_default(lldb::eRegisterKindGeneric);
3513         if (abi_sp->CreateDefaultUnwindPlan(arch_default)) {
3514           result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3515           arch_default.Dump(result.GetOutputStream(), thread.get(),
3516                             LLDB_INVALID_ADDRESS);
3517           result.GetOutputStream().Printf("\n");
3518         }
3519 
3520         UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
3521         if (abi_sp->CreateFunctionEntryUnwindPlan(arch_entry)) {
3522           result.GetOutputStream().Printf(
3523               "Arch default at entry point UnwindPlan:\n");
3524           arch_entry.Dump(result.GetOutputStream(), thread.get(),
3525                           LLDB_INVALID_ADDRESS);
3526           result.GetOutputStream().Printf("\n");
3527         }
3528       }
3529 
3530       result.GetOutputStream().Printf("\n");
3531     }
3532     return result.Succeeded();
3533   }
3534 
3535   CommandOptions m_options;
3536 };
3537 
3538 // Lookup information in images
3539 #define LLDB_OPTIONS_target_modules_lookup
3540 #include "CommandOptions.inc"
3541 
3542 class CommandObjectTargetModulesLookup : public CommandObjectParsed {
3543 public:
3544   enum {
3545     eLookupTypeInvalid = -1,
3546     eLookupTypeAddress = 0,
3547     eLookupTypeSymbol,
3548     eLookupTypeFileLine, // Line is optional
3549     eLookupTypeFunction,
3550     eLookupTypeFunctionOrSymbol,
3551     eLookupTypeType,
3552     kNumLookupTypes
3553   };
3554 
3555   class CommandOptions : public Options {
3556   public:
3557     CommandOptions() { OptionParsingStarting(nullptr); }
3558 
3559     ~CommandOptions() override = default;
3560 
3561     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3562                           ExecutionContext *execution_context) override {
3563       Status error;
3564 
3565       const int short_option = m_getopt_table[option_idx].val;
3566 
3567       switch (short_option) {
3568       case 'a': {
3569         m_type = eLookupTypeAddress;
3570         m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
3571                                             LLDB_INVALID_ADDRESS, &error);
3572       } break;
3573 
3574       case 'o':
3575         if (option_arg.getAsInteger(0, m_offset))
3576           error.SetErrorStringWithFormat("invalid offset string '%s'",
3577                                          option_arg.str().c_str());
3578         break;
3579 
3580       case 's':
3581         m_str = std::string(option_arg);
3582         m_type = eLookupTypeSymbol;
3583         break;
3584 
3585       case 'f':
3586         m_file.SetFile(option_arg, FileSpec::Style::native);
3587         m_type = eLookupTypeFileLine;
3588         break;
3589 
3590       case 'i':
3591         m_include_inlines = false;
3592         break;
3593 
3594       case 'l':
3595         if (option_arg.getAsInteger(0, m_line_number))
3596           error.SetErrorStringWithFormat("invalid line number string '%s'",
3597                                          option_arg.str().c_str());
3598         else if (m_line_number == 0)
3599           error.SetErrorString("zero is an invalid line number");
3600         m_type = eLookupTypeFileLine;
3601         break;
3602 
3603       case 'F':
3604         m_str = std::string(option_arg);
3605         m_type = eLookupTypeFunction;
3606         break;
3607 
3608       case 'n':
3609         m_str = std::string(option_arg);
3610         m_type = eLookupTypeFunctionOrSymbol;
3611         break;
3612 
3613       case 't':
3614         m_str = std::string(option_arg);
3615         m_type = eLookupTypeType;
3616         break;
3617 
3618       case 'v':
3619         m_verbose = true;
3620         break;
3621 
3622       case 'A':
3623         m_print_all = true;
3624         break;
3625 
3626       case 'r':
3627         m_use_regex = true;
3628         break;
3629 
3630       case '\x01':
3631         m_all_ranges = true;
3632         break;
3633       default:
3634         llvm_unreachable("Unimplemented option");
3635       }
3636 
3637       return error;
3638     }
3639 
3640     void OptionParsingStarting(ExecutionContext *execution_context) override {
3641       m_type = eLookupTypeInvalid;
3642       m_str.clear();
3643       m_file.Clear();
3644       m_addr = LLDB_INVALID_ADDRESS;
3645       m_offset = 0;
3646       m_line_number = 0;
3647       m_use_regex = false;
3648       m_include_inlines = true;
3649       m_all_ranges = false;
3650       m_verbose = false;
3651       m_print_all = false;
3652     }
3653 
3654     Status OptionParsingFinished(ExecutionContext *execution_context) override {
3655       Status status;
3656       if (m_all_ranges && !m_verbose) {
3657         status.SetErrorString("--show-variable-ranges must be used in "
3658                               "conjunction with --verbose.");
3659       }
3660       return status;
3661     }
3662 
3663     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3664       return llvm::makeArrayRef(g_target_modules_lookup_options);
3665     }
3666 
3667     int m_type;        // Should be a eLookupTypeXXX enum after parsing options
3668     std::string m_str; // Holds name lookup
3669     FileSpec m_file;   // Files for file lookups
3670     lldb::addr_t m_addr; // Holds the address to lookup
3671     lldb::addr_t
3672         m_offset; // Subtract this offset from m_addr before doing lookups.
3673     uint32_t m_line_number; // Line number for file+line lookups
3674     bool m_use_regex;       // Name lookups in m_str are regular expressions.
3675     bool m_include_inlines; // Check for inline entries when looking up by
3676                             // file/line.
3677     bool m_all_ranges;      // Print all ranges or single range.
3678     bool m_verbose;         // Enable verbose lookup info
3679     bool m_print_all; // Print all matches, even in cases where there's a best
3680                       // match.
3681   };
3682 
3683   CommandObjectTargetModulesLookup(CommandInterpreter &interpreter)
3684       : CommandObjectParsed(interpreter, "target modules lookup",
3685                             "Look up information within executable and "
3686                             "dependent shared library images.",
3687                             nullptr, eCommandRequiresTarget) {
3688     CommandArgumentEntry arg;
3689     CommandArgumentData file_arg;
3690 
3691     // Define the first (and only) variant of this arg.
3692     file_arg.arg_type = eArgTypeFilename;
3693     file_arg.arg_repetition = eArgRepeatStar;
3694 
3695     // There is only one variant this argument could be; put it into the
3696     // argument entry.
3697     arg.push_back(file_arg);
3698 
3699     // Push the data for the first argument into the m_arguments vector.
3700     m_arguments.push_back(arg);
3701   }
3702 
3703   ~CommandObjectTargetModulesLookup() override = default;
3704 
3705   Options *GetOptions() override { return &m_options; }
3706 
3707   bool LookupHere(CommandInterpreter &interpreter, CommandReturnObject &result,
3708                   bool &syntax_error) {
3709     switch (m_options.m_type) {
3710     case eLookupTypeAddress:
3711     case eLookupTypeFileLine:
3712     case eLookupTypeFunction:
3713     case eLookupTypeFunctionOrSymbol:
3714     case eLookupTypeSymbol:
3715     default:
3716       return false;
3717     case eLookupTypeType:
3718       break;
3719     }
3720 
3721     StackFrameSP frame = m_exe_ctx.GetFrameSP();
3722 
3723     if (!frame)
3724       return false;
3725 
3726     const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
3727 
3728     if (!sym_ctx.module_sp)
3729       return false;
3730 
3731     switch (m_options.m_type) {
3732     default:
3733       return false;
3734     case eLookupTypeType:
3735       if (!m_options.m_str.empty()) {
3736         if (LookupTypeHere(&GetSelectedTarget(), m_interpreter,
3737                            result.GetOutputStream(), *sym_ctx.module_sp,
3738                            m_options.m_str.c_str(), m_options.m_use_regex)) {
3739           result.SetStatus(eReturnStatusSuccessFinishResult);
3740           return true;
3741         }
3742       }
3743       break;
3744     }
3745 
3746     return false;
3747   }
3748 
3749   bool LookupInModule(CommandInterpreter &interpreter, Module *module,
3750                       CommandReturnObject &result, bool &syntax_error) {
3751     switch (m_options.m_type) {
3752     case eLookupTypeAddress:
3753       if (m_options.m_addr != LLDB_INVALID_ADDRESS) {
3754         if (LookupAddressInModule(
3755                 m_interpreter, result.GetOutputStream(), module,
3756                 eSymbolContextEverything |
3757                     (m_options.m_verbose
3758                          ? static_cast<int>(eSymbolContextVariable)
3759                          : 0),
3760                 m_options.m_addr, m_options.m_offset, m_options.m_verbose,
3761                 m_options.m_all_ranges)) {
3762           result.SetStatus(eReturnStatusSuccessFinishResult);
3763           return true;
3764         }
3765       }
3766       break;
3767 
3768     case eLookupTypeSymbol:
3769       if (!m_options.m_str.empty()) {
3770         if (LookupSymbolInModule(m_interpreter, result.GetOutputStream(),
3771                                  module, m_options.m_str.c_str(),
3772                                  m_options.m_use_regex, m_options.m_verbose,
3773                                  m_options.m_all_ranges)) {
3774           result.SetStatus(eReturnStatusSuccessFinishResult);
3775           return true;
3776         }
3777       }
3778       break;
3779 
3780     case eLookupTypeFileLine:
3781       if (m_options.m_file) {
3782         if (LookupFileAndLineInModule(
3783                 m_interpreter, result.GetOutputStream(), module,
3784                 m_options.m_file, m_options.m_line_number,
3785                 m_options.m_include_inlines, m_options.m_verbose,
3786                 m_options.m_all_ranges)) {
3787           result.SetStatus(eReturnStatusSuccessFinishResult);
3788           return true;
3789         }
3790       }
3791       break;
3792 
3793     case eLookupTypeFunctionOrSymbol:
3794     case eLookupTypeFunction:
3795       if (!m_options.m_str.empty()) {
3796         ModuleFunctionSearchOptions function_options;
3797         function_options.include_symbols =
3798             m_options.m_type == eLookupTypeFunctionOrSymbol;
3799         function_options.include_inlines = m_options.m_include_inlines;
3800 
3801         if (LookupFunctionInModule(m_interpreter, result.GetOutputStream(),
3802                                    module, m_options.m_str.c_str(),
3803                                    m_options.m_use_regex, function_options,
3804                                    m_options.m_verbose,
3805                                    m_options.m_all_ranges)) {
3806           result.SetStatus(eReturnStatusSuccessFinishResult);
3807           return true;
3808         }
3809       }
3810       break;
3811 
3812     case eLookupTypeType:
3813       if (!m_options.m_str.empty()) {
3814         if (LookupTypeInModule(
3815                 &GetSelectedTarget(), m_interpreter, result.GetOutputStream(),
3816                 module, m_options.m_str.c_str(), m_options.m_use_regex)) {
3817           result.SetStatus(eReturnStatusSuccessFinishResult);
3818           return true;
3819         }
3820       }
3821       break;
3822 
3823     default:
3824       m_options.GenerateOptionUsage(
3825           result.GetErrorStream(), *this,
3826           GetCommandInterpreter().GetDebugger().GetTerminalWidth());
3827       syntax_error = true;
3828       break;
3829     }
3830 
3831     result.SetStatus(eReturnStatusFailed);
3832     return false;
3833   }
3834 
3835 protected:
3836   bool DoExecute(Args &command, CommandReturnObject &result) override {
3837     Target *target = &GetSelectedTarget();
3838     bool syntax_error = false;
3839     uint32_t i;
3840     uint32_t num_successful_lookups = 0;
3841     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3842     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3843     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3844     // Dump all sections for all modules images
3845 
3846     if (command.GetArgumentCount() == 0) {
3847       ModuleSP current_module;
3848 
3849       // Where it is possible to look in the current symbol context first,
3850       // try that.  If this search was successful and --all was not passed,
3851       // don't print anything else.
3852       if (LookupHere(m_interpreter, result, syntax_error)) {
3853         result.GetOutputStream().EOL();
3854         num_successful_lookups++;
3855         if (!m_options.m_print_all) {
3856           result.SetStatus(eReturnStatusSuccessFinishResult);
3857           return result.Succeeded();
3858         }
3859       }
3860 
3861       // Dump all sections for all other modules
3862 
3863       const ModuleList &target_modules = target->GetImages();
3864       std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
3865       if (target_modules.GetSize() == 0) {
3866         result.AppendError("the target has no associated executable images");
3867         return false;
3868       }
3869 
3870       for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
3871         if (module_sp != current_module &&
3872             LookupInModule(m_interpreter, module_sp.get(), result,
3873                            syntax_error)) {
3874           result.GetOutputStream().EOL();
3875           num_successful_lookups++;
3876         }
3877       }
3878     } else {
3879       // Dump specified images (by basename or fullpath)
3880       const char *arg_cstr;
3881       for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
3882                   !syntax_error;
3883            ++i) {
3884         ModuleList module_list;
3885         const size_t num_matches =
3886             FindModulesByName(target, arg_cstr, module_list, false);
3887         if (num_matches > 0) {
3888           for (size_t j = 0; j < num_matches; ++j) {
3889             Module *module = module_list.GetModulePointerAtIndex(j);
3890             if (module) {
3891               if (LookupInModule(m_interpreter, module, result, syntax_error)) {
3892                 result.GetOutputStream().EOL();
3893                 num_successful_lookups++;
3894               }
3895             }
3896           }
3897         } else
3898           result.AppendWarningWithFormat(
3899               "Unable to find an image that matches '%s'.\n", arg_cstr);
3900       }
3901     }
3902 
3903     if (num_successful_lookups > 0)
3904       result.SetStatus(eReturnStatusSuccessFinishResult);
3905     else
3906       result.SetStatus(eReturnStatusFailed);
3907     return result.Succeeded();
3908   }
3909 
3910   CommandOptions m_options;
3911 };
3912 
3913 #pragma mark CommandObjectMultiwordImageSearchPaths
3914 
3915 // CommandObjectMultiwordImageSearchPaths
3916 
3917 class CommandObjectTargetModulesImageSearchPaths
3918     : public CommandObjectMultiword {
3919 public:
3920   CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
3921       : CommandObjectMultiword(
3922             interpreter, "target modules search-paths",
3923             "Commands for managing module search paths for a target.",
3924             "target modules search-paths <subcommand> [<subcommand-options>]") {
3925     LoadSubCommand(
3926         "add", CommandObjectSP(
3927                    new CommandObjectTargetModulesSearchPathsAdd(interpreter)));
3928     LoadSubCommand(
3929         "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear(
3930                      interpreter)));
3931     LoadSubCommand(
3932         "insert",
3933         CommandObjectSP(
3934             new CommandObjectTargetModulesSearchPathsInsert(interpreter)));
3935     LoadSubCommand(
3936         "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList(
3937                     interpreter)));
3938     LoadSubCommand(
3939         "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery(
3940                      interpreter)));
3941   }
3942 
3943   ~CommandObjectTargetModulesImageSearchPaths() override = default;
3944 };
3945 
3946 #pragma mark CommandObjectTargetModules
3947 
3948 // CommandObjectTargetModules
3949 
3950 class CommandObjectTargetModules : public CommandObjectMultiword {
3951 public:
3952   // Constructors and Destructors
3953   CommandObjectTargetModules(CommandInterpreter &interpreter)
3954       : CommandObjectMultiword(interpreter, "target modules",
3955                                "Commands for accessing information for one or "
3956                                "more target modules.",
3957                                "target modules <sub-command> ...") {
3958     LoadSubCommand(
3959         "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter)));
3960     LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad(
3961                                interpreter)));
3962     LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump(
3963                                interpreter)));
3964     LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList(
3965                                interpreter)));
3966     LoadSubCommand(
3967         "lookup",
3968         CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter)));
3969     LoadSubCommand(
3970         "search-paths",
3971         CommandObjectSP(
3972             new CommandObjectTargetModulesImageSearchPaths(interpreter)));
3973     LoadSubCommand(
3974         "show-unwind",
3975         CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter)));
3976   }
3977 
3978   ~CommandObjectTargetModules() override = default;
3979 
3980 private:
3981   // For CommandObjectTargetModules only
3982   CommandObjectTargetModules(const CommandObjectTargetModules &) = delete;
3983   const CommandObjectTargetModules &
3984   operator=(const CommandObjectTargetModules &) = delete;
3985 };
3986 
3987 class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
3988 public:
3989   CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter)
3990       : CommandObjectParsed(
3991             interpreter, "target symbols add",
3992             "Add a debug symbol file to one of the target's current modules by "
3993             "specifying a path to a debug symbols file or by using the options "
3994             "to specify a module.",
3995             "target symbols add <cmd-options> [<symfile>]",
3996             eCommandRequiresTarget),
3997         m_file_option(
3998             LLDB_OPT_SET_1, false, "shlib", 's',
3999             CommandCompletions::eModuleCompletion, eArgTypeShlibName,
4000             "Locate the debug symbols for the shared library specified by "
4001             "name."),
4002         m_current_frame_option(
4003             LLDB_OPT_SET_2, false, "frame", 'F',
4004             "Locate the debug symbols for the currently selected frame.", false,
4005             true),
4006         m_current_stack_option(LLDB_OPT_SET_2, false, "stack", 'S',
4007                                "Locate the debug symbols for every frame in "
4008                                "the current call stack.",
4009                                false, true)
4010 
4011   {
4012     m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
4013                           LLDB_OPT_SET_1);
4014     m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
4015     m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2,
4016                           LLDB_OPT_SET_2);
4017     m_option_group.Append(&m_current_stack_option, LLDB_OPT_SET_2,
4018                           LLDB_OPT_SET_2);
4019     m_option_group.Finalize();
4020     CommandArgumentData module_arg{eArgTypeShlibName, eArgRepeatPlain};
4021     m_arguments.push_back({module_arg});
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     CommandArgumentData hook_arg{eArgTypeStopHookID, eArgRepeatStar};
4872     m_arguments.push_back({hook_arg});
4873   }
4874 
4875   ~CommandObjectTargetStopHookDelete() override = default;
4876 
4877   void
4878   HandleArgumentCompletion(CompletionRequest &request,
4879                            OptionElementVector &opt_element_vector) override {
4880     CommandCompletions::InvokeCommonCompletionCallbacks(
4881         GetCommandInterpreter(), CommandCompletions::eStopHookIDCompletion,
4882         request, nullptr);
4883   }
4884 
4885 protected:
4886   bool DoExecute(Args &command, CommandReturnObject &result) override {
4887     Target &target = GetSelectedOrDummyTarget();
4888     // FIXME: see if we can use the breakpoint id style parser?
4889     size_t num_args = command.GetArgumentCount();
4890     if (num_args == 0) {
4891       if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
4892         result.SetStatus(eReturnStatusFailed);
4893         return false;
4894       } else {
4895         target.RemoveAllStopHooks();
4896       }
4897     } else {
4898       for (size_t i = 0; i < num_args; i++) {
4899         lldb::user_id_t user_id;
4900         if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
4901           result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4902                                        command.GetArgumentAtIndex(i));
4903           return false;
4904         }
4905         if (!target.RemoveStopHookByID(user_id)) {
4906           result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4907                                        command.GetArgumentAtIndex(i));
4908           return false;
4909         }
4910       }
4911     }
4912     result.SetStatus(eReturnStatusSuccessFinishNoResult);
4913     return result.Succeeded();
4914   }
4915 };
4916 
4917 #pragma mark CommandObjectTargetStopHookEnableDisable
4918 
4919 // CommandObjectTargetStopHookEnableDisable
4920 
4921 class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed {
4922 public:
4923   CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter,
4924                                            bool enable, const char *name,
4925                                            const char *help, const char *syntax)
4926       : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) {
4927     CommandArgumentData hook_arg{eArgTypeStopHookID, eArgRepeatStar};
4928     m_arguments.push_back({hook_arg});
4929   }
4930 
4931   ~CommandObjectTargetStopHookEnableDisable() override = default;
4932 
4933   void
4934   HandleArgumentCompletion(CompletionRequest &request,
4935                            OptionElementVector &opt_element_vector) override {
4936     if (request.GetCursorIndex())
4937       return;
4938     CommandCompletions::InvokeCommonCompletionCallbacks(
4939         GetCommandInterpreter(), CommandCompletions::eStopHookIDCompletion,
4940         request, nullptr);
4941   }
4942 
4943 protected:
4944   bool DoExecute(Args &command, CommandReturnObject &result) override {
4945     Target &target = GetSelectedOrDummyTarget();
4946     // FIXME: see if we can use the breakpoint id style parser?
4947     size_t num_args = command.GetArgumentCount();
4948     bool success;
4949 
4950     if (num_args == 0) {
4951       target.SetAllStopHooksActiveState(m_enable);
4952     } else {
4953       for (size_t i = 0; i < num_args; i++) {
4954         lldb::user_id_t user_id;
4955         if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
4956           result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4957                                        command.GetArgumentAtIndex(i));
4958           return false;
4959         }
4960         success = target.SetStopHookActiveStateByID(user_id, m_enable);
4961         if (!success) {
4962           result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4963                                        command.GetArgumentAtIndex(i));
4964           return false;
4965         }
4966       }
4967     }
4968     result.SetStatus(eReturnStatusSuccessFinishNoResult);
4969     return result.Succeeded();
4970   }
4971 
4972 private:
4973   bool m_enable;
4974 };
4975 
4976 #pragma mark CommandObjectTargetStopHookList
4977 
4978 // CommandObjectTargetStopHookList
4979 
4980 class CommandObjectTargetStopHookList : public CommandObjectParsed {
4981 public:
4982   CommandObjectTargetStopHookList(CommandInterpreter &interpreter)
4983       : CommandObjectParsed(interpreter, "target stop-hook list",
4984                             "List all stop-hooks.", "target stop-hook list") {}
4985 
4986   ~CommandObjectTargetStopHookList() override = default;
4987 
4988 protected:
4989   bool DoExecute(Args &command, CommandReturnObject &result) override {
4990     Target &target = GetSelectedOrDummyTarget();
4991 
4992     size_t num_hooks = target.GetNumStopHooks();
4993     if (num_hooks == 0) {
4994       result.GetOutputStream().PutCString("No stop hooks.\n");
4995     } else {
4996       for (size_t i = 0; i < num_hooks; i++) {
4997         Target::StopHookSP this_hook = target.GetStopHookAtIndex(i);
4998         if (i > 0)
4999           result.GetOutputStream().PutCString("\n");
5000         this_hook->GetDescription(&(result.GetOutputStream()),
5001                                   eDescriptionLevelFull);
5002       }
5003     }
5004     result.SetStatus(eReturnStatusSuccessFinishResult);
5005     return result.Succeeded();
5006   }
5007 };
5008 
5009 #pragma mark CommandObjectMultiwordTargetStopHooks
5010 
5011 // CommandObjectMultiwordTargetStopHooks
5012 
5013 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword {
5014 public:
5015   CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
5016       : CommandObjectMultiword(
5017             interpreter, "target stop-hook",
5018             "Commands for operating on debugger target stop-hooks.",
5019             "target stop-hook <subcommand> [<subcommand-options>]") {
5020     LoadSubCommand("add", CommandObjectSP(
5021                               new CommandObjectTargetStopHookAdd(interpreter)));
5022     LoadSubCommand(
5023         "delete",
5024         CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter)));
5025     LoadSubCommand("disable",
5026                    CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
5027                        interpreter, false, "target stop-hook disable [<id>]",
5028                        "Disable a stop-hook.", "target stop-hook disable")));
5029     LoadSubCommand("enable",
5030                    CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
5031                        interpreter, true, "target stop-hook enable [<id>]",
5032                        "Enable a stop-hook.", "target stop-hook enable")));
5033     LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList(
5034                                interpreter)));
5035   }
5036 
5037   ~CommandObjectMultiwordTargetStopHooks() override = default;
5038 };
5039 
5040 #pragma mark CommandObjectTargetDumpTypesystem
5041 
5042 /// Dumps the TypeSystem of the selected Target.
5043 class CommandObjectTargetDumpTypesystem : public CommandObjectParsed {
5044 public:
5045   CommandObjectTargetDumpTypesystem(CommandInterpreter &interpreter)
5046       : CommandObjectParsed(
5047             interpreter, "target dump typesystem",
5048             "Dump the state of the target's internal type system.\n"
5049             "Intended to be used for debugging LLDB itself.",
5050             nullptr, eCommandRequiresTarget) {}
5051 
5052   ~CommandObjectTargetDumpTypesystem() override = default;
5053 
5054 protected:
5055   bool DoExecute(Args &command, CommandReturnObject &result) override {
5056     // Go over every scratch TypeSystem and dump to the command output.
5057     for (TypeSystem *ts : GetSelectedTarget().GetScratchTypeSystems())
5058       ts->Dump(result.GetOutputStream().AsRawOstream());
5059 
5060     result.SetStatus(eReturnStatusSuccessFinishResult);
5061     return result.Succeeded();
5062   }
5063 };
5064 
5065 #pragma mark CommandObjectTargetDump
5066 
5067 /// Multi-word command for 'target dump'.
5068 class CommandObjectTargetDump : public CommandObjectMultiword {
5069 public:
5070   // Constructors and Destructors
5071   CommandObjectTargetDump(CommandInterpreter &interpreter)
5072       : CommandObjectMultiword(
5073             interpreter, "target dump",
5074             "Commands for dumping information about the target.",
5075             "target dump [typesystem]") {
5076     LoadSubCommand(
5077         "typesystem",
5078         CommandObjectSP(new CommandObjectTargetDumpTypesystem(interpreter)));
5079   }
5080 
5081   ~CommandObjectTargetDump() override = default;
5082 };
5083 
5084 #pragma mark CommandObjectMultiwordTarget
5085 
5086 // CommandObjectMultiwordTarget
5087 
5088 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(
5089     CommandInterpreter &interpreter)
5090     : CommandObjectMultiword(interpreter, "target",
5091                              "Commands for operating on debugger targets.",
5092                              "target <subcommand> [<subcommand-options>]") {
5093   LoadSubCommand("create",
5094                  CommandObjectSP(new CommandObjectTargetCreate(interpreter)));
5095   LoadSubCommand("delete",
5096                  CommandObjectSP(new CommandObjectTargetDelete(interpreter)));
5097   LoadSubCommand("dump",
5098                  CommandObjectSP(new CommandObjectTargetDump(interpreter)));
5099   LoadSubCommand("list",
5100                  CommandObjectSP(new CommandObjectTargetList(interpreter)));
5101   LoadSubCommand("select",
5102                  CommandObjectSP(new CommandObjectTargetSelect(interpreter)));
5103   LoadSubCommand("show-launch-environment",
5104                  CommandObjectSP(new CommandObjectTargetShowLaunchEnvironment(
5105                      interpreter)));
5106   LoadSubCommand(
5107       "stop-hook",
5108       CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter)));
5109   LoadSubCommand("modules",
5110                  CommandObjectSP(new CommandObjectTargetModules(interpreter)));
5111   LoadSubCommand("symbols",
5112                  CommandObjectSP(new CommandObjectTargetSymbols(interpreter)));
5113   LoadSubCommand("variable",
5114                  CommandObjectSP(new CommandObjectTargetVariable(interpreter)));
5115 }
5116 
5117 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;
5118