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