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