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