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