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