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