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