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