1 //===-- CommandObjectTarget.cpp ---------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "CommandObjectTarget.h"
11 
12 // C Includes
13 #include <errno.h>
14 
15 // C++ Includes
16 // Other libraries and framework includes
17 // Project includes
18 #include "lldb/Interpreter/Args.h"
19 #include "lldb/Core/Debugger.h"
20 #include "lldb/Core/InputReader.h"
21 #include "lldb/Core/Section.h"
22 #include "lldb/Core/State.h"
23 #include "lldb/Core/Timer.h"
24 #include "lldb/Core/ValueObjectVariable.h"
25 #include "lldb/Interpreter/CommandInterpreter.h"
26 #include "lldb/Interpreter/CommandReturnObject.h"
27 #include "lldb/Interpreter/Options.h"
28 #include "lldb/Interpreter/OptionGroupArchitecture.h"
29 #include "lldb/Interpreter/OptionGroupBoolean.h"
30 #include "lldb/Interpreter/OptionGroupFile.h"
31 #include "lldb/Interpreter/OptionGroupFormat.h"
32 #include "lldb/Interpreter/OptionGroupVariable.h"
33 #include "lldb/Interpreter/OptionGroupPlatform.h"
34 #include "lldb/Interpreter/OptionGroupUInt64.h"
35 #include "lldb/Interpreter/OptionGroupUUID.h"
36 #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
37 #include "lldb/Symbol/LineTable.h"
38 #include "lldb/Symbol/ObjectFile.h"
39 #include "lldb/Symbol/SymbolFile.h"
40 #include "lldb/Symbol/SymbolVendor.h"
41 #include "lldb/Symbol/VariableList.h"
42 #include "lldb/Target/Process.h"
43 #include "lldb/Target/StackFrame.h"
44 #include "lldb/Target/Thread.h"
45 #include "lldb/Target/ThreadSpec.h"
46 
47 using namespace lldb;
48 using namespace lldb_private;
49 
50 
51 
52 static void
53 DumpTargetInfo (uint32_t target_idx, Target *target, const char *prefix_cstr, bool show_stopped_process_status, Stream &strm)
54 {
55     const ArchSpec &target_arch = target->GetArchitecture();
56 
57     Module *exe_module = target->GetExecutableModulePointer();
58     char exe_path[PATH_MAX];
59     bool exe_valid = false;
60     if (exe_module)
61         exe_valid = exe_module->GetFileSpec().GetPath (exe_path, sizeof(exe_path));
62 
63     if (!exe_valid)
64         ::strcpy (exe_path, "<none>");
65 
66     strm.Printf ("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx, exe_path);
67 
68     uint32_t properties = 0;
69     if (target_arch.IsValid())
70     {
71         strm.Printf ("%sarch=%s", properties++ > 0 ? ", " : " ( ", target_arch.GetTriple().str().c_str());
72         properties++;
73     }
74     PlatformSP platform_sp (target->GetPlatform());
75     if (platform_sp)
76         strm.Printf ("%splatform=%s", properties++ > 0 ? ", " : " ( ", platform_sp->GetName());
77 
78     ProcessSP process_sp (target->GetProcessSP());
79     bool show_process_status = false;
80     if (process_sp)
81     {
82         lldb::pid_t pid = process_sp->GetID();
83         StateType state = process_sp->GetState();
84         if (show_stopped_process_status)
85             show_process_status = StateIsStoppedState(state, true);
86         const char *state_cstr = StateAsCString (state);
87         if (pid != LLDB_INVALID_PROCESS_ID)
88             strm.Printf ("%spid=%llu", properties++ > 0 ? ", " : " ( ", pid);
89         strm.Printf ("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
90     }
91     if (properties > 0)
92         strm.PutCString (" )\n");
93     else
94         strm.EOL();
95     if (show_process_status)
96     {
97         const bool only_threads_with_stop_reason = true;
98         const uint32_t start_frame = 0;
99         const uint32_t num_frames = 1;
100         const uint32_t num_frames_with_source = 1;
101         process_sp->GetStatus (strm);
102         process_sp->GetThreadStatus (strm,
103                                      only_threads_with_stop_reason,
104                                      start_frame,
105                                      num_frames,
106                                      num_frames_with_source);
107 
108     }
109 }
110 
111 static uint32_t
112 DumpTargetList (TargetList &target_list, bool show_stopped_process_status, Stream &strm)
113 {
114     const uint32_t num_targets = target_list.GetNumTargets();
115     if (num_targets)
116     {
117         TargetSP selected_target_sp (target_list.GetSelectedTarget());
118         strm.PutCString ("Current targets:\n");
119         for (uint32_t i=0; i<num_targets; ++i)
120         {
121             TargetSP target_sp (target_list.GetTargetAtIndex (i));
122             if (target_sp)
123             {
124                 bool is_selected = target_sp.get() == selected_target_sp.get();
125                 DumpTargetInfo (i,
126                                 target_sp.get(),
127                                 is_selected ? "* " : "  ",
128                                 show_stopped_process_status,
129                                 strm);
130             }
131         }
132     }
133     return num_targets;
134 }
135 #pragma mark CommandObjectTargetCreate
136 
137 //-------------------------------------------------------------------------
138 // "target create"
139 //-------------------------------------------------------------------------
140 
141 class CommandObjectTargetCreate : public CommandObject
142 {
143 public:
144     CommandObjectTargetCreate(CommandInterpreter &interpreter) :
145         CommandObject (interpreter,
146                        "target create",
147                        "Create a target using the argument as the main executable.",
148                        NULL),
149         m_option_group (interpreter),
150         m_arch_option (),
151         m_platform_options(true) // Do include the "--platform" option in the platform settings by passing true
152     {
153         CommandArgumentEntry arg;
154         CommandArgumentData file_arg;
155 
156         // Define the first (and only) variant of this arg.
157             file_arg.arg_type = eArgTypeFilename;
158         file_arg.arg_repetition = eArgRepeatPlain;
159 
160         // There is only one variant this argument could be; put it into the argument entry.
161         arg.push_back (file_arg);
162 
163         // Push the data for the first argument into the m_arguments vector.
164         m_arguments.push_back (arg);
165 
166         m_option_group.Append (&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
167         m_option_group.Append (&m_platform_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
168         m_option_group.Finalize();
169     }
170 
171     ~CommandObjectTargetCreate ()
172     {
173     }
174 
175     Options *
176     GetOptions ()
177     {
178         return &m_option_group;
179     }
180 
181     bool
182     Execute (Args& command, CommandReturnObject &result)
183     {
184         const int argc = command.GetArgumentCount();
185         if (argc == 1)
186         {
187             const char *file_path = command.GetArgumentAtIndex(0);
188             Timer scoped_timer(__PRETTY_FUNCTION__, "(lldb) target create '%s'", file_path);
189             FileSpec file_spec (file_path, true);
190 
191             TargetSP target_sp;
192             Debugger &debugger = m_interpreter.GetDebugger();
193             const char *arch_cstr = m_arch_option.GetArchitectureName();
194             const bool get_dependent_files = true;
195             Error error (debugger.GetTargetList().CreateTarget (debugger,
196                                                                 file_spec,
197                                                                 arch_cstr,
198                                                                 get_dependent_files,
199                                                                 &m_platform_options,
200                                                                 target_sp));
201 
202             if (target_sp)
203             {
204                 debugger.GetTargetList().SetSelectedTarget(target_sp.get());
205                 result.AppendMessageWithFormat ("Current executable set to '%s' (%s).\n", file_path, target_sp->GetArchitecture().GetArchitectureName());
206                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
207             }
208             else
209             {
210                 result.AppendError(error.AsCString());
211                 result.SetStatus (eReturnStatusFailed);
212             }
213         }
214         else
215         {
216             result.AppendErrorWithFormat("'%s' takes exactly one executable path argument.\n", m_cmd_name.c_str());
217             result.SetStatus (eReturnStatusFailed);
218         }
219         return result.Succeeded();
220 
221     }
222 
223     int
224     HandleArgumentCompletion (Args &input,
225                               int &cursor_index,
226                               int &cursor_char_position,
227                               OptionElementVector &opt_element_vector,
228                               int match_start_point,
229                               int max_return_elements,
230                               bool &word_complete,
231                               StringList &matches)
232     {
233         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
234         completion_str.erase (cursor_char_position);
235 
236         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
237                                                              CommandCompletions::eDiskFileCompletion,
238                                                              completion_str.c_str(),
239                                                              match_start_point,
240                                                              max_return_elements,
241                                                              NULL,
242                                                              word_complete,
243                                                              matches);
244         return matches.GetSize();
245     }
246 private:
247     OptionGroupOptions m_option_group;
248     OptionGroupArchitecture m_arch_option;
249     OptionGroupPlatform m_platform_options;
250 
251 };
252 
253 #pragma mark CommandObjectTargetList
254 
255 //----------------------------------------------------------------------
256 // "target list"
257 //----------------------------------------------------------------------
258 
259 class CommandObjectTargetList : public CommandObject
260 {
261 public:
262     CommandObjectTargetList (CommandInterpreter &interpreter) :
263         CommandObject (interpreter,
264                        "target list",
265                        "List all current targets in the current debug session.",
266                        NULL,
267                        0)
268     {
269     }
270 
271     virtual
272     ~CommandObjectTargetList ()
273     {
274     }
275 
276     virtual bool
277     Execute (Args& args, CommandReturnObject &result)
278     {
279         if (args.GetArgumentCount() == 0)
280         {
281             Stream &strm = result.GetOutputStream();
282 
283             bool show_stopped_process_status = false;
284             if (DumpTargetList (m_interpreter.GetDebugger().GetTargetList(), show_stopped_process_status, strm) == 0)
285             {
286                 strm.PutCString ("No targets.\n");
287             }
288             result.SetStatus (eReturnStatusSuccessFinishResult);
289         }
290         else
291         {
292             result.AppendError ("the 'target list' command takes no arguments\n");
293             result.SetStatus (eReturnStatusFailed);
294         }
295         return result.Succeeded();
296     }
297 };
298 
299 
300 #pragma mark CommandObjectTargetSelect
301 
302 //----------------------------------------------------------------------
303 // "target select"
304 //----------------------------------------------------------------------
305 
306 class CommandObjectTargetSelect : public CommandObject
307 {
308 public:
309     CommandObjectTargetSelect (CommandInterpreter &interpreter) :
310         CommandObject (interpreter,
311                        "target select",
312                        "Select a target as the current target by target index.",
313                        NULL,
314                        0)
315     {
316     }
317 
318     virtual
319     ~CommandObjectTargetSelect ()
320     {
321     }
322 
323     virtual bool
324     Execute (Args& args, CommandReturnObject &result)
325     {
326         if (args.GetArgumentCount() == 1)
327         {
328             bool success = false;
329             const char *target_idx_arg = args.GetArgumentAtIndex(0);
330             uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success);
331             if (success)
332             {
333                 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
334                 const uint32_t num_targets = target_list.GetNumTargets();
335                 if (target_idx < num_targets)
336                 {
337                     TargetSP target_sp (target_list.GetTargetAtIndex (target_idx));
338                     if (target_sp)
339                     {
340                         Stream &strm = result.GetOutputStream();
341                         target_list.SetSelectedTarget (target_sp.get());
342                         bool show_stopped_process_status = false;
343                         DumpTargetList (target_list, show_stopped_process_status, strm);
344                         result.SetStatus (eReturnStatusSuccessFinishResult);
345                     }
346                     else
347                     {
348                         result.AppendErrorWithFormat ("target #%u is NULL in target list\n", target_idx);
349                         result.SetStatus (eReturnStatusFailed);
350                     }
351                 }
352                 else
353                 {
354                     result.AppendErrorWithFormat ("index %u is out of range, valid target indexes are 0 - %u\n",
355                                                   target_idx,
356                                                   num_targets - 1);
357                     result.SetStatus (eReturnStatusFailed);
358                 }
359             }
360             else
361             {
362                 result.AppendErrorWithFormat("invalid index string value '%s'\n", target_idx_arg);
363                 result.SetStatus (eReturnStatusFailed);
364             }
365         }
366         else
367         {
368             result.AppendError ("'target select' takes a single argument: a target index\n");
369             result.SetStatus (eReturnStatusFailed);
370         }
371         return result.Succeeded();
372     }
373 };
374 
375 #pragma mark CommandObjectTargetSelect
376 
377 //----------------------------------------------------------------------
378 // "target delete"
379 //----------------------------------------------------------------------
380 
381 class CommandObjectTargetDelete : public CommandObject
382 {
383 public:
384     CommandObjectTargetDelete (CommandInterpreter &interpreter) :
385         CommandObject (interpreter,
386                        "target delete",
387                        "Delete one or more targets by target index.",
388                        NULL,
389                        0),
390         m_option_group (interpreter),
391         m_cleanup_option (LLDB_OPT_SET_1, false, "clean", 'c', 0, eArgTypeNone, "Perform extra cleanup to minimize memory consumption after deleting the target.", false)
392     {
393         m_option_group.Append (&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
394         m_option_group.Finalize();
395     }
396 
397     virtual
398     ~CommandObjectTargetDelete ()
399     {
400     }
401 
402     virtual bool
403     Execute (Args& args, CommandReturnObject &result)
404     {
405         const size_t argc = args.GetArgumentCount();
406         std::vector<TargetSP> delete_target_list;
407         TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
408         bool success = true;
409         TargetSP target_sp;
410         if (argc > 0)
411         {
412             const uint32_t num_targets = target_list.GetNumTargets();
413             for (uint32_t arg_idx = 0; success && arg_idx < argc; ++arg_idx)
414             {
415                 const char *target_idx_arg = args.GetArgumentAtIndex(arg_idx);
416                 uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success);
417                 if (success)
418                 {
419                     if (target_idx < num_targets)
420                     {
421                         target_sp = target_list.GetTargetAtIndex (target_idx);
422                         if (target_sp)
423                         {
424                             delete_target_list.push_back (target_sp);
425                             continue;
426                         }
427                     }
428                     result.AppendErrorWithFormat ("target index %u is out of range, valid target indexes are 0 - %u\n",
429                                                   target_idx,
430                                                   num_targets - 1);
431                     result.SetStatus (eReturnStatusFailed);
432                     success = false;
433                 }
434                 else
435                 {
436                     result.AppendErrorWithFormat("invalid target index '%s'\n", target_idx_arg);
437                     result.SetStatus (eReturnStatusFailed);
438                     success = false;
439                 }
440             }
441 
442         }
443         else
444         {
445             target_sp = target_list.GetSelectedTarget();
446             if (target_sp)
447             {
448                 delete_target_list.push_back (target_sp);
449             }
450             else
451             {
452                 result.AppendErrorWithFormat("no target is currently selected\n");
453                 result.SetStatus (eReturnStatusFailed);
454                 success = false;
455             }
456         }
457         if (success)
458         {
459             const size_t num_targets_to_delete = delete_target_list.size();
460             for (size_t idx = 0; idx < num_targets_to_delete; ++idx)
461             {
462                 target_sp = delete_target_list[idx];
463                 target_list.DeleteTarget(target_sp);
464                 target_sp->Destroy();
465             }
466             // If "--clean" was specified, prune any orphaned shared modules from
467             // the global shared module list
468             if (m_cleanup_option.GetOptionValue ())
469             {
470                 ModuleList::RemoveOrphanSharedModules();
471             }
472             result.GetOutputStream().Printf("%u targets deleted.\n", (uint32_t)num_targets_to_delete);
473             result.SetStatus(eReturnStatusSuccessFinishResult);
474         }
475 
476         return result.Succeeded();
477     }
478 
479     Options *
480     GetOptions ()
481     {
482         return &m_option_group;
483     }
484 
485 protected:
486     OptionGroupOptions m_option_group;
487     OptionGroupBoolean m_cleanup_option;
488 };
489 
490 
491 #pragma mark CommandObjectTargetVariable
492 
493 //----------------------------------------------------------------------
494 // "target variable"
495 //----------------------------------------------------------------------
496 
497 class CommandObjectTargetVariable : public CommandObject
498 {
499 public:
500     CommandObjectTargetVariable (CommandInterpreter &interpreter) :
501         CommandObject (interpreter,
502                        "target variable",
503                        "Read global variable(s) prior to running your binary.",
504                        NULL,
505                        0),
506         m_option_group (interpreter),
507         m_option_variable (false), // Don't include frame options
508         m_option_format (eFormatDefault),
509         m_option_compile_units    (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypePath, "A basename or fullpath to a file that contains global variables. This option can be specified multiple times."),
510         m_option_shared_libraries (LLDB_OPT_SET_1, false, "shlib",'s', 0, eArgTypePath, "A basename or fullpath to a shared library to use in the search for global variables. This option can be specified multiple times."),
511         m_varobj_options()
512     {
513         CommandArgumentEntry arg;
514         CommandArgumentData var_name_arg;
515 
516         // Define the first (and only) variant of this arg.
517         var_name_arg.arg_type = eArgTypeVarName;
518         var_name_arg.arg_repetition = eArgRepeatPlus;
519 
520         // There is only one variant this argument could be; put it into the argument entry.
521         arg.push_back (var_name_arg);
522 
523         // Push the data for the first argument into the m_arguments vector.
524         m_arguments.push_back (arg);
525 
526         m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
527         m_option_group.Append (&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
528         m_option_group.Append (&m_option_format, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1);
529         m_option_group.Append (&m_option_compile_units, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
530         m_option_group.Append (&m_option_shared_libraries, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
531         m_option_group.Finalize();
532     }
533 
534     virtual
535     ~CommandObjectTargetVariable ()
536     {
537     }
538 
539     void
540     DumpValueObject (Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp, const char *root_name)
541     {
542         ValueObject::DumpValueObjectOptions options;
543 
544         options.SetPointerDepth(m_varobj_options.ptr_depth)
545                .SetMaximumDepth(m_varobj_options.max_depth)
546                .SetShowTypes(m_varobj_options.show_types)
547                .SetShowLocation(m_varobj_options.show_location)
548                .SetUseObjectiveC(m_varobj_options.use_objc)
549                .SetUseDynamicType(m_varobj_options.use_dynamic)
550                .SetUseSyntheticValue((lldb::SyntheticValueType)m_varobj_options.use_synth)
551                .SetFlatOutput(m_varobj_options.flat_output)
552                .SetOmitSummaryDepth(m_varobj_options.no_summary_depth)
553                .SetIgnoreCap(m_varobj_options.ignore_cap);
554 
555         switch (var_sp->GetScope())
556         {
557             case eValueTypeVariableGlobal:
558                 if (m_option_variable.show_scope)
559                     s.PutCString("GLOBAL: ");
560                 break;
561 
562             case eValueTypeVariableStatic:
563                 if (m_option_variable.show_scope)
564                     s.PutCString("STATIC: ");
565                 break;
566 
567             case eValueTypeVariableArgument:
568                 if (m_option_variable.show_scope)
569                     s.PutCString("   ARG: ");
570                 break;
571 
572             case eValueTypeVariableLocal:
573                 if (m_option_variable.show_scope)
574                     s.PutCString(" LOCAL: ");
575                 break;
576 
577             default:
578                 break;
579         }
580 
581         if (m_option_variable.show_decl)
582         {
583             bool show_fullpaths = false;
584             bool show_module = true;
585             if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
586                 s.PutCString (": ");
587         }
588 
589         const Format format = m_option_format.GetFormat();
590         if (format != eFormatDefault)
591             valobj_sp->SetFormat (format);
592 
593         ValueObject::DumpValueObject (s,
594                                       valobj_sp.get(),
595                                       root_name,
596                                       options,
597                                       format);
598 
599     }
600 
601 
602     static uint32_t GetVariableCallback (void *baton,
603                                          const char *name,
604                                          VariableList &variable_list)
605     {
606         Target *target = static_cast<Target *>(baton);
607         if (target)
608         {
609             return target->GetImages().FindGlobalVariables (ConstString(name),
610                                                             true,
611                                                             UINT32_MAX,
612                                                             variable_list);
613         }
614         return 0;
615     }
616 
617 
618 
619     virtual bool
620     Execute (Args& args, CommandReturnObject &result)
621     {
622         ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
623         Target *target = exe_ctx.GetTargetPtr();
624         if (target)
625         {
626             const size_t argc = args.GetArgumentCount();
627             Stream &s = result.GetOutputStream();
628             if (argc > 0)
629             {
630 
631                 for (size_t idx = 0; idx < argc; ++idx)
632                 {
633                     VariableList variable_list;
634                     ValueObjectList valobj_list;
635 
636                     const char *arg = args.GetArgumentAtIndex(idx);
637                     uint32_t matches = 0;
638                     bool use_var_name = false;
639                     if (m_option_variable.use_regex)
640                     {
641                         RegularExpression regex(arg);
642                         if (!regex.IsValid ())
643                         {
644                             result.GetErrorStream().Printf ("error: invalid regular expression: '%s'\n", arg);
645                             result.SetStatus (eReturnStatusFailed);
646                             return false;
647                         }
648                         use_var_name = true;
649                         matches = target->GetImages().FindGlobalVariables (regex,
650                                                                            true,
651                                                                            UINT32_MAX,
652                                                                            variable_list);
653                     }
654                     else
655                     {
656                         Error error (Variable::GetValuesForVariableExpressionPath (arg,
657                                                                                    exe_ctx.GetBestExecutionContextScope(),
658                                                                                    GetVariableCallback,
659                                                                                    target,
660                                                                                    variable_list,
661                                                                                    valobj_list));
662                         matches = variable_list.GetSize();
663                     }
664 
665                     if (matches == 0)
666                     {
667                         result.GetErrorStream().Printf ("error: can't find global variable '%s'\n", arg);
668                         result.SetStatus (eReturnStatusFailed);
669                         return false;
670                     }
671                     else
672                     {
673                         for (uint32_t global_idx=0; global_idx<matches; ++global_idx)
674                         {
675                             VariableSP var_sp (variable_list.GetVariableAtIndex(global_idx));
676                             if (var_sp)
677                             {
678                                 ValueObjectSP valobj_sp (valobj_list.GetValueObjectAtIndex(global_idx));
679                                 if (!valobj_sp)
680                                     valobj_sp = ValueObjectVariable::Create (exe_ctx.GetBestExecutionContextScope(), var_sp);
681 
682                                 if (valobj_sp)
683                                     DumpValueObject (s, var_sp, valobj_sp, use_var_name ? var_sp->GetName().GetCString() : arg);
684                             }
685                         }
686                     }
687                 }
688             }
689             else
690             {
691                 bool success = false;
692                 StackFrame *frame = exe_ctx.GetFramePtr();
693                 CompileUnit *comp_unit = NULL;
694                 if (frame)
695                 {
696                     comp_unit = frame->GetSymbolContext (eSymbolContextCompUnit).comp_unit;
697                     if (comp_unit)
698                     {
699                         const bool can_create = true;
700                         VariableListSP comp_unit_varlist_sp (comp_unit->GetVariableList(can_create));
701                         if (comp_unit_varlist_sp)
702                         {
703                             size_t count = comp_unit_varlist_sp->GetSize();
704                             if (count > 0)
705                             {
706                                 s.Printf ("Global variables for %s/%s:\n",
707                                           comp_unit->GetDirectory().GetCString(),
708                                           comp_unit->GetFilename().GetCString());
709 
710                                 success = true;
711                                 for (uint32_t i=0; i<count; ++i)
712                                 {
713                                     VariableSP var_sp (comp_unit_varlist_sp->GetVariableAtIndex(i));
714                                     if (var_sp)
715                                     {
716                                         ValueObjectSP valobj_sp (ValueObjectVariable::Create (exe_ctx.GetBestExecutionContextScope(), var_sp));
717 
718                                         if (valobj_sp)
719                                             DumpValueObject (s, var_sp, valobj_sp, var_sp->GetName().GetCString());
720                                     }
721                                 }
722                             }
723                         }
724                     }
725                 }
726                 if (!success)
727                 {
728                     if (frame)
729                     {
730                         if (comp_unit)
731                             result.AppendErrorWithFormat ("no global variables in current compile unit: %s/%s\n",
732                                                           comp_unit->GetDirectory().GetCString(),
733                                                           comp_unit->GetFilename().GetCString());
734                         else
735                             result.AppendError ("no debug information for frame %u\n", frame->GetFrameIndex());
736                     }
737                     else
738                         result.AppendError ("'target variable' takes one or more global variable names as arguments\n");
739                     result.SetStatus (eReturnStatusFailed);
740                 }
741             }
742         }
743         else
744         {
745             result.AppendError ("invalid target, create a debug target using the 'target create' command");
746             result.SetStatus (eReturnStatusFailed);
747             return false;
748         }
749 
750         if (m_interpreter.TruncationWarningNecessary())
751         {
752             result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
753                                             m_cmd_name.c_str());
754             m_interpreter.TruncationWarningGiven();
755         }
756 
757         return result.Succeeded();
758     }
759 
760     Options *
761     GetOptions ()
762     {
763         return &m_option_group;
764     }
765 
766 protected:
767     OptionGroupOptions m_option_group;
768     OptionGroupVariable m_option_variable;
769     OptionGroupFormat m_option_format;
770     OptionGroupFileList m_option_compile_units;
771     OptionGroupFileList m_option_shared_libraries;
772     OptionGroupValueObjectDisplay m_varobj_options;
773 
774 };
775 
776 
777 #pragma mark CommandObjectTargetModulesSearchPathsAdd
778 
779 class CommandObjectTargetModulesSearchPathsAdd : public CommandObject
780 {
781 public:
782 
783     CommandObjectTargetModulesSearchPathsAdd (CommandInterpreter &interpreter) :
784         CommandObject (interpreter,
785                        "target modules search-paths add",
786                        "Add new image search paths substitution pairs to the current target.",
787                        NULL)
788     {
789         CommandArgumentEntry arg;
790         CommandArgumentData old_prefix_arg;
791         CommandArgumentData new_prefix_arg;
792 
793         // Define the first variant of this arg pair.
794         old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
795         old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
796 
797         // Define the first variant of this arg pair.
798         new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
799         new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
800 
801         // There are two required arguments that must always occur together, i.e. an argument "pair".  Because they
802         // must always occur together, they are treated as two variants of one argument rather than two independent
803         // arguments.  Push them both into the first argument position for m_arguments...
804 
805         arg.push_back (old_prefix_arg);
806         arg.push_back (new_prefix_arg);
807 
808         m_arguments.push_back (arg);
809     }
810 
811     ~CommandObjectTargetModulesSearchPathsAdd ()
812     {
813     }
814 
815     bool
816     Execute (Args& command,
817              CommandReturnObject &result)
818     {
819         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
820         if (target)
821         {
822             uint32_t argc = command.GetArgumentCount();
823             if (argc & 1)
824             {
825                 result.AppendError ("add requires an even number of arguments\n");
826                 result.SetStatus (eReturnStatusFailed);
827             }
828             else
829             {
830                 for (uint32_t i=0; i<argc; i+=2)
831                 {
832                     const char *from = command.GetArgumentAtIndex(i);
833                     const char *to = command.GetArgumentAtIndex(i+1);
834 
835                     if (from[0] && to[0])
836                     {
837                         bool last_pair = ((argc - i) == 2);
838                         target->GetImageSearchPathList().Append (ConstString(from),
839                                                                  ConstString(to),
840                                                                  last_pair); // Notify if this is the last pair
841                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
842                     }
843                     else
844                     {
845                         if (from[0])
846                             result.AppendError ("<path-prefix> can't be empty\n");
847                         else
848                             result.AppendError ("<new-path-prefix> can't be empty\n");
849                         result.SetStatus (eReturnStatusFailed);
850                     }
851                 }
852             }
853         }
854         else
855         {
856             result.AppendError ("invalid target\n");
857             result.SetStatus (eReturnStatusFailed);
858         }
859         return result.Succeeded();
860     }
861 };
862 
863 #pragma mark CommandObjectTargetModulesSearchPathsClear
864 
865 class CommandObjectTargetModulesSearchPathsClear : public CommandObject
866 {
867 public:
868 
869     CommandObjectTargetModulesSearchPathsClear (CommandInterpreter &interpreter) :
870         CommandObject (interpreter,
871                        "target modules search-paths clear",
872                        "Clear all current image search path substitution pairs from the current target.",
873                        "target modules search-paths clear")
874     {
875     }
876 
877     ~CommandObjectTargetModulesSearchPathsClear ()
878     {
879     }
880 
881     bool
882     Execute (Args& command,
883              CommandReturnObject &result)
884     {
885         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
886         if (target)
887         {
888             bool notify = true;
889             target->GetImageSearchPathList().Clear(notify);
890             result.SetStatus (eReturnStatusSuccessFinishNoResult);
891         }
892         else
893         {
894             result.AppendError ("invalid target\n");
895             result.SetStatus (eReturnStatusFailed);
896         }
897         return result.Succeeded();
898     }
899 };
900 
901 #pragma mark CommandObjectTargetModulesSearchPathsInsert
902 
903 class CommandObjectTargetModulesSearchPathsInsert : public CommandObject
904 {
905 public:
906 
907     CommandObjectTargetModulesSearchPathsInsert (CommandInterpreter &interpreter) :
908         CommandObject (interpreter,
909                        "target modules search-paths insert",
910                        "Insert a new image search path substitution pair into the current target at the specified index.",
911                        NULL)
912     {
913         CommandArgumentEntry arg1;
914         CommandArgumentEntry arg2;
915         CommandArgumentData index_arg;
916         CommandArgumentData old_prefix_arg;
917         CommandArgumentData new_prefix_arg;
918 
919         // Define the first and only variant of this arg.
920         index_arg.arg_type = eArgTypeIndex;
921         index_arg.arg_repetition = eArgRepeatPlain;
922 
923         // Put the one and only variant into the first arg for m_arguments:
924         arg1.push_back (index_arg);
925 
926         // Define the first variant of this arg pair.
927         old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
928         old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
929 
930         // Define the first variant of this arg pair.
931         new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
932         new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
933 
934         // There are two required arguments that must always occur together, i.e. an argument "pair".  Because they
935         // must always occur together, they are treated as two variants of one argument rather than two independent
936         // arguments.  Push them both into the same argument position for m_arguments...
937 
938         arg2.push_back (old_prefix_arg);
939         arg2.push_back (new_prefix_arg);
940 
941         // Add arguments to m_arguments.
942         m_arguments.push_back (arg1);
943         m_arguments.push_back (arg2);
944     }
945 
946     ~CommandObjectTargetModulesSearchPathsInsert ()
947     {
948     }
949 
950     bool
951     Execute (Args& command,
952              CommandReturnObject &result)
953     {
954         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
955         if (target)
956         {
957             uint32_t argc = command.GetArgumentCount();
958             // check for at least 3 arguments and an odd nubmer of parameters
959             if (argc >= 3 && argc & 1)
960             {
961                 bool success = false;
962 
963                 uint32_t insert_idx = Args::StringToUInt32(command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
964 
965                 if (!success)
966                 {
967                     result.AppendErrorWithFormat("<index> parameter is not an integer: '%s'.\n", command.GetArgumentAtIndex(0));
968                     result.SetStatus (eReturnStatusFailed);
969                     return result.Succeeded();
970                 }
971 
972                 // shift off the index
973                 command.Shift();
974                 argc = command.GetArgumentCount();
975 
976                 for (uint32_t i=0; i<argc; i+=2, ++insert_idx)
977                 {
978                     const char *from = command.GetArgumentAtIndex(i);
979                     const char *to = command.GetArgumentAtIndex(i+1);
980 
981                     if (from[0] && to[0])
982                     {
983                         bool last_pair = ((argc - i) == 2);
984                         target->GetImageSearchPathList().Insert (ConstString(from),
985                                                                  ConstString(to),
986                                                                  insert_idx,
987                                                                  last_pair);
988                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
989                     }
990                     else
991                     {
992                         if (from[0])
993                             result.AppendError ("<path-prefix> can't be empty\n");
994                         else
995                             result.AppendError ("<new-path-prefix> can't be empty\n");
996                         result.SetStatus (eReturnStatusFailed);
997                         return false;
998                     }
999                 }
1000             }
1001             else
1002             {
1003                 result.AppendError ("insert requires at least three arguments\n");
1004                 result.SetStatus (eReturnStatusFailed);
1005                 return result.Succeeded();
1006             }
1007 
1008         }
1009         else
1010         {
1011             result.AppendError ("invalid target\n");
1012             result.SetStatus (eReturnStatusFailed);
1013         }
1014         return result.Succeeded();
1015     }
1016 };
1017 
1018 
1019 #pragma mark CommandObjectTargetModulesSearchPathsList
1020 
1021 
1022 class CommandObjectTargetModulesSearchPathsList : public CommandObject
1023 {
1024 public:
1025 
1026     CommandObjectTargetModulesSearchPathsList (CommandInterpreter &interpreter) :
1027         CommandObject (interpreter,
1028                        "target modules search-paths list",
1029                        "List all current image search path substitution pairs in the current target.",
1030                        "target modules search-paths list")
1031     {
1032     }
1033 
1034     ~CommandObjectTargetModulesSearchPathsList ()
1035     {
1036     }
1037 
1038     bool
1039     Execute (Args& command,
1040              CommandReturnObject &result)
1041     {
1042         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1043         if (target)
1044         {
1045             if (command.GetArgumentCount() != 0)
1046             {
1047                 result.AppendError ("list takes no arguments\n");
1048                 result.SetStatus (eReturnStatusFailed);
1049                 return result.Succeeded();
1050             }
1051 
1052             target->GetImageSearchPathList().Dump(&result.GetOutputStream());
1053             result.SetStatus (eReturnStatusSuccessFinishResult);
1054         }
1055         else
1056         {
1057             result.AppendError ("invalid target\n");
1058             result.SetStatus (eReturnStatusFailed);
1059         }
1060         return result.Succeeded();
1061     }
1062 };
1063 
1064 #pragma mark CommandObjectTargetModulesSearchPathsQuery
1065 
1066 class CommandObjectTargetModulesSearchPathsQuery : public CommandObject
1067 {
1068 public:
1069 
1070     CommandObjectTargetModulesSearchPathsQuery (CommandInterpreter &interpreter) :
1071     CommandObject (interpreter,
1072                    "target modules search-paths query",
1073                    "Transform a path using the first applicable image search path.",
1074                    NULL)
1075     {
1076         CommandArgumentEntry arg;
1077         CommandArgumentData path_arg;
1078 
1079         // Define the first (and only) variant of this arg.
1080         path_arg.arg_type = eArgTypePath;
1081         path_arg.arg_repetition = eArgRepeatPlain;
1082 
1083         // There is only one variant this argument could be; put it into the argument entry.
1084         arg.push_back (path_arg);
1085 
1086         // Push the data for the first argument into the m_arguments vector.
1087         m_arguments.push_back (arg);
1088     }
1089 
1090     ~CommandObjectTargetModulesSearchPathsQuery ()
1091     {
1092     }
1093 
1094     bool
1095     Execute (Args& command,
1096              CommandReturnObject &result)
1097     {
1098         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1099         if (target)
1100         {
1101             if (command.GetArgumentCount() != 1)
1102             {
1103                 result.AppendError ("query requires one argument\n");
1104                 result.SetStatus (eReturnStatusFailed);
1105                 return result.Succeeded();
1106             }
1107 
1108             ConstString orig(command.GetArgumentAtIndex(0));
1109             ConstString transformed;
1110             if (target->GetImageSearchPathList().RemapPath(orig, transformed))
1111                 result.GetOutputStream().Printf("%s\n", transformed.GetCString());
1112             else
1113                 result.GetOutputStream().Printf("%s\n", orig.GetCString());
1114 
1115             result.SetStatus (eReturnStatusSuccessFinishResult);
1116         }
1117         else
1118         {
1119             result.AppendError ("invalid target\n");
1120             result.SetStatus (eReturnStatusFailed);
1121         }
1122         return result.Succeeded();
1123     }
1124 };
1125 
1126 //----------------------------------------------------------------------
1127 // Static Helper functions
1128 //----------------------------------------------------------------------
1129 static void
1130 DumpModuleArchitecture (Stream &strm, Module *module, bool full_triple, uint32_t width)
1131 {
1132     if (module)
1133     {
1134         const char *arch_cstr;
1135         if (full_triple)
1136             arch_cstr = module->GetArchitecture().GetTriple().str().c_str();
1137         else
1138             arch_cstr = module->GetArchitecture().GetArchitectureName();
1139         if (width)
1140             strm.Printf("%-*s", width, arch_cstr);
1141         else
1142             strm.PutCString(arch_cstr);
1143     }
1144 }
1145 
1146 static void
1147 DumpModuleUUID (Stream &strm, Module *module)
1148 {
1149     if (module->GetUUID().IsValid())
1150         module->GetUUID().Dump (&strm);
1151     else
1152         strm.PutCString("                                    ");
1153 }
1154 
1155 static uint32_t
1156 DumpCompileUnitLineTable
1157 (
1158  CommandInterpreter &interpreter,
1159  Stream &strm,
1160  Module *module,
1161  const FileSpec &file_spec,
1162  bool load_addresses
1163  )
1164 {
1165     uint32_t num_matches = 0;
1166     if (module)
1167     {
1168         SymbolContextList sc_list;
1169         num_matches = module->ResolveSymbolContextsForFileSpec (file_spec,
1170                                                                 0,
1171                                                                 false,
1172                                                                 eSymbolContextCompUnit,
1173                                                                 sc_list);
1174 
1175         for (uint32_t i=0; i<num_matches; ++i)
1176         {
1177             SymbolContext sc;
1178             if (sc_list.GetContextAtIndex(i, sc))
1179             {
1180                 if (i > 0)
1181                     strm << "\n\n";
1182 
1183                 strm << "Line table for " << *static_cast<FileSpec*> (sc.comp_unit) << " in `"
1184                 << module->GetFileSpec().GetFilename() << "\n";
1185                 LineTable *line_table = sc.comp_unit->GetLineTable();
1186                 if (line_table)
1187                     line_table->GetDescription (&strm,
1188                                                 interpreter.GetExecutionContext().GetTargetPtr(),
1189                                                 lldb::eDescriptionLevelBrief);
1190                 else
1191                     strm << "No line table";
1192             }
1193         }
1194     }
1195     return num_matches;
1196 }
1197 
1198 static void
1199 DumpFullpath (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
1200 {
1201     if (file_spec_ptr)
1202     {
1203         if (width > 0)
1204         {
1205             char fullpath[PATH_MAX];
1206             if (file_spec_ptr->GetPath(fullpath, sizeof(fullpath)))
1207             {
1208                 strm.Printf("%-*s", width, fullpath);
1209                 return;
1210             }
1211         }
1212         else
1213         {
1214             file_spec_ptr->Dump(&strm);
1215             return;
1216         }
1217     }
1218     // Keep the width spacing correct if things go wrong...
1219     if (width > 0)
1220         strm.Printf("%-*s", width, "");
1221 }
1222 
1223 static void
1224 DumpDirectory (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
1225 {
1226     if (file_spec_ptr)
1227     {
1228         if (width > 0)
1229             strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
1230         else
1231             file_spec_ptr->GetDirectory().Dump(&strm);
1232         return;
1233     }
1234     // Keep the width spacing correct if things go wrong...
1235     if (width > 0)
1236         strm.Printf("%-*s", width, "");
1237 }
1238 
1239 static void
1240 DumpBasename (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
1241 {
1242     if (file_spec_ptr)
1243     {
1244         if (width > 0)
1245             strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
1246         else
1247             file_spec_ptr->GetFilename().Dump(&strm);
1248         return;
1249     }
1250     // Keep the width spacing correct if things go wrong...
1251     if (width > 0)
1252         strm.Printf("%-*s", width, "");
1253 }
1254 
1255 
1256 static void
1257 DumpModuleSymtab (CommandInterpreter &interpreter, Stream &strm, Module *module, SortOrder sort_order)
1258 {
1259     if (module)
1260     {
1261         ObjectFile *objfile = module->GetObjectFile ();
1262         if (objfile)
1263         {
1264             Symtab *symtab = objfile->GetSymtab();
1265             if (symtab)
1266                 symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), sort_order);
1267         }
1268     }
1269 }
1270 
1271 static void
1272 DumpModuleSections (CommandInterpreter &interpreter, Stream &strm, Module *module)
1273 {
1274     if (module)
1275     {
1276         ObjectFile *objfile = module->GetObjectFile ();
1277         if (objfile)
1278         {
1279             SectionList *section_list = objfile->GetSectionList();
1280             if (section_list)
1281             {
1282                 strm.PutCString ("Sections for '");
1283                 strm << module->GetFileSpec();
1284                 if (module->GetObjectName())
1285                     strm << '(' << module->GetObjectName() << ')';
1286                 strm.Printf ("' (%s):\n", module->GetArchitecture().GetArchitectureName());
1287                 strm.IndentMore();
1288                 section_list->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), true, UINT32_MAX);
1289                 strm.IndentLess();
1290             }
1291         }
1292     }
1293 }
1294 
1295 static bool
1296 DumpModuleSymbolVendor (Stream &strm, Module *module)
1297 {
1298     if (module)
1299     {
1300         SymbolVendor *symbol_vendor = module->GetSymbolVendor(true);
1301         if (symbol_vendor)
1302         {
1303             symbol_vendor->Dump(&strm);
1304             return true;
1305         }
1306     }
1307     return false;
1308 }
1309 
1310 static bool
1311 LookupAddressInModule
1312 (
1313  CommandInterpreter &interpreter,
1314  Stream &strm,
1315  Module *module,
1316  uint32_t resolve_mask,
1317  lldb::addr_t raw_addr,
1318  lldb::addr_t offset,
1319  bool verbose
1320  )
1321 {
1322     if (module)
1323     {
1324         lldb::addr_t addr = raw_addr - offset;
1325         Address so_addr;
1326         SymbolContext sc;
1327         Target *target = interpreter.GetExecutionContext().GetTargetPtr();
1328         if (target && !target->GetSectionLoadList().IsEmpty())
1329         {
1330             if (!target->GetSectionLoadList().ResolveLoadAddress (addr, so_addr))
1331                 return false;
1332             else if (so_addr.GetModulePtr() != module)
1333                 return false;
1334         }
1335         else
1336         {
1337             if (!module->ResolveFileAddress (addr, so_addr))
1338                 return false;
1339         }
1340 
1341         ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope();
1342         strm.IndentMore();
1343         strm.Indent ("    Address: ");
1344         so_addr.Dump (&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1345         strm.PutCString (" (");
1346         so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1347         strm.PutCString (")\n");
1348         strm.Indent ("    Summary: ");
1349         const uint32_t save_indent = strm.GetIndentLevel ();
1350         strm.SetIndentLevel (save_indent + 13);
1351         so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription);
1352         strm.SetIndentLevel (save_indent);
1353         // Print out detailed address information when verbose is enabled
1354         if (verbose)
1355         {
1356             strm.EOL();
1357             so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
1358         }
1359         strm.IndentLess();
1360         return true;
1361     }
1362 
1363     return false;
1364 }
1365 
1366 static uint32_t
1367 LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex)
1368 {
1369     if (module)
1370     {
1371         SymbolContext sc;
1372 
1373         ObjectFile *objfile = module->GetObjectFile ();
1374         if (objfile)
1375         {
1376             Symtab *symtab = objfile->GetSymtab();
1377             if (symtab)
1378             {
1379                 uint32_t i;
1380                 std::vector<uint32_t> match_indexes;
1381                 ConstString symbol_name (name);
1382                 uint32_t num_matches = 0;
1383                 if (name_is_regex)
1384                 {
1385                     RegularExpression name_regexp(name);
1386                     num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType (name_regexp,
1387                                                                                    eSymbolTypeAny,
1388                                                                                    match_indexes);
1389                 }
1390                 else
1391                 {
1392                     num_matches = symtab->AppendSymbolIndexesWithName (symbol_name, match_indexes);
1393                 }
1394 
1395 
1396                 if (num_matches > 0)
1397                 {
1398                     strm.Indent ();
1399                     strm.Printf("%u symbols match %s'%s' in ", num_matches,
1400                                 name_is_regex ? "the regular expression " : "", name);
1401                     DumpFullpath (strm, &module->GetFileSpec(), 0);
1402                     strm.PutCString(":\n");
1403                     strm.IndentMore ();
1404                     Symtab::DumpSymbolHeader (&strm);
1405                     for (i=0; i < num_matches; ++i)
1406                     {
1407                         Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
1408                         strm.Indent ();
1409                         symbol->Dump (&strm, interpreter.GetExecutionContext().GetTargetPtr(), i);
1410                     }
1411                     strm.IndentLess ();
1412                     return num_matches;
1413                 }
1414             }
1415         }
1416     }
1417     return 0;
1418 }
1419 
1420 
1421 static void
1422 DumpSymbolContextList (CommandInterpreter &interpreter, Stream &strm, SymbolContextList &sc_list, bool prepend_addr, bool verbose)
1423 {
1424     strm.IndentMore ();
1425     uint32_t i;
1426     const uint32_t num_matches = sc_list.GetSize();
1427 
1428     for (i=0; i<num_matches; ++i)
1429     {
1430         SymbolContext sc;
1431         if (sc_list.GetContextAtIndex(i, sc))
1432         {
1433             strm.Indent();
1434             ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope ();
1435 
1436             if (prepend_addr)
1437             {
1438                 if (sc.line_entry.range.GetBaseAddress().IsValid())
1439                 {
1440                     sc.line_entry.range.GetBaseAddress().Dump (&strm,
1441                                                                exe_scope,
1442                                                                Address::DumpStyleLoadAddress,
1443                                                                Address::DumpStyleModuleWithFileAddress);
1444                     strm.PutCString(" in ");
1445                 }
1446             }
1447             sc.DumpStopContext(&strm,
1448                                exe_scope,
1449                                sc.line_entry.range.GetBaseAddress(),
1450                                true,
1451                                true,
1452                                false);
1453             strm.EOL();
1454             if (verbose)
1455             {
1456                 if (sc.line_entry.range.GetBaseAddress().IsValid())
1457                 {
1458                     if (sc.line_entry.range.GetBaseAddress().Dump (&strm,
1459                                                                    exe_scope,
1460                                                                    Address::DumpStyleDetailedSymbolContext))
1461                         strm.PutCString("\n\n");
1462                 }
1463                 else if (sc.function->GetAddressRange().GetBaseAddress().IsValid())
1464                 {
1465                     if (sc.function->GetAddressRange().GetBaseAddress().Dump (&strm,
1466                                                                               exe_scope,
1467                                                                               Address::DumpStyleDetailedSymbolContext))
1468                         strm.PutCString("\n\n");
1469                 }
1470             }
1471         }
1472     }
1473     strm.IndentLess ();
1474 }
1475 
1476 static uint32_t
1477 LookupFunctionInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, bool verbose)
1478 {
1479     if (module && name && name[0])
1480     {
1481         SymbolContextList sc_list;
1482         const bool include_symbols = false;
1483         const bool append = true;
1484         uint32_t num_matches = 0;
1485         if (name_is_regex)
1486         {
1487             RegularExpression function_name_regex (name);
1488             num_matches = module->FindFunctions (function_name_regex,
1489                                                  include_symbols,
1490                                                  append,
1491                                                  sc_list);
1492         }
1493         else
1494         {
1495             ConstString function_name (name);
1496             num_matches = module->FindFunctions (function_name,
1497                                                  NULL,
1498                                                  eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector,
1499                                                  include_symbols,
1500                                                  append,
1501                                                  sc_list);
1502         }
1503 
1504         if (num_matches)
1505         {
1506             strm.Indent ();
1507             strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1508             DumpFullpath (strm, &module->GetFileSpec(), 0);
1509             strm.PutCString(":\n");
1510             DumpSymbolContextList (interpreter, strm, sc_list, true, verbose);
1511         }
1512         return num_matches;
1513     }
1514     return 0;
1515 }
1516 
1517 static uint32_t
1518 LookupTypeInModule (CommandInterpreter &interpreter,
1519                     Stream &strm,
1520                     Module *module,
1521                     const char *name_cstr,
1522                     bool name_is_regex)
1523 {
1524     if (module && name_cstr && name_cstr[0])
1525     {
1526         TypeList type_list;
1527         const uint32_t max_num_matches = 1;
1528         uint32_t num_matches = 0;
1529         SymbolContext sc;
1530 
1531         ConstString name(name_cstr);
1532         num_matches = module->FindTypes(sc, name, NULL, true, max_num_matches, type_list);
1533 
1534         if (num_matches)
1535         {
1536             strm.Indent ();
1537             strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1538             DumpFullpath (strm, &module->GetFileSpec(), 0);
1539             strm.PutCString(":\n");
1540             const uint32_t num_types = type_list.GetSize();
1541             for (uint32_t i=0; i<num_types; ++i)
1542             {
1543                 TypeSP type_sp (type_list.GetTypeAtIndex(i));
1544                 if (type_sp)
1545                 {
1546                     // Resolve the clang type so that any forward references
1547                     // to types that haven't yet been parsed will get parsed.
1548                     type_sp->GetClangFullType ();
1549                     type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
1550                 }
1551                 strm.EOL();
1552             }
1553         }
1554         return num_matches;
1555     }
1556     return 0;
1557 }
1558 
1559 static uint32_t
1560 LookupFileAndLineInModule (CommandInterpreter &interpreter,
1561                            Stream &strm,
1562                            Module *module,
1563                            const FileSpec &file_spec,
1564                            uint32_t line,
1565                            bool check_inlines,
1566                            bool verbose)
1567 {
1568     if (module && file_spec)
1569     {
1570         SymbolContextList sc_list;
1571         const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
1572                                                                               eSymbolContextEverything, sc_list);
1573         if (num_matches > 0)
1574         {
1575             strm.Indent ();
1576             strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1577             strm << file_spec;
1578             if (line > 0)
1579                 strm.Printf (":%u", line);
1580             strm << " in ";
1581             DumpFullpath (strm, &module->GetFileSpec(), 0);
1582             strm.PutCString(":\n");
1583             DumpSymbolContextList (interpreter, strm, sc_list, true, verbose);
1584             return num_matches;
1585         }
1586     }
1587     return 0;
1588 
1589 }
1590 
1591 
1592 static size_t
1593 FindModulesByName (Target *target,
1594                    const char *module_name,
1595                    ModuleList &module_list,
1596                    bool check_global_list)
1597 {
1598 // Dump specified images (by basename or fullpath)
1599     FileSpec module_file_spec(module_name, false);
1600 
1601     const size_t initial_size = module_list.GetSize ();
1602 
1603     size_t num_matches = 0;
1604 
1605     if (target)
1606     {
1607         num_matches = target->GetImages().FindModules (&module_file_spec,
1608                                                        NULL,
1609                                                        NULL,
1610                                                        NULL,
1611                                                        module_list);
1612 
1613         // Not found in our module list for our target, check the main
1614         // shared module list in case it is a extra file used somewhere
1615         // else
1616         if (num_matches == 0)
1617             num_matches = ModuleList::FindSharedModules (module_file_spec,
1618                                                          target->GetArchitecture(),
1619                                                          NULL,
1620                                                          NULL,
1621                                                          module_list);
1622     }
1623     else
1624     {
1625         num_matches = ModuleList::FindSharedModules (module_file_spec,
1626                                                      ArchSpec(),
1627                                                      NULL,
1628                                                      NULL,
1629                                                      module_list);
1630     }
1631 
1632     if (check_global_list && num_matches == 0)
1633     {
1634         // Check the global list
1635         Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex());
1636         const uint32_t num_modules = Module::GetNumberAllocatedModules();
1637         ModuleSP module_sp;
1638         for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
1639         {
1640             Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
1641 
1642             if (module)
1643             {
1644                 if (FileSpec::Equal(module->GetFileSpec(), module_file_spec, true))
1645                 {
1646                     module_sp = module->shared_from_this();
1647                     module_list.AppendIfNeeded(module_sp);
1648                 }
1649             }
1650         }
1651     }
1652     return module_list.GetSize () - initial_size;
1653 }
1654 
1655 #pragma mark CommandObjectTargetModulesModuleAutoComplete
1656 
1657 //----------------------------------------------------------------------
1658 // A base command object class that can auto complete with module file
1659 // paths
1660 //----------------------------------------------------------------------
1661 
1662 class CommandObjectTargetModulesModuleAutoComplete : public CommandObject
1663 {
1664 public:
1665 
1666     CommandObjectTargetModulesModuleAutoComplete (CommandInterpreter &interpreter,
1667                                       const char *name,
1668                                       const char *help,
1669                                       const char *syntax) :
1670     CommandObject (interpreter, name, help, syntax)
1671     {
1672         CommandArgumentEntry arg;
1673         CommandArgumentData file_arg;
1674 
1675         // Define the first (and only) variant of this arg.
1676         file_arg.arg_type = eArgTypeFilename;
1677         file_arg.arg_repetition = eArgRepeatStar;
1678 
1679         // There is only one variant this argument could be; put it into the argument entry.
1680         arg.push_back (file_arg);
1681 
1682         // Push the data for the first argument into the m_arguments vector.
1683         m_arguments.push_back (arg);
1684     }
1685 
1686     virtual
1687     ~CommandObjectTargetModulesModuleAutoComplete ()
1688     {
1689     }
1690 
1691     virtual int
1692     HandleArgumentCompletion (Args &input,
1693                               int &cursor_index,
1694                               int &cursor_char_position,
1695                               OptionElementVector &opt_element_vector,
1696                               int match_start_point,
1697                               int max_return_elements,
1698                               bool &word_complete,
1699                               StringList &matches)
1700     {
1701         // Arguments are the standard module completer.
1702         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1703         completion_str.erase (cursor_char_position);
1704 
1705         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1706                                                              CommandCompletions::eModuleCompletion,
1707                                                              completion_str.c_str(),
1708                                                              match_start_point,
1709                                                              max_return_elements,
1710                                                              NULL,
1711                                                              word_complete,
1712                                                              matches);
1713         return matches.GetSize();
1714     }
1715 };
1716 
1717 #pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1718 
1719 //----------------------------------------------------------------------
1720 // A base command object class that can auto complete with module source
1721 // file paths
1722 //----------------------------------------------------------------------
1723 
1724 class CommandObjectTargetModulesSourceFileAutoComplete : public CommandObject
1725 {
1726 public:
1727 
1728     CommandObjectTargetModulesSourceFileAutoComplete (CommandInterpreter &interpreter,
1729                                           const char *name,
1730                                           const char *help,
1731                                           const char *syntax) :
1732     CommandObject (interpreter, name, help, syntax)
1733     {
1734         CommandArgumentEntry arg;
1735         CommandArgumentData source_file_arg;
1736 
1737         // Define the first (and only) variant of this arg.
1738         source_file_arg.arg_type = eArgTypeSourceFile;
1739         source_file_arg.arg_repetition = eArgRepeatPlus;
1740 
1741         // There is only one variant this argument could be; put it into the argument entry.
1742         arg.push_back (source_file_arg);
1743 
1744         // Push the data for the first argument into the m_arguments vector.
1745         m_arguments.push_back (arg);
1746     }
1747 
1748     virtual
1749     ~CommandObjectTargetModulesSourceFileAutoComplete ()
1750     {
1751     }
1752 
1753     virtual int
1754     HandleArgumentCompletion (Args &input,
1755                               int &cursor_index,
1756                               int &cursor_char_position,
1757                               OptionElementVector &opt_element_vector,
1758                               int match_start_point,
1759                               int max_return_elements,
1760                               bool &word_complete,
1761                               StringList &matches)
1762     {
1763         // Arguments are the standard source file completer.
1764         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1765         completion_str.erase (cursor_char_position);
1766 
1767         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1768                                                              CommandCompletions::eSourceFileCompletion,
1769                                                              completion_str.c_str(),
1770                                                              match_start_point,
1771                                                              max_return_elements,
1772                                                              NULL,
1773                                                              word_complete,
1774                                                              matches);
1775         return matches.GetSize();
1776     }
1777 };
1778 
1779 
1780 #pragma mark CommandObjectTargetModulesDumpSymtab
1781 
1782 
1783 class CommandObjectTargetModulesDumpSymtab : public CommandObjectTargetModulesModuleAutoComplete
1784 {
1785 public:
1786     CommandObjectTargetModulesDumpSymtab (CommandInterpreter &interpreter) :
1787     CommandObjectTargetModulesModuleAutoComplete (interpreter,
1788                                       "target modules dump symtab",
1789                                       "Dump the symbol table from one or more target modules.",
1790                                       NULL),
1791     m_options (interpreter)
1792     {
1793     }
1794 
1795     virtual
1796     ~CommandObjectTargetModulesDumpSymtab ()
1797     {
1798     }
1799 
1800     virtual bool
1801     Execute (Args& command,
1802              CommandReturnObject &result)
1803     {
1804         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1805         if (target == NULL)
1806         {
1807             result.AppendError ("invalid target, create a debug target using the 'target create' command");
1808             result.SetStatus (eReturnStatusFailed);
1809             return false;
1810         }
1811         else
1812         {
1813             uint32_t num_dumped = 0;
1814 
1815             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1816             result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1817             result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1818 
1819             if (command.GetArgumentCount() == 0)
1820             {
1821                 // Dump all sections for all modules images
1822                 const uint32_t num_modules = target->GetImages().GetSize();
1823                 if (num_modules > 0)
1824                 {
1825                     result.GetOutputStream().Printf("Dumping symbol table for %u modules.\n", num_modules);
1826                     for (uint32_t image_idx = 0;  image_idx<num_modules; ++image_idx)
1827                     {
1828                         if (num_dumped > 0)
1829                         {
1830                             result.GetOutputStream().EOL();
1831                             result.GetOutputStream().EOL();
1832                         }
1833                         num_dumped++;
1834                         DumpModuleSymtab (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx), m_options.m_sort_order);
1835                     }
1836                 }
1837                 else
1838                 {
1839                     result.AppendError ("the target has no associated executable images");
1840                     result.SetStatus (eReturnStatusFailed);
1841                     return false;
1842                 }
1843             }
1844             else
1845             {
1846                 // Dump specified images (by basename or fullpath)
1847                 const char *arg_cstr;
1848                 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
1849                 {
1850                     ModuleList module_list;
1851                     const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
1852                     if (num_matches > 0)
1853                     {
1854                         for (size_t i=0; i<num_matches; ++i)
1855                         {
1856                             Module *module = module_list.GetModulePointerAtIndex(i);
1857                             if (module)
1858                             {
1859                                 if (num_dumped > 0)
1860                                 {
1861                                     result.GetOutputStream().EOL();
1862                                     result.GetOutputStream().EOL();
1863                                 }
1864                                 num_dumped++;
1865                                 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), module, m_options.m_sort_order);
1866                             }
1867                         }
1868                     }
1869                     else
1870                         result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
1871                 }
1872             }
1873 
1874             if (num_dumped > 0)
1875                 result.SetStatus (eReturnStatusSuccessFinishResult);
1876             else
1877             {
1878                 result.AppendError ("no matching executable images found");
1879                 result.SetStatus (eReturnStatusFailed);
1880             }
1881         }
1882         return result.Succeeded();
1883     }
1884 
1885     virtual Options *
1886     GetOptions ()
1887     {
1888         return &m_options;
1889     }
1890 
1891     class CommandOptions : public Options
1892     {
1893     public:
1894 
1895         CommandOptions (CommandInterpreter &interpreter) :
1896         Options(interpreter),
1897         m_sort_order (eSortOrderNone)
1898         {
1899         }
1900 
1901         virtual
1902         ~CommandOptions ()
1903         {
1904         }
1905 
1906         virtual Error
1907         SetOptionValue (uint32_t option_idx, const char *option_arg)
1908         {
1909             Error error;
1910             char short_option = (char) m_getopt_table[option_idx].val;
1911 
1912             switch (short_option)
1913             {
1914                 case 's':
1915                     m_sort_order = (SortOrder) Args::StringToOptionEnum (option_arg,
1916                                                                          g_option_table[option_idx].enum_values,
1917                                                                          eSortOrderNone,
1918                                                                          error);
1919                     break;
1920 
1921                 default:
1922                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1923                     break;
1924 
1925             }
1926             return error;
1927         }
1928 
1929         void
1930         OptionParsingStarting ()
1931         {
1932             m_sort_order = eSortOrderNone;
1933         }
1934 
1935         const OptionDefinition*
1936         GetDefinitions ()
1937         {
1938             return g_option_table;
1939         }
1940 
1941         // Options table: Required for subclasses of Options.
1942         static OptionDefinition g_option_table[];
1943 
1944         SortOrder m_sort_order;
1945     };
1946 
1947 protected:
1948 
1949     CommandOptions m_options;
1950 };
1951 
1952 static OptionEnumValueElement
1953 g_sort_option_enumeration[4] =
1954 {
1955     { eSortOrderNone,       "none",     "No sorting, use the original symbol table order."},
1956     { eSortOrderByAddress,  "address",  "Sort output by symbol address."},
1957     { eSortOrderByName,     "name",     "Sort output by symbol name."},
1958     { 0,                    NULL,       NULL }
1959 };
1960 
1961 
1962 OptionDefinition
1963 CommandObjectTargetModulesDumpSymtab::CommandOptions::g_option_table[] =
1964 {
1965     { LLDB_OPT_SET_1, false, "sort", 's', required_argument, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."},
1966     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1967 };
1968 
1969 #pragma mark CommandObjectTargetModulesDumpSections
1970 
1971 //----------------------------------------------------------------------
1972 // Image section dumping command
1973 //----------------------------------------------------------------------
1974 
1975 class CommandObjectTargetModulesDumpSections : public CommandObjectTargetModulesModuleAutoComplete
1976 {
1977 public:
1978     CommandObjectTargetModulesDumpSections (CommandInterpreter &interpreter) :
1979     CommandObjectTargetModulesModuleAutoComplete (interpreter,
1980                                       "target modules dump sections",
1981                                       "Dump the sections from one or more target modules.",
1982                                       //"target modules dump sections [<file1> ...]")
1983                                       NULL)
1984     {
1985     }
1986 
1987     virtual
1988     ~CommandObjectTargetModulesDumpSections ()
1989     {
1990     }
1991 
1992     virtual bool
1993     Execute (Args& command,
1994              CommandReturnObject &result)
1995     {
1996         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1997         if (target == NULL)
1998         {
1999             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2000             result.SetStatus (eReturnStatusFailed);
2001             return false;
2002         }
2003         else
2004         {
2005             uint32_t num_dumped = 0;
2006 
2007             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2008             result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2009             result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2010 
2011             if (command.GetArgumentCount() == 0)
2012             {
2013                 // Dump all sections for all modules images
2014                 const uint32_t num_modules = target->GetImages().GetSize();
2015                 if (num_modules > 0)
2016                 {
2017                     result.GetOutputStream().Printf("Dumping sections for %u modules.\n", num_modules);
2018                     for (uint32_t image_idx = 0;  image_idx<num_modules; ++image_idx)
2019                     {
2020                         num_dumped++;
2021                         DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
2022                     }
2023                 }
2024                 else
2025                 {
2026                     result.AppendError ("the target has no associated executable images");
2027                     result.SetStatus (eReturnStatusFailed);
2028                     return false;
2029                 }
2030             }
2031             else
2032             {
2033                 // Dump specified images (by basename or fullpath)
2034                 const char *arg_cstr;
2035                 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2036                 {
2037                     ModuleList module_list;
2038                     const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
2039                     if (num_matches > 0)
2040                     {
2041                         for (size_t i=0; i<num_matches; ++i)
2042                         {
2043                             Module *module = module_list.GetModulePointerAtIndex(i);
2044                             if (module)
2045                             {
2046                                 num_dumped++;
2047                                 DumpModuleSections (m_interpreter, result.GetOutputStream(), module);
2048                             }
2049                         }
2050                     }
2051                     else
2052                     {
2053                         // Check the global list
2054                         Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex());
2055 
2056                         result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
2057                     }
2058                 }
2059             }
2060 
2061             if (num_dumped > 0)
2062                 result.SetStatus (eReturnStatusSuccessFinishResult);
2063             else
2064             {
2065                 result.AppendError ("no matching executable images found");
2066                 result.SetStatus (eReturnStatusFailed);
2067             }
2068         }
2069         return result.Succeeded();
2070     }
2071 };
2072 
2073 
2074 #pragma mark CommandObjectTargetModulesDumpSymfile
2075 
2076 //----------------------------------------------------------------------
2077 // Image debug symbol dumping command
2078 //----------------------------------------------------------------------
2079 
2080 class CommandObjectTargetModulesDumpSymfile : public CommandObjectTargetModulesModuleAutoComplete
2081 {
2082 public:
2083     CommandObjectTargetModulesDumpSymfile (CommandInterpreter &interpreter) :
2084     CommandObjectTargetModulesModuleAutoComplete (interpreter,
2085                                       "target modules dump symfile",
2086                                       "Dump the debug symbol file for one or more target modules.",
2087                                       //"target modules dump symfile [<file1> ...]")
2088                                       NULL)
2089     {
2090     }
2091 
2092     virtual
2093     ~CommandObjectTargetModulesDumpSymfile ()
2094     {
2095     }
2096 
2097     virtual bool
2098     Execute (Args& command,
2099              CommandReturnObject &result)
2100     {
2101         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2102         if (target == NULL)
2103         {
2104             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2105             result.SetStatus (eReturnStatusFailed);
2106             return false;
2107         }
2108         else
2109         {
2110             uint32_t num_dumped = 0;
2111 
2112             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2113             result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2114             result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2115 
2116             if (command.GetArgumentCount() == 0)
2117             {
2118                 // Dump all sections for all modules images
2119                 const uint32_t num_modules = target->GetImages().GetSize();
2120                 if (num_modules > 0)
2121                 {
2122                     result.GetOutputStream().Printf("Dumping debug symbols for %u modules.\n", num_modules);
2123                     for (uint32_t image_idx = 0;  image_idx<num_modules; ++image_idx)
2124                     {
2125                         if (DumpModuleSymbolVendor (result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx)))
2126                             num_dumped++;
2127                     }
2128                 }
2129                 else
2130                 {
2131                     result.AppendError ("the target has no associated executable images");
2132                     result.SetStatus (eReturnStatusFailed);
2133                     return false;
2134                 }
2135             }
2136             else
2137             {
2138                 // Dump specified images (by basename or fullpath)
2139                 const char *arg_cstr;
2140                 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2141                 {
2142                     ModuleList module_list;
2143                     const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
2144                     if (num_matches > 0)
2145                     {
2146                         for (size_t i=0; i<num_matches; ++i)
2147                         {
2148                             Module *module = module_list.GetModulePointerAtIndex(i);
2149                             if (module)
2150                             {
2151                                 if (DumpModuleSymbolVendor (result.GetOutputStream(), module))
2152                                     num_dumped++;
2153                             }
2154                         }
2155                     }
2156                     else
2157                         result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
2158                 }
2159             }
2160 
2161             if (num_dumped > 0)
2162                 result.SetStatus (eReturnStatusSuccessFinishResult);
2163             else
2164             {
2165                 result.AppendError ("no matching executable images found");
2166                 result.SetStatus (eReturnStatusFailed);
2167             }
2168         }
2169         return result.Succeeded();
2170     }
2171 };
2172 
2173 
2174 #pragma mark CommandObjectTargetModulesDumpLineTable
2175 
2176 //----------------------------------------------------------------------
2177 // Image debug line table dumping command
2178 //----------------------------------------------------------------------
2179 
2180 class CommandObjectTargetModulesDumpLineTable : public CommandObjectTargetModulesSourceFileAutoComplete
2181 {
2182 public:
2183     CommandObjectTargetModulesDumpLineTable (CommandInterpreter &interpreter) :
2184     CommandObjectTargetModulesSourceFileAutoComplete (interpreter,
2185                                           "target modules dump line-table",
2186                                           "Dump the debug symbol file for one or more target modules.",
2187                                           NULL)
2188     {
2189     }
2190 
2191     virtual
2192     ~CommandObjectTargetModulesDumpLineTable ()
2193     {
2194     }
2195 
2196     virtual bool
2197     Execute (Args& command,
2198              CommandReturnObject &result)
2199     {
2200         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2201         if (target == NULL)
2202         {
2203             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2204             result.SetStatus (eReturnStatusFailed);
2205             return false;
2206         }
2207         else
2208         {
2209             ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
2210             uint32_t total_num_dumped = 0;
2211 
2212             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2213             result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2214             result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2215 
2216             if (command.GetArgumentCount() == 0)
2217             {
2218                 result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str());
2219                 result.SetStatus (eReturnStatusFailed);
2220             }
2221             else
2222             {
2223                 // Dump specified images (by basename or fullpath)
2224                 const char *arg_cstr;
2225                 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2226                 {
2227                     FileSpec file_spec(arg_cstr, false);
2228                     const uint32_t num_modules = target->GetImages().GetSize();
2229                     if (num_modules > 0)
2230                     {
2231                         uint32_t num_dumped = 0;
2232                         for (uint32_t i = 0; i<num_modules; ++i)
2233                         {
2234                             if (DumpCompileUnitLineTable (m_interpreter,
2235                                                           result.GetOutputStream(),
2236                                                           target->GetImages().GetModulePointerAtIndex(i),
2237                                                           file_spec,
2238                                                           exe_ctx.GetProcessPtr() && exe_ctx.GetProcessRef().IsAlive()))
2239                                 num_dumped++;
2240                         }
2241                         if (num_dumped == 0)
2242                             result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr);
2243                         else
2244                             total_num_dumped += num_dumped;
2245                     }
2246                 }
2247             }
2248 
2249             if (total_num_dumped > 0)
2250                 result.SetStatus (eReturnStatusSuccessFinishResult);
2251             else
2252             {
2253                 result.AppendError ("no source filenames matched any command arguments");
2254                 result.SetStatus (eReturnStatusFailed);
2255             }
2256         }
2257         return result.Succeeded();
2258     }
2259 };
2260 
2261 
2262 #pragma mark CommandObjectTargetModulesDump
2263 
2264 //----------------------------------------------------------------------
2265 // Dump multi-word command for target modules
2266 //----------------------------------------------------------------------
2267 
2268 class CommandObjectTargetModulesDump : public CommandObjectMultiword
2269 {
2270 public:
2271 
2272     //------------------------------------------------------------------
2273     // Constructors and Destructors
2274     //------------------------------------------------------------------
2275     CommandObjectTargetModulesDump(CommandInterpreter &interpreter) :
2276     CommandObjectMultiword (interpreter,
2277                             "target modules dump",
2278                             "A set of commands for dumping information about one or more target modules.",
2279                             "target modules dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]")
2280     {
2281         LoadSubCommand ("symtab",      CommandObjectSP (new CommandObjectTargetModulesDumpSymtab (interpreter)));
2282         LoadSubCommand ("sections",    CommandObjectSP (new CommandObjectTargetModulesDumpSections (interpreter)));
2283         LoadSubCommand ("symfile",     CommandObjectSP (new CommandObjectTargetModulesDumpSymfile (interpreter)));
2284         LoadSubCommand ("line-table",  CommandObjectSP (new CommandObjectTargetModulesDumpLineTable (interpreter)));
2285     }
2286 
2287     virtual
2288     ~CommandObjectTargetModulesDump()
2289     {
2290     }
2291 };
2292 
2293 class CommandObjectTargetModulesAdd : public CommandObject
2294 {
2295 public:
2296     CommandObjectTargetModulesAdd (CommandInterpreter &interpreter) :
2297     CommandObject (interpreter,
2298                    "target modules add",
2299                    "Add a new module to the current target's modules.",
2300                    "target modules add [<module>]")
2301     {
2302     }
2303 
2304     virtual
2305     ~CommandObjectTargetModulesAdd ()
2306     {
2307     }
2308 
2309     virtual bool
2310     Execute (Args& args,
2311              CommandReturnObject &result)
2312     {
2313         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2314         if (target == NULL)
2315         {
2316             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2317             result.SetStatus (eReturnStatusFailed);
2318             return false;
2319         }
2320         else
2321         {
2322             const size_t argc = args.GetArgumentCount();
2323             if (argc == 0)
2324             {
2325                 result.AppendError ("one or more executable image paths must be specified");
2326                 result.SetStatus (eReturnStatusFailed);
2327                 return false;
2328             }
2329             else
2330             {
2331                 for (size_t i=0; i<argc; ++i)
2332                 {
2333                     const char *path = args.GetArgumentAtIndex(i);
2334                     if (path)
2335                     {
2336                         FileSpec file_spec(path, true);
2337                         ArchSpec arch;
2338                         if (file_spec.Exists())
2339                         {
2340                             ModuleSP module_sp (target->GetSharedModule(file_spec, arch));
2341                             if (!module_sp)
2342                             {
2343                                 result.AppendError ("one or more executable image paths must be specified");
2344                                 result.SetStatus (eReturnStatusFailed);
2345                                 return false;
2346                             }
2347                             result.SetStatus (eReturnStatusSuccessFinishResult);
2348                         }
2349                         else
2350                         {
2351                             char resolved_path[PATH_MAX];
2352                             result.SetStatus (eReturnStatusFailed);
2353                             if (file_spec.GetPath (resolved_path, sizeof(resolved_path)))
2354                             {
2355                                 if (strcmp (resolved_path, path) != 0)
2356                                 {
2357                                     result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", path, resolved_path);
2358                                     break;
2359                                 }
2360                             }
2361                             result.AppendErrorWithFormat ("invalid module path '%s'\n", path);
2362                             break;
2363                         }
2364                     }
2365                 }
2366             }
2367         }
2368         return result.Succeeded();
2369     }
2370 
2371     int
2372     HandleArgumentCompletion (Args &input,
2373                               int &cursor_index,
2374                               int &cursor_char_position,
2375                               OptionElementVector &opt_element_vector,
2376                               int match_start_point,
2377                               int max_return_elements,
2378                               bool &word_complete,
2379                               StringList &matches)
2380     {
2381         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2382         completion_str.erase (cursor_char_position);
2383 
2384         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
2385                                                              CommandCompletions::eDiskFileCompletion,
2386                                                              completion_str.c_str(),
2387                                                              match_start_point,
2388                                                              max_return_elements,
2389                                                              NULL,
2390                                                              word_complete,
2391                                                              matches);
2392         return matches.GetSize();
2393     }
2394 
2395 };
2396 
2397 class CommandObjectTargetModulesLoad : public CommandObjectTargetModulesModuleAutoComplete
2398 {
2399 public:
2400     CommandObjectTargetModulesLoad (CommandInterpreter &interpreter) :
2401         CommandObjectTargetModulesModuleAutoComplete (interpreter,
2402                                                       "target modules load",
2403                                                       "Set the load addresses for one or more sections in a target module.",
2404                                                       "target modules load [--file <module> --uuid <uuid>] <sect-name> <address> [<sect-name> <address> ....]"),
2405         m_option_group (interpreter),
2406         m_file_option (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypePath, "Fullpath or basename for module to load."),
2407         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)
2408     {
2409         m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2410         m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2411         m_option_group.Append (&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2412         m_option_group.Finalize();
2413     }
2414 
2415     virtual
2416     ~CommandObjectTargetModulesLoad ()
2417     {
2418     }
2419 
2420     virtual bool
2421     Execute (Args& args,
2422              CommandReturnObject &result)
2423     {
2424         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2425         if (target == NULL)
2426         {
2427             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2428             result.SetStatus (eReturnStatusFailed);
2429             return false;
2430         }
2431         else
2432         {
2433             const size_t argc = args.GetArgumentCount();
2434             const FileSpec *file_ptr = NULL;
2435             const UUID *uuid_ptr = NULL;
2436             if (m_file_option.GetOptionValue().OptionWasSet())
2437                 file_ptr = &m_file_option.GetOptionValue().GetCurrentValue();
2438 
2439             if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2440                 uuid_ptr = &m_uuid_option_group.GetOptionValue().GetCurrentValue();
2441 
2442             if (file_ptr || uuid_ptr)
2443             {
2444 
2445                 ModuleList matching_modules;
2446                 const size_t num_matches = target->GetImages().FindModules (file_ptr,   // File spec to match (can be NULL to match by UUID only)
2447                                                                             NULL,       // Architecture
2448                                                                             uuid_ptr,   // UUID to match (can be NULL to not match on UUID)
2449                                                                             NULL,       // Object name
2450                                                                             matching_modules);
2451 
2452                 char path[PATH_MAX];
2453                 if (num_matches == 1)
2454                 {
2455                     Module *module = matching_modules.GetModulePointerAtIndex(0);
2456                     if (module)
2457                     {
2458                         ObjectFile *objfile = module->GetObjectFile();
2459                         if (objfile)
2460                         {
2461                             SectionList *section_list = objfile->GetSectionList();
2462                             if (section_list)
2463                             {
2464                                 if (argc == 0)
2465                                 {
2466                                     if (m_slide_option.GetOptionValue().OptionWasSet())
2467                                     {
2468                                         Module *module = matching_modules.GetModulePointerAtIndex(0);
2469                                         if (module)
2470                                         {
2471                                             ObjectFile *objfile = module->GetObjectFile();
2472                                             if (objfile)
2473                                             {
2474                                                 SectionList *section_list = objfile->GetSectionList();
2475                                                 if (section_list)
2476                                                 {
2477                                                     const size_t num_sections = section_list->GetSize();
2478                                                     const addr_t slide = m_slide_option.GetOptionValue().GetCurrentValue();
2479                                                     for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
2480                                                     {
2481                                                         SectionSP section_sp (section_list->GetSectionAtIndex(sect_idx));
2482                                                         if (section_sp)
2483                                                             target->GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), section_sp->GetFileAddress() + slide);
2484                                                     }
2485                                                 }
2486                                             }
2487                                         }
2488                                     }
2489                                     else
2490                                     {
2491                                         result.AppendError ("one or more section name + load address pair must be specified");
2492                                         result.SetStatus (eReturnStatusFailed);
2493                                         return false;
2494                                     }
2495                                 }
2496                                 else
2497                                 {
2498                                     if (m_slide_option.GetOptionValue().OptionWasSet())
2499                                     {
2500                                         result.AppendError ("The \"--slide <offset>\" option can't be used in conjunction with setting section load addresses.\n");
2501                                         result.SetStatus (eReturnStatusFailed);
2502                                         return false;
2503                                     }
2504 
2505                                     for (size_t i=0; i<argc; i += 2)
2506                                     {
2507                                         const char *sect_name = args.GetArgumentAtIndex(i);
2508                                         const char *load_addr_cstr = args.GetArgumentAtIndex(i+1);
2509                                         if (sect_name && load_addr_cstr)
2510                                         {
2511                                             ConstString const_sect_name(sect_name);
2512                                             bool success = false;
2513                                             addr_t load_addr = Args::StringToUInt64(load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
2514                                             if (success)
2515                                             {
2516                                                 SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
2517                                                 if (section_sp)
2518                                                 {
2519                                                     target->GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), load_addr);
2520                                                     result.AppendMessageWithFormat("section '%s' loaded at 0x%llx\n", sect_name, load_addr);
2521                                                 }
2522                                                 else
2523                                                 {
2524                                                     result.AppendErrorWithFormat ("no section found that matches the section name '%s'\n", sect_name);
2525                                                     result.SetStatus (eReturnStatusFailed);
2526                                                     break;
2527                                                 }
2528                                             }
2529                                             else
2530                                             {
2531                                                 result.AppendErrorWithFormat ("invalid load address string '%s'\n", load_addr_cstr);
2532                                                 result.SetStatus (eReturnStatusFailed);
2533                                                 break;
2534                                             }
2535                                         }
2536                                         else
2537                                         {
2538                                             if (sect_name)
2539                                                 result.AppendError ("section names must be followed by a load address.\n");
2540                                             else
2541                                                 result.AppendError ("one or more section name + load address pair must be specified.\n");
2542                                             result.SetStatus (eReturnStatusFailed);
2543                                             break;
2544                                         }
2545                                     }
2546                                 }
2547                             }
2548                             else
2549                             {
2550                                 module->GetFileSpec().GetPath (path, sizeof(path));
2551                                 result.AppendErrorWithFormat ("no sections in object file '%s'\n", path);
2552                                 result.SetStatus (eReturnStatusFailed);
2553                             }
2554                         }
2555                         else
2556                         {
2557                             module->GetFileSpec().GetPath (path, sizeof(path));
2558                             result.AppendErrorWithFormat ("no object file for module '%s'\n", path);
2559                             result.SetStatus (eReturnStatusFailed);
2560                         }
2561                     }
2562                     else
2563                     {
2564                         module->GetFileSpec().GetPath (path, sizeof(path));
2565                         result.AppendErrorWithFormat ("invalid module '%s'.\n", path);
2566                         result.SetStatus (eReturnStatusFailed);
2567                     }
2568                 }
2569                 else
2570                 {
2571                     char uuid_cstr[64];
2572                     if (file_ptr)
2573                         file_ptr->GetPath (path, sizeof(path));
2574                     else
2575                         path[0] = '\0';
2576 
2577                     if (uuid_ptr)
2578                         uuid_ptr->GetAsCString(uuid_cstr, sizeof(uuid_cstr));
2579                     else
2580                         uuid_cstr[0] = '\0';
2581                     if (num_matches > 1)
2582                     {
2583                         result.AppendErrorWithFormat ("multiple modules match%s%s%s%s:\n",
2584                                                       path[0] ? " file=" : "",
2585                                                       path,
2586                                                       uuid_cstr[0] ? " uuid=" : "",
2587                                                       uuid_cstr);
2588                         for (size_t i=0; i<num_matches; ++i)
2589                         {
2590                             if (matching_modules.GetModulePointerAtIndex(i)->GetFileSpec().GetPath (path, sizeof(path)))
2591                                 result.AppendMessageWithFormat("%s\n", path);
2592                         }
2593                     }
2594                     else
2595                     {
2596                         result.AppendErrorWithFormat ("no modules were found  that match%s%s%s%s.\n",
2597                                                       path[0] ? " file=" : "",
2598                                                       path,
2599                                                       uuid_cstr[0] ? " uuid=" : "",
2600                                                       uuid_cstr);
2601                     }
2602                     result.SetStatus (eReturnStatusFailed);
2603                 }
2604             }
2605             else
2606             {
2607                 result.AppendError ("either the \"--file <module>\" or the \"--uuid <uuid>\" option must be specified.\n");
2608                 result.SetStatus (eReturnStatusFailed);
2609                 return false;
2610             }
2611         }
2612         return result.Succeeded();
2613     }
2614 
2615     virtual Options *
2616     GetOptions ()
2617     {
2618         return &m_option_group;
2619     }
2620 
2621 protected:
2622     OptionGroupOptions m_option_group;
2623     OptionGroupUUID m_uuid_option_group;
2624     OptionGroupFile m_file_option;
2625     OptionGroupUInt64 m_slide_option;
2626 };
2627 
2628 //----------------------------------------------------------------------
2629 // List images with associated information
2630 //----------------------------------------------------------------------
2631 class CommandObjectTargetModulesList : public CommandObject
2632 {
2633 public:
2634 
2635     class CommandOptions : public Options
2636     {
2637     public:
2638 
2639         CommandOptions (CommandInterpreter &interpreter) :
2640             Options(interpreter),
2641             m_format_array(),
2642             m_use_global_module_list (false),
2643             m_module_addr (LLDB_INVALID_ADDRESS)
2644         {
2645         }
2646 
2647         virtual
2648         ~CommandOptions ()
2649         {
2650         }
2651 
2652         virtual Error
2653         SetOptionValue (uint32_t option_idx, const char *option_arg)
2654         {
2655             char short_option = (char) m_getopt_table[option_idx].val;
2656             if (short_option == 'g')
2657             {
2658                 m_use_global_module_list = true;
2659             }
2660             else if (short_option == 'a')
2661             {
2662                 bool success;
2663                 m_module_addr = Args::StringToAddress(option_arg, LLDB_INVALID_ADDRESS, &success);
2664                 if (!success)
2665                 {
2666                     Error error;
2667                     error.SetErrorStringWithFormat("invalid address: \"%s\"", option_arg);
2668                 }
2669             }
2670             else
2671             {
2672                 uint32_t width = 0;
2673                 if (option_arg)
2674                     width = strtoul (option_arg, NULL, 0);
2675                 m_format_array.push_back(std::make_pair(short_option, width));
2676             }
2677             Error error;
2678             return error;
2679         }
2680 
2681         void
2682         OptionParsingStarting ()
2683         {
2684             m_format_array.clear();
2685             m_use_global_module_list = false;
2686             m_module_addr = LLDB_INVALID_ADDRESS;
2687         }
2688 
2689         const OptionDefinition*
2690         GetDefinitions ()
2691         {
2692             return g_option_table;
2693         }
2694 
2695         // Options table: Required for subclasses of Options.
2696 
2697         static OptionDefinition g_option_table[];
2698 
2699         // Instance variables to hold the values for command options.
2700         typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection;
2701         FormatWidthCollection m_format_array;
2702         bool m_use_global_module_list;
2703         lldb::addr_t m_module_addr;
2704     };
2705 
2706     CommandObjectTargetModulesList (CommandInterpreter &interpreter) :
2707     CommandObject (interpreter,
2708                    "target modules list",
2709                    "List current executable and dependent shared library images.",
2710                    "target modules list [<cmd-options>]"),
2711         m_options (interpreter)
2712     {
2713     }
2714 
2715     virtual
2716     ~CommandObjectTargetModulesList ()
2717     {
2718     }
2719 
2720     virtual
2721     Options *
2722     GetOptions ()
2723     {
2724         return &m_options;
2725     }
2726 
2727     virtual bool
2728     Execute (Args& command,
2729              CommandReturnObject &result)
2730     {
2731         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2732         const bool use_global_module_list = m_options.m_use_global_module_list;
2733         if (target == NULL && use_global_module_list == false)
2734         {
2735             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2736             result.SetStatus (eReturnStatusFailed);
2737             return false;
2738         }
2739         else
2740         {
2741             if (target)
2742             {
2743                 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2744                 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2745                 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2746             }
2747             // Dump all sections for all modules images
2748             uint32_t num_modules = 0;
2749             Mutex::Locker locker;
2750 
2751             Stream &strm = result.GetOutputStream();
2752 
2753             if (m_options.m_module_addr != LLDB_INVALID_ADDRESS)
2754             {
2755                 if (target)
2756                 {
2757                     Address module_address;
2758                     if (module_address.SetLoadAddress(m_options.m_module_addr, target))
2759                     {
2760                         Module *module = module_address.GetModulePtr();
2761                         if (module)
2762                         {
2763                             PrintModule (target, module, UINT32_MAX, 0, strm);
2764                             result.SetStatus (eReturnStatusSuccessFinishResult);
2765                         }
2766                         else
2767                         {
2768                             result.AppendError ("Couldn't find module matching address: 0x%llx.", m_options.m_module_addr);
2769                             result.SetStatus (eReturnStatusFailed);
2770                         }
2771                     }
2772                     else
2773                     {
2774                         result.AppendError ("Couldn't find module containing address: 0x%llx.", m_options.m_module_addr);
2775                         result.SetStatus (eReturnStatusFailed);
2776                     }
2777                 }
2778                 else
2779                 {
2780                     result.AppendError ("Can only look up modules by address with a valid target.");
2781                     result.SetStatus (eReturnStatusFailed);
2782                 }
2783                 return result.Succeeded();
2784             }
2785 
2786             if (use_global_module_list)
2787             {
2788                 locker.Reset (Module::GetAllocationModuleCollectionMutex()->GetMutex());
2789                 num_modules = Module::GetNumberAllocatedModules();
2790             }
2791             else
2792                 num_modules = target->GetImages().GetSize();
2793 
2794             if (num_modules > 0)
2795             {
2796                 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
2797                 {
2798                     ModuleSP module_sp;
2799                     Module *module;
2800                     if (use_global_module_list)
2801                     {
2802                         module = Module::GetAllocatedModuleAtIndex(image_idx);
2803                         module_sp = module->shared_from_this();
2804                     }
2805                     else
2806                     {
2807                         module_sp = target->GetImages().GetModuleAtIndex(image_idx);
2808                         module = module_sp.get();
2809                     }
2810 
2811                     int indent = strm.Printf("[%3u] ", image_idx);
2812                     PrintModule (target, module, image_idx, indent, strm);
2813 
2814                 }
2815                 result.SetStatus (eReturnStatusSuccessFinishResult);
2816             }
2817             else
2818             {
2819                 if (use_global_module_list)
2820                     result.AppendError ("the global module list is empty");
2821                 else
2822                     result.AppendError ("the target has no associated executable images");
2823                 result.SetStatus (eReturnStatusFailed);
2824                 return false;
2825             }
2826         }
2827         return result.Succeeded();
2828     }
2829 protected:
2830 
2831     void
2832     PrintModule (Target *target, Module *module, uint32_t idx, int indent, Stream &strm)
2833     {
2834 
2835         bool dump_object_name = false;
2836         if (m_options.m_format_array.empty())
2837         {
2838             m_options.m_format_array.push_back(std::make_pair('u', 0));
2839             m_options.m_format_array.push_back(std::make_pair('h', 0));
2840             m_options.m_format_array.push_back(std::make_pair('f', 0));
2841             m_options.m_format_array.push_back(std::make_pair('S', 0));
2842         }
2843         const size_t num_entries = m_options.m_format_array.size();
2844         bool print_space = false;
2845         for (size_t i=0; i<num_entries; ++i)
2846         {
2847             if (print_space)
2848                 strm.PutChar(' ');
2849             print_space = true;
2850             const char format_char = m_options.m_format_array[i].first;
2851             uint32_t width = m_options.m_format_array[i].second;
2852             switch (format_char)
2853             {
2854                 case 'A':
2855                     DumpModuleArchitecture (strm, module, false, width);
2856                     break;
2857 
2858                 case 't':
2859                     DumpModuleArchitecture (strm, module, true, width);
2860                     break;
2861 
2862                 case 'f':
2863                     DumpFullpath (strm, &module->GetFileSpec(), width);
2864                     dump_object_name = true;
2865                     break;
2866 
2867                 case 'd':
2868                     DumpDirectory (strm, &module->GetFileSpec(), width);
2869                     break;
2870 
2871                 case 'b':
2872                     DumpBasename (strm, &module->GetFileSpec(), width);
2873                     dump_object_name = true;
2874                     break;
2875 
2876                 case 'h':
2877                 case 'o':
2878                     // Image header address
2879                     {
2880                         uint32_t addr_nibble_width = target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16;
2881 
2882                         ObjectFile *objfile = module->GetObjectFile ();
2883                         if (objfile)
2884                         {
2885                             Address header_addr(objfile->GetHeaderAddress());
2886                             if (header_addr.IsValid())
2887                             {
2888                                 if (target && !target->GetSectionLoadList().IsEmpty())
2889                                 {
2890                                     lldb::addr_t header_load_addr = header_addr.GetLoadAddress (target);
2891                                     if (header_load_addr == LLDB_INVALID_ADDRESS)
2892                                     {
2893                                         header_addr.Dump (&strm, target, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleFileAddress);
2894                                     }
2895                                     else
2896                                     {
2897                                         if (format_char == 'o')
2898                                         {
2899                                             // Show the offset of slide for the image
2900                                             strm.Printf ("0x%*.*llx", addr_nibble_width, addr_nibble_width, header_load_addr - header_addr.GetFileAddress());
2901                                         }
2902                                         else
2903                                         {
2904                                             // Show the load address of the image
2905                                             strm.Printf ("0x%*.*llx", addr_nibble_width, addr_nibble_width, header_load_addr);
2906                                         }
2907                                     }
2908                                     break;
2909                                 }
2910                                 // The address was valid, but the image isn't loaded, output the address in an appropriate format
2911                                 header_addr.Dump (&strm, target, Address::DumpStyleFileAddress);
2912                                 break;
2913                             }
2914                         }
2915                         strm.Printf ("%*s", addr_nibble_width + 2, "");
2916                     }
2917                     break;
2918                 case 'r':
2919                     {
2920                         uint32_t ref_count = 0;
2921                         ModuleSP module_sp (module->shared_from_this());
2922                         if (module_sp)
2923                         {
2924                             // Take one away to make sure we don't count our local "module_sp"
2925                             ref_count = module_sp.use_count() - 1;
2926                         }
2927                         if (width)
2928                             strm.Printf("{%*u}", width, ref_count);
2929                         else
2930                             strm.Printf("{%u}", ref_count);
2931                     }
2932                     break;
2933 
2934                 case 's':
2935                 case 'S':
2936                     {
2937                         SymbolVendor *symbol_vendor = module->GetSymbolVendor();
2938                         if (symbol_vendor)
2939                         {
2940                             SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
2941                             if (symbol_file)
2942                             {
2943                                 if (format_char == 'S')
2944                                 {
2945                                     FileSpec &symfile_spec = symbol_file->GetObjectFile()->GetFileSpec();
2946                                     // Dump symbol file only if different from module file
2947                                     if (!symfile_spec || symfile_spec == module->GetFileSpec())
2948                                     {
2949                                         print_space = false;
2950                                         break;
2951                                     }
2952                                     // Add a newline and indent past the index
2953                                     strm.Printf ("\n%*s", indent, "");
2954                                 }
2955                                 DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
2956                                 dump_object_name = true;
2957                                 break;
2958                             }
2959                         }
2960                         strm.Printf("%.*s", width, "<NONE>");
2961                     }
2962                     break;
2963 
2964                 case 'm':
2965                     module->GetModificationTime().Dump(&strm, width);
2966                     break;
2967 
2968                 case 'p':
2969                     strm.Printf("%p", module);
2970                     break;
2971 
2972                 case 'u':
2973                     DumpModuleUUID(strm, module);
2974                     break;
2975 
2976                 default:
2977                     break;
2978             }
2979 
2980         }
2981         if (dump_object_name)
2982         {
2983             const char *object_name = module->GetObjectName().GetCString();
2984             if (object_name)
2985                 strm.Printf ("(%s)", object_name);
2986         }
2987         strm.EOL();
2988     }
2989 
2990     CommandOptions m_options;
2991 };
2992 
2993 OptionDefinition
2994 CommandObjectTargetModulesList::CommandOptions::g_option_table[] =
2995 {
2996     { LLDB_OPT_SET_1, false, "address",    'a', required_argument, NULL, 0, eArgTypeAddress, "Display the image at this address."},
2997     { LLDB_OPT_SET_1, false, "arch",       'A', optional_argument, NULL, 0, eArgTypeWidth,   "Display the architecture when listing images."},
2998     { LLDB_OPT_SET_1, false, "triple",     't', optional_argument, NULL, 0, eArgTypeWidth,   "Display the triple when listing images."},
2999     { 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."},
3000     { 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)."},
3001     { LLDB_OPT_SET_1, false, "uuid",       'u', no_argument,       NULL, 0, eArgTypeNone,    "Display the UUID when listing images."},
3002     { LLDB_OPT_SET_1, false, "fullpath",   'f', optional_argument, NULL, 0, eArgTypeWidth,   "Display the fullpath to the image object file."},
3003     { LLDB_OPT_SET_1, false, "directory",  'd', optional_argument, NULL, 0, eArgTypeWidth,   "Display the directory with optional width for the image object file."},
3004     { LLDB_OPT_SET_1, false, "basename",   'b', optional_argument, NULL, 0, eArgTypeWidth,   "Display the basename with optional width for the image object file."},
3005     { LLDB_OPT_SET_1, false, "symfile",    's', optional_argument, NULL, 0, eArgTypeWidth,   "Display the fullpath to the image symbol file with optional width."},
3006     { 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."},
3007     { LLDB_OPT_SET_1, false, "mod-time",   'm', optional_argument, NULL, 0, eArgTypeWidth,   "Display the modification time with optional width of the module."},
3008     { 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."},
3009     { LLDB_OPT_SET_1, false, "pointer",    'p', optional_argument, NULL, 0, eArgTypeNone,    "Display the module pointer."},
3010     { 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."},
3011     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
3012 };
3013 
3014 
3015 
3016 //----------------------------------------------------------------------
3017 // Lookup information in images
3018 //----------------------------------------------------------------------
3019 class CommandObjectTargetModulesLookup : public CommandObject
3020 {
3021 public:
3022 
3023     enum
3024     {
3025         eLookupTypeInvalid = -1,
3026         eLookupTypeAddress = 0,
3027         eLookupTypeSymbol,
3028         eLookupTypeFileLine,    // Line is optional
3029         eLookupTypeFunction,
3030         eLookupTypeType,
3031         kNumLookupTypes
3032     };
3033 
3034     class CommandOptions : public Options
3035     {
3036     public:
3037 
3038         CommandOptions (CommandInterpreter &interpreter) :
3039         Options(interpreter)
3040         {
3041             OptionParsingStarting();
3042         }
3043 
3044         virtual
3045         ~CommandOptions ()
3046         {
3047         }
3048 
3049         virtual Error
3050         SetOptionValue (uint32_t option_idx, const char *option_arg)
3051         {
3052             Error error;
3053 
3054             char short_option = (char) m_getopt_table[option_idx].val;
3055 
3056             switch (short_option)
3057             {
3058                 case 'a':
3059                     m_type = eLookupTypeAddress;
3060                     m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
3061                     if (m_addr == LLDB_INVALID_ADDRESS)
3062                         error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg);
3063                     break;
3064 
3065                 case 'o':
3066                     m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
3067                     if (m_offset == LLDB_INVALID_ADDRESS)
3068                         error.SetErrorStringWithFormat ("invalid offset string '%s'", option_arg);
3069                     break;
3070 
3071                 case 's':
3072                     m_str = option_arg;
3073                     m_type = eLookupTypeSymbol;
3074                     break;
3075 
3076                 case 'f':
3077                     m_file.SetFile (option_arg, false);
3078                     m_type = eLookupTypeFileLine;
3079                     break;
3080 
3081                 case 'i':
3082                     m_check_inlines = false;
3083                     break;
3084 
3085                 case 'l':
3086                     m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX);
3087                     if (m_line_number == UINT32_MAX)
3088                         error.SetErrorStringWithFormat ("invalid line number string '%s'", option_arg);
3089                     else if (m_line_number == 0)
3090                         error.SetErrorString ("zero is an invalid line number");
3091                     m_type = eLookupTypeFileLine;
3092                     break;
3093 
3094                 case 'n':
3095                     m_str = option_arg;
3096                     m_type = eLookupTypeFunction;
3097                     break;
3098 
3099                 case 't':
3100                     m_str = option_arg;
3101                     m_type = eLookupTypeType;
3102                     break;
3103 
3104                 case 'v':
3105                     m_verbose = 1;
3106                     break;
3107 
3108                 case 'r':
3109                     m_use_regex = true;
3110                     break;
3111             }
3112 
3113             return error;
3114         }
3115 
3116         void
3117         OptionParsingStarting ()
3118         {
3119             m_type = eLookupTypeInvalid;
3120             m_str.clear();
3121             m_file.Clear();
3122             m_addr = LLDB_INVALID_ADDRESS;
3123             m_offset = 0;
3124             m_line_number = 0;
3125             m_use_regex = false;
3126             m_check_inlines = true;
3127             m_verbose = false;
3128         }
3129 
3130         const OptionDefinition*
3131         GetDefinitions ()
3132         {
3133             return g_option_table;
3134         }
3135 
3136         // Options table: Required for subclasses of Options.
3137 
3138         static OptionDefinition g_option_table[];
3139         int             m_type;         // Should be a eLookupTypeXXX enum after parsing options
3140         std::string     m_str;          // Holds name lookup
3141         FileSpec        m_file;         // Files for file lookups
3142         lldb::addr_t    m_addr;         // Holds the address to lookup
3143         lldb::addr_t    m_offset;       // Subtract this offset from m_addr before doing lookups.
3144         uint32_t        m_line_number;  // Line number for file+line lookups
3145         bool            m_use_regex;    // Name lookups in m_str are regular expressions.
3146         bool            m_check_inlines;// Check for inline entries when looking up by file/line.
3147         bool            m_verbose;      // Enable verbose lookup info
3148 
3149     };
3150 
3151     CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) :
3152     CommandObject (interpreter,
3153                    "target modules lookup",
3154                    "Look up information within executable and dependent shared library images.",
3155                    NULL),
3156     m_options (interpreter)
3157     {
3158         CommandArgumentEntry arg;
3159         CommandArgumentData file_arg;
3160 
3161         // Define the first (and only) variant of this arg.
3162         file_arg.arg_type = eArgTypeFilename;
3163         file_arg.arg_repetition = eArgRepeatStar;
3164 
3165         // There is only one variant this argument could be; put it into the argument entry.
3166         arg.push_back (file_arg);
3167 
3168         // Push the data for the first argument into the m_arguments vector.
3169         m_arguments.push_back (arg);
3170     }
3171 
3172     virtual
3173     ~CommandObjectTargetModulesLookup ()
3174     {
3175     }
3176 
3177     virtual Options *
3178     GetOptions ()
3179     {
3180         return &m_options;
3181     }
3182 
3183 
3184     bool
3185     LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
3186     {
3187         switch (m_options.m_type)
3188         {
3189             case eLookupTypeAddress:
3190                 if (m_options.m_addr != LLDB_INVALID_ADDRESS)
3191                 {
3192                     if (LookupAddressInModule (m_interpreter,
3193                                                result.GetOutputStream(),
3194                                                module,
3195                                                eSymbolContextEverything,
3196                                                m_options.m_addr,
3197                                                m_options.m_offset,
3198                                                m_options.m_verbose))
3199                     {
3200                         result.SetStatus(eReturnStatusSuccessFinishResult);
3201                         return true;
3202                     }
3203                 }
3204                 break;
3205 
3206             case eLookupTypeSymbol:
3207                 if (!m_options.m_str.empty())
3208                 {
3209                     if (LookupSymbolInModule (m_interpreter, result.GetOutputStream(), module, m_options.m_str.c_str(), m_options.m_use_regex))
3210                     {
3211                         result.SetStatus(eReturnStatusSuccessFinishResult);
3212                         return true;
3213                     }
3214                 }
3215                 break;
3216 
3217             case eLookupTypeFileLine:
3218                 if (m_options.m_file)
3219                 {
3220 
3221                     if (LookupFileAndLineInModule (m_interpreter,
3222                                                    result.GetOutputStream(),
3223                                                    module,
3224                                                    m_options.m_file,
3225                                                    m_options.m_line_number,
3226                                                    m_options.m_check_inlines,
3227                                                    m_options.m_verbose))
3228                     {
3229                         result.SetStatus(eReturnStatusSuccessFinishResult);
3230                         return true;
3231                     }
3232                 }
3233                 break;
3234 
3235             case eLookupTypeFunction:
3236                 if (!m_options.m_str.empty())
3237                 {
3238                     if (LookupFunctionInModule (m_interpreter,
3239                                                 result.GetOutputStream(),
3240                                                 module,
3241                                                 m_options.m_str.c_str(),
3242                                                 m_options.m_use_regex,
3243                                                 m_options.m_verbose))
3244                     {
3245                         result.SetStatus(eReturnStatusSuccessFinishResult);
3246                         return true;
3247                     }
3248                 }
3249                 break;
3250 
3251             case eLookupTypeType:
3252                 if (!m_options.m_str.empty())
3253                 {
3254                     if (LookupTypeInModule (m_interpreter,
3255                                             result.GetOutputStream(),
3256                                             module,
3257                                             m_options.m_str.c_str(),
3258                                             m_options.m_use_regex))
3259                     {
3260                         result.SetStatus(eReturnStatusSuccessFinishResult);
3261                         return true;
3262                     }
3263                 }
3264                 break;
3265 
3266             default:
3267                 m_options.GenerateOptionUsage (result.GetErrorStream(), this);
3268                 syntax_error = true;
3269                 break;
3270         }
3271 
3272         result.SetStatus (eReturnStatusFailed);
3273         return false;
3274     }
3275 
3276     virtual bool
3277     Execute (Args& command,
3278              CommandReturnObject &result)
3279     {
3280         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3281         if (target == NULL)
3282         {
3283             result.AppendError ("invalid target, create a debug target using the 'target create' command");
3284             result.SetStatus (eReturnStatusFailed);
3285             return false;
3286         }
3287         else
3288         {
3289             bool syntax_error = false;
3290             uint32_t i;
3291             uint32_t num_successful_lookups = 0;
3292             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3293             result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3294             result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3295             // Dump all sections for all modules images
3296 
3297             if (command.GetArgumentCount() == 0)
3298             {
3299                 // Dump all sections for all modules images
3300                 const uint32_t num_modules = target->GetImages().GetSize();
3301                 if (num_modules > 0)
3302                 {
3303                     for (i = 0; i<num_modules && syntax_error == false; ++i)
3304                     {
3305                         if (LookupInModule (m_interpreter, target->GetImages().GetModulePointerAtIndex(i), result, syntax_error))
3306                         {
3307                             result.GetOutputStream().EOL();
3308                             num_successful_lookups++;
3309                         }
3310                     }
3311                 }
3312                 else
3313                 {
3314                     result.AppendError ("the target has no associated executable images");
3315                     result.SetStatus (eReturnStatusFailed);
3316                     return false;
3317                 }
3318             }
3319             else
3320             {
3321                 // Dump specified images (by basename or fullpath)
3322                 const char *arg_cstr;
3323                 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i)
3324                 {
3325                     ModuleList module_list;
3326                     const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, false);
3327                     if (num_matches > 0)
3328                     {
3329                         for (size_t i=0; i<num_matches; ++i)
3330                         {
3331                             Module *module = module_list.GetModulePointerAtIndex(i);
3332                             if (module)
3333                             {
3334                                 if (LookupInModule (m_interpreter, module, result, syntax_error))
3335                                 {
3336                                     result.GetOutputStream().EOL();
3337                                     num_successful_lookups++;
3338                                 }
3339                             }
3340                         }
3341                     }
3342                     else
3343                         result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
3344                 }
3345             }
3346 
3347             if (num_successful_lookups > 0)
3348                 result.SetStatus (eReturnStatusSuccessFinishResult);
3349             else
3350                 result.SetStatus (eReturnStatusFailed);
3351         }
3352         return result.Succeeded();
3353     }
3354 protected:
3355 
3356     CommandOptions m_options;
3357 };
3358 
3359 OptionDefinition
3360 CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] =
3361 {
3362     { LLDB_OPT_SET_1,   true,  "address",    'a', required_argument, NULL, 0, eArgTypeAddress,      "Lookup an address in one or more target modules."},
3363     { 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."},
3364     { LLDB_OPT_SET_2| LLDB_OPT_SET_4
3365       /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_5 */ ,
3366                         false, "regex",      'r', no_argument,       NULL, 0, eArgTypeNone,         "The <name> argument for name lookups are regular expressions."},
3367     { 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."},
3368     { 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."},
3369     { 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)."},
3370     { LLDB_OPT_SET_3,   false, "no-inlines", 'i', no_argument,       NULL, 0, eArgTypeNone,         "Check inline line entries (must be used in conjunction with --file)."},
3371     { LLDB_OPT_SET_4,   true,  "function",   'n', required_argument, NULL, 0, eArgTypeFunctionName, "Lookup a function by name in the debug symbols in one or more target modules."},
3372     { LLDB_OPT_SET_5,   true,  "type",       't', required_argument, NULL, 0, eArgTypeName,         "Lookup a type by name in the debug symbols in one or more target modules."},
3373     { LLDB_OPT_SET_ALL, false, "verbose",    'v', no_argument,       NULL, 0, eArgTypeNone,         "Enable verbose lookup information."},
3374     { 0, false, NULL,           0, 0,                 NULL, 0, eArgTypeNone, NULL }
3375 };
3376 
3377 
3378 #pragma mark CommandObjectMultiwordImageSearchPaths
3379 
3380 //-------------------------------------------------------------------------
3381 // CommandObjectMultiwordImageSearchPaths
3382 //-------------------------------------------------------------------------
3383 
3384 class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword
3385 {
3386 public:
3387 
3388     CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) :
3389     CommandObjectMultiword (interpreter,
3390                             "target modules search-paths",
3391                             "A set of commands for operating on debugger target image search paths.",
3392                             "target modules search-paths <subcommand> [<subcommand-options>]")
3393     {
3394         LoadSubCommand ("add",     CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter)));
3395         LoadSubCommand ("clear",   CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter)));
3396         LoadSubCommand ("insert",  CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter)));
3397         LoadSubCommand ("list",    CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter)));
3398         LoadSubCommand ("query",   CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter)));
3399     }
3400 
3401     ~CommandObjectTargetModulesImageSearchPaths()
3402     {
3403     }
3404 };
3405 
3406 
3407 
3408 #pragma mark CommandObjectTargetModules
3409 
3410 //-------------------------------------------------------------------------
3411 // CommandObjectTargetModules
3412 //-------------------------------------------------------------------------
3413 
3414 class CommandObjectTargetModules : public CommandObjectMultiword
3415 {
3416 public:
3417     //------------------------------------------------------------------
3418     // Constructors and Destructors
3419     //------------------------------------------------------------------
3420     CommandObjectTargetModules(CommandInterpreter &interpreter) :
3421         CommandObjectMultiword (interpreter,
3422                                 "target modules",
3423                                 "A set of commands for accessing information for one or more target modules.",
3424                                 "target modules <sub-command> ...")
3425     {
3426         LoadSubCommand ("add",          CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter)));
3427         LoadSubCommand ("load",         CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter)));
3428         //LoadSubCommand ("unload",       CommandObjectSP (new CommandObjectTargetModulesUnload (interpreter)));
3429         LoadSubCommand ("dump",         CommandObjectSP (new CommandObjectTargetModulesDump (interpreter)));
3430         LoadSubCommand ("list",         CommandObjectSP (new CommandObjectTargetModulesList (interpreter)));
3431         LoadSubCommand ("lookup",       CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter)));
3432         LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter)));
3433 
3434     }
3435     virtual
3436     ~CommandObjectTargetModules()
3437     {
3438     }
3439 
3440 private:
3441     //------------------------------------------------------------------
3442     // For CommandObjectTargetModules only
3443     //------------------------------------------------------------------
3444     DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules);
3445 };
3446 
3447 
3448 #pragma mark CommandObjectTargetStopHookAdd
3449 
3450 //-------------------------------------------------------------------------
3451 // CommandObjectTargetStopHookAdd
3452 //-------------------------------------------------------------------------
3453 
3454 class CommandObjectTargetStopHookAdd : public CommandObject
3455 {
3456 public:
3457 
3458     class CommandOptions : public Options
3459     {
3460     public:
3461         CommandOptions (CommandInterpreter &interpreter) :
3462             Options(interpreter),
3463             m_line_start(0),
3464             m_line_end (UINT_MAX),
3465             m_func_name_type_mask (eFunctionNameTypeAuto),
3466             m_sym_ctx_specified (false),
3467             m_thread_specified (false),
3468             m_use_one_liner (false),
3469             m_one_liner()
3470         {
3471         }
3472 
3473         ~CommandOptions () {}
3474 
3475         const OptionDefinition*
3476         GetDefinitions ()
3477         {
3478             return g_option_table;
3479         }
3480 
3481         virtual Error
3482         SetOptionValue (uint32_t option_idx, const char *option_arg)
3483         {
3484             Error error;
3485             char short_option = (char) m_getopt_table[option_idx].val;
3486             bool success;
3487 
3488             switch (short_option)
3489             {
3490                 case 'c':
3491                     m_class_name = option_arg;
3492                     m_sym_ctx_specified = true;
3493                 break;
3494 
3495                 case 'e':
3496                     m_line_end = Args::StringToUInt32 (option_arg, UINT_MAX, 0, &success);
3497                     if (!success)
3498                     {
3499                         error.SetErrorStringWithFormat ("invalid end line number: \"%s\"", option_arg);
3500                         break;
3501                     }
3502                     m_sym_ctx_specified = true;
3503                 break;
3504 
3505                 case 'l':
3506                     m_line_start = Args::StringToUInt32 (option_arg, 0, 0, &success);
3507                     if (!success)
3508                     {
3509                         error.SetErrorStringWithFormat ("invalid start line number: \"%s\"", option_arg);
3510                         break;
3511                     }
3512                     m_sym_ctx_specified = true;
3513                 break;
3514 
3515                 case 'n':
3516                     m_function_name = option_arg;
3517                     m_func_name_type_mask |= eFunctionNameTypeAuto;
3518                     m_sym_ctx_specified = true;
3519                 break;
3520 
3521                 case 'f':
3522                     m_file_name = option_arg;
3523                     m_sym_ctx_specified = true;
3524                 break;
3525                 case 's':
3526                     m_module_name = option_arg;
3527                     m_sym_ctx_specified = true;
3528                 break;
3529                 case 't' :
3530                 {
3531                     m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
3532                     if (m_thread_id == LLDB_INVALID_THREAD_ID)
3533                        error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
3534                     m_thread_specified = true;
3535                 }
3536                 break;
3537                 case 'T':
3538                     m_thread_name = option_arg;
3539                     m_thread_specified = true;
3540                 break;
3541                 case 'q':
3542                     m_queue_name = option_arg;
3543                     m_thread_specified = true;
3544                     break;
3545                 case 'x':
3546                 {
3547                     m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
3548                     if (m_thread_id == UINT32_MAX)
3549                        error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
3550                     m_thread_specified = true;
3551                 }
3552                 break;
3553                 case 'o':
3554                     m_use_one_liner = true;
3555                     m_one_liner = option_arg;
3556                 break;
3557                 default:
3558                     error.SetErrorStringWithFormat ("unrecognized option %c.", short_option);
3559                 break;
3560             }
3561             return error;
3562         }
3563 
3564         void
3565         OptionParsingStarting ()
3566         {
3567             m_class_name.clear();
3568             m_function_name.clear();
3569             m_line_start = 0;
3570             m_line_end = UINT_MAX;
3571             m_file_name.clear();
3572             m_module_name.clear();
3573             m_func_name_type_mask = eFunctionNameTypeAuto;
3574             m_thread_id = LLDB_INVALID_THREAD_ID;
3575             m_thread_index = UINT32_MAX;
3576             m_thread_name.clear();
3577             m_queue_name.clear();
3578 
3579             m_sym_ctx_specified = false;
3580             m_thread_specified = false;
3581 
3582             m_use_one_liner = false;
3583             m_one_liner.clear();
3584         }
3585 
3586 
3587         static OptionDefinition g_option_table[];
3588 
3589         std::string m_class_name;
3590         std::string m_function_name;
3591         uint32_t    m_line_start;
3592         uint32_t    m_line_end;
3593         std::string m_file_name;
3594         std::string m_module_name;
3595         uint32_t m_func_name_type_mask;  // A pick from lldb::FunctionNameType.
3596         lldb::tid_t m_thread_id;
3597         uint32_t m_thread_index;
3598         std::string m_thread_name;
3599         std::string m_queue_name;
3600         bool        m_sym_ctx_specified;
3601         bool        m_thread_specified;
3602         // Instance variables to hold the values for one_liner options.
3603         bool m_use_one_liner;
3604         std::string m_one_liner;
3605     };
3606 
3607     Options *
3608     GetOptions ()
3609     {
3610         return &m_options;
3611     }
3612 
3613     CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) :
3614         CommandObject (interpreter,
3615                        "target stop-hook add ",
3616                        "Add a hook to be executed when the target stops.",
3617                        "target stop-hook add"),
3618         m_options (interpreter)
3619     {
3620     }
3621 
3622     ~CommandObjectTargetStopHookAdd ()
3623     {
3624     }
3625 
3626     static size_t
3627     ReadCommandsCallbackFunction (void *baton,
3628                                   InputReader &reader,
3629                                   lldb::InputReaderAction notification,
3630                                   const char *bytes,
3631                                   size_t bytes_len)
3632     {
3633         StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
3634         Target::StopHook *new_stop_hook = ((Target::StopHook *) baton);
3635         static bool got_interrupted;
3636         bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
3637 
3638         switch (notification)
3639         {
3640         case eInputReaderActivate:
3641             if (!batch_mode)
3642             {
3643                 out_stream->Printf ("%s\n", "Enter your stop hook command(s).  Type 'DONE' to end.");
3644                 if (reader.GetPrompt())
3645                     out_stream->Printf ("%s", reader.GetPrompt());
3646                 out_stream->Flush();
3647             }
3648             got_interrupted = false;
3649             break;
3650 
3651         case eInputReaderDeactivate:
3652             break;
3653 
3654         case eInputReaderReactivate:
3655             if (reader.GetPrompt() && !batch_mode)
3656             {
3657                 out_stream->Printf ("%s", reader.GetPrompt());
3658                 out_stream->Flush();
3659             }
3660             got_interrupted = false;
3661             break;
3662 
3663         case eInputReaderAsynchronousOutputWritten:
3664             break;
3665 
3666         case eInputReaderGotToken:
3667             if (bytes && bytes_len && baton)
3668             {
3669                 StringList *commands = new_stop_hook->GetCommandPointer();
3670                 if (commands)
3671                 {
3672                     commands->AppendString (bytes, bytes_len);
3673                 }
3674             }
3675             if (!reader.IsDone() && reader.GetPrompt() && !batch_mode)
3676             {
3677                 out_stream->Printf ("%s", reader.GetPrompt());
3678                 out_stream->Flush();
3679             }
3680             break;
3681 
3682         case eInputReaderInterrupt:
3683             {
3684                 // Finish, and cancel the stop hook.
3685                 new_stop_hook->GetTarget()->RemoveStopHookByID(new_stop_hook->GetID());
3686                 if (!batch_mode)
3687                 {
3688                     out_stream->Printf ("Stop hook cancelled.\n");
3689                     out_stream->Flush();
3690                 }
3691 
3692                 reader.SetIsDone (true);
3693             }
3694             got_interrupted = true;
3695             break;
3696 
3697         case eInputReaderEndOfFile:
3698             reader.SetIsDone (true);
3699             break;
3700 
3701         case eInputReaderDone:
3702             if (!got_interrupted && !batch_mode)
3703             {
3704                 out_stream->Printf ("Stop hook #%llu added.\n", new_stop_hook->GetID());
3705                 out_stream->Flush();
3706             }
3707             break;
3708         }
3709 
3710         return bytes_len;
3711     }
3712 
3713     bool
3714     Execute (Args& command,
3715              CommandReturnObject &result)
3716     {
3717         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3718         if (target)
3719         {
3720             Target::StopHookSP new_hook_sp;
3721             target->AddStopHook (new_hook_sp);
3722 
3723             //  First step, make the specifier.
3724             std::auto_ptr<SymbolContextSpecifier> specifier_ap;
3725             if (m_options.m_sym_ctx_specified)
3726             {
3727                 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget()));
3728 
3729                 if (!m_options.m_module_name.empty())
3730                 {
3731                     specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified);
3732                 }
3733 
3734                 if (!m_options.m_class_name.empty())
3735                 {
3736                     specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified);
3737                 }
3738 
3739                 if (!m_options.m_file_name.empty())
3740                 {
3741                     specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified);
3742                 }
3743 
3744                 if (m_options.m_line_start != 0)
3745                 {
3746                     specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified);
3747                 }
3748 
3749                 if (m_options.m_line_end != UINT_MAX)
3750                 {
3751                     specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
3752                 }
3753 
3754                 if (!m_options.m_function_name.empty())
3755                 {
3756                     specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified);
3757                 }
3758             }
3759 
3760             if (specifier_ap.get())
3761                 new_hook_sp->SetSpecifier (specifier_ap.release());
3762 
3763             // Next see if any of the thread options have been entered:
3764 
3765             if (m_options.m_thread_specified)
3766             {
3767                 ThreadSpec *thread_spec = new ThreadSpec();
3768 
3769                 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
3770                 {
3771                     thread_spec->SetTID (m_options.m_thread_id);
3772                 }
3773 
3774                 if (m_options.m_thread_index != UINT32_MAX)
3775                     thread_spec->SetIndex (m_options.m_thread_index);
3776 
3777                 if (!m_options.m_thread_name.empty())
3778                     thread_spec->SetName (m_options.m_thread_name.c_str());
3779 
3780                 if (!m_options.m_queue_name.empty())
3781                     thread_spec->SetQueueName (m_options.m_queue_name.c_str());
3782 
3783                 new_hook_sp->SetThreadSpecifier (thread_spec);
3784 
3785             }
3786             if (m_options.m_use_one_liner)
3787             {
3788                 // Use one-liner.
3789                 new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str());
3790                 result.AppendMessageWithFormat("Stop hook #%llu added.\n", new_hook_sp->GetID());
3791             }
3792             else
3793             {
3794                 // Otherwise gather up the command list, we'll push an input reader and suck the data from that directly into
3795                 // the new stop hook's command string.
3796                 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
3797                 if (!reader_sp)
3798                 {
3799                     result.AppendError("out of memory\n");
3800                     result.SetStatus (eReturnStatusFailed);
3801                     target->RemoveStopHookByID (new_hook_sp->GetID());
3802                     return false;
3803                 }
3804 
3805                 Error err (reader_sp->Initialize (CommandObjectTargetStopHookAdd::ReadCommandsCallbackFunction,
3806                                                   new_hook_sp.get(), // baton
3807                                                   eInputReaderGranularityLine,  // token size, to pass to callback function
3808                                                   "DONE",                       // end token
3809                                                   "> ",                         // prompt
3810                                                   true));                       // echo input
3811                 if (!err.Success())
3812                 {
3813                     result.AppendError (err.AsCString());
3814                     result.SetStatus (eReturnStatusFailed);
3815                     target->RemoveStopHookByID (new_hook_sp->GetID());
3816                     return false;
3817                 }
3818                 m_interpreter.GetDebugger().PushInputReader (reader_sp);
3819             }
3820             result.SetStatus (eReturnStatusSuccessFinishNoResult);
3821         }
3822         else
3823         {
3824             result.AppendError ("invalid target\n");
3825             result.SetStatus (eReturnStatusFailed);
3826         }
3827 
3828         return result.Succeeded();
3829     }
3830 private:
3831     CommandOptions m_options;
3832 };
3833 
3834 OptionDefinition
3835 CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] =
3836 {
3837     { LLDB_OPT_SET_ALL, false, "one-liner", 'o', required_argument, NULL, NULL, eArgTypeOneLiner,
3838         "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
3839     { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
3840         "Set the module within which the stop-hook is to be run."},
3841     { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, NULL, eArgTypeThreadIndex,
3842         "The stop hook is run only for the thread whose index matches this argument."},
3843     { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, NULL, eArgTypeThreadID,
3844         "The stop hook is run only for the thread whose TID matches this argument."},
3845     { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, NULL, eArgTypeThreadName,
3846         "The stop hook is run only for the thread whose thread name matches this argument."},
3847     { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, NULL, eArgTypeQueueName,
3848         "The stop hook is run only for threads in the queue whose name is given by this argument."},
3849     { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
3850         "Specify the source file within which the stop-hook is to be run." },
3851     { LLDB_OPT_SET_1, false, "start-line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
3852         "Set the start of the line range for which the stop-hook is to be run."},
3853     { LLDB_OPT_SET_1, false, "end-line", 'e', required_argument, NULL, 0, eArgTypeLineNum,
3854         "Set the end of the line range for which the stop-hook is to be run."},
3855     { LLDB_OPT_SET_2, false, "classname", 'c', required_argument, NULL, NULL, eArgTypeClassName,
3856         "Specify the class within which the stop-hook is to be run." },
3857     { LLDB_OPT_SET_3, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
3858         "Set the function name within which the stop hook will be run." },
3859     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
3860 };
3861 
3862 #pragma mark CommandObjectTargetStopHookDelete
3863 
3864 //-------------------------------------------------------------------------
3865 // CommandObjectTargetStopHookDelete
3866 //-------------------------------------------------------------------------
3867 
3868 class CommandObjectTargetStopHookDelete : public CommandObject
3869 {
3870 public:
3871 
3872     CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) :
3873         CommandObject (interpreter,
3874                        "target stop-hook delete",
3875                        "Delete a stop-hook.",
3876                        "target stop-hook delete [<idx>]")
3877     {
3878     }
3879 
3880     ~CommandObjectTargetStopHookDelete ()
3881     {
3882     }
3883 
3884     bool
3885     Execute (Args& command,
3886              CommandReturnObject &result)
3887     {
3888         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3889         if (target)
3890         {
3891             // FIXME: see if we can use the breakpoint id style parser?
3892             size_t num_args = command.GetArgumentCount();
3893             if (num_args == 0)
3894             {
3895                 if (!m_interpreter.Confirm ("Delete all stop hooks?", true))
3896                 {
3897                     result.SetStatus (eReturnStatusFailed);
3898                     return false;
3899                 }
3900                 else
3901                 {
3902                     target->RemoveAllStopHooks();
3903                 }
3904             }
3905             else
3906             {
3907                 bool success;
3908                 for (size_t i = 0; i < num_args; i++)
3909                 {
3910                     lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
3911                     if (!success)
3912                     {
3913                         result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
3914                         result.SetStatus(eReturnStatusFailed);
3915                         return false;
3916                     }
3917                     success = target->RemoveStopHookByID (user_id);
3918                     if (!success)
3919                     {
3920                         result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
3921                         result.SetStatus(eReturnStatusFailed);
3922                         return false;
3923                     }
3924                 }
3925             }
3926             result.SetStatus (eReturnStatusSuccessFinishNoResult);
3927         }
3928         else
3929         {
3930             result.AppendError ("invalid target\n");
3931             result.SetStatus (eReturnStatusFailed);
3932         }
3933 
3934         return result.Succeeded();
3935     }
3936 };
3937 #pragma mark CommandObjectTargetStopHookEnableDisable
3938 
3939 //-------------------------------------------------------------------------
3940 // CommandObjectTargetStopHookEnableDisable
3941 //-------------------------------------------------------------------------
3942 
3943 class CommandObjectTargetStopHookEnableDisable : public CommandObject
3944 {
3945 public:
3946 
3947     CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) :
3948         CommandObject (interpreter,
3949                        name,
3950                        help,
3951                        syntax),
3952         m_enable (enable)
3953     {
3954     }
3955 
3956     ~CommandObjectTargetStopHookEnableDisable ()
3957     {
3958     }
3959 
3960     bool
3961     Execute (Args& command,
3962              CommandReturnObject &result)
3963     {
3964         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3965         if (target)
3966         {
3967             // FIXME: see if we can use the breakpoint id style parser?
3968             size_t num_args = command.GetArgumentCount();
3969             bool success;
3970 
3971             if (num_args == 0)
3972             {
3973                 target->SetAllStopHooksActiveState (m_enable);
3974             }
3975             else
3976             {
3977                 for (size_t i = 0; i < num_args; i++)
3978                 {
3979                     lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
3980                     if (!success)
3981                     {
3982                         result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
3983                         result.SetStatus(eReturnStatusFailed);
3984                         return false;
3985                     }
3986                     success = target->SetStopHookActiveStateByID (user_id, m_enable);
3987                     if (!success)
3988                     {
3989                         result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
3990                         result.SetStatus(eReturnStatusFailed);
3991                         return false;
3992                     }
3993                 }
3994             }
3995             result.SetStatus (eReturnStatusSuccessFinishNoResult);
3996         }
3997         else
3998         {
3999             result.AppendError ("invalid target\n");
4000             result.SetStatus (eReturnStatusFailed);
4001         }
4002         return result.Succeeded();
4003     }
4004 private:
4005     bool m_enable;
4006 };
4007 
4008 #pragma mark CommandObjectTargetStopHookList
4009 
4010 //-------------------------------------------------------------------------
4011 // CommandObjectTargetStopHookList
4012 //-------------------------------------------------------------------------
4013 
4014 class CommandObjectTargetStopHookList : public CommandObject
4015 {
4016 public:
4017 
4018     CommandObjectTargetStopHookList (CommandInterpreter &interpreter) :
4019         CommandObject (interpreter,
4020                        "target stop-hook list",
4021                        "List all stop-hooks.",
4022                        "target stop-hook list [<type>]")
4023     {
4024     }
4025 
4026     ~CommandObjectTargetStopHookList ()
4027     {
4028     }
4029 
4030     bool
4031     Execute (Args& command,
4032              CommandReturnObject &result)
4033     {
4034         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
4035         if (!target)
4036         {
4037             result.AppendError ("invalid target\n");
4038             result.SetStatus (eReturnStatusFailed);
4039             return result.Succeeded();
4040         }
4041 
4042         size_t num_hooks = target->GetNumStopHooks ();
4043         if (num_hooks == 0)
4044         {
4045             result.GetOutputStream().PutCString ("No stop hooks.\n");
4046         }
4047         else
4048         {
4049             for (size_t i = 0; i < num_hooks; i++)
4050             {
4051                 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i);
4052                 if (i > 0)
4053                     result.GetOutputStream().PutCString ("\n");
4054                 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull);
4055             }
4056         }
4057         result.SetStatus (eReturnStatusSuccessFinishResult);
4058         return result.Succeeded();
4059     }
4060 };
4061 
4062 #pragma mark CommandObjectMultiwordTargetStopHooks
4063 //-------------------------------------------------------------------------
4064 // CommandObjectMultiwordTargetStopHooks
4065 //-------------------------------------------------------------------------
4066 
4067 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword
4068 {
4069 public:
4070 
4071     CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) :
4072         CommandObjectMultiword (interpreter,
4073                                 "target stop-hook",
4074                                 "A set of commands for operating on debugger target stop-hooks.",
4075                                 "target stop-hook <subcommand> [<subcommand-options>]")
4076     {
4077         LoadSubCommand ("add",      CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter)));
4078         LoadSubCommand ("delete",   CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter)));
4079         LoadSubCommand ("disable",  CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
4080                                                                                                    false,
4081                                                                                                    "target stop-hook disable [<id>]",
4082                                                                                                    "Disable a stop-hook.",
4083                                                                                                    "target stop-hook disable")));
4084         LoadSubCommand ("enable",   CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
4085                                                                                                    true,
4086                                                                                                    "target stop-hook enable [<id>]",
4087                                                                                                    "Enable a stop-hook.",
4088                                                                                                    "target stop-hook enable")));
4089         LoadSubCommand ("list",     CommandObjectSP (new CommandObjectTargetStopHookList (interpreter)));
4090     }
4091 
4092     ~CommandObjectMultiwordTargetStopHooks()
4093     {
4094     }
4095 };
4096 
4097 
4098 
4099 #pragma mark CommandObjectMultiwordTarget
4100 
4101 //-------------------------------------------------------------------------
4102 // CommandObjectMultiwordTarget
4103 //-------------------------------------------------------------------------
4104 
4105 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) :
4106     CommandObjectMultiword (interpreter,
4107                             "target",
4108                             "A set of commands for operating on debugger targets.",
4109                             "target <subcommand> [<subcommand-options>]")
4110 {
4111 
4112     LoadSubCommand ("create",    CommandObjectSP (new CommandObjectTargetCreate (interpreter)));
4113     LoadSubCommand ("delete",    CommandObjectSP (new CommandObjectTargetDelete (interpreter)));
4114     LoadSubCommand ("list",      CommandObjectSP (new CommandObjectTargetList   (interpreter)));
4115     LoadSubCommand ("select",    CommandObjectSP (new CommandObjectTargetSelect (interpreter)));
4116     LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter)));
4117     LoadSubCommand ("modules",   CommandObjectSP (new CommandObjectTargetModules (interpreter)));
4118     LoadSubCommand ("variable",  CommandObjectSP (new CommandObjectTargetVariable (interpreter)));
4119 }
4120 
4121 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget ()
4122 {
4123 }
4124 
4125 
4126