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