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