xref: /freebsd-src/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp (revision 5e801ac66d24704442eba426ed13c3effb8a34e7)
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::eOpenOptionReadOnly);
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::eOpenOptionReadOnly);
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               from, to, last_pair); // Notify if this is the last pair
1051           result.SetStatus(eReturnStatusSuccessFinishNoResult);
1052         } else {
1053           if (from[0])
1054             result.AppendError("<path-prefix> can't be empty\n");
1055           else
1056             result.AppendError("<new-path-prefix> can't be empty\n");
1057         }
1058       }
1059     }
1060     return result.Succeeded();
1061   }
1062 };
1063 
1064 #pragma mark CommandObjectTargetModulesSearchPathsClear
1065 
1066 class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed {
1067 public:
1068   CommandObjectTargetModulesSearchPathsClear(CommandInterpreter &interpreter)
1069       : CommandObjectParsed(interpreter, "target modules search-paths clear",
1070                             "Clear all current image search path substitution "
1071                             "pairs from the current target.",
1072                             "target modules search-paths clear",
1073                             eCommandRequiresTarget) {}
1074 
1075   ~CommandObjectTargetModulesSearchPathsClear() override = default;
1076 
1077 protected:
1078   bool DoExecute(Args &command, CommandReturnObject &result) override {
1079     Target *target = &GetSelectedTarget();
1080     bool notify = true;
1081     target->GetImageSearchPathList().Clear(notify);
1082     result.SetStatus(eReturnStatusSuccessFinishNoResult);
1083     return result.Succeeded();
1084   }
1085 };
1086 
1087 #pragma mark CommandObjectTargetModulesSearchPathsInsert
1088 
1089 class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed {
1090 public:
1091   CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter &interpreter)
1092       : CommandObjectParsed(interpreter, "target modules search-paths insert",
1093                             "Insert a new image search path substitution pair "
1094                             "into the current target at the specified index.",
1095                             nullptr, eCommandRequiresTarget) {
1096     CommandArgumentEntry arg1;
1097     CommandArgumentEntry arg2;
1098     CommandArgumentData index_arg;
1099     CommandArgumentData old_prefix_arg;
1100     CommandArgumentData new_prefix_arg;
1101 
1102     // Define the first and only variant of this arg.
1103     index_arg.arg_type = eArgTypeIndex;
1104     index_arg.arg_repetition = eArgRepeatPlain;
1105 
1106     // Put the one and only variant into the first arg for m_arguments:
1107     arg1.push_back(index_arg);
1108 
1109     // Define the first variant of this arg pair.
1110     old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1111     old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1112 
1113     // Define the first variant of this arg pair.
1114     new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1115     new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1116 
1117     // There are two required arguments that must always occur together, i.e.
1118     // an argument "pair".  Because they must always occur together, they are
1119     // treated as two variants of one argument rather than two independent
1120     // arguments.  Push them both into the same argument position for
1121     // m_arguments...
1122 
1123     arg2.push_back(old_prefix_arg);
1124     arg2.push_back(new_prefix_arg);
1125 
1126     // Add arguments to m_arguments.
1127     m_arguments.push_back(arg1);
1128     m_arguments.push_back(arg2);
1129   }
1130 
1131   ~CommandObjectTargetModulesSearchPathsInsert() override = default;
1132 
1133   void
1134   HandleArgumentCompletion(CompletionRequest &request,
1135                            OptionElementVector &opt_element_vector) override {
1136     if (!m_exe_ctx.HasTargetScope() || request.GetCursorIndex() != 0)
1137       return;
1138 
1139     Target *target = m_exe_ctx.GetTargetPtr();
1140     const PathMappingList &list = target->GetImageSearchPathList();
1141     const size_t num = list.GetSize();
1142     ConstString old_path, new_path;
1143     for (size_t i = 0; i < num; ++i) {
1144       if (!list.GetPathsAtIndex(i, old_path, new_path))
1145         break;
1146       StreamString strm;
1147       strm << old_path << " -> " << new_path;
1148       request.TryCompleteCurrentArg(std::to_string(i), strm.GetString());
1149     }
1150   }
1151 
1152 protected:
1153   bool DoExecute(Args &command, CommandReturnObject &result) override {
1154     Target *target = &GetSelectedTarget();
1155     size_t argc = command.GetArgumentCount();
1156     // check for at least 3 arguments and an odd number of parameters
1157     if (argc >= 3 && argc & 1) {
1158       uint32_t insert_idx;
1159 
1160       if (!llvm::to_integer(command.GetArgumentAtIndex(0), insert_idx)) {
1161         result.AppendErrorWithFormat(
1162             "<index> parameter is not an integer: '%s'.\n",
1163             command.GetArgumentAtIndex(0));
1164         return result.Succeeded();
1165       }
1166 
1167       // shift off the index
1168       command.Shift();
1169       argc = command.GetArgumentCount();
1170 
1171       for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) {
1172         const char *from = command.GetArgumentAtIndex(i);
1173         const char *to = command.GetArgumentAtIndex(i + 1);
1174 
1175         if (from[0] && to[0]) {
1176           bool last_pair = ((argc - i) == 2);
1177           target->GetImageSearchPathList().Insert(from, to, insert_idx,
1178                                                   last_pair);
1179           result.SetStatus(eReturnStatusSuccessFinishNoResult);
1180         } else {
1181           if (from[0])
1182             result.AppendError("<path-prefix> can't be empty\n");
1183           else
1184             result.AppendError("<new-path-prefix> can't be empty\n");
1185           return false;
1186         }
1187       }
1188     } else {
1189       result.AppendError("insert requires at least three arguments\n");
1190       return result.Succeeded();
1191     }
1192     return result.Succeeded();
1193   }
1194 };
1195 
1196 #pragma mark CommandObjectTargetModulesSearchPathsList
1197 
1198 class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed {
1199 public:
1200   CommandObjectTargetModulesSearchPathsList(CommandInterpreter &interpreter)
1201       : CommandObjectParsed(interpreter, "target modules search-paths list",
1202                             "List all current image search path substitution "
1203                             "pairs in the current target.",
1204                             "target modules search-paths list",
1205                             eCommandRequiresTarget) {}
1206 
1207   ~CommandObjectTargetModulesSearchPathsList() override = default;
1208 
1209 protected:
1210   bool DoExecute(Args &command, CommandReturnObject &result) override {
1211     Target *target = &GetSelectedTarget();
1212     if (command.GetArgumentCount() != 0) {
1213       result.AppendError("list takes no arguments\n");
1214       return result.Succeeded();
1215     }
1216 
1217     target->GetImageSearchPathList().Dump(&result.GetOutputStream());
1218     result.SetStatus(eReturnStatusSuccessFinishResult);
1219     return result.Succeeded();
1220   }
1221 };
1222 
1223 #pragma mark CommandObjectTargetModulesSearchPathsQuery
1224 
1225 class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed {
1226 public:
1227   CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter &interpreter)
1228       : CommandObjectParsed(
1229             interpreter, "target modules search-paths query",
1230             "Transform a path using the first applicable image search path.",
1231             nullptr, eCommandRequiresTarget) {
1232     CommandArgumentEntry arg;
1233     CommandArgumentData path_arg;
1234 
1235     // Define the first (and only) variant of this arg.
1236     path_arg.arg_type = eArgTypeDirectoryName;
1237     path_arg.arg_repetition = eArgRepeatPlain;
1238 
1239     // There is only one variant this argument could be; put it into the
1240     // argument entry.
1241     arg.push_back(path_arg);
1242 
1243     // Push the data for the first argument into the m_arguments vector.
1244     m_arguments.push_back(arg);
1245   }
1246 
1247   ~CommandObjectTargetModulesSearchPathsQuery() override = default;
1248 
1249 protected:
1250   bool DoExecute(Args &command, CommandReturnObject &result) override {
1251     Target *target = &GetSelectedTarget();
1252     if (command.GetArgumentCount() != 1) {
1253       result.AppendError("query requires one argument\n");
1254       return result.Succeeded();
1255     }
1256 
1257     ConstString orig(command.GetArgumentAtIndex(0));
1258     ConstString transformed;
1259     if (target->GetImageSearchPathList().RemapPath(orig, transformed))
1260       result.GetOutputStream().Printf("%s\n", transformed.GetCString());
1261     else
1262       result.GetOutputStream().Printf("%s\n", orig.GetCString());
1263 
1264     result.SetStatus(eReturnStatusSuccessFinishResult);
1265     return result.Succeeded();
1266   }
1267 };
1268 
1269 // Static Helper functions
1270 static void DumpModuleArchitecture(Stream &strm, Module *module,
1271                                    bool full_triple, uint32_t width) {
1272   if (module) {
1273     StreamString arch_strm;
1274 
1275     if (full_triple)
1276       module->GetArchitecture().DumpTriple(arch_strm.AsRawOstream());
1277     else
1278       arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
1279     std::string arch_str = std::string(arch_strm.GetString());
1280 
1281     if (width)
1282       strm.Printf("%-*s", width, arch_str.c_str());
1283     else
1284       strm.PutCString(arch_str);
1285   }
1286 }
1287 
1288 static void DumpModuleUUID(Stream &strm, Module *module) {
1289   if (module && module->GetUUID().IsValid())
1290     module->GetUUID().Dump(&strm);
1291   else
1292     strm.PutCString("                                    ");
1293 }
1294 
1295 static uint32_t DumpCompileUnitLineTable(CommandInterpreter &interpreter,
1296                                          Stream &strm, Module *module,
1297                                          const FileSpec &file_spec,
1298                                          lldb::DescriptionLevel desc_level) {
1299   uint32_t num_matches = 0;
1300   if (module) {
1301     SymbolContextList sc_list;
1302     num_matches = module->ResolveSymbolContextsForFileSpec(
1303         file_spec, 0, false, eSymbolContextCompUnit, sc_list);
1304 
1305     for (uint32_t i = 0; i < num_matches; ++i) {
1306       SymbolContext sc;
1307       if (sc_list.GetContextAtIndex(i, sc)) {
1308         if (i > 0)
1309           strm << "\n\n";
1310 
1311         strm << "Line table for " << sc.comp_unit->GetPrimaryFile() << " in `"
1312              << module->GetFileSpec().GetFilename() << "\n";
1313         LineTable *line_table = sc.comp_unit->GetLineTable();
1314         if (line_table)
1315           line_table->GetDescription(
1316               &strm, interpreter.GetExecutionContext().GetTargetPtr(),
1317               desc_level);
1318         else
1319           strm << "No line table";
1320       }
1321     }
1322   }
1323   return num_matches;
1324 }
1325 
1326 static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr,
1327                          uint32_t width) {
1328   if (file_spec_ptr) {
1329     if (width > 0) {
1330       std::string fullpath = file_spec_ptr->GetPath();
1331       strm.Printf("%-*s", width, fullpath.c_str());
1332       return;
1333     } else {
1334       file_spec_ptr->Dump(strm.AsRawOstream());
1335       return;
1336     }
1337   }
1338   // Keep the width spacing correct if things go wrong...
1339   if (width > 0)
1340     strm.Printf("%-*s", width, "");
1341 }
1342 
1343 static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr,
1344                           uint32_t width) {
1345   if (file_spec_ptr) {
1346     if (width > 0)
1347       strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
1348     else
1349       file_spec_ptr->GetDirectory().Dump(&strm);
1350     return;
1351   }
1352   // Keep the width spacing correct if things go wrong...
1353   if (width > 0)
1354     strm.Printf("%-*s", width, "");
1355 }
1356 
1357 static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,
1358                          uint32_t width) {
1359   if (file_spec_ptr) {
1360     if (width > 0)
1361       strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
1362     else
1363       file_spec_ptr->GetFilename().Dump(&strm);
1364     return;
1365   }
1366   // Keep the width spacing correct if things go wrong...
1367   if (width > 0)
1368     strm.Printf("%-*s", width, "");
1369 }
1370 
1371 static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
1372   std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
1373   const size_t num_modules = module_list.GetSize();
1374   if (num_modules == 0)
1375     return 0;
1376 
1377   size_t num_dumped = 0;
1378   strm.Format("Dumping headers for {0} module(s).\n", num_modules);
1379   strm.IndentMore();
1380   for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
1381     if (module_sp) {
1382       if (num_dumped++ > 0) {
1383         strm.EOL();
1384         strm.EOL();
1385       }
1386       ObjectFile *objfile = module_sp->GetObjectFile();
1387       if (objfile)
1388         objfile->Dump(&strm);
1389       else {
1390         strm.Format("No object file for module: {0:F}\n",
1391                     module_sp->GetFileSpec());
1392       }
1393     }
1394   }
1395   strm.IndentLess();
1396   return num_dumped;
1397 }
1398 
1399 static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm,
1400                              Module *module, SortOrder sort_order,
1401                              Mangled::NamePreference name_preference) {
1402   if (!module)
1403     return;
1404   if (Symtab *symtab = module->GetSymtab())
1405     symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),
1406                  sort_order, name_preference);
1407 }
1408 
1409 static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,
1410                                Module *module) {
1411   if (module) {
1412     SectionList *section_list = module->GetSectionList();
1413     if (section_list) {
1414       strm.Printf("Sections for '%s' (%s):\n",
1415                   module->GetSpecificationDescription().c_str(),
1416                   module->GetArchitecture().GetArchitectureName());
1417       section_list->Dump(strm.AsRawOstream(), strm.GetIndentLevel() + 2,
1418                          interpreter.GetExecutionContext().GetTargetPtr(), true,
1419                          UINT32_MAX);
1420     }
1421   }
1422 }
1423 
1424 static bool DumpModuleSymbolFile(Stream &strm, Module *module) {
1425   if (module) {
1426     if (SymbolFile *symbol_file = module->GetSymbolFile(true)) {
1427       symbol_file->Dump(strm);
1428       return true;
1429     }
1430   }
1431   return false;
1432 }
1433 
1434 static void DumpAddress(ExecutionContextScope *exe_scope,
1435                         const Address &so_addr, bool verbose, Stream &strm) {
1436   strm.IndentMore();
1437   strm.Indent("    Address: ");
1438   so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1439   strm.PutCString(" (");
1440   so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1441   strm.PutCString(")\n");
1442   strm.Indent("    Summary: ");
1443   const uint32_t save_indent = strm.GetIndentLevel();
1444   strm.SetIndentLevel(save_indent + 13);
1445   so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription);
1446   strm.SetIndentLevel(save_indent);
1447   // Print out detailed address information when verbose is enabled
1448   if (verbose) {
1449     strm.EOL();
1450     so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
1451   }
1452   strm.IndentLess();
1453 }
1454 
1455 static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
1456                                   Module *module, uint32_t resolve_mask,
1457                                   lldb::addr_t raw_addr, lldb::addr_t offset,
1458                                   bool verbose) {
1459   if (module) {
1460     lldb::addr_t addr = raw_addr - offset;
1461     Address so_addr;
1462     SymbolContext sc;
1463     Target *target = interpreter.GetExecutionContext().GetTargetPtr();
1464     if (target && !target->GetSectionLoadList().IsEmpty()) {
1465       if (!target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
1466         return false;
1467       else if (so_addr.GetModule().get() != module)
1468         return false;
1469     } else {
1470       if (!module->ResolveFileAddress(addr, so_addr))
1471         return false;
1472     }
1473 
1474     ExecutionContextScope *exe_scope =
1475         interpreter.GetExecutionContext().GetBestExecutionContextScope();
1476     DumpAddress(exe_scope, so_addr, verbose, strm);
1477     //        strm.IndentMore();
1478     //        strm.Indent ("    Address: ");
1479     //        so_addr.Dump (&strm, exe_scope,
1480     //        Address::DumpStyleModuleWithFileAddress);
1481     //        strm.PutCString (" (");
1482     //        so_addr.Dump (&strm, exe_scope,
1483     //        Address::DumpStyleSectionNameOffset);
1484     //        strm.PutCString (")\n");
1485     //        strm.Indent ("    Summary: ");
1486     //        const uint32_t save_indent = strm.GetIndentLevel ();
1487     //        strm.SetIndentLevel (save_indent + 13);
1488     //        so_addr.Dump (&strm, exe_scope,
1489     //        Address::DumpStyleResolvedDescription);
1490     //        strm.SetIndentLevel (save_indent);
1491     //        // Print out detailed address information when verbose is enabled
1492     //        if (verbose)
1493     //        {
1494     //            strm.EOL();
1495     //            so_addr.Dump (&strm, exe_scope,
1496     //            Address::DumpStyleDetailedSymbolContext);
1497     //        }
1498     //        strm.IndentLess();
1499     return true;
1500   }
1501 
1502   return false;
1503 }
1504 
1505 static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
1506                                      Stream &strm, Module *module,
1507                                      const char *name, bool name_is_regex,
1508                                      bool verbose) {
1509   if (!module)
1510     return 0;
1511 
1512   Symtab *symtab = module->GetSymtab();
1513   if (!symtab)
1514     return 0;
1515 
1516   SymbolContext sc;
1517   std::vector<uint32_t> match_indexes;
1518   ConstString symbol_name(name);
1519   uint32_t num_matches = 0;
1520   if (name_is_regex) {
1521     RegularExpression name_regexp(symbol_name.GetStringRef());
1522     num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType(
1523         name_regexp, eSymbolTypeAny, match_indexes);
1524   } else {
1525     num_matches =
1526         symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes);
1527   }
1528 
1529   if (num_matches > 0) {
1530     strm.Indent();
1531     strm.Printf("%u symbols match %s'%s' in ", num_matches,
1532                 name_is_regex ? "the regular expression " : "", name);
1533     DumpFullpath(strm, &module->GetFileSpec(), 0);
1534     strm.PutCString(":\n");
1535     strm.IndentMore();
1536     for (uint32_t i = 0; i < num_matches; ++i) {
1537       Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
1538       if (symbol && symbol->ValueIsAddress()) {
1539         DumpAddress(
1540             interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1541             symbol->GetAddressRef(), verbose, strm);
1542       }
1543     }
1544     strm.IndentLess();
1545   }
1546   return num_matches;
1547 }
1548 
1549 static void DumpSymbolContextList(ExecutionContextScope *exe_scope,
1550                                   Stream &strm, SymbolContextList &sc_list,
1551                                   bool verbose) {
1552   strm.IndentMore();
1553 
1554   const uint32_t num_matches = sc_list.GetSize();
1555 
1556   for (uint32_t i = 0; i < num_matches; ++i) {
1557     SymbolContext sc;
1558     if (sc_list.GetContextAtIndex(i, sc)) {
1559       AddressRange range;
1560 
1561       sc.GetAddressRange(eSymbolContextEverything, 0, true, range);
1562 
1563       DumpAddress(exe_scope, range.GetBaseAddress(), verbose, strm);
1564     }
1565   }
1566   strm.IndentLess();
1567 }
1568 
1569 static size_t LookupFunctionInModule(CommandInterpreter &interpreter,
1570                                      Stream &strm, Module *module,
1571                                      const char *name, bool name_is_regex,
1572                                      const ModuleFunctionSearchOptions &options,
1573                                      bool verbose) {
1574   if (module && name && name[0]) {
1575     SymbolContextList sc_list;
1576     size_t num_matches = 0;
1577     if (name_is_regex) {
1578       RegularExpression function_name_regex((llvm::StringRef(name)));
1579       module->FindFunctions(function_name_regex, options, sc_list);
1580     } else {
1581       ConstString function_name(name);
1582       module->FindFunctions(function_name, CompilerDeclContext(),
1583                             eFunctionNameTypeAuto, options, sc_list);
1584     }
1585     num_matches = sc_list.GetSize();
1586     if (num_matches) {
1587       strm.Indent();
1588       strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1589                   num_matches > 1 ? "es" : "");
1590       DumpFullpath(strm, &module->GetFileSpec(), 0);
1591       strm.PutCString(":\n");
1592       DumpSymbolContextList(
1593           interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1594           strm, sc_list, verbose);
1595     }
1596     return num_matches;
1597   }
1598   return 0;
1599 }
1600 
1601 static size_t LookupTypeInModule(Target *target,
1602                                  CommandInterpreter &interpreter, Stream &strm,
1603                                  Module *module, const char *name_cstr,
1604                                  bool name_is_regex) {
1605   TypeList type_list;
1606   if (module && name_cstr && name_cstr[0]) {
1607     const uint32_t max_num_matches = UINT32_MAX;
1608     size_t num_matches = 0;
1609     bool name_is_fully_qualified = false;
1610 
1611     ConstString name(name_cstr);
1612     llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
1613     module->FindTypes(name, name_is_fully_qualified, max_num_matches,
1614                       searched_symbol_files, type_list);
1615 
1616     if (type_list.Empty())
1617       return 0;
1618 
1619     strm.Indent();
1620     strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1621                 num_matches > 1 ? "es" : "");
1622     DumpFullpath(strm, &module->GetFileSpec(), 0);
1623     strm.PutCString(":\n");
1624     for (TypeSP type_sp : type_list.Types()) {
1625       if (!type_sp)
1626         continue;
1627       // Resolve the clang type so that any forward references to types
1628       // that haven't yet been parsed will get parsed.
1629       type_sp->GetFullCompilerType();
1630       type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
1631       // Print all typedef chains
1632       TypeSP typedef_type_sp(type_sp);
1633       TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1634       while (typedefed_type_sp) {
1635         strm.EOL();
1636         strm.Printf("     typedef '%s': ",
1637                     typedef_type_sp->GetName().GetCString());
1638         typedefed_type_sp->GetFullCompilerType();
1639         typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
1640                                           target);
1641         typedef_type_sp = typedefed_type_sp;
1642         typedefed_type_sp = typedef_type_sp->GetTypedefType();
1643       }
1644     }
1645     strm.EOL();
1646   }
1647   return type_list.GetSize();
1648 }
1649 
1650 static size_t LookupTypeHere(Target *target, CommandInterpreter &interpreter,
1651                              Stream &strm, Module &module,
1652                              const char *name_cstr, bool name_is_regex) {
1653   TypeList type_list;
1654   const uint32_t max_num_matches = UINT32_MAX;
1655   bool name_is_fully_qualified = false;
1656 
1657   ConstString name(name_cstr);
1658   llvm::DenseSet<SymbolFile *> searched_symbol_files;
1659   module.FindTypes(name, name_is_fully_qualified, max_num_matches,
1660                    searched_symbol_files, type_list);
1661 
1662   if (type_list.Empty())
1663     return 0;
1664 
1665   strm.Indent();
1666   strm.PutCString("Best match found in ");
1667   DumpFullpath(strm, &module.GetFileSpec(), 0);
1668   strm.PutCString(":\n");
1669 
1670   TypeSP type_sp(type_list.GetTypeAtIndex(0));
1671   if (type_sp) {
1672     // Resolve the clang type so that any forward references to types that
1673     // haven't yet been parsed will get parsed.
1674     type_sp->GetFullCompilerType();
1675     type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
1676     // Print all typedef chains.
1677     TypeSP typedef_type_sp(type_sp);
1678     TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1679     while (typedefed_type_sp) {
1680       strm.EOL();
1681       strm.Printf("     typedef '%s': ",
1682                   typedef_type_sp->GetName().GetCString());
1683       typedefed_type_sp->GetFullCompilerType();
1684       typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
1685                                         target);
1686       typedef_type_sp = typedefed_type_sp;
1687       typedefed_type_sp = typedef_type_sp->GetTypedefType();
1688     }
1689   }
1690   strm.EOL();
1691   return type_list.GetSize();
1692 }
1693 
1694 static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter,
1695                                           Stream &strm, Module *module,
1696                                           const FileSpec &file_spec,
1697                                           uint32_t line, bool check_inlines,
1698                                           bool verbose) {
1699   if (module && file_spec) {
1700     SymbolContextList sc_list;
1701     const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(
1702         file_spec, line, check_inlines, eSymbolContextEverything, sc_list);
1703     if (num_matches > 0) {
1704       strm.Indent();
1705       strm.Printf("%u match%s found in ", num_matches,
1706                   num_matches > 1 ? "es" : "");
1707       strm << file_spec;
1708       if (line > 0)
1709         strm.Printf(":%u", line);
1710       strm << " in ";
1711       DumpFullpath(strm, &module->GetFileSpec(), 0);
1712       strm.PutCString(":\n");
1713       DumpSymbolContextList(
1714           interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1715           strm, sc_list, verbose);
1716       return num_matches;
1717     }
1718   }
1719   return 0;
1720 }
1721 
1722 static size_t FindModulesByName(Target *target, const char *module_name,
1723                                 ModuleList &module_list,
1724                                 bool check_global_list) {
1725   FileSpec module_file_spec(module_name);
1726   ModuleSpec module_spec(module_file_spec);
1727 
1728   const size_t initial_size = module_list.GetSize();
1729 
1730   if (check_global_list) {
1731     // Check the global list
1732     std::lock_guard<std::recursive_mutex> guard(
1733         Module::GetAllocationModuleCollectionMutex());
1734     const size_t num_modules = Module::GetNumberAllocatedModules();
1735     ModuleSP module_sp;
1736     for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1737       Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
1738 
1739       if (module) {
1740         if (module->MatchesModuleSpec(module_spec)) {
1741           module_sp = module->shared_from_this();
1742           module_list.AppendIfNeeded(module_sp);
1743         }
1744       }
1745     }
1746   } else {
1747     if (target) {
1748       target->GetImages().FindModules(module_spec, module_list);
1749       const size_t num_matches = module_list.GetSize();
1750 
1751       // Not found in our module list for our target, check the main shared
1752       // module list in case it is a extra file used somewhere else
1753       if (num_matches == 0) {
1754         module_spec.GetArchitecture() = target->GetArchitecture();
1755         ModuleList::FindSharedModules(module_spec, module_list);
1756       }
1757     } else {
1758       ModuleList::FindSharedModules(module_spec, module_list);
1759     }
1760   }
1761 
1762   return module_list.GetSize() - initial_size;
1763 }
1764 
1765 #pragma mark CommandObjectTargetModulesModuleAutoComplete
1766 
1767 // A base command object class that can auto complete with module file
1768 // paths
1769 
1770 class CommandObjectTargetModulesModuleAutoComplete
1771     : public CommandObjectParsed {
1772 public:
1773   CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter,
1774                                                const char *name,
1775                                                const char *help,
1776                                                const char *syntax,
1777                                                uint32_t flags = 0)
1778       : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1779     CommandArgumentEntry arg;
1780     CommandArgumentData file_arg;
1781 
1782     // Define the first (and only) variant of this arg.
1783     file_arg.arg_type = eArgTypeFilename;
1784     file_arg.arg_repetition = eArgRepeatStar;
1785 
1786     // There is only one variant this argument could be; put it into the
1787     // argument entry.
1788     arg.push_back(file_arg);
1789 
1790     // Push the data for the first argument into the m_arguments vector.
1791     m_arguments.push_back(arg);
1792   }
1793 
1794   ~CommandObjectTargetModulesModuleAutoComplete() override = default;
1795 
1796   void
1797   HandleArgumentCompletion(CompletionRequest &request,
1798                            OptionElementVector &opt_element_vector) override {
1799     CommandCompletions::InvokeCommonCompletionCallbacks(
1800         GetCommandInterpreter(), CommandCompletions::eModuleCompletion, request,
1801         nullptr);
1802   }
1803 };
1804 
1805 #pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1806 
1807 // A base command object class that can auto complete with module source
1808 // file paths
1809 
1810 class CommandObjectTargetModulesSourceFileAutoComplete
1811     : public CommandObjectParsed {
1812 public:
1813   CommandObjectTargetModulesSourceFileAutoComplete(
1814       CommandInterpreter &interpreter, const char *name, const char *help,
1815       const char *syntax, uint32_t flags)
1816       : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1817     CommandArgumentEntry arg;
1818     CommandArgumentData source_file_arg;
1819 
1820     // Define the first (and only) variant of this arg.
1821     source_file_arg.arg_type = eArgTypeSourceFile;
1822     source_file_arg.arg_repetition = eArgRepeatPlus;
1823 
1824     // There is only one variant this argument could be; put it into the
1825     // argument entry.
1826     arg.push_back(source_file_arg);
1827 
1828     // Push the data for the first argument into the m_arguments vector.
1829     m_arguments.push_back(arg);
1830   }
1831 
1832   ~CommandObjectTargetModulesSourceFileAutoComplete() override = default;
1833 
1834   void
1835   HandleArgumentCompletion(CompletionRequest &request,
1836                            OptionElementVector &opt_element_vector) override {
1837     CommandCompletions::InvokeCommonCompletionCallbacks(
1838         GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion,
1839         request, nullptr);
1840   }
1841 };
1842 
1843 #pragma mark CommandObjectTargetModulesDumpObjfile
1844 
1845 class CommandObjectTargetModulesDumpObjfile
1846     : public CommandObjectTargetModulesModuleAutoComplete {
1847 public:
1848   CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter)
1849       : CommandObjectTargetModulesModuleAutoComplete(
1850             interpreter, "target modules dump objfile",
1851             "Dump the object file headers from one or more target modules.",
1852             nullptr, eCommandRequiresTarget) {}
1853 
1854   ~CommandObjectTargetModulesDumpObjfile() override = default;
1855 
1856 protected:
1857   bool DoExecute(Args &command, CommandReturnObject &result) override {
1858     Target *target = &GetSelectedTarget();
1859 
1860     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1861     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1862     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1863 
1864     size_t num_dumped = 0;
1865     if (command.GetArgumentCount() == 0) {
1866       // Dump all headers for all modules images
1867       num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(),
1868                                             target->GetImages());
1869       if (num_dumped == 0) {
1870         result.AppendError("the target has no associated executable images");
1871       }
1872     } else {
1873       // Find the modules that match the basename or full path.
1874       ModuleList module_list;
1875       const char *arg_cstr;
1876       for (int arg_idx = 0;
1877            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
1878            ++arg_idx) {
1879         size_t num_matched =
1880             FindModulesByName(target, arg_cstr, module_list, true);
1881         if (num_matched == 0) {
1882           result.AppendWarningWithFormat(
1883               "Unable to find an image that matches '%s'.\n", arg_cstr);
1884         }
1885       }
1886       // Dump all the modules we found.
1887       num_dumped =
1888           DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
1889     }
1890 
1891     if (num_dumped > 0) {
1892       result.SetStatus(eReturnStatusSuccessFinishResult);
1893     } else {
1894       result.AppendError("no matching executable images found");
1895     }
1896     return result.Succeeded();
1897   }
1898 };
1899 
1900 #pragma mark CommandObjectTargetModulesDumpSymtab
1901 
1902 static constexpr OptionEnumValueElement g_sort_option_enumeration[] = {
1903     {
1904         eSortOrderNone,
1905         "none",
1906         "No sorting, use the original symbol table order.",
1907     },
1908     {
1909         eSortOrderByAddress,
1910         "address",
1911         "Sort output by symbol address.",
1912     },
1913     {
1914         eSortOrderByName,
1915         "name",
1916         "Sort output by symbol name.",
1917     },
1918 };
1919 
1920 #define LLDB_OPTIONS_target_modules_dump_symtab
1921 #include "CommandOptions.inc"
1922 
1923 class CommandObjectTargetModulesDumpSymtab
1924     : public CommandObjectTargetModulesModuleAutoComplete {
1925 public:
1926   CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter)
1927       : CommandObjectTargetModulesModuleAutoComplete(
1928             interpreter, "target modules dump symtab",
1929             "Dump the symbol table from one or more target modules.", nullptr,
1930             eCommandRequiresTarget),
1931         m_options() {}
1932 
1933   ~CommandObjectTargetModulesDumpSymtab() override = default;
1934 
1935   Options *GetOptions() override { return &m_options; }
1936 
1937   class CommandOptions : public Options {
1938   public:
1939     CommandOptions() : Options() {}
1940 
1941     ~CommandOptions() override = default;
1942 
1943     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1944                           ExecutionContext *execution_context) override {
1945       Status error;
1946       const int short_option = m_getopt_table[option_idx].val;
1947 
1948       switch (short_option) {
1949       case 'm':
1950         m_prefer_mangled.SetCurrentValue(true);
1951         m_prefer_mangled.SetOptionWasSet();
1952         break;
1953 
1954       case 's':
1955         m_sort_order = (SortOrder)OptionArgParser::ToOptionEnum(
1956             option_arg, GetDefinitions()[option_idx].enum_values,
1957             eSortOrderNone, error);
1958         break;
1959 
1960       default:
1961         llvm_unreachable("Unimplemented option");
1962       }
1963       return error;
1964     }
1965 
1966     void OptionParsingStarting(ExecutionContext *execution_context) override {
1967       m_sort_order = eSortOrderNone;
1968       m_prefer_mangled.Clear();
1969     }
1970 
1971     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1972       return llvm::makeArrayRef(g_target_modules_dump_symtab_options);
1973     }
1974 
1975     SortOrder m_sort_order = eSortOrderNone;
1976     OptionValueBoolean m_prefer_mangled = {false, false};
1977   };
1978 
1979 protected:
1980   bool DoExecute(Args &command, CommandReturnObject &result) override {
1981     Target *target = &GetSelectedTarget();
1982     uint32_t num_dumped = 0;
1983     Mangled::NamePreference name_preference =
1984         (m_options.m_prefer_mangled ? Mangled::ePreferMangled
1985                                     : Mangled::ePreferDemangled);
1986 
1987     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1988     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1989     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1990 
1991     if (command.GetArgumentCount() == 0) {
1992       // Dump all sections for all modules images
1993       const ModuleList &module_list = target->GetImages();
1994       std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
1995       const size_t num_modules = module_list.GetSize();
1996       if (num_modules > 0) {
1997         result.GetOutputStream().Format(
1998             "Dumping symbol table for {0} modules.\n", num_modules);
1999         for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
2000           if (num_dumped > 0) {
2001             result.GetOutputStream().EOL();
2002             result.GetOutputStream().EOL();
2003           }
2004           if (m_interpreter.WasInterrupted())
2005             break;
2006           num_dumped++;
2007           DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
2008                            module_sp.get(), m_options.m_sort_order,
2009                            name_preference);
2010         }
2011       } else {
2012         result.AppendError("the target has no associated executable images");
2013         return false;
2014       }
2015     } else {
2016       // Dump specified images (by basename or fullpath)
2017       const char *arg_cstr;
2018       for (int arg_idx = 0;
2019            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2020            ++arg_idx) {
2021         ModuleList module_list;
2022         const size_t num_matches =
2023             FindModulesByName(target, arg_cstr, module_list, true);
2024         if (num_matches > 0) {
2025           for (ModuleSP module_sp : module_list.Modules()) {
2026             if (module_sp) {
2027               if (num_dumped > 0) {
2028                 result.GetOutputStream().EOL();
2029                 result.GetOutputStream().EOL();
2030               }
2031               if (m_interpreter.WasInterrupted())
2032                 break;
2033               num_dumped++;
2034               DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
2035                                module_sp.get(), m_options.m_sort_order,
2036                                name_preference);
2037             }
2038           }
2039         } else
2040           result.AppendWarningWithFormat(
2041               "Unable to find an image that matches '%s'.\n", arg_cstr);
2042       }
2043     }
2044 
2045     if (num_dumped > 0)
2046       result.SetStatus(eReturnStatusSuccessFinishResult);
2047     else {
2048       result.AppendError("no matching executable images found");
2049     }
2050     return result.Succeeded();
2051   }
2052 
2053   CommandOptions m_options;
2054 };
2055 
2056 #pragma mark CommandObjectTargetModulesDumpSections
2057 
2058 // Image section dumping command
2059 
2060 class CommandObjectTargetModulesDumpSections
2061     : public CommandObjectTargetModulesModuleAutoComplete {
2062 public:
2063   CommandObjectTargetModulesDumpSections(CommandInterpreter &interpreter)
2064       : CommandObjectTargetModulesModuleAutoComplete(
2065             interpreter, "target modules dump sections",
2066             "Dump the sections from one or more target modules.",
2067             //"target modules dump sections [<file1> ...]")
2068             nullptr, eCommandRequiresTarget) {}
2069 
2070   ~CommandObjectTargetModulesDumpSections() override = default;
2071 
2072 protected:
2073   bool DoExecute(Args &command, CommandReturnObject &result) override {
2074     Target *target = &GetSelectedTarget();
2075     uint32_t num_dumped = 0;
2076 
2077     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2078     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2079     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2080 
2081     if (command.GetArgumentCount() == 0) {
2082       // Dump all sections for all modules images
2083       const size_t num_modules = target->GetImages().GetSize();
2084       if (num_modules == 0) {
2085         result.AppendError("the target has no associated executable images");
2086         return false;
2087       }
2088 
2089       result.GetOutputStream().Format("Dumping sections for {0} modules.\n",
2090                                       num_modules);
2091       for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2092         if (m_interpreter.WasInterrupted())
2093           break;
2094         num_dumped++;
2095         DumpModuleSections(
2096             m_interpreter, result.GetOutputStream(),
2097             target->GetImages().GetModulePointerAtIndex(image_idx));
2098       }
2099     } else {
2100       // Dump specified images (by basename or fullpath)
2101       const char *arg_cstr;
2102       for (int arg_idx = 0;
2103            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2104            ++arg_idx) {
2105         ModuleList module_list;
2106         const size_t num_matches =
2107             FindModulesByName(target, arg_cstr, module_list, true);
2108         if (num_matches > 0) {
2109           for (size_t i = 0; i < num_matches; ++i) {
2110             if (m_interpreter.WasInterrupted())
2111               break;
2112             Module *module = module_list.GetModulePointerAtIndex(i);
2113             if (module) {
2114               num_dumped++;
2115               DumpModuleSections(m_interpreter, result.GetOutputStream(),
2116                                  module);
2117             }
2118           }
2119         } else {
2120           // Check the global list
2121           std::lock_guard<std::recursive_mutex> guard(
2122               Module::GetAllocationModuleCollectionMutex());
2123 
2124           result.AppendWarningWithFormat(
2125               "Unable to find an image that matches '%s'.\n", arg_cstr);
2126         }
2127       }
2128     }
2129 
2130     if (num_dumped > 0)
2131       result.SetStatus(eReturnStatusSuccessFinishResult);
2132     else {
2133       result.AppendError("no matching executable images found");
2134     }
2135     return result.Succeeded();
2136   }
2137 };
2138 
2139 #pragma mark CommandObjectTargetModulesDumpClangAST
2140 
2141 // Clang AST dumping command
2142 
2143 class CommandObjectTargetModulesDumpClangAST
2144     : public CommandObjectTargetModulesModuleAutoComplete {
2145 public:
2146   CommandObjectTargetModulesDumpClangAST(CommandInterpreter &interpreter)
2147       : CommandObjectTargetModulesModuleAutoComplete(
2148             interpreter, "target modules dump ast",
2149             "Dump the clang ast for a given module's symbol file.",
2150             //"target modules dump ast [<file1> ...]")
2151             nullptr, eCommandRequiresTarget) {}
2152 
2153   ~CommandObjectTargetModulesDumpClangAST() override = default;
2154 
2155 protected:
2156   bool DoExecute(Args &command, CommandReturnObject &result) override {
2157     Target *target = &GetSelectedTarget();
2158 
2159     const ModuleList &module_list = target->GetImages();
2160     const size_t num_modules = module_list.GetSize();
2161     if (num_modules == 0) {
2162       result.AppendError("the target has no associated executable images");
2163       return false;
2164     }
2165 
2166     if (command.GetArgumentCount() == 0) {
2167       // Dump all ASTs for all modules images
2168       result.GetOutputStream().Format("Dumping clang ast for {0} modules.\n",
2169                                       num_modules);
2170       for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
2171         if (m_interpreter.WasInterrupted())
2172           break;
2173         if (SymbolFile *sf = module_sp->GetSymbolFile())
2174           sf->DumpClangAST(result.GetOutputStream());
2175       }
2176       result.SetStatus(eReturnStatusSuccessFinishResult);
2177       return true;
2178     }
2179 
2180     // Dump specified ASTs (by basename or fullpath)
2181     for (const Args::ArgEntry &arg : command.entries()) {
2182       ModuleList module_list;
2183       const size_t num_matches =
2184           FindModulesByName(target, arg.c_str(), module_list, true);
2185       if (num_matches == 0) {
2186         // Check the global list
2187         std::lock_guard<std::recursive_mutex> guard(
2188             Module::GetAllocationModuleCollectionMutex());
2189 
2190         result.AppendWarningWithFormat(
2191             "Unable to find an image that matches '%s'.\n", arg.c_str());
2192         continue;
2193       }
2194 
2195       for (size_t i = 0; i < num_matches; ++i) {
2196         if (m_interpreter.WasInterrupted())
2197           break;
2198         Module *m = module_list.GetModulePointerAtIndex(i);
2199         if (SymbolFile *sf = m->GetSymbolFile())
2200           sf->DumpClangAST(result.GetOutputStream());
2201       }
2202     }
2203     result.SetStatus(eReturnStatusSuccessFinishResult);
2204     return true;
2205   }
2206 };
2207 
2208 #pragma mark CommandObjectTargetModulesDumpSymfile
2209 
2210 // Image debug symbol dumping command
2211 
2212 class CommandObjectTargetModulesDumpSymfile
2213     : public CommandObjectTargetModulesModuleAutoComplete {
2214 public:
2215   CommandObjectTargetModulesDumpSymfile(CommandInterpreter &interpreter)
2216       : CommandObjectTargetModulesModuleAutoComplete(
2217             interpreter, "target modules dump symfile",
2218             "Dump the debug symbol file for one or more target modules.",
2219             //"target modules dump symfile [<file1> ...]")
2220             nullptr, eCommandRequiresTarget) {}
2221 
2222   ~CommandObjectTargetModulesDumpSymfile() override = default;
2223 
2224 protected:
2225   bool DoExecute(Args &command, CommandReturnObject &result) override {
2226     Target *target = &GetSelectedTarget();
2227     uint32_t num_dumped = 0;
2228 
2229     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2230     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2231     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2232 
2233     if (command.GetArgumentCount() == 0) {
2234       // Dump all sections for all modules images
2235       const ModuleList &target_modules = target->GetImages();
2236       std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2237       const size_t num_modules = target_modules.GetSize();
2238       if (num_modules == 0) {
2239         result.AppendError("the target has no associated executable images");
2240         return false;
2241       }
2242       result.GetOutputStream().Format(
2243           "Dumping debug symbols for {0} modules.\n", num_modules);
2244       for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
2245         if (m_interpreter.WasInterrupted())
2246           break;
2247         if (DumpModuleSymbolFile(result.GetOutputStream(), module_sp.get()))
2248           num_dumped++;
2249       }
2250     } else {
2251       // Dump specified images (by basename or fullpath)
2252       const char *arg_cstr;
2253       for (int arg_idx = 0;
2254            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2255            ++arg_idx) {
2256         ModuleList module_list;
2257         const size_t num_matches =
2258             FindModulesByName(target, arg_cstr, module_list, true);
2259         if (num_matches > 0) {
2260           for (size_t i = 0; i < num_matches; ++i) {
2261             if (m_interpreter.WasInterrupted())
2262               break;
2263             Module *module = module_list.GetModulePointerAtIndex(i);
2264             if (module) {
2265               if (DumpModuleSymbolFile(result.GetOutputStream(), module))
2266                 num_dumped++;
2267             }
2268           }
2269         } else
2270           result.AppendWarningWithFormat(
2271               "Unable to find an image that matches '%s'.\n", arg_cstr);
2272       }
2273     }
2274 
2275     if (num_dumped > 0)
2276       result.SetStatus(eReturnStatusSuccessFinishResult);
2277     else {
2278       result.AppendError("no matching executable images found");
2279     }
2280     return result.Succeeded();
2281   }
2282 };
2283 
2284 #pragma mark CommandObjectTargetModulesDumpLineTable
2285 #define LLDB_OPTIONS_target_modules_dump
2286 #include "CommandOptions.inc"
2287 
2288 // Image debug line table dumping command
2289 
2290 class CommandObjectTargetModulesDumpLineTable
2291     : public CommandObjectTargetModulesSourceFileAutoComplete {
2292 public:
2293   CommandObjectTargetModulesDumpLineTable(CommandInterpreter &interpreter)
2294       : CommandObjectTargetModulesSourceFileAutoComplete(
2295             interpreter, "target modules dump line-table",
2296             "Dump the line table for one or more compilation units.", nullptr,
2297             eCommandRequiresTarget) {}
2298 
2299   ~CommandObjectTargetModulesDumpLineTable() override = default;
2300 
2301   Options *GetOptions() override { return &m_options; }
2302 
2303 protected:
2304   bool DoExecute(Args &command, CommandReturnObject &result) override {
2305     Target *target = m_exe_ctx.GetTargetPtr();
2306     uint32_t total_num_dumped = 0;
2307 
2308     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2309     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2310     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2311 
2312     if (command.GetArgumentCount() == 0) {
2313       result.AppendError("file option must be specified.");
2314       return result.Succeeded();
2315     } else {
2316       // Dump specified images (by basename or fullpath)
2317       const char *arg_cstr;
2318       for (int arg_idx = 0;
2319            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2320            ++arg_idx) {
2321         FileSpec file_spec(arg_cstr);
2322 
2323         const ModuleList &target_modules = target->GetImages();
2324         std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2325         if (target_modules.GetSize() > 0) {
2326           uint32_t num_dumped = 0;
2327           for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
2328             if (m_interpreter.WasInterrupted())
2329               break;
2330             if (DumpCompileUnitLineTable(
2331                     m_interpreter, result.GetOutputStream(), module_sp.get(),
2332                     file_spec,
2333                     m_options.m_verbose ? eDescriptionLevelFull
2334                                         : eDescriptionLevelBrief))
2335               num_dumped++;
2336           }
2337           if (num_dumped == 0)
2338             result.AppendWarningWithFormat(
2339                 "No source filenames matched '%s'.\n", arg_cstr);
2340           else
2341             total_num_dumped += num_dumped;
2342         }
2343       }
2344     }
2345 
2346     if (total_num_dumped > 0)
2347       result.SetStatus(eReturnStatusSuccessFinishResult);
2348     else {
2349       result.AppendError("no source filenames matched any command arguments");
2350     }
2351     return result.Succeeded();
2352   }
2353 
2354   class CommandOptions : public Options {
2355   public:
2356     CommandOptions() : Options() { OptionParsingStarting(nullptr); }
2357 
2358     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2359                           ExecutionContext *execution_context) override {
2360       assert(option_idx == 0 && "We only have one option.");
2361       m_verbose = true;
2362 
2363       return Status();
2364     }
2365 
2366     void OptionParsingStarting(ExecutionContext *execution_context) override {
2367       m_verbose = false;
2368     }
2369 
2370     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2371       return llvm::makeArrayRef(g_target_modules_dump_options);
2372     }
2373 
2374     bool m_verbose;
2375   };
2376 
2377   CommandOptions m_options;
2378 };
2379 
2380 #pragma mark CommandObjectTargetModulesDump
2381 
2382 // Dump multi-word command for target modules
2383 
2384 class CommandObjectTargetModulesDump : public CommandObjectMultiword {
2385 public:
2386   // Constructors and Destructors
2387   CommandObjectTargetModulesDump(CommandInterpreter &interpreter)
2388       : CommandObjectMultiword(
2389             interpreter, "target modules dump",
2390             "Commands for dumping information about one or "
2391             "more target modules.",
2392             "target modules dump "
2393             "[headers|symtab|sections|ast|symfile|line-table] "
2394             "[<file1> <file2> ...]") {
2395     LoadSubCommand("objfile",
2396                    CommandObjectSP(
2397                        new CommandObjectTargetModulesDumpObjfile(interpreter)));
2398     LoadSubCommand(
2399         "symtab",
2400         CommandObjectSP(new CommandObjectTargetModulesDumpSymtab(interpreter)));
2401     LoadSubCommand("sections",
2402                    CommandObjectSP(new CommandObjectTargetModulesDumpSections(
2403                        interpreter)));
2404     LoadSubCommand("symfile",
2405                    CommandObjectSP(
2406                        new CommandObjectTargetModulesDumpSymfile(interpreter)));
2407     LoadSubCommand(
2408         "ast", CommandObjectSP(
2409                    new CommandObjectTargetModulesDumpClangAST(interpreter)));
2410     LoadSubCommand("line-table",
2411                    CommandObjectSP(new CommandObjectTargetModulesDumpLineTable(
2412                        interpreter)));
2413   }
2414 
2415   ~CommandObjectTargetModulesDump() override = default;
2416 };
2417 
2418 class CommandObjectTargetModulesAdd : public CommandObjectParsed {
2419 public:
2420   CommandObjectTargetModulesAdd(CommandInterpreter &interpreter)
2421       : CommandObjectParsed(interpreter, "target modules add",
2422                             "Add a new module to the current target's modules.",
2423                             "target modules add [<module>]",
2424                             eCommandRequiresTarget),
2425         m_option_group(), m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's',
2426                                         0, eArgTypeFilename,
2427                                         "Fullpath to a stand alone debug "
2428                                         "symbols file for when debug symbols "
2429                                         "are not in the executable.") {
2430     m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2431                           LLDB_OPT_SET_1);
2432     m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2433     m_option_group.Finalize();
2434   }
2435 
2436   ~CommandObjectTargetModulesAdd() override = default;
2437 
2438   Options *GetOptions() override { return &m_option_group; }
2439 
2440   void
2441   HandleArgumentCompletion(CompletionRequest &request,
2442                            OptionElementVector &opt_element_vector) override {
2443     CommandCompletions::InvokeCommonCompletionCallbacks(
2444         GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
2445         request, nullptr);
2446   }
2447 
2448 protected:
2449   OptionGroupOptions m_option_group;
2450   OptionGroupUUID m_uuid_option_group;
2451   OptionGroupFile m_symbol_file;
2452 
2453   bool DoExecute(Args &args, CommandReturnObject &result) override {
2454     Target *target = &GetSelectedTarget();
2455     bool flush = false;
2456 
2457     const size_t argc = args.GetArgumentCount();
2458     if (argc == 0) {
2459       if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2460         // We are given a UUID only, go locate the file
2461         ModuleSpec module_spec;
2462         module_spec.GetUUID() =
2463             m_uuid_option_group.GetOptionValue().GetCurrentValue();
2464         if (m_symbol_file.GetOptionValue().OptionWasSet())
2465           module_spec.GetSymbolFileSpec() =
2466               m_symbol_file.GetOptionValue().GetCurrentValue();
2467         if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
2468           ModuleSP module_sp(
2469               target->GetOrCreateModule(module_spec, true /* notify */));
2470           if (module_sp) {
2471             result.SetStatus(eReturnStatusSuccessFinishResult);
2472             return true;
2473           } else {
2474             StreamString strm;
2475             module_spec.GetUUID().Dump(&strm);
2476             if (module_spec.GetFileSpec()) {
2477               if (module_spec.GetSymbolFileSpec()) {
2478                 result.AppendErrorWithFormat(
2479                     "Unable to create the executable or symbol file with "
2480                     "UUID %s with path %s and symbol file %s",
2481                     strm.GetData(), module_spec.GetFileSpec().GetPath().c_str(),
2482                     module_spec.GetSymbolFileSpec().GetPath().c_str());
2483               } else {
2484                 result.AppendErrorWithFormat(
2485                     "Unable to create the executable or symbol file with "
2486                     "UUID %s with path %s",
2487                     strm.GetData(),
2488                     module_spec.GetFileSpec().GetPath().c_str());
2489               }
2490             } else {
2491               result.AppendErrorWithFormat("Unable to create the executable "
2492                                            "or symbol file with UUID %s",
2493                                            strm.GetData());
2494             }
2495             return false;
2496           }
2497         } else {
2498           StreamString strm;
2499           module_spec.GetUUID().Dump(&strm);
2500           result.AppendErrorWithFormat(
2501               "Unable to locate the executable or symbol file with UUID %s",
2502               strm.GetData());
2503           return false;
2504         }
2505       } else {
2506         result.AppendError(
2507             "one or more executable image paths must be specified");
2508         return false;
2509       }
2510     } else {
2511       for (auto &entry : args.entries()) {
2512         if (entry.ref().empty())
2513           continue;
2514 
2515         FileSpec file_spec(entry.ref());
2516         if (FileSystem::Instance().Exists(file_spec)) {
2517           ModuleSpec module_spec(file_spec);
2518           if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2519             module_spec.GetUUID() =
2520                 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2521           if (m_symbol_file.GetOptionValue().OptionWasSet())
2522             module_spec.GetSymbolFileSpec() =
2523                 m_symbol_file.GetOptionValue().GetCurrentValue();
2524           if (!module_spec.GetArchitecture().IsValid())
2525             module_spec.GetArchitecture() = target->GetArchitecture();
2526           Status error;
2527           ModuleSP module_sp(target->GetOrCreateModule(
2528               module_spec, true /* notify */, &error));
2529           if (!module_sp) {
2530             const char *error_cstr = error.AsCString();
2531             if (error_cstr)
2532               result.AppendError(error_cstr);
2533             else
2534               result.AppendErrorWithFormat("unsupported module: %s",
2535                                            entry.c_str());
2536             return false;
2537           } else {
2538             flush = true;
2539           }
2540           result.SetStatus(eReturnStatusSuccessFinishResult);
2541         } else {
2542           std::string resolved_path = file_spec.GetPath();
2543           if (resolved_path != entry.ref()) {
2544             result.AppendErrorWithFormat(
2545                 "invalid module path '%s' with resolved path '%s'\n",
2546                 entry.ref().str().c_str(), resolved_path.c_str());
2547             break;
2548           }
2549           result.AppendErrorWithFormat("invalid module path '%s'\n",
2550                                        entry.c_str());
2551           break;
2552         }
2553       }
2554     }
2555 
2556     if (flush) {
2557       ProcessSP process = target->GetProcessSP();
2558       if (process)
2559         process->Flush();
2560     }
2561 
2562     return result.Succeeded();
2563   }
2564 };
2565 
2566 class CommandObjectTargetModulesLoad
2567     : public CommandObjectTargetModulesModuleAutoComplete {
2568 public:
2569   CommandObjectTargetModulesLoad(CommandInterpreter &interpreter)
2570       : CommandObjectTargetModulesModuleAutoComplete(
2571             interpreter, "target modules load",
2572             "Set the load addresses for one or more sections in a target "
2573             "module.",
2574             "target modules load [--file <module> --uuid <uuid>] <sect-name> "
2575             "<address> [<sect-name> <address> ....]",
2576             eCommandRequiresTarget),
2577         m_option_group(),
2578         m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,
2579                       "Fullpath or basename for module to load.", ""),
2580         m_load_option(LLDB_OPT_SET_1, false, "load", 'l',
2581                       "Write file contents to the memory.", false, true),
2582         m_pc_option(LLDB_OPT_SET_1, false, "set-pc-to-entry", 'p',
2583                     "Set PC to the entry point."
2584                     " Only applicable with '--load' option.",
2585                     false, true),
2586         m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,
2587                        "Set the load address for all sections to be the "
2588                        "virtual address in the file plus the offset.",
2589                        0) {
2590     m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2591                           LLDB_OPT_SET_1);
2592     m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2593     m_option_group.Append(&m_load_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2594     m_option_group.Append(&m_pc_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2595     m_option_group.Append(&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2596     m_option_group.Finalize();
2597   }
2598 
2599   ~CommandObjectTargetModulesLoad() override = default;
2600 
2601   Options *GetOptions() override { return &m_option_group; }
2602 
2603 protected:
2604   bool DoExecute(Args &args, CommandReturnObject &result) override {
2605     Target *target = &GetSelectedTarget();
2606     const bool load = m_load_option.GetOptionValue().GetCurrentValue();
2607     const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue();
2608 
2609     const size_t argc = args.GetArgumentCount();
2610     ModuleSpec module_spec;
2611     bool search_using_module_spec = false;
2612 
2613     // Allow "load" option to work without --file or --uuid option.
2614     if (load) {
2615       if (!m_file_option.GetOptionValue().OptionWasSet() &&
2616           !m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2617         ModuleList &module_list = target->GetImages();
2618         if (module_list.GetSize() == 1) {
2619           search_using_module_spec = true;
2620           module_spec.GetFileSpec() =
2621               module_list.GetModuleAtIndex(0)->GetFileSpec();
2622         }
2623       }
2624     }
2625 
2626     if (m_file_option.GetOptionValue().OptionWasSet()) {
2627       search_using_module_spec = true;
2628       const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
2629       const bool use_global_module_list = true;
2630       ModuleList module_list;
2631       const size_t num_matches = FindModulesByName(
2632           target, arg_cstr, module_list, use_global_module_list);
2633       if (num_matches == 1) {
2634         module_spec.GetFileSpec() =
2635             module_list.GetModuleAtIndex(0)->GetFileSpec();
2636       } else if (num_matches > 1) {
2637         search_using_module_spec = false;
2638         result.AppendErrorWithFormat(
2639             "more than 1 module matched by name '%s'\n", arg_cstr);
2640       } else {
2641         search_using_module_spec = false;
2642         result.AppendErrorWithFormat("no object file for module '%s'\n",
2643                                      arg_cstr);
2644       }
2645     }
2646 
2647     if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2648       search_using_module_spec = true;
2649       module_spec.GetUUID() =
2650           m_uuid_option_group.GetOptionValue().GetCurrentValue();
2651     }
2652 
2653     if (search_using_module_spec) {
2654       ModuleList matching_modules;
2655       target->GetImages().FindModules(module_spec, matching_modules);
2656       const size_t num_matches = matching_modules.GetSize();
2657 
2658       char path[PATH_MAX];
2659       if (num_matches == 1) {
2660         Module *module = matching_modules.GetModulePointerAtIndex(0);
2661         if (module) {
2662           ObjectFile *objfile = module->GetObjectFile();
2663           if (objfile) {
2664             SectionList *section_list = module->GetSectionList();
2665             if (section_list) {
2666               bool changed = false;
2667               if (argc == 0) {
2668                 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2669                   const addr_t slide =
2670                       m_slide_option.GetOptionValue().GetCurrentValue();
2671                   const bool slide_is_offset = true;
2672                   module->SetLoadAddress(*target, slide, slide_is_offset,
2673                                          changed);
2674                 } else {
2675                   result.AppendError("one or more section name + load "
2676                                      "address pair must be specified");
2677                   return false;
2678                 }
2679               } else {
2680                 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2681                   result.AppendError("The \"--slide <offset>\" option can't "
2682                                      "be used in conjunction with setting "
2683                                      "section load addresses.\n");
2684                   return false;
2685                 }
2686 
2687                 for (size_t i = 0; i < argc; i += 2) {
2688                   const char *sect_name = args.GetArgumentAtIndex(i);
2689                   const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
2690                   if (sect_name && load_addr_cstr) {
2691                     ConstString const_sect_name(sect_name);
2692                     addr_t load_addr;
2693                     if (llvm::to_integer(load_addr_cstr, load_addr)) {
2694                       SectionSP section_sp(
2695                           section_list->FindSectionByName(const_sect_name));
2696                       if (section_sp) {
2697                         if (section_sp->IsThreadSpecific()) {
2698                           result.AppendErrorWithFormat(
2699                               "thread specific sections are not yet "
2700                               "supported (section '%s')\n",
2701                               sect_name);
2702                           break;
2703                         } else {
2704                           if (target->GetSectionLoadList()
2705                                   .SetSectionLoadAddress(section_sp, load_addr))
2706                             changed = true;
2707                           result.AppendMessageWithFormat(
2708                               "section '%s' loaded at 0x%" PRIx64 "\n",
2709                               sect_name, load_addr);
2710                         }
2711                       } else {
2712                         result.AppendErrorWithFormat("no section found that "
2713                                                      "matches the section "
2714                                                      "name '%s'\n",
2715                                                      sect_name);
2716                         break;
2717                       }
2718                     } else {
2719                       result.AppendErrorWithFormat(
2720                           "invalid load address string '%s'\n", load_addr_cstr);
2721                       break;
2722                     }
2723                   } else {
2724                     if (sect_name)
2725                       result.AppendError("section names must be followed by "
2726                                          "a load address.\n");
2727                     else
2728                       result.AppendError("one or more section name + load "
2729                                          "address pair must be specified.\n");
2730                     break;
2731                   }
2732                 }
2733               }
2734 
2735               if (changed) {
2736                 target->ModulesDidLoad(matching_modules);
2737                 Process *process = m_exe_ctx.GetProcessPtr();
2738                 if (process)
2739                   process->Flush();
2740               }
2741               if (load) {
2742                 ProcessSP process = target->CalculateProcess();
2743                 Address file_entry = objfile->GetEntryPointAddress();
2744                 if (!process) {
2745                   result.AppendError("No process");
2746                   return false;
2747                 }
2748                 if (set_pc && !file_entry.IsValid()) {
2749                   result.AppendError("No entry address in object file");
2750                   return false;
2751                 }
2752                 std::vector<ObjectFile::LoadableData> loadables(
2753                     objfile->GetLoadableData(*target));
2754                 if (loadables.size() == 0) {
2755                   result.AppendError("No loadable sections");
2756                   return false;
2757                 }
2758                 Status error = process->WriteObjectFile(std::move(loadables));
2759                 if (error.Fail()) {
2760                   result.AppendError(error.AsCString());
2761                   return false;
2762                 }
2763                 if (set_pc) {
2764                   ThreadList &thread_list = process->GetThreadList();
2765                   RegisterContextSP reg_context(
2766                       thread_list.GetSelectedThread()->GetRegisterContext());
2767                   addr_t file_entry_addr = file_entry.GetLoadAddress(target);
2768                   if (!reg_context->SetPC(file_entry_addr)) {
2769                     result.AppendErrorWithFormat("failed to set PC value to "
2770                                                  "0x%" PRIx64 "\n",
2771                                                  file_entry_addr);
2772                   }
2773                 }
2774               }
2775             } else {
2776               module->GetFileSpec().GetPath(path, sizeof(path));
2777               result.AppendErrorWithFormat("no sections in object file '%s'\n",
2778                                            path);
2779             }
2780           } else {
2781             module->GetFileSpec().GetPath(path, sizeof(path));
2782             result.AppendErrorWithFormat("no object file for module '%s'\n",
2783                                          path);
2784           }
2785         } else {
2786           FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
2787           if (module_spec_file) {
2788             module_spec_file->GetPath(path, sizeof(path));
2789             result.AppendErrorWithFormat("invalid module '%s'.\n", path);
2790           } else
2791             result.AppendError("no module spec");
2792         }
2793       } else {
2794         std::string uuid_str;
2795 
2796         if (module_spec.GetFileSpec())
2797           module_spec.GetFileSpec().GetPath(path, sizeof(path));
2798         else
2799           path[0] = '\0';
2800 
2801         if (module_spec.GetUUIDPtr())
2802           uuid_str = module_spec.GetUUID().GetAsString();
2803         if (num_matches > 1) {
2804           result.AppendErrorWithFormat(
2805               "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "",
2806               path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
2807           for (size_t i = 0; i < num_matches; ++i) {
2808             if (matching_modules.GetModulePointerAtIndex(i)
2809                     ->GetFileSpec()
2810                     .GetPath(path, sizeof(path)))
2811               result.AppendMessageWithFormat("%s\n", path);
2812           }
2813         } else {
2814           result.AppendErrorWithFormat(
2815               "no modules were found  that match%s%s%s%s.\n",
2816               path[0] ? " file=" : "", path, !uuid_str.empty() ? " uuid=" : "",
2817               uuid_str.c_str());
2818         }
2819       }
2820     } else {
2821       result.AppendError("either the \"--file <module>\" or the \"--uuid "
2822                          "<uuid>\" option must be specified.\n");
2823       return false;
2824     }
2825     return result.Succeeded();
2826   }
2827 
2828   OptionGroupOptions m_option_group;
2829   OptionGroupUUID m_uuid_option_group;
2830   OptionGroupString m_file_option;
2831   OptionGroupBoolean m_load_option;
2832   OptionGroupBoolean m_pc_option;
2833   OptionGroupUInt64 m_slide_option;
2834 };
2835 
2836 #pragma mark CommandObjectTargetModulesList
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.", false,
3966             true),
3967         m_current_stack_option(LLDB_OPT_SET_2, false, "stack", 'S',
3968                                "Locate the debug symbols for every frame in "
3969                                "the current call stack.",
3970                                false, true)
3971 
3972   {
3973     m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
3974                           LLDB_OPT_SET_1);
3975     m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
3976     m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2,
3977                           LLDB_OPT_SET_2);
3978     m_option_group.Append(&m_current_stack_option, LLDB_OPT_SET_2,
3979                           LLDB_OPT_SET_2);
3980     m_option_group.Finalize();
3981   }
3982 
3983   ~CommandObjectTargetSymbolsAdd() override = default;
3984 
3985   void
3986   HandleArgumentCompletion(CompletionRequest &request,
3987                            OptionElementVector &opt_element_vector) override {
3988     CommandCompletions::InvokeCommonCompletionCallbacks(
3989         GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
3990         request, nullptr);
3991   }
3992 
3993   Options *GetOptions() override { return &m_option_group; }
3994 
3995 protected:
3996   bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,
3997                         CommandReturnObject &result) {
3998     const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
3999     if (!symbol_fspec) {
4000       result.AppendError(
4001           "one or more executable image paths must be specified");
4002       return false;
4003     }
4004 
4005     char symfile_path[PATH_MAX];
4006     symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));
4007 
4008     if (!module_spec.GetUUID().IsValid()) {
4009       if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
4010         module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
4011     }
4012 
4013     // Now module_spec represents a symbol file for a module that might exist
4014     // in the current target.  Let's find possible matches.
4015     ModuleList matching_modules;
4016 
4017     // First extract all module specs from the symbol file
4018     lldb_private::ModuleSpecList symfile_module_specs;
4019     if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(),
4020                                             0, 0, symfile_module_specs)) {
4021       // Now extract the module spec that matches the target architecture
4022       ModuleSpec target_arch_module_spec;
4023       ModuleSpec symfile_module_spec;
4024       target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
4025       if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,
4026                                                       symfile_module_spec)) {
4027         if (symfile_module_spec.GetUUID().IsValid()) {
4028           // It has a UUID, look for this UUID in the target modules
4029           ModuleSpec symfile_uuid_module_spec;
4030           symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4031           target->GetImages().FindModules(symfile_uuid_module_spec,
4032                                           matching_modules);
4033         }
4034       }
4035 
4036       if (matching_modules.IsEmpty()) {
4037         // No matches yet.  Iterate through the module specs to find a UUID
4038         // value that we can match up to an image in our target.
4039         const size_t num_symfile_module_specs = symfile_module_specs.GetSize();
4040         for (size_t i = 0;
4041              i < num_symfile_module_specs && matching_modules.IsEmpty(); ++i) {
4042           if (symfile_module_specs.GetModuleSpecAtIndex(
4043                   i, symfile_module_spec)) {
4044             if (symfile_module_spec.GetUUID().IsValid()) {
4045               // It has a UUID.  Look for this UUID in the target modules.
4046               ModuleSpec symfile_uuid_module_spec;
4047               symfile_uuid_module_spec.GetUUID() =
4048                   symfile_module_spec.GetUUID();
4049               target->GetImages().FindModules(symfile_uuid_module_spec,
4050                                               matching_modules);
4051             }
4052           }
4053         }
4054       }
4055     }
4056 
4057     // Just try to match up the file by basename if we have no matches at
4058     // this point.  For example, module foo might have symbols in foo.debug.
4059     if (matching_modules.IsEmpty())
4060       target->GetImages().FindModules(module_spec, matching_modules);
4061 
4062     while (matching_modules.IsEmpty()) {
4063       ConstString filename_no_extension(
4064           module_spec.GetFileSpec().GetFileNameStrippingExtension());
4065       // Empty string returned, let's bail
4066       if (!filename_no_extension)
4067         break;
4068 
4069       // Check if there was no extension to strip and the basename is the same
4070       if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
4071         break;
4072 
4073       // Replace basename with one fewer extension
4074       module_spec.GetFileSpec().GetFilename() = filename_no_extension;
4075       target->GetImages().FindModules(module_spec, matching_modules);
4076     }
4077 
4078     if (matching_modules.GetSize() > 1) {
4079       result.AppendErrorWithFormat("multiple modules match symbol file '%s', "
4080                                    "use the --uuid option to resolve the "
4081                                    "ambiguity.\n",
4082                                    symfile_path);
4083       return false;
4084     }
4085 
4086     if (matching_modules.GetSize() == 1) {
4087       ModuleSP module_sp(matching_modules.GetModuleAtIndex(0));
4088 
4089       // The module has not yet created its symbol vendor, we can just give
4090       // the existing target module the symfile path to use for when it
4091       // decides to create it!
4092       module_sp->SetSymbolFileFileSpec(symbol_fspec);
4093 
4094       SymbolFile *symbol_file =
4095           module_sp->GetSymbolFile(true, &result.GetErrorStream());
4096       if (symbol_file) {
4097         ObjectFile *object_file = symbol_file->GetObjectFile();
4098         if (object_file && object_file->GetFileSpec() == symbol_fspec) {
4099           // Provide feedback that the symfile has been successfully added.
4100           const FileSpec &module_fs = module_sp->GetFileSpec();
4101           result.AppendMessageWithFormat(
4102               "symbol file '%s' has been added to '%s'\n", symfile_path,
4103               module_fs.GetPath().c_str());
4104 
4105           // Let clients know something changed in the module if it is
4106           // currently loaded
4107           ModuleList module_list;
4108           module_list.Append(module_sp);
4109           target->SymbolsDidLoad(module_list);
4110 
4111           // Make sure we load any scripting resources that may be embedded
4112           // in the debug info files in case the platform supports that.
4113           Status error;
4114           StreamString feedback_stream;
4115           module_sp->LoadScriptingResourceInTarget(target, error,
4116                                                    &feedback_stream);
4117           if (error.Fail() && error.AsCString())
4118             result.AppendWarningWithFormat(
4119                 "unable to load scripting data for module %s - error "
4120                 "reported was %s",
4121                 module_sp->GetFileSpec()
4122                     .GetFileNameStrippingExtension()
4123                     .GetCString(),
4124                 error.AsCString());
4125           else if (feedback_stream.GetSize())
4126             result.AppendWarning(feedback_stream.GetData());
4127 
4128           flush = true;
4129           result.SetStatus(eReturnStatusSuccessFinishResult);
4130           return true;
4131         }
4132       }
4133       // Clear the symbol file spec if anything went wrong
4134       module_sp->SetSymbolFileFileSpec(FileSpec());
4135     }
4136 
4137     StreamString ss_symfile_uuid;
4138     if (module_spec.GetUUID().IsValid()) {
4139       ss_symfile_uuid << " (";
4140       module_spec.GetUUID().Dump(&ss_symfile_uuid);
4141       ss_symfile_uuid << ')';
4142     }
4143     result.AppendErrorWithFormat(
4144         "symbol file '%s'%s does not match any existing module%s\n",
4145         symfile_path, ss_symfile_uuid.GetData(),
4146         !llvm::sys::fs::is_regular_file(symbol_fspec.GetPath())
4147             ? "\n       please specify the full path to the symbol file"
4148             : "");
4149     return false;
4150   }
4151 
4152   bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
4153                                    CommandReturnObject &result, bool &flush) {
4154     if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
4155       if (module_spec.GetSymbolFileSpec())
4156         return AddModuleSymbols(m_exe_ctx.GetTargetPtr(), module_spec, flush,
4157                                 result);
4158     }
4159     return false;
4160   }
4161 
4162   bool AddSymbolsForUUID(CommandReturnObject &result, bool &flush) {
4163     assert(m_uuid_option_group.GetOptionValue().OptionWasSet());
4164 
4165     ModuleSpec module_spec;
4166     module_spec.GetUUID() =
4167         m_uuid_option_group.GetOptionValue().GetCurrentValue();
4168 
4169     if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4170       StreamString error_strm;
4171       error_strm.PutCString("unable to find debug symbols for UUID ");
4172       module_spec.GetUUID().Dump(&error_strm);
4173       result.AppendError(error_strm.GetString());
4174       return false;
4175     }
4176 
4177     return true;
4178   }
4179 
4180   bool AddSymbolsForFile(CommandReturnObject &result, bool &flush) {
4181     assert(m_file_option.GetOptionValue().OptionWasSet());
4182 
4183     ModuleSpec module_spec;
4184     module_spec.GetFileSpec() =
4185         m_file_option.GetOptionValue().GetCurrentValue();
4186 
4187     Target *target = m_exe_ctx.GetTargetPtr();
4188     ModuleSP module_sp(target->GetImages().FindFirstModule(module_spec));
4189     if (module_sp) {
4190       module_spec.GetFileSpec() = module_sp->GetFileSpec();
4191       module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();
4192       module_spec.GetUUID() = module_sp->GetUUID();
4193       module_spec.GetArchitecture() = module_sp->GetArchitecture();
4194     } else {
4195       module_spec.GetArchitecture() = target->GetArchitecture();
4196     }
4197 
4198     if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4199       StreamString error_strm;
4200       error_strm.PutCString(
4201           "unable to find debug symbols for the executable file ");
4202       error_strm << module_spec.GetFileSpec();
4203       result.AppendError(error_strm.GetString());
4204       return false;
4205     }
4206 
4207     return true;
4208   }
4209 
4210   bool AddSymbolsForFrame(CommandReturnObject &result, bool &flush) {
4211     assert(m_current_frame_option.GetOptionValue().OptionWasSet());
4212 
4213     Process *process = m_exe_ctx.GetProcessPtr();
4214     if (!process) {
4215       result.AppendError(
4216           "a process must exist in order to use the --frame option");
4217       return false;
4218     }
4219 
4220     const StateType process_state = process->GetState();
4221     if (!StateIsStoppedState(process_state, true)) {
4222       result.AppendErrorWithFormat("process is not stopped: %s",
4223                                    StateAsCString(process_state));
4224       return false;
4225     }
4226 
4227     StackFrame *frame = m_exe_ctx.GetFramePtr();
4228     if (!frame) {
4229       result.AppendError("invalid current frame");
4230       return false;
4231     }
4232 
4233     ModuleSP frame_module_sp(
4234         frame->GetSymbolContext(eSymbolContextModule).module_sp);
4235     if (!frame_module_sp) {
4236       result.AppendError("frame has no module");
4237       return false;
4238     }
4239 
4240     ModuleSpec module_spec;
4241     module_spec.GetUUID() = frame_module_sp->GetUUID();
4242 
4243     if (FileSystem::Instance().Exists(frame_module_sp->GetPlatformFileSpec())) {
4244       module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
4245       module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
4246     }
4247 
4248     if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4249       result.AppendError("unable to find debug symbols for the current frame");
4250       return false;
4251     }
4252 
4253     return true;
4254   }
4255 
4256   bool AddSymbolsForStack(CommandReturnObject &result, bool &flush) {
4257     assert(m_current_stack_option.GetOptionValue().OptionWasSet());
4258 
4259     Process *process = m_exe_ctx.GetProcessPtr();
4260     if (!process) {
4261       result.AppendError(
4262           "a process must exist in order to use the --stack option");
4263       return false;
4264     }
4265 
4266     const StateType process_state = process->GetState();
4267     if (!StateIsStoppedState(process_state, true)) {
4268       result.AppendErrorWithFormat("process is not stopped: %s",
4269                                    StateAsCString(process_state));
4270       return false;
4271     }
4272 
4273     Thread *thread = m_exe_ctx.GetThreadPtr();
4274     if (!thread) {
4275       result.AppendError("invalid current thread");
4276       return false;
4277     }
4278 
4279     bool symbols_found = false;
4280     uint32_t frame_count = thread->GetStackFrameCount();
4281     for (uint32_t i = 0; i < frame_count; ++i) {
4282       lldb::StackFrameSP frame_sp = thread->GetStackFrameAtIndex(i);
4283 
4284       ModuleSP frame_module_sp(
4285           frame_sp->GetSymbolContext(eSymbolContextModule).module_sp);
4286       if (!frame_module_sp)
4287         continue;
4288 
4289       ModuleSpec module_spec;
4290       module_spec.GetUUID() = frame_module_sp->GetUUID();
4291 
4292       if (FileSystem::Instance().Exists(
4293               frame_module_sp->GetPlatformFileSpec())) {
4294         module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
4295         module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
4296       }
4297 
4298       bool current_frame_flush = false;
4299       if (DownloadObjectAndSymbolFile(module_spec, result, current_frame_flush))
4300         symbols_found = true;
4301       flush |= current_frame_flush;
4302     }
4303 
4304     if (!symbols_found) {
4305       result.AppendError(
4306           "unable to find debug symbols in the current call stack");
4307       return false;
4308     }
4309 
4310     return true;
4311   }
4312 
4313   bool DoExecute(Args &args, CommandReturnObject &result) override {
4314     Target *target = m_exe_ctx.GetTargetPtr();
4315     result.SetStatus(eReturnStatusFailed);
4316     bool flush = false;
4317     ModuleSpec module_spec;
4318     const bool uuid_option_set =
4319         m_uuid_option_group.GetOptionValue().OptionWasSet();
4320     const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4321     const bool frame_option_set =
4322         m_current_frame_option.GetOptionValue().OptionWasSet();
4323     const bool stack_option_set =
4324         m_current_stack_option.GetOptionValue().OptionWasSet();
4325     const size_t argc = args.GetArgumentCount();
4326 
4327     if (argc == 0) {
4328       if (uuid_option_set)
4329         AddSymbolsForUUID(result, flush);
4330       else if (file_option_set)
4331         AddSymbolsForFile(result, flush);
4332       else if (frame_option_set)
4333         AddSymbolsForFrame(result, flush);
4334       else if (stack_option_set)
4335         AddSymbolsForStack(result, flush);
4336       else
4337         result.AppendError("one or more symbol file paths must be specified, "
4338                            "or options must be specified");
4339     } else {
4340       if (uuid_option_set) {
4341         result.AppendError("specify either one or more paths to symbol files "
4342                            "or use the --uuid option without arguments");
4343       } else if (frame_option_set) {
4344         result.AppendError("specify either one or more paths to symbol files "
4345                            "or use the --frame option without arguments");
4346       } else if (file_option_set && argc > 1) {
4347         result.AppendError("specify at most one symbol file path when "
4348                            "--shlib option is set");
4349       } else {
4350         PlatformSP platform_sp(target->GetPlatform());
4351 
4352         for (auto &entry : args.entries()) {
4353           if (!entry.ref().empty()) {
4354             auto &symbol_file_spec = module_spec.GetSymbolFileSpec();
4355             symbol_file_spec.SetFile(entry.ref(), FileSpec::Style::native);
4356             FileSystem::Instance().Resolve(symbol_file_spec);
4357             if (file_option_set) {
4358               module_spec.GetFileSpec() =
4359                   m_file_option.GetOptionValue().GetCurrentValue();
4360             }
4361             if (platform_sp) {
4362               FileSpec symfile_spec;
4363               if (platform_sp
4364                       ->ResolveSymbolFile(*target, module_spec, symfile_spec)
4365                       .Success())
4366                 module_spec.GetSymbolFileSpec() = symfile_spec;
4367             }
4368 
4369             bool symfile_exists =
4370                 FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec());
4371 
4372             if (symfile_exists) {
4373               if (!AddModuleSymbols(target, module_spec, flush, result))
4374                 break;
4375             } else {
4376               std::string resolved_symfile_path =
4377                   module_spec.GetSymbolFileSpec().GetPath();
4378               if (resolved_symfile_path != entry.ref()) {
4379                 result.AppendErrorWithFormat(
4380                     "invalid module path '%s' with resolved path '%s'\n",
4381                     entry.c_str(), resolved_symfile_path.c_str());
4382                 break;
4383               }
4384               result.AppendErrorWithFormat("invalid module path '%s'\n",
4385                                            entry.c_str());
4386               break;
4387             }
4388           }
4389         }
4390       }
4391     }
4392 
4393     if (flush) {
4394       Process *process = m_exe_ctx.GetProcessPtr();
4395       if (process)
4396         process->Flush();
4397     }
4398     return result.Succeeded();
4399   }
4400 
4401   OptionGroupOptions m_option_group;
4402   OptionGroupUUID m_uuid_option_group;
4403   OptionGroupFile m_file_option;
4404   OptionGroupBoolean m_current_frame_option;
4405   OptionGroupBoolean m_current_stack_option;
4406 };
4407 
4408 #pragma mark CommandObjectTargetSymbols
4409 
4410 // CommandObjectTargetSymbols
4411 
4412 class CommandObjectTargetSymbols : public CommandObjectMultiword {
4413 public:
4414   // Constructors and Destructors
4415   CommandObjectTargetSymbols(CommandInterpreter &interpreter)
4416       : CommandObjectMultiword(
4417             interpreter, "target symbols",
4418             "Commands for adding and managing debug symbol files.",
4419             "target symbols <sub-command> ...") {
4420     LoadSubCommand(
4421         "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));
4422   }
4423 
4424   ~CommandObjectTargetSymbols() override = default;
4425 
4426 private:
4427   // For CommandObjectTargetModules only
4428   CommandObjectTargetSymbols(const CommandObjectTargetSymbols &) = delete;
4429   const CommandObjectTargetSymbols &
4430   operator=(const CommandObjectTargetSymbols &) = delete;
4431 };
4432 
4433 #pragma mark CommandObjectTargetStopHookAdd
4434 
4435 // CommandObjectTargetStopHookAdd
4436 #define LLDB_OPTIONS_target_stop_hook_add
4437 #include "CommandOptions.inc"
4438 
4439 class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
4440                                        public IOHandlerDelegateMultiline {
4441 public:
4442   class CommandOptions : public OptionGroup {
4443   public:
4444     CommandOptions() : OptionGroup(), m_line_end(UINT_MAX), m_one_liner() {}
4445 
4446     ~CommandOptions() override = default;
4447 
4448     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
4449       return llvm::makeArrayRef(g_target_stop_hook_add_options);
4450     }
4451 
4452     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
4453                           ExecutionContext *execution_context) override {
4454       Status error;
4455       const int short_option =
4456           g_target_stop_hook_add_options[option_idx].short_option;
4457 
4458       switch (short_option) {
4459       case 'c':
4460         m_class_name = std::string(option_arg);
4461         m_sym_ctx_specified = true;
4462         break;
4463 
4464       case 'e':
4465         if (option_arg.getAsInteger(0, m_line_end)) {
4466           error.SetErrorStringWithFormat("invalid end line number: \"%s\"",
4467                                          option_arg.str().c_str());
4468           break;
4469         }
4470         m_sym_ctx_specified = true;
4471         break;
4472 
4473       case 'G': {
4474         bool value, success;
4475         value = OptionArgParser::ToBoolean(option_arg, false, &success);
4476         if (success) {
4477           m_auto_continue = value;
4478         } else
4479           error.SetErrorStringWithFormat(
4480               "invalid boolean value '%s' passed for -G option",
4481               option_arg.str().c_str());
4482       } break;
4483       case 'l':
4484         if (option_arg.getAsInteger(0, m_line_start)) {
4485           error.SetErrorStringWithFormat("invalid start line number: \"%s\"",
4486                                          option_arg.str().c_str());
4487           break;
4488         }
4489         m_sym_ctx_specified = true;
4490         break;
4491 
4492       case 'i':
4493         m_no_inlines = true;
4494         break;
4495 
4496       case 'n':
4497         m_function_name = std::string(option_arg);
4498         m_func_name_type_mask |= eFunctionNameTypeAuto;
4499         m_sym_ctx_specified = true;
4500         break;
4501 
4502       case 'f':
4503         m_file_name = std::string(option_arg);
4504         m_sym_ctx_specified = true;
4505         break;
4506 
4507       case 's':
4508         m_module_name = std::string(option_arg);
4509         m_sym_ctx_specified = true;
4510         break;
4511 
4512       case 't':
4513         if (option_arg.getAsInteger(0, m_thread_id))
4514           error.SetErrorStringWithFormat("invalid thread id string '%s'",
4515                                          option_arg.str().c_str());
4516         m_thread_specified = true;
4517         break;
4518 
4519       case 'T':
4520         m_thread_name = std::string(option_arg);
4521         m_thread_specified = true;
4522         break;
4523 
4524       case 'q':
4525         m_queue_name = std::string(option_arg);
4526         m_thread_specified = true;
4527         break;
4528 
4529       case 'x':
4530         if (option_arg.getAsInteger(0, m_thread_index))
4531           error.SetErrorStringWithFormat("invalid thread index string '%s'",
4532                                          option_arg.str().c_str());
4533         m_thread_specified = true;
4534         break;
4535 
4536       case 'o':
4537         m_use_one_liner = true;
4538         m_one_liner.push_back(std::string(option_arg));
4539         break;
4540 
4541       default:
4542         llvm_unreachable("Unimplemented option");
4543       }
4544       return error;
4545     }
4546 
4547     void OptionParsingStarting(ExecutionContext *execution_context) override {
4548       m_class_name.clear();
4549       m_function_name.clear();
4550       m_line_start = 0;
4551       m_line_end = UINT_MAX;
4552       m_file_name.clear();
4553       m_module_name.clear();
4554       m_func_name_type_mask = eFunctionNameTypeAuto;
4555       m_thread_id = LLDB_INVALID_THREAD_ID;
4556       m_thread_index = UINT32_MAX;
4557       m_thread_name.clear();
4558       m_queue_name.clear();
4559 
4560       m_no_inlines = false;
4561       m_sym_ctx_specified = false;
4562       m_thread_specified = false;
4563 
4564       m_use_one_liner = false;
4565       m_one_liner.clear();
4566       m_auto_continue = false;
4567     }
4568 
4569     std::string m_class_name;
4570     std::string m_function_name;
4571     uint32_t m_line_start = 0;
4572     uint32_t m_line_end;
4573     std::string m_file_name;
4574     std::string m_module_name;
4575     uint32_t m_func_name_type_mask =
4576         eFunctionNameTypeAuto; // A pick from lldb::FunctionNameType.
4577     lldb::tid_t m_thread_id;
4578     uint32_t m_thread_index;
4579     std::string m_thread_name;
4580     std::string m_queue_name;
4581     bool m_sym_ctx_specified = false;
4582     bool m_no_inlines;
4583     bool m_thread_specified = false;
4584     // Instance variables to hold the values for one_liner options.
4585     bool m_use_one_liner = false;
4586     std::vector<std::string> m_one_liner;
4587 
4588     bool m_auto_continue;
4589   };
4590 
4591   CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
4592       : CommandObjectParsed(interpreter, "target stop-hook add",
4593                             "Add a hook to be executed when the target stops."
4594                             "The hook can either be a list of commands or an "
4595                             "appropriately defined Python class.  You can also "
4596                             "add filters so the hook only runs a certain stop "
4597                             "points.",
4598                             "target stop-hook add"),
4599         IOHandlerDelegateMultiline("DONE",
4600                                    IOHandlerDelegate::Completion::LLDBCommand),
4601         m_options(), m_python_class_options("scripted stop-hook", true, 'P') {
4602     SetHelpLong(
4603         R"(
4604 Command Based stop-hooks:
4605 -------------------------
4606   Stop hooks can run a list of lldb commands by providing one or more
4607   --one-line-command options.  The commands will get run in the order they are
4608   added.  Or you can provide no commands, in which case you will enter a
4609   command editor where you can enter the commands to be run.
4610 
4611 Python Based Stop Hooks:
4612 ------------------------
4613   Stop hooks can be implemented with a suitably defined Python class, whose name
4614   is passed in the --python-class option.
4615 
4616   When the stop hook is added, the class is initialized by calling:
4617 
4618     def __init__(self, target, extra_args, internal_dict):
4619 
4620     target: The target that the stop hook is being added to.
4621     extra_args: An SBStructuredData Dictionary filled with the -key -value
4622                 option pairs passed to the command.
4623     dict: An implementation detail provided by lldb.
4624 
4625   Then when the stop-hook triggers, lldb will run the 'handle_stop' method.
4626   The method has the signature:
4627 
4628     def handle_stop(self, exe_ctx, stream):
4629 
4630     exe_ctx: An SBExecutionContext for the thread that has stopped.
4631     stream: An SBStream, anything written to this stream will be printed in the
4632             the stop message when the process stops.
4633 
4634     Return Value: The method returns "should_stop".  If should_stop is false
4635                   from all the stop hook executions on threads that stopped
4636                   with a reason, then the process will continue.  Note that this
4637                   will happen only after all the stop hooks are run.
4638 
4639 Filter Options:
4640 ---------------
4641   Stop hooks can be set to always run, or to only run when the stopped thread
4642   matches the filter options passed on the command line.  The available filter
4643   options include a shared library or a thread or queue specification,
4644   a line range in a source file, a function name or a class name.
4645             )");
4646     m_all_options.Append(&m_python_class_options,
4647                          LLDB_OPT_SET_1 | LLDB_OPT_SET_2,
4648                          LLDB_OPT_SET_FROM_TO(4, 6));
4649     m_all_options.Append(&m_options);
4650     m_all_options.Finalize();
4651   }
4652 
4653   ~CommandObjectTargetStopHookAdd() override = default;
4654 
4655   Options *GetOptions() override { return &m_all_options; }
4656 
4657 protected:
4658   void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
4659     StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
4660     if (output_sp && interactive) {
4661       output_sp->PutCString(
4662           "Enter your stop hook command(s).  Type 'DONE' to end.\n");
4663       output_sp->Flush();
4664     }
4665   }
4666 
4667   void IOHandlerInputComplete(IOHandler &io_handler,
4668                               std::string &line) override {
4669     if (m_stop_hook_sp) {
4670       if (line.empty()) {
4671         StreamFileSP error_sp(io_handler.GetErrorStreamFileSP());
4672         if (error_sp) {
4673           error_sp->Printf("error: stop hook #%" PRIu64
4674                            " aborted, no commands.\n",
4675                            m_stop_hook_sp->GetID());
4676           error_sp->Flush();
4677         }
4678         Target *target = GetDebugger().GetSelectedTarget().get();
4679         if (target) {
4680           target->UndoCreateStopHook(m_stop_hook_sp->GetID());
4681         }
4682       } else {
4683         // The IOHandler editor is only for command lines stop hooks:
4684         Target::StopHookCommandLine *hook_ptr =
4685             static_cast<Target::StopHookCommandLine *>(m_stop_hook_sp.get());
4686 
4687         hook_ptr->SetActionFromString(line);
4688         StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
4689         if (output_sp) {
4690           output_sp->Printf("Stop hook #%" PRIu64 " added.\n",
4691                             m_stop_hook_sp->GetID());
4692           output_sp->Flush();
4693         }
4694       }
4695       m_stop_hook_sp.reset();
4696     }
4697     io_handler.SetIsDone(true);
4698   }
4699 
4700   bool DoExecute(Args &command, CommandReturnObject &result) override {
4701     m_stop_hook_sp.reset();
4702 
4703     Target &target = GetSelectedOrDummyTarget();
4704     Target::StopHookSP new_hook_sp =
4705         target.CreateStopHook(m_python_class_options.GetName().empty() ?
4706                                Target::StopHook::StopHookKind::CommandBased
4707                                : Target::StopHook::StopHookKind::ScriptBased);
4708 
4709     //  First step, make the specifier.
4710     std::unique_ptr<SymbolContextSpecifier> specifier_up;
4711     if (m_options.m_sym_ctx_specified) {
4712       specifier_up = std::make_unique<SymbolContextSpecifier>(
4713           GetDebugger().GetSelectedTarget());
4714 
4715       if (!m_options.m_module_name.empty()) {
4716         specifier_up->AddSpecification(
4717             m_options.m_module_name.c_str(),
4718             SymbolContextSpecifier::eModuleSpecified);
4719       }
4720 
4721       if (!m_options.m_class_name.empty()) {
4722         specifier_up->AddSpecification(
4723             m_options.m_class_name.c_str(),
4724             SymbolContextSpecifier::eClassOrNamespaceSpecified);
4725       }
4726 
4727       if (!m_options.m_file_name.empty()) {
4728         specifier_up->AddSpecification(m_options.m_file_name.c_str(),
4729                                        SymbolContextSpecifier::eFileSpecified);
4730       }
4731 
4732       if (m_options.m_line_start != 0) {
4733         specifier_up->AddLineSpecification(
4734             m_options.m_line_start,
4735             SymbolContextSpecifier::eLineStartSpecified);
4736       }
4737 
4738       if (m_options.m_line_end != UINT_MAX) {
4739         specifier_up->AddLineSpecification(
4740             m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
4741       }
4742 
4743       if (!m_options.m_function_name.empty()) {
4744         specifier_up->AddSpecification(
4745             m_options.m_function_name.c_str(),
4746             SymbolContextSpecifier::eFunctionSpecified);
4747       }
4748     }
4749 
4750     if (specifier_up)
4751       new_hook_sp->SetSpecifier(specifier_up.release());
4752 
4753     // Next see if any of the thread options have been entered:
4754 
4755     if (m_options.m_thread_specified) {
4756       ThreadSpec *thread_spec = new ThreadSpec();
4757 
4758       if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) {
4759         thread_spec->SetTID(m_options.m_thread_id);
4760       }
4761 
4762       if (m_options.m_thread_index != UINT32_MAX)
4763         thread_spec->SetIndex(m_options.m_thread_index);
4764 
4765       if (!m_options.m_thread_name.empty())
4766         thread_spec->SetName(m_options.m_thread_name.c_str());
4767 
4768       if (!m_options.m_queue_name.empty())
4769         thread_spec->SetQueueName(m_options.m_queue_name.c_str());
4770 
4771       new_hook_sp->SetThreadSpecifier(thread_spec);
4772     }
4773 
4774     new_hook_sp->SetAutoContinue(m_options.m_auto_continue);
4775     if (m_options.m_use_one_liner) {
4776       // This is a command line stop hook:
4777       Target::StopHookCommandLine *hook_ptr =
4778           static_cast<Target::StopHookCommandLine *>(new_hook_sp.get());
4779       hook_ptr->SetActionFromStrings(m_options.m_one_liner);
4780       result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
4781                                      new_hook_sp->GetID());
4782     } else if (!m_python_class_options.GetName().empty()) {
4783       // This is a scripted stop hook:
4784       Target::StopHookScripted *hook_ptr =
4785           static_cast<Target::StopHookScripted *>(new_hook_sp.get());
4786       Status error = hook_ptr->SetScriptCallback(
4787           m_python_class_options.GetName(),
4788           m_python_class_options.GetStructuredData());
4789       if (error.Success())
4790         result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
4791                                        new_hook_sp->GetID());
4792       else {
4793         // FIXME: Set the stop hook ID counter back.
4794         result.AppendErrorWithFormat("Couldn't add stop hook: %s",
4795                                      error.AsCString());
4796         target.UndoCreateStopHook(new_hook_sp->GetID());
4797         return false;
4798       }
4799     } else {
4800       m_stop_hook_sp = new_hook_sp;
4801       m_interpreter.GetLLDBCommandsFromIOHandler("> ",   // Prompt
4802                                                  *this); // IOHandlerDelegate
4803     }
4804     result.SetStatus(eReturnStatusSuccessFinishNoResult);
4805 
4806     return result.Succeeded();
4807   }
4808 
4809 private:
4810   CommandOptions m_options;
4811   OptionGroupPythonClassWithDict m_python_class_options;
4812   OptionGroupOptions m_all_options;
4813 
4814   Target::StopHookSP m_stop_hook_sp;
4815 };
4816 
4817 #pragma mark CommandObjectTargetStopHookDelete
4818 
4819 // CommandObjectTargetStopHookDelete
4820 
4821 class CommandObjectTargetStopHookDelete : public CommandObjectParsed {
4822 public:
4823   CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter)
4824       : CommandObjectParsed(interpreter, "target stop-hook delete",
4825                             "Delete a stop-hook.",
4826                             "target stop-hook delete [<idx>]") {}
4827 
4828   ~CommandObjectTargetStopHookDelete() override = default;
4829 
4830   void
4831   HandleArgumentCompletion(CompletionRequest &request,
4832                            OptionElementVector &opt_element_vector) override {
4833     CommandCompletions::InvokeCommonCompletionCallbacks(
4834         GetCommandInterpreter(), CommandCompletions::eStopHookIDCompletion,
4835         request, nullptr);
4836   }
4837 
4838 protected:
4839   bool DoExecute(Args &command, CommandReturnObject &result) override {
4840     Target &target = GetSelectedOrDummyTarget();
4841     // FIXME: see if we can use the breakpoint id style parser?
4842     size_t num_args = command.GetArgumentCount();
4843     if (num_args == 0) {
4844       if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
4845         result.SetStatus(eReturnStatusFailed);
4846         return false;
4847       } else {
4848         target.RemoveAllStopHooks();
4849       }
4850     } else {
4851       for (size_t i = 0; i < num_args; i++) {
4852         lldb::user_id_t user_id;
4853         if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
4854           result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4855                                        command.GetArgumentAtIndex(i));
4856           return false;
4857         }
4858         if (!target.RemoveStopHookByID(user_id)) {
4859           result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4860                                        command.GetArgumentAtIndex(i));
4861           return false;
4862         }
4863       }
4864     }
4865     result.SetStatus(eReturnStatusSuccessFinishNoResult);
4866     return result.Succeeded();
4867   }
4868 };
4869 
4870 #pragma mark CommandObjectTargetStopHookEnableDisable
4871 
4872 // CommandObjectTargetStopHookEnableDisable
4873 
4874 class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed {
4875 public:
4876   CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter,
4877                                            bool enable, const char *name,
4878                                            const char *help, const char *syntax)
4879       : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) {
4880   }
4881 
4882   ~CommandObjectTargetStopHookEnableDisable() override = default;
4883 
4884   void
4885   HandleArgumentCompletion(CompletionRequest &request,
4886                            OptionElementVector &opt_element_vector) override {
4887     if (request.GetCursorIndex())
4888       return;
4889     CommandCompletions::InvokeCommonCompletionCallbacks(
4890         GetCommandInterpreter(), CommandCompletions::eStopHookIDCompletion,
4891         request, nullptr);
4892   }
4893 
4894 protected:
4895   bool DoExecute(Args &command, CommandReturnObject &result) override {
4896     Target &target = GetSelectedOrDummyTarget();
4897     // FIXME: see if we can use the breakpoint id style parser?
4898     size_t num_args = command.GetArgumentCount();
4899     bool success;
4900 
4901     if (num_args == 0) {
4902       target.SetAllStopHooksActiveState(m_enable);
4903     } else {
4904       for (size_t i = 0; i < num_args; i++) {
4905         lldb::user_id_t user_id;
4906         if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
4907           result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4908                                        command.GetArgumentAtIndex(i));
4909           return false;
4910         }
4911         success = target.SetStopHookActiveStateByID(user_id, m_enable);
4912         if (!success) {
4913           result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4914                                        command.GetArgumentAtIndex(i));
4915           return false;
4916         }
4917       }
4918     }
4919     result.SetStatus(eReturnStatusSuccessFinishNoResult);
4920     return result.Succeeded();
4921   }
4922 
4923 private:
4924   bool m_enable;
4925 };
4926 
4927 #pragma mark CommandObjectTargetStopHookList
4928 
4929 // CommandObjectTargetStopHookList
4930 
4931 class CommandObjectTargetStopHookList : public CommandObjectParsed {
4932 public:
4933   CommandObjectTargetStopHookList(CommandInterpreter &interpreter)
4934       : CommandObjectParsed(interpreter, "target stop-hook list",
4935                             "List all stop-hooks.",
4936                             "target stop-hook list [<type>]") {}
4937 
4938   ~CommandObjectTargetStopHookList() override = default;
4939 
4940 protected:
4941   bool DoExecute(Args &command, CommandReturnObject &result) override {
4942     Target &target = GetSelectedOrDummyTarget();
4943 
4944     size_t num_hooks = target.GetNumStopHooks();
4945     if (num_hooks == 0) {
4946       result.GetOutputStream().PutCString("No stop hooks.\n");
4947     } else {
4948       for (size_t i = 0; i < num_hooks; i++) {
4949         Target::StopHookSP this_hook = target.GetStopHookAtIndex(i);
4950         if (i > 0)
4951           result.GetOutputStream().PutCString("\n");
4952         this_hook->GetDescription(&(result.GetOutputStream()),
4953                                   eDescriptionLevelFull);
4954       }
4955     }
4956     result.SetStatus(eReturnStatusSuccessFinishResult);
4957     return result.Succeeded();
4958   }
4959 };
4960 
4961 #pragma mark CommandObjectMultiwordTargetStopHooks
4962 
4963 // CommandObjectMultiwordTargetStopHooks
4964 
4965 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword {
4966 public:
4967   CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
4968       : CommandObjectMultiword(
4969             interpreter, "target stop-hook",
4970             "Commands for operating on debugger target stop-hooks.",
4971             "target stop-hook <subcommand> [<subcommand-options>]") {
4972     LoadSubCommand("add", CommandObjectSP(
4973                               new CommandObjectTargetStopHookAdd(interpreter)));
4974     LoadSubCommand(
4975         "delete",
4976         CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter)));
4977     LoadSubCommand("disable",
4978                    CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
4979                        interpreter, false, "target stop-hook disable [<id>]",
4980                        "Disable a stop-hook.", "target stop-hook disable")));
4981     LoadSubCommand("enable",
4982                    CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
4983                        interpreter, true, "target stop-hook enable [<id>]",
4984                        "Enable a stop-hook.", "target stop-hook enable")));
4985     LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList(
4986                                interpreter)));
4987   }
4988 
4989   ~CommandObjectMultiwordTargetStopHooks() override = default;
4990 };
4991 
4992 #pragma mark CommandObjectTargetDumpTypesystem
4993 
4994 /// Dumps the TypeSystem of the selected Target.
4995 class CommandObjectTargetDumpTypesystem : public CommandObjectParsed {
4996 public:
4997   CommandObjectTargetDumpTypesystem(CommandInterpreter &interpreter)
4998       : CommandObjectParsed(
4999             interpreter, "target dump typesystem",
5000             "Dump the state of the target's internal type system.\n"
5001             "Intended to be used for debugging LLDB itself.",
5002             nullptr, eCommandRequiresTarget) {}
5003 
5004   ~CommandObjectTargetDumpTypesystem() override = default;
5005 
5006 protected:
5007   bool DoExecute(Args &command, CommandReturnObject &result) override {
5008     if (!command.empty()) {
5009       result.AppendError("target dump typesystem doesn't take arguments.");
5010       return result.Succeeded();
5011     }
5012 
5013     // Go over every scratch TypeSystem and dump to the command output.
5014     for (TypeSystem *ts : GetSelectedTarget().GetScratchTypeSystems())
5015       ts->Dump(result.GetOutputStream().AsRawOstream());
5016 
5017     result.SetStatus(eReturnStatusSuccessFinishResult);
5018     return result.Succeeded();
5019   }
5020 };
5021 
5022 #pragma mark CommandObjectTargetDump
5023 
5024 /// Multi-word command for 'target dump'.
5025 class CommandObjectTargetDump : public CommandObjectMultiword {
5026 public:
5027   // Constructors and Destructors
5028   CommandObjectTargetDump(CommandInterpreter &interpreter)
5029       : CommandObjectMultiword(
5030             interpreter, "target dump",
5031             "Commands for dumping information about the target.",
5032             "target dump [typesystem]") {
5033     LoadSubCommand(
5034         "typesystem",
5035         CommandObjectSP(new CommandObjectTargetDumpTypesystem(interpreter)));
5036   }
5037 
5038   ~CommandObjectTargetDump() override = default;
5039 };
5040 
5041 #pragma mark CommandObjectMultiwordTarget
5042 
5043 // CommandObjectMultiwordTarget
5044 
5045 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(
5046     CommandInterpreter &interpreter)
5047     : CommandObjectMultiword(interpreter, "target",
5048                              "Commands for operating on debugger targets.",
5049                              "target <subcommand> [<subcommand-options>]") {
5050   LoadSubCommand("create",
5051                  CommandObjectSP(new CommandObjectTargetCreate(interpreter)));
5052   LoadSubCommand("delete",
5053                  CommandObjectSP(new CommandObjectTargetDelete(interpreter)));
5054   LoadSubCommand("dump",
5055                  CommandObjectSP(new CommandObjectTargetDump(interpreter)));
5056   LoadSubCommand("list",
5057                  CommandObjectSP(new CommandObjectTargetList(interpreter)));
5058   LoadSubCommand("select",
5059                  CommandObjectSP(new CommandObjectTargetSelect(interpreter)));
5060   LoadSubCommand("show-launch-environment",
5061                  CommandObjectSP(new CommandObjectTargetShowLaunchEnvironment(
5062                      interpreter)));
5063   LoadSubCommand(
5064       "stop-hook",
5065       CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter)));
5066   LoadSubCommand("modules",
5067                  CommandObjectSP(new CommandObjectTargetModules(interpreter)));
5068   LoadSubCommand("symbols",
5069                  CommandObjectSP(new CommandObjectTargetSymbols(interpreter)));
5070   LoadSubCommand("variable",
5071                  CommandObjectSP(new CommandObjectTargetVariable(interpreter)));
5072 }
5073 
5074 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;
5075