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