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