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