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