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