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   OptionGroupDependents(const OptionGroupDependents &) = delete;
204   const OptionGroupDependents &
205   operator=(const OptionGroupDependents &) = delete;
206 };
207 
208 #pragma mark CommandObjectTargetCreate
209 
210 // "target create"
211 
212 class CommandObjectTargetCreate : public CommandObjectParsed {
213 public:
214   CommandObjectTargetCreate(CommandInterpreter &interpreter)
215       : CommandObjectParsed(
216             interpreter, "target create",
217             "Create a target using the argument as the main executable.",
218             nullptr),
219         m_option_group(), m_arch_option(),
220         m_core_file(LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename,
221                     "Fullpath to a core file to use for this target."),
222         m_platform_path(LLDB_OPT_SET_1, false, "platform-path", 'P', 0,
223                         eArgTypePath,
224                         "Path to the remote file to use for this target."),
225         m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
226                       eArgTypeFilename,
227                       "Fullpath to a stand alone debug "
228                       "symbols file for when debug symbols "
229                       "are not in the executable."),
230         m_remote_file(
231             LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename,
232             "Fullpath to the file on the remote host if debugging remotely."),
233         m_add_dependents() {
234     CommandArgumentEntry arg;
235     CommandArgumentData file_arg;
236 
237     // Define the first (and only) variant of this arg.
238     file_arg.arg_type = eArgTypeFilename;
239     file_arg.arg_repetition = eArgRepeatPlain;
240 
241     // There is only one variant this argument could be; put it into the
242     // argument entry.
243     arg.push_back(file_arg);
244 
245     // Push the data for the first argument into the m_arguments vector.
246     m_arguments.push_back(arg);
247 
248     m_option_group.Append(&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
249     m_option_group.Append(&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
250     m_option_group.Append(&m_platform_path, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
251     m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
252     m_option_group.Append(&m_remote_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
253     m_option_group.Append(&m_add_dependents, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
254     m_option_group.Finalize();
255   }
256 
257   ~CommandObjectTargetCreate() override = default;
258 
259   Options *GetOptions() override { return &m_option_group; }
260 
261   void
262   HandleArgumentCompletion(CompletionRequest &request,
263                            OptionElementVector &opt_element_vector) override {
264     CommandCompletions::InvokeCommonCompletionCallbacks(
265         GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
266         request, nullptr);
267   }
268 
269 protected:
270   bool DoExecute(Args &command, CommandReturnObject &result) override {
271     const size_t argc = command.GetArgumentCount();
272     FileSpec core_file(m_core_file.GetOptionValue().GetCurrentValue());
273     FileSpec remote_file(m_remote_file.GetOptionValue().GetCurrentValue());
274 
275     if (core_file) {
276       auto file = FileSystem::Instance().Open(
277           core_file, lldb_private::File::eOpenOptionRead);
278 
279       if (!file) {
280         result.AppendErrorWithFormatv("Cannot open '{0}': {1}.",
281                                       core_file.GetPath(),
282                                       llvm::toString(file.takeError()));
283         result.SetStatus(eReturnStatusFailed);
284         return false;
285       }
286     }
287 
288     if (argc == 1 || core_file || remote_file) {
289       FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue());
290       if (symfile) {
291         auto file = FileSystem::Instance().Open(
292             symfile, lldb_private::File::eOpenOptionRead);
293 
294         if (!file) {
295           result.AppendErrorWithFormatv("Cannot open '{0}': {1}.",
296                                         symfile.GetPath(),
297                                         llvm::toString(file.takeError()));
298           result.SetStatus(eReturnStatusFailed);
299           return false;
300         }
301       }
302 
303       const char *file_path = command.GetArgumentAtIndex(0);
304       static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
305       Timer scoped_timer(func_cat, "(lldb) target create '%s'", file_path);
306       FileSpec file_spec;
307 
308       if (file_path) {
309         file_spec.SetFile(file_path, FileSpec::Style::native);
310         FileSystem::Instance().Resolve(file_spec);
311       }
312 
313       bool must_set_platform_path = false;
314 
315       Debugger &debugger = GetDebugger();
316 
317       TargetSP target_sp;
318       llvm::StringRef arch_cstr = m_arch_option.GetArchitectureName();
319       Status error(debugger.GetTargetList().CreateTarget(
320           debugger, file_path, arch_cstr,
321           m_add_dependents.m_load_dependent_files, nullptr, target_sp));
322 
323       if (target_sp) {
324         // Only get the platform after we create the target because we might
325         // have switched platforms depending on what the arguments were to
326         // CreateTarget() we can't rely on the selected platform.
327 
328         PlatformSP platform_sp = target_sp->GetPlatform();
329 
330         if (remote_file) {
331           if (platform_sp) {
332             // I have a remote file.. two possible cases
333             if (file_spec && FileSystem::Instance().Exists(file_spec)) {
334               // if the remote file does not exist, push it there
335               if (!platform_sp->GetFileExists(remote_file)) {
336                 Status err = platform_sp->PutFile(file_spec, remote_file);
337                 if (err.Fail()) {
338                   result.AppendError(err.AsCString());
339                   result.SetStatus(eReturnStatusFailed);
340                   return false;
341                 }
342               }
343             } else {
344               // there is no local file and we need one
345               // in order to make the remote ---> local transfer we need a
346               // platform
347               // TODO: if the user has passed in a --platform argument, use it
348               // to fetch the right platform
349               if (!platform_sp) {
350                 result.AppendError(
351                     "unable to perform remote debugging without a platform");
352                 result.SetStatus(eReturnStatusFailed);
353                 return false;
354               }
355               if (file_path) {
356                 // copy the remote file to the local file
357                 Status err = platform_sp->GetFile(remote_file, file_spec);
358                 if (err.Fail()) {
359                   result.AppendError(err.AsCString());
360                   result.SetStatus(eReturnStatusFailed);
361                   return false;
362                 }
363               } else {
364                 // make up a local file
365                 result.AppendError("remote --> local transfer without local "
366                                    "path is not implemented yet");
367                 result.SetStatus(eReturnStatusFailed);
368                 return false;
369               }
370             }
371           } else {
372             result.AppendError("no platform found for target");
373             result.SetStatus(eReturnStatusFailed);
374             return false;
375           }
376         }
377 
378         if (symfile || remote_file) {
379           ModuleSP module_sp(target_sp->GetExecutableModule());
380           if (module_sp) {
381             if (symfile)
382               module_sp->SetSymbolFileFileSpec(symfile);
383             if (remote_file) {
384               std::string remote_path = remote_file.GetPath();
385               target_sp->SetArg0(remote_path.c_str());
386               module_sp->SetPlatformFileSpec(remote_file);
387             }
388           }
389         }
390 
391         debugger.GetTargetList().SetSelectedTarget(target_sp.get());
392         if (must_set_platform_path) {
393           ModuleSpec main_module_spec(file_spec);
394           ModuleSP module_sp =
395               target_sp->GetOrCreateModule(main_module_spec, true /* notify */);
396           if (module_sp)
397             module_sp->SetPlatformFileSpec(remote_file);
398         }
399 
400         if (core_file) {
401           FileSpec core_file_dir;
402           core_file_dir.GetDirectory() = core_file.GetDirectory();
403           target_sp->AppendExecutableSearchPaths(core_file_dir);
404 
405           ProcessSP process_sp(target_sp->CreateProcess(
406               GetDebugger().GetListener(), llvm::StringRef(), &core_file));
407 
408           if (process_sp) {
409             // Seems weird that we Launch a core file, but that is what we
410             // do!
411             error = process_sp->LoadCore();
412 
413             if (error.Fail()) {
414               result.AppendError(
415                   error.AsCString("can't find plug-in for core file"));
416               result.SetStatus(eReturnStatusFailed);
417               return false;
418             } else {
419               result.AppendMessageWithFormatv("Core file '{0}' ({1}) was loaded.\n", core_file.GetPath(),
420                   target_sp->GetArchitecture().GetArchitectureName());
421               result.SetStatus(eReturnStatusSuccessFinishNoResult);
422             }
423           } else {
424             result.AppendErrorWithFormatv(
425                 "Unable to find process plug-in for core file '{0}'\n",
426                 core_file.GetPath());
427             result.SetStatus(eReturnStatusFailed);
428           }
429         } else {
430           result.AppendMessageWithFormat(
431               "Current executable set to '%s' (%s).\n",
432               file_spec.GetPath().c_str(),
433               target_sp->GetArchitecture().GetArchitectureName());
434           result.SetStatus(eReturnStatusSuccessFinishNoResult);
435         }
436       } else {
437         result.AppendError(error.AsCString());
438         result.SetStatus(eReturnStatusFailed);
439       }
440     } else {
441       result.AppendErrorWithFormat("'%s' takes exactly one executable path "
442                                    "argument, or use the --core option.\n",
443                                    m_cmd_name.c_str());
444       result.SetStatus(eReturnStatusFailed);
445     }
446     return result.Succeeded();
447   }
448 
449 private:
450   OptionGroupOptions m_option_group;
451   OptionGroupArchitecture m_arch_option;
452   OptionGroupFile m_core_file;
453   OptionGroupFile m_platform_path;
454   OptionGroupFile m_symbol_file;
455   OptionGroupFile m_remote_file;
456   OptionGroupDependents m_add_dependents;
457 };
458 
459 #pragma mark CommandObjectTargetList
460 
461 // "target list"
462 
463 class CommandObjectTargetList : public CommandObjectParsed {
464 public:
465   CommandObjectTargetList(CommandInterpreter &interpreter)
466       : CommandObjectParsed(
467             interpreter, "target list",
468             "List all current targets in the current debug session.", nullptr) {
469   }
470 
471   ~CommandObjectTargetList() override = default;
472 
473 protected:
474   bool DoExecute(Args &args, CommandReturnObject &result) override {
475     if (args.GetArgumentCount() == 0) {
476       Stream &strm = result.GetOutputStream();
477 
478       bool show_stopped_process_status = false;
479       if (DumpTargetList(GetDebugger().GetTargetList(),
480                          show_stopped_process_status, strm) == 0) {
481         strm.PutCString("No targets.\n");
482       }
483       result.SetStatus(eReturnStatusSuccessFinishResult);
484     } else {
485       result.AppendError("the 'target list' command takes no arguments\n");
486       result.SetStatus(eReturnStatusFailed);
487     }
488     return result.Succeeded();
489   }
490 };
491 
492 #pragma mark CommandObjectTargetSelect
493 
494 // "target select"
495 
496 class CommandObjectTargetSelect : public CommandObjectParsed {
497 public:
498   CommandObjectTargetSelect(CommandInterpreter &interpreter)
499       : CommandObjectParsed(
500             interpreter, "target select",
501             "Select a target as the current target by target index.", nullptr) {
502   }
503 
504   ~CommandObjectTargetSelect() override = default;
505 
506 protected:
507   bool DoExecute(Args &args, CommandReturnObject &result) override {
508     if (args.GetArgumentCount() == 1) {
509       bool success = false;
510       const char *target_idx_arg = args.GetArgumentAtIndex(0);
511       uint32_t target_idx =
512           StringConvert::ToUInt32(target_idx_arg, UINT32_MAX, 0, &success);
513       if (success) {
514         TargetList &target_list = GetDebugger().GetTargetList();
515         const uint32_t num_targets = target_list.GetNumTargets();
516         if (target_idx < num_targets) {
517           TargetSP target_sp(target_list.GetTargetAtIndex(target_idx));
518           if (target_sp) {
519             Stream &strm = result.GetOutputStream();
520             target_list.SetSelectedTarget(target_sp.get());
521             bool show_stopped_process_status = false;
522             DumpTargetList(target_list, show_stopped_process_status, strm);
523             result.SetStatus(eReturnStatusSuccessFinishResult);
524           } else {
525             result.AppendErrorWithFormat("target #%u is NULL in target list\n",
526                                          target_idx);
527             result.SetStatus(eReturnStatusFailed);
528           }
529         } else {
530           if (num_targets > 0) {
531             result.AppendErrorWithFormat(
532                 "index %u is out of range, valid target indexes are 0 - %u\n",
533                 target_idx, num_targets - 1);
534           } else {
535             result.AppendErrorWithFormat(
536                 "index %u is out of range since there are no active targets\n",
537                 target_idx);
538           }
539           result.SetStatus(eReturnStatusFailed);
540         }
541       } else {
542         result.AppendErrorWithFormat("invalid index string value '%s'\n",
543                                      target_idx_arg);
544         result.SetStatus(eReturnStatusFailed);
545       }
546     } else {
547       result.AppendError(
548           "'target select' takes a single argument: a target index\n");
549       result.SetStatus(eReturnStatusFailed);
550     }
551     return result.Succeeded();
552   }
553 };
554 
555 #pragma mark CommandObjectTargetDelete
556 
557 // "target delete"
558 
559 class CommandObjectTargetDelete : public CommandObjectParsed {
560 public:
561   CommandObjectTargetDelete(CommandInterpreter &interpreter)
562       : CommandObjectParsed(interpreter, "target delete",
563                             "Delete one or more targets by target index.",
564                             nullptr),
565         m_option_group(), m_all_option(LLDB_OPT_SET_1, false, "all", 'a',
566                                        "Delete all targets.", false, true),
567         m_cleanup_option(
568             LLDB_OPT_SET_1, false, "clean", 'c',
569             "Perform extra cleanup to minimize memory consumption after "
570             "deleting the target.  "
571             "By default, LLDB will keep in memory any modules previously "
572             "loaded by the target as well "
573             "as all of its debug info.  Specifying --clean will unload all of "
574             "these shared modules and "
575             "cause them to be reparsed again the next time the target is run",
576             false, true) {
577     m_option_group.Append(&m_all_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
578     m_option_group.Append(&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
579     m_option_group.Finalize();
580   }
581 
582   ~CommandObjectTargetDelete() override = default;
583 
584   Options *GetOptions() override { return &m_option_group; }
585 
586 protected:
587   bool DoExecute(Args &args, CommandReturnObject &result) override {
588     const size_t argc = args.GetArgumentCount();
589     std::vector<TargetSP> delete_target_list;
590     TargetList &target_list = GetDebugger().GetTargetList();
591     TargetSP target_sp;
592 
593     if (m_all_option.GetOptionValue()) {
594       for (int i = 0; i < target_list.GetNumTargets(); ++i)
595         delete_target_list.push_back(target_list.GetTargetAtIndex(i));
596     } else if (argc > 0) {
597       const uint32_t num_targets = target_list.GetNumTargets();
598       // Bail out if don't have any targets.
599       if (num_targets == 0) {
600         result.AppendError("no targets to delete");
601         result.SetStatus(eReturnStatusFailed);
602         return false;
603       }
604 
605       for (auto &entry : args.entries()) {
606         uint32_t target_idx;
607         if (entry.ref().getAsInteger(0, target_idx)) {
608           result.AppendErrorWithFormat("invalid target index '%s'\n",
609                                        entry.c_str());
610           result.SetStatus(eReturnStatusFailed);
611           return false;
612         }
613         if (target_idx < num_targets) {
614           target_sp = target_list.GetTargetAtIndex(target_idx);
615           if (target_sp) {
616             delete_target_list.push_back(target_sp);
617             continue;
618           }
619         }
620         if (num_targets > 1)
621           result.AppendErrorWithFormat("target index %u is out of range, valid "
622                                        "target indexes are 0 - %u\n",
623                                        target_idx, num_targets - 1);
624         else
625           result.AppendErrorWithFormat(
626               "target index %u is out of range, the only valid index is 0\n",
627               target_idx);
628 
629         result.SetStatus(eReturnStatusFailed);
630         return false;
631       }
632     } else {
633       target_sp = target_list.GetSelectedTarget();
634       if (!target_sp) {
635         result.AppendErrorWithFormat("no target is currently selected\n");
636         result.SetStatus(eReturnStatusFailed);
637         return false;
638       }
639       delete_target_list.push_back(target_sp);
640     }
641 
642     const size_t num_targets_to_delete = delete_target_list.size();
643     for (size_t idx = 0; idx < num_targets_to_delete; ++idx) {
644       target_sp = delete_target_list[idx];
645       target_list.DeleteTarget(target_sp);
646       target_sp->Destroy();
647     }
648     // If "--clean" was specified, prune any orphaned shared modules from the
649     // global shared module list
650     if (m_cleanup_option.GetOptionValue()) {
651       const bool mandatory = true;
652       ModuleList::RemoveOrphanSharedModules(mandatory);
653     }
654     result.GetOutputStream().Printf("%u targets deleted.\n",
655                                     (uint32_t)num_targets_to_delete);
656     result.SetStatus(eReturnStatusSuccessFinishResult);
657 
658     return true;
659   }
660 
661   OptionGroupOptions m_option_group;
662   OptionGroupBoolean m_all_option;
663   OptionGroupBoolean m_cleanup_option;
664 };
665 
666 class CommandObjectTargetShowLaunchEnvironment : public CommandObjectParsed {
667 public:
668   CommandObjectTargetShowLaunchEnvironment(CommandInterpreter &interpreter)
669       : CommandObjectParsed(
670             interpreter, "target show-launch-environment",
671             "Shows the environment being passed to the process when launched, "
672             "taking info account 3 settings: target.env-vars, "
673             "target.inherit-env and target.unset-env-vars.",
674             nullptr, eCommandRequiresTarget) {}
675 
676   ~CommandObjectTargetShowLaunchEnvironment() override = default;
677 
678 protected:
679   bool DoExecute(Args &args, CommandReturnObject &result) override {
680     Target *target = m_exe_ctx.GetTargetPtr();
681     Environment env = target->GetEnvironment();
682 
683     std::vector<Environment::value_type *> env_vector;
684     env_vector.reserve(env.size());
685     for (auto &KV : env)
686       env_vector.push_back(&KV);
687     std::sort(env_vector.begin(), env_vector.end(),
688               [](Environment::value_type *a, Environment::value_type *b) {
689                 return a->first() < b->first();
690               });
691 
692     auto &strm = result.GetOutputStream();
693     for (auto &KV : env_vector)
694       strm.Format("{0}={1}\n", KV->first(), KV->second);
695 
696     result.SetStatus(eReturnStatusSuccessFinishResult);
697     return result.Succeeded();
698   }
699 };
700 
701 #pragma mark CommandObjectTargetVariable
702 
703 // "target variable"
704 
705 class CommandObjectTargetVariable : public CommandObjectParsed {
706   static const uint32_t SHORT_OPTION_FILE = 0x66696c65; // 'file'
707   static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb'
708 
709 public:
710   CommandObjectTargetVariable(CommandInterpreter &interpreter)
711       : CommandObjectParsed(interpreter, "target variable",
712                             "Read global variables for the current target, "
713                             "before or while running a process.",
714                             nullptr, eCommandRequiresTarget),
715         m_option_group(),
716         m_option_variable(false), // Don't include frame options
717         m_option_format(eFormatDefault),
718         m_option_compile_units(LLDB_OPT_SET_1, false, "file", SHORT_OPTION_FILE,
719                                0, eArgTypeFilename,
720                                "A basename or fullpath to a file that contains "
721                                "global variables. This option can be "
722                                "specified multiple times."),
723         m_option_shared_libraries(
724             LLDB_OPT_SET_1, false, "shlib", SHORT_OPTION_SHLB, 0,
725             eArgTypeFilename,
726             "A basename or fullpath to a shared library to use in the search "
727             "for global "
728             "variables. This option can be specified multiple times."),
729         m_varobj_options() {
730     CommandArgumentEntry arg;
731     CommandArgumentData var_name_arg;
732 
733     // Define the first (and only) variant of this arg.
734     var_name_arg.arg_type = eArgTypeVarName;
735     var_name_arg.arg_repetition = eArgRepeatPlus;
736 
737     // There is only one variant this argument could be; put it into the
738     // argument entry.
739     arg.push_back(var_name_arg);
740 
741     // Push the data for the first argument into the m_arguments vector.
742     m_arguments.push_back(arg);
743 
744     m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
745     m_option_group.Append(&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
746     m_option_group.Append(&m_option_format,
747                           OptionGroupFormat::OPTION_GROUP_FORMAT |
748                               OptionGroupFormat::OPTION_GROUP_GDB_FMT,
749                           LLDB_OPT_SET_1);
750     m_option_group.Append(&m_option_compile_units, LLDB_OPT_SET_ALL,
751                           LLDB_OPT_SET_1);
752     m_option_group.Append(&m_option_shared_libraries, LLDB_OPT_SET_ALL,
753                           LLDB_OPT_SET_1);
754     m_option_group.Finalize();
755   }
756 
757   ~CommandObjectTargetVariable() override = default;
758 
759   void DumpValueObject(Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp,
760                        const char *root_name) {
761     DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());
762 
763     if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
764         valobj_sp->IsRuntimeSupportValue())
765       return;
766 
767     switch (var_sp->GetScope()) {
768     case eValueTypeVariableGlobal:
769       if (m_option_variable.show_scope)
770         s.PutCString("GLOBAL: ");
771       break;
772 
773     case eValueTypeVariableStatic:
774       if (m_option_variable.show_scope)
775         s.PutCString("STATIC: ");
776       break;
777 
778     case eValueTypeVariableArgument:
779       if (m_option_variable.show_scope)
780         s.PutCString("   ARG: ");
781       break;
782 
783     case eValueTypeVariableLocal:
784       if (m_option_variable.show_scope)
785         s.PutCString(" LOCAL: ");
786       break;
787 
788     case eValueTypeVariableThreadLocal:
789       if (m_option_variable.show_scope)
790         s.PutCString("THREAD: ");
791       break;
792 
793     default:
794       break;
795     }
796 
797     if (m_option_variable.show_decl) {
798       bool show_fullpaths = false;
799       bool show_module = true;
800       if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
801         s.PutCString(": ");
802     }
803 
804     const Format format = m_option_format.GetFormat();
805     if (format != eFormatDefault)
806       options.SetFormat(format);
807 
808     options.SetRootValueObjectName(root_name);
809 
810     valobj_sp->Dump(s, options);
811   }
812 
813   static size_t GetVariableCallback(void *baton, const char *name,
814                                     VariableList &variable_list) {
815     size_t old_size = variable_list.GetSize();
816     Target *target = static_cast<Target *>(baton);
817     if (target)
818       target->GetImages().FindGlobalVariables(ConstString(name), UINT32_MAX,
819                                               variable_list);
820     return variable_list.GetSize() - old_size;
821   }
822 
823   Options *GetOptions() override { return &m_option_group; }
824 
825 protected:
826   void DumpGlobalVariableList(const ExecutionContext &exe_ctx,
827                               const SymbolContext &sc,
828                               const VariableList &variable_list, Stream &s) {
829     if (variable_list.Empty())
830       return;
831     if (sc.module_sp) {
832       if (sc.comp_unit) {
833         s.Format("Global variables for {0} in {1}:\n",
834                  sc.comp_unit->GetPrimaryFile(), sc.module_sp->GetFileSpec());
835       } else {
836         s.Printf("Global variables for %s\n",
837                  sc.module_sp->GetFileSpec().GetPath().c_str());
838       }
839     } else if (sc.comp_unit) {
840       s.Format("Global variables for {0}\n", sc.comp_unit->GetPrimaryFile());
841     }
842 
843     for (VariableSP var_sp : variable_list) {
844       if (!var_sp)
845         continue;
846       ValueObjectSP valobj_sp(ValueObjectVariable::Create(
847           exe_ctx.GetBestExecutionContextScope(), var_sp));
848 
849       if (valobj_sp)
850         DumpValueObject(s, var_sp, valobj_sp, var_sp->GetName().GetCString());
851     }
852   }
853 
854   bool DoExecute(Args &args, CommandReturnObject &result) override {
855     Target *target = m_exe_ctx.GetTargetPtr();
856     const size_t argc = args.GetArgumentCount();
857     Stream &s = result.GetOutputStream();
858 
859     if (argc > 0) {
860       for (const Args::ArgEntry &arg : args) {
861         VariableList variable_list;
862         ValueObjectList valobj_list;
863 
864         size_t matches = 0;
865         bool use_var_name = false;
866         if (m_option_variable.use_regex) {
867           RegularExpression regex(
868               llvm::StringRef::withNullAsEmpty(arg.c_str()));
869           if (!regex.IsValid()) {
870             result.GetErrorStream().Printf(
871                 "error: invalid regular expression: '%s'\n", arg.c_str());
872             result.SetStatus(eReturnStatusFailed);
873             return false;
874           }
875           use_var_name = true;
876           target->GetImages().FindGlobalVariables(regex, UINT32_MAX,
877                                                   variable_list);
878           matches = variable_list.GetSize();
879         } else {
880           Status error(Variable::GetValuesForVariableExpressionPath(
881               arg.c_str(), m_exe_ctx.GetBestExecutionContextScope(),
882               GetVariableCallback, target, variable_list, valobj_list));
883           matches = variable_list.GetSize();
884         }
885 
886         if (matches == 0) {
887           result.GetErrorStream().Printf(
888               "error: can't find global variable '%s'\n", arg.c_str());
889           result.SetStatus(eReturnStatusFailed);
890           return false;
891         } else {
892           for (uint32_t global_idx = 0; global_idx < matches; ++global_idx) {
893             VariableSP var_sp(variable_list.GetVariableAtIndex(global_idx));
894             if (var_sp) {
895               ValueObjectSP valobj_sp(
896                   valobj_list.GetValueObjectAtIndex(global_idx));
897               if (!valobj_sp)
898                 valobj_sp = ValueObjectVariable::Create(
899                     m_exe_ctx.GetBestExecutionContextScope(), var_sp);
900 
901               if (valobj_sp)
902                 DumpValueObject(s, var_sp, valobj_sp,
903                                 use_var_name ? var_sp->GetName().GetCString()
904                                              : arg.c_str());
905             }
906           }
907         }
908       }
909     } else {
910       const FileSpecList &compile_units =
911           m_option_compile_units.GetOptionValue().GetCurrentValue();
912       const FileSpecList &shlibs =
913           m_option_shared_libraries.GetOptionValue().GetCurrentValue();
914       SymbolContextList sc_list;
915       const size_t num_compile_units = compile_units.GetSize();
916       const size_t num_shlibs = shlibs.GetSize();
917       if (num_compile_units == 0 && num_shlibs == 0) {
918         bool success = false;
919         StackFrame *frame = m_exe_ctx.GetFramePtr();
920         CompileUnit *comp_unit = nullptr;
921         if (frame) {
922           SymbolContext sc = frame->GetSymbolContext(eSymbolContextCompUnit);
923           if (sc.comp_unit) {
924             const bool can_create = true;
925             VariableListSP comp_unit_varlist_sp(
926                 sc.comp_unit->GetVariableList(can_create));
927             if (comp_unit_varlist_sp) {
928               size_t count = comp_unit_varlist_sp->GetSize();
929               if (count > 0) {
930                 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
931                 success = true;
932               }
933             }
934           }
935         }
936         if (!success) {
937           if (frame) {
938             if (comp_unit)
939               result.AppendErrorWithFormatv(
940                   "no global variables in current compile unit: {0}\n",
941                   comp_unit->GetPrimaryFile());
942             else
943               result.AppendErrorWithFormat(
944                   "no debug information for frame %u\n",
945                   frame->GetFrameIndex());
946           } else
947             result.AppendError("'target variable' takes one or more global "
948                                "variable names as arguments\n");
949           result.SetStatus(eReturnStatusFailed);
950         }
951       } else {
952         SymbolContextList sc_list;
953         // We have one or more compile unit or shlib
954         if (num_shlibs > 0) {
955           for (size_t shlib_idx = 0; shlib_idx < num_shlibs; ++shlib_idx) {
956             const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));
957             ModuleSpec module_spec(module_file);
958 
959             ModuleSP module_sp(
960                 target->GetImages().FindFirstModule(module_spec));
961             if (module_sp) {
962               if (num_compile_units > 0) {
963                 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
964                   module_sp->FindCompileUnits(
965                       compile_units.GetFileSpecAtIndex(cu_idx), sc_list);
966               } else {
967                 SymbolContext sc;
968                 sc.module_sp = module_sp;
969                 sc_list.Append(sc);
970               }
971             } else {
972               // Didn't find matching shlib/module in target...
973               result.AppendErrorWithFormat(
974                   "target doesn't contain the specified shared library: %s\n",
975                   module_file.GetPath().c_str());
976             }
977           }
978         } else {
979           // No shared libraries, we just want to find globals for the compile
980           // units files that were specified
981           for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
982             target->GetImages().FindCompileUnits(
983                 compile_units.GetFileSpecAtIndex(cu_idx), sc_list);
984         }
985 
986         const uint32_t num_scs = sc_list.GetSize();
987         if (num_scs > 0) {
988           SymbolContext sc;
989           for (uint32_t sc_idx = 0; sc_idx < num_scs; ++sc_idx) {
990             if (sc_list.GetContextAtIndex(sc_idx, sc)) {
991               if (sc.comp_unit) {
992                 const bool can_create = true;
993                 VariableListSP comp_unit_varlist_sp(
994                     sc.comp_unit->GetVariableList(can_create));
995                 if (comp_unit_varlist_sp)
996                   DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,
997                                          s);
998               } else if (sc.module_sp) {
999                 // Get all global variables for this module
1000                 lldb_private::RegularExpression all_globals_regex(
1001                     llvm::StringRef(
1002                         ".")); // Any global with at least one character
1003                 VariableList variable_list;
1004                 sc.module_sp->FindGlobalVariables(all_globals_regex, UINT32_MAX,
1005                                                   variable_list);
1006                 DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s);
1007               }
1008             }
1009           }
1010         }
1011       }
1012     }
1013 
1014     if (m_interpreter.TruncationWarningNecessary()) {
1015       result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
1016                                       m_cmd_name.c_str());
1017       m_interpreter.TruncationWarningGiven();
1018     }
1019 
1020     return result.Succeeded();
1021   }
1022 
1023   OptionGroupOptions m_option_group;
1024   OptionGroupVariable m_option_variable;
1025   OptionGroupFormat m_option_format;
1026   OptionGroupFileList m_option_compile_units;
1027   OptionGroupFileList m_option_shared_libraries;
1028   OptionGroupValueObjectDisplay m_varobj_options;
1029 };
1030 
1031 #pragma mark CommandObjectTargetModulesSearchPathsAdd
1032 
1033 class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed {
1034 public:
1035   CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter &interpreter)
1036       : CommandObjectParsed(interpreter, "target modules search-paths add",
1037                             "Add new image search paths substitution pairs to "
1038                             "the current target.",
1039                             nullptr, eCommandRequiresTarget) {
1040     CommandArgumentEntry arg;
1041     CommandArgumentData old_prefix_arg;
1042     CommandArgumentData new_prefix_arg;
1043 
1044     // Define the first variant of this arg pair.
1045     old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1046     old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1047 
1048     // Define the first variant of this arg pair.
1049     new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1050     new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1051 
1052     // There are two required arguments that must always occur together, i.e.
1053     // an argument "pair".  Because they must always occur together, they are
1054     // treated as two variants of one argument rather than two independent
1055     // arguments.  Push them both into the first argument position for
1056     // m_arguments...
1057 
1058     arg.push_back(old_prefix_arg);
1059     arg.push_back(new_prefix_arg);
1060 
1061     m_arguments.push_back(arg);
1062   }
1063 
1064   ~CommandObjectTargetModulesSearchPathsAdd() override = default;
1065 
1066 protected:
1067   bool DoExecute(Args &command, CommandReturnObject &result) override {
1068     Target *target = &GetSelectedTarget();
1069     const size_t argc = command.GetArgumentCount();
1070     if (argc & 1) {
1071       result.AppendError("add requires an even number of arguments\n");
1072       result.SetStatus(eReturnStatusFailed);
1073     } else {
1074       for (size_t i = 0; i < argc; i += 2) {
1075         const char *from = command.GetArgumentAtIndex(i);
1076         const char *to = command.GetArgumentAtIndex(i + 1);
1077 
1078         if (from[0] && to[0]) {
1079           Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
1080           if (log) {
1081             LLDB_LOGF(log,
1082                       "target modules search path adding ImageSearchPath "
1083                       "pair: '%s' -> '%s'",
1084                       from, to);
1085           }
1086           bool last_pair = ((argc - i) == 2);
1087           target->GetImageSearchPathList().Append(
1088               ConstString(from), ConstString(to),
1089               last_pair); // Notify if this is the last pair
1090           result.SetStatus(eReturnStatusSuccessFinishNoResult);
1091         } else {
1092           if (from[0])
1093             result.AppendError("<path-prefix> can't be empty\n");
1094           else
1095             result.AppendError("<new-path-prefix> can't be empty\n");
1096           result.SetStatus(eReturnStatusFailed);
1097         }
1098       }
1099     }
1100     return result.Succeeded();
1101   }
1102 };
1103 
1104 #pragma mark CommandObjectTargetModulesSearchPathsClear
1105 
1106 class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed {
1107 public:
1108   CommandObjectTargetModulesSearchPathsClear(CommandInterpreter &interpreter)
1109       : CommandObjectParsed(interpreter, "target modules search-paths clear",
1110                             "Clear all current image search path substitution "
1111                             "pairs from the current target.",
1112                             "target modules search-paths clear",
1113                             eCommandRequiresTarget) {}
1114 
1115   ~CommandObjectTargetModulesSearchPathsClear() override = default;
1116 
1117 protected:
1118   bool DoExecute(Args &command, CommandReturnObject &result) override {
1119     Target *target = &GetSelectedTarget();
1120     bool notify = true;
1121     target->GetImageSearchPathList().Clear(notify);
1122     result.SetStatus(eReturnStatusSuccessFinishNoResult);
1123     return result.Succeeded();
1124   }
1125 };
1126 
1127 #pragma mark CommandObjectTargetModulesSearchPathsInsert
1128 
1129 class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed {
1130 public:
1131   CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter &interpreter)
1132       : CommandObjectParsed(interpreter, "target modules search-paths insert",
1133                             "Insert a new image search path substitution pair "
1134                             "into the current target at the specified index.",
1135                             nullptr, eCommandRequiresTarget) {
1136     CommandArgumentEntry arg1;
1137     CommandArgumentEntry arg2;
1138     CommandArgumentData index_arg;
1139     CommandArgumentData old_prefix_arg;
1140     CommandArgumentData new_prefix_arg;
1141 
1142     // Define the first and only variant of this arg.
1143     index_arg.arg_type = eArgTypeIndex;
1144     index_arg.arg_repetition = eArgRepeatPlain;
1145 
1146     // Put the one and only variant into the first arg for m_arguments:
1147     arg1.push_back(index_arg);
1148 
1149     // Define the first variant of this arg pair.
1150     old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1151     old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1152 
1153     // Define the first variant of this arg pair.
1154     new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1155     new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1156 
1157     // There are two required arguments that must always occur together, i.e.
1158     // an argument "pair".  Because they must always occur together, they are
1159     // treated as two variants of one argument rather than two independent
1160     // arguments.  Push them both into the same argument position for
1161     // m_arguments...
1162 
1163     arg2.push_back(old_prefix_arg);
1164     arg2.push_back(new_prefix_arg);
1165 
1166     // Add arguments to m_arguments.
1167     m_arguments.push_back(arg1);
1168     m_arguments.push_back(arg2);
1169   }
1170 
1171   ~CommandObjectTargetModulesSearchPathsInsert() override = default;
1172 
1173 protected:
1174   bool DoExecute(Args &command, CommandReturnObject &result) override {
1175     Target *target = &GetSelectedTarget();
1176     size_t argc = command.GetArgumentCount();
1177     // check for at least 3 arguments and an odd number of parameters
1178     if (argc >= 3 && argc & 1) {
1179       bool success = false;
1180 
1181       uint32_t insert_idx = StringConvert::ToUInt32(
1182           command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
1183 
1184       if (!success) {
1185         result.AppendErrorWithFormat(
1186             "<index> parameter is not an integer: '%s'.\n",
1187             command.GetArgumentAtIndex(0));
1188         result.SetStatus(eReturnStatusFailed);
1189         return result.Succeeded();
1190       }
1191 
1192       // shift off the index
1193       command.Shift();
1194       argc = command.GetArgumentCount();
1195 
1196       for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) {
1197         const char *from = command.GetArgumentAtIndex(i);
1198         const char *to = command.GetArgumentAtIndex(i + 1);
1199 
1200         if (from[0] && to[0]) {
1201           bool last_pair = ((argc - i) == 2);
1202           target->GetImageSearchPathList().Insert(
1203               ConstString(from), ConstString(to), insert_idx, last_pair);
1204           result.SetStatus(eReturnStatusSuccessFinishNoResult);
1205         } else {
1206           if (from[0])
1207             result.AppendError("<path-prefix> can't be empty\n");
1208           else
1209             result.AppendError("<new-path-prefix> can't be empty\n");
1210           result.SetStatus(eReturnStatusFailed);
1211           return false;
1212         }
1213       }
1214     } else {
1215       result.AppendError("insert requires at least three arguments\n");
1216       result.SetStatus(eReturnStatusFailed);
1217       return result.Succeeded();
1218     }
1219     return result.Succeeded();
1220   }
1221 };
1222 
1223 #pragma mark CommandObjectTargetModulesSearchPathsList
1224 
1225 class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed {
1226 public:
1227   CommandObjectTargetModulesSearchPathsList(CommandInterpreter &interpreter)
1228       : CommandObjectParsed(interpreter, "target modules search-paths list",
1229                             "List all current image search path substitution "
1230                             "pairs in the current target.",
1231                             "target modules search-paths list",
1232                             eCommandRequiresTarget) {}
1233 
1234   ~CommandObjectTargetModulesSearchPathsList() override = default;
1235 
1236 protected:
1237   bool DoExecute(Args &command, CommandReturnObject &result) override {
1238     Target *target = &GetSelectedTarget();
1239     if (command.GetArgumentCount() != 0) {
1240       result.AppendError("list takes no arguments\n");
1241       result.SetStatus(eReturnStatusFailed);
1242       return result.Succeeded();
1243     }
1244 
1245     target->GetImageSearchPathList().Dump(&result.GetOutputStream());
1246     result.SetStatus(eReturnStatusSuccessFinishResult);
1247     return result.Succeeded();
1248   }
1249 };
1250 
1251 #pragma mark CommandObjectTargetModulesSearchPathsQuery
1252 
1253 class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed {
1254 public:
1255   CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter &interpreter)
1256       : CommandObjectParsed(
1257             interpreter, "target modules search-paths query",
1258             "Transform a path using the first applicable image search path.",
1259             nullptr, eCommandRequiresTarget) {
1260     CommandArgumentEntry arg;
1261     CommandArgumentData path_arg;
1262 
1263     // Define the first (and only) variant of this arg.
1264     path_arg.arg_type = eArgTypeDirectoryName;
1265     path_arg.arg_repetition = eArgRepeatPlain;
1266 
1267     // There is only one variant this argument could be; put it into the
1268     // argument entry.
1269     arg.push_back(path_arg);
1270 
1271     // Push the data for the first argument into the m_arguments vector.
1272     m_arguments.push_back(arg);
1273   }
1274 
1275   ~CommandObjectTargetModulesSearchPathsQuery() override = default;
1276 
1277 protected:
1278   bool DoExecute(Args &command, CommandReturnObject &result) override {
1279     Target *target = &GetSelectedTarget();
1280     if (command.GetArgumentCount() != 1) {
1281       result.AppendError("query requires one argument\n");
1282       result.SetStatus(eReturnStatusFailed);
1283       return result.Succeeded();
1284     }
1285 
1286     ConstString orig(command.GetArgumentAtIndex(0));
1287     ConstString transformed;
1288     if (target->GetImageSearchPathList().RemapPath(orig, transformed))
1289       result.GetOutputStream().Printf("%s\n", transformed.GetCString());
1290     else
1291       result.GetOutputStream().Printf("%s\n", orig.GetCString());
1292 
1293     result.SetStatus(eReturnStatusSuccessFinishResult);
1294     return result.Succeeded();
1295   }
1296 };
1297 
1298 // Static Helper functions
1299 static void DumpModuleArchitecture(Stream &strm, Module *module,
1300                                    bool full_triple, uint32_t width) {
1301   if (module) {
1302     StreamString arch_strm;
1303 
1304     if (full_triple)
1305       module->GetArchitecture().DumpTriple(arch_strm.AsRawOstream());
1306     else
1307       arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
1308     std::string arch_str = std::string(arch_strm.GetString());
1309 
1310     if (width)
1311       strm.Printf("%-*s", width, arch_str.c_str());
1312     else
1313       strm.PutCString(arch_str);
1314   }
1315 }
1316 
1317 static void DumpModuleUUID(Stream &strm, Module *module) {
1318   if (module && module->GetUUID().IsValid())
1319     module->GetUUID().Dump(&strm);
1320   else
1321     strm.PutCString("                                    ");
1322 }
1323 
1324 static uint32_t DumpCompileUnitLineTable(CommandInterpreter &interpreter,
1325                                          Stream &strm, Module *module,
1326                                          const FileSpec &file_spec,
1327                                          lldb::DescriptionLevel desc_level) {
1328   uint32_t num_matches = 0;
1329   if (module) {
1330     SymbolContextList sc_list;
1331     num_matches = module->ResolveSymbolContextsForFileSpec(
1332         file_spec, 0, false, eSymbolContextCompUnit, sc_list);
1333 
1334     for (uint32_t i = 0; i < num_matches; ++i) {
1335       SymbolContext sc;
1336       if (sc_list.GetContextAtIndex(i, sc)) {
1337         if (i > 0)
1338           strm << "\n\n";
1339 
1340         strm << "Line table for " << sc.comp_unit->GetPrimaryFile() << " in `"
1341              << module->GetFileSpec().GetFilename() << "\n";
1342         LineTable *line_table = sc.comp_unit->GetLineTable();
1343         if (line_table)
1344           line_table->GetDescription(
1345               &strm, interpreter.GetExecutionContext().GetTargetPtr(),
1346               desc_level);
1347         else
1348           strm << "No line table";
1349       }
1350     }
1351   }
1352   return num_matches;
1353 }
1354 
1355 static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr,
1356                          uint32_t width) {
1357   if (file_spec_ptr) {
1358     if (width > 0) {
1359       std::string fullpath = file_spec_ptr->GetPath();
1360       strm.Printf("%-*s", width, fullpath.c_str());
1361       return;
1362     } else {
1363       file_spec_ptr->Dump(strm.AsRawOstream());
1364       return;
1365     }
1366   }
1367   // Keep the width spacing correct if things go wrong...
1368   if (width > 0)
1369     strm.Printf("%-*s", width, "");
1370 }
1371 
1372 static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr,
1373                           uint32_t width) {
1374   if (file_spec_ptr) {
1375     if (width > 0)
1376       strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
1377     else
1378       file_spec_ptr->GetDirectory().Dump(&strm);
1379     return;
1380   }
1381   // Keep the width spacing correct if things go wrong...
1382   if (width > 0)
1383     strm.Printf("%-*s", width, "");
1384 }
1385 
1386 static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,
1387                          uint32_t width) {
1388   if (file_spec_ptr) {
1389     if (width > 0)
1390       strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
1391     else
1392       file_spec_ptr->GetFilename().Dump(&strm);
1393     return;
1394   }
1395   // Keep the width spacing correct if things go wrong...
1396   if (width > 0)
1397     strm.Printf("%-*s", width, "");
1398 }
1399 
1400 static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
1401   size_t num_dumped = 0;
1402   std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
1403   const size_t num_modules = module_list.GetSize();
1404   if (num_modules > 0) {
1405     strm.Printf("Dumping headers for %" PRIu64 " module(s).\n",
1406                 static_cast<uint64_t>(num_modules));
1407     strm.IndentMore();
1408     for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1409       Module *module = module_list.GetModulePointerAtIndexUnlocked(image_idx);
1410       if (module) {
1411         if (num_dumped++ > 0) {
1412           strm.EOL();
1413           strm.EOL();
1414         }
1415         ObjectFile *objfile = module->GetObjectFile();
1416         if (objfile)
1417           objfile->Dump(&strm);
1418         else {
1419           strm.Format("No object file for module: {0:F}\n",
1420                       module->GetFileSpec());
1421         }
1422       }
1423     }
1424     strm.IndentLess();
1425   }
1426   return num_dumped;
1427 }
1428 
1429 static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm,
1430                              Module *module, SortOrder sort_order,
1431                              Mangled::NamePreference name_preference) {
1432   if (!module)
1433     return;
1434   if (Symtab *symtab = module->GetSymtab())
1435     symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),
1436                  sort_order, name_preference);
1437 }
1438 
1439 static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,
1440                                Module *module) {
1441   if (module) {
1442     SectionList *section_list = module->GetSectionList();
1443     if (section_list) {
1444       strm.Printf("Sections for '%s' (%s):\n",
1445                   module->GetSpecificationDescription().c_str(),
1446                   module->GetArchitecture().GetArchitectureName());
1447       section_list->Dump(strm.AsRawOstream(), strm.GetIndentLevel() + 2,
1448                          interpreter.GetExecutionContext().GetTargetPtr(), true,
1449                          UINT32_MAX);
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   CommandObjectTargetModules(const CommandObjectTargetModules &) = delete;
4003   const CommandObjectTargetModules &
4004   operator=(const CommandObjectTargetModules &) = delete;
4005 };
4006 
4007 class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
4008 public:
4009   CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter)
4010       : CommandObjectParsed(
4011             interpreter, "target symbols add",
4012             "Add a debug symbol file to one of the target's current modules by "
4013             "specifying a path to a debug symbols file or by using the options "
4014             "to specify a module.",
4015             "target symbols add <cmd-options> [<symfile>]",
4016             eCommandRequiresTarget),
4017         m_option_group(),
4018         m_file_option(
4019             LLDB_OPT_SET_1, false, "shlib", 's',
4020             CommandCompletions::eModuleCompletion, eArgTypeShlibName,
4021             "Locate the debug symbols for the shared library specified by "
4022             "name."),
4023         m_current_frame_option(
4024             LLDB_OPT_SET_2, false, "frame", 'F',
4025             "Locate the debug symbols for the currently selected frame.",
4026             false, true)
4027 
4028   {
4029     m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
4030                           LLDB_OPT_SET_1);
4031     m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
4032     m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2,
4033                           LLDB_OPT_SET_2);
4034     m_option_group.Finalize();
4035   }
4036 
4037   ~CommandObjectTargetSymbolsAdd() override = default;
4038 
4039   void
4040   HandleArgumentCompletion(CompletionRequest &request,
4041                            OptionElementVector &opt_element_vector) override {
4042     CommandCompletions::InvokeCommonCompletionCallbacks(
4043         GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
4044         request, nullptr);
4045   }
4046 
4047   Options *GetOptions() override { return &m_option_group; }
4048 
4049 protected:
4050   bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,
4051                         CommandReturnObject &result) {
4052     const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
4053     if (!symbol_fspec) {
4054       result.AppendError(
4055           "one or more executable image paths must be specified");
4056       result.SetStatus(eReturnStatusFailed);
4057       return false;
4058     }
4059 
4060     char symfile_path[PATH_MAX];
4061     symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));
4062 
4063     if (!module_spec.GetUUID().IsValid()) {
4064       if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
4065         module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
4066     }
4067 
4068     // Now module_spec represents a symbol file for a module that might exist
4069     // in the current target.  Let's find possible matches.
4070     ModuleList matching_modules;
4071 
4072     // First extract all module specs from the symbol file
4073     lldb_private::ModuleSpecList symfile_module_specs;
4074     if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(),
4075                                             0, 0, symfile_module_specs)) {
4076       // Now extract the module spec that matches the target architecture
4077       ModuleSpec target_arch_module_spec;
4078       ModuleSpec symfile_module_spec;
4079       target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
4080       if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,
4081                                                       symfile_module_spec)) {
4082         if (symfile_module_spec.GetUUID().IsValid()) {
4083           // It has a UUID, look for this UUID in the target modules
4084           ModuleSpec symfile_uuid_module_spec;
4085           symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4086           target->GetImages().FindModules(symfile_uuid_module_spec,
4087                                           matching_modules);
4088         }
4089       }
4090 
4091       if (matching_modules.IsEmpty()) {
4092         // No matches yet.  Iterate through the module specs to find a UUID
4093         // value that we can match up to an image in our target.
4094         const size_t num_symfile_module_specs = symfile_module_specs.GetSize();
4095         for (size_t i = 0;
4096              i < num_symfile_module_specs && matching_modules.IsEmpty(); ++i) {
4097           if (symfile_module_specs.GetModuleSpecAtIndex(
4098                   i, symfile_module_spec)) {
4099             if (symfile_module_spec.GetUUID().IsValid()) {
4100               // It has a UUID.  Look for this UUID in the target modules.
4101               ModuleSpec symfile_uuid_module_spec;
4102               symfile_uuid_module_spec.GetUUID() =
4103                   symfile_module_spec.GetUUID();
4104               target->GetImages().FindModules(symfile_uuid_module_spec,
4105                                               matching_modules);
4106             }
4107           }
4108         }
4109       }
4110     }
4111 
4112     // Just try to match up the file by basename if we have no matches at
4113     // this point.  For example, module foo might have symbols in foo.debug.
4114     if (matching_modules.IsEmpty())
4115       target->GetImages().FindModules(module_spec, matching_modules);
4116 
4117     while (matching_modules.IsEmpty()) {
4118       ConstString filename_no_extension(
4119           module_spec.GetFileSpec().GetFileNameStrippingExtension());
4120       // Empty string returned, let's bail
4121       if (!filename_no_extension)
4122         break;
4123 
4124       // Check if there was no extension to strip and the basename is the same
4125       if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
4126         break;
4127 
4128       // Replace basename with one fewer extension
4129       module_spec.GetFileSpec().GetFilename() = filename_no_extension;
4130       target->GetImages().FindModules(module_spec, matching_modules);
4131     }
4132 
4133     if (matching_modules.GetSize() > 1) {
4134       result.AppendErrorWithFormat("multiple modules match symbol file '%s', "
4135                                    "use the --uuid option to resolve the "
4136                                    "ambiguity.\n",
4137                                    symfile_path);
4138       result.SetStatus(eReturnStatusFailed);
4139       return false;
4140     }
4141 
4142     if (matching_modules.GetSize() == 1) {
4143       ModuleSP module_sp(matching_modules.GetModuleAtIndex(0));
4144 
4145       // The module has not yet created its symbol vendor, we can just give
4146       // the existing target module the symfile path to use for when it
4147       // decides to create it!
4148       module_sp->SetSymbolFileFileSpec(symbol_fspec);
4149 
4150       SymbolFile *symbol_file =
4151           module_sp->GetSymbolFile(true, &result.GetErrorStream());
4152       if (symbol_file) {
4153         ObjectFile *object_file = symbol_file->GetObjectFile();
4154         if (object_file && object_file->GetFileSpec() == symbol_fspec) {
4155           // Provide feedback that the symfile has been successfully added.
4156           const FileSpec &module_fs = module_sp->GetFileSpec();
4157           result.AppendMessageWithFormat(
4158               "symbol file '%s' has been added to '%s'\n", symfile_path,
4159               module_fs.GetPath().c_str());
4160 
4161           // Let clients know something changed in the module if it is
4162           // currently loaded
4163           ModuleList module_list;
4164           module_list.Append(module_sp);
4165           target->SymbolsDidLoad(module_list);
4166 
4167           // Make sure we load any scripting resources that may be embedded
4168           // in the debug info files in case the platform supports that.
4169           Status error;
4170           StreamString feedback_stream;
4171           module_sp->LoadScriptingResourceInTarget(target, error,
4172                                                    &feedback_stream);
4173           if (error.Fail() && error.AsCString())
4174             result.AppendWarningWithFormat(
4175                 "unable to load scripting data for module %s - error "
4176                 "reported was %s",
4177                 module_sp->GetFileSpec()
4178                     .GetFileNameStrippingExtension()
4179                     .GetCString(),
4180                 error.AsCString());
4181           else if (feedback_stream.GetSize())
4182             result.AppendWarning(feedback_stream.GetData());
4183 
4184           flush = true;
4185           result.SetStatus(eReturnStatusSuccessFinishResult);
4186           return true;
4187         }
4188       }
4189       // Clear the symbol file spec if anything went wrong
4190       module_sp->SetSymbolFileFileSpec(FileSpec());
4191     }
4192 
4193     StreamString ss_symfile_uuid;
4194     if (module_spec.GetUUID().IsValid()) {
4195       ss_symfile_uuid << " (";
4196       module_spec.GetUUID().Dump(&ss_symfile_uuid);
4197       ss_symfile_uuid << ')';
4198     }
4199     result.AppendErrorWithFormat(
4200         "symbol file '%s'%s does not match any existing module%s\n",
4201         symfile_path, ss_symfile_uuid.GetData(),
4202         !llvm::sys::fs::is_regular_file(symbol_fspec.GetPath())
4203             ? "\n       please specify the full path to the symbol file"
4204             : "");
4205     result.SetStatus(eReturnStatusFailed);
4206     return false;
4207   }
4208 
4209   bool DoExecute(Args &args, CommandReturnObject &result) override {
4210     Target *target = m_exe_ctx.GetTargetPtr();
4211     result.SetStatus(eReturnStatusFailed);
4212     bool flush = false;
4213     ModuleSpec module_spec;
4214     const bool uuid_option_set =
4215         m_uuid_option_group.GetOptionValue().OptionWasSet();
4216     const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4217     const bool frame_option_set =
4218         m_current_frame_option.GetOptionValue().OptionWasSet();
4219     const size_t argc = args.GetArgumentCount();
4220 
4221     if (argc == 0) {
4222       if (uuid_option_set || file_option_set || frame_option_set) {
4223         bool success = false;
4224         bool error_set = false;
4225         if (frame_option_set) {
4226           Process *process = m_exe_ctx.GetProcessPtr();
4227           if (process) {
4228             const StateType process_state = process->GetState();
4229             if (StateIsStoppedState(process_state, true)) {
4230               StackFrame *frame = m_exe_ctx.GetFramePtr();
4231               if (frame) {
4232                 ModuleSP frame_module_sp(
4233                     frame->GetSymbolContext(eSymbolContextModule).module_sp);
4234                 if (frame_module_sp) {
4235                   if (FileSystem::Instance().Exists(
4236                           frame_module_sp->GetPlatformFileSpec())) {
4237                     module_spec.GetArchitecture() =
4238                         frame_module_sp->GetArchitecture();
4239                     module_spec.GetFileSpec() =
4240                         frame_module_sp->GetPlatformFileSpec();
4241                   }
4242                   module_spec.GetUUID() = frame_module_sp->GetUUID();
4243                   success = module_spec.GetUUID().IsValid() ||
4244                             module_spec.GetFileSpec();
4245                 } else {
4246                   result.AppendError("frame has no module");
4247                   error_set = true;
4248                 }
4249               } else {
4250                 result.AppendError("invalid current frame");
4251                 error_set = true;
4252               }
4253             } else {
4254               result.AppendErrorWithFormat("process is not stopped: %s",
4255                                            StateAsCString(process_state));
4256               error_set = true;
4257             }
4258           } else {
4259             result.AppendError(
4260                 "a process must exist in order to use the --frame option");
4261             error_set = true;
4262           }
4263         } else {
4264           if (uuid_option_set) {
4265             module_spec.GetUUID() =
4266                 m_uuid_option_group.GetOptionValue().GetCurrentValue();
4267             success |= module_spec.GetUUID().IsValid();
4268           } else if (file_option_set) {
4269             module_spec.GetFileSpec() =
4270                 m_file_option.GetOptionValue().GetCurrentValue();
4271             ModuleSP module_sp(
4272                 target->GetImages().FindFirstModule(module_spec));
4273             if (module_sp) {
4274               module_spec.GetFileSpec() = module_sp->GetFileSpec();
4275               module_spec.GetPlatformFileSpec() =
4276                   module_sp->GetPlatformFileSpec();
4277               module_spec.GetUUID() = module_sp->GetUUID();
4278               module_spec.GetArchitecture() = module_sp->GetArchitecture();
4279             } else {
4280               module_spec.GetArchitecture() = target->GetArchitecture();
4281             }
4282             success |= module_spec.GetUUID().IsValid() ||
4283                        FileSystem::Instance().Exists(module_spec.GetFileSpec());
4284           }
4285         }
4286 
4287         if (success) {
4288           if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
4289             if (module_spec.GetSymbolFileSpec())
4290               success = AddModuleSymbols(target, module_spec, flush, result);
4291           }
4292         }
4293 
4294         if (!success && !error_set) {
4295           StreamString error_strm;
4296           if (uuid_option_set) {
4297             error_strm.PutCString("unable to find debug symbols for UUID ");
4298             module_spec.GetUUID().Dump(&error_strm);
4299           } else if (file_option_set) {
4300             error_strm.PutCString(
4301                 "unable to find debug symbols for the executable file ");
4302             error_strm << module_spec.GetFileSpec();
4303           } else if (frame_option_set) {
4304             error_strm.PutCString(
4305                 "unable to find debug symbols for the current frame");
4306           }
4307           result.AppendError(error_strm.GetString());
4308         }
4309       } else {
4310         result.AppendError("one or more symbol file paths must be specified, "
4311                            "or options must be specified");
4312       }
4313     } else {
4314       if (uuid_option_set) {
4315         result.AppendError("specify either one or more paths to symbol files "
4316                            "or use the --uuid option without arguments");
4317       } else if (frame_option_set) {
4318         result.AppendError("specify either one or more paths to symbol files "
4319                            "or use the --frame option without arguments");
4320       } else if (file_option_set && argc > 1) {
4321         result.AppendError("specify at most one symbol file path when "
4322                            "--shlib option is set");
4323       } else {
4324         PlatformSP platform_sp(target->GetPlatform());
4325 
4326         for (auto &entry : args.entries()) {
4327           if (!entry.ref().empty()) {
4328             auto &symbol_file_spec = module_spec.GetSymbolFileSpec();
4329             symbol_file_spec.SetFile(entry.ref(), FileSpec::Style::native);
4330             FileSystem::Instance().Resolve(symbol_file_spec);
4331             if (file_option_set) {
4332               module_spec.GetFileSpec() =
4333                   m_file_option.GetOptionValue().GetCurrentValue();
4334             }
4335             if (platform_sp) {
4336               FileSpec symfile_spec;
4337               if (platform_sp
4338                       ->ResolveSymbolFile(*target, module_spec, symfile_spec)
4339                       .Success())
4340                 module_spec.GetSymbolFileSpec() = symfile_spec;
4341             }
4342 
4343             ArchSpec arch;
4344             bool symfile_exists =
4345                 FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec());
4346 
4347             if (symfile_exists) {
4348               if (!AddModuleSymbols(target, module_spec, flush, result))
4349                 break;
4350             } else {
4351               std::string resolved_symfile_path =
4352                   module_spec.GetSymbolFileSpec().GetPath();
4353               if (resolved_symfile_path != entry.ref()) {
4354                 result.AppendErrorWithFormat(
4355                     "invalid module path '%s' with resolved path '%s'\n",
4356                     entry.c_str(), resolved_symfile_path.c_str());
4357                 break;
4358               }
4359               result.AppendErrorWithFormat("invalid module path '%s'\n",
4360                                            entry.c_str());
4361               break;
4362             }
4363           }
4364         }
4365       }
4366     }
4367 
4368     if (flush) {
4369       Process *process = m_exe_ctx.GetProcessPtr();
4370       if (process)
4371         process->Flush();
4372     }
4373     return result.Succeeded();
4374   }
4375 
4376   OptionGroupOptions m_option_group;
4377   OptionGroupUUID m_uuid_option_group;
4378   OptionGroupFile m_file_option;
4379   OptionGroupBoolean m_current_frame_option;
4380 };
4381 
4382 #pragma mark CommandObjectTargetSymbols
4383 
4384 // CommandObjectTargetSymbols
4385 
4386 class CommandObjectTargetSymbols : public CommandObjectMultiword {
4387 public:
4388   // Constructors and Destructors
4389   CommandObjectTargetSymbols(CommandInterpreter &interpreter)
4390       : CommandObjectMultiword(
4391             interpreter, "target symbols",
4392             "Commands for adding and managing debug symbol files.",
4393             "target symbols <sub-command> ...") {
4394     LoadSubCommand(
4395         "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));
4396   }
4397 
4398   ~CommandObjectTargetSymbols() override = default;
4399 
4400 private:
4401   // For CommandObjectTargetModules only
4402   CommandObjectTargetSymbols(const CommandObjectTargetSymbols &) = delete;
4403   const CommandObjectTargetSymbols &
4404   operator=(const CommandObjectTargetSymbols &) = delete;
4405 };
4406 
4407 #pragma mark CommandObjectTargetStopHookAdd
4408 
4409 // CommandObjectTargetStopHookAdd
4410 #define LLDB_OPTIONS_target_stop_hook_add
4411 #include "CommandOptions.inc"
4412 
4413 class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
4414                                        public IOHandlerDelegateMultiline {
4415 public:
4416   class CommandOptions : public Options {
4417   public:
4418     CommandOptions()
4419         : Options(), m_line_start(0), m_line_end(UINT_MAX),
4420           m_func_name_type_mask(eFunctionNameTypeAuto),
4421           m_sym_ctx_specified(false), m_thread_specified(false),
4422           m_use_one_liner(false), m_one_liner() {}
4423 
4424     ~CommandOptions() override = default;
4425 
4426     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
4427       return llvm::makeArrayRef(g_target_stop_hook_add_options);
4428     }
4429 
4430     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
4431                           ExecutionContext *execution_context) override {
4432       Status error;
4433       const int short_option = m_getopt_table[option_idx].val;
4434 
4435       switch (short_option) {
4436       case 'c':
4437         m_class_name = std::string(option_arg);
4438         m_sym_ctx_specified = true;
4439         break;
4440 
4441       case 'e':
4442         if (option_arg.getAsInteger(0, m_line_end)) {
4443           error.SetErrorStringWithFormat("invalid end line number: \"%s\"",
4444                                          option_arg.str().c_str());
4445           break;
4446         }
4447         m_sym_ctx_specified = true;
4448         break;
4449 
4450       case 'G': {
4451         bool value, success;
4452         value = OptionArgParser::ToBoolean(option_arg, false, &success);
4453         if (success) {
4454           m_auto_continue = value;
4455         } else
4456           error.SetErrorStringWithFormat(
4457               "invalid boolean value '%s' passed for -G option",
4458               option_arg.str().c_str());
4459       } break;
4460       case 'l':
4461         if (option_arg.getAsInteger(0, m_line_start)) {
4462           error.SetErrorStringWithFormat("invalid start line number: \"%s\"",
4463                                          option_arg.str().c_str());
4464           break;
4465         }
4466         m_sym_ctx_specified = true;
4467         break;
4468 
4469       case 'i':
4470         m_no_inlines = true;
4471         break;
4472 
4473       case 'n':
4474         m_function_name = std::string(option_arg);
4475         m_func_name_type_mask |= eFunctionNameTypeAuto;
4476         m_sym_ctx_specified = true;
4477         break;
4478 
4479       case 'f':
4480         m_file_name = std::string(option_arg);
4481         m_sym_ctx_specified = true;
4482         break;
4483 
4484       case 's':
4485         m_module_name = std::string(option_arg);
4486         m_sym_ctx_specified = true;
4487         break;
4488 
4489       case 't':
4490         if (option_arg.getAsInteger(0, m_thread_id))
4491           error.SetErrorStringWithFormat("invalid thread id string '%s'",
4492                                          option_arg.str().c_str());
4493         m_thread_specified = true;
4494         break;
4495 
4496       case 'T':
4497         m_thread_name = std::string(option_arg);
4498         m_thread_specified = true;
4499         break;
4500 
4501       case 'q':
4502         m_queue_name = std::string(option_arg);
4503         m_thread_specified = true;
4504         break;
4505 
4506       case 'x':
4507         if (option_arg.getAsInteger(0, m_thread_index))
4508           error.SetErrorStringWithFormat("invalid thread index string '%s'",
4509                                          option_arg.str().c_str());
4510         m_thread_specified = true;
4511         break;
4512 
4513       case 'o':
4514         m_use_one_liner = true;
4515         m_one_liner.push_back(std::string(option_arg));
4516         break;
4517 
4518       default:
4519         llvm_unreachable("Unimplemented option");
4520       }
4521       return error;
4522     }
4523 
4524     void OptionParsingStarting(ExecutionContext *execution_context) override {
4525       m_class_name.clear();
4526       m_function_name.clear();
4527       m_line_start = 0;
4528       m_line_end = UINT_MAX;
4529       m_file_name.clear();
4530       m_module_name.clear();
4531       m_func_name_type_mask = eFunctionNameTypeAuto;
4532       m_thread_id = LLDB_INVALID_THREAD_ID;
4533       m_thread_index = UINT32_MAX;
4534       m_thread_name.clear();
4535       m_queue_name.clear();
4536 
4537       m_no_inlines = false;
4538       m_sym_ctx_specified = false;
4539       m_thread_specified = false;
4540 
4541       m_use_one_liner = false;
4542       m_one_liner.clear();
4543       m_auto_continue = false;
4544     }
4545 
4546     std::string m_class_name;
4547     std::string m_function_name;
4548     uint32_t m_line_start;
4549     uint32_t m_line_end;
4550     std::string m_file_name;
4551     std::string m_module_name;
4552     uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType.
4553     lldb::tid_t m_thread_id;
4554     uint32_t m_thread_index;
4555     std::string m_thread_name;
4556     std::string m_queue_name;
4557     bool m_sym_ctx_specified;
4558     bool m_no_inlines;
4559     bool m_thread_specified;
4560     // Instance variables to hold the values for one_liner options.
4561     bool m_use_one_liner;
4562     std::vector<std::string> m_one_liner;
4563     bool m_auto_continue;
4564   };
4565 
4566   CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
4567       : CommandObjectParsed(interpreter, "target stop-hook add",
4568                             "Add a hook to be executed when the target stops.",
4569                             "target stop-hook add"),
4570         IOHandlerDelegateMultiline("DONE",
4571                                    IOHandlerDelegate::Completion::LLDBCommand),
4572         m_options() {}
4573 
4574   ~CommandObjectTargetStopHookAdd() override = default;
4575 
4576   Options *GetOptions() override { return &m_options; }
4577 
4578 protected:
4579   void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
4580     StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
4581     if (output_sp && interactive) {
4582       output_sp->PutCString(
4583           "Enter your stop hook command(s).  Type 'DONE' to end.\n");
4584       output_sp->Flush();
4585     }
4586   }
4587 
4588   void IOHandlerInputComplete(IOHandler &io_handler,
4589                               std::string &line) override {
4590     if (m_stop_hook_sp) {
4591       if (line.empty()) {
4592         StreamFileSP error_sp(io_handler.GetErrorStreamFileSP());
4593         if (error_sp) {
4594           error_sp->Printf("error: stop hook #%" PRIu64
4595                            " aborted, no commands.\n",
4596                            m_stop_hook_sp->GetID());
4597           error_sp->Flush();
4598         }
4599         Target *target = GetDebugger().GetSelectedTarget().get();
4600         if (target)
4601           target->RemoveStopHookByID(m_stop_hook_sp->GetID());
4602       } else {
4603         m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
4604         StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
4605         if (output_sp) {
4606           output_sp->Printf("Stop hook #%" PRIu64 " added.\n",
4607                             m_stop_hook_sp->GetID());
4608           output_sp->Flush();
4609         }
4610       }
4611       m_stop_hook_sp.reset();
4612     }
4613     io_handler.SetIsDone(true);
4614   }
4615 
4616   bool DoExecute(Args &command, CommandReturnObject &result) override {
4617     m_stop_hook_sp.reset();
4618 
4619     Target &target = GetSelectedOrDummyTarget();
4620     Target::StopHookSP new_hook_sp = target.CreateStopHook();
4621 
4622     //  First step, make the specifier.
4623     std::unique_ptr<SymbolContextSpecifier> specifier_up;
4624     if (m_options.m_sym_ctx_specified) {
4625       specifier_up.reset(
4626           new SymbolContextSpecifier(GetDebugger().GetSelectedTarget()));
4627 
4628       if (!m_options.m_module_name.empty()) {
4629         specifier_up->AddSpecification(
4630             m_options.m_module_name.c_str(),
4631             SymbolContextSpecifier::eModuleSpecified);
4632       }
4633 
4634       if (!m_options.m_class_name.empty()) {
4635         specifier_up->AddSpecification(
4636             m_options.m_class_name.c_str(),
4637             SymbolContextSpecifier::eClassOrNamespaceSpecified);
4638       }
4639 
4640       if (!m_options.m_file_name.empty()) {
4641         specifier_up->AddSpecification(m_options.m_file_name.c_str(),
4642                                        SymbolContextSpecifier::eFileSpecified);
4643       }
4644 
4645       if (m_options.m_line_start != 0) {
4646         specifier_up->AddLineSpecification(
4647             m_options.m_line_start,
4648             SymbolContextSpecifier::eLineStartSpecified);
4649       }
4650 
4651       if (m_options.m_line_end != UINT_MAX) {
4652         specifier_up->AddLineSpecification(
4653             m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
4654       }
4655 
4656       if (!m_options.m_function_name.empty()) {
4657         specifier_up->AddSpecification(
4658             m_options.m_function_name.c_str(),
4659             SymbolContextSpecifier::eFunctionSpecified);
4660       }
4661     }
4662 
4663     if (specifier_up)
4664       new_hook_sp->SetSpecifier(specifier_up.release());
4665 
4666     // Next see if any of the thread options have been entered:
4667 
4668     if (m_options.m_thread_specified) {
4669       ThreadSpec *thread_spec = new ThreadSpec();
4670 
4671       if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) {
4672         thread_spec->SetTID(m_options.m_thread_id);
4673       }
4674 
4675       if (m_options.m_thread_index != UINT32_MAX)
4676         thread_spec->SetIndex(m_options.m_thread_index);
4677 
4678       if (!m_options.m_thread_name.empty())
4679         thread_spec->SetName(m_options.m_thread_name.c_str());
4680 
4681       if (!m_options.m_queue_name.empty())
4682         thread_spec->SetQueueName(m_options.m_queue_name.c_str());
4683 
4684       new_hook_sp->SetThreadSpecifier(thread_spec);
4685     }
4686 
4687     new_hook_sp->SetAutoContinue(m_options.m_auto_continue);
4688     if (m_options.m_use_one_liner) {
4689       // Use one-liners.
4690       for (auto cmd : m_options.m_one_liner)
4691         new_hook_sp->GetCommandPointer()->AppendString(cmd.c_str());
4692       result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
4693                                      new_hook_sp->GetID());
4694     } else {
4695       m_stop_hook_sp = new_hook_sp;
4696       m_interpreter.GetLLDBCommandsFromIOHandler("> ",   // Prompt
4697                                                  *this); // IOHandlerDelegate
4698     }
4699     result.SetStatus(eReturnStatusSuccessFinishNoResult);
4700 
4701     return result.Succeeded();
4702   }
4703 
4704 private:
4705   CommandOptions m_options;
4706   Target::StopHookSP m_stop_hook_sp;
4707 };
4708 
4709 #pragma mark CommandObjectTargetStopHookDelete
4710 
4711 // CommandObjectTargetStopHookDelete
4712 
4713 class CommandObjectTargetStopHookDelete : public CommandObjectParsed {
4714 public:
4715   CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter)
4716       : CommandObjectParsed(interpreter, "target stop-hook delete",
4717                             "Delete a stop-hook.",
4718                             "target stop-hook delete [<idx>]") {}
4719 
4720   ~CommandObjectTargetStopHookDelete() override = default;
4721 
4722 protected:
4723   bool DoExecute(Args &command, CommandReturnObject &result) override {
4724     Target &target = GetSelectedOrDummyTarget();
4725     // FIXME: see if we can use the breakpoint id style parser?
4726     size_t num_args = command.GetArgumentCount();
4727     if (num_args == 0) {
4728       if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
4729         result.SetStatus(eReturnStatusFailed);
4730         return false;
4731       } else {
4732         target.RemoveAllStopHooks();
4733       }
4734     } else {
4735       bool success;
4736       for (size_t i = 0; i < num_args; i++) {
4737         lldb::user_id_t user_id = StringConvert::ToUInt32(
4738             command.GetArgumentAtIndex(i), 0, 0, &success);
4739         if (!success) {
4740           result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4741                                        command.GetArgumentAtIndex(i));
4742           result.SetStatus(eReturnStatusFailed);
4743           return false;
4744         }
4745         success = target.RemoveStopHookByID(user_id);
4746         if (!success) {
4747           result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4748                                        command.GetArgumentAtIndex(i));
4749           result.SetStatus(eReturnStatusFailed);
4750           return false;
4751         }
4752       }
4753     }
4754     result.SetStatus(eReturnStatusSuccessFinishNoResult);
4755     return result.Succeeded();
4756   }
4757 };
4758 
4759 #pragma mark CommandObjectTargetStopHookEnableDisable
4760 
4761 // CommandObjectTargetStopHookEnableDisable
4762 
4763 class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed {
4764 public:
4765   CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter,
4766                                            bool enable, const char *name,
4767                                            const char *help, const char *syntax)
4768       : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) {
4769   }
4770 
4771   ~CommandObjectTargetStopHookEnableDisable() override = default;
4772 
4773 protected:
4774   bool DoExecute(Args &command, CommandReturnObject &result) override {
4775     Target &target = GetSelectedOrDummyTarget();
4776     // FIXME: see if we can use the breakpoint id style parser?
4777     size_t num_args = command.GetArgumentCount();
4778     bool success;
4779 
4780     if (num_args == 0) {
4781       target.SetAllStopHooksActiveState(m_enable);
4782     } else {
4783       for (size_t i = 0; i < num_args; i++) {
4784         lldb::user_id_t user_id = StringConvert::ToUInt32(
4785             command.GetArgumentAtIndex(i), 0, 0, &success);
4786         if (!success) {
4787           result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4788                                        command.GetArgumentAtIndex(i));
4789           result.SetStatus(eReturnStatusFailed);
4790           return false;
4791         }
4792         success = target.SetStopHookActiveStateByID(user_id, m_enable);
4793         if (!success) {
4794           result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4795                                        command.GetArgumentAtIndex(i));
4796           result.SetStatus(eReturnStatusFailed);
4797           return false;
4798         }
4799       }
4800     }
4801     result.SetStatus(eReturnStatusSuccessFinishNoResult);
4802     return result.Succeeded();
4803   }
4804 
4805 private:
4806   bool m_enable;
4807 };
4808 
4809 #pragma mark CommandObjectTargetStopHookList
4810 
4811 // CommandObjectTargetStopHookList
4812 
4813 class CommandObjectTargetStopHookList : public CommandObjectParsed {
4814 public:
4815   CommandObjectTargetStopHookList(CommandInterpreter &interpreter)
4816       : CommandObjectParsed(interpreter, "target stop-hook list",
4817                             "List all stop-hooks.",
4818                             "target stop-hook list [<type>]") {}
4819 
4820   ~CommandObjectTargetStopHookList() override = default;
4821 
4822 protected:
4823   bool DoExecute(Args &command, CommandReturnObject &result) override {
4824     Target &target = GetSelectedOrDummyTarget();
4825 
4826     size_t num_hooks = target.GetNumStopHooks();
4827     if (num_hooks == 0) {
4828       result.GetOutputStream().PutCString("No stop hooks.\n");
4829     } else {
4830       for (size_t i = 0; i < num_hooks; i++) {
4831         Target::StopHookSP this_hook = target.GetStopHookAtIndex(i);
4832         if (i > 0)
4833           result.GetOutputStream().PutCString("\n");
4834         this_hook->GetDescription(&(result.GetOutputStream()),
4835                                   eDescriptionLevelFull);
4836       }
4837     }
4838     result.SetStatus(eReturnStatusSuccessFinishResult);
4839     return result.Succeeded();
4840   }
4841 };
4842 
4843 #pragma mark CommandObjectMultiwordTargetStopHooks
4844 
4845 // CommandObjectMultiwordTargetStopHooks
4846 
4847 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword {
4848 public:
4849   CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
4850       : CommandObjectMultiword(
4851             interpreter, "target stop-hook",
4852             "Commands for operating on debugger target stop-hooks.",
4853             "target stop-hook <subcommand> [<subcommand-options>]") {
4854     LoadSubCommand("add", CommandObjectSP(
4855                               new CommandObjectTargetStopHookAdd(interpreter)));
4856     LoadSubCommand(
4857         "delete",
4858         CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter)));
4859     LoadSubCommand("disable",
4860                    CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
4861                        interpreter, false, "target stop-hook disable [<id>]",
4862                        "Disable a stop-hook.", "target stop-hook disable")));
4863     LoadSubCommand("enable",
4864                    CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
4865                        interpreter, true, "target stop-hook enable [<id>]",
4866                        "Enable a stop-hook.", "target stop-hook enable")));
4867     LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList(
4868                                interpreter)));
4869   }
4870 
4871   ~CommandObjectMultiwordTargetStopHooks() override = default;
4872 };
4873 
4874 #pragma mark CommandObjectMultiwordTarget
4875 
4876 // CommandObjectMultiwordTarget
4877 
4878 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(
4879     CommandInterpreter &interpreter)
4880     : CommandObjectMultiword(interpreter, "target",
4881                              "Commands for operating on debugger targets.",
4882                              "target <subcommand> [<subcommand-options>]") {
4883   LoadSubCommand("create",
4884                  CommandObjectSP(new CommandObjectTargetCreate(interpreter)));
4885   LoadSubCommand("delete",
4886                  CommandObjectSP(new CommandObjectTargetDelete(interpreter)));
4887   LoadSubCommand("list",
4888                  CommandObjectSP(new CommandObjectTargetList(interpreter)));
4889   LoadSubCommand("select",
4890                  CommandObjectSP(new CommandObjectTargetSelect(interpreter)));
4891   LoadSubCommand("show-launch-environment",
4892                  CommandObjectSP(new CommandObjectTargetShowLaunchEnvironment(
4893                      interpreter)));
4894   LoadSubCommand(
4895       "stop-hook",
4896       CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter)));
4897   LoadSubCommand("modules",
4898                  CommandObjectSP(new CommandObjectTargetModules(interpreter)));
4899   LoadSubCommand("symbols",
4900                  CommandObjectSP(new CommandObjectTargetSymbols(interpreter)));
4901   LoadSubCommand("variable",
4902                  CommandObjectSP(new CommandObjectTargetVariable(interpreter)));
4903 }
4904 
4905 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;
4906