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