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