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