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