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