1 //===-- CommandObjectTarget.cpp -------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "CommandObjectTarget.h"
10 
11 #include "lldb/Core/Debugger.h"
12 #include "lldb/Core/IOHandler.h"
13 #include "lldb/Core/Module.h"
14 #include "lldb/Core/ModuleSpec.h"
15 #include "lldb/Core/Section.h"
16 #include "lldb/Core/ValueObjectVariable.h"
17 #include "lldb/DataFormatters/ValueObjectPrinter.h"
18 #include "lldb/Host/OptionParser.h"
19 #include "lldb/Interpreter/CommandInterpreter.h"
20 #include "lldb/Interpreter/CommandReturnObject.h"
21 #include "lldb/Interpreter/OptionArgParser.h"
22 #include "lldb/Interpreter/OptionGroupArchitecture.h"
23 #include "lldb/Interpreter/OptionGroupBoolean.h"
24 #include "lldb/Interpreter/OptionGroupFile.h"
25 #include "lldb/Interpreter/OptionGroupFormat.h"
26 #include "lldb/Interpreter/OptionGroupPlatform.h"
27 #include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
28 #include "lldb/Interpreter/OptionGroupString.h"
29 #include "lldb/Interpreter/OptionGroupUInt64.h"
30 #include "lldb/Interpreter/OptionGroupUUID.h"
31 #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
32 #include "lldb/Interpreter/OptionGroupVariable.h"
33 #include "lldb/Interpreter/Options.h"
34 #include "lldb/Symbol/CompileUnit.h"
35 #include "lldb/Symbol/FuncUnwinders.h"
36 #include "lldb/Symbol/LineTable.h"
37 #include "lldb/Symbol/LocateSymbolFile.h"
38 #include "lldb/Symbol/ObjectFile.h"
39 #include "lldb/Symbol/SymbolFile.h"
40 #include "lldb/Symbol/UnwindPlan.h"
41 #include "lldb/Symbol/VariableList.h"
42 #include "lldb/Target/ABI.h"
43 #include "lldb/Target/Process.h"
44 #include "lldb/Target/RegisterContext.h"
45 #include "lldb/Target/SectionLoadList.h"
46 #include "lldb/Target/StackFrame.h"
47 #include "lldb/Target/Thread.h"
48 #include "lldb/Target/ThreadSpec.h"
49 #include "lldb/Utility/Args.h"
50 #include "lldb/Utility/LLDBLog.h"
51 #include "lldb/Utility/State.h"
52 #include "lldb/Utility/Timer.h"
53 #include "lldb/lldb-private-enumerations.h"
54 
55 #include "llvm/ADT/ScopeExit.h"
56 #include "llvm/Support/FileSystem.h"
57 #include "llvm/Support/FormatAdapters.h"
58 
59 
60 using namespace lldb;
61 using namespace lldb_private;
62 
63 static void DumpTargetInfo(uint32_t target_idx, Target *target,
64                            const char *prefix_cstr,
65                            bool show_stopped_process_status, Stream &strm) {
66   const ArchSpec &target_arch = target->GetArchitecture();
67 
68   Module *exe_module = target->GetExecutableModulePointer();
69   char exe_path[PATH_MAX];
70   bool exe_valid = false;
71   if (exe_module)
72     exe_valid = exe_module->GetFileSpec().GetPath(exe_path, sizeof(exe_path));
73 
74   if (!exe_valid)
75     ::strcpy(exe_path, "<none>");
76 
77   strm.Printf("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx,
78               exe_path);
79 
80   uint32_t properties = 0;
81   if (target_arch.IsValid()) {
82     strm.Printf("%sarch=", properties++ > 0 ? ", " : " ( ");
83     target_arch.DumpTriple(strm.AsRawOstream());
84     properties++;
85   }
86   PlatformSP platform_sp(target->GetPlatform());
87   if (platform_sp)
88     strm.Format("{0}platform={1}", properties++ > 0 ? ", " : " ( ",
89                 platform_sp->GetName());
90 
91   ProcessSP process_sp(target->GetProcessSP());
92   bool show_process_status = false;
93   if (process_sp) {
94     lldb::pid_t pid = process_sp->GetID();
95     StateType state = process_sp->GetState();
96     if (show_stopped_process_status)
97       show_process_status = StateIsStoppedState(state, true);
98     const char *state_cstr = StateAsCString(state);
99     if (pid != LLDB_INVALID_PROCESS_ID)
100       strm.Printf("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid);
101     strm.Printf("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
102   }
103   if (properties > 0)
104     strm.PutCString(" )\n");
105   else
106     strm.EOL();
107   if (show_process_status) {
108     const bool only_threads_with_stop_reason = true;
109     const uint32_t start_frame = 0;
110     const uint32_t num_frames = 1;
111     const uint32_t num_frames_with_source = 1;
112     const bool stop_format = false;
113     process_sp->GetStatus(strm);
114     process_sp->GetThreadStatus(strm, only_threads_with_stop_reason,
115                                 start_frame, num_frames, num_frames_with_source,
116                                 stop_format);
117   }
118 }
119 
120 static uint32_t DumpTargetList(TargetList &target_list,
121                                bool show_stopped_process_status, Stream &strm) {
122   const uint32_t num_targets = target_list.GetNumTargets();
123   if (num_targets) {
124     TargetSP selected_target_sp(target_list.GetSelectedTarget());
125     strm.PutCString("Current targets:\n");
126     for (uint32_t i = 0; i < num_targets; ++i) {
127       TargetSP target_sp(target_list.GetTargetAtIndex(i));
128       if (target_sp) {
129         bool is_selected = target_sp.get() == selected_target_sp.get();
130         DumpTargetInfo(i, target_sp.get(), is_selected ? "* " : "  ",
131                        show_stopped_process_status, strm);
132       }
133     }
134   }
135   return num_targets;
136 }
137 
138 // Note that the negation in the argument name causes a slightly confusing
139 // mapping of the enum values.
140 static constexpr OptionEnumValueElement g_dependents_enumaration[] = {
141     {
142         eLoadDependentsDefault,
143         "default",
144         "Only load dependents when the target is an executable.",
145     },
146     {
147         eLoadDependentsNo,
148         "true",
149         "Don't load dependents, even if the target is an executable.",
150     },
151     {
152         eLoadDependentsYes,
153         "false",
154         "Load dependents, even if the target is not an executable.",
155     },
156 };
157 
158 #define LLDB_OPTIONS_target_dependents
159 #include "CommandOptions.inc"
160 
161 class OptionGroupDependents : public OptionGroup {
162 public:
163   OptionGroupDependents() = default;
164 
165   ~OptionGroupDependents() override = default;
166 
167   llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
168     return llvm::makeArrayRef(g_target_dependents_options);
169   }
170 
171   Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
172                         ExecutionContext *execution_context) override {
173     Status error;
174 
175     // For compatibility no value means don't load dependents.
176     if (option_value.empty()) {
177       m_load_dependent_files = eLoadDependentsNo;
178       return error;
179     }
180 
181     const char short_option =
182         g_target_dependents_options[option_idx].short_option;
183     if (short_option == 'd') {
184       LoadDependentFiles tmp_load_dependents;
185       tmp_load_dependents = (LoadDependentFiles)OptionArgParser::ToOptionEnum(
186           option_value, g_target_dependents_options[option_idx].enum_values, 0,
187           error);
188       if (error.Success())
189         m_load_dependent_files = tmp_load_dependents;
190     } else {
191       error.SetErrorStringWithFormat("unrecognized short option '%c'",
192                                      short_option);
193     }
194 
195     return error;
196   }
197 
198   Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete;
199 
200   void OptionParsingStarting(ExecutionContext *execution_context) override {
201     m_load_dependent_files = eLoadDependentsDefault;
202   }
203 
204   LoadDependentFiles m_load_dependent_files;
205 
206 private:
207   OptionGroupDependents(const OptionGroupDependents &) = delete;
208   const OptionGroupDependents &
209   operator=(const OptionGroupDependents &) = delete;
210 };
211 
212 #pragma mark CommandObjectTargetCreate
213 
214 class CommandObjectTargetCreate : public CommandObjectParsed {
215 public:
216   CommandObjectTargetCreate(CommandInterpreter &interpreter)
217       : CommandObjectParsed(
218             interpreter, "target create",
219             "Create a target using the argument as the main executable.",
220             nullptr),
221         m_platform_options(true), // Include the --platform option.
222         m_core_file(LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename,
223                     "Fullpath to a core file to use for this target."),
224         m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
225                       eArgTypeFilename,
226                       "Fullpath to a stand alone debug "
227                       "symbols file for when debug symbols "
228                       "are not in the executable."),
229         m_remote_file(
230             LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename,
231             "Fullpath to the file on the remote host if debugging remotely.") {
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_all_option(LLDB_OPT_SET_1, false, "all", 'a', "Delete all targets.",
538                      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_variable(false), // Don't include frame options
682         m_option_format(eFormatDefault),
683         m_option_compile_units(LLDB_OPT_SET_1, false, "file", SHORT_OPTION_FILE,
684                                0, eArgTypeFilename,
685                                "A basename or fullpath to a file that contains "
686                                "global variables. This option can be "
687                                "specified multiple times."),
688         m_option_shared_libraries(
689             LLDB_OPT_SET_1, false, "shlib", SHORT_OPTION_SHLB, 0,
690             eArgTypeFilename,
691             "A basename or fullpath to a shared library to use in the search "
692             "for global "
693             "variables. This option can be specified multiple times.") {
694     CommandArgumentEntry arg;
695     CommandArgumentData var_name_arg;
696 
697     // Define the first (and only) variant of this arg.
698     var_name_arg.arg_type = eArgTypeVarName;
699     var_name_arg.arg_repetition = eArgRepeatPlus;
700 
701     // There is only one variant this argument could be; put it into the
702     // argument entry.
703     arg.push_back(var_name_arg);
704 
705     // Push the data for the first argument into the m_arguments vector.
706     m_arguments.push_back(arg);
707 
708     m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
709     m_option_group.Append(&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
710     m_option_group.Append(&m_option_format,
711                           OptionGroupFormat::OPTION_GROUP_FORMAT |
712                               OptionGroupFormat::OPTION_GROUP_GDB_FMT,
713                           LLDB_OPT_SET_1);
714     m_option_group.Append(&m_option_compile_units, LLDB_OPT_SET_ALL,
715                           LLDB_OPT_SET_1);
716     m_option_group.Append(&m_option_shared_libraries, LLDB_OPT_SET_ALL,
717                           LLDB_OPT_SET_1);
718     m_option_group.Finalize();
719   }
720 
721   ~CommandObjectTargetVariable() override = default;
722 
723   void DumpValueObject(Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp,
724                        const char *root_name) {
725     DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());
726 
727     if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
728         valobj_sp->IsRuntimeSupportValue())
729       return;
730 
731     switch (var_sp->GetScope()) {
732     case eValueTypeVariableGlobal:
733       if (m_option_variable.show_scope)
734         s.PutCString("GLOBAL: ");
735       break;
736 
737     case eValueTypeVariableStatic:
738       if (m_option_variable.show_scope)
739         s.PutCString("STATIC: ");
740       break;
741 
742     case eValueTypeVariableArgument:
743       if (m_option_variable.show_scope)
744         s.PutCString("   ARG: ");
745       break;
746 
747     case eValueTypeVariableLocal:
748       if (m_option_variable.show_scope)
749         s.PutCString(" LOCAL: ");
750       break;
751 
752     case eValueTypeVariableThreadLocal:
753       if (m_option_variable.show_scope)
754         s.PutCString("THREAD: ");
755       break;
756 
757     default:
758       break;
759     }
760 
761     if (m_option_variable.show_decl) {
762       bool show_fullpaths = false;
763       bool show_module = true;
764       if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
765         s.PutCString(": ");
766     }
767 
768     const Format format = m_option_format.GetFormat();
769     if (format != eFormatDefault)
770       options.SetFormat(format);
771 
772     options.SetRootValueObjectName(root_name);
773 
774     valobj_sp->Dump(s, options);
775   }
776 
777   static size_t GetVariableCallback(void *baton, const char *name,
778                                     VariableList &variable_list) {
779     size_t old_size = variable_list.GetSize();
780     Target *target = static_cast<Target *>(baton);
781     if (target)
782       target->GetImages().FindGlobalVariables(ConstString(name), UINT32_MAX,
783                                               variable_list);
784     return variable_list.GetSize() - old_size;
785   }
786 
787   Options *GetOptions() override { return &m_option_group; }
788 
789 protected:
790   void DumpGlobalVariableList(const ExecutionContext &exe_ctx,
791                               const SymbolContext &sc,
792                               const VariableList &variable_list, Stream &s) {
793     if (variable_list.Empty())
794       return;
795     if (sc.module_sp) {
796       if (sc.comp_unit) {
797         s.Format("Global variables for {0} in {1}:\n",
798                  sc.comp_unit->GetPrimaryFile(), sc.module_sp->GetFileSpec());
799       } else {
800         s.Printf("Global variables for %s\n",
801                  sc.module_sp->GetFileSpec().GetPath().c_str());
802       }
803     } else if (sc.comp_unit) {
804       s.Format("Global variables for {0}\n", sc.comp_unit->GetPrimaryFile());
805     }
806 
807     for (VariableSP var_sp : variable_list) {
808       if (!var_sp)
809         continue;
810       ValueObjectSP valobj_sp(ValueObjectVariable::Create(
811           exe_ctx.GetBestExecutionContextScope(), var_sp));
812 
813       if (valobj_sp)
814         DumpValueObject(s, var_sp, valobj_sp, var_sp->GetName().GetCString());
815     }
816   }
817 
818   bool DoExecute(Args &args, CommandReturnObject &result) override {
819     Target *target = m_exe_ctx.GetTargetPtr();
820     const size_t argc = args.GetArgumentCount();
821     Stream &s = result.GetOutputStream();
822 
823     if (argc > 0) {
824       for (const Args::ArgEntry &arg : args) {
825         VariableList variable_list;
826         ValueObjectList valobj_list;
827 
828         size_t matches = 0;
829         bool use_var_name = false;
830         if (m_option_variable.use_regex) {
831           RegularExpression regex(arg.ref());
832           if (!regex.IsValid()) {
833             result.GetErrorStream().Printf(
834                 "error: invalid regular expression: '%s'\n", arg.c_str());
835             return false;
836           }
837           use_var_name = true;
838           target->GetImages().FindGlobalVariables(regex, UINT32_MAX,
839                                                   variable_list);
840           matches = variable_list.GetSize();
841         } else {
842           Status error(Variable::GetValuesForVariableExpressionPath(
843               arg.c_str(), m_exe_ctx.GetBestExecutionContextScope(),
844               GetVariableCallback, target, variable_list, valobj_list));
845           matches = variable_list.GetSize();
846         }
847 
848         if (matches == 0) {
849           result.AppendErrorWithFormat("can't find global variable '%s'",
850                                        arg.c_str());
851           return false;
852         } else {
853           for (uint32_t global_idx = 0; global_idx < matches; ++global_idx) {
854             VariableSP var_sp(variable_list.GetVariableAtIndex(global_idx));
855             if (var_sp) {
856               ValueObjectSP valobj_sp(
857                   valobj_list.GetValueObjectAtIndex(global_idx));
858               if (!valobj_sp)
859                 valobj_sp = ValueObjectVariable::Create(
860                     m_exe_ctx.GetBestExecutionContextScope(), var_sp);
861 
862               if (valobj_sp)
863                 DumpValueObject(s, var_sp, valobj_sp,
864                                 use_var_name ? var_sp->GetName().GetCString()
865                                              : arg.c_str());
866             }
867           }
868         }
869       }
870     } else {
871       const FileSpecList &compile_units =
872           m_option_compile_units.GetOptionValue().GetCurrentValue();
873       const FileSpecList &shlibs =
874           m_option_shared_libraries.GetOptionValue().GetCurrentValue();
875       SymbolContextList sc_list;
876       const size_t num_compile_units = compile_units.GetSize();
877       const size_t num_shlibs = shlibs.GetSize();
878       if (num_compile_units == 0 && num_shlibs == 0) {
879         bool success = false;
880         StackFrame *frame = m_exe_ctx.GetFramePtr();
881         CompileUnit *comp_unit = nullptr;
882         if (frame) {
883           SymbolContext sc = frame->GetSymbolContext(eSymbolContextCompUnit);
884           comp_unit = sc.comp_unit;
885           if (sc.comp_unit) {
886             const bool can_create = true;
887             VariableListSP comp_unit_varlist_sp(
888                 sc.comp_unit->GetVariableList(can_create));
889             if (comp_unit_varlist_sp) {
890               size_t count = comp_unit_varlist_sp->GetSize();
891               if (count > 0) {
892                 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
893                 success = true;
894               }
895             }
896           }
897         }
898         if (!success) {
899           if (frame) {
900             if (comp_unit)
901               result.AppendErrorWithFormatv(
902                   "no global variables in current compile unit: {0}\n",
903                   comp_unit->GetPrimaryFile());
904             else
905               result.AppendErrorWithFormat(
906                   "no debug information for frame %u\n",
907                   frame->GetFrameIndex());
908           } else
909             result.AppendError("'target variable' takes one or more global "
910                                "variable names as arguments\n");
911         }
912       } else {
913         SymbolContextList sc_list;
914         // We have one or more compile unit or shlib
915         if (num_shlibs > 0) {
916           for (size_t shlib_idx = 0; shlib_idx < num_shlibs; ++shlib_idx) {
917             const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));
918             ModuleSpec module_spec(module_file);
919 
920             ModuleSP module_sp(
921                 target->GetImages().FindFirstModule(module_spec));
922             if (module_sp) {
923               if (num_compile_units > 0) {
924                 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
925                   module_sp->FindCompileUnits(
926                       compile_units.GetFileSpecAtIndex(cu_idx), sc_list);
927               } else {
928                 SymbolContext sc;
929                 sc.module_sp = module_sp;
930                 sc_list.Append(sc);
931               }
932             } else {
933               // Didn't find matching shlib/module in target...
934               result.AppendErrorWithFormat(
935                   "target doesn't contain the specified shared library: %s\n",
936                   module_file.GetPath().c_str());
937             }
938           }
939         } else {
940           // No shared libraries, we just want to find globals for the compile
941           // units files that were specified
942           for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
943             target->GetImages().FindCompileUnits(
944                 compile_units.GetFileSpecAtIndex(cu_idx), sc_list);
945         }
946 
947         const uint32_t num_scs = sc_list.GetSize();
948         if (num_scs > 0) {
949           SymbolContext sc;
950           for (uint32_t sc_idx = 0; sc_idx < num_scs; ++sc_idx) {
951             if (sc_list.GetContextAtIndex(sc_idx, sc)) {
952               if (sc.comp_unit) {
953                 const bool can_create = true;
954                 VariableListSP comp_unit_varlist_sp(
955                     sc.comp_unit->GetVariableList(can_create));
956                 if (comp_unit_varlist_sp)
957                   DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,
958                                          s);
959               } else if (sc.module_sp) {
960                 // Get all global variables for this module
961                 lldb_private::RegularExpression all_globals_regex(
962                     llvm::StringRef(
963                         ".")); // Any global with at least one character
964                 VariableList variable_list;
965                 sc.module_sp->FindGlobalVariables(all_globals_regex, UINT32_MAX,
966                                                   variable_list);
967                 DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s);
968               }
969             }
970           }
971         }
972       }
973     }
974 
975     if (m_interpreter.TruncationWarningNecessary()) {
976       result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
977                                       m_cmd_name.c_str());
978       m_interpreter.TruncationWarningGiven();
979     }
980 
981     return result.Succeeded();
982   }
983 
984   OptionGroupOptions m_option_group;
985   OptionGroupVariable m_option_variable;
986   OptionGroupFormat m_option_format;
987   OptionGroupFileList m_option_compile_units;
988   OptionGroupFileList m_option_shared_libraries;
989   OptionGroupValueObjectDisplay m_varobj_options;
990 };
991 
992 #pragma mark CommandObjectTargetModulesSearchPathsAdd
993 
994 class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed {
995 public:
996   CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter &interpreter)
997       : CommandObjectParsed(interpreter, "target modules search-paths add",
998                             "Add new image search paths substitution pairs to "
999                             "the current target.",
1000                             nullptr, eCommandRequiresTarget) {
1001     CommandArgumentEntry arg;
1002     CommandArgumentData old_prefix_arg;
1003     CommandArgumentData new_prefix_arg;
1004 
1005     // Define the first variant of this arg pair.
1006     old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1007     old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1008 
1009     // Define the first variant of this arg pair.
1010     new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1011     new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1012 
1013     // There are two required arguments that must always occur together, i.e.
1014     // an argument "pair".  Because they must always occur together, they are
1015     // treated as two variants of one argument rather than two independent
1016     // arguments.  Push them both into the first argument position for
1017     // m_arguments...
1018 
1019     arg.push_back(old_prefix_arg);
1020     arg.push_back(new_prefix_arg);
1021 
1022     m_arguments.push_back(arg);
1023   }
1024 
1025   ~CommandObjectTargetModulesSearchPathsAdd() override = default;
1026 
1027 protected:
1028   bool DoExecute(Args &command, CommandReturnObject &result) override {
1029     Target *target = &GetSelectedTarget();
1030     const size_t argc = command.GetArgumentCount();
1031     if (argc & 1) {
1032       result.AppendError("add requires an even number of arguments\n");
1033     } else {
1034       for (size_t i = 0; i < argc; i += 2) {
1035         const char *from = command.GetArgumentAtIndex(i);
1036         const char *to = command.GetArgumentAtIndex(i + 1);
1037 
1038         if (from[0] && to[0]) {
1039           Log *log = GetLog(LLDBLog::Host);
1040           if (log) {
1041             LLDB_LOGF(log,
1042                       "target modules search path adding ImageSearchPath "
1043                       "pair: '%s' -> '%s'",
1044                       from, to);
1045           }
1046           bool last_pair = ((argc - i) == 2);
1047           target->GetImageSearchPathList().Append(
1048               from, to, last_pair); // Notify if this is the last pair
1049           result.SetStatus(eReturnStatusSuccessFinishNoResult);
1050         } else {
1051           if (from[0])
1052             result.AppendError("<path-prefix> can't be empty\n");
1053           else
1054             result.AppendError("<new-path-prefix> can't be empty\n");
1055         }
1056       }
1057     }
1058     return result.Succeeded();
1059   }
1060 };
1061 
1062 #pragma mark CommandObjectTargetModulesSearchPathsClear
1063 
1064 class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed {
1065 public:
1066   CommandObjectTargetModulesSearchPathsClear(CommandInterpreter &interpreter)
1067       : CommandObjectParsed(interpreter, "target modules search-paths clear",
1068                             "Clear all current image search path substitution "
1069                             "pairs from the current target.",
1070                             "target modules search-paths clear",
1071                             eCommandRequiresTarget) {}
1072 
1073   ~CommandObjectTargetModulesSearchPathsClear() override = default;
1074 
1075 protected:
1076   bool DoExecute(Args &command, CommandReturnObject &result) override {
1077     Target *target = &GetSelectedTarget();
1078     bool notify = true;
1079     target->GetImageSearchPathList().Clear(notify);
1080     result.SetStatus(eReturnStatusSuccessFinishNoResult);
1081     return result.Succeeded();
1082   }
1083 };
1084 
1085 #pragma mark CommandObjectTargetModulesSearchPathsInsert
1086 
1087 class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed {
1088 public:
1089   CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter &interpreter)
1090       : CommandObjectParsed(interpreter, "target modules search-paths insert",
1091                             "Insert a new image search path substitution pair "
1092                             "into the current target at the specified index.",
1093                             nullptr, eCommandRequiresTarget) {
1094     CommandArgumentEntry arg1;
1095     CommandArgumentEntry arg2;
1096     CommandArgumentData index_arg;
1097     CommandArgumentData old_prefix_arg;
1098     CommandArgumentData new_prefix_arg;
1099 
1100     // Define the first and only variant of this arg.
1101     index_arg.arg_type = eArgTypeIndex;
1102     index_arg.arg_repetition = eArgRepeatPlain;
1103 
1104     // Put the one and only variant into the first arg for m_arguments:
1105     arg1.push_back(index_arg);
1106 
1107     // Define the first variant of this arg pair.
1108     old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1109     old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1110 
1111     // Define the first variant of this arg pair.
1112     new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1113     new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1114 
1115     // There are two required arguments that must always occur together, i.e.
1116     // an argument "pair".  Because they must always occur together, they are
1117     // treated as two variants of one argument rather than two independent
1118     // arguments.  Push them both into the same argument position for
1119     // m_arguments...
1120 
1121     arg2.push_back(old_prefix_arg);
1122     arg2.push_back(new_prefix_arg);
1123 
1124     // Add arguments to m_arguments.
1125     m_arguments.push_back(arg1);
1126     m_arguments.push_back(arg2);
1127   }
1128 
1129   ~CommandObjectTargetModulesSearchPathsInsert() override = default;
1130 
1131   void
1132   HandleArgumentCompletion(CompletionRequest &request,
1133                            OptionElementVector &opt_element_vector) override {
1134     if (!m_exe_ctx.HasTargetScope() || request.GetCursorIndex() != 0)
1135       return;
1136 
1137     Target *target = m_exe_ctx.GetTargetPtr();
1138     const PathMappingList &list = target->GetImageSearchPathList();
1139     const size_t num = list.GetSize();
1140     ConstString old_path, new_path;
1141     for (size_t i = 0; i < num; ++i) {
1142       if (!list.GetPathsAtIndex(i, old_path, new_path))
1143         break;
1144       StreamString strm;
1145       strm << old_path << " -> " << new_path;
1146       request.TryCompleteCurrentArg(std::to_string(i), strm.GetString());
1147     }
1148   }
1149 
1150 protected:
1151   bool DoExecute(Args &command, CommandReturnObject &result) override {
1152     Target *target = &GetSelectedTarget();
1153     size_t argc = command.GetArgumentCount();
1154     // check for at least 3 arguments and an odd number of parameters
1155     if (argc >= 3 && argc & 1) {
1156       uint32_t insert_idx;
1157 
1158       if (!llvm::to_integer(command.GetArgumentAtIndex(0), insert_idx)) {
1159         result.AppendErrorWithFormat(
1160             "<index> parameter is not an integer: '%s'.\n",
1161             command.GetArgumentAtIndex(0));
1162         return result.Succeeded();
1163       }
1164 
1165       // shift off the index
1166       command.Shift();
1167       argc = command.GetArgumentCount();
1168 
1169       for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) {
1170         const char *from = command.GetArgumentAtIndex(i);
1171         const char *to = command.GetArgumentAtIndex(i + 1);
1172 
1173         if (from[0] && to[0]) {
1174           bool last_pair = ((argc - i) == 2);
1175           target->GetImageSearchPathList().Insert(from, to, insert_idx,
1176                                                   last_pair);
1177           result.SetStatus(eReturnStatusSuccessFinishNoResult);
1178         } else {
1179           if (from[0])
1180             result.AppendError("<path-prefix> can't be empty\n");
1181           else
1182             result.AppendError("<new-path-prefix> can't be empty\n");
1183           return false;
1184         }
1185       }
1186     } else {
1187       result.AppendError("insert requires at least three arguments\n");
1188       return result.Succeeded();
1189     }
1190     return result.Succeeded();
1191   }
1192 };
1193 
1194 #pragma mark CommandObjectTargetModulesSearchPathsList
1195 
1196 class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed {
1197 public:
1198   CommandObjectTargetModulesSearchPathsList(CommandInterpreter &interpreter)
1199       : CommandObjectParsed(interpreter, "target modules search-paths list",
1200                             "List all current image search path substitution "
1201                             "pairs in the current target.",
1202                             "target modules search-paths list",
1203                             eCommandRequiresTarget) {}
1204 
1205   ~CommandObjectTargetModulesSearchPathsList() override = default;
1206 
1207 protected:
1208   bool DoExecute(Args &command, CommandReturnObject &result) override {
1209     Target *target = &GetSelectedTarget();
1210     if (command.GetArgumentCount() != 0) {
1211       result.AppendError("list takes no arguments\n");
1212       return result.Succeeded();
1213     }
1214 
1215     target->GetImageSearchPathList().Dump(&result.GetOutputStream());
1216     result.SetStatus(eReturnStatusSuccessFinishResult);
1217     return result.Succeeded();
1218   }
1219 };
1220 
1221 #pragma mark CommandObjectTargetModulesSearchPathsQuery
1222 
1223 class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed {
1224 public:
1225   CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter &interpreter)
1226       : CommandObjectParsed(
1227             interpreter, "target modules search-paths query",
1228             "Transform a path using the first applicable image search path.",
1229             nullptr, eCommandRequiresTarget) {
1230     CommandArgumentEntry arg;
1231     CommandArgumentData path_arg;
1232 
1233     // Define the first (and only) variant of this arg.
1234     path_arg.arg_type = eArgTypeDirectoryName;
1235     path_arg.arg_repetition = eArgRepeatPlain;
1236 
1237     // There is only one variant this argument could be; put it into the
1238     // argument entry.
1239     arg.push_back(path_arg);
1240 
1241     // Push the data for the first argument into the m_arguments vector.
1242     m_arguments.push_back(arg);
1243   }
1244 
1245   ~CommandObjectTargetModulesSearchPathsQuery() override = default;
1246 
1247 protected:
1248   bool DoExecute(Args &command, CommandReturnObject &result) override {
1249     Target *target = &GetSelectedTarget();
1250     if (command.GetArgumentCount() != 1) {
1251       result.AppendError("query requires one argument\n");
1252       return result.Succeeded();
1253     }
1254 
1255     ConstString orig(command.GetArgumentAtIndex(0));
1256     ConstString transformed;
1257     if (target->GetImageSearchPathList().RemapPath(orig, transformed))
1258       result.GetOutputStream().Printf("%s\n", transformed.GetCString());
1259     else
1260       result.GetOutputStream().Printf("%s\n", orig.GetCString());
1261 
1262     result.SetStatus(eReturnStatusSuccessFinishResult);
1263     return result.Succeeded();
1264   }
1265 };
1266 
1267 // Static Helper functions
1268 static void DumpModuleArchitecture(Stream &strm, Module *module,
1269                                    bool full_triple, uint32_t width) {
1270   if (module) {
1271     StreamString arch_strm;
1272 
1273     if (full_triple)
1274       module->GetArchitecture().DumpTriple(arch_strm.AsRawOstream());
1275     else
1276       arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
1277     std::string arch_str = std::string(arch_strm.GetString());
1278 
1279     if (width)
1280       strm.Printf("%-*s", width, arch_str.c_str());
1281     else
1282       strm.PutCString(arch_str);
1283   }
1284 }
1285 
1286 static void DumpModuleUUID(Stream &strm, Module *module) {
1287   if (module && module->GetUUID().IsValid())
1288     module->GetUUID().Dump(&strm);
1289   else
1290     strm.PutCString("                                    ");
1291 }
1292 
1293 static uint32_t DumpCompileUnitLineTable(CommandInterpreter &interpreter,
1294                                          Stream &strm, Module *module,
1295                                          const FileSpec &file_spec,
1296                                          lldb::DescriptionLevel desc_level) {
1297   uint32_t num_matches = 0;
1298   if (module) {
1299     SymbolContextList sc_list;
1300     num_matches = module->ResolveSymbolContextsForFileSpec(
1301         file_spec, 0, false, eSymbolContextCompUnit, sc_list);
1302 
1303     for (uint32_t i = 0; i < num_matches; ++i) {
1304       SymbolContext sc;
1305       if (sc_list.GetContextAtIndex(i, sc)) {
1306         if (i > 0)
1307           strm << "\n\n";
1308 
1309         strm << "Line table for " << sc.comp_unit->GetPrimaryFile() << " in `"
1310              << module->GetFileSpec().GetFilename() << "\n";
1311         LineTable *line_table = sc.comp_unit->GetLineTable();
1312         if (line_table)
1313           line_table->GetDescription(
1314               &strm, interpreter.GetExecutionContext().GetTargetPtr(),
1315               desc_level);
1316         else
1317           strm << "No line table";
1318       }
1319     }
1320   }
1321   return num_matches;
1322 }
1323 
1324 static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr,
1325                          uint32_t width) {
1326   if (file_spec_ptr) {
1327     if (width > 0) {
1328       std::string fullpath = file_spec_ptr->GetPath();
1329       strm.Printf("%-*s", width, fullpath.c_str());
1330       return;
1331     } else {
1332       file_spec_ptr->Dump(strm.AsRawOstream());
1333       return;
1334     }
1335   }
1336   // Keep the width spacing correct if things go wrong...
1337   if (width > 0)
1338     strm.Printf("%-*s", width, "");
1339 }
1340 
1341 static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr,
1342                           uint32_t width) {
1343   if (file_spec_ptr) {
1344     if (width > 0)
1345       strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
1346     else
1347       file_spec_ptr->GetDirectory().Dump(&strm);
1348     return;
1349   }
1350   // Keep the width spacing correct if things go wrong...
1351   if (width > 0)
1352     strm.Printf("%-*s", width, "");
1353 }
1354 
1355 static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,
1356                          uint32_t width) {
1357   if (file_spec_ptr) {
1358     if (width > 0)
1359       strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
1360     else
1361       file_spec_ptr->GetFilename().Dump(&strm);
1362     return;
1363   }
1364   // Keep the width spacing correct if things go wrong...
1365   if (width > 0)
1366     strm.Printf("%-*s", width, "");
1367 }
1368 
1369 static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
1370   std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
1371   const size_t num_modules = module_list.GetSize();
1372   if (num_modules == 0)
1373     return 0;
1374 
1375   size_t num_dumped = 0;
1376   strm.Format("Dumping headers for {0} module(s).\n", num_modules);
1377   strm.IndentMore();
1378   for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
1379     if (module_sp) {
1380       if (num_dumped++ > 0) {
1381         strm.EOL();
1382         strm.EOL();
1383       }
1384       ObjectFile *objfile = module_sp->GetObjectFile();
1385       if (objfile)
1386         objfile->Dump(&strm);
1387       else {
1388         strm.Format("No object file for module: {0:F}\n",
1389                     module_sp->GetFileSpec());
1390       }
1391     }
1392   }
1393   strm.IndentLess();
1394   return num_dumped;
1395 }
1396 
1397 static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm,
1398                              Module *module, SortOrder sort_order,
1399                              Mangled::NamePreference name_preference) {
1400   if (!module)
1401     return;
1402   if (Symtab *symtab = module->GetSymtab())
1403     symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),
1404                  sort_order, name_preference);
1405 }
1406 
1407 static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,
1408                                Module *module) {
1409   if (module) {
1410     SectionList *section_list = module->GetSectionList();
1411     if (section_list) {
1412       strm.Printf("Sections for '%s' (%s):\n",
1413                   module->GetSpecificationDescription().c_str(),
1414                   module->GetArchitecture().GetArchitectureName());
1415       section_list->Dump(strm.AsRawOstream(), strm.GetIndentLevel() + 2,
1416                          interpreter.GetExecutionContext().GetTargetPtr(), true,
1417                          UINT32_MAX);
1418     }
1419   }
1420 }
1421 
1422 static bool DumpModuleSymbolFile(Stream &strm, Module *module) {
1423   if (module) {
1424     if (SymbolFile *symbol_file = module->GetSymbolFile(true)) {
1425       symbol_file->Dump(strm);
1426       return true;
1427     }
1428   }
1429   return false;
1430 }
1431 
1432 static void DumpAddress(ExecutionContextScope *exe_scope,
1433                         const Address &so_addr, bool verbose, bool all_ranges,
1434                         Stream &strm) {
1435   strm.IndentMore();
1436   strm.Indent("    Address: ");
1437   so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1438   strm.PutCString(" (");
1439   so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1440   strm.PutCString(")\n");
1441   strm.Indent("    Summary: ");
1442   const uint32_t save_indent = strm.GetIndentLevel();
1443   strm.SetIndentLevel(save_indent + 13);
1444   so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription);
1445   strm.SetIndentLevel(save_indent);
1446   // Print out detailed address information when verbose is enabled
1447   if (verbose) {
1448     strm.EOL();
1449     so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext,
1450                  Address::DumpStyleInvalid, UINT32_MAX, all_ranges);
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, bool all_ranges) {
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, all_ranges, 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, bool all_ranges) {
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, all_ranges, 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, bool all_ranges) {
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, all_ranges, 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, bool all_ranges) {
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, all_ranges);
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     bool name_is_fully_qualified = false;
1609 
1610     ConstString name(name_cstr);
1611     llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
1612     module->FindTypes(name, name_is_fully_qualified, max_num_matches,
1613                       searched_symbol_files, type_list);
1614 
1615     if (type_list.Empty())
1616       return 0;
1617 
1618     const uint64_t num_matches = type_list.GetSize();
1619 
1620     strm.Indent();
1621     strm.Printf("%" PRIu64 " match%s found in ", num_matches,
1622                 num_matches > 1 ? "es" : "");
1623     DumpFullpath(strm, &module->GetFileSpec(), 0);
1624     strm.PutCString(":\n");
1625     for (TypeSP type_sp : type_list.Types()) {
1626       if (!type_sp)
1627         continue;
1628       // Resolve the clang type so that any forward references to types
1629       // that haven't yet been parsed will get parsed.
1630       type_sp->GetFullCompilerType();
1631       type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
1632       // Print all typedef chains
1633       TypeSP typedef_type_sp(type_sp);
1634       TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1635       while (typedefed_type_sp) {
1636         strm.EOL();
1637         strm.Printf("     typedef '%s': ",
1638                     typedef_type_sp->GetName().GetCString());
1639         typedefed_type_sp->GetFullCompilerType();
1640         typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
1641                                           target);
1642         typedef_type_sp = typedefed_type_sp;
1643         typedefed_type_sp = typedef_type_sp->GetTypedefType();
1644       }
1645     }
1646     strm.EOL();
1647   }
1648   return type_list.GetSize();
1649 }
1650 
1651 static size_t LookupTypeHere(Target *target, CommandInterpreter &interpreter,
1652                              Stream &strm, Module &module,
1653                              const char *name_cstr, bool name_is_regex) {
1654   TypeList type_list;
1655   const uint32_t max_num_matches = UINT32_MAX;
1656   bool name_is_fully_qualified = false;
1657 
1658   ConstString name(name_cstr);
1659   llvm::DenseSet<SymbolFile *> searched_symbol_files;
1660   module.FindTypes(name, name_is_fully_qualified, max_num_matches,
1661                    searched_symbol_files, type_list);
1662 
1663   if (type_list.Empty())
1664     return 0;
1665 
1666   strm.Indent();
1667   strm.PutCString("Best match found in ");
1668   DumpFullpath(strm, &module.GetFileSpec(), 0);
1669   strm.PutCString(":\n");
1670 
1671   TypeSP type_sp(type_list.GetTypeAtIndex(0));
1672   if (type_sp) {
1673     // Resolve the clang type so that any forward references to types that
1674     // haven't yet been parsed will get parsed.
1675     type_sp->GetFullCompilerType();
1676     type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
1677     // Print all typedef chains.
1678     TypeSP typedef_type_sp(type_sp);
1679     TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1680     while (typedefed_type_sp) {
1681       strm.EOL();
1682       strm.Printf("     typedef '%s': ",
1683                   typedef_type_sp->GetName().GetCString());
1684       typedefed_type_sp->GetFullCompilerType();
1685       typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
1686                                         target);
1687       typedef_type_sp = typedefed_type_sp;
1688       typedefed_type_sp = typedef_type_sp->GetTypedefType();
1689     }
1690   }
1691   strm.EOL();
1692   return type_list.GetSize();
1693 }
1694 
1695 static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter,
1696                                           Stream &strm, Module *module,
1697                                           const FileSpec &file_spec,
1698                                           uint32_t line, bool check_inlines,
1699                                           bool verbose, bool all_ranges) {
1700   if (module && file_spec) {
1701     SymbolContextList sc_list;
1702     const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(
1703         file_spec, line, check_inlines, eSymbolContextEverything, sc_list);
1704     if (num_matches > 0) {
1705       strm.Indent();
1706       strm.Printf("%u match%s found in ", num_matches,
1707                   num_matches > 1 ? "es" : "");
1708       strm << file_spec;
1709       if (line > 0)
1710         strm.Printf(":%u", line);
1711       strm << " in ";
1712       DumpFullpath(strm, &module->GetFileSpec(), 0);
1713       strm.PutCString(":\n");
1714       DumpSymbolContextList(
1715           interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1716           strm, sc_list, verbose, all_ranges);
1717       return num_matches;
1718     }
1719   }
1720   return 0;
1721 }
1722 
1723 static size_t FindModulesByName(Target *target, const char *module_name,
1724                                 ModuleList &module_list,
1725                                 bool check_global_list) {
1726   FileSpec module_file_spec(module_name);
1727   ModuleSpec module_spec(module_file_spec);
1728 
1729   const size_t initial_size = module_list.GetSize();
1730 
1731   if (check_global_list) {
1732     // Check the global list
1733     std::lock_guard<std::recursive_mutex> guard(
1734         Module::GetAllocationModuleCollectionMutex());
1735     const size_t num_modules = Module::GetNumberAllocatedModules();
1736     ModuleSP module_sp;
1737     for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1738       Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
1739 
1740       if (module) {
1741         if (module->MatchesModuleSpec(module_spec)) {
1742           module_sp = module->shared_from_this();
1743           module_list.AppendIfNeeded(module_sp);
1744         }
1745       }
1746     }
1747   } else {
1748     if (target) {
1749       target->GetImages().FindModules(module_spec, module_list);
1750       const size_t num_matches = module_list.GetSize();
1751 
1752       // Not found in our module list for our target, check the main shared
1753       // module list in case it is a extra file used somewhere else
1754       if (num_matches == 0) {
1755         module_spec.GetArchitecture() = target->GetArchitecture();
1756         ModuleList::FindSharedModules(module_spec, module_list);
1757       }
1758     } else {
1759       ModuleList::FindSharedModules(module_spec, module_list);
1760     }
1761   }
1762 
1763   return module_list.GetSize() - initial_size;
1764 }
1765 
1766 #pragma mark CommandObjectTargetModulesModuleAutoComplete
1767 
1768 // A base command object class that can auto complete with module file
1769 // paths
1770 
1771 class CommandObjectTargetModulesModuleAutoComplete
1772     : public CommandObjectParsed {
1773 public:
1774   CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter,
1775                                                const char *name,
1776                                                const char *help,
1777                                                const char *syntax,
1778                                                uint32_t flags = 0)
1779       : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1780     CommandArgumentEntry arg;
1781     CommandArgumentData file_arg;
1782 
1783     // Define the first (and only) variant of this arg.
1784     file_arg.arg_type = eArgTypeFilename;
1785     file_arg.arg_repetition = eArgRepeatStar;
1786 
1787     // There is only one variant this argument could be; put it into the
1788     // argument entry.
1789     arg.push_back(file_arg);
1790 
1791     // Push the data for the first argument into the m_arguments vector.
1792     m_arguments.push_back(arg);
1793   }
1794 
1795   ~CommandObjectTargetModulesModuleAutoComplete() override = default;
1796 
1797   void
1798   HandleArgumentCompletion(CompletionRequest &request,
1799                            OptionElementVector &opt_element_vector) override {
1800     CommandCompletions::InvokeCommonCompletionCallbacks(
1801         GetCommandInterpreter(), CommandCompletions::eModuleCompletion, request,
1802         nullptr);
1803   }
1804 };
1805 
1806 #pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1807 
1808 // A base command object class that can auto complete with module source
1809 // file paths
1810 
1811 class CommandObjectTargetModulesSourceFileAutoComplete
1812     : public CommandObjectParsed {
1813 public:
1814   CommandObjectTargetModulesSourceFileAutoComplete(
1815       CommandInterpreter &interpreter, const char *name, const char *help,
1816       const char *syntax, uint32_t flags)
1817       : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1818     CommandArgumentEntry arg;
1819     CommandArgumentData source_file_arg;
1820 
1821     // Define the first (and only) variant of this arg.
1822     source_file_arg.arg_type = eArgTypeSourceFile;
1823     source_file_arg.arg_repetition = eArgRepeatPlus;
1824 
1825     // There is only one variant this argument could be; put it into the
1826     // argument entry.
1827     arg.push_back(source_file_arg);
1828 
1829     // Push the data for the first argument into the m_arguments vector.
1830     m_arguments.push_back(arg);
1831   }
1832 
1833   ~CommandObjectTargetModulesSourceFileAutoComplete() override = default;
1834 
1835   void
1836   HandleArgumentCompletion(CompletionRequest &request,
1837                            OptionElementVector &opt_element_vector) override {
1838     CommandCompletions::InvokeCommonCompletionCallbacks(
1839         GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion,
1840         request, nullptr);
1841   }
1842 };
1843 
1844 #pragma mark CommandObjectTargetModulesDumpObjfile
1845 
1846 class CommandObjectTargetModulesDumpObjfile
1847     : public CommandObjectTargetModulesModuleAutoComplete {
1848 public:
1849   CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter)
1850       : CommandObjectTargetModulesModuleAutoComplete(
1851             interpreter, "target modules dump objfile",
1852             "Dump the object file headers from one or more target modules.",
1853             nullptr, eCommandRequiresTarget) {}
1854 
1855   ~CommandObjectTargetModulesDumpObjfile() override = default;
1856 
1857 protected:
1858   bool DoExecute(Args &command, CommandReturnObject &result) override {
1859     Target *target = &GetSelectedTarget();
1860 
1861     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1862     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1863     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1864 
1865     size_t num_dumped = 0;
1866     if (command.GetArgumentCount() == 0) {
1867       // Dump all headers for all modules images
1868       num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(),
1869                                             target->GetImages());
1870       if (num_dumped == 0) {
1871         result.AppendError("the target has no associated executable images");
1872       }
1873     } else {
1874       // Find the modules that match the basename or full path.
1875       ModuleList module_list;
1876       const char *arg_cstr;
1877       for (int arg_idx = 0;
1878            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
1879            ++arg_idx) {
1880         size_t num_matched =
1881             FindModulesByName(target, arg_cstr, module_list, true);
1882         if (num_matched == 0) {
1883           result.AppendWarningWithFormat(
1884               "Unable to find an image that matches '%s'.\n", arg_cstr);
1885         }
1886       }
1887       // Dump all the modules we found.
1888       num_dumped =
1889           DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
1890     }
1891 
1892     if (num_dumped > 0) {
1893       result.SetStatus(eReturnStatusSuccessFinishResult);
1894     } else {
1895       result.AppendError("no matching executable images found");
1896     }
1897     return result.Succeeded();
1898   }
1899 };
1900 
1901 #pragma mark CommandObjectTargetModulesDumpSymtab
1902 
1903 static constexpr OptionEnumValueElement g_sort_option_enumeration[] = {
1904     {
1905         eSortOrderNone,
1906         "none",
1907         "No sorting, use the original symbol table order.",
1908     },
1909     {
1910         eSortOrderByAddress,
1911         "address",
1912         "Sort output by symbol address.",
1913     },
1914     {
1915         eSortOrderByName,
1916         "name",
1917         "Sort output by symbol name.",
1918     },
1919 };
1920 
1921 #define LLDB_OPTIONS_target_modules_dump_symtab
1922 #include "CommandOptions.inc"
1923 
1924 class CommandObjectTargetModulesDumpSymtab
1925     : public CommandObjectTargetModulesModuleAutoComplete {
1926 public:
1927   CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter)
1928       : CommandObjectTargetModulesModuleAutoComplete(
1929             interpreter, "target modules dump symtab",
1930             "Dump the symbol table from one or more target modules.", nullptr,
1931             eCommandRequiresTarget) {}
1932 
1933   ~CommandObjectTargetModulesDumpSymtab() override = default;
1934 
1935   Options *GetOptions() override { return &m_options; }
1936 
1937   class CommandOptions : public Options {
1938   public:
1939     CommandOptions() {}
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() { 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_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
2426                       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_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,
2578                       "Fullpath or basename for module to load.", ""),
2579         m_load_option(LLDB_OPT_SET_1, false, "load", 'l',
2580                       "Write file contents to the memory.", false, true),
2581         m_pc_option(LLDB_OPT_SET_1, false, "set-pc-to-entry", 'p',
2582                     "Set PC to the entry point."
2583                     " Only applicable with '--load' option.",
2584                     false, true),
2585         m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,
2586                        "Set the load address for all sections to be the "
2587                        "virtual address in the file plus the offset.",
2588                        0) {
2589     m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2590                           LLDB_OPT_SET_1);
2591     m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2592     m_option_group.Append(&m_load_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2593     m_option_group.Append(&m_pc_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2594     m_option_group.Append(&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2595     m_option_group.Finalize();
2596   }
2597 
2598   ~CommandObjectTargetModulesLoad() override = default;
2599 
2600   Options *GetOptions() override { return &m_option_group; }
2601 
2602 protected:
2603   bool DoExecute(Args &args, CommandReturnObject &result) override {
2604     Target *target = &GetSelectedTarget();
2605     const bool load = m_load_option.GetOptionValue().GetCurrentValue();
2606     const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue();
2607 
2608     const size_t argc = args.GetArgumentCount();
2609     ModuleSpec module_spec;
2610     bool search_using_module_spec = false;
2611 
2612     // Allow "load" option to work without --file or --uuid option.
2613     if (load) {
2614       if (!m_file_option.GetOptionValue().OptionWasSet() &&
2615           !m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2616         ModuleList &module_list = target->GetImages();
2617         if (module_list.GetSize() == 1) {
2618           search_using_module_spec = true;
2619           module_spec.GetFileSpec() =
2620               module_list.GetModuleAtIndex(0)->GetFileSpec();
2621         }
2622       }
2623     }
2624 
2625     if (m_file_option.GetOptionValue().OptionWasSet()) {
2626       search_using_module_spec = true;
2627       const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
2628       const bool use_global_module_list = true;
2629       ModuleList module_list;
2630       const size_t num_matches = FindModulesByName(
2631           target, arg_cstr, module_list, use_global_module_list);
2632       if (num_matches == 1) {
2633         module_spec.GetFileSpec() =
2634             module_list.GetModuleAtIndex(0)->GetFileSpec();
2635       } else if (num_matches > 1) {
2636         search_using_module_spec = false;
2637         result.AppendErrorWithFormat(
2638             "more than 1 module matched by name '%s'\n", arg_cstr);
2639       } else {
2640         search_using_module_spec = false;
2641         result.AppendErrorWithFormat("no object file for module '%s'\n",
2642                                      arg_cstr);
2643       }
2644     }
2645 
2646     if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2647       search_using_module_spec = true;
2648       module_spec.GetUUID() =
2649           m_uuid_option_group.GetOptionValue().GetCurrentValue();
2650     }
2651 
2652     if (search_using_module_spec) {
2653       ModuleList matching_modules;
2654       target->GetImages().FindModules(module_spec, matching_modules);
2655       const size_t num_matches = matching_modules.GetSize();
2656 
2657       char path[PATH_MAX];
2658       if (num_matches == 1) {
2659         Module *module = matching_modules.GetModulePointerAtIndex(0);
2660         if (module) {
2661           ObjectFile *objfile = module->GetObjectFile();
2662           if (objfile) {
2663             SectionList *section_list = module->GetSectionList();
2664             if (section_list) {
2665               bool changed = false;
2666               if (argc == 0) {
2667                 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2668                   const addr_t slide =
2669                       m_slide_option.GetOptionValue().GetCurrentValue();
2670                   const bool slide_is_offset = true;
2671                   module->SetLoadAddress(*target, slide, slide_is_offset,
2672                                          changed);
2673                 } else {
2674                   result.AppendError("one or more section name + load "
2675                                      "address pair must be specified");
2676                   return false;
2677                 }
2678               } else {
2679                 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2680                   result.AppendError("The \"--slide <offset>\" option can't "
2681                                      "be used in conjunction with setting "
2682                                      "section load addresses.\n");
2683                   return false;
2684                 }
2685 
2686                 for (size_t i = 0; i < argc; i += 2) {
2687                   const char *sect_name = args.GetArgumentAtIndex(i);
2688                   const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
2689                   if (sect_name && load_addr_cstr) {
2690                     ConstString const_sect_name(sect_name);
2691                     addr_t load_addr;
2692                     if (llvm::to_integer(load_addr_cstr, load_addr)) {
2693                       SectionSP section_sp(
2694                           section_list->FindSectionByName(const_sect_name));
2695                       if (section_sp) {
2696                         if (section_sp->IsThreadSpecific()) {
2697                           result.AppendErrorWithFormat(
2698                               "thread specific sections are not yet "
2699                               "supported (section '%s')\n",
2700                               sect_name);
2701                           break;
2702                         } else {
2703                           if (target->GetSectionLoadList()
2704                                   .SetSectionLoadAddress(section_sp, load_addr))
2705                             changed = true;
2706                           result.AppendMessageWithFormat(
2707                               "section '%s' loaded at 0x%" PRIx64 "\n",
2708                               sect_name, load_addr);
2709                         }
2710                       } else {
2711                         result.AppendErrorWithFormat("no section found that "
2712                                                      "matches the section "
2713                                                      "name '%s'\n",
2714                                                      sect_name);
2715                         break;
2716                       }
2717                     } else {
2718                       result.AppendErrorWithFormat(
2719                           "invalid load address string '%s'\n", load_addr_cstr);
2720                       break;
2721                     }
2722                   } else {
2723                     if (sect_name)
2724                       result.AppendError("section names must be followed by "
2725                                          "a load address.\n");
2726                     else
2727                       result.AppendError("one or more section name + load "
2728                                          "address pair must be specified.\n");
2729                     break;
2730                   }
2731                 }
2732               }
2733 
2734               if (changed) {
2735                 target->ModulesDidLoad(matching_modules);
2736                 Process *process = m_exe_ctx.GetProcessPtr();
2737                 if (process)
2738                   process->Flush();
2739               }
2740               if (load) {
2741                 ProcessSP process = target->CalculateProcess();
2742                 Address file_entry = objfile->GetEntryPointAddress();
2743                 if (!process) {
2744                   result.AppendError("No process");
2745                   return false;
2746                 }
2747                 if (set_pc && !file_entry.IsValid()) {
2748                   result.AppendError("No entry address in object file");
2749                   return false;
2750                 }
2751                 std::vector<ObjectFile::LoadableData> loadables(
2752                     objfile->GetLoadableData(*target));
2753                 if (loadables.size() == 0) {
2754                   result.AppendError("No loadable sections");
2755                   return false;
2756                 }
2757                 Status error = process->WriteObjectFile(std::move(loadables));
2758                 if (error.Fail()) {
2759                   result.AppendError(error.AsCString());
2760                   return false;
2761                 }
2762                 if (set_pc) {
2763                   ThreadList &thread_list = process->GetThreadList();
2764                   RegisterContextSP reg_context(
2765                       thread_list.GetSelectedThread()->GetRegisterContext());
2766                   addr_t file_entry_addr = file_entry.GetLoadAddress(target);
2767                   if (!reg_context->SetPC(file_entry_addr)) {
2768                     result.AppendErrorWithFormat("failed to set PC value to "
2769                                                  "0x%" PRIx64 "\n",
2770                                                  file_entry_addr);
2771                   }
2772                 }
2773               }
2774             } else {
2775               module->GetFileSpec().GetPath(path, sizeof(path));
2776               result.AppendErrorWithFormat("no sections in object file '%s'\n",
2777                                            path);
2778             }
2779           } else {
2780             module->GetFileSpec().GetPath(path, sizeof(path));
2781             result.AppendErrorWithFormat("no object file for module '%s'\n",
2782                                          path);
2783           }
2784         } else {
2785           FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
2786           if (module_spec_file) {
2787             module_spec_file->GetPath(path, sizeof(path));
2788             result.AppendErrorWithFormat("invalid module '%s'.\n", path);
2789           } else
2790             result.AppendError("no module spec");
2791         }
2792       } else {
2793         std::string uuid_str;
2794 
2795         if (module_spec.GetFileSpec())
2796           module_spec.GetFileSpec().GetPath(path, sizeof(path));
2797         else
2798           path[0] = '\0';
2799 
2800         if (module_spec.GetUUIDPtr())
2801           uuid_str = module_spec.GetUUID().GetAsString();
2802         if (num_matches > 1) {
2803           result.AppendErrorWithFormat(
2804               "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "",
2805               path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
2806           for (size_t i = 0; i < num_matches; ++i) {
2807             if (matching_modules.GetModulePointerAtIndex(i)
2808                     ->GetFileSpec()
2809                     .GetPath(path, sizeof(path)))
2810               result.AppendMessageWithFormat("%s\n", path);
2811           }
2812         } else {
2813           result.AppendErrorWithFormat(
2814               "no modules were found  that match%s%s%s%s.\n",
2815               path[0] ? " file=" : "", path, !uuid_str.empty() ? " uuid=" : "",
2816               uuid_str.c_str());
2817         }
2818       }
2819     } else {
2820       result.AppendError("either the \"--file <module>\" or the \"--uuid "
2821                          "<uuid>\" option must be specified.\n");
2822       return false;
2823     }
2824     return result.Succeeded();
2825   }
2826 
2827   OptionGroupOptions m_option_group;
2828   OptionGroupUUID m_uuid_option_group;
2829   OptionGroupString m_file_option;
2830   OptionGroupBoolean m_load_option;
2831   OptionGroupBoolean m_pc_option;
2832   OptionGroupUInt64 m_slide_option;
2833 };
2834 
2835 #pragma mark CommandObjectTargetModulesList
2836 // List images with associated information
2837 #define LLDB_OPTIONS_target_modules_list
2838 #include "CommandOptions.inc"
2839 
2840 class CommandObjectTargetModulesList : public CommandObjectParsed {
2841 public:
2842   class CommandOptions : public Options {
2843   public:
2844     CommandOptions() {}
2845 
2846     ~CommandOptions() override = default;
2847 
2848     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2849                           ExecutionContext *execution_context) override {
2850       Status error;
2851 
2852       const int short_option = m_getopt_table[option_idx].val;
2853       if (short_option == 'g') {
2854         m_use_global_module_list = true;
2855       } else if (short_option == 'a') {
2856         m_module_addr = OptionArgParser::ToAddress(
2857             execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);
2858       } else {
2859         unsigned long width = 0;
2860         option_arg.getAsInteger(0, width);
2861         m_format_array.push_back(std::make_pair(short_option, width));
2862       }
2863       return error;
2864     }
2865 
2866     void OptionParsingStarting(ExecutionContext *execution_context) override {
2867       m_format_array.clear();
2868       m_use_global_module_list = false;
2869       m_module_addr = LLDB_INVALID_ADDRESS;
2870     }
2871 
2872     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2873       return llvm::makeArrayRef(g_target_modules_list_options);
2874     }
2875 
2876     // Instance variables to hold the values for command options.
2877     typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection;
2878     FormatWidthCollection m_format_array;
2879     bool m_use_global_module_list = false;
2880     lldb::addr_t m_module_addr = LLDB_INVALID_ADDRESS;
2881   };
2882 
2883   CommandObjectTargetModulesList(CommandInterpreter &interpreter)
2884       : CommandObjectParsed(
2885             interpreter, "target modules list",
2886             "List current executable and dependent shared library images.",
2887             "target modules list [<cmd-options>]") {}
2888 
2889   ~CommandObjectTargetModulesList() override = default;
2890 
2891   Options *GetOptions() override { return &m_options; }
2892 
2893 protected:
2894   bool DoExecute(Args &command, CommandReturnObject &result) override {
2895     Target *target = GetDebugger().GetSelectedTarget().get();
2896     const bool use_global_module_list = m_options.m_use_global_module_list;
2897     // Define a local module list here to ensure it lives longer than any
2898     // "locker" object which might lock its contents below (through the
2899     // "module_list_ptr" variable).
2900     ModuleList module_list;
2901     if (target == nullptr && !use_global_module_list) {
2902       result.AppendError("invalid target, create a debug target using the "
2903                          "'target create' command");
2904       return false;
2905     } else {
2906       if (target) {
2907         uint32_t addr_byte_size =
2908             target->GetArchitecture().GetAddressByteSize();
2909         result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2910         result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2911       }
2912       // Dump all sections for all modules images
2913       Stream &strm = result.GetOutputStream();
2914 
2915       if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) {
2916         if (target) {
2917           Address module_address;
2918           if (module_address.SetLoadAddress(m_options.m_module_addr, target)) {
2919             ModuleSP module_sp(module_address.GetModule());
2920             if (module_sp) {
2921               PrintModule(target, module_sp.get(), 0, strm);
2922               result.SetStatus(eReturnStatusSuccessFinishResult);
2923             } else {
2924               result.AppendErrorWithFormat(
2925                   "Couldn't find module matching address: 0x%" PRIx64 ".",
2926                   m_options.m_module_addr);
2927             }
2928           } else {
2929             result.AppendErrorWithFormat(
2930                 "Couldn't find module containing address: 0x%" PRIx64 ".",
2931                 m_options.m_module_addr);
2932           }
2933         } else {
2934           result.AppendError(
2935               "Can only look up modules by address with a valid target.");
2936         }
2937         return result.Succeeded();
2938       }
2939 
2940       size_t num_modules = 0;
2941 
2942       // This locker will be locked on the mutex in module_list_ptr if it is
2943       // non-nullptr. Otherwise it will lock the
2944       // AllocationModuleCollectionMutex when accessing the global module list
2945       // directly.
2946       std::unique_lock<std::recursive_mutex> guard(
2947           Module::GetAllocationModuleCollectionMutex(), std::defer_lock);
2948 
2949       const ModuleList *module_list_ptr = nullptr;
2950       const size_t argc = command.GetArgumentCount();
2951       if (argc == 0) {
2952         if (use_global_module_list) {
2953           guard.lock();
2954           num_modules = Module::GetNumberAllocatedModules();
2955         } else {
2956           module_list_ptr = &target->GetImages();
2957         }
2958       } else {
2959         for (const Args::ArgEntry &arg : command) {
2960           // Dump specified images (by basename or fullpath)
2961           const size_t num_matches = FindModulesByName(
2962               target, arg.c_str(), module_list, use_global_module_list);
2963           if (num_matches == 0) {
2964             if (argc == 1) {
2965               result.AppendErrorWithFormat("no modules found that match '%s'",
2966                                            arg.c_str());
2967               return false;
2968             }
2969           }
2970         }
2971 
2972         module_list_ptr = &module_list;
2973       }
2974 
2975       std::unique_lock<std::recursive_mutex> lock;
2976       if (module_list_ptr != nullptr) {
2977         lock =
2978             std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
2979 
2980         num_modules = module_list_ptr->GetSize();
2981       }
2982 
2983       if (num_modules > 0) {
2984         for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2985           ModuleSP module_sp;
2986           Module *module;
2987           if (module_list_ptr) {
2988             module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
2989             module = module_sp.get();
2990           } else {
2991             module = Module::GetAllocatedModuleAtIndex(image_idx);
2992             module_sp = module->shared_from_this();
2993           }
2994 
2995           const size_t indent = strm.Printf("[%3u] ", image_idx);
2996           PrintModule(target, module, indent, strm);
2997         }
2998         result.SetStatus(eReturnStatusSuccessFinishResult);
2999       } else {
3000         if (argc) {
3001           if (use_global_module_list)
3002             result.AppendError(
3003                 "the global module list has no matching modules");
3004           else
3005             result.AppendError("the target has no matching modules");
3006         } else {
3007           if (use_global_module_list)
3008             result.AppendError("the global module list is empty");
3009           else
3010             result.AppendError(
3011                 "the target has no associated executable images");
3012         }
3013         return false;
3014       }
3015     }
3016     return result.Succeeded();
3017   }
3018 
3019   void PrintModule(Target *target, Module *module, int indent, Stream &strm) {
3020     if (module == nullptr) {
3021       strm.PutCString("Null module");
3022       return;
3023     }
3024 
3025     bool dump_object_name = false;
3026     if (m_options.m_format_array.empty()) {
3027       m_options.m_format_array.push_back(std::make_pair('u', 0));
3028       m_options.m_format_array.push_back(std::make_pair('h', 0));
3029       m_options.m_format_array.push_back(std::make_pair('f', 0));
3030       m_options.m_format_array.push_back(std::make_pair('S', 0));
3031     }
3032     const size_t num_entries = m_options.m_format_array.size();
3033     bool print_space = false;
3034     for (size_t i = 0; i < num_entries; ++i) {
3035       if (print_space)
3036         strm.PutChar(' ');
3037       print_space = true;
3038       const char format_char = m_options.m_format_array[i].first;
3039       uint32_t width = m_options.m_format_array[i].second;
3040       switch (format_char) {
3041       case 'A':
3042         DumpModuleArchitecture(strm, module, false, width);
3043         break;
3044 
3045       case 't':
3046         DumpModuleArchitecture(strm, module, true, width);
3047         break;
3048 
3049       case 'f':
3050         DumpFullpath(strm, &module->GetFileSpec(), width);
3051         dump_object_name = true;
3052         break;
3053 
3054       case 'd':
3055         DumpDirectory(strm, &module->GetFileSpec(), width);
3056         break;
3057 
3058       case 'b':
3059         DumpBasename(strm, &module->GetFileSpec(), width);
3060         dump_object_name = true;
3061         break;
3062 
3063       case 'h':
3064       case 'o':
3065         // Image header address
3066         {
3067           uint32_t addr_nibble_width =
3068               target ? (target->GetArchitecture().GetAddressByteSize() * 2)
3069                      : 16;
3070 
3071           ObjectFile *objfile = module->GetObjectFile();
3072           if (objfile) {
3073             Address base_addr(objfile->GetBaseAddress());
3074             if (base_addr.IsValid()) {
3075               if (target && !target->GetSectionLoadList().IsEmpty()) {
3076                 lldb::addr_t load_addr = base_addr.GetLoadAddress(target);
3077                 if (load_addr == LLDB_INVALID_ADDRESS) {
3078                   base_addr.Dump(&strm, target,
3079                                  Address::DumpStyleModuleWithFileAddress,
3080                                  Address::DumpStyleFileAddress);
3081                 } else {
3082                   if (format_char == 'o') {
3083                     // Show the offset of slide for the image
3084                     strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3085                                 addr_nibble_width,
3086                                 load_addr - base_addr.GetFileAddress());
3087                   } else {
3088                     // Show the load address of the image
3089                     strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3090                                 addr_nibble_width, load_addr);
3091                   }
3092                 }
3093                 break;
3094               }
3095               // The address was valid, but the image isn't loaded, output the
3096               // address in an appropriate format
3097               base_addr.Dump(&strm, target, Address::DumpStyleFileAddress);
3098               break;
3099             }
3100           }
3101           strm.Printf("%*s", addr_nibble_width + 2, "");
3102         }
3103         break;
3104 
3105       case 'r': {
3106         size_t ref_count = 0;
3107         ModuleSP module_sp(module->shared_from_this());
3108         if (module_sp) {
3109           // Take one away to make sure we don't count our local "module_sp"
3110           ref_count = module_sp.use_count() - 1;
3111         }
3112         if (width)
3113           strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count);
3114         else
3115           strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count);
3116       } break;
3117 
3118       case 's':
3119       case 'S': {
3120         if (const SymbolFile *symbol_file = module->GetSymbolFile()) {
3121           const FileSpec symfile_spec =
3122               symbol_file->GetObjectFile()->GetFileSpec();
3123           if (format_char == 'S') {
3124             // Dump symbol file only if different from module file
3125             if (!symfile_spec || symfile_spec == module->GetFileSpec()) {
3126               print_space = false;
3127               break;
3128             }
3129             // Add a newline and indent past the index
3130             strm.Printf("\n%*s", indent, "");
3131           }
3132           DumpFullpath(strm, &symfile_spec, width);
3133           dump_object_name = true;
3134           break;
3135         }
3136         strm.Printf("%.*s", width, "<NONE>");
3137       } break;
3138 
3139       case 'm':
3140         strm.Format("{0:%c}", llvm::fmt_align(module->GetModificationTime(),
3141                                               llvm::AlignStyle::Left, width));
3142         break;
3143 
3144       case 'p':
3145         strm.Printf("%p", static_cast<void *>(module));
3146         break;
3147 
3148       case 'u':
3149         DumpModuleUUID(strm, module);
3150         break;
3151 
3152       default:
3153         break;
3154       }
3155     }
3156     if (dump_object_name) {
3157       const char *object_name = module->GetObjectName().GetCString();
3158       if (object_name)
3159         strm.Printf("(%s)", object_name);
3160     }
3161     strm.EOL();
3162   }
3163 
3164   CommandOptions m_options;
3165 };
3166 
3167 #pragma mark CommandObjectTargetModulesShowUnwind
3168 
3169 // Lookup unwind information in images
3170 #define LLDB_OPTIONS_target_modules_show_unwind
3171 #include "CommandOptions.inc"
3172 
3173 class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
3174 public:
3175   enum {
3176     eLookupTypeInvalid = -1,
3177     eLookupTypeAddress = 0,
3178     eLookupTypeSymbol,
3179     eLookupTypeFunction,
3180     eLookupTypeFunctionOrSymbol,
3181     kNumLookupTypes
3182   };
3183 
3184   class CommandOptions : public Options {
3185   public:
3186     CommandOptions() {}
3187 
3188     ~CommandOptions() override = default;
3189 
3190     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3191                           ExecutionContext *execution_context) override {
3192       Status error;
3193 
3194       const int short_option = m_getopt_table[option_idx].val;
3195 
3196       switch (short_option) {
3197       case 'a': {
3198         m_str = std::string(option_arg);
3199         m_type = eLookupTypeAddress;
3200         m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
3201                                             LLDB_INVALID_ADDRESS, &error);
3202         if (m_addr == LLDB_INVALID_ADDRESS)
3203           error.SetErrorStringWithFormat("invalid address string '%s'",
3204                                          option_arg.str().c_str());
3205         break;
3206       }
3207 
3208       case 'n':
3209         m_str = std::string(option_arg);
3210         m_type = eLookupTypeFunctionOrSymbol;
3211         break;
3212 
3213       default:
3214         llvm_unreachable("Unimplemented option");
3215       }
3216 
3217       return error;
3218     }
3219 
3220     void OptionParsingStarting(ExecutionContext *execution_context) override {
3221       m_type = eLookupTypeInvalid;
3222       m_str.clear();
3223       m_addr = LLDB_INVALID_ADDRESS;
3224     }
3225 
3226     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3227       return llvm::makeArrayRef(g_target_modules_show_unwind_options);
3228     }
3229 
3230     // Instance variables to hold the values for command options.
3231 
3232     int m_type = eLookupTypeInvalid; // Should be a eLookupTypeXXX enum after
3233                                      // parsing options
3234     std::string m_str; // Holds name lookup
3235     lldb::addr_t m_addr = LLDB_INVALID_ADDRESS; // Holds the address to lookup
3236   };
3237 
3238   CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter)
3239       : CommandObjectParsed(
3240             interpreter, "target modules show-unwind",
3241             "Show synthesized unwind instructions for a function.", nullptr,
3242             eCommandRequiresTarget | eCommandRequiresProcess |
3243                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
3244 
3245   ~CommandObjectTargetModulesShowUnwind() override = default;
3246 
3247   Options *GetOptions() override { return &m_options; }
3248 
3249 protected:
3250   bool DoExecute(Args &command, CommandReturnObject &result) override {
3251     Target *target = m_exe_ctx.GetTargetPtr();
3252     Process *process = m_exe_ctx.GetProcessPtr();
3253     ABI *abi = nullptr;
3254     if (process)
3255       abi = process->GetABI().get();
3256 
3257     if (process == nullptr) {
3258       result.AppendError(
3259           "You must have a process running to use this command.");
3260       return false;
3261     }
3262 
3263     ThreadList threads(process->GetThreadList());
3264     if (threads.GetSize() == 0) {
3265       result.AppendError("The process must be paused to use this command.");
3266       return false;
3267     }
3268 
3269     ThreadSP thread(threads.GetThreadAtIndex(0));
3270     if (!thread) {
3271       result.AppendError("The process must be paused to use this command.");
3272       return false;
3273     }
3274 
3275     SymbolContextList sc_list;
3276 
3277     if (m_options.m_type == eLookupTypeFunctionOrSymbol) {
3278       ConstString function_name(m_options.m_str.c_str());
3279       ModuleFunctionSearchOptions function_options;
3280       function_options.include_symbols = true;
3281       function_options.include_inlines = false;
3282       target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,
3283                                         function_options, sc_list);
3284     } else if (m_options.m_type == eLookupTypeAddress && target) {
3285       Address addr;
3286       if (target->GetSectionLoadList().ResolveLoadAddress(m_options.m_addr,
3287                                                           addr)) {
3288         SymbolContext sc;
3289         ModuleSP module_sp(addr.GetModule());
3290         module_sp->ResolveSymbolContextForAddress(addr,
3291                                                   eSymbolContextEverything, sc);
3292         if (sc.function || sc.symbol) {
3293           sc_list.Append(sc);
3294         }
3295       }
3296     } else {
3297       result.AppendError(
3298           "address-expression or function name option must be specified.");
3299       return false;
3300     }
3301 
3302     size_t num_matches = sc_list.GetSize();
3303     if (num_matches == 0) {
3304       result.AppendErrorWithFormat("no unwind data found that matches '%s'.",
3305                                    m_options.m_str.c_str());
3306       return false;
3307     }
3308 
3309     for (uint32_t idx = 0; idx < num_matches; idx++) {
3310       SymbolContext sc;
3311       sc_list.GetContextAtIndex(idx, sc);
3312       if (sc.symbol == nullptr && sc.function == nullptr)
3313         continue;
3314       if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
3315         continue;
3316       AddressRange range;
3317       if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
3318                               false, range))
3319         continue;
3320       if (!range.GetBaseAddress().IsValid())
3321         continue;
3322       ConstString funcname(sc.GetFunctionName());
3323       if (funcname.IsEmpty())
3324         continue;
3325       addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
3326       if (abi)
3327         start_addr = abi->FixCodeAddress(start_addr);
3328 
3329       FuncUnwindersSP func_unwinders_sp(
3330           sc.module_sp->GetUnwindTable()
3331               .GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
3332       if (!func_unwinders_sp)
3333         continue;
3334 
3335       result.GetOutputStream().Printf(
3336           "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n",
3337           sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(),
3338           funcname.AsCString(), start_addr);
3339 
3340       Args args;
3341       target->GetUserSpecifiedTrapHandlerNames(args);
3342       size_t count = args.GetArgumentCount();
3343       for (size_t i = 0; i < count; i++) {
3344         const char *trap_func_name = args.GetArgumentAtIndex(i);
3345         if (strcmp(funcname.GetCString(), trap_func_name) == 0)
3346           result.GetOutputStream().Printf(
3347               "This function is "
3348               "treated as a trap handler function via user setting.\n");
3349       }
3350       PlatformSP platform_sp(target->GetPlatform());
3351       if (platform_sp) {
3352         const std::vector<ConstString> trap_handler_names(
3353             platform_sp->GetTrapHandlerSymbolNames());
3354         for (ConstString trap_name : trap_handler_names) {
3355           if (trap_name == funcname) {
3356             result.GetOutputStream().Printf(
3357                 "This function's "
3358                 "name is listed by the platform as a trap handler.\n");
3359           }
3360         }
3361       }
3362 
3363       result.GetOutputStream().Printf("\n");
3364 
3365       UnwindPlanSP non_callsite_unwind_plan =
3366           func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread);
3367       if (non_callsite_unwind_plan) {
3368         result.GetOutputStream().Printf(
3369             "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
3370             non_callsite_unwind_plan->GetSourceName().AsCString());
3371       }
3372       UnwindPlanSP callsite_unwind_plan =
3373           func_unwinders_sp->GetUnwindPlanAtCallSite(*target, *thread);
3374       if (callsite_unwind_plan) {
3375         result.GetOutputStream().Printf(
3376             "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
3377             callsite_unwind_plan->GetSourceName().AsCString());
3378       }
3379       UnwindPlanSP fast_unwind_plan =
3380           func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
3381       if (fast_unwind_plan) {
3382         result.GetOutputStream().Printf(
3383             "Fast UnwindPlan is '%s'\n",
3384             fast_unwind_plan->GetSourceName().AsCString());
3385       }
3386 
3387       result.GetOutputStream().Printf("\n");
3388 
3389       UnwindPlanSP assembly_sp =
3390           func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread);
3391       if (assembly_sp) {
3392         result.GetOutputStream().Printf(
3393             "Assembly language inspection UnwindPlan:\n");
3394         assembly_sp->Dump(result.GetOutputStream(), thread.get(),
3395                           LLDB_INVALID_ADDRESS);
3396         result.GetOutputStream().Printf("\n");
3397       }
3398 
3399       UnwindPlanSP of_unwind_sp =
3400           func_unwinders_sp->GetObjectFileUnwindPlan(*target);
3401       if (of_unwind_sp) {
3402         result.GetOutputStream().Printf("object file UnwindPlan:\n");
3403         of_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3404                            LLDB_INVALID_ADDRESS);
3405         result.GetOutputStream().Printf("\n");
3406       }
3407 
3408       UnwindPlanSP of_unwind_augmented_sp =
3409           func_unwinders_sp->GetObjectFileAugmentedUnwindPlan(*target, *thread);
3410       if (of_unwind_augmented_sp) {
3411         result.GetOutputStream().Printf("object file augmented UnwindPlan:\n");
3412         of_unwind_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
3413                                      LLDB_INVALID_ADDRESS);
3414         result.GetOutputStream().Printf("\n");
3415       }
3416 
3417       UnwindPlanSP ehframe_sp =
3418           func_unwinders_sp->GetEHFrameUnwindPlan(*target);
3419       if (ehframe_sp) {
3420         result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3421         ehframe_sp->Dump(result.GetOutputStream(), thread.get(),
3422                          LLDB_INVALID_ADDRESS);
3423         result.GetOutputStream().Printf("\n");
3424       }
3425 
3426       UnwindPlanSP ehframe_augmented_sp =
3427           func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread);
3428       if (ehframe_augmented_sp) {
3429         result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3430         ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
3431                                    LLDB_INVALID_ADDRESS);
3432         result.GetOutputStream().Printf("\n");
3433       }
3434 
3435       if (UnwindPlanSP plan_sp =
3436               func_unwinders_sp->GetDebugFrameUnwindPlan(*target)) {
3437         result.GetOutputStream().Printf("debug_frame UnwindPlan:\n");
3438         plan_sp->Dump(result.GetOutputStream(), thread.get(),
3439                       LLDB_INVALID_ADDRESS);
3440         result.GetOutputStream().Printf("\n");
3441       }
3442 
3443       if (UnwindPlanSP plan_sp =
3444               func_unwinders_sp->GetDebugFrameAugmentedUnwindPlan(*target,
3445                                                                   *thread)) {
3446         result.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n");
3447         plan_sp->Dump(result.GetOutputStream(), thread.get(),
3448                       LLDB_INVALID_ADDRESS);
3449         result.GetOutputStream().Printf("\n");
3450       }
3451 
3452       UnwindPlanSP arm_unwind_sp =
3453           func_unwinders_sp->GetArmUnwindUnwindPlan(*target);
3454       if (arm_unwind_sp) {
3455         result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
3456         arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3457                             LLDB_INVALID_ADDRESS);
3458         result.GetOutputStream().Printf("\n");
3459       }
3460 
3461       if (UnwindPlanSP symfile_plan_sp =
3462               func_unwinders_sp->GetSymbolFileUnwindPlan(*thread)) {
3463         result.GetOutputStream().Printf("Symbol file UnwindPlan:\n");
3464         symfile_plan_sp->Dump(result.GetOutputStream(), thread.get(),
3465                               LLDB_INVALID_ADDRESS);
3466         result.GetOutputStream().Printf("\n");
3467       }
3468 
3469       UnwindPlanSP compact_unwind_sp =
3470           func_unwinders_sp->GetCompactUnwindUnwindPlan(*target);
3471       if (compact_unwind_sp) {
3472         result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3473         compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3474                                 LLDB_INVALID_ADDRESS);
3475         result.GetOutputStream().Printf("\n");
3476       }
3477 
3478       if (fast_unwind_plan) {
3479         result.GetOutputStream().Printf("Fast UnwindPlan:\n");
3480         fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(),
3481                                LLDB_INVALID_ADDRESS);
3482         result.GetOutputStream().Printf("\n");
3483       }
3484 
3485       ABISP abi_sp = process->GetABI();
3486       if (abi_sp) {
3487         UnwindPlan arch_default(lldb::eRegisterKindGeneric);
3488         if (abi_sp->CreateDefaultUnwindPlan(arch_default)) {
3489           result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3490           arch_default.Dump(result.GetOutputStream(), thread.get(),
3491                             LLDB_INVALID_ADDRESS);
3492           result.GetOutputStream().Printf("\n");
3493         }
3494 
3495         UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
3496         if (abi_sp->CreateFunctionEntryUnwindPlan(arch_entry)) {
3497           result.GetOutputStream().Printf(
3498               "Arch default at entry point UnwindPlan:\n");
3499           arch_entry.Dump(result.GetOutputStream(), thread.get(),
3500                           LLDB_INVALID_ADDRESS);
3501           result.GetOutputStream().Printf("\n");
3502         }
3503       }
3504 
3505       result.GetOutputStream().Printf("\n");
3506     }
3507     return result.Succeeded();
3508   }
3509 
3510   CommandOptions m_options;
3511 };
3512 
3513 // Lookup information in images
3514 #define LLDB_OPTIONS_target_modules_lookup
3515 #include "CommandOptions.inc"
3516 
3517 class CommandObjectTargetModulesLookup : public CommandObjectParsed {
3518 public:
3519   enum {
3520     eLookupTypeInvalid = -1,
3521     eLookupTypeAddress = 0,
3522     eLookupTypeSymbol,
3523     eLookupTypeFileLine, // Line is optional
3524     eLookupTypeFunction,
3525     eLookupTypeFunctionOrSymbol,
3526     eLookupTypeType,
3527     kNumLookupTypes
3528   };
3529 
3530   class CommandOptions : public Options {
3531   public:
3532     CommandOptions() { OptionParsingStarting(nullptr); }
3533 
3534     ~CommandOptions() override = default;
3535 
3536     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3537                           ExecutionContext *execution_context) override {
3538       Status error;
3539 
3540       const int short_option = m_getopt_table[option_idx].val;
3541 
3542       switch (short_option) {
3543       case 'a': {
3544         m_type = eLookupTypeAddress;
3545         m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
3546                                             LLDB_INVALID_ADDRESS, &error);
3547       } break;
3548 
3549       case 'o':
3550         if (option_arg.getAsInteger(0, m_offset))
3551           error.SetErrorStringWithFormat("invalid offset string '%s'",
3552                                          option_arg.str().c_str());
3553         break;
3554 
3555       case 's':
3556         m_str = std::string(option_arg);
3557         m_type = eLookupTypeSymbol;
3558         break;
3559 
3560       case 'f':
3561         m_file.SetFile(option_arg, FileSpec::Style::native);
3562         m_type = eLookupTypeFileLine;
3563         break;
3564 
3565       case 'i':
3566         m_include_inlines = false;
3567         break;
3568 
3569       case 'l':
3570         if (option_arg.getAsInteger(0, m_line_number))
3571           error.SetErrorStringWithFormat("invalid line number string '%s'",
3572                                          option_arg.str().c_str());
3573         else if (m_line_number == 0)
3574           error.SetErrorString("zero is an invalid line number");
3575         m_type = eLookupTypeFileLine;
3576         break;
3577 
3578       case 'F':
3579         m_str = std::string(option_arg);
3580         m_type = eLookupTypeFunction;
3581         break;
3582 
3583       case 'n':
3584         m_str = std::string(option_arg);
3585         m_type = eLookupTypeFunctionOrSymbol;
3586         break;
3587 
3588       case 't':
3589         m_str = std::string(option_arg);
3590         m_type = eLookupTypeType;
3591         break;
3592 
3593       case 'v':
3594         m_verbose = true;
3595         break;
3596 
3597       case 'A':
3598         m_print_all = true;
3599         break;
3600 
3601       case 'r':
3602         m_use_regex = true;
3603         break;
3604 
3605       case '\x01':
3606         m_all_ranges = true;
3607         break;
3608       default:
3609         llvm_unreachable("Unimplemented option");
3610       }
3611 
3612       return error;
3613     }
3614 
3615     void OptionParsingStarting(ExecutionContext *execution_context) override {
3616       m_type = eLookupTypeInvalid;
3617       m_str.clear();
3618       m_file.Clear();
3619       m_addr = LLDB_INVALID_ADDRESS;
3620       m_offset = 0;
3621       m_line_number = 0;
3622       m_use_regex = false;
3623       m_include_inlines = true;
3624       m_all_ranges = false;
3625       m_verbose = false;
3626       m_print_all = false;
3627     }
3628 
3629     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3630       return llvm::makeArrayRef(g_target_modules_lookup_options);
3631     }
3632 
3633     int m_type;        // Should be a eLookupTypeXXX enum after parsing options
3634     std::string m_str; // Holds name lookup
3635     FileSpec m_file;   // Files for file lookups
3636     lldb::addr_t m_addr; // Holds the address to lookup
3637     lldb::addr_t
3638         m_offset; // Subtract this offset from m_addr before doing lookups.
3639     uint32_t m_line_number; // Line number for file+line lookups
3640     bool m_use_regex;       // Name lookups in m_str are regular expressions.
3641     bool m_include_inlines; // Check for inline entries when looking up by
3642                             // file/line.
3643     bool m_all_ranges;      // Print all ranges or single range.
3644     bool m_verbose;         // Enable verbose lookup info
3645     bool m_print_all; // Print all matches, even in cases where there's a best
3646                       // match.
3647   };
3648 
3649   CommandObjectTargetModulesLookup(CommandInterpreter &interpreter)
3650       : CommandObjectParsed(interpreter, "target modules lookup",
3651                             "Look up information within executable and "
3652                             "dependent shared library images.",
3653                             nullptr, eCommandRequiresTarget) {
3654     CommandArgumentEntry arg;
3655     CommandArgumentData file_arg;
3656 
3657     // Define the first (and only) variant of this arg.
3658     file_arg.arg_type = eArgTypeFilename;
3659     file_arg.arg_repetition = eArgRepeatStar;
3660 
3661     // There is only one variant this argument could be; put it into the
3662     // argument entry.
3663     arg.push_back(file_arg);
3664 
3665     // Push the data for the first argument into the m_arguments vector.
3666     m_arguments.push_back(arg);
3667   }
3668 
3669   ~CommandObjectTargetModulesLookup() override = default;
3670 
3671   Options *GetOptions() override { return &m_options; }
3672 
3673   bool LookupHere(CommandInterpreter &interpreter, CommandReturnObject &result,
3674                   bool &syntax_error) {
3675     switch (m_options.m_type) {
3676     case eLookupTypeAddress:
3677     case eLookupTypeFileLine:
3678     case eLookupTypeFunction:
3679     case eLookupTypeFunctionOrSymbol:
3680     case eLookupTypeSymbol:
3681     default:
3682       return false;
3683     case eLookupTypeType:
3684       break;
3685     }
3686 
3687     StackFrameSP frame = m_exe_ctx.GetFrameSP();
3688 
3689     if (!frame)
3690       return false;
3691 
3692     const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
3693 
3694     if (!sym_ctx.module_sp)
3695       return false;
3696 
3697     switch (m_options.m_type) {
3698     default:
3699       return false;
3700     case eLookupTypeType:
3701       if (!m_options.m_str.empty()) {
3702         if (LookupTypeHere(&GetSelectedTarget(), m_interpreter,
3703                            result.GetOutputStream(), *sym_ctx.module_sp,
3704                            m_options.m_str.c_str(), m_options.m_use_regex)) {
3705           result.SetStatus(eReturnStatusSuccessFinishResult);
3706           return true;
3707         }
3708       }
3709       break;
3710     }
3711 
3712     return false;
3713   }
3714 
3715   bool LookupInModule(CommandInterpreter &interpreter, Module *module,
3716                       CommandReturnObject &result, bool &syntax_error) {
3717     switch (m_options.m_type) {
3718     case eLookupTypeAddress:
3719       if (m_options.m_addr != LLDB_INVALID_ADDRESS) {
3720         if (LookupAddressInModule(
3721                 m_interpreter, result.GetOutputStream(), module,
3722                 eSymbolContextEverything |
3723                     (m_options.m_verbose
3724                          ? static_cast<int>(eSymbolContextVariable)
3725                          : 0),
3726                 m_options.m_addr, m_options.m_offset, m_options.m_verbose,
3727                 m_options.m_all_ranges)) {
3728           result.SetStatus(eReturnStatusSuccessFinishResult);
3729           return true;
3730         }
3731       }
3732       break;
3733 
3734     case eLookupTypeSymbol:
3735       if (!m_options.m_str.empty()) {
3736         if (LookupSymbolInModule(m_interpreter, result.GetOutputStream(),
3737                                  module, m_options.m_str.c_str(),
3738                                  m_options.m_use_regex, m_options.m_verbose,
3739                                  m_options.m_all_ranges)) {
3740           result.SetStatus(eReturnStatusSuccessFinishResult);
3741           return true;
3742         }
3743       }
3744       break;
3745 
3746     case eLookupTypeFileLine:
3747       if (m_options.m_file) {
3748         if (LookupFileAndLineInModule(
3749                 m_interpreter, result.GetOutputStream(), module,
3750                 m_options.m_file, m_options.m_line_number,
3751                 m_options.m_include_inlines, m_options.m_verbose,
3752                 m_options.m_all_ranges)) {
3753           result.SetStatus(eReturnStatusSuccessFinishResult);
3754           return true;
3755         }
3756       }
3757       break;
3758 
3759     case eLookupTypeFunctionOrSymbol:
3760     case eLookupTypeFunction:
3761       if (!m_options.m_str.empty()) {
3762         ModuleFunctionSearchOptions function_options;
3763         function_options.include_symbols =
3764             m_options.m_type == eLookupTypeFunctionOrSymbol;
3765         function_options.include_inlines = m_options.m_include_inlines;
3766 
3767         if (LookupFunctionInModule(m_interpreter, result.GetOutputStream(),
3768                                    module, m_options.m_str.c_str(),
3769                                    m_options.m_use_regex, function_options,
3770                                    m_options.m_verbose,
3771                                    m_options.m_all_ranges)) {
3772           result.SetStatus(eReturnStatusSuccessFinishResult);
3773           return true;
3774         }
3775       }
3776       break;
3777 
3778     case eLookupTypeType:
3779       if (!m_options.m_str.empty()) {
3780         if (LookupTypeInModule(
3781                 &GetSelectedTarget(), m_interpreter, result.GetOutputStream(),
3782                 module, m_options.m_str.c_str(), m_options.m_use_regex)) {
3783           result.SetStatus(eReturnStatusSuccessFinishResult);
3784           return true;
3785         }
3786       }
3787       break;
3788 
3789     default:
3790       m_options.GenerateOptionUsage(
3791           result.GetErrorStream(), this,
3792           GetCommandInterpreter().GetDebugger().GetTerminalWidth());
3793       syntax_error = true;
3794       break;
3795     }
3796 
3797     result.SetStatus(eReturnStatusFailed);
3798     return false;
3799   }
3800 
3801 protected:
3802   bool DoExecute(Args &command, CommandReturnObject &result) override {
3803     Target *target = &GetSelectedTarget();
3804     bool syntax_error = false;
3805     uint32_t i;
3806     uint32_t num_successful_lookups = 0;
3807     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3808     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3809     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3810     // Dump all sections for all modules images
3811 
3812     if (command.GetArgumentCount() == 0) {
3813       ModuleSP current_module;
3814 
3815       // Where it is possible to look in the current symbol context first,
3816       // try that.  If this search was successful and --all was not passed,
3817       // don't print anything else.
3818       if (LookupHere(m_interpreter, result, syntax_error)) {
3819         result.GetOutputStream().EOL();
3820         num_successful_lookups++;
3821         if (!m_options.m_print_all) {
3822           result.SetStatus(eReturnStatusSuccessFinishResult);
3823           return result.Succeeded();
3824         }
3825       }
3826 
3827       // Dump all sections for all other modules
3828 
3829       const ModuleList &target_modules = target->GetImages();
3830       std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
3831       if (target_modules.GetSize() == 0) {
3832         result.AppendError("the target has no associated executable images");
3833         return false;
3834       }
3835 
3836       for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
3837         if (module_sp != current_module &&
3838             LookupInModule(m_interpreter, module_sp.get(), result,
3839                            syntax_error)) {
3840           result.GetOutputStream().EOL();
3841           num_successful_lookups++;
3842         }
3843       }
3844     } else {
3845       // Dump specified images (by basename or fullpath)
3846       const char *arg_cstr;
3847       for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
3848                   !syntax_error;
3849            ++i) {
3850         ModuleList module_list;
3851         const size_t num_matches =
3852             FindModulesByName(target, arg_cstr, module_list, false);
3853         if (num_matches > 0) {
3854           for (size_t j = 0; j < num_matches; ++j) {
3855             Module *module = module_list.GetModulePointerAtIndex(j);
3856             if (module) {
3857               if (LookupInModule(m_interpreter, module, result, syntax_error)) {
3858                 result.GetOutputStream().EOL();
3859                 num_successful_lookups++;
3860               }
3861             }
3862           }
3863         } else
3864           result.AppendWarningWithFormat(
3865               "Unable to find an image that matches '%s'.\n", arg_cstr);
3866       }
3867     }
3868 
3869     if (num_successful_lookups > 0)
3870       result.SetStatus(eReturnStatusSuccessFinishResult);
3871     else
3872       result.SetStatus(eReturnStatusFailed);
3873     return result.Succeeded();
3874   }
3875 
3876   CommandOptions m_options;
3877 };
3878 
3879 #pragma mark CommandObjectMultiwordImageSearchPaths
3880 
3881 // CommandObjectMultiwordImageSearchPaths
3882 
3883 class CommandObjectTargetModulesImageSearchPaths
3884     : public CommandObjectMultiword {
3885 public:
3886   CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
3887       : CommandObjectMultiword(
3888             interpreter, "target modules search-paths",
3889             "Commands for managing module search paths for a target.",
3890             "target modules search-paths <subcommand> [<subcommand-options>]") {
3891     LoadSubCommand(
3892         "add", CommandObjectSP(
3893                    new CommandObjectTargetModulesSearchPathsAdd(interpreter)));
3894     LoadSubCommand(
3895         "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear(
3896                      interpreter)));
3897     LoadSubCommand(
3898         "insert",
3899         CommandObjectSP(
3900             new CommandObjectTargetModulesSearchPathsInsert(interpreter)));
3901     LoadSubCommand(
3902         "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList(
3903                     interpreter)));
3904     LoadSubCommand(
3905         "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery(
3906                      interpreter)));
3907   }
3908 
3909   ~CommandObjectTargetModulesImageSearchPaths() override = default;
3910 };
3911 
3912 #pragma mark CommandObjectTargetModules
3913 
3914 // CommandObjectTargetModules
3915 
3916 class CommandObjectTargetModules : public CommandObjectMultiword {
3917 public:
3918   // Constructors and Destructors
3919   CommandObjectTargetModules(CommandInterpreter &interpreter)
3920       : CommandObjectMultiword(interpreter, "target modules",
3921                                "Commands for accessing information for one or "
3922                                "more target modules.",
3923                                "target modules <sub-command> ...") {
3924     LoadSubCommand(
3925         "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter)));
3926     LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad(
3927                                interpreter)));
3928     LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump(
3929                                interpreter)));
3930     LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList(
3931                                interpreter)));
3932     LoadSubCommand(
3933         "lookup",
3934         CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter)));
3935     LoadSubCommand(
3936         "search-paths",
3937         CommandObjectSP(
3938             new CommandObjectTargetModulesImageSearchPaths(interpreter)));
3939     LoadSubCommand(
3940         "show-unwind",
3941         CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter)));
3942   }
3943 
3944   ~CommandObjectTargetModules() override = default;
3945 
3946 private:
3947   // For CommandObjectTargetModules only
3948   CommandObjectTargetModules(const CommandObjectTargetModules &) = delete;
3949   const CommandObjectTargetModules &
3950   operator=(const CommandObjectTargetModules &) = delete;
3951 };
3952 
3953 class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
3954 public:
3955   CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter)
3956       : CommandObjectParsed(
3957             interpreter, "target symbols add",
3958             "Add a debug symbol file to one of the target's current modules by "
3959             "specifying a path to a debug symbols file or by using the options "
3960             "to specify a module.",
3961             "target symbols add <cmd-options> [<symfile>]",
3962             eCommandRequiresTarget),
3963         m_file_option(
3964             LLDB_OPT_SET_1, false, "shlib", 's',
3965             CommandCompletions::eModuleCompletion, eArgTypeShlibName,
3966             "Locate the debug symbols for the shared library specified by "
3967             "name."),
3968         m_current_frame_option(
3969             LLDB_OPT_SET_2, false, "frame", 'F',
3970             "Locate the debug symbols for the currently selected frame.", false,
3971             true),
3972         m_current_stack_option(LLDB_OPT_SET_2, false, "stack", 'S',
3973                                "Locate the debug symbols for every frame in "
3974                                "the current call stack.",
3975                                false, true)
3976 
3977   {
3978     m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
3979                           LLDB_OPT_SET_1);
3980     m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
3981     m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2,
3982                           LLDB_OPT_SET_2);
3983     m_option_group.Append(&m_current_stack_option, LLDB_OPT_SET_2,
3984                           LLDB_OPT_SET_2);
3985     m_option_group.Finalize();
3986   }
3987 
3988   ~CommandObjectTargetSymbolsAdd() override = default;
3989 
3990   void
3991   HandleArgumentCompletion(CompletionRequest &request,
3992                            OptionElementVector &opt_element_vector) override {
3993     CommandCompletions::InvokeCommonCompletionCallbacks(
3994         GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
3995         request, nullptr);
3996   }
3997 
3998   Options *GetOptions() override { return &m_option_group; }
3999 
4000 protected:
4001   bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,
4002                         CommandReturnObject &result) {
4003     const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
4004     if (!symbol_fspec) {
4005       result.AppendError(
4006           "one or more executable image paths must be specified");
4007       return false;
4008     }
4009 
4010     char symfile_path[PATH_MAX];
4011     symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));
4012 
4013     if (!module_spec.GetUUID().IsValid()) {
4014       if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
4015         module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
4016     }
4017 
4018     // Now module_spec represents a symbol file for a module that might exist
4019     // in the current target.  Let's find possible matches.
4020     ModuleList matching_modules;
4021 
4022     // First extract all module specs from the symbol file
4023     lldb_private::ModuleSpecList symfile_module_specs;
4024     if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(),
4025                                             0, 0, symfile_module_specs)) {
4026       // Now extract the module spec that matches the target architecture
4027       ModuleSpec target_arch_module_spec;
4028       ModuleSpec symfile_module_spec;
4029       target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
4030       if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,
4031                                                       symfile_module_spec)) {
4032         if (symfile_module_spec.GetUUID().IsValid()) {
4033           // It has a UUID, look for this UUID in the target modules
4034           ModuleSpec symfile_uuid_module_spec;
4035           symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4036           target->GetImages().FindModules(symfile_uuid_module_spec,
4037                                           matching_modules);
4038         }
4039       }
4040 
4041       if (matching_modules.IsEmpty()) {
4042         // No matches yet.  Iterate through the module specs to find a UUID
4043         // value that we can match up to an image in our target.
4044         const size_t num_symfile_module_specs = symfile_module_specs.GetSize();
4045         for (size_t i = 0;
4046              i < num_symfile_module_specs && matching_modules.IsEmpty(); ++i) {
4047           if (symfile_module_specs.GetModuleSpecAtIndex(
4048                   i, symfile_module_spec)) {
4049             if (symfile_module_spec.GetUUID().IsValid()) {
4050               // It has a UUID.  Look for this UUID in the target modules.
4051               ModuleSpec symfile_uuid_module_spec;
4052               symfile_uuid_module_spec.GetUUID() =
4053                   symfile_module_spec.GetUUID();
4054               target->GetImages().FindModules(symfile_uuid_module_spec,
4055                                               matching_modules);
4056             }
4057           }
4058         }
4059       }
4060     }
4061 
4062     // Just try to match up the file by basename if we have no matches at
4063     // this point.  For example, module foo might have symbols in foo.debug.
4064     if (matching_modules.IsEmpty())
4065       target->GetImages().FindModules(module_spec, matching_modules);
4066 
4067     while (matching_modules.IsEmpty()) {
4068       ConstString filename_no_extension(
4069           module_spec.GetFileSpec().GetFileNameStrippingExtension());
4070       // Empty string returned, let's bail
4071       if (!filename_no_extension)
4072         break;
4073 
4074       // Check if there was no extension to strip and the basename is the same
4075       if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
4076         break;
4077 
4078       // Replace basename with one fewer extension
4079       module_spec.GetFileSpec().GetFilename() = filename_no_extension;
4080       target->GetImages().FindModules(module_spec, matching_modules);
4081     }
4082 
4083     if (matching_modules.GetSize() > 1) {
4084       result.AppendErrorWithFormat("multiple modules match symbol file '%s', "
4085                                    "use the --uuid option to resolve the "
4086                                    "ambiguity.\n",
4087                                    symfile_path);
4088       return false;
4089     }
4090 
4091     if (matching_modules.GetSize() == 1) {
4092       ModuleSP module_sp(matching_modules.GetModuleAtIndex(0));
4093 
4094       // The module has not yet created its symbol vendor, we can just give
4095       // the existing target module the symfile path to use for when it
4096       // decides to create it!
4097       module_sp->SetSymbolFileFileSpec(symbol_fspec);
4098 
4099       SymbolFile *symbol_file =
4100           module_sp->GetSymbolFile(true, &result.GetErrorStream());
4101       if (symbol_file) {
4102         ObjectFile *object_file = symbol_file->GetObjectFile();
4103         if (object_file && object_file->GetFileSpec() == symbol_fspec) {
4104           // Provide feedback that the symfile has been successfully added.
4105           const FileSpec &module_fs = module_sp->GetFileSpec();
4106           result.AppendMessageWithFormat(
4107               "symbol file '%s' has been added to '%s'\n", symfile_path,
4108               module_fs.GetPath().c_str());
4109 
4110           // Let clients know something changed in the module if it is
4111           // currently loaded
4112           ModuleList module_list;
4113           module_list.Append(module_sp);
4114           target->SymbolsDidLoad(module_list);
4115 
4116           // Make sure we load any scripting resources that may be embedded
4117           // in the debug info files in case the platform supports that.
4118           Status error;
4119           StreamString feedback_stream;
4120           module_sp->LoadScriptingResourceInTarget(target, error,
4121                                                    &feedback_stream);
4122           if (error.Fail() && error.AsCString())
4123             result.AppendWarningWithFormat(
4124                 "unable to load scripting data for module %s - error "
4125                 "reported was %s",
4126                 module_sp->GetFileSpec()
4127                     .GetFileNameStrippingExtension()
4128                     .GetCString(),
4129                 error.AsCString());
4130           else if (feedback_stream.GetSize())
4131             result.AppendWarning(feedback_stream.GetData());
4132 
4133           flush = true;
4134           result.SetStatus(eReturnStatusSuccessFinishResult);
4135           return true;
4136         }
4137       }
4138       // Clear the symbol file spec if anything went wrong
4139       module_sp->SetSymbolFileFileSpec(FileSpec());
4140     }
4141 
4142     StreamString ss_symfile_uuid;
4143     if (module_spec.GetUUID().IsValid()) {
4144       ss_symfile_uuid << " (";
4145       module_spec.GetUUID().Dump(&ss_symfile_uuid);
4146       ss_symfile_uuid << ')';
4147     }
4148     result.AppendErrorWithFormat(
4149         "symbol file '%s'%s does not match any existing module%s\n",
4150         symfile_path, ss_symfile_uuid.GetData(),
4151         !llvm::sys::fs::is_regular_file(symbol_fspec.GetPath())
4152             ? "\n       please specify the full path to the symbol file"
4153             : "");
4154     return false;
4155   }
4156 
4157   bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
4158                                    CommandReturnObject &result, bool &flush) {
4159     if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
4160       if (module_spec.GetSymbolFileSpec())
4161         return AddModuleSymbols(m_exe_ctx.GetTargetPtr(), module_spec, flush,
4162                                 result);
4163     }
4164     return false;
4165   }
4166 
4167   bool AddSymbolsForUUID(CommandReturnObject &result, bool &flush) {
4168     assert(m_uuid_option_group.GetOptionValue().OptionWasSet());
4169 
4170     ModuleSpec module_spec;
4171     module_spec.GetUUID() =
4172         m_uuid_option_group.GetOptionValue().GetCurrentValue();
4173 
4174     if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4175       StreamString error_strm;
4176       error_strm.PutCString("unable to find debug symbols for UUID ");
4177       module_spec.GetUUID().Dump(&error_strm);
4178       result.AppendError(error_strm.GetString());
4179       return false;
4180     }
4181 
4182     return true;
4183   }
4184 
4185   bool AddSymbolsForFile(CommandReturnObject &result, bool &flush) {
4186     assert(m_file_option.GetOptionValue().OptionWasSet());
4187 
4188     ModuleSpec module_spec;
4189     module_spec.GetFileSpec() =
4190         m_file_option.GetOptionValue().GetCurrentValue();
4191 
4192     Target *target = m_exe_ctx.GetTargetPtr();
4193     ModuleSP module_sp(target->GetImages().FindFirstModule(module_spec));
4194     if (module_sp) {
4195       module_spec.GetFileSpec() = module_sp->GetFileSpec();
4196       module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();
4197       module_spec.GetUUID() = module_sp->GetUUID();
4198       module_spec.GetArchitecture() = module_sp->GetArchitecture();
4199     } else {
4200       module_spec.GetArchitecture() = target->GetArchitecture();
4201     }
4202 
4203     if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4204       StreamString error_strm;
4205       error_strm.PutCString(
4206           "unable to find debug symbols for the executable file ");
4207       error_strm << module_spec.GetFileSpec();
4208       result.AppendError(error_strm.GetString());
4209       return false;
4210     }
4211 
4212     return true;
4213   }
4214 
4215   bool AddSymbolsForFrame(CommandReturnObject &result, bool &flush) {
4216     assert(m_current_frame_option.GetOptionValue().OptionWasSet());
4217 
4218     Process *process = m_exe_ctx.GetProcessPtr();
4219     if (!process) {
4220       result.AppendError(
4221           "a process must exist in order to use the --frame option");
4222       return false;
4223     }
4224 
4225     const StateType process_state = process->GetState();
4226     if (!StateIsStoppedState(process_state, true)) {
4227       result.AppendErrorWithFormat("process is not stopped: %s",
4228                                    StateAsCString(process_state));
4229       return false;
4230     }
4231 
4232     StackFrame *frame = m_exe_ctx.GetFramePtr();
4233     if (!frame) {
4234       result.AppendError("invalid current frame");
4235       return false;
4236     }
4237 
4238     ModuleSP frame_module_sp(
4239         frame->GetSymbolContext(eSymbolContextModule).module_sp);
4240     if (!frame_module_sp) {
4241       result.AppendError("frame has no module");
4242       return false;
4243     }
4244 
4245     ModuleSpec module_spec;
4246     module_spec.GetUUID() = frame_module_sp->GetUUID();
4247 
4248     if (FileSystem::Instance().Exists(frame_module_sp->GetPlatformFileSpec())) {
4249       module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
4250       module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
4251     }
4252 
4253     if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4254       result.AppendError("unable to find debug symbols for the current frame");
4255       return false;
4256     }
4257 
4258     return true;
4259   }
4260 
4261   bool AddSymbolsForStack(CommandReturnObject &result, bool &flush) {
4262     assert(m_current_stack_option.GetOptionValue().OptionWasSet());
4263 
4264     Process *process = m_exe_ctx.GetProcessPtr();
4265     if (!process) {
4266       result.AppendError(
4267           "a process must exist in order to use the --stack option");
4268       return false;
4269     }
4270 
4271     const StateType process_state = process->GetState();
4272     if (!StateIsStoppedState(process_state, true)) {
4273       result.AppendErrorWithFormat("process is not stopped: %s",
4274                                    StateAsCString(process_state));
4275       return false;
4276     }
4277 
4278     Thread *thread = m_exe_ctx.GetThreadPtr();
4279     if (!thread) {
4280       result.AppendError("invalid current thread");
4281       return false;
4282     }
4283 
4284     bool symbols_found = false;
4285     uint32_t frame_count = thread->GetStackFrameCount();
4286     for (uint32_t i = 0; i < frame_count; ++i) {
4287       lldb::StackFrameSP frame_sp = thread->GetStackFrameAtIndex(i);
4288 
4289       ModuleSP frame_module_sp(
4290           frame_sp->GetSymbolContext(eSymbolContextModule).module_sp);
4291       if (!frame_module_sp)
4292         continue;
4293 
4294       ModuleSpec module_spec;
4295       module_spec.GetUUID() = frame_module_sp->GetUUID();
4296 
4297       if (FileSystem::Instance().Exists(
4298               frame_module_sp->GetPlatformFileSpec())) {
4299         module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
4300         module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
4301       }
4302 
4303       bool current_frame_flush = false;
4304       if (DownloadObjectAndSymbolFile(module_spec, result, current_frame_flush))
4305         symbols_found = true;
4306       flush |= current_frame_flush;
4307     }
4308 
4309     if (!symbols_found) {
4310       result.AppendError(
4311           "unable to find debug symbols in the current call stack");
4312       return false;
4313     }
4314 
4315     return true;
4316   }
4317 
4318   bool DoExecute(Args &args, CommandReturnObject &result) override {
4319     Target *target = m_exe_ctx.GetTargetPtr();
4320     result.SetStatus(eReturnStatusFailed);
4321     bool flush = false;
4322     ModuleSpec module_spec;
4323     const bool uuid_option_set =
4324         m_uuid_option_group.GetOptionValue().OptionWasSet();
4325     const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4326     const bool frame_option_set =
4327         m_current_frame_option.GetOptionValue().OptionWasSet();
4328     const bool stack_option_set =
4329         m_current_stack_option.GetOptionValue().OptionWasSet();
4330     const size_t argc = args.GetArgumentCount();
4331 
4332     if (argc == 0) {
4333       if (uuid_option_set)
4334         AddSymbolsForUUID(result, flush);
4335       else if (file_option_set)
4336         AddSymbolsForFile(result, flush);
4337       else if (frame_option_set)
4338         AddSymbolsForFrame(result, flush);
4339       else if (stack_option_set)
4340         AddSymbolsForStack(result, flush);
4341       else
4342         result.AppendError("one or more symbol file paths must be specified, "
4343                            "or options must be specified");
4344     } else {
4345       if (uuid_option_set) {
4346         result.AppendError("specify either one or more paths to symbol files "
4347                            "or use the --uuid option without arguments");
4348       } else if (frame_option_set) {
4349         result.AppendError("specify either one or more paths to symbol files "
4350                            "or use the --frame option without arguments");
4351       } else if (file_option_set && argc > 1) {
4352         result.AppendError("specify at most one symbol file path when "
4353                            "--shlib option is set");
4354       } else {
4355         PlatformSP platform_sp(target->GetPlatform());
4356 
4357         for (auto &entry : args.entries()) {
4358           if (!entry.ref().empty()) {
4359             auto &symbol_file_spec = module_spec.GetSymbolFileSpec();
4360             symbol_file_spec.SetFile(entry.ref(), FileSpec::Style::native);
4361             FileSystem::Instance().Resolve(symbol_file_spec);
4362             if (file_option_set) {
4363               module_spec.GetFileSpec() =
4364                   m_file_option.GetOptionValue().GetCurrentValue();
4365             }
4366             if (platform_sp) {
4367               FileSpec symfile_spec;
4368               if (platform_sp
4369                       ->ResolveSymbolFile(*target, module_spec, symfile_spec)
4370                       .Success())
4371                 module_spec.GetSymbolFileSpec() = symfile_spec;
4372             }
4373 
4374             bool symfile_exists =
4375                 FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec());
4376 
4377             if (symfile_exists) {
4378               if (!AddModuleSymbols(target, module_spec, flush, result))
4379                 break;
4380             } else {
4381               std::string resolved_symfile_path =
4382                   module_spec.GetSymbolFileSpec().GetPath();
4383               if (resolved_symfile_path != entry.ref()) {
4384                 result.AppendErrorWithFormat(
4385                     "invalid module path '%s' with resolved path '%s'\n",
4386                     entry.c_str(), resolved_symfile_path.c_str());
4387                 break;
4388               }
4389               result.AppendErrorWithFormat("invalid module path '%s'\n",
4390                                            entry.c_str());
4391               break;
4392             }
4393           }
4394         }
4395       }
4396     }
4397 
4398     if (flush) {
4399       Process *process = m_exe_ctx.GetProcessPtr();
4400       if (process)
4401         process->Flush();
4402     }
4403     return result.Succeeded();
4404   }
4405 
4406   OptionGroupOptions m_option_group;
4407   OptionGroupUUID m_uuid_option_group;
4408   OptionGroupFile m_file_option;
4409   OptionGroupBoolean m_current_frame_option;
4410   OptionGroupBoolean m_current_stack_option;
4411 };
4412 
4413 #pragma mark CommandObjectTargetSymbols
4414 
4415 // CommandObjectTargetSymbols
4416 
4417 class CommandObjectTargetSymbols : public CommandObjectMultiword {
4418 public:
4419   // Constructors and Destructors
4420   CommandObjectTargetSymbols(CommandInterpreter &interpreter)
4421       : CommandObjectMultiword(
4422             interpreter, "target symbols",
4423             "Commands for adding and managing debug symbol files.",
4424             "target symbols <sub-command> ...") {
4425     LoadSubCommand(
4426         "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));
4427   }
4428 
4429   ~CommandObjectTargetSymbols() override = default;
4430 
4431 private:
4432   // For CommandObjectTargetModules only
4433   CommandObjectTargetSymbols(const CommandObjectTargetSymbols &) = delete;
4434   const CommandObjectTargetSymbols &
4435   operator=(const CommandObjectTargetSymbols &) = delete;
4436 };
4437 
4438 #pragma mark CommandObjectTargetStopHookAdd
4439 
4440 // CommandObjectTargetStopHookAdd
4441 #define LLDB_OPTIONS_target_stop_hook_add
4442 #include "CommandOptions.inc"
4443 
4444 class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
4445                                        public IOHandlerDelegateMultiline {
4446 public:
4447   class CommandOptions : public OptionGroup {
4448   public:
4449     CommandOptions() : m_line_end(UINT_MAX) {}
4450 
4451     ~CommandOptions() override = default;
4452 
4453     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
4454       return llvm::makeArrayRef(g_target_stop_hook_add_options);
4455     }
4456 
4457     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
4458                           ExecutionContext *execution_context) override {
4459       Status error;
4460       const int short_option =
4461           g_target_stop_hook_add_options[option_idx].short_option;
4462 
4463       switch (short_option) {
4464       case 'c':
4465         m_class_name = std::string(option_arg);
4466         m_sym_ctx_specified = true;
4467         break;
4468 
4469       case 'e':
4470         if (option_arg.getAsInteger(0, m_line_end)) {
4471           error.SetErrorStringWithFormat("invalid end line number: \"%s\"",
4472                                          option_arg.str().c_str());
4473           break;
4474         }
4475         m_sym_ctx_specified = true;
4476         break;
4477 
4478       case 'G': {
4479         bool value, success;
4480         value = OptionArgParser::ToBoolean(option_arg, false, &success);
4481         if (success) {
4482           m_auto_continue = value;
4483         } else
4484           error.SetErrorStringWithFormat(
4485               "invalid boolean value '%s' passed for -G option",
4486               option_arg.str().c_str());
4487       } break;
4488       case 'l':
4489         if (option_arg.getAsInteger(0, m_line_start)) {
4490           error.SetErrorStringWithFormat("invalid start line number: \"%s\"",
4491                                          option_arg.str().c_str());
4492           break;
4493         }
4494         m_sym_ctx_specified = true;
4495         break;
4496 
4497       case 'i':
4498         m_no_inlines = true;
4499         break;
4500 
4501       case 'n':
4502         m_function_name = std::string(option_arg);
4503         m_func_name_type_mask |= eFunctionNameTypeAuto;
4504         m_sym_ctx_specified = true;
4505         break;
4506 
4507       case 'f':
4508         m_file_name = std::string(option_arg);
4509         m_sym_ctx_specified = true;
4510         break;
4511 
4512       case 's':
4513         m_module_name = std::string(option_arg);
4514         m_sym_ctx_specified = true;
4515         break;
4516 
4517       case 't':
4518         if (option_arg.getAsInteger(0, m_thread_id))
4519           error.SetErrorStringWithFormat("invalid thread id string '%s'",
4520                                          option_arg.str().c_str());
4521         m_thread_specified = true;
4522         break;
4523 
4524       case 'T':
4525         m_thread_name = std::string(option_arg);
4526         m_thread_specified = true;
4527         break;
4528 
4529       case 'q':
4530         m_queue_name = std::string(option_arg);
4531         m_thread_specified = true;
4532         break;
4533 
4534       case 'x':
4535         if (option_arg.getAsInteger(0, m_thread_index))
4536           error.SetErrorStringWithFormat("invalid thread index string '%s'",
4537                                          option_arg.str().c_str());
4538         m_thread_specified = true;
4539         break;
4540 
4541       case 'o':
4542         m_use_one_liner = true;
4543         m_one_liner.push_back(std::string(option_arg));
4544         break;
4545 
4546       default:
4547         llvm_unreachable("Unimplemented option");
4548       }
4549       return error;
4550     }
4551 
4552     void OptionParsingStarting(ExecutionContext *execution_context) override {
4553       m_class_name.clear();
4554       m_function_name.clear();
4555       m_line_start = 0;
4556       m_line_end = UINT_MAX;
4557       m_file_name.clear();
4558       m_module_name.clear();
4559       m_func_name_type_mask = eFunctionNameTypeAuto;
4560       m_thread_id = LLDB_INVALID_THREAD_ID;
4561       m_thread_index = UINT32_MAX;
4562       m_thread_name.clear();
4563       m_queue_name.clear();
4564 
4565       m_no_inlines = false;
4566       m_sym_ctx_specified = false;
4567       m_thread_specified = false;
4568 
4569       m_use_one_liner = false;
4570       m_one_liner.clear();
4571       m_auto_continue = false;
4572     }
4573 
4574     std::string m_class_name;
4575     std::string m_function_name;
4576     uint32_t m_line_start = 0;
4577     uint32_t m_line_end;
4578     std::string m_file_name;
4579     std::string m_module_name;
4580     uint32_t m_func_name_type_mask =
4581         eFunctionNameTypeAuto; // A pick from lldb::FunctionNameType.
4582     lldb::tid_t m_thread_id;
4583     uint32_t m_thread_index;
4584     std::string m_thread_name;
4585     std::string m_queue_name;
4586     bool m_sym_ctx_specified = false;
4587     bool m_no_inlines;
4588     bool m_thread_specified = false;
4589     // Instance variables to hold the values for one_liner options.
4590     bool m_use_one_liner = false;
4591     std::vector<std::string> m_one_liner;
4592 
4593     bool m_auto_continue;
4594   };
4595 
4596   CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
4597       : CommandObjectParsed(interpreter, "target stop-hook add",
4598                             "Add a hook to be executed when the target stops."
4599                             "The hook can either be a list of commands or an "
4600                             "appropriately defined Python class.  You can also "
4601                             "add filters so the hook only runs a certain stop "
4602                             "points.",
4603                             "target stop-hook add"),
4604         IOHandlerDelegateMultiline("DONE",
4605                                    IOHandlerDelegate::Completion::LLDBCommand),
4606         m_python_class_options("scripted stop-hook", true, 'P') {
4607     SetHelpLong(
4608         R"(
4609 Command Based stop-hooks:
4610 -------------------------
4611   Stop hooks can run a list of lldb commands by providing one or more
4612   --one-line-command options.  The commands will get run in the order they are
4613   added.  Or you can provide no commands, in which case you will enter a
4614   command editor where you can enter the commands to be run.
4615 
4616 Python Based Stop Hooks:
4617 ------------------------
4618   Stop hooks can be implemented with a suitably defined Python class, whose name
4619   is passed in the --python-class option.
4620 
4621   When the stop hook is added, the class is initialized by calling:
4622 
4623     def __init__(self, target, extra_args, internal_dict):
4624 
4625     target: The target that the stop hook is being added to.
4626     extra_args: An SBStructuredData Dictionary filled with the -key -value
4627                 option pairs passed to the command.
4628     dict: An implementation detail provided by lldb.
4629 
4630   Then when the stop-hook triggers, lldb will run the 'handle_stop' method.
4631   The method has the signature:
4632 
4633     def handle_stop(self, exe_ctx, stream):
4634 
4635     exe_ctx: An SBExecutionContext for the thread that has stopped.
4636     stream: An SBStream, anything written to this stream will be printed in the
4637             the stop message when the process stops.
4638 
4639     Return Value: The method returns "should_stop".  If should_stop is false
4640                   from all the stop hook executions on threads that stopped
4641                   with a reason, then the process will continue.  Note that this
4642                   will happen only after all the stop hooks are run.
4643 
4644 Filter Options:
4645 ---------------
4646   Stop hooks can be set to always run, or to only run when the stopped thread
4647   matches the filter options passed on the command line.  The available filter
4648   options include a shared library or a thread or queue specification,
4649   a line range in a source file, a function name or a class name.
4650             )");
4651     m_all_options.Append(&m_python_class_options,
4652                          LLDB_OPT_SET_1 | LLDB_OPT_SET_2,
4653                          LLDB_OPT_SET_FROM_TO(4, 6));
4654     m_all_options.Append(&m_options);
4655     m_all_options.Finalize();
4656   }
4657 
4658   ~CommandObjectTargetStopHookAdd() override = default;
4659 
4660   Options *GetOptions() override { return &m_all_options; }
4661 
4662 protected:
4663   void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
4664     StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
4665     if (output_sp && interactive) {
4666       output_sp->PutCString(
4667           "Enter your stop hook command(s).  Type 'DONE' to end.\n");
4668       output_sp->Flush();
4669     }
4670   }
4671 
4672   void IOHandlerInputComplete(IOHandler &io_handler,
4673                               std::string &line) override {
4674     if (m_stop_hook_sp) {
4675       if (line.empty()) {
4676         StreamFileSP error_sp(io_handler.GetErrorStreamFileSP());
4677         if (error_sp) {
4678           error_sp->Printf("error: stop hook #%" PRIu64
4679                            " aborted, no commands.\n",
4680                            m_stop_hook_sp->GetID());
4681           error_sp->Flush();
4682         }
4683         Target *target = GetDebugger().GetSelectedTarget().get();
4684         if (target) {
4685           target->UndoCreateStopHook(m_stop_hook_sp->GetID());
4686         }
4687       } else {
4688         // The IOHandler editor is only for command lines stop hooks:
4689         Target::StopHookCommandLine *hook_ptr =
4690             static_cast<Target::StopHookCommandLine *>(m_stop_hook_sp.get());
4691 
4692         hook_ptr->SetActionFromString(line);
4693         StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
4694         if (output_sp) {
4695           output_sp->Printf("Stop hook #%" PRIu64 " added.\n",
4696                             m_stop_hook_sp->GetID());
4697           output_sp->Flush();
4698         }
4699       }
4700       m_stop_hook_sp.reset();
4701     }
4702     io_handler.SetIsDone(true);
4703   }
4704 
4705   bool DoExecute(Args &command, CommandReturnObject &result) override {
4706     m_stop_hook_sp.reset();
4707 
4708     Target &target = GetSelectedOrDummyTarget();
4709     Target::StopHookSP new_hook_sp =
4710         target.CreateStopHook(m_python_class_options.GetName().empty() ?
4711                                Target::StopHook::StopHookKind::CommandBased
4712                                : Target::StopHook::StopHookKind::ScriptBased);
4713 
4714     //  First step, make the specifier.
4715     std::unique_ptr<SymbolContextSpecifier> specifier_up;
4716     if (m_options.m_sym_ctx_specified) {
4717       specifier_up = std::make_unique<SymbolContextSpecifier>(
4718           GetDebugger().GetSelectedTarget());
4719 
4720       if (!m_options.m_module_name.empty()) {
4721         specifier_up->AddSpecification(
4722             m_options.m_module_name.c_str(),
4723             SymbolContextSpecifier::eModuleSpecified);
4724       }
4725 
4726       if (!m_options.m_class_name.empty()) {
4727         specifier_up->AddSpecification(
4728             m_options.m_class_name.c_str(),
4729             SymbolContextSpecifier::eClassOrNamespaceSpecified);
4730       }
4731 
4732       if (!m_options.m_file_name.empty()) {
4733         specifier_up->AddSpecification(m_options.m_file_name.c_str(),
4734                                        SymbolContextSpecifier::eFileSpecified);
4735       }
4736 
4737       if (m_options.m_line_start != 0) {
4738         specifier_up->AddLineSpecification(
4739             m_options.m_line_start,
4740             SymbolContextSpecifier::eLineStartSpecified);
4741       }
4742 
4743       if (m_options.m_line_end != UINT_MAX) {
4744         specifier_up->AddLineSpecification(
4745             m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
4746       }
4747 
4748       if (!m_options.m_function_name.empty()) {
4749         specifier_up->AddSpecification(
4750             m_options.m_function_name.c_str(),
4751             SymbolContextSpecifier::eFunctionSpecified);
4752       }
4753     }
4754 
4755     if (specifier_up)
4756       new_hook_sp->SetSpecifier(specifier_up.release());
4757 
4758     // Next see if any of the thread options have been entered:
4759 
4760     if (m_options.m_thread_specified) {
4761       ThreadSpec *thread_spec = new ThreadSpec();
4762 
4763       if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) {
4764         thread_spec->SetTID(m_options.m_thread_id);
4765       }
4766 
4767       if (m_options.m_thread_index != UINT32_MAX)
4768         thread_spec->SetIndex(m_options.m_thread_index);
4769 
4770       if (!m_options.m_thread_name.empty())
4771         thread_spec->SetName(m_options.m_thread_name.c_str());
4772 
4773       if (!m_options.m_queue_name.empty())
4774         thread_spec->SetQueueName(m_options.m_queue_name.c_str());
4775 
4776       new_hook_sp->SetThreadSpecifier(thread_spec);
4777     }
4778 
4779     new_hook_sp->SetAutoContinue(m_options.m_auto_continue);
4780     if (m_options.m_use_one_liner) {
4781       // This is a command line stop hook:
4782       Target::StopHookCommandLine *hook_ptr =
4783           static_cast<Target::StopHookCommandLine *>(new_hook_sp.get());
4784       hook_ptr->SetActionFromStrings(m_options.m_one_liner);
4785       result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
4786                                      new_hook_sp->GetID());
4787     } else if (!m_python_class_options.GetName().empty()) {
4788       // This is a scripted stop hook:
4789       Target::StopHookScripted *hook_ptr =
4790           static_cast<Target::StopHookScripted *>(new_hook_sp.get());
4791       Status error = hook_ptr->SetScriptCallback(
4792           m_python_class_options.GetName(),
4793           m_python_class_options.GetStructuredData());
4794       if (error.Success())
4795         result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
4796                                        new_hook_sp->GetID());
4797       else {
4798         // FIXME: Set the stop hook ID counter back.
4799         result.AppendErrorWithFormat("Couldn't add stop hook: %s",
4800                                      error.AsCString());
4801         target.UndoCreateStopHook(new_hook_sp->GetID());
4802         return false;
4803       }
4804     } else {
4805       m_stop_hook_sp = new_hook_sp;
4806       m_interpreter.GetLLDBCommandsFromIOHandler("> ",   // Prompt
4807                                                  *this); // IOHandlerDelegate
4808     }
4809     result.SetStatus(eReturnStatusSuccessFinishNoResult);
4810 
4811     return result.Succeeded();
4812   }
4813 
4814 private:
4815   CommandOptions m_options;
4816   OptionGroupPythonClassWithDict m_python_class_options;
4817   OptionGroupOptions m_all_options;
4818 
4819   Target::StopHookSP m_stop_hook_sp;
4820 };
4821 
4822 #pragma mark CommandObjectTargetStopHookDelete
4823 
4824 // CommandObjectTargetStopHookDelete
4825 
4826 class CommandObjectTargetStopHookDelete : public CommandObjectParsed {
4827 public:
4828   CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter)
4829       : CommandObjectParsed(interpreter, "target stop-hook delete",
4830                             "Delete a stop-hook.",
4831                             "target stop-hook delete [<idx>]") {}
4832 
4833   ~CommandObjectTargetStopHookDelete() override = default;
4834 
4835   void
4836   HandleArgumentCompletion(CompletionRequest &request,
4837                            OptionElementVector &opt_element_vector) override {
4838     CommandCompletions::InvokeCommonCompletionCallbacks(
4839         GetCommandInterpreter(), CommandCompletions::eStopHookIDCompletion,
4840         request, nullptr);
4841   }
4842 
4843 protected:
4844   bool DoExecute(Args &command, CommandReturnObject &result) override {
4845     Target &target = GetSelectedOrDummyTarget();
4846     // FIXME: see if we can use the breakpoint id style parser?
4847     size_t num_args = command.GetArgumentCount();
4848     if (num_args == 0) {
4849       if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
4850         result.SetStatus(eReturnStatusFailed);
4851         return false;
4852       } else {
4853         target.RemoveAllStopHooks();
4854       }
4855     } else {
4856       for (size_t i = 0; i < num_args; i++) {
4857         lldb::user_id_t user_id;
4858         if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
4859           result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4860                                        command.GetArgumentAtIndex(i));
4861           return false;
4862         }
4863         if (!target.RemoveStopHookByID(user_id)) {
4864           result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4865                                        command.GetArgumentAtIndex(i));
4866           return false;
4867         }
4868       }
4869     }
4870     result.SetStatus(eReturnStatusSuccessFinishNoResult);
4871     return result.Succeeded();
4872   }
4873 };
4874 
4875 #pragma mark CommandObjectTargetStopHookEnableDisable
4876 
4877 // CommandObjectTargetStopHookEnableDisable
4878 
4879 class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed {
4880 public:
4881   CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter,
4882                                            bool enable, const char *name,
4883                                            const char *help, const char *syntax)
4884       : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) {
4885   }
4886 
4887   ~CommandObjectTargetStopHookEnableDisable() override = default;
4888 
4889   void
4890   HandleArgumentCompletion(CompletionRequest &request,
4891                            OptionElementVector &opt_element_vector) override {
4892     if (request.GetCursorIndex())
4893       return;
4894     CommandCompletions::InvokeCommonCompletionCallbacks(
4895         GetCommandInterpreter(), CommandCompletions::eStopHookIDCompletion,
4896         request, nullptr);
4897   }
4898 
4899 protected:
4900   bool DoExecute(Args &command, CommandReturnObject &result) override {
4901     Target &target = GetSelectedOrDummyTarget();
4902     // FIXME: see if we can use the breakpoint id style parser?
4903     size_t num_args = command.GetArgumentCount();
4904     bool success;
4905 
4906     if (num_args == 0) {
4907       target.SetAllStopHooksActiveState(m_enable);
4908     } else {
4909       for (size_t i = 0; i < num_args; i++) {
4910         lldb::user_id_t user_id;
4911         if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
4912           result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4913                                        command.GetArgumentAtIndex(i));
4914           return false;
4915         }
4916         success = target.SetStopHookActiveStateByID(user_id, m_enable);
4917         if (!success) {
4918           result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4919                                        command.GetArgumentAtIndex(i));
4920           return false;
4921         }
4922       }
4923     }
4924     result.SetStatus(eReturnStatusSuccessFinishNoResult);
4925     return result.Succeeded();
4926   }
4927 
4928 private:
4929   bool m_enable;
4930 };
4931 
4932 #pragma mark CommandObjectTargetStopHookList
4933 
4934 // CommandObjectTargetStopHookList
4935 
4936 class CommandObjectTargetStopHookList : public CommandObjectParsed {
4937 public:
4938   CommandObjectTargetStopHookList(CommandInterpreter &interpreter)
4939       : CommandObjectParsed(interpreter, "target stop-hook list",
4940                             "List all stop-hooks.",
4941                             "target stop-hook list [<type>]") {}
4942 
4943   ~CommandObjectTargetStopHookList() override = default;
4944 
4945 protected:
4946   bool DoExecute(Args &command, CommandReturnObject &result) override {
4947     Target &target = GetSelectedOrDummyTarget();
4948 
4949     size_t num_hooks = target.GetNumStopHooks();
4950     if (num_hooks == 0) {
4951       result.GetOutputStream().PutCString("No stop hooks.\n");
4952     } else {
4953       for (size_t i = 0; i < num_hooks; i++) {
4954         Target::StopHookSP this_hook = target.GetStopHookAtIndex(i);
4955         if (i > 0)
4956           result.GetOutputStream().PutCString("\n");
4957         this_hook->GetDescription(&(result.GetOutputStream()),
4958                                   eDescriptionLevelFull);
4959       }
4960     }
4961     result.SetStatus(eReturnStatusSuccessFinishResult);
4962     return result.Succeeded();
4963   }
4964 };
4965 
4966 #pragma mark CommandObjectMultiwordTargetStopHooks
4967 
4968 // CommandObjectMultiwordTargetStopHooks
4969 
4970 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword {
4971 public:
4972   CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
4973       : CommandObjectMultiword(
4974             interpreter, "target stop-hook",
4975             "Commands for operating on debugger target stop-hooks.",
4976             "target stop-hook <subcommand> [<subcommand-options>]") {
4977     LoadSubCommand("add", CommandObjectSP(
4978                               new CommandObjectTargetStopHookAdd(interpreter)));
4979     LoadSubCommand(
4980         "delete",
4981         CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter)));
4982     LoadSubCommand("disable",
4983                    CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
4984                        interpreter, false, "target stop-hook disable [<id>]",
4985                        "Disable a stop-hook.", "target stop-hook disable")));
4986     LoadSubCommand("enable",
4987                    CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
4988                        interpreter, true, "target stop-hook enable [<id>]",
4989                        "Enable a stop-hook.", "target stop-hook enable")));
4990     LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList(
4991                                interpreter)));
4992   }
4993 
4994   ~CommandObjectMultiwordTargetStopHooks() override = default;
4995 };
4996 
4997 #pragma mark CommandObjectTargetDumpTypesystem
4998 
4999 /// Dumps the TypeSystem of the selected Target.
5000 class CommandObjectTargetDumpTypesystem : public CommandObjectParsed {
5001 public:
5002   CommandObjectTargetDumpTypesystem(CommandInterpreter &interpreter)
5003       : CommandObjectParsed(
5004             interpreter, "target dump typesystem",
5005             "Dump the state of the target's internal type system.\n"
5006             "Intended to be used for debugging LLDB itself.",
5007             nullptr, eCommandRequiresTarget) {}
5008 
5009   ~CommandObjectTargetDumpTypesystem() override = default;
5010 
5011 protected:
5012   bool DoExecute(Args &command, CommandReturnObject &result) override {
5013     if (!command.empty()) {
5014       result.AppendError("target dump typesystem doesn't take arguments.");
5015       return result.Succeeded();
5016     }
5017 
5018     // Go over every scratch TypeSystem and dump to the command output.
5019     for (TypeSystem *ts : GetSelectedTarget().GetScratchTypeSystems())
5020       ts->Dump(result.GetOutputStream().AsRawOstream());
5021 
5022     result.SetStatus(eReturnStatusSuccessFinishResult);
5023     return result.Succeeded();
5024   }
5025 };
5026 
5027 #pragma mark CommandObjectTargetDump
5028 
5029 /// Multi-word command for 'target dump'.
5030 class CommandObjectTargetDump : public CommandObjectMultiword {
5031 public:
5032   // Constructors and Destructors
5033   CommandObjectTargetDump(CommandInterpreter &interpreter)
5034       : CommandObjectMultiword(
5035             interpreter, "target dump",
5036             "Commands for dumping information about the target.",
5037             "target dump [typesystem]") {
5038     LoadSubCommand(
5039         "typesystem",
5040         CommandObjectSP(new CommandObjectTargetDumpTypesystem(interpreter)));
5041   }
5042 
5043   ~CommandObjectTargetDump() override = default;
5044 };
5045 
5046 #pragma mark CommandObjectMultiwordTarget
5047 
5048 // CommandObjectMultiwordTarget
5049 
5050 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(
5051     CommandInterpreter &interpreter)
5052     : CommandObjectMultiword(interpreter, "target",
5053                              "Commands for operating on debugger targets.",
5054                              "target <subcommand> [<subcommand-options>]") {
5055   LoadSubCommand("create",
5056                  CommandObjectSP(new CommandObjectTargetCreate(interpreter)));
5057   LoadSubCommand("delete",
5058                  CommandObjectSP(new CommandObjectTargetDelete(interpreter)));
5059   LoadSubCommand("dump",
5060                  CommandObjectSP(new CommandObjectTargetDump(interpreter)));
5061   LoadSubCommand("list",
5062                  CommandObjectSP(new CommandObjectTargetList(interpreter)));
5063   LoadSubCommand("select",
5064                  CommandObjectSP(new CommandObjectTargetSelect(interpreter)));
5065   LoadSubCommand("show-launch-environment",
5066                  CommandObjectSP(new CommandObjectTargetShowLaunchEnvironment(
5067                      interpreter)));
5068   LoadSubCommand(
5069       "stop-hook",
5070       CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter)));
5071   LoadSubCommand("modules",
5072                  CommandObjectSP(new CommandObjectTargetModules(interpreter)));
5073   LoadSubCommand("symbols",
5074                  CommandObjectSP(new CommandObjectTargetSymbols(interpreter)));
5075   LoadSubCommand("variable",
5076                  CommandObjectSP(new CommandObjectTargetVariable(interpreter)));
5077 }
5078 
5079 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;
5080