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