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                                      const ModuleFunctionSearchOptions &options,
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, options, sc_list);
1581     } else {
1582       ConstString function_name(name);
1583       module->FindFunctions(function_name, CompilerDeclContext(),
1584                             eFunctionNameTypeAuto, options, sc_list);
1585     }
1586     num_matches = sc_list.GetSize();
1587     if (num_matches) {
1588       strm.Indent();
1589       strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1590                   num_matches > 1 ? "es" : "");
1591       DumpFullpath(strm, &module->GetFileSpec(), 0);
1592       strm.PutCString(":\n");
1593       DumpSymbolContextList(
1594           interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1595           strm, sc_list, verbose);
1596     }
1597     return num_matches;
1598   }
1599   return 0;
1600 }
1601 
1602 static size_t LookupTypeInModule(Target *target,
1603                                  CommandInterpreter &interpreter, Stream &strm,
1604                                  Module *module, const char *name_cstr,
1605                                  bool name_is_regex) {
1606   TypeList type_list;
1607   if (module && name_cstr && name_cstr[0]) {
1608     const uint32_t max_num_matches = UINT32_MAX;
1609     size_t num_matches = 0;
1610     bool name_is_fully_qualified = false;
1611 
1612     ConstString name(name_cstr);
1613     llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
1614     module->FindTypes(name, name_is_fully_qualified, max_num_matches,
1615                       searched_symbol_files, type_list);
1616 
1617     if (type_list.Empty())
1618       return 0;
1619 
1620     strm.Indent();
1621     strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1622                 num_matches > 1 ? "es" : "");
1623     DumpFullpath(strm, &module->GetFileSpec(), 0);
1624     strm.PutCString(":\n");
1625     for (TypeSP type_sp : type_list.Types()) {
1626       if (!type_sp)
1627         continue;
1628       // Resolve the clang type so that any forward references to types
1629       // that haven't yet been parsed will get parsed.
1630       type_sp->GetFullCompilerType();
1631       type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
1632       // Print all typedef chains
1633       TypeSP typedef_type_sp(type_sp);
1634       TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1635       while (typedefed_type_sp) {
1636         strm.EOL();
1637         strm.Printf("     typedef '%s': ",
1638                     typedef_type_sp->GetName().GetCString());
1639         typedefed_type_sp->GetFullCompilerType();
1640         typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
1641                                           target);
1642         typedef_type_sp = typedefed_type_sp;
1643         typedefed_type_sp = typedef_type_sp->GetTypedefType();
1644       }
1645     }
1646     strm.EOL();
1647   }
1648   return type_list.GetSize();
1649 }
1650 
1651 static size_t LookupTypeHere(Target *target, CommandInterpreter &interpreter,
1652                              Stream &strm, Module &module,
1653                              const char *name_cstr, bool name_is_regex) {
1654   TypeList type_list;
1655   const uint32_t max_num_matches = UINT32_MAX;
1656   bool name_is_fully_qualified = false;
1657 
1658   ConstString name(name_cstr);
1659   llvm::DenseSet<SymbolFile *> searched_symbol_files;
1660   module.FindTypes(name, name_is_fully_qualified, max_num_matches,
1661                    searched_symbol_files, type_list);
1662 
1663   if (type_list.Empty())
1664     return 0;
1665 
1666   strm.Indent();
1667   strm.PutCString("Best match found in ");
1668   DumpFullpath(strm, &module.GetFileSpec(), 0);
1669   strm.PutCString(":\n");
1670 
1671   TypeSP type_sp(type_list.GetTypeAtIndex(0));
1672   if (type_sp) {
1673     // Resolve the clang type so that any forward references to types that
1674     // haven't yet been parsed will get parsed.
1675     type_sp->GetFullCompilerType();
1676     type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
1677     // Print all typedef chains.
1678     TypeSP typedef_type_sp(type_sp);
1679     TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1680     while (typedefed_type_sp) {
1681       strm.EOL();
1682       strm.Printf("     typedef '%s': ",
1683                   typedef_type_sp->GetName().GetCString());
1684       typedefed_type_sp->GetFullCompilerType();
1685       typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
1686                                         target);
1687       typedef_type_sp = typedefed_type_sp;
1688       typedefed_type_sp = typedef_type_sp->GetTypedefType();
1689     }
1690   }
1691   strm.EOL();
1692   return type_list.GetSize();
1693 }
1694 
1695 static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter,
1696                                           Stream &strm, Module *module,
1697                                           const FileSpec &file_spec,
1698                                           uint32_t line, bool check_inlines,
1699                                           bool verbose) {
1700   if (module && file_spec) {
1701     SymbolContextList sc_list;
1702     const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(
1703         file_spec, line, check_inlines, eSymbolContextEverything, sc_list);
1704     if (num_matches > 0) {
1705       strm.Indent();
1706       strm.Printf("%u match%s found in ", num_matches,
1707                   num_matches > 1 ? "es" : "");
1708       strm << file_spec;
1709       if (line > 0)
1710         strm.Printf(":%u", line);
1711       strm << " in ";
1712       DumpFullpath(strm, &module->GetFileSpec(), 0);
1713       strm.PutCString(":\n");
1714       DumpSymbolContextList(
1715           interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1716           strm, sc_list, verbose);
1717       return num_matches;
1718     }
1719   }
1720   return 0;
1721 }
1722 
1723 static size_t FindModulesByName(Target *target, const char *module_name,
1724                                 ModuleList &module_list,
1725                                 bool check_global_list) {
1726   FileSpec module_file_spec(module_name);
1727   ModuleSpec module_spec(module_file_spec);
1728 
1729   const size_t initial_size = module_list.GetSize();
1730 
1731   if (check_global_list) {
1732     // Check the global list
1733     std::lock_guard<std::recursive_mutex> guard(
1734         Module::GetAllocationModuleCollectionMutex());
1735     const size_t num_modules = Module::GetNumberAllocatedModules();
1736     ModuleSP module_sp;
1737     for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1738       Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
1739 
1740       if (module) {
1741         if (module->MatchesModuleSpec(module_spec)) {
1742           module_sp = module->shared_from_this();
1743           module_list.AppendIfNeeded(module_sp);
1744         }
1745       }
1746     }
1747   } else {
1748     if (target) {
1749       target->GetImages().FindModules(module_spec, module_list);
1750       const size_t num_matches = module_list.GetSize();
1751 
1752       // Not found in our module list for our target, check the main shared
1753       // module list in case it is a extra file used somewhere else
1754       if (num_matches == 0) {
1755         module_spec.GetArchitecture() = target->GetArchitecture();
1756         ModuleList::FindSharedModules(module_spec, module_list);
1757       }
1758     } else {
1759       ModuleList::FindSharedModules(module_spec, module_list);
1760     }
1761   }
1762 
1763   return module_list.GetSize() - initial_size;
1764 }
1765 
1766 #pragma mark CommandObjectTargetModulesModuleAutoComplete
1767 
1768 // A base command object class that can auto complete with module file
1769 // paths
1770 
1771 class CommandObjectTargetModulesModuleAutoComplete
1772     : public CommandObjectParsed {
1773 public:
1774   CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter,
1775                                                const char *name,
1776                                                const char *help,
1777                                                const char *syntax,
1778                                                uint32_t flags = 0)
1779       : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1780     CommandArgumentEntry arg;
1781     CommandArgumentData file_arg;
1782 
1783     // Define the first (and only) variant of this arg.
1784     file_arg.arg_type = eArgTypeFilename;
1785     file_arg.arg_repetition = eArgRepeatStar;
1786 
1787     // There is only one variant this argument could be; put it into the
1788     // argument entry.
1789     arg.push_back(file_arg);
1790 
1791     // Push the data for the first argument into the m_arguments vector.
1792     m_arguments.push_back(arg);
1793   }
1794 
1795   ~CommandObjectTargetModulesModuleAutoComplete() override = default;
1796 
1797   void
1798   HandleArgumentCompletion(CompletionRequest &request,
1799                            OptionElementVector &opt_element_vector) override {
1800     CommandCompletions::InvokeCommonCompletionCallbacks(
1801         GetCommandInterpreter(), CommandCompletions::eModuleCompletion, request,
1802         nullptr);
1803   }
1804 };
1805 
1806 #pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1807 
1808 // A base command object class that can auto complete with module source
1809 // file paths
1810 
1811 class CommandObjectTargetModulesSourceFileAutoComplete
1812     : public CommandObjectParsed {
1813 public:
1814   CommandObjectTargetModulesSourceFileAutoComplete(
1815       CommandInterpreter &interpreter, const char *name, const char *help,
1816       const char *syntax, uint32_t flags)
1817       : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1818     CommandArgumentEntry arg;
1819     CommandArgumentData source_file_arg;
1820 
1821     // Define the first (and only) variant of this arg.
1822     source_file_arg.arg_type = eArgTypeSourceFile;
1823     source_file_arg.arg_repetition = eArgRepeatPlus;
1824 
1825     // There is only one variant this argument could be; put it into the
1826     // argument entry.
1827     arg.push_back(source_file_arg);
1828 
1829     // Push the data for the first argument into the m_arguments vector.
1830     m_arguments.push_back(arg);
1831   }
1832 
1833   ~CommandObjectTargetModulesSourceFileAutoComplete() override = default;
1834 
1835   void
1836   HandleArgumentCompletion(CompletionRequest &request,
1837                            OptionElementVector &opt_element_vector) override {
1838     CommandCompletions::InvokeCommonCompletionCallbacks(
1839         GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion,
1840         request, nullptr);
1841   }
1842 };
1843 
1844 #pragma mark CommandObjectTargetModulesDumpObjfile
1845 
1846 class CommandObjectTargetModulesDumpObjfile
1847     : public CommandObjectTargetModulesModuleAutoComplete {
1848 public:
1849   CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter)
1850       : CommandObjectTargetModulesModuleAutoComplete(
1851             interpreter, "target modules dump objfile",
1852             "Dump the object file headers from one or more target modules.",
1853             nullptr, eCommandRequiresTarget) {}
1854 
1855   ~CommandObjectTargetModulesDumpObjfile() override = default;
1856 
1857 protected:
1858   bool DoExecute(Args &command, CommandReturnObject &result) override {
1859     Target *target = &GetSelectedTarget();
1860 
1861     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1862     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1863     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1864 
1865     size_t num_dumped = 0;
1866     if (command.GetArgumentCount() == 0) {
1867       // Dump all headers for all modules images
1868       num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(),
1869                                             target->GetImages());
1870       if (num_dumped == 0) {
1871         result.AppendError("the target has no associated executable images");
1872       }
1873     } else {
1874       // Find the modules that match the basename or full path.
1875       ModuleList module_list;
1876       const char *arg_cstr;
1877       for (int arg_idx = 0;
1878            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
1879            ++arg_idx) {
1880         size_t num_matched =
1881             FindModulesByName(target, arg_cstr, module_list, true);
1882         if (num_matched == 0) {
1883           result.AppendWarningWithFormat(
1884               "Unable to find an image that matches '%s'.\n", arg_cstr);
1885         }
1886       }
1887       // Dump all the modules we found.
1888       num_dumped =
1889           DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
1890     }
1891 
1892     if (num_dumped > 0) {
1893       result.SetStatus(eReturnStatusSuccessFinishResult);
1894     } else {
1895       result.AppendError("no matching executable images found");
1896     }
1897     return result.Succeeded();
1898   }
1899 };
1900 
1901 #pragma mark CommandObjectTargetModulesDumpSymtab
1902 
1903 static constexpr OptionEnumValueElement g_sort_option_enumeration[] = {
1904     {
1905         eSortOrderNone,
1906         "none",
1907         "No sorting, use the original symbol table order.",
1908     },
1909     {
1910         eSortOrderByAddress,
1911         "address",
1912         "Sort output by symbol address.",
1913     },
1914     {
1915         eSortOrderByName,
1916         "name",
1917         "Sort output by symbol name.",
1918     },
1919 };
1920 
1921 #define LLDB_OPTIONS_target_modules_dump_symtab
1922 #include "CommandOptions.inc"
1923 
1924 class CommandObjectTargetModulesDumpSymtab
1925     : public CommandObjectTargetModulesModuleAutoComplete {
1926 public:
1927   CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter)
1928       : CommandObjectTargetModulesModuleAutoComplete(
1929             interpreter, "target modules dump symtab",
1930             "Dump the symbol table from one or more target modules.", nullptr,
1931             eCommandRequiresTarget),
1932         m_options() {}
1933 
1934   ~CommandObjectTargetModulesDumpSymtab() override = default;
1935 
1936   Options *GetOptions() override { return &m_options; }
1937 
1938   class CommandOptions : public Options {
1939   public:
1940     CommandOptions() : Options() {}
1941 
1942     ~CommandOptions() override = default;
1943 
1944     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1945                           ExecutionContext *execution_context) override {
1946       Status error;
1947       const int short_option = m_getopt_table[option_idx].val;
1948 
1949       switch (short_option) {
1950       case 'm':
1951         m_prefer_mangled.SetCurrentValue(true);
1952         m_prefer_mangled.SetOptionWasSet();
1953         break;
1954 
1955       case 's':
1956         m_sort_order = (SortOrder)OptionArgParser::ToOptionEnum(
1957             option_arg, GetDefinitions()[option_idx].enum_values,
1958             eSortOrderNone, error);
1959         break;
1960 
1961       default:
1962         llvm_unreachable("Unimplemented option");
1963       }
1964       return error;
1965     }
1966 
1967     void OptionParsingStarting(ExecutionContext *execution_context) override {
1968       m_sort_order = eSortOrderNone;
1969       m_prefer_mangled.Clear();
1970     }
1971 
1972     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1973       return llvm::makeArrayRef(g_target_modules_dump_symtab_options);
1974     }
1975 
1976     SortOrder m_sort_order = eSortOrderNone;
1977     OptionValueBoolean m_prefer_mangled = {false, false};
1978   };
1979 
1980 protected:
1981   bool DoExecute(Args &command, CommandReturnObject &result) override {
1982     Target *target = &GetSelectedTarget();
1983     uint32_t num_dumped = 0;
1984     Mangled::NamePreference name_preference =
1985         (m_options.m_prefer_mangled ? Mangled::ePreferMangled
1986                                     : Mangled::ePreferDemangled);
1987 
1988     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1989     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1990     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1991 
1992     if (command.GetArgumentCount() == 0) {
1993       // Dump all sections for all modules images
1994       const ModuleList &module_list = target->GetImages();
1995       std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
1996       const size_t num_modules = module_list.GetSize();
1997       if (num_modules > 0) {
1998         result.GetOutputStream().Format(
1999             "Dumping symbol table for {0} modules.\n", num_modules);
2000         for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
2001           if (num_dumped > 0) {
2002             result.GetOutputStream().EOL();
2003             result.GetOutputStream().EOL();
2004           }
2005           if (m_interpreter.WasInterrupted())
2006             break;
2007           num_dumped++;
2008           DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
2009                            module_sp.get(), m_options.m_sort_order,
2010                            name_preference);
2011         }
2012       } else {
2013         result.AppendError("the target has no associated executable images");
2014         return false;
2015       }
2016     } else {
2017       // Dump specified images (by basename or fullpath)
2018       const char *arg_cstr;
2019       for (int arg_idx = 0;
2020            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2021            ++arg_idx) {
2022         ModuleList module_list;
2023         const size_t num_matches =
2024             FindModulesByName(target, arg_cstr, module_list, true);
2025         if (num_matches > 0) {
2026           for (ModuleSP module_sp : module_list.Modules()) {
2027             if (module_sp) {
2028               if (num_dumped > 0) {
2029                 result.GetOutputStream().EOL();
2030                 result.GetOutputStream().EOL();
2031               }
2032               if (m_interpreter.WasInterrupted())
2033                 break;
2034               num_dumped++;
2035               DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
2036                                module_sp.get(), m_options.m_sort_order,
2037                                name_preference);
2038             }
2039           }
2040         } else
2041           result.AppendWarningWithFormat(
2042               "Unable to find an image that matches '%s'.\n", arg_cstr);
2043       }
2044     }
2045 
2046     if (num_dumped > 0)
2047       result.SetStatus(eReturnStatusSuccessFinishResult);
2048     else {
2049       result.AppendError("no matching executable images found");
2050     }
2051     return result.Succeeded();
2052   }
2053 
2054   CommandOptions m_options;
2055 };
2056 
2057 #pragma mark CommandObjectTargetModulesDumpSections
2058 
2059 // Image section dumping command
2060 
2061 class CommandObjectTargetModulesDumpSections
2062     : public CommandObjectTargetModulesModuleAutoComplete {
2063 public:
2064   CommandObjectTargetModulesDumpSections(CommandInterpreter &interpreter)
2065       : CommandObjectTargetModulesModuleAutoComplete(
2066             interpreter, "target modules dump sections",
2067             "Dump the sections from one or more target modules.",
2068             //"target modules dump sections [<file1> ...]")
2069             nullptr, eCommandRequiresTarget) {}
2070 
2071   ~CommandObjectTargetModulesDumpSections() override = default;
2072 
2073 protected:
2074   bool DoExecute(Args &command, CommandReturnObject &result) override {
2075     Target *target = &GetSelectedTarget();
2076     uint32_t num_dumped = 0;
2077 
2078     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2079     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2080     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2081 
2082     if (command.GetArgumentCount() == 0) {
2083       // Dump all sections for all modules images
2084       const size_t num_modules = target->GetImages().GetSize();
2085       if (num_modules == 0) {
2086         result.AppendError("the target has no associated executable images");
2087         return false;
2088       }
2089 
2090       result.GetOutputStream().Format("Dumping sections for {0} modules.\n",
2091                                       num_modules);
2092       for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2093         if (m_interpreter.WasInterrupted())
2094           break;
2095         num_dumped++;
2096         DumpModuleSections(
2097             m_interpreter, result.GetOutputStream(),
2098             target->GetImages().GetModulePointerAtIndex(image_idx));
2099       }
2100     } else {
2101       // Dump specified images (by basename or fullpath)
2102       const char *arg_cstr;
2103       for (int arg_idx = 0;
2104            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2105            ++arg_idx) {
2106         ModuleList module_list;
2107         const size_t num_matches =
2108             FindModulesByName(target, arg_cstr, module_list, true);
2109         if (num_matches > 0) {
2110           for (size_t i = 0; i < num_matches; ++i) {
2111             if (m_interpreter.WasInterrupted())
2112               break;
2113             Module *module = module_list.GetModulePointerAtIndex(i);
2114             if (module) {
2115               num_dumped++;
2116               DumpModuleSections(m_interpreter, result.GetOutputStream(),
2117                                  module);
2118             }
2119           }
2120         } else {
2121           // Check the global list
2122           std::lock_guard<std::recursive_mutex> guard(
2123               Module::GetAllocationModuleCollectionMutex());
2124 
2125           result.AppendWarningWithFormat(
2126               "Unable to find an image that matches '%s'.\n", arg_cstr);
2127         }
2128       }
2129     }
2130 
2131     if (num_dumped > 0)
2132       result.SetStatus(eReturnStatusSuccessFinishResult);
2133     else {
2134       result.AppendError("no matching executable images found");
2135     }
2136     return result.Succeeded();
2137   }
2138 };
2139 
2140 #pragma mark CommandObjectTargetModulesDumpClangAST
2141 
2142 // Clang AST dumping command
2143 
2144 class CommandObjectTargetModulesDumpClangAST
2145     : public CommandObjectTargetModulesModuleAutoComplete {
2146 public:
2147   CommandObjectTargetModulesDumpClangAST(CommandInterpreter &interpreter)
2148       : CommandObjectTargetModulesModuleAutoComplete(
2149             interpreter, "target modules dump ast",
2150             "Dump the clang ast for a given module's symbol file.",
2151             //"target modules dump ast [<file1> ...]")
2152             nullptr, eCommandRequiresTarget) {}
2153 
2154   ~CommandObjectTargetModulesDumpClangAST() override = default;
2155 
2156 protected:
2157   bool DoExecute(Args &command, CommandReturnObject &result) override {
2158     Target *target = &GetSelectedTarget();
2159 
2160     const ModuleList &module_list = target->GetImages();
2161     const size_t num_modules = module_list.GetSize();
2162     if (num_modules == 0) {
2163       result.AppendError("the target has no associated executable images");
2164       return false;
2165     }
2166 
2167     if (command.GetArgumentCount() == 0) {
2168       // Dump all ASTs for all modules images
2169       result.GetOutputStream().Format("Dumping clang ast for {0} modules.\n",
2170                                       num_modules);
2171       for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
2172         if (m_interpreter.WasInterrupted())
2173           break;
2174         if (SymbolFile *sf = module_sp->GetSymbolFile())
2175           sf->DumpClangAST(result.GetOutputStream());
2176       }
2177       result.SetStatus(eReturnStatusSuccessFinishResult);
2178       return true;
2179     }
2180 
2181     // Dump specified ASTs (by basename or fullpath)
2182     for (const Args::ArgEntry &arg : command.entries()) {
2183       ModuleList module_list;
2184       const size_t num_matches =
2185           FindModulesByName(target, arg.c_str(), module_list, true);
2186       if (num_matches == 0) {
2187         // Check the global list
2188         std::lock_guard<std::recursive_mutex> guard(
2189             Module::GetAllocationModuleCollectionMutex());
2190 
2191         result.AppendWarningWithFormat(
2192             "Unable to find an image that matches '%s'.\n", arg.c_str());
2193         continue;
2194       }
2195 
2196       for (size_t i = 0; i < num_matches; ++i) {
2197         if (m_interpreter.WasInterrupted())
2198           break;
2199         Module *m = module_list.GetModulePointerAtIndex(i);
2200         if (SymbolFile *sf = m->GetSymbolFile())
2201           sf->DumpClangAST(result.GetOutputStream());
2202       }
2203     }
2204     result.SetStatus(eReturnStatusSuccessFinishResult);
2205     return true;
2206   }
2207 };
2208 
2209 #pragma mark CommandObjectTargetModulesDumpSymfile
2210 
2211 // Image debug symbol dumping command
2212 
2213 class CommandObjectTargetModulesDumpSymfile
2214     : public CommandObjectTargetModulesModuleAutoComplete {
2215 public:
2216   CommandObjectTargetModulesDumpSymfile(CommandInterpreter &interpreter)
2217       : CommandObjectTargetModulesModuleAutoComplete(
2218             interpreter, "target modules dump symfile",
2219             "Dump the debug symbol file for one or more target modules.",
2220             //"target modules dump symfile [<file1> ...]")
2221             nullptr, eCommandRequiresTarget) {}
2222 
2223   ~CommandObjectTargetModulesDumpSymfile() override = default;
2224 
2225 protected:
2226   bool DoExecute(Args &command, CommandReturnObject &result) override {
2227     Target *target = &GetSelectedTarget();
2228     uint32_t num_dumped = 0;
2229 
2230     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2231     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2232     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2233 
2234     if (command.GetArgumentCount() == 0) {
2235       // Dump all sections for all modules images
2236       const ModuleList &target_modules = target->GetImages();
2237       std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2238       const size_t num_modules = target_modules.GetSize();
2239       if (num_modules == 0) {
2240         result.AppendError("the target has no associated executable images");
2241         return false;
2242       }
2243       result.GetOutputStream().Format(
2244           "Dumping debug symbols for {0} modules.\n", num_modules);
2245       for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
2246         if (m_interpreter.WasInterrupted())
2247           break;
2248         if (DumpModuleSymbolFile(result.GetOutputStream(), module_sp.get()))
2249           num_dumped++;
2250       }
2251     } else {
2252       // Dump specified images (by basename or fullpath)
2253       const char *arg_cstr;
2254       for (int arg_idx = 0;
2255            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2256            ++arg_idx) {
2257         ModuleList module_list;
2258         const size_t num_matches =
2259             FindModulesByName(target, arg_cstr, module_list, true);
2260         if (num_matches > 0) {
2261           for (size_t i = 0; i < num_matches; ++i) {
2262             if (m_interpreter.WasInterrupted())
2263               break;
2264             Module *module = module_list.GetModulePointerAtIndex(i);
2265             if (module) {
2266               if (DumpModuleSymbolFile(result.GetOutputStream(), module))
2267                 num_dumped++;
2268             }
2269           }
2270         } else
2271           result.AppendWarningWithFormat(
2272               "Unable to find an image that matches '%s'.\n", arg_cstr);
2273       }
2274     }
2275 
2276     if (num_dumped > 0)
2277       result.SetStatus(eReturnStatusSuccessFinishResult);
2278     else {
2279       result.AppendError("no matching executable images found");
2280     }
2281     return result.Succeeded();
2282   }
2283 };
2284 
2285 #pragma mark CommandObjectTargetModulesDumpLineTable
2286 #define LLDB_OPTIONS_target_modules_dump
2287 #include "CommandOptions.inc"
2288 
2289 // Image debug line table dumping command
2290 
2291 class CommandObjectTargetModulesDumpLineTable
2292     : public CommandObjectTargetModulesSourceFileAutoComplete {
2293 public:
2294   CommandObjectTargetModulesDumpLineTable(CommandInterpreter &interpreter)
2295       : CommandObjectTargetModulesSourceFileAutoComplete(
2296             interpreter, "target modules dump line-table",
2297             "Dump the line table for one or more compilation units.", nullptr,
2298             eCommandRequiresTarget) {}
2299 
2300   ~CommandObjectTargetModulesDumpLineTable() override = default;
2301 
2302   Options *GetOptions() override { return &m_options; }
2303 
2304 protected:
2305   bool DoExecute(Args &command, CommandReturnObject &result) override {
2306     Target *target = m_exe_ctx.GetTargetPtr();
2307     uint32_t total_num_dumped = 0;
2308 
2309     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2310     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2311     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2312 
2313     if (command.GetArgumentCount() == 0) {
2314       result.AppendError("file option must be specified.");
2315       return result.Succeeded();
2316     } else {
2317       // Dump specified images (by basename or fullpath)
2318       const char *arg_cstr;
2319       for (int arg_idx = 0;
2320            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2321            ++arg_idx) {
2322         FileSpec file_spec(arg_cstr);
2323 
2324         const ModuleList &target_modules = target->GetImages();
2325         std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2326         if (target_modules.GetSize() > 0) {
2327           uint32_t num_dumped = 0;
2328           for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
2329             if (m_interpreter.WasInterrupted())
2330               break;
2331             if (DumpCompileUnitLineTable(
2332                     m_interpreter, result.GetOutputStream(), module_sp.get(),
2333                     file_spec,
2334                     m_options.m_verbose ? eDescriptionLevelFull
2335                                         : eDescriptionLevelBrief))
2336               num_dumped++;
2337           }
2338           if (num_dumped == 0)
2339             result.AppendWarningWithFormat(
2340                 "No source filenames matched '%s'.\n", arg_cstr);
2341           else
2342             total_num_dumped += num_dumped;
2343         }
2344       }
2345     }
2346 
2347     if (total_num_dumped > 0)
2348       result.SetStatus(eReturnStatusSuccessFinishResult);
2349     else {
2350       result.AppendError("no source filenames matched any command arguments");
2351     }
2352     return result.Succeeded();
2353   }
2354 
2355   class CommandOptions : public Options {
2356   public:
2357     CommandOptions() : Options() { OptionParsingStarting(nullptr); }
2358 
2359     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2360                           ExecutionContext *execution_context) override {
2361       assert(option_idx == 0 && "We only have one option.");
2362       m_verbose = true;
2363 
2364       return Status();
2365     }
2366 
2367     void OptionParsingStarting(ExecutionContext *execution_context) override {
2368       m_verbose = false;
2369     }
2370 
2371     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2372       return llvm::makeArrayRef(g_target_modules_dump_options);
2373     }
2374 
2375     bool m_verbose;
2376   };
2377 
2378   CommandOptions m_options;
2379 };
2380 
2381 #pragma mark CommandObjectTargetModulesDump
2382 
2383 // Dump multi-word command for target modules
2384 
2385 class CommandObjectTargetModulesDump : public CommandObjectMultiword {
2386 public:
2387   // Constructors and Destructors
2388   CommandObjectTargetModulesDump(CommandInterpreter &interpreter)
2389       : CommandObjectMultiword(
2390             interpreter, "target modules dump",
2391             "Commands for dumping information about one or "
2392             "more target modules.",
2393             "target modules dump "
2394             "[headers|symtab|sections|ast|symfile|line-table] "
2395             "[<file1> <file2> ...]") {
2396     LoadSubCommand("objfile",
2397                    CommandObjectSP(
2398                        new CommandObjectTargetModulesDumpObjfile(interpreter)));
2399     LoadSubCommand(
2400         "symtab",
2401         CommandObjectSP(new CommandObjectTargetModulesDumpSymtab(interpreter)));
2402     LoadSubCommand("sections",
2403                    CommandObjectSP(new CommandObjectTargetModulesDumpSections(
2404                        interpreter)));
2405     LoadSubCommand("symfile",
2406                    CommandObjectSP(
2407                        new CommandObjectTargetModulesDumpSymfile(interpreter)));
2408     LoadSubCommand(
2409         "ast", CommandObjectSP(
2410                    new CommandObjectTargetModulesDumpClangAST(interpreter)));
2411     LoadSubCommand("line-table",
2412                    CommandObjectSP(new CommandObjectTargetModulesDumpLineTable(
2413                        interpreter)));
2414   }
2415 
2416   ~CommandObjectTargetModulesDump() override = default;
2417 };
2418 
2419 class CommandObjectTargetModulesAdd : public CommandObjectParsed {
2420 public:
2421   CommandObjectTargetModulesAdd(CommandInterpreter &interpreter)
2422       : CommandObjectParsed(interpreter, "target modules add",
2423                             "Add a new module to the current target's modules.",
2424                             "target modules add [<module>]",
2425                             eCommandRequiresTarget),
2426         m_option_group(), m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's',
2427                                         0, eArgTypeFilename,
2428                                         "Fullpath to a stand alone debug "
2429                                         "symbols file for when debug symbols "
2430                                         "are not in the executable.") {
2431     m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2432                           LLDB_OPT_SET_1);
2433     m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2434     m_option_group.Finalize();
2435   }
2436 
2437   ~CommandObjectTargetModulesAdd() override = default;
2438 
2439   Options *GetOptions() override { return &m_option_group; }
2440 
2441   void
2442   HandleArgumentCompletion(CompletionRequest &request,
2443                            OptionElementVector &opt_element_vector) override {
2444     CommandCompletions::InvokeCommonCompletionCallbacks(
2445         GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
2446         request, nullptr);
2447   }
2448 
2449 protected:
2450   OptionGroupOptions m_option_group;
2451   OptionGroupUUID m_uuid_option_group;
2452   OptionGroupFile m_symbol_file;
2453 
2454   bool DoExecute(Args &args, CommandReturnObject &result) override {
2455     Target *target = &GetSelectedTarget();
2456     bool flush = false;
2457 
2458     const size_t argc = args.GetArgumentCount();
2459     if (argc == 0) {
2460       if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2461         // We are given a UUID only, go locate the file
2462         ModuleSpec module_spec;
2463         module_spec.GetUUID() =
2464             m_uuid_option_group.GetOptionValue().GetCurrentValue();
2465         if (m_symbol_file.GetOptionValue().OptionWasSet())
2466           module_spec.GetSymbolFileSpec() =
2467               m_symbol_file.GetOptionValue().GetCurrentValue();
2468         if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
2469           ModuleSP module_sp(
2470               target->GetOrCreateModule(module_spec, true /* notify */));
2471           if (module_sp) {
2472             result.SetStatus(eReturnStatusSuccessFinishResult);
2473             return true;
2474           } else {
2475             StreamString strm;
2476             module_spec.GetUUID().Dump(&strm);
2477             if (module_spec.GetFileSpec()) {
2478               if (module_spec.GetSymbolFileSpec()) {
2479                 result.AppendErrorWithFormat(
2480                     "Unable to create the executable or symbol file with "
2481                     "UUID %s with path %s and symbol file %s",
2482                     strm.GetData(), module_spec.GetFileSpec().GetPath().c_str(),
2483                     module_spec.GetSymbolFileSpec().GetPath().c_str());
2484               } else {
2485                 result.AppendErrorWithFormat(
2486                     "Unable to create the executable or symbol file with "
2487                     "UUID %s with path %s",
2488                     strm.GetData(),
2489                     module_spec.GetFileSpec().GetPath().c_str());
2490               }
2491             } else {
2492               result.AppendErrorWithFormat("Unable to create the executable "
2493                                            "or symbol file with UUID %s",
2494                                            strm.GetData());
2495             }
2496             return false;
2497           }
2498         } else {
2499           StreamString strm;
2500           module_spec.GetUUID().Dump(&strm);
2501           result.AppendErrorWithFormat(
2502               "Unable to locate the executable or symbol file with UUID %s",
2503               strm.GetData());
2504           return false;
2505         }
2506       } else {
2507         result.AppendError(
2508             "one or more executable image paths must be specified");
2509         return false;
2510       }
2511     } else {
2512       for (auto &entry : args.entries()) {
2513         if (entry.ref().empty())
2514           continue;
2515 
2516         FileSpec file_spec(entry.ref());
2517         if (FileSystem::Instance().Exists(file_spec)) {
2518           ModuleSpec module_spec(file_spec);
2519           if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2520             module_spec.GetUUID() =
2521                 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2522           if (m_symbol_file.GetOptionValue().OptionWasSet())
2523             module_spec.GetSymbolFileSpec() =
2524                 m_symbol_file.GetOptionValue().GetCurrentValue();
2525           if (!module_spec.GetArchitecture().IsValid())
2526             module_spec.GetArchitecture() = target->GetArchitecture();
2527           Status error;
2528           ModuleSP module_sp(target->GetOrCreateModule(
2529               module_spec, true /* notify */, &error));
2530           if (!module_sp) {
2531             const char *error_cstr = error.AsCString();
2532             if (error_cstr)
2533               result.AppendError(error_cstr);
2534             else
2535               result.AppendErrorWithFormat("unsupported module: %s",
2536                                            entry.c_str());
2537             return false;
2538           } else {
2539             flush = true;
2540           }
2541           result.SetStatus(eReturnStatusSuccessFinishResult);
2542         } else {
2543           std::string resolved_path = file_spec.GetPath();
2544           if (resolved_path != entry.ref()) {
2545             result.AppendErrorWithFormat(
2546                 "invalid module path '%s' with resolved path '%s'\n",
2547                 entry.ref().str().c_str(), resolved_path.c_str());
2548             break;
2549           }
2550           result.AppendErrorWithFormat("invalid module path '%s'\n",
2551                                        entry.c_str());
2552           break;
2553         }
2554       }
2555     }
2556 
2557     if (flush) {
2558       ProcessSP process = target->GetProcessSP();
2559       if (process)
2560         process->Flush();
2561     }
2562 
2563     return result.Succeeded();
2564   }
2565 };
2566 
2567 class CommandObjectTargetModulesLoad
2568     : public CommandObjectTargetModulesModuleAutoComplete {
2569 public:
2570   CommandObjectTargetModulesLoad(CommandInterpreter &interpreter)
2571       : CommandObjectTargetModulesModuleAutoComplete(
2572             interpreter, "target modules load",
2573             "Set the load addresses for one or more sections in a target "
2574             "module.",
2575             "target modules load [--file <module> --uuid <uuid>] <sect-name> "
2576             "<address> [<sect-name> <address> ....]",
2577             eCommandRequiresTarget),
2578         m_option_group(),
2579         m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,
2580                       "Fullpath or basename for module to load.", ""),
2581         m_load_option(LLDB_OPT_SET_1, false, "load", 'l',
2582                       "Write file contents to the memory.", false, true),
2583         m_pc_option(LLDB_OPT_SET_1, false, "set-pc-to-entry", 'p',
2584                     "Set PC to the entry point."
2585                     " Only applicable with '--load' option.",
2586                     false, true),
2587         m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,
2588                        "Set the load address for all sections to be the "
2589                        "virtual address in the file plus the offset.",
2590                        0) {
2591     m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2592                           LLDB_OPT_SET_1);
2593     m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2594     m_option_group.Append(&m_load_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2595     m_option_group.Append(&m_pc_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2596     m_option_group.Append(&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2597     m_option_group.Finalize();
2598   }
2599 
2600   ~CommandObjectTargetModulesLoad() override = default;
2601 
2602   Options *GetOptions() override { return &m_option_group; }
2603 
2604 protected:
2605   bool DoExecute(Args &args, CommandReturnObject &result) override {
2606     Target *target = &GetSelectedTarget();
2607     const bool load = m_load_option.GetOptionValue().GetCurrentValue();
2608     const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue();
2609 
2610     const size_t argc = args.GetArgumentCount();
2611     ModuleSpec module_spec;
2612     bool search_using_module_spec = false;
2613 
2614     // Allow "load" option to work without --file or --uuid option.
2615     if (load) {
2616       if (!m_file_option.GetOptionValue().OptionWasSet() &&
2617           !m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2618         ModuleList &module_list = target->GetImages();
2619         if (module_list.GetSize() == 1) {
2620           search_using_module_spec = true;
2621           module_spec.GetFileSpec() =
2622               module_list.GetModuleAtIndex(0)->GetFileSpec();
2623         }
2624       }
2625     }
2626 
2627     if (m_file_option.GetOptionValue().OptionWasSet()) {
2628       search_using_module_spec = true;
2629       const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
2630       const bool use_global_module_list = true;
2631       ModuleList module_list;
2632       const size_t num_matches = FindModulesByName(
2633           target, arg_cstr, module_list, use_global_module_list);
2634       if (num_matches == 1) {
2635         module_spec.GetFileSpec() =
2636             module_list.GetModuleAtIndex(0)->GetFileSpec();
2637       } else if (num_matches > 1) {
2638         search_using_module_spec = false;
2639         result.AppendErrorWithFormat(
2640             "more than 1 module matched by name '%s'\n", arg_cstr);
2641       } else {
2642         search_using_module_spec = false;
2643         result.AppendErrorWithFormat("no object file for module '%s'\n",
2644                                      arg_cstr);
2645       }
2646     }
2647 
2648     if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2649       search_using_module_spec = true;
2650       module_spec.GetUUID() =
2651           m_uuid_option_group.GetOptionValue().GetCurrentValue();
2652     }
2653 
2654     if (search_using_module_spec) {
2655       ModuleList matching_modules;
2656       target->GetImages().FindModules(module_spec, matching_modules);
2657       const size_t num_matches = matching_modules.GetSize();
2658 
2659       char path[PATH_MAX];
2660       if (num_matches == 1) {
2661         Module *module = matching_modules.GetModulePointerAtIndex(0);
2662         if (module) {
2663           ObjectFile *objfile = module->GetObjectFile();
2664           if (objfile) {
2665             SectionList *section_list = module->GetSectionList();
2666             if (section_list) {
2667               bool changed = false;
2668               if (argc == 0) {
2669                 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2670                   const addr_t slide =
2671                       m_slide_option.GetOptionValue().GetCurrentValue();
2672                   const bool slide_is_offset = true;
2673                   module->SetLoadAddress(*target, slide, slide_is_offset,
2674                                          changed);
2675                 } else {
2676                   result.AppendError("one or more section name + load "
2677                                      "address pair must be specified");
2678                   return false;
2679                 }
2680               } else {
2681                 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2682                   result.AppendError("The \"--slide <offset>\" option can't "
2683                                      "be used in conjunction with setting "
2684                                      "section load addresses.\n");
2685                   return false;
2686                 }
2687 
2688                 for (size_t i = 0; i < argc; i += 2) {
2689                   const char *sect_name = args.GetArgumentAtIndex(i);
2690                   const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
2691                   if (sect_name && load_addr_cstr) {
2692                     ConstString const_sect_name(sect_name);
2693                     addr_t load_addr;
2694                     if (llvm::to_integer(load_addr_cstr, load_addr)) {
2695                       SectionSP section_sp(
2696                           section_list->FindSectionByName(const_sect_name));
2697                       if (section_sp) {
2698                         if (section_sp->IsThreadSpecific()) {
2699                           result.AppendErrorWithFormat(
2700                               "thread specific sections are not yet "
2701                               "supported (section '%s')\n",
2702                               sect_name);
2703                           break;
2704                         } else {
2705                           if (target->GetSectionLoadList()
2706                                   .SetSectionLoadAddress(section_sp, load_addr))
2707                             changed = true;
2708                           result.AppendMessageWithFormat(
2709                               "section '%s' loaded at 0x%" PRIx64 "\n",
2710                               sect_name, load_addr);
2711                         }
2712                       } else {
2713                         result.AppendErrorWithFormat("no section found that "
2714                                                      "matches the section "
2715                                                      "name '%s'\n",
2716                                                      sect_name);
2717                         break;
2718                       }
2719                     } else {
2720                       result.AppendErrorWithFormat(
2721                           "invalid load address string '%s'\n", load_addr_cstr);
2722                       break;
2723                     }
2724                   } else {
2725                     if (sect_name)
2726                       result.AppendError("section names must be followed by "
2727                                          "a load address.\n");
2728                     else
2729                       result.AppendError("one or more section name + load "
2730                                          "address pair must be specified.\n");
2731                     break;
2732                   }
2733                 }
2734               }
2735 
2736               if (changed) {
2737                 target->ModulesDidLoad(matching_modules);
2738                 Process *process = m_exe_ctx.GetProcessPtr();
2739                 if (process)
2740                   process->Flush();
2741               }
2742               if (load) {
2743                 ProcessSP process = target->CalculateProcess();
2744                 Address file_entry = objfile->GetEntryPointAddress();
2745                 if (!process) {
2746                   result.AppendError("No process");
2747                   return false;
2748                 }
2749                 if (set_pc && !file_entry.IsValid()) {
2750                   result.AppendError("No entry address in object file");
2751                   return false;
2752                 }
2753                 std::vector<ObjectFile::LoadableData> loadables(
2754                     objfile->GetLoadableData(*target));
2755                 if (loadables.size() == 0) {
2756                   result.AppendError("No loadable sections");
2757                   return false;
2758                 }
2759                 Status error = process->WriteObjectFile(std::move(loadables));
2760                 if (error.Fail()) {
2761                   result.AppendError(error.AsCString());
2762                   return false;
2763                 }
2764                 if (set_pc) {
2765                   ThreadList &thread_list = process->GetThreadList();
2766                   RegisterContextSP reg_context(
2767                       thread_list.GetSelectedThread()->GetRegisterContext());
2768                   addr_t file_entry_addr = file_entry.GetLoadAddress(target);
2769                   if (!reg_context->SetPC(file_entry_addr)) {
2770                     result.AppendErrorWithFormat("failed to set PC value to "
2771                                                  "0x%" PRIx64 "\n",
2772                                                  file_entry_addr);
2773                   }
2774                 }
2775               }
2776             } else {
2777               module->GetFileSpec().GetPath(path, sizeof(path));
2778               result.AppendErrorWithFormat("no sections in object file '%s'\n",
2779                                            path);
2780             }
2781           } else {
2782             module->GetFileSpec().GetPath(path, sizeof(path));
2783             result.AppendErrorWithFormat("no object file for module '%s'\n",
2784                                          path);
2785           }
2786         } else {
2787           FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
2788           if (module_spec_file) {
2789             module_spec_file->GetPath(path, sizeof(path));
2790             result.AppendErrorWithFormat("invalid module '%s'.\n", path);
2791           } else
2792             result.AppendError("no module spec");
2793         }
2794       } else {
2795         std::string uuid_str;
2796 
2797         if (module_spec.GetFileSpec())
2798           module_spec.GetFileSpec().GetPath(path, sizeof(path));
2799         else
2800           path[0] = '\0';
2801 
2802         if (module_spec.GetUUIDPtr())
2803           uuid_str = module_spec.GetUUID().GetAsString();
2804         if (num_matches > 1) {
2805           result.AppendErrorWithFormat(
2806               "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "",
2807               path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
2808           for (size_t i = 0; i < num_matches; ++i) {
2809             if (matching_modules.GetModulePointerAtIndex(i)
2810                     ->GetFileSpec()
2811                     .GetPath(path, sizeof(path)))
2812               result.AppendMessageWithFormat("%s\n", path);
2813           }
2814         } else {
2815           result.AppendErrorWithFormat(
2816               "no modules were found  that match%s%s%s%s.\n",
2817               path[0] ? " file=" : "", path, !uuid_str.empty() ? " uuid=" : "",
2818               uuid_str.c_str());
2819         }
2820       }
2821     } else {
2822       result.AppendError("either the \"--file <module>\" or the \"--uuid "
2823                          "<uuid>\" option must be specified.\n");
2824       return false;
2825     }
2826     return result.Succeeded();
2827   }
2828 
2829   OptionGroupOptions m_option_group;
2830   OptionGroupUUID m_uuid_option_group;
2831   OptionGroupString m_file_option;
2832   OptionGroupBoolean m_load_option;
2833   OptionGroupBoolean m_pc_option;
2834   OptionGroupUInt64 m_slide_option;
2835 };
2836 
2837 // List images with associated information
2838 #define LLDB_OPTIONS_target_modules_list
2839 #include "CommandOptions.inc"
2840 
2841 class CommandObjectTargetModulesList : public CommandObjectParsed {
2842 public:
2843   class CommandOptions : public Options {
2844   public:
2845     CommandOptions() : Options(), m_format_array() {}
2846 
2847     ~CommandOptions() override = default;
2848 
2849     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2850                           ExecutionContext *execution_context) override {
2851       Status error;
2852 
2853       const int short_option = m_getopt_table[option_idx].val;
2854       if (short_option == 'g') {
2855         m_use_global_module_list = true;
2856       } else if (short_option == 'a') {
2857         m_module_addr = OptionArgParser::ToAddress(
2858             execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);
2859       } else {
2860         unsigned long width = 0;
2861         option_arg.getAsInteger(0, width);
2862         m_format_array.push_back(std::make_pair(short_option, width));
2863       }
2864       return error;
2865     }
2866 
2867     void OptionParsingStarting(ExecutionContext *execution_context) override {
2868       m_format_array.clear();
2869       m_use_global_module_list = false;
2870       m_module_addr = LLDB_INVALID_ADDRESS;
2871     }
2872 
2873     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2874       return llvm::makeArrayRef(g_target_modules_list_options);
2875     }
2876 
2877     // Instance variables to hold the values for command options.
2878     typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection;
2879     FormatWidthCollection m_format_array;
2880     bool m_use_global_module_list = false;
2881     lldb::addr_t m_module_addr = LLDB_INVALID_ADDRESS;
2882   };
2883 
2884   CommandObjectTargetModulesList(CommandInterpreter &interpreter)
2885       : CommandObjectParsed(
2886             interpreter, "target modules list",
2887             "List current executable and dependent shared library images.",
2888             "target modules list [<cmd-options>]"),
2889         m_options() {}
2890 
2891   ~CommandObjectTargetModulesList() override = default;
2892 
2893   Options *GetOptions() override { return &m_options; }
2894 
2895 protected:
2896   bool DoExecute(Args &command, CommandReturnObject &result) override {
2897     Target *target = GetDebugger().GetSelectedTarget().get();
2898     const bool use_global_module_list = m_options.m_use_global_module_list;
2899     // Define a local module list here to ensure it lives longer than any
2900     // "locker" object which might lock its contents below (through the
2901     // "module_list_ptr" variable).
2902     ModuleList module_list;
2903     if (target == nullptr && !use_global_module_list) {
2904       result.AppendError("invalid target, create a debug target using the "
2905                          "'target create' command");
2906       return false;
2907     } else {
2908       if (target) {
2909         uint32_t addr_byte_size =
2910             target->GetArchitecture().GetAddressByteSize();
2911         result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2912         result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2913       }
2914       // Dump all sections for all modules images
2915       Stream &strm = result.GetOutputStream();
2916 
2917       if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) {
2918         if (target) {
2919           Address module_address;
2920           if (module_address.SetLoadAddress(m_options.m_module_addr, target)) {
2921             ModuleSP module_sp(module_address.GetModule());
2922             if (module_sp) {
2923               PrintModule(target, module_sp.get(), 0, strm);
2924               result.SetStatus(eReturnStatusSuccessFinishResult);
2925             } else {
2926               result.AppendErrorWithFormat(
2927                   "Couldn't find module matching address: 0x%" PRIx64 ".",
2928                   m_options.m_module_addr);
2929             }
2930           } else {
2931             result.AppendErrorWithFormat(
2932                 "Couldn't find module containing address: 0x%" PRIx64 ".",
2933                 m_options.m_module_addr);
2934           }
2935         } else {
2936           result.AppendError(
2937               "Can only look up modules by address with a valid target.");
2938         }
2939         return result.Succeeded();
2940       }
2941 
2942       size_t num_modules = 0;
2943 
2944       // This locker will be locked on the mutex in module_list_ptr if it is
2945       // non-nullptr. Otherwise it will lock the
2946       // AllocationModuleCollectionMutex when accessing the global module list
2947       // directly.
2948       std::unique_lock<std::recursive_mutex> guard(
2949           Module::GetAllocationModuleCollectionMutex(), std::defer_lock);
2950 
2951       const ModuleList *module_list_ptr = nullptr;
2952       const size_t argc = command.GetArgumentCount();
2953       if (argc == 0) {
2954         if (use_global_module_list) {
2955           guard.lock();
2956           num_modules = Module::GetNumberAllocatedModules();
2957         } else {
2958           module_list_ptr = &target->GetImages();
2959         }
2960       } else {
2961         for (const Args::ArgEntry &arg : command) {
2962           // Dump specified images (by basename or fullpath)
2963           const size_t num_matches = FindModulesByName(
2964               target, arg.c_str(), module_list, use_global_module_list);
2965           if (num_matches == 0) {
2966             if (argc == 1) {
2967               result.AppendErrorWithFormat("no modules found that match '%s'",
2968                                            arg.c_str());
2969               return false;
2970             }
2971           }
2972         }
2973 
2974         module_list_ptr = &module_list;
2975       }
2976 
2977       std::unique_lock<std::recursive_mutex> lock;
2978       if (module_list_ptr != nullptr) {
2979         lock =
2980             std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
2981 
2982         num_modules = module_list_ptr->GetSize();
2983       }
2984 
2985       if (num_modules > 0) {
2986         for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2987           ModuleSP module_sp;
2988           Module *module;
2989           if (module_list_ptr) {
2990             module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
2991             module = module_sp.get();
2992           } else {
2993             module = Module::GetAllocatedModuleAtIndex(image_idx);
2994             module_sp = module->shared_from_this();
2995           }
2996 
2997           const size_t indent = strm.Printf("[%3u] ", image_idx);
2998           PrintModule(target, module, indent, strm);
2999         }
3000         result.SetStatus(eReturnStatusSuccessFinishResult);
3001       } else {
3002         if (argc) {
3003           if (use_global_module_list)
3004             result.AppendError(
3005                 "the global module list has no matching modules");
3006           else
3007             result.AppendError("the target has no matching modules");
3008         } else {
3009           if (use_global_module_list)
3010             result.AppendError("the global module list is empty");
3011           else
3012             result.AppendError(
3013                 "the target has no associated executable images");
3014         }
3015         return false;
3016       }
3017     }
3018     return result.Succeeded();
3019   }
3020 
3021   void PrintModule(Target *target, Module *module, int indent, Stream &strm) {
3022     if (module == nullptr) {
3023       strm.PutCString("Null module");
3024       return;
3025     }
3026 
3027     bool dump_object_name = false;
3028     if (m_options.m_format_array.empty()) {
3029       m_options.m_format_array.push_back(std::make_pair('u', 0));
3030       m_options.m_format_array.push_back(std::make_pair('h', 0));
3031       m_options.m_format_array.push_back(std::make_pair('f', 0));
3032       m_options.m_format_array.push_back(std::make_pair('S', 0));
3033     }
3034     const size_t num_entries = m_options.m_format_array.size();
3035     bool print_space = false;
3036     for (size_t i = 0; i < num_entries; ++i) {
3037       if (print_space)
3038         strm.PutChar(' ');
3039       print_space = true;
3040       const char format_char = m_options.m_format_array[i].first;
3041       uint32_t width = m_options.m_format_array[i].second;
3042       switch (format_char) {
3043       case 'A':
3044         DumpModuleArchitecture(strm, module, false, width);
3045         break;
3046 
3047       case 't':
3048         DumpModuleArchitecture(strm, module, true, width);
3049         break;
3050 
3051       case 'f':
3052         DumpFullpath(strm, &module->GetFileSpec(), width);
3053         dump_object_name = true;
3054         break;
3055 
3056       case 'd':
3057         DumpDirectory(strm, &module->GetFileSpec(), width);
3058         break;
3059 
3060       case 'b':
3061         DumpBasename(strm, &module->GetFileSpec(), width);
3062         dump_object_name = true;
3063         break;
3064 
3065       case 'h':
3066       case 'o':
3067         // Image header address
3068         {
3069           uint32_t addr_nibble_width =
3070               target ? (target->GetArchitecture().GetAddressByteSize() * 2)
3071                      : 16;
3072 
3073           ObjectFile *objfile = module->GetObjectFile();
3074           if (objfile) {
3075             Address base_addr(objfile->GetBaseAddress());
3076             if (base_addr.IsValid()) {
3077               if (target && !target->GetSectionLoadList().IsEmpty()) {
3078                 lldb::addr_t load_addr = base_addr.GetLoadAddress(target);
3079                 if (load_addr == LLDB_INVALID_ADDRESS) {
3080                   base_addr.Dump(&strm, target,
3081                                  Address::DumpStyleModuleWithFileAddress,
3082                                  Address::DumpStyleFileAddress);
3083                 } else {
3084                   if (format_char == 'o') {
3085                     // Show the offset of slide for the image
3086                     strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3087                                 addr_nibble_width,
3088                                 load_addr - base_addr.GetFileAddress());
3089                   } else {
3090                     // Show the load address of the image
3091                     strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3092                                 addr_nibble_width, load_addr);
3093                   }
3094                 }
3095                 break;
3096               }
3097               // The address was valid, but the image isn't loaded, output the
3098               // address in an appropriate format
3099               base_addr.Dump(&strm, target, Address::DumpStyleFileAddress);
3100               break;
3101             }
3102           }
3103           strm.Printf("%*s", addr_nibble_width + 2, "");
3104         }
3105         break;
3106 
3107       case 'r': {
3108         size_t ref_count = 0;
3109         ModuleSP module_sp(module->shared_from_this());
3110         if (module_sp) {
3111           // Take one away to make sure we don't count our local "module_sp"
3112           ref_count = module_sp.use_count() - 1;
3113         }
3114         if (width)
3115           strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count);
3116         else
3117           strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count);
3118       } break;
3119 
3120       case 's':
3121       case 'S': {
3122         if (const SymbolFile *symbol_file = module->GetSymbolFile()) {
3123           const FileSpec symfile_spec =
3124               symbol_file->GetObjectFile()->GetFileSpec();
3125           if (format_char == 'S') {
3126             // Dump symbol file only if different from module file
3127             if (!symfile_spec || symfile_spec == module->GetFileSpec()) {
3128               print_space = false;
3129               break;
3130             }
3131             // Add a newline and indent past the index
3132             strm.Printf("\n%*s", indent, "");
3133           }
3134           DumpFullpath(strm, &symfile_spec, width);
3135           dump_object_name = true;
3136           break;
3137         }
3138         strm.Printf("%.*s", width, "<NONE>");
3139       } break;
3140 
3141       case 'm':
3142         strm.Format("{0:%c}", llvm::fmt_align(module->GetModificationTime(),
3143                                               llvm::AlignStyle::Left, width));
3144         break;
3145 
3146       case 'p':
3147         strm.Printf("%p", static_cast<void *>(module));
3148         break;
3149 
3150       case 'u':
3151         DumpModuleUUID(strm, module);
3152         break;
3153 
3154       default:
3155         break;
3156       }
3157     }
3158     if (dump_object_name) {
3159       const char *object_name = module->GetObjectName().GetCString();
3160       if (object_name)
3161         strm.Printf("(%s)", object_name);
3162     }
3163     strm.EOL();
3164   }
3165 
3166   CommandOptions m_options;
3167 };
3168 
3169 #pragma mark CommandObjectTargetModulesShowUnwind
3170 
3171 // Lookup unwind information in images
3172 #define LLDB_OPTIONS_target_modules_show_unwind
3173 #include "CommandOptions.inc"
3174 
3175 class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
3176 public:
3177   enum {
3178     eLookupTypeInvalid = -1,
3179     eLookupTypeAddress = 0,
3180     eLookupTypeSymbol,
3181     eLookupTypeFunction,
3182     eLookupTypeFunctionOrSymbol,
3183     kNumLookupTypes
3184   };
3185 
3186   class CommandOptions : public Options {
3187   public:
3188     CommandOptions() : Options(), m_str() {}
3189 
3190     ~CommandOptions() override = default;
3191 
3192     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3193                           ExecutionContext *execution_context) override {
3194       Status error;
3195 
3196       const int short_option = m_getopt_table[option_idx].val;
3197 
3198       switch (short_option) {
3199       case 'a': {
3200         m_str = std::string(option_arg);
3201         m_type = eLookupTypeAddress;
3202         m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
3203                                             LLDB_INVALID_ADDRESS, &error);
3204         if (m_addr == LLDB_INVALID_ADDRESS)
3205           error.SetErrorStringWithFormat("invalid address string '%s'",
3206                                          option_arg.str().c_str());
3207         break;
3208       }
3209 
3210       case 'n':
3211         m_str = std::string(option_arg);
3212         m_type = eLookupTypeFunctionOrSymbol;
3213         break;
3214 
3215       default:
3216         llvm_unreachable("Unimplemented option");
3217       }
3218 
3219       return error;
3220     }
3221 
3222     void OptionParsingStarting(ExecutionContext *execution_context) override {
3223       m_type = eLookupTypeInvalid;
3224       m_str.clear();
3225       m_addr = LLDB_INVALID_ADDRESS;
3226     }
3227 
3228     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3229       return llvm::makeArrayRef(g_target_modules_show_unwind_options);
3230     }
3231 
3232     // Instance variables to hold the values for command options.
3233 
3234     int m_type = eLookupTypeInvalid; // Should be a eLookupTypeXXX enum after
3235                                      // parsing options
3236     std::string m_str; // Holds name lookup
3237     lldb::addr_t m_addr = LLDB_INVALID_ADDRESS; // Holds the address to lookup
3238   };
3239 
3240   CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter)
3241       : CommandObjectParsed(
3242             interpreter, "target modules show-unwind",
3243             "Show synthesized unwind instructions for a function.", nullptr,
3244             eCommandRequiresTarget | eCommandRequiresProcess |
3245                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
3246         m_options() {}
3247 
3248   ~CommandObjectTargetModulesShowUnwind() override = default;
3249 
3250   Options *GetOptions() override { return &m_options; }
3251 
3252 protected:
3253   bool DoExecute(Args &command, CommandReturnObject &result) override {
3254     Target *target = m_exe_ctx.GetTargetPtr();
3255     Process *process = m_exe_ctx.GetProcessPtr();
3256     ABI *abi = nullptr;
3257     if (process)
3258       abi = process->GetABI().get();
3259 
3260     if (process == nullptr) {
3261       result.AppendError(
3262           "You must have a process running to use this command.");
3263       return false;
3264     }
3265 
3266     ThreadList threads(process->GetThreadList());
3267     if (threads.GetSize() == 0) {
3268       result.AppendError("The process must be paused to use this command.");
3269       return false;
3270     }
3271 
3272     ThreadSP thread(threads.GetThreadAtIndex(0));
3273     if (!thread) {
3274       result.AppendError("The process must be paused to use this command.");
3275       return false;
3276     }
3277 
3278     SymbolContextList sc_list;
3279 
3280     if (m_options.m_type == eLookupTypeFunctionOrSymbol) {
3281       ConstString function_name(m_options.m_str.c_str());
3282       ModuleFunctionSearchOptions function_options;
3283       function_options.include_symbols = true;
3284       function_options.include_inlines = false;
3285       target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,
3286                                         function_options, sc_list);
3287     } else if (m_options.m_type == eLookupTypeAddress && target) {
3288       Address addr;
3289       if (target->GetSectionLoadList().ResolveLoadAddress(m_options.m_addr,
3290                                                           addr)) {
3291         SymbolContext sc;
3292         ModuleSP module_sp(addr.GetModule());
3293         module_sp->ResolveSymbolContextForAddress(addr,
3294                                                   eSymbolContextEverything, sc);
3295         if (sc.function || sc.symbol) {
3296           sc_list.Append(sc);
3297         }
3298       }
3299     } else {
3300       result.AppendError(
3301           "address-expression or function name option must be specified.");
3302       return false;
3303     }
3304 
3305     size_t num_matches = sc_list.GetSize();
3306     if (num_matches == 0) {
3307       result.AppendErrorWithFormat("no unwind data found that matches '%s'.",
3308                                    m_options.m_str.c_str());
3309       return false;
3310     }
3311 
3312     for (uint32_t idx = 0; idx < num_matches; idx++) {
3313       SymbolContext sc;
3314       sc_list.GetContextAtIndex(idx, sc);
3315       if (sc.symbol == nullptr && sc.function == nullptr)
3316         continue;
3317       if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
3318         continue;
3319       AddressRange range;
3320       if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
3321                               false, range))
3322         continue;
3323       if (!range.GetBaseAddress().IsValid())
3324         continue;
3325       ConstString funcname(sc.GetFunctionName());
3326       if (funcname.IsEmpty())
3327         continue;
3328       addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
3329       if (abi)
3330         start_addr = abi->FixCodeAddress(start_addr);
3331 
3332       FuncUnwindersSP func_unwinders_sp(
3333           sc.module_sp->GetUnwindTable()
3334               .GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
3335       if (!func_unwinders_sp)
3336         continue;
3337 
3338       result.GetOutputStream().Printf(
3339           "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n",
3340           sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(),
3341           funcname.AsCString(), start_addr);
3342 
3343       Args args;
3344       target->GetUserSpecifiedTrapHandlerNames(args);
3345       size_t count = args.GetArgumentCount();
3346       for (size_t i = 0; i < count; i++) {
3347         const char *trap_func_name = args.GetArgumentAtIndex(i);
3348         if (strcmp(funcname.GetCString(), trap_func_name) == 0)
3349           result.GetOutputStream().Printf(
3350               "This function is "
3351               "treated as a trap handler function via user setting.\n");
3352       }
3353       PlatformSP platform_sp(target->GetPlatform());
3354       if (platform_sp) {
3355         const std::vector<ConstString> trap_handler_names(
3356             platform_sp->GetTrapHandlerSymbolNames());
3357         for (ConstString trap_name : trap_handler_names) {
3358           if (trap_name == funcname) {
3359             result.GetOutputStream().Printf(
3360                 "This function's "
3361                 "name is listed by the platform as a trap handler.\n");
3362           }
3363         }
3364       }
3365 
3366       result.GetOutputStream().Printf("\n");
3367 
3368       UnwindPlanSP non_callsite_unwind_plan =
3369           func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread);
3370       if (non_callsite_unwind_plan) {
3371         result.GetOutputStream().Printf(
3372             "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
3373             non_callsite_unwind_plan->GetSourceName().AsCString());
3374       }
3375       UnwindPlanSP callsite_unwind_plan =
3376           func_unwinders_sp->GetUnwindPlanAtCallSite(*target, *thread);
3377       if (callsite_unwind_plan) {
3378         result.GetOutputStream().Printf(
3379             "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
3380             callsite_unwind_plan->GetSourceName().AsCString());
3381       }
3382       UnwindPlanSP fast_unwind_plan =
3383           func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
3384       if (fast_unwind_plan) {
3385         result.GetOutputStream().Printf(
3386             "Fast UnwindPlan is '%s'\n",
3387             fast_unwind_plan->GetSourceName().AsCString());
3388       }
3389 
3390       result.GetOutputStream().Printf("\n");
3391 
3392       UnwindPlanSP assembly_sp =
3393           func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread);
3394       if (assembly_sp) {
3395         result.GetOutputStream().Printf(
3396             "Assembly language inspection UnwindPlan:\n");
3397         assembly_sp->Dump(result.GetOutputStream(), thread.get(),
3398                           LLDB_INVALID_ADDRESS);
3399         result.GetOutputStream().Printf("\n");
3400       }
3401 
3402       UnwindPlanSP of_unwind_sp =
3403           func_unwinders_sp->GetObjectFileUnwindPlan(*target);
3404       if (of_unwind_sp) {
3405         result.GetOutputStream().Printf("object file UnwindPlan:\n");
3406         of_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3407                            LLDB_INVALID_ADDRESS);
3408         result.GetOutputStream().Printf("\n");
3409       }
3410 
3411       UnwindPlanSP of_unwind_augmented_sp =
3412           func_unwinders_sp->GetObjectFileAugmentedUnwindPlan(*target, *thread);
3413       if (of_unwind_augmented_sp) {
3414         result.GetOutputStream().Printf("object file augmented UnwindPlan:\n");
3415         of_unwind_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
3416                                      LLDB_INVALID_ADDRESS);
3417         result.GetOutputStream().Printf("\n");
3418       }
3419 
3420       UnwindPlanSP ehframe_sp =
3421           func_unwinders_sp->GetEHFrameUnwindPlan(*target);
3422       if (ehframe_sp) {
3423         result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3424         ehframe_sp->Dump(result.GetOutputStream(), thread.get(),
3425                          LLDB_INVALID_ADDRESS);
3426         result.GetOutputStream().Printf("\n");
3427       }
3428 
3429       UnwindPlanSP ehframe_augmented_sp =
3430           func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread);
3431       if (ehframe_augmented_sp) {
3432         result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3433         ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
3434                                    LLDB_INVALID_ADDRESS);
3435         result.GetOutputStream().Printf("\n");
3436       }
3437 
3438       if (UnwindPlanSP plan_sp =
3439               func_unwinders_sp->GetDebugFrameUnwindPlan(*target)) {
3440         result.GetOutputStream().Printf("debug_frame UnwindPlan:\n");
3441         plan_sp->Dump(result.GetOutputStream(), thread.get(),
3442                       LLDB_INVALID_ADDRESS);
3443         result.GetOutputStream().Printf("\n");
3444       }
3445 
3446       if (UnwindPlanSP plan_sp =
3447               func_unwinders_sp->GetDebugFrameAugmentedUnwindPlan(*target,
3448                                                                   *thread)) {
3449         result.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n");
3450         plan_sp->Dump(result.GetOutputStream(), thread.get(),
3451                       LLDB_INVALID_ADDRESS);
3452         result.GetOutputStream().Printf("\n");
3453       }
3454 
3455       UnwindPlanSP arm_unwind_sp =
3456           func_unwinders_sp->GetArmUnwindUnwindPlan(*target);
3457       if (arm_unwind_sp) {
3458         result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
3459         arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3460                             LLDB_INVALID_ADDRESS);
3461         result.GetOutputStream().Printf("\n");
3462       }
3463 
3464       if (UnwindPlanSP symfile_plan_sp =
3465               func_unwinders_sp->GetSymbolFileUnwindPlan(*thread)) {
3466         result.GetOutputStream().Printf("Symbol file UnwindPlan:\n");
3467         symfile_plan_sp->Dump(result.GetOutputStream(), thread.get(),
3468                               LLDB_INVALID_ADDRESS);
3469         result.GetOutputStream().Printf("\n");
3470       }
3471 
3472       UnwindPlanSP compact_unwind_sp =
3473           func_unwinders_sp->GetCompactUnwindUnwindPlan(*target);
3474       if (compact_unwind_sp) {
3475         result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3476         compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3477                                 LLDB_INVALID_ADDRESS);
3478         result.GetOutputStream().Printf("\n");
3479       }
3480 
3481       if (fast_unwind_plan) {
3482         result.GetOutputStream().Printf("Fast UnwindPlan:\n");
3483         fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(),
3484                                LLDB_INVALID_ADDRESS);
3485         result.GetOutputStream().Printf("\n");
3486       }
3487 
3488       ABISP abi_sp = process->GetABI();
3489       if (abi_sp) {
3490         UnwindPlan arch_default(lldb::eRegisterKindGeneric);
3491         if (abi_sp->CreateDefaultUnwindPlan(arch_default)) {
3492           result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3493           arch_default.Dump(result.GetOutputStream(), thread.get(),
3494                             LLDB_INVALID_ADDRESS);
3495           result.GetOutputStream().Printf("\n");
3496         }
3497 
3498         UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
3499         if (abi_sp->CreateFunctionEntryUnwindPlan(arch_entry)) {
3500           result.GetOutputStream().Printf(
3501               "Arch default at entry point UnwindPlan:\n");
3502           arch_entry.Dump(result.GetOutputStream(), thread.get(),
3503                           LLDB_INVALID_ADDRESS);
3504           result.GetOutputStream().Printf("\n");
3505         }
3506       }
3507 
3508       result.GetOutputStream().Printf("\n");
3509     }
3510     return result.Succeeded();
3511   }
3512 
3513   CommandOptions m_options;
3514 };
3515 
3516 // Lookup information in images
3517 #define LLDB_OPTIONS_target_modules_lookup
3518 #include "CommandOptions.inc"
3519 
3520 class CommandObjectTargetModulesLookup : public CommandObjectParsed {
3521 public:
3522   enum {
3523     eLookupTypeInvalid = -1,
3524     eLookupTypeAddress = 0,
3525     eLookupTypeSymbol,
3526     eLookupTypeFileLine, // Line is optional
3527     eLookupTypeFunction,
3528     eLookupTypeFunctionOrSymbol,
3529     eLookupTypeType,
3530     kNumLookupTypes
3531   };
3532 
3533   class CommandOptions : public Options {
3534   public:
3535     CommandOptions() : Options() { OptionParsingStarting(nullptr); }
3536 
3537     ~CommandOptions() override = default;
3538 
3539     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3540                           ExecutionContext *execution_context) override {
3541       Status error;
3542 
3543       const int short_option = m_getopt_table[option_idx].val;
3544 
3545       switch (short_option) {
3546       case 'a': {
3547         m_type = eLookupTypeAddress;
3548         m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
3549                                             LLDB_INVALID_ADDRESS, &error);
3550       } break;
3551 
3552       case 'o':
3553         if (option_arg.getAsInteger(0, m_offset))
3554           error.SetErrorStringWithFormat("invalid offset string '%s'",
3555                                          option_arg.str().c_str());
3556         break;
3557 
3558       case 's':
3559         m_str = std::string(option_arg);
3560         m_type = eLookupTypeSymbol;
3561         break;
3562 
3563       case 'f':
3564         m_file.SetFile(option_arg, FileSpec::Style::native);
3565         m_type = eLookupTypeFileLine;
3566         break;
3567 
3568       case 'i':
3569         m_include_inlines = false;
3570         break;
3571 
3572       case 'l':
3573         if (option_arg.getAsInteger(0, m_line_number))
3574           error.SetErrorStringWithFormat("invalid line number string '%s'",
3575                                          option_arg.str().c_str());
3576         else if (m_line_number == 0)
3577           error.SetErrorString("zero is an invalid line number");
3578         m_type = eLookupTypeFileLine;
3579         break;
3580 
3581       case 'F':
3582         m_str = std::string(option_arg);
3583         m_type = eLookupTypeFunction;
3584         break;
3585 
3586       case 'n':
3587         m_str = std::string(option_arg);
3588         m_type = eLookupTypeFunctionOrSymbol;
3589         break;
3590 
3591       case 't':
3592         m_str = std::string(option_arg);
3593         m_type = eLookupTypeType;
3594         break;
3595 
3596       case 'v':
3597         m_verbose = true;
3598         break;
3599 
3600       case 'A':
3601         m_print_all = true;
3602         break;
3603 
3604       case 'r':
3605         m_use_regex = true;
3606         break;
3607       default:
3608         llvm_unreachable("Unimplemented option");
3609       }
3610 
3611       return error;
3612     }
3613 
3614     void OptionParsingStarting(ExecutionContext *execution_context) override {
3615       m_type = eLookupTypeInvalid;
3616       m_str.clear();
3617       m_file.Clear();
3618       m_addr = LLDB_INVALID_ADDRESS;
3619       m_offset = 0;
3620       m_line_number = 0;
3621       m_use_regex = false;
3622       m_include_inlines = true;
3623       m_verbose = false;
3624       m_print_all = false;
3625     }
3626 
3627     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3628       return llvm::makeArrayRef(g_target_modules_lookup_options);
3629     }
3630 
3631     int m_type;        // Should be a eLookupTypeXXX enum after parsing options
3632     std::string m_str; // Holds name lookup
3633     FileSpec m_file;   // Files for file lookups
3634     lldb::addr_t m_addr; // Holds the address to lookup
3635     lldb::addr_t
3636         m_offset; // Subtract this offset from m_addr before doing lookups.
3637     uint32_t m_line_number; // Line number for file+line lookups
3638     bool m_use_regex;       // Name lookups in m_str are regular expressions.
3639     bool m_include_inlines; // Check for inline entries when looking up by
3640                             // file/line.
3641     bool m_verbose;         // Enable verbose lookup info
3642     bool m_print_all; // Print all matches, even in cases where there's a best
3643                       // match.
3644   };
3645 
3646   CommandObjectTargetModulesLookup(CommandInterpreter &interpreter)
3647       : CommandObjectParsed(interpreter, "target modules lookup",
3648                             "Look up information within executable and "
3649                             "dependent shared library images.",
3650                             nullptr, eCommandRequiresTarget),
3651         m_options() {
3652     CommandArgumentEntry arg;
3653     CommandArgumentData file_arg;
3654 
3655     // Define the first (and only) variant of this arg.
3656     file_arg.arg_type = eArgTypeFilename;
3657     file_arg.arg_repetition = eArgRepeatStar;
3658 
3659     // There is only one variant this argument could be; put it into the
3660     // argument entry.
3661     arg.push_back(file_arg);
3662 
3663     // Push the data for the first argument into the m_arguments vector.
3664     m_arguments.push_back(arg);
3665   }
3666 
3667   ~CommandObjectTargetModulesLookup() override = default;
3668 
3669   Options *GetOptions() override { return &m_options; }
3670 
3671   bool LookupHere(CommandInterpreter &interpreter, CommandReturnObject &result,
3672                   bool &syntax_error) {
3673     switch (m_options.m_type) {
3674     case eLookupTypeAddress:
3675     case eLookupTypeFileLine:
3676     case eLookupTypeFunction:
3677     case eLookupTypeFunctionOrSymbol:
3678     case eLookupTypeSymbol:
3679     default:
3680       return false;
3681     case eLookupTypeType:
3682       break;
3683     }
3684 
3685     StackFrameSP frame = m_exe_ctx.GetFrameSP();
3686 
3687     if (!frame)
3688       return false;
3689 
3690     const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
3691 
3692     if (!sym_ctx.module_sp)
3693       return false;
3694 
3695     switch (m_options.m_type) {
3696     default:
3697       return false;
3698     case eLookupTypeType:
3699       if (!m_options.m_str.empty()) {
3700         if (LookupTypeHere(&GetSelectedTarget(), m_interpreter,
3701                            result.GetOutputStream(), *sym_ctx.module_sp,
3702                            m_options.m_str.c_str(), m_options.m_use_regex)) {
3703           result.SetStatus(eReturnStatusSuccessFinishResult);
3704           return true;
3705         }
3706       }
3707       break;
3708     }
3709 
3710     return false;
3711   }
3712 
3713   bool LookupInModule(CommandInterpreter &interpreter, Module *module,
3714                       CommandReturnObject &result, bool &syntax_error) {
3715     switch (m_options.m_type) {
3716     case eLookupTypeAddress:
3717       if (m_options.m_addr != LLDB_INVALID_ADDRESS) {
3718         if (LookupAddressInModule(
3719                 m_interpreter, result.GetOutputStream(), module,
3720                 eSymbolContextEverything |
3721                     (m_options.m_verbose
3722                          ? static_cast<int>(eSymbolContextVariable)
3723                          : 0),
3724                 m_options.m_addr, m_options.m_offset, m_options.m_verbose)) {
3725           result.SetStatus(eReturnStatusSuccessFinishResult);
3726           return true;
3727         }
3728       }
3729       break;
3730 
3731     case eLookupTypeSymbol:
3732       if (!m_options.m_str.empty()) {
3733         if (LookupSymbolInModule(m_interpreter, result.GetOutputStream(),
3734                                  module, m_options.m_str.c_str(),
3735                                  m_options.m_use_regex, m_options.m_verbose)) {
3736           result.SetStatus(eReturnStatusSuccessFinishResult);
3737           return true;
3738         }
3739       }
3740       break;
3741 
3742     case eLookupTypeFileLine:
3743       if (m_options.m_file) {
3744         if (LookupFileAndLineInModule(
3745                 m_interpreter, result.GetOutputStream(), module,
3746                 m_options.m_file, m_options.m_line_number,
3747                 m_options.m_include_inlines, m_options.m_verbose)) {
3748           result.SetStatus(eReturnStatusSuccessFinishResult);
3749           return true;
3750         }
3751       }
3752       break;
3753 
3754     case eLookupTypeFunctionOrSymbol:
3755     case eLookupTypeFunction:
3756       if (!m_options.m_str.empty()) {
3757         ModuleFunctionSearchOptions function_options;
3758         function_options.include_symbols =
3759             m_options.m_type == eLookupTypeFunctionOrSymbol;
3760         function_options.include_inlines = m_options.m_include_inlines;
3761 
3762         if (LookupFunctionInModule(m_interpreter, result.GetOutputStream(),
3763                                    module, m_options.m_str.c_str(),
3764                                    m_options.m_use_regex, function_options,
3765                                    m_options.m_verbose)) {
3766           result.SetStatus(eReturnStatusSuccessFinishResult);
3767           return true;
3768         }
3769       }
3770       break;
3771 
3772     case eLookupTypeType:
3773       if (!m_options.m_str.empty()) {
3774         if (LookupTypeInModule(
3775                 &GetSelectedTarget(), m_interpreter, result.GetOutputStream(),
3776                 module, m_options.m_str.c_str(), m_options.m_use_regex)) {
3777           result.SetStatus(eReturnStatusSuccessFinishResult);
3778           return true;
3779         }
3780       }
3781       break;
3782 
3783     default:
3784       m_options.GenerateOptionUsage(
3785           result.GetErrorStream(), this,
3786           GetCommandInterpreter().GetDebugger().GetTerminalWidth());
3787       syntax_error = true;
3788       break;
3789     }
3790 
3791     result.SetStatus(eReturnStatusFailed);
3792     return false;
3793   }
3794 
3795 protected:
3796   bool DoExecute(Args &command, CommandReturnObject &result) override {
3797     Target *target = &GetSelectedTarget();
3798     bool syntax_error = false;
3799     uint32_t i;
3800     uint32_t num_successful_lookups = 0;
3801     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3802     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3803     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3804     // Dump all sections for all modules images
3805 
3806     if (command.GetArgumentCount() == 0) {
3807       ModuleSP current_module;
3808 
3809       // Where it is possible to look in the current symbol context first,
3810       // try that.  If this search was successful and --all was not passed,
3811       // don't print anything else.
3812       if (LookupHere(m_interpreter, result, syntax_error)) {
3813         result.GetOutputStream().EOL();
3814         num_successful_lookups++;
3815         if (!m_options.m_print_all) {
3816           result.SetStatus(eReturnStatusSuccessFinishResult);
3817           return result.Succeeded();
3818         }
3819       }
3820 
3821       // Dump all sections for all other modules
3822 
3823       const ModuleList &target_modules = target->GetImages();
3824       std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
3825       if (target_modules.GetSize() == 0) {
3826         result.AppendError("the target has no associated executable images");
3827         return false;
3828       }
3829 
3830       for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
3831         if (module_sp != current_module &&
3832             LookupInModule(m_interpreter, module_sp.get(), result,
3833                            syntax_error)) {
3834           result.GetOutputStream().EOL();
3835           num_successful_lookups++;
3836         }
3837       }
3838     } else {
3839       // Dump specified images (by basename or fullpath)
3840       const char *arg_cstr;
3841       for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
3842                   !syntax_error;
3843            ++i) {
3844         ModuleList module_list;
3845         const size_t num_matches =
3846             FindModulesByName(target, arg_cstr, module_list, false);
3847         if (num_matches > 0) {
3848           for (size_t j = 0; j < num_matches; ++j) {
3849             Module *module = module_list.GetModulePointerAtIndex(j);
3850             if (module) {
3851               if (LookupInModule(m_interpreter, module, result, syntax_error)) {
3852                 result.GetOutputStream().EOL();
3853                 num_successful_lookups++;
3854               }
3855             }
3856           }
3857         } else
3858           result.AppendWarningWithFormat(
3859               "Unable to find an image that matches '%s'.\n", arg_cstr);
3860       }
3861     }
3862 
3863     if (num_successful_lookups > 0)
3864       result.SetStatus(eReturnStatusSuccessFinishResult);
3865     else
3866       result.SetStatus(eReturnStatusFailed);
3867     return result.Succeeded();
3868   }
3869 
3870   CommandOptions m_options;
3871 };
3872 
3873 #pragma mark CommandObjectMultiwordImageSearchPaths
3874 
3875 // CommandObjectMultiwordImageSearchPaths
3876 
3877 class CommandObjectTargetModulesImageSearchPaths
3878     : public CommandObjectMultiword {
3879 public:
3880   CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
3881       : CommandObjectMultiword(
3882             interpreter, "target modules search-paths",
3883             "Commands for managing module search paths for a target.",
3884             "target modules search-paths <subcommand> [<subcommand-options>]") {
3885     LoadSubCommand(
3886         "add", CommandObjectSP(
3887                    new CommandObjectTargetModulesSearchPathsAdd(interpreter)));
3888     LoadSubCommand(
3889         "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear(
3890                      interpreter)));
3891     LoadSubCommand(
3892         "insert",
3893         CommandObjectSP(
3894             new CommandObjectTargetModulesSearchPathsInsert(interpreter)));
3895     LoadSubCommand(
3896         "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList(
3897                     interpreter)));
3898     LoadSubCommand(
3899         "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery(
3900                      interpreter)));
3901   }
3902 
3903   ~CommandObjectTargetModulesImageSearchPaths() override = default;
3904 };
3905 
3906 #pragma mark CommandObjectTargetModules
3907 
3908 // CommandObjectTargetModules
3909 
3910 class CommandObjectTargetModules : public CommandObjectMultiword {
3911 public:
3912   // Constructors and Destructors
3913   CommandObjectTargetModules(CommandInterpreter &interpreter)
3914       : CommandObjectMultiword(interpreter, "target modules",
3915                                "Commands for accessing information for one or "
3916                                "more target modules.",
3917                                "target modules <sub-command> ...") {
3918     LoadSubCommand(
3919         "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter)));
3920     LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad(
3921                                interpreter)));
3922     LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump(
3923                                interpreter)));
3924     LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList(
3925                                interpreter)));
3926     LoadSubCommand(
3927         "lookup",
3928         CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter)));
3929     LoadSubCommand(
3930         "search-paths",
3931         CommandObjectSP(
3932             new CommandObjectTargetModulesImageSearchPaths(interpreter)));
3933     LoadSubCommand(
3934         "show-unwind",
3935         CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter)));
3936   }
3937 
3938   ~CommandObjectTargetModules() override = default;
3939 
3940 private:
3941   // For CommandObjectTargetModules only
3942   CommandObjectTargetModules(const CommandObjectTargetModules &) = delete;
3943   const CommandObjectTargetModules &
3944   operator=(const CommandObjectTargetModules &) = delete;
3945 };
3946 
3947 class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
3948 public:
3949   CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter)
3950       : CommandObjectParsed(
3951             interpreter, "target symbols add",
3952             "Add a debug symbol file to one of the target's current modules by "
3953             "specifying a path to a debug symbols file or by using the options "
3954             "to specify a module.",
3955             "target symbols add <cmd-options> [<symfile>]",
3956             eCommandRequiresTarget),
3957         m_option_group(),
3958         m_file_option(
3959             LLDB_OPT_SET_1, false, "shlib", 's',
3960             CommandCompletions::eModuleCompletion, eArgTypeShlibName,
3961             "Locate the debug symbols for the shared library specified by "
3962             "name."),
3963         m_current_frame_option(
3964             LLDB_OPT_SET_2, false, "frame", 'F',
3965             "Locate the debug symbols for the currently selected frame.",
3966             false, true)
3967 
3968   {
3969     m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
3970                           LLDB_OPT_SET_1);
3971     m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
3972     m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2,
3973                           LLDB_OPT_SET_2);
3974     m_option_group.Finalize();
3975   }
3976 
3977   ~CommandObjectTargetSymbolsAdd() override = default;
3978 
3979   void
3980   HandleArgumentCompletion(CompletionRequest &request,
3981                            OptionElementVector &opt_element_vector) override {
3982     CommandCompletions::InvokeCommonCompletionCallbacks(
3983         GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
3984         request, nullptr);
3985   }
3986 
3987   Options *GetOptions() override { return &m_option_group; }
3988 
3989 protected:
3990   bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,
3991                         CommandReturnObject &result) {
3992     const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
3993     if (!symbol_fspec) {
3994       result.AppendError(
3995           "one or more executable image paths must be specified");
3996       return false;
3997     }
3998 
3999     char symfile_path[PATH_MAX];
4000     symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));
4001 
4002     if (!module_spec.GetUUID().IsValid()) {
4003       if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
4004         module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
4005     }
4006 
4007     // Now module_spec represents a symbol file for a module that might exist
4008     // in the current target.  Let's find possible matches.
4009     ModuleList matching_modules;
4010 
4011     // First extract all module specs from the symbol file
4012     lldb_private::ModuleSpecList symfile_module_specs;
4013     if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(),
4014                                             0, 0, symfile_module_specs)) {
4015       // Now extract the module spec that matches the target architecture
4016       ModuleSpec target_arch_module_spec;
4017       ModuleSpec symfile_module_spec;
4018       target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
4019       if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,
4020                                                       symfile_module_spec)) {
4021         if (symfile_module_spec.GetUUID().IsValid()) {
4022           // It has a UUID, look for this UUID in the target modules
4023           ModuleSpec symfile_uuid_module_spec;
4024           symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4025           target->GetImages().FindModules(symfile_uuid_module_spec,
4026                                           matching_modules);
4027         }
4028       }
4029 
4030       if (matching_modules.IsEmpty()) {
4031         // No matches yet.  Iterate through the module specs to find a UUID
4032         // value that we can match up to an image in our target.
4033         const size_t num_symfile_module_specs = symfile_module_specs.GetSize();
4034         for (size_t i = 0;
4035              i < num_symfile_module_specs && matching_modules.IsEmpty(); ++i) {
4036           if (symfile_module_specs.GetModuleSpecAtIndex(
4037                   i, symfile_module_spec)) {
4038             if (symfile_module_spec.GetUUID().IsValid()) {
4039               // It has a UUID.  Look for this UUID in the target modules.
4040               ModuleSpec symfile_uuid_module_spec;
4041               symfile_uuid_module_spec.GetUUID() =
4042                   symfile_module_spec.GetUUID();
4043               target->GetImages().FindModules(symfile_uuid_module_spec,
4044                                               matching_modules);
4045             }
4046           }
4047         }
4048       }
4049     }
4050 
4051     // Just try to match up the file by basename if we have no matches at
4052     // this point.  For example, module foo might have symbols in foo.debug.
4053     if (matching_modules.IsEmpty())
4054       target->GetImages().FindModules(module_spec, matching_modules);
4055 
4056     while (matching_modules.IsEmpty()) {
4057       ConstString filename_no_extension(
4058           module_spec.GetFileSpec().GetFileNameStrippingExtension());
4059       // Empty string returned, let's bail
4060       if (!filename_no_extension)
4061         break;
4062 
4063       // Check if there was no extension to strip and the basename is the same
4064       if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
4065         break;
4066 
4067       // Replace basename with one fewer extension
4068       module_spec.GetFileSpec().GetFilename() = filename_no_extension;
4069       target->GetImages().FindModules(module_spec, matching_modules);
4070     }
4071 
4072     if (matching_modules.GetSize() > 1) {
4073       result.AppendErrorWithFormat("multiple modules match symbol file '%s', "
4074                                    "use the --uuid option to resolve the "
4075                                    "ambiguity.\n",
4076                                    symfile_path);
4077       return false;
4078     }
4079 
4080     if (matching_modules.GetSize() == 1) {
4081       ModuleSP module_sp(matching_modules.GetModuleAtIndex(0));
4082 
4083       // The module has not yet created its symbol vendor, we can just give
4084       // the existing target module the symfile path to use for when it
4085       // decides to create it!
4086       module_sp->SetSymbolFileFileSpec(symbol_fspec);
4087 
4088       SymbolFile *symbol_file =
4089           module_sp->GetSymbolFile(true, &result.GetErrorStream());
4090       if (symbol_file) {
4091         ObjectFile *object_file = symbol_file->GetObjectFile();
4092         if (object_file && object_file->GetFileSpec() == symbol_fspec) {
4093           // Provide feedback that the symfile has been successfully added.
4094           const FileSpec &module_fs = module_sp->GetFileSpec();
4095           result.AppendMessageWithFormat(
4096               "symbol file '%s' has been added to '%s'\n", symfile_path,
4097               module_fs.GetPath().c_str());
4098 
4099           // Let clients know something changed in the module if it is
4100           // currently loaded
4101           ModuleList module_list;
4102           module_list.Append(module_sp);
4103           target->SymbolsDidLoad(module_list);
4104 
4105           // Make sure we load any scripting resources that may be embedded
4106           // in the debug info files in case the platform supports that.
4107           Status error;
4108           StreamString feedback_stream;
4109           module_sp->LoadScriptingResourceInTarget(target, error,
4110                                                    &feedback_stream);
4111           if (error.Fail() && error.AsCString())
4112             result.AppendWarningWithFormat(
4113                 "unable to load scripting data for module %s - error "
4114                 "reported was %s",
4115                 module_sp->GetFileSpec()
4116                     .GetFileNameStrippingExtension()
4117                     .GetCString(),
4118                 error.AsCString());
4119           else if (feedback_stream.GetSize())
4120             result.AppendWarning(feedback_stream.GetData());
4121 
4122           flush = true;
4123           result.SetStatus(eReturnStatusSuccessFinishResult);
4124           return true;
4125         }
4126       }
4127       // Clear the symbol file spec if anything went wrong
4128       module_sp->SetSymbolFileFileSpec(FileSpec());
4129     }
4130 
4131     StreamString ss_symfile_uuid;
4132     if (module_spec.GetUUID().IsValid()) {
4133       ss_symfile_uuid << " (";
4134       module_spec.GetUUID().Dump(&ss_symfile_uuid);
4135       ss_symfile_uuid << ')';
4136     }
4137     result.AppendErrorWithFormat(
4138         "symbol file '%s'%s does not match any existing module%s\n",
4139         symfile_path, ss_symfile_uuid.GetData(),
4140         !llvm::sys::fs::is_regular_file(symbol_fspec.GetPath())
4141             ? "\n       please specify the full path to the symbol file"
4142             : "");
4143     return false;
4144   }
4145 
4146   bool DoExecute(Args &args, CommandReturnObject &result) override {
4147     Target *target = m_exe_ctx.GetTargetPtr();
4148     result.SetStatus(eReturnStatusFailed);
4149     bool flush = false;
4150     ModuleSpec module_spec;
4151     const bool uuid_option_set =
4152         m_uuid_option_group.GetOptionValue().OptionWasSet();
4153     const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4154     const bool frame_option_set =
4155         m_current_frame_option.GetOptionValue().OptionWasSet();
4156     const size_t argc = args.GetArgumentCount();
4157 
4158     if (argc == 0) {
4159       if (uuid_option_set || file_option_set || frame_option_set) {
4160         bool success = false;
4161         bool error_set = false;
4162         if (frame_option_set) {
4163           Process *process = m_exe_ctx.GetProcessPtr();
4164           if (process) {
4165             const StateType process_state = process->GetState();
4166             if (StateIsStoppedState(process_state, true)) {
4167               StackFrame *frame = m_exe_ctx.GetFramePtr();
4168               if (frame) {
4169                 ModuleSP frame_module_sp(
4170                     frame->GetSymbolContext(eSymbolContextModule).module_sp);
4171                 if (frame_module_sp) {
4172                   if (FileSystem::Instance().Exists(
4173                           frame_module_sp->GetPlatformFileSpec())) {
4174                     module_spec.GetArchitecture() =
4175                         frame_module_sp->GetArchitecture();
4176                     module_spec.GetFileSpec() =
4177                         frame_module_sp->GetPlatformFileSpec();
4178                   }
4179                   module_spec.GetUUID() = frame_module_sp->GetUUID();
4180                   success = module_spec.GetUUID().IsValid() ||
4181                             module_spec.GetFileSpec();
4182                 } else {
4183                   result.AppendError("frame has no module");
4184                   error_set = true;
4185                 }
4186               } else {
4187                 result.AppendError("invalid current frame");
4188                 error_set = true;
4189               }
4190             } else {
4191               result.AppendErrorWithFormat("process is not stopped: %s",
4192                                            StateAsCString(process_state));
4193               error_set = true;
4194             }
4195           } else {
4196             result.AppendError(
4197                 "a process must exist in order to use the --frame option");
4198             error_set = true;
4199           }
4200         } else {
4201           if (uuid_option_set) {
4202             module_spec.GetUUID() =
4203                 m_uuid_option_group.GetOptionValue().GetCurrentValue();
4204             success |= module_spec.GetUUID().IsValid();
4205           } else if (file_option_set) {
4206             module_spec.GetFileSpec() =
4207                 m_file_option.GetOptionValue().GetCurrentValue();
4208             ModuleSP module_sp(
4209                 target->GetImages().FindFirstModule(module_spec));
4210             if (module_sp) {
4211               module_spec.GetFileSpec() = module_sp->GetFileSpec();
4212               module_spec.GetPlatformFileSpec() =
4213                   module_sp->GetPlatformFileSpec();
4214               module_spec.GetUUID() = module_sp->GetUUID();
4215               module_spec.GetArchitecture() = module_sp->GetArchitecture();
4216             } else {
4217               module_spec.GetArchitecture() = target->GetArchitecture();
4218             }
4219             success |= module_spec.GetUUID().IsValid() ||
4220                        FileSystem::Instance().Exists(module_spec.GetFileSpec());
4221           }
4222         }
4223 
4224         if (success) {
4225           if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
4226             if (module_spec.GetSymbolFileSpec())
4227               success = AddModuleSymbols(target, module_spec, flush, result);
4228           }
4229         }
4230 
4231         if (!success && !error_set) {
4232           StreamString error_strm;
4233           if (uuid_option_set) {
4234             error_strm.PutCString("unable to find debug symbols for UUID ");
4235             module_spec.GetUUID().Dump(&error_strm);
4236           } else if (file_option_set) {
4237             error_strm.PutCString(
4238                 "unable to find debug symbols for the executable file ");
4239             error_strm << module_spec.GetFileSpec();
4240           } else if (frame_option_set) {
4241             error_strm.PutCString(
4242                 "unable to find debug symbols for the current frame");
4243           }
4244           result.AppendError(error_strm.GetString());
4245         }
4246       } else {
4247         result.AppendError("one or more symbol file paths must be specified, "
4248                            "or options must be specified");
4249       }
4250     } else {
4251       if (uuid_option_set) {
4252         result.AppendError("specify either one or more paths to symbol files "
4253                            "or use the --uuid option without arguments");
4254       } else if (frame_option_set) {
4255         result.AppendError("specify either one or more paths to symbol files "
4256                            "or use the --frame option without arguments");
4257       } else if (file_option_set && argc > 1) {
4258         result.AppendError("specify at most one symbol file path when "
4259                            "--shlib option is set");
4260       } else {
4261         PlatformSP platform_sp(target->GetPlatform());
4262 
4263         for (auto &entry : args.entries()) {
4264           if (!entry.ref().empty()) {
4265             auto &symbol_file_spec = module_spec.GetSymbolFileSpec();
4266             symbol_file_spec.SetFile(entry.ref(), FileSpec::Style::native);
4267             FileSystem::Instance().Resolve(symbol_file_spec);
4268             if (file_option_set) {
4269               module_spec.GetFileSpec() =
4270                   m_file_option.GetOptionValue().GetCurrentValue();
4271             }
4272             if (platform_sp) {
4273               FileSpec symfile_spec;
4274               if (platform_sp
4275                       ->ResolveSymbolFile(*target, module_spec, symfile_spec)
4276                       .Success())
4277                 module_spec.GetSymbolFileSpec() = symfile_spec;
4278             }
4279 
4280             bool symfile_exists =
4281                 FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec());
4282 
4283             if (symfile_exists) {
4284               if (!AddModuleSymbols(target, module_spec, flush, result))
4285                 break;
4286             } else {
4287               std::string resolved_symfile_path =
4288                   module_spec.GetSymbolFileSpec().GetPath();
4289               if (resolved_symfile_path != entry.ref()) {
4290                 result.AppendErrorWithFormat(
4291                     "invalid module path '%s' with resolved path '%s'\n",
4292                     entry.c_str(), resolved_symfile_path.c_str());
4293                 break;
4294               }
4295               result.AppendErrorWithFormat("invalid module path '%s'\n",
4296                                            entry.c_str());
4297               break;
4298             }
4299           }
4300         }
4301       }
4302     }
4303 
4304     if (flush) {
4305       Process *process = m_exe_ctx.GetProcessPtr();
4306       if (process)
4307         process->Flush();
4308     }
4309     return result.Succeeded();
4310   }
4311 
4312   OptionGroupOptions m_option_group;
4313   OptionGroupUUID m_uuid_option_group;
4314   OptionGroupFile m_file_option;
4315   OptionGroupBoolean m_current_frame_option;
4316 };
4317 
4318 #pragma mark CommandObjectTargetSymbols
4319 
4320 // CommandObjectTargetSymbols
4321 
4322 class CommandObjectTargetSymbols : public CommandObjectMultiword {
4323 public:
4324   // Constructors and Destructors
4325   CommandObjectTargetSymbols(CommandInterpreter &interpreter)
4326       : CommandObjectMultiword(
4327             interpreter, "target symbols",
4328             "Commands for adding and managing debug symbol files.",
4329             "target symbols <sub-command> ...") {
4330     LoadSubCommand(
4331         "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));
4332   }
4333 
4334   ~CommandObjectTargetSymbols() override = default;
4335 
4336 private:
4337   // For CommandObjectTargetModules only
4338   CommandObjectTargetSymbols(const CommandObjectTargetSymbols &) = delete;
4339   const CommandObjectTargetSymbols &
4340   operator=(const CommandObjectTargetSymbols &) = delete;
4341 };
4342 
4343 #pragma mark CommandObjectTargetStopHookAdd
4344 
4345 // CommandObjectTargetStopHookAdd
4346 #define LLDB_OPTIONS_target_stop_hook_add
4347 #include "CommandOptions.inc"
4348 
4349 class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
4350                                        public IOHandlerDelegateMultiline {
4351 public:
4352   class CommandOptions : public OptionGroup {
4353   public:
4354     CommandOptions() : OptionGroup(), m_line_end(UINT_MAX), m_one_liner() {}
4355 
4356     ~CommandOptions() override = default;
4357 
4358     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
4359       return llvm::makeArrayRef(g_target_stop_hook_add_options);
4360     }
4361 
4362     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
4363                           ExecutionContext *execution_context) override {
4364       Status error;
4365       const int short_option =
4366           g_target_stop_hook_add_options[option_idx].short_option;
4367 
4368       switch (short_option) {
4369       case 'c':
4370         m_class_name = std::string(option_arg);
4371         m_sym_ctx_specified = true;
4372         break;
4373 
4374       case 'e':
4375         if (option_arg.getAsInteger(0, m_line_end)) {
4376           error.SetErrorStringWithFormat("invalid end line number: \"%s\"",
4377                                          option_arg.str().c_str());
4378           break;
4379         }
4380         m_sym_ctx_specified = true;
4381         break;
4382 
4383       case 'G': {
4384         bool value, success;
4385         value = OptionArgParser::ToBoolean(option_arg, false, &success);
4386         if (success) {
4387           m_auto_continue = value;
4388         } else
4389           error.SetErrorStringWithFormat(
4390               "invalid boolean value '%s' passed for -G option",
4391               option_arg.str().c_str());
4392       } break;
4393       case 'l':
4394         if (option_arg.getAsInteger(0, m_line_start)) {
4395           error.SetErrorStringWithFormat("invalid start line number: \"%s\"",
4396                                          option_arg.str().c_str());
4397           break;
4398         }
4399         m_sym_ctx_specified = true;
4400         break;
4401 
4402       case 'i':
4403         m_no_inlines = true;
4404         break;
4405 
4406       case 'n':
4407         m_function_name = std::string(option_arg);
4408         m_func_name_type_mask |= eFunctionNameTypeAuto;
4409         m_sym_ctx_specified = true;
4410         break;
4411 
4412       case 'f':
4413         m_file_name = std::string(option_arg);
4414         m_sym_ctx_specified = true;
4415         break;
4416 
4417       case 's':
4418         m_module_name = std::string(option_arg);
4419         m_sym_ctx_specified = true;
4420         break;
4421 
4422       case 't':
4423         if (option_arg.getAsInteger(0, m_thread_id))
4424           error.SetErrorStringWithFormat("invalid thread id string '%s'",
4425                                          option_arg.str().c_str());
4426         m_thread_specified = true;
4427         break;
4428 
4429       case 'T':
4430         m_thread_name = std::string(option_arg);
4431         m_thread_specified = true;
4432         break;
4433 
4434       case 'q':
4435         m_queue_name = std::string(option_arg);
4436         m_thread_specified = true;
4437         break;
4438 
4439       case 'x':
4440         if (option_arg.getAsInteger(0, m_thread_index))
4441           error.SetErrorStringWithFormat("invalid thread index string '%s'",
4442                                          option_arg.str().c_str());
4443         m_thread_specified = true;
4444         break;
4445 
4446       case 'o':
4447         m_use_one_liner = true;
4448         m_one_liner.push_back(std::string(option_arg));
4449         break;
4450 
4451       default:
4452         llvm_unreachable("Unimplemented option");
4453       }
4454       return error;
4455     }
4456 
4457     void OptionParsingStarting(ExecutionContext *execution_context) override {
4458       m_class_name.clear();
4459       m_function_name.clear();
4460       m_line_start = 0;
4461       m_line_end = UINT_MAX;
4462       m_file_name.clear();
4463       m_module_name.clear();
4464       m_func_name_type_mask = eFunctionNameTypeAuto;
4465       m_thread_id = LLDB_INVALID_THREAD_ID;
4466       m_thread_index = UINT32_MAX;
4467       m_thread_name.clear();
4468       m_queue_name.clear();
4469 
4470       m_no_inlines = false;
4471       m_sym_ctx_specified = false;
4472       m_thread_specified = false;
4473 
4474       m_use_one_liner = false;
4475       m_one_liner.clear();
4476       m_auto_continue = false;
4477     }
4478 
4479     std::string m_class_name;
4480     std::string m_function_name;
4481     uint32_t m_line_start = 0;
4482     uint32_t m_line_end;
4483     std::string m_file_name;
4484     std::string m_module_name;
4485     uint32_t m_func_name_type_mask =
4486         eFunctionNameTypeAuto; // A pick from lldb::FunctionNameType.
4487     lldb::tid_t m_thread_id;
4488     uint32_t m_thread_index;
4489     std::string m_thread_name;
4490     std::string m_queue_name;
4491     bool m_sym_ctx_specified = false;
4492     bool m_no_inlines;
4493     bool m_thread_specified = false;
4494     // Instance variables to hold the values for one_liner options.
4495     bool m_use_one_liner = false;
4496     std::vector<std::string> m_one_liner;
4497 
4498     bool m_auto_continue;
4499   };
4500 
4501   CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
4502       : CommandObjectParsed(interpreter, "target stop-hook add",
4503                             "Add a hook to be executed when the target stops."
4504                             "The hook can either be a list of commands or an "
4505                             "appropriately defined Python class.  You can also "
4506                             "add filters so the hook only runs a certain stop "
4507                             "points.",
4508                             "target stop-hook add"),
4509         IOHandlerDelegateMultiline("DONE",
4510                                    IOHandlerDelegate::Completion::LLDBCommand),
4511         m_options(), m_python_class_options("scripted stop-hook", true, 'P') {
4512     SetHelpLong(
4513         R"(
4514 Command Based stop-hooks:
4515 -------------------------
4516   Stop hooks can run a list of lldb commands by providing one or more
4517   --one-line-command options.  The commands will get run in the order they are
4518   added.  Or you can provide no commands, in which case you will enter a
4519   command editor where you can enter the commands to be run.
4520 
4521 Python Based Stop Hooks:
4522 ------------------------
4523   Stop hooks can be implemented with a suitably defined Python class, whose name
4524   is passed in the --python-class option.
4525 
4526   When the stop hook is added, the class is initialized by calling:
4527 
4528     def __init__(self, target, extra_args, internal_dict):
4529 
4530     target: The target that the stop hook is being added to.
4531     extra_args: An SBStructuredData Dictionary filled with the -key -value
4532                 option pairs passed to the command.
4533     dict: An implementation detail provided by lldb.
4534 
4535   Then when the stop-hook triggers, lldb will run the 'handle_stop' method.
4536   The method has the signature:
4537 
4538     def handle_stop(self, exe_ctx, stream):
4539 
4540     exe_ctx: An SBExecutionContext for the thread that has stopped.
4541     stream: An SBStream, anything written to this stream will be printed in the
4542             the stop message when the process stops.
4543 
4544     Return Value: The method returns "should_stop".  If should_stop is false
4545                   from all the stop hook executions on threads that stopped
4546                   with a reason, then the process will continue.  Note that this
4547                   will happen only after all the stop hooks are run.
4548 
4549 Filter Options:
4550 ---------------
4551   Stop hooks can be set to always run, or to only run when the stopped thread
4552   matches the filter options passed on the command line.  The available filter
4553   options include a shared library or a thread or queue specification,
4554   a line range in a source file, a function name or a class name.
4555             )");
4556     m_all_options.Append(&m_python_class_options,
4557                          LLDB_OPT_SET_1 | LLDB_OPT_SET_2,
4558                          LLDB_OPT_SET_FROM_TO(4, 6));
4559     m_all_options.Append(&m_options);
4560     m_all_options.Finalize();
4561   }
4562 
4563   ~CommandObjectTargetStopHookAdd() override = default;
4564 
4565   Options *GetOptions() override { return &m_all_options; }
4566 
4567 protected:
4568   void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
4569     StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
4570     if (output_sp && interactive) {
4571       output_sp->PutCString(
4572           "Enter your stop hook command(s).  Type 'DONE' to end.\n");
4573       output_sp->Flush();
4574     }
4575   }
4576 
4577   void IOHandlerInputComplete(IOHandler &io_handler,
4578                               std::string &line) override {
4579     if (m_stop_hook_sp) {
4580       if (line.empty()) {
4581         StreamFileSP error_sp(io_handler.GetErrorStreamFileSP());
4582         if (error_sp) {
4583           error_sp->Printf("error: stop hook #%" PRIu64
4584                            " aborted, no commands.\n",
4585                            m_stop_hook_sp->GetID());
4586           error_sp->Flush();
4587         }
4588         Target *target = GetDebugger().GetSelectedTarget().get();
4589         if (target) {
4590           target->UndoCreateStopHook(m_stop_hook_sp->GetID());
4591         }
4592       } else {
4593         // The IOHandler editor is only for command lines stop hooks:
4594         Target::StopHookCommandLine *hook_ptr =
4595             static_cast<Target::StopHookCommandLine *>(m_stop_hook_sp.get());
4596 
4597         hook_ptr->SetActionFromString(line);
4598         StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
4599         if (output_sp) {
4600           output_sp->Printf("Stop hook #%" PRIu64 " added.\n",
4601                             m_stop_hook_sp->GetID());
4602           output_sp->Flush();
4603         }
4604       }
4605       m_stop_hook_sp.reset();
4606     }
4607     io_handler.SetIsDone(true);
4608   }
4609 
4610   bool DoExecute(Args &command, CommandReturnObject &result) override {
4611     m_stop_hook_sp.reset();
4612 
4613     Target &target = GetSelectedOrDummyTarget();
4614     Target::StopHookSP new_hook_sp =
4615         target.CreateStopHook(m_python_class_options.GetName().empty() ?
4616                                Target::StopHook::StopHookKind::CommandBased
4617                                : Target::StopHook::StopHookKind::ScriptBased);
4618 
4619     //  First step, make the specifier.
4620     std::unique_ptr<SymbolContextSpecifier> specifier_up;
4621     if (m_options.m_sym_ctx_specified) {
4622       specifier_up = std::make_unique<SymbolContextSpecifier>(
4623           GetDebugger().GetSelectedTarget());
4624 
4625       if (!m_options.m_module_name.empty()) {
4626         specifier_up->AddSpecification(
4627             m_options.m_module_name.c_str(),
4628             SymbolContextSpecifier::eModuleSpecified);
4629       }
4630 
4631       if (!m_options.m_class_name.empty()) {
4632         specifier_up->AddSpecification(
4633             m_options.m_class_name.c_str(),
4634             SymbolContextSpecifier::eClassOrNamespaceSpecified);
4635       }
4636 
4637       if (!m_options.m_file_name.empty()) {
4638         specifier_up->AddSpecification(m_options.m_file_name.c_str(),
4639                                        SymbolContextSpecifier::eFileSpecified);
4640       }
4641 
4642       if (m_options.m_line_start != 0) {
4643         specifier_up->AddLineSpecification(
4644             m_options.m_line_start,
4645             SymbolContextSpecifier::eLineStartSpecified);
4646       }
4647 
4648       if (m_options.m_line_end != UINT_MAX) {
4649         specifier_up->AddLineSpecification(
4650             m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
4651       }
4652 
4653       if (!m_options.m_function_name.empty()) {
4654         specifier_up->AddSpecification(
4655             m_options.m_function_name.c_str(),
4656             SymbolContextSpecifier::eFunctionSpecified);
4657       }
4658     }
4659 
4660     if (specifier_up)
4661       new_hook_sp->SetSpecifier(specifier_up.release());
4662 
4663     // Next see if any of the thread options have been entered:
4664 
4665     if (m_options.m_thread_specified) {
4666       ThreadSpec *thread_spec = new ThreadSpec();
4667 
4668       if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) {
4669         thread_spec->SetTID(m_options.m_thread_id);
4670       }
4671 
4672       if (m_options.m_thread_index != UINT32_MAX)
4673         thread_spec->SetIndex(m_options.m_thread_index);
4674 
4675       if (!m_options.m_thread_name.empty())
4676         thread_spec->SetName(m_options.m_thread_name.c_str());
4677 
4678       if (!m_options.m_queue_name.empty())
4679         thread_spec->SetQueueName(m_options.m_queue_name.c_str());
4680 
4681       new_hook_sp->SetThreadSpecifier(thread_spec);
4682     }
4683 
4684     new_hook_sp->SetAutoContinue(m_options.m_auto_continue);
4685     if (m_options.m_use_one_liner) {
4686       // This is a command line stop hook:
4687       Target::StopHookCommandLine *hook_ptr =
4688           static_cast<Target::StopHookCommandLine *>(new_hook_sp.get());
4689       hook_ptr->SetActionFromStrings(m_options.m_one_liner);
4690       result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
4691                                      new_hook_sp->GetID());
4692     } else if (!m_python_class_options.GetName().empty()) {
4693       // This is a scripted stop hook:
4694       Target::StopHookScripted *hook_ptr =
4695           static_cast<Target::StopHookScripted *>(new_hook_sp.get());
4696       Status error = hook_ptr->SetScriptCallback(
4697           m_python_class_options.GetName(),
4698           m_python_class_options.GetStructuredData());
4699       if (error.Success())
4700         result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
4701                                        new_hook_sp->GetID());
4702       else {
4703         // FIXME: Set the stop hook ID counter back.
4704         result.AppendErrorWithFormat("Couldn't add stop hook: %s",
4705                                      error.AsCString());
4706         target.UndoCreateStopHook(new_hook_sp->GetID());
4707         return false;
4708       }
4709     } else {
4710       m_stop_hook_sp = new_hook_sp;
4711       m_interpreter.GetLLDBCommandsFromIOHandler("> ",   // Prompt
4712                                                  *this); // IOHandlerDelegate
4713     }
4714     result.SetStatus(eReturnStatusSuccessFinishNoResult);
4715 
4716     return result.Succeeded();
4717   }
4718 
4719 private:
4720   CommandOptions m_options;
4721   OptionGroupPythonClassWithDict m_python_class_options;
4722   OptionGroupOptions m_all_options;
4723 
4724   Target::StopHookSP m_stop_hook_sp;
4725 };
4726 
4727 #pragma mark CommandObjectTargetStopHookDelete
4728 
4729 // CommandObjectTargetStopHookDelete
4730 
4731 class CommandObjectTargetStopHookDelete : public CommandObjectParsed {
4732 public:
4733   CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter)
4734       : CommandObjectParsed(interpreter, "target stop-hook delete",
4735                             "Delete a stop-hook.",
4736                             "target stop-hook delete [<idx>]") {}
4737 
4738   ~CommandObjectTargetStopHookDelete() override = default;
4739 
4740   void
4741   HandleArgumentCompletion(CompletionRequest &request,
4742                            OptionElementVector &opt_element_vector) override {
4743     CommandCompletions::InvokeCommonCompletionCallbacks(
4744         GetCommandInterpreter(), CommandCompletions::eStopHookIDCompletion,
4745         request, nullptr);
4746   }
4747 
4748 protected:
4749   bool DoExecute(Args &command, CommandReturnObject &result) override {
4750     Target &target = GetSelectedOrDummyTarget();
4751     // FIXME: see if we can use the breakpoint id style parser?
4752     size_t num_args = command.GetArgumentCount();
4753     if (num_args == 0) {
4754       if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
4755         result.SetStatus(eReturnStatusFailed);
4756         return false;
4757       } else {
4758         target.RemoveAllStopHooks();
4759       }
4760     } else {
4761       for (size_t i = 0; i < num_args; i++) {
4762         lldb::user_id_t user_id;
4763         if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
4764           result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4765                                        command.GetArgumentAtIndex(i));
4766           return false;
4767         }
4768         if (!target.RemoveStopHookByID(user_id)) {
4769           result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4770                                        command.GetArgumentAtIndex(i));
4771           return false;
4772         }
4773       }
4774     }
4775     result.SetStatus(eReturnStatusSuccessFinishNoResult);
4776     return result.Succeeded();
4777   }
4778 };
4779 
4780 #pragma mark CommandObjectTargetStopHookEnableDisable
4781 
4782 // CommandObjectTargetStopHookEnableDisable
4783 
4784 class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed {
4785 public:
4786   CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter,
4787                                            bool enable, const char *name,
4788                                            const char *help, const char *syntax)
4789       : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) {
4790   }
4791 
4792   ~CommandObjectTargetStopHookEnableDisable() override = default;
4793 
4794   void
4795   HandleArgumentCompletion(CompletionRequest &request,
4796                            OptionElementVector &opt_element_vector) override {
4797     if (request.GetCursorIndex())
4798       return;
4799     CommandCompletions::InvokeCommonCompletionCallbacks(
4800         GetCommandInterpreter(), CommandCompletions::eStopHookIDCompletion,
4801         request, nullptr);
4802   }
4803 
4804 protected:
4805   bool DoExecute(Args &command, CommandReturnObject &result) override {
4806     Target &target = GetSelectedOrDummyTarget();
4807     // FIXME: see if we can use the breakpoint id style parser?
4808     size_t num_args = command.GetArgumentCount();
4809     bool success;
4810 
4811     if (num_args == 0) {
4812       target.SetAllStopHooksActiveState(m_enable);
4813     } else {
4814       for (size_t i = 0; i < num_args; i++) {
4815         lldb::user_id_t user_id;
4816         if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
4817           result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4818                                        command.GetArgumentAtIndex(i));
4819           return false;
4820         }
4821         success = target.SetStopHookActiveStateByID(user_id, m_enable);
4822         if (!success) {
4823           result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4824                                        command.GetArgumentAtIndex(i));
4825           return false;
4826         }
4827       }
4828     }
4829     result.SetStatus(eReturnStatusSuccessFinishNoResult);
4830     return result.Succeeded();
4831   }
4832 
4833 private:
4834   bool m_enable;
4835 };
4836 
4837 #pragma mark CommandObjectTargetStopHookList
4838 
4839 // CommandObjectTargetStopHookList
4840 
4841 class CommandObjectTargetStopHookList : public CommandObjectParsed {
4842 public:
4843   CommandObjectTargetStopHookList(CommandInterpreter &interpreter)
4844       : CommandObjectParsed(interpreter, "target stop-hook list",
4845                             "List all stop-hooks.",
4846                             "target stop-hook list [<type>]") {}
4847 
4848   ~CommandObjectTargetStopHookList() override = default;
4849 
4850 protected:
4851   bool DoExecute(Args &command, CommandReturnObject &result) override {
4852     Target &target = GetSelectedOrDummyTarget();
4853 
4854     size_t num_hooks = target.GetNumStopHooks();
4855     if (num_hooks == 0) {
4856       result.GetOutputStream().PutCString("No stop hooks.\n");
4857     } else {
4858       for (size_t i = 0; i < num_hooks; i++) {
4859         Target::StopHookSP this_hook = target.GetStopHookAtIndex(i);
4860         if (i > 0)
4861           result.GetOutputStream().PutCString("\n");
4862         this_hook->GetDescription(&(result.GetOutputStream()),
4863                                   eDescriptionLevelFull);
4864       }
4865     }
4866     result.SetStatus(eReturnStatusSuccessFinishResult);
4867     return result.Succeeded();
4868   }
4869 };
4870 
4871 #pragma mark CommandObjectMultiwordTargetStopHooks
4872 
4873 // CommandObjectMultiwordTargetStopHooks
4874 
4875 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword {
4876 public:
4877   CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
4878       : CommandObjectMultiword(
4879             interpreter, "target stop-hook",
4880             "Commands for operating on debugger target stop-hooks.",
4881             "target stop-hook <subcommand> [<subcommand-options>]") {
4882     LoadSubCommand("add", CommandObjectSP(
4883                               new CommandObjectTargetStopHookAdd(interpreter)));
4884     LoadSubCommand(
4885         "delete",
4886         CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter)));
4887     LoadSubCommand("disable",
4888                    CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
4889                        interpreter, false, "target stop-hook disable [<id>]",
4890                        "Disable a stop-hook.", "target stop-hook disable")));
4891     LoadSubCommand("enable",
4892                    CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
4893                        interpreter, true, "target stop-hook enable [<id>]",
4894                        "Enable a stop-hook.", "target stop-hook enable")));
4895     LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList(
4896                                interpreter)));
4897   }
4898 
4899   ~CommandObjectMultiwordTargetStopHooks() override = default;
4900 };
4901 
4902 #pragma mark CommandObjectMultiwordTarget
4903 
4904 // CommandObjectMultiwordTarget
4905 
4906 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(
4907     CommandInterpreter &interpreter)
4908     : CommandObjectMultiword(interpreter, "target",
4909                              "Commands for operating on debugger targets.",
4910                              "target <subcommand> [<subcommand-options>]") {
4911   LoadSubCommand("create",
4912                  CommandObjectSP(new CommandObjectTargetCreate(interpreter)));
4913   LoadSubCommand("delete",
4914                  CommandObjectSP(new CommandObjectTargetDelete(interpreter)));
4915   LoadSubCommand("list",
4916                  CommandObjectSP(new CommandObjectTargetList(interpreter)));
4917   LoadSubCommand("select",
4918                  CommandObjectSP(new CommandObjectTargetSelect(interpreter)));
4919   LoadSubCommand("show-launch-environment",
4920                  CommandObjectSP(new CommandObjectTargetShowLaunchEnvironment(
4921                      interpreter)));
4922   LoadSubCommand(
4923       "stop-hook",
4924       CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter)));
4925   LoadSubCommand("modules",
4926                  CommandObjectSP(new CommandObjectTargetModules(interpreter)));
4927   LoadSubCommand("symbols",
4928                  CommandObjectSP(new CommandObjectTargetSymbols(interpreter)));
4929   LoadSubCommand("variable",
4930                  CommandObjectSP(new CommandObjectTargetVariable(interpreter)));
4931 }
4932 
4933 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;
4934