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