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