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                                                  eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector,
1503                                                  include_symbols,
1504                                                  append,
1505                                                  sc_list);
1506         }
1507 
1508         if (num_matches)
1509         {
1510             strm.Indent ();
1511             strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1512             DumpFullpath (strm, &module->GetFileSpec(), 0);
1513             strm.PutCString(":\n");
1514             DumpSymbolContextList (interpreter, strm, sc_list, true, verbose);
1515         }
1516         return num_matches;
1517     }
1518     return 0;
1519 }
1520 
1521 static uint32_t
1522 LookupTypeInModule (CommandInterpreter &interpreter,
1523                     Stream &strm,
1524                     Module *module,
1525                     const char *name_cstr,
1526                     bool name_is_regex)
1527 {
1528     if (module && name_cstr && name_cstr[0])
1529     {
1530         /*SymbolContextList sc_list;
1531 
1532         SymbolVendor *symbol_vendor = module->GetSymbolVendor();
1533         if (symbol_vendor)
1534         {*/
1535             TypeList type_list;
1536             uint32_t num_matches = 0;
1537             SymbolContext sc;
1538             //            if (name_is_regex)
1539             //            {
1540             //                RegularExpression name_regex (name_cstr);
1541             //                num_matches = symbol_vendor->FindFunctions(sc, name_regex, true, UINT32_MAX, type_list);
1542             //            }
1543             //            else
1544             //            {
1545             ConstString name(name_cstr);
1546             num_matches = module->FindTypes(sc, name, true, UINT32_MAX, type_list);
1547             //            }
1548 
1549             if (num_matches)
1550             {
1551                 strm.Indent ();
1552                 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1553                 DumpFullpath (strm, &module->GetFileSpec(), 0);
1554                 strm.PutCString(":\n");
1555                 const uint32_t num_types = type_list.GetSize();
1556                 for (uint32_t i=0; i<num_types; ++i)
1557                 {
1558                     TypeSP type_sp (type_list.GetTypeAtIndex(i));
1559                     if (type_sp)
1560                     {
1561                         // Resolve the clang type so that any forward references
1562                         // to types that haven't yet been parsed will get parsed.
1563                         type_sp->GetClangFullType ();
1564                         type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
1565                     }
1566                     strm.EOL();
1567                 }
1568             }
1569             return num_matches;
1570         //}
1571     }
1572     return 0;
1573 }
1574 
1575 static uint32_t
1576 LookupFileAndLineInModule (CommandInterpreter &interpreter,
1577                            Stream &strm,
1578                            Module *module,
1579                            const FileSpec &file_spec,
1580                            uint32_t line,
1581                            bool check_inlines,
1582                            bool verbose)
1583 {
1584     if (module && file_spec)
1585     {
1586         SymbolContextList sc_list;
1587         const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
1588                                                                               eSymbolContextEverything, sc_list);
1589         if (num_matches > 0)
1590         {
1591             strm.Indent ();
1592             strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1593             strm << file_spec;
1594             if (line > 0)
1595                 strm.Printf (":%u", line);
1596             strm << " in ";
1597             DumpFullpath (strm, &module->GetFileSpec(), 0);
1598             strm.PutCString(":\n");
1599             DumpSymbolContextList (interpreter, strm, sc_list, true, verbose);
1600             return num_matches;
1601         }
1602     }
1603     return 0;
1604 
1605 }
1606 
1607 #pragma mark CommandObjectTargetModulesModuleAutoComplete
1608 
1609 //----------------------------------------------------------------------
1610 // A base command object class that can auto complete with module file
1611 // paths
1612 //----------------------------------------------------------------------
1613 
1614 class CommandObjectTargetModulesModuleAutoComplete : public CommandObject
1615 {
1616 public:
1617 
1618     CommandObjectTargetModulesModuleAutoComplete (CommandInterpreter &interpreter,
1619                                       const char *name,
1620                                       const char *help,
1621                                       const char *syntax) :
1622     CommandObject (interpreter, name, help, syntax)
1623     {
1624         CommandArgumentEntry arg;
1625         CommandArgumentData file_arg;
1626 
1627         // Define the first (and only) variant of this arg.
1628         file_arg.arg_type = eArgTypeFilename;
1629         file_arg.arg_repetition = eArgRepeatStar;
1630 
1631         // There is only one variant this argument could be; put it into the argument entry.
1632         arg.push_back (file_arg);
1633 
1634         // Push the data for the first argument into the m_arguments vector.
1635         m_arguments.push_back (arg);
1636     }
1637 
1638     virtual
1639     ~CommandObjectTargetModulesModuleAutoComplete ()
1640     {
1641     }
1642 
1643     virtual int
1644     HandleArgumentCompletion (Args &input,
1645                               int &cursor_index,
1646                               int &cursor_char_position,
1647                               OptionElementVector &opt_element_vector,
1648                               int match_start_point,
1649                               int max_return_elements,
1650                               bool &word_complete,
1651                               StringList &matches)
1652     {
1653         // Arguments are the standard module completer.
1654         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1655         completion_str.erase (cursor_char_position);
1656 
1657         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1658                                                              CommandCompletions::eModuleCompletion,
1659                                                              completion_str.c_str(),
1660                                                              match_start_point,
1661                                                              max_return_elements,
1662                                                              NULL,
1663                                                              word_complete,
1664                                                              matches);
1665         return matches.GetSize();
1666     }
1667 };
1668 
1669 #pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1670 
1671 //----------------------------------------------------------------------
1672 // A base command object class that can auto complete with module source
1673 // file paths
1674 //----------------------------------------------------------------------
1675 
1676 class CommandObjectTargetModulesSourceFileAutoComplete : public CommandObject
1677 {
1678 public:
1679 
1680     CommandObjectTargetModulesSourceFileAutoComplete (CommandInterpreter &interpreter,
1681                                           const char *name,
1682                                           const char *help,
1683                                           const char *syntax) :
1684     CommandObject (interpreter, name, help, syntax)
1685     {
1686         CommandArgumentEntry arg;
1687         CommandArgumentData source_file_arg;
1688 
1689         // Define the first (and only) variant of this arg.
1690         source_file_arg.arg_type = eArgTypeSourceFile;
1691         source_file_arg.arg_repetition = eArgRepeatPlus;
1692 
1693         // There is only one variant this argument could be; put it into the argument entry.
1694         arg.push_back (source_file_arg);
1695 
1696         // Push the data for the first argument into the m_arguments vector.
1697         m_arguments.push_back (arg);
1698     }
1699 
1700     virtual
1701     ~CommandObjectTargetModulesSourceFileAutoComplete ()
1702     {
1703     }
1704 
1705     virtual int
1706     HandleArgumentCompletion (Args &input,
1707                               int &cursor_index,
1708                               int &cursor_char_position,
1709                               OptionElementVector &opt_element_vector,
1710                               int match_start_point,
1711                               int max_return_elements,
1712                               bool &word_complete,
1713                               StringList &matches)
1714     {
1715         // Arguments are the standard source file completer.
1716         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1717         completion_str.erase (cursor_char_position);
1718 
1719         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1720                                                              CommandCompletions::eSourceFileCompletion,
1721                                                              completion_str.c_str(),
1722                                                              match_start_point,
1723                                                              max_return_elements,
1724                                                              NULL,
1725                                                              word_complete,
1726                                                              matches);
1727         return matches.GetSize();
1728     }
1729 };
1730 
1731 
1732 #pragma mark CommandObjectTargetModulesDumpSymtab
1733 
1734 
1735 class CommandObjectTargetModulesDumpSymtab : public CommandObjectTargetModulesModuleAutoComplete
1736 {
1737 public:
1738     CommandObjectTargetModulesDumpSymtab (CommandInterpreter &interpreter) :
1739     CommandObjectTargetModulesModuleAutoComplete (interpreter,
1740                                       "target modules dump symtab",
1741                                       "Dump the symbol table from one or more target modules.",
1742                                       NULL),
1743     m_options (interpreter)
1744     {
1745     }
1746 
1747     virtual
1748     ~CommandObjectTargetModulesDumpSymtab ()
1749     {
1750     }
1751 
1752     virtual bool
1753     Execute (Args& command,
1754              CommandReturnObject &result)
1755     {
1756         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1757         if (target == NULL)
1758         {
1759             result.AppendError ("invalid target, create a debug target using the 'target create' command");
1760             result.SetStatus (eReturnStatusFailed);
1761             return false;
1762         }
1763         else
1764         {
1765             uint32_t num_dumped = 0;
1766 
1767             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1768             result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1769             result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1770 
1771             if (command.GetArgumentCount() == 0)
1772             {
1773                 // Dump all sections for all modules images
1774                 const uint32_t num_modules = target->GetImages().GetSize();
1775                 if (num_modules > 0)
1776                 {
1777                     result.GetOutputStream().Printf("Dumping symbol table for %u modules.\n", num_modules);
1778                     for (uint32_t image_idx = 0;  image_idx<num_modules; ++image_idx)
1779                     {
1780                         if (num_dumped > 0)
1781                         {
1782                             result.GetOutputStream().EOL();
1783                             result.GetOutputStream().EOL();
1784                         }
1785                         num_dumped++;
1786                         DumpModuleSymtab (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx), m_options.m_sort_order);
1787                     }
1788                 }
1789                 else
1790                 {
1791                     result.AppendError ("the target has no associated executable images");
1792                     result.SetStatus (eReturnStatusFailed);
1793                     return false;
1794                 }
1795             }
1796             else
1797             {
1798                 // Dump specified images (by basename or fullpath)
1799                 const char *arg_cstr;
1800                 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
1801                 {
1802                     FileSpec image_file(arg_cstr, false);
1803                     ModuleList matching_modules;
1804                     size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
1805 
1806                     // Not found in our module list for our target, check the main
1807                     // shared module list in case it is a extra file used somewhere
1808                     // else
1809                     if (num_matching_modules == 0)
1810                         num_matching_modules = ModuleList::FindSharedModules (image_file,
1811                                                                               target->GetArchitecture(),
1812                                                                               NULL,
1813                                                                               NULL,
1814                                                                               matching_modules);
1815 
1816                     if (num_matching_modules > 0)
1817                     {
1818                         for (size_t i=0; i<num_matching_modules; ++i)
1819                         {
1820                             Module *image_module = matching_modules.GetModulePointerAtIndex(i);
1821                             if (image_module)
1822                             {
1823                                 if (num_dumped > 0)
1824                                 {
1825                                     result.GetOutputStream().EOL();
1826                                     result.GetOutputStream().EOL();
1827                                 }
1828                                 num_dumped++;
1829                                 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), image_module, m_options.m_sort_order);
1830                             }
1831                         }
1832                     }
1833                     else
1834                         result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
1835                 }
1836             }
1837 
1838             if (num_dumped > 0)
1839                 result.SetStatus (eReturnStatusSuccessFinishResult);
1840             else
1841             {
1842                 result.AppendError ("no matching executable images found");
1843                 result.SetStatus (eReturnStatusFailed);
1844             }
1845         }
1846         return result.Succeeded();
1847     }
1848 
1849     virtual Options *
1850     GetOptions ()
1851     {
1852         return &m_options;
1853     }
1854 
1855     class CommandOptions : public Options
1856     {
1857     public:
1858 
1859         CommandOptions (CommandInterpreter &interpreter) :
1860         Options(interpreter),
1861         m_sort_order (eSortOrderNone)
1862         {
1863         }
1864 
1865         virtual
1866         ~CommandOptions ()
1867         {
1868         }
1869 
1870         virtual Error
1871         SetOptionValue (uint32_t option_idx, const char *option_arg)
1872         {
1873             Error error;
1874             char short_option = (char) m_getopt_table[option_idx].val;
1875 
1876             switch (short_option)
1877             {
1878                 case 's':
1879                     m_sort_order = (SortOrder) Args::StringToOptionEnum (option_arg,
1880                                                                          g_option_table[option_idx].enum_values,
1881                                                                          eSortOrderNone,
1882                                                                          error);
1883                     break;
1884 
1885                 default:
1886                     error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
1887                     break;
1888 
1889             }
1890             return error;
1891         }
1892 
1893         void
1894         OptionParsingStarting ()
1895         {
1896             m_sort_order = eSortOrderNone;
1897         }
1898 
1899         const OptionDefinition*
1900         GetDefinitions ()
1901         {
1902             return g_option_table;
1903         }
1904 
1905         // Options table: Required for subclasses of Options.
1906         static OptionDefinition g_option_table[];
1907 
1908         SortOrder m_sort_order;
1909     };
1910 
1911 protected:
1912 
1913     CommandOptions m_options;
1914 };
1915 
1916 static OptionEnumValueElement
1917 g_sort_option_enumeration[4] =
1918 {
1919     { eSortOrderNone,       "none",     "No sorting, use the original symbol table order."},
1920     { eSortOrderByAddress,  "address",  "Sort output by symbol address."},
1921     { eSortOrderByName,     "name",     "Sort output by symbol name."},
1922     { 0,                    NULL,       NULL }
1923 };
1924 
1925 
1926 OptionDefinition
1927 CommandObjectTargetModulesDumpSymtab::CommandOptions::g_option_table[] =
1928 {
1929     { LLDB_OPT_SET_1, false, "sort", 's', required_argument, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."},
1930     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1931 };
1932 
1933 #pragma mark CommandObjectTargetModulesDumpSections
1934 
1935 //----------------------------------------------------------------------
1936 // Image section dumping command
1937 //----------------------------------------------------------------------
1938 
1939 class CommandObjectTargetModulesDumpSections : public CommandObjectTargetModulesModuleAutoComplete
1940 {
1941 public:
1942     CommandObjectTargetModulesDumpSections (CommandInterpreter &interpreter) :
1943     CommandObjectTargetModulesModuleAutoComplete (interpreter,
1944                                       "target modules dump sections",
1945                                       "Dump the sections from one or more target modules.",
1946                                       //"target modules dump sections [<file1> ...]")
1947                                       NULL)
1948     {
1949     }
1950 
1951     virtual
1952     ~CommandObjectTargetModulesDumpSections ()
1953     {
1954     }
1955 
1956     virtual bool
1957     Execute (Args& command,
1958              CommandReturnObject &result)
1959     {
1960         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1961         if (target == NULL)
1962         {
1963             result.AppendError ("invalid target, create a debug target using the 'target create' command");
1964             result.SetStatus (eReturnStatusFailed);
1965             return false;
1966         }
1967         else
1968         {
1969             uint32_t num_dumped = 0;
1970 
1971             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1972             result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1973             result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1974 
1975             if (command.GetArgumentCount() == 0)
1976             {
1977                 // Dump all sections for all modules images
1978                 const uint32_t num_modules = target->GetImages().GetSize();
1979                 if (num_modules > 0)
1980                 {
1981                     result.GetOutputStream().Printf("Dumping sections for %u modules.\n", num_modules);
1982                     for (uint32_t image_idx = 0;  image_idx<num_modules; ++image_idx)
1983                     {
1984                         num_dumped++;
1985                         DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
1986                     }
1987                 }
1988                 else
1989                 {
1990                     result.AppendError ("the target has no associated executable images");
1991                     result.SetStatus (eReturnStatusFailed);
1992                     return false;
1993                 }
1994             }
1995             else
1996             {
1997                 // Dump specified images (by basename or fullpath)
1998                 const char *arg_cstr;
1999                 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2000                 {
2001                     FileSpec image_file(arg_cstr, false);
2002                     ModuleList matching_modules;
2003                     size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
2004 
2005                     // Not found in our module list for our target, check the main
2006                     // shared module list in case it is a extra file used somewhere
2007                     // else
2008                     if (num_matching_modules == 0)
2009                         num_matching_modules = ModuleList::FindSharedModules (image_file,
2010                                                                               target->GetArchitecture(),
2011                                                                               NULL,
2012                                                                               NULL,
2013                                                                               matching_modules);
2014 
2015                     if (num_matching_modules > 0)
2016                     {
2017                         for (size_t i=0; i<num_matching_modules; ++i)
2018                         {
2019                             Module * image_module = matching_modules.GetModulePointerAtIndex(i);
2020                             if (image_module)
2021                             {
2022                                 num_dumped++;
2023                                 DumpModuleSections (m_interpreter, result.GetOutputStream(), image_module);
2024                             }
2025                         }
2026                     }
2027                     else
2028                         result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
2029                 }
2030             }
2031 
2032             if (num_dumped > 0)
2033                 result.SetStatus (eReturnStatusSuccessFinishResult);
2034             else
2035             {
2036                 result.AppendError ("no matching executable images found");
2037                 result.SetStatus (eReturnStatusFailed);
2038             }
2039         }
2040         return result.Succeeded();
2041     }
2042 };
2043 
2044 
2045 #pragma mark CommandObjectTargetModulesDumpSymfile
2046 
2047 //----------------------------------------------------------------------
2048 // Image debug symbol dumping command
2049 //----------------------------------------------------------------------
2050 
2051 class CommandObjectTargetModulesDumpSymfile : public CommandObjectTargetModulesModuleAutoComplete
2052 {
2053 public:
2054     CommandObjectTargetModulesDumpSymfile (CommandInterpreter &interpreter) :
2055     CommandObjectTargetModulesModuleAutoComplete (interpreter,
2056                                       "target modules dump symfile",
2057                                       "Dump the debug symbol file for one or more target modules.",
2058                                       //"target modules dump symfile [<file1> ...]")
2059                                       NULL)
2060     {
2061     }
2062 
2063     virtual
2064     ~CommandObjectTargetModulesDumpSymfile ()
2065     {
2066     }
2067 
2068     virtual bool
2069     Execute (Args& command,
2070              CommandReturnObject &result)
2071     {
2072         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2073         if (target == NULL)
2074         {
2075             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2076             result.SetStatus (eReturnStatusFailed);
2077             return false;
2078         }
2079         else
2080         {
2081             uint32_t num_dumped = 0;
2082 
2083             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2084             result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2085             result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2086 
2087             if (command.GetArgumentCount() == 0)
2088             {
2089                 // Dump all sections for all modules images
2090                 const uint32_t num_modules = target->GetImages().GetSize();
2091                 if (num_modules > 0)
2092                 {
2093                     result.GetOutputStream().Printf("Dumping debug symbols for %u modules.\n", num_modules);
2094                     for (uint32_t image_idx = 0;  image_idx<num_modules; ++image_idx)
2095                     {
2096                         if (DumpModuleSymbolVendor (result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx)))
2097                             num_dumped++;
2098                     }
2099                 }
2100                 else
2101                 {
2102                     result.AppendError ("the target has no associated executable images");
2103                     result.SetStatus (eReturnStatusFailed);
2104                     return false;
2105                 }
2106             }
2107             else
2108             {
2109                 // Dump specified images (by basename or fullpath)
2110                 const char *arg_cstr;
2111                 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2112                 {
2113                     FileSpec image_file(arg_cstr, false);
2114                     ModuleList matching_modules;
2115                     size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
2116 
2117                     // Not found in our module list for our target, check the main
2118                     // shared module list in case it is a extra file used somewhere
2119                     // else
2120                     if (num_matching_modules == 0)
2121                         num_matching_modules = ModuleList::FindSharedModules (image_file,
2122                                                                               target->GetArchitecture(),
2123                                                                               NULL,
2124                                                                               NULL,
2125                                                                               matching_modules);
2126 
2127                     if (num_matching_modules > 0)
2128                     {
2129                         for (size_t i=0; i<num_matching_modules; ++i)
2130                         {
2131                             Module * image_module = matching_modules.GetModulePointerAtIndex(i);
2132                             if (image_module)
2133                             {
2134                                 if (DumpModuleSymbolVendor (result.GetOutputStream(), image_module))
2135                                     num_dumped++;
2136                             }
2137                         }
2138                     }
2139                     else
2140                         result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
2141                 }
2142             }
2143 
2144             if (num_dumped > 0)
2145                 result.SetStatus (eReturnStatusSuccessFinishResult);
2146             else
2147             {
2148                 result.AppendError ("no matching executable images found");
2149                 result.SetStatus (eReturnStatusFailed);
2150             }
2151         }
2152         return result.Succeeded();
2153     }
2154 };
2155 
2156 
2157 #pragma mark CommandObjectTargetModulesDumpLineTable
2158 
2159 //----------------------------------------------------------------------
2160 // Image debug line table dumping command
2161 //----------------------------------------------------------------------
2162 
2163 class CommandObjectTargetModulesDumpLineTable : public CommandObjectTargetModulesSourceFileAutoComplete
2164 {
2165 public:
2166     CommandObjectTargetModulesDumpLineTable (CommandInterpreter &interpreter) :
2167     CommandObjectTargetModulesSourceFileAutoComplete (interpreter,
2168                                           "target modules dump line-table",
2169                                           "Dump the debug symbol file for one or more target modules.",
2170                                           NULL)
2171     {
2172     }
2173 
2174     virtual
2175     ~CommandObjectTargetModulesDumpLineTable ()
2176     {
2177     }
2178 
2179     virtual bool
2180     Execute (Args& command,
2181              CommandReturnObject &result)
2182     {
2183         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2184         if (target == NULL)
2185         {
2186             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2187             result.SetStatus (eReturnStatusFailed);
2188             return false;
2189         }
2190         else
2191         {
2192             ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
2193             uint32_t total_num_dumped = 0;
2194 
2195             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2196             result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2197             result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2198 
2199             if (command.GetArgumentCount() == 0)
2200             {
2201                 result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str());
2202                 result.SetStatus (eReturnStatusFailed);
2203             }
2204             else
2205             {
2206                 // Dump specified images (by basename or fullpath)
2207                 const char *arg_cstr;
2208                 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2209                 {
2210                     FileSpec file_spec(arg_cstr, false);
2211                     const uint32_t num_modules = target->GetImages().GetSize();
2212                     if (num_modules > 0)
2213                     {
2214                         uint32_t num_dumped = 0;
2215                         for (uint32_t i = 0; i<num_modules; ++i)
2216                         {
2217                             if (DumpCompileUnitLineTable (m_interpreter,
2218                                                           result.GetOutputStream(),
2219                                                           target->GetImages().GetModulePointerAtIndex(i),
2220                                                           file_spec,
2221                                                           exe_ctx.GetProcessPtr() && exe_ctx.GetProcessRef().IsAlive()))
2222                                 num_dumped++;
2223                         }
2224                         if (num_dumped == 0)
2225                             result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr);
2226                         else
2227                             total_num_dumped += num_dumped;
2228                     }
2229                 }
2230             }
2231 
2232             if (total_num_dumped > 0)
2233                 result.SetStatus (eReturnStatusSuccessFinishResult);
2234             else
2235             {
2236                 result.AppendError ("no source filenames matched any command arguments");
2237                 result.SetStatus (eReturnStatusFailed);
2238             }
2239         }
2240         return result.Succeeded();
2241     }
2242 };
2243 
2244 
2245 #pragma mark CommandObjectTargetModulesDump
2246 
2247 //----------------------------------------------------------------------
2248 // Dump multi-word command for target modules
2249 //----------------------------------------------------------------------
2250 
2251 class CommandObjectTargetModulesDump : public CommandObjectMultiword
2252 {
2253 public:
2254 
2255     //------------------------------------------------------------------
2256     // Constructors and Destructors
2257     //------------------------------------------------------------------
2258     CommandObjectTargetModulesDump(CommandInterpreter &interpreter) :
2259     CommandObjectMultiword (interpreter,
2260                             "target modules dump",
2261                             "A set of commands for dumping information about one or more target modules.",
2262                             "target modules dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]")
2263     {
2264         LoadSubCommand ("symtab",      CommandObjectSP (new CommandObjectTargetModulesDumpSymtab (interpreter)));
2265         LoadSubCommand ("sections",    CommandObjectSP (new CommandObjectTargetModulesDumpSections (interpreter)));
2266         LoadSubCommand ("symfile",     CommandObjectSP (new CommandObjectTargetModulesDumpSymfile (interpreter)));
2267         LoadSubCommand ("line-table",  CommandObjectSP (new CommandObjectTargetModulesDumpLineTable (interpreter)));
2268     }
2269 
2270     virtual
2271     ~CommandObjectTargetModulesDump()
2272     {
2273     }
2274 };
2275 
2276 class CommandObjectTargetModulesAdd : public CommandObject
2277 {
2278 public:
2279     CommandObjectTargetModulesAdd (CommandInterpreter &interpreter) :
2280     CommandObject (interpreter,
2281                    "target modules add",
2282                    "Add a new module to the current target's modules.",
2283                    "target modules add [<module>]")
2284     {
2285     }
2286 
2287     virtual
2288     ~CommandObjectTargetModulesAdd ()
2289     {
2290     }
2291 
2292     virtual bool
2293     Execute (Args& args,
2294              CommandReturnObject &result)
2295     {
2296         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2297         if (target == NULL)
2298         {
2299             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2300             result.SetStatus (eReturnStatusFailed);
2301             return false;
2302         }
2303         else
2304         {
2305             const size_t argc = args.GetArgumentCount();
2306             if (argc == 0)
2307             {
2308                 result.AppendError ("one or more executable image paths must be specified");
2309                 result.SetStatus (eReturnStatusFailed);
2310                 return false;
2311             }
2312             else
2313             {
2314                 for (size_t i=0; i<argc; ++i)
2315                 {
2316                     const char *path = args.GetArgumentAtIndex(i);
2317                     if (path)
2318                     {
2319                         FileSpec file_spec(path, true);
2320                         ArchSpec arch;
2321                         if (file_spec.Exists())
2322                         {
2323                             ModuleSP module_sp (target->GetSharedModule(file_spec, arch));
2324                             if (!module_sp)
2325                             {
2326                                 result.AppendError ("one or more executable image paths must be specified");
2327                                 result.SetStatus (eReturnStatusFailed);
2328                                 return false;
2329                             }
2330                             result.SetStatus (eReturnStatusSuccessFinishResult);
2331                         }
2332                         else
2333                         {
2334                             char resolved_path[PATH_MAX];
2335                             result.SetStatus (eReturnStatusFailed);
2336                             if (file_spec.GetPath (resolved_path, sizeof(resolved_path)))
2337                             {
2338                                 if (strcmp (resolved_path, path) != 0)
2339                                 {
2340                                     result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", path, resolved_path);
2341                                     break;
2342                                 }
2343                             }
2344                             result.AppendErrorWithFormat ("invalid module path '%s'\n", path);
2345                             break;
2346                         }
2347                     }
2348                 }
2349             }
2350         }
2351         return result.Succeeded();
2352     }
2353 
2354     int
2355     HandleArgumentCompletion (Args &input,
2356                               int &cursor_index,
2357                               int &cursor_char_position,
2358                               OptionElementVector &opt_element_vector,
2359                               int match_start_point,
2360                               int max_return_elements,
2361                               bool &word_complete,
2362                               StringList &matches)
2363     {
2364         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2365         completion_str.erase (cursor_char_position);
2366 
2367         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
2368                                                              CommandCompletions::eDiskFileCompletion,
2369                                                              completion_str.c_str(),
2370                                                              match_start_point,
2371                                                              max_return_elements,
2372                                                              NULL,
2373                                                              word_complete,
2374                                                              matches);
2375         return matches.GetSize();
2376     }
2377 
2378 };
2379 
2380 class CommandObjectTargetModulesLoad : public CommandObjectTargetModulesModuleAutoComplete
2381 {
2382 public:
2383     CommandObjectTargetModulesLoad (CommandInterpreter &interpreter) :
2384         CommandObjectTargetModulesModuleAutoComplete (interpreter,
2385                                                       "target modules load",
2386                                                       "Set the load addresses for one or more sections in a target module.",
2387                                                       "target modules load [--file <module> --uuid <uuid>] <sect-name> <address> [<sect-name> <address> ....]"),
2388         m_option_group (interpreter),
2389         m_file_option (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypePath, "Fullpath or basename for module to load."),
2390         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)
2391     {
2392         m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2393         m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2394         m_option_group.Append (&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2395         m_option_group.Finalize();
2396     }
2397 
2398     virtual
2399     ~CommandObjectTargetModulesLoad ()
2400     {
2401     }
2402 
2403     virtual bool
2404     Execute (Args& args,
2405              CommandReturnObject &result)
2406     {
2407         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2408         if (target == NULL)
2409         {
2410             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2411             result.SetStatus (eReturnStatusFailed);
2412             return false;
2413         }
2414         else
2415         {
2416             const size_t argc = args.GetArgumentCount();
2417             const FileSpec *file_ptr = NULL;
2418             const UUID *uuid_ptr = NULL;
2419             if (m_file_option.GetOptionValue().OptionWasSet())
2420                 file_ptr = &m_file_option.GetOptionValue().GetCurrentValue();
2421 
2422             if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2423                 uuid_ptr = &m_uuid_option_group.GetOptionValue().GetCurrentValue();
2424 
2425             if (file_ptr || uuid_ptr)
2426             {
2427 
2428                 ModuleList matching_modules;
2429                 const size_t num_matches = target->GetImages().FindModules (file_ptr,   // File spec to match (can be NULL to match by UUID only)
2430                                                                             NULL,       // Architecture
2431                                                                             uuid_ptr,   // UUID to match (can be NULL to not match on UUID)
2432                                                                             NULL,       // Object name
2433                                                                             matching_modules);
2434 
2435                 char path[PATH_MAX];
2436                 if (num_matches == 1)
2437                 {
2438                     Module *module = matching_modules.GetModulePointerAtIndex(0);
2439                     if (module)
2440                     {
2441                         ObjectFile *objfile = module->GetObjectFile();
2442                         if (objfile)
2443                         {
2444                             SectionList *section_list = objfile->GetSectionList();
2445                             if (section_list)
2446                             {
2447                                 if (argc == 0)
2448                                 {
2449                                     if (m_slide_option.GetOptionValue().OptionWasSet())
2450                                     {
2451                                         Module *module = matching_modules.GetModulePointerAtIndex(0);
2452                                         if (module)
2453                                         {
2454                                             ObjectFile *objfile = module->GetObjectFile();
2455                                             if (objfile)
2456                                             {
2457                                                 SectionList *section_list = objfile->GetSectionList();
2458                                                 if (section_list)
2459                                                 {
2460                                                     const size_t num_sections = section_list->GetSize();
2461                                                     const addr_t slide = m_slide_option.GetOptionValue().GetCurrentValue();
2462                                                     for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
2463                                                     {
2464                                                         SectionSP section_sp (section_list->GetSectionAtIndex(sect_idx));
2465                                                         if (section_sp)
2466                                                             target->GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), section_sp->GetFileAddress() + slide);
2467                                                     }
2468                                                 }
2469                                             }
2470                                         }
2471                                     }
2472                                     else
2473                                     {
2474                                         result.AppendError ("one or more section name + load address pair must be specified");
2475                                         result.SetStatus (eReturnStatusFailed);
2476                                         return false;
2477                                     }
2478                                 }
2479                                 else
2480                                 {
2481                                     if (m_slide_option.GetOptionValue().OptionWasSet())
2482                                     {
2483                                         result.AppendError ("The \"--slide <offset>\" option can't be used in conjunction with setting section load addresses.\n");
2484                                         result.SetStatus (eReturnStatusFailed);
2485                                         return false;
2486                                     }
2487 
2488                                     for (size_t i=0; i<argc; i += 2)
2489                                     {
2490                                         const char *sect_name = args.GetArgumentAtIndex(i);
2491                                         const char *load_addr_cstr = args.GetArgumentAtIndex(i+1);
2492                                         if (sect_name && load_addr_cstr)
2493                                         {
2494                                             ConstString const_sect_name(sect_name);
2495                                             bool success = false;
2496                                             addr_t load_addr = Args::StringToUInt64(load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
2497                                             if (success)
2498                                             {
2499                                                 SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
2500                                                 if (section_sp)
2501                                                 {
2502                                                     target->GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), load_addr);
2503                                                     result.AppendMessageWithFormat("section '%s' loaded at 0x%llx\n", sect_name, load_addr);
2504                                                 }
2505                                                 else
2506                                                 {
2507                                                     result.AppendErrorWithFormat ("no section found that matches the section name '%s'\n", sect_name);
2508                                                     result.SetStatus (eReturnStatusFailed);
2509                                                     break;
2510                                                 }
2511                                             }
2512                                             else
2513                                             {
2514                                                 result.AppendErrorWithFormat ("invalid load address string '%s'\n", load_addr_cstr);
2515                                                 result.SetStatus (eReturnStatusFailed);
2516                                                 break;
2517                                             }
2518                                         }
2519                                         else
2520                                         {
2521                                             if (sect_name)
2522                                                 result.AppendError ("section names must be followed by a load address.\n");
2523                                             else
2524                                                 result.AppendError ("one or more section name + load address pair must be specified.\n");
2525                                             result.SetStatus (eReturnStatusFailed);
2526                                             break;
2527                                         }
2528                                     }
2529                                 }
2530                             }
2531                             else
2532                             {
2533                                 module->GetFileSpec().GetPath (path, sizeof(path));
2534                                 result.AppendErrorWithFormat ("no sections in object file '%s'\n", path);
2535                                 result.SetStatus (eReturnStatusFailed);
2536                             }
2537                         }
2538                         else
2539                         {
2540                             module->GetFileSpec().GetPath (path, sizeof(path));
2541                             result.AppendErrorWithFormat ("no object file for module '%s'\n", path);
2542                             result.SetStatus (eReturnStatusFailed);
2543                         }
2544                     }
2545                     else
2546                     {
2547                         module->GetFileSpec().GetPath (path, sizeof(path));
2548                         result.AppendErrorWithFormat ("invalid module '%s'.\n", path);
2549                         result.SetStatus (eReturnStatusFailed);
2550                     }
2551                 }
2552                 else
2553                 {
2554                     char uuid_cstr[64];
2555                     if (file_ptr)
2556                         file_ptr->GetPath (path, sizeof(path));
2557                     else
2558                         path[0] = '\0';
2559 
2560                     if (uuid_ptr)
2561                         uuid_ptr->GetAsCString(uuid_cstr, sizeof(uuid_cstr));
2562                     else
2563                         uuid_cstr[0] = '\0';
2564                     if (num_matches > 1)
2565                     {
2566                         result.AppendErrorWithFormat ("multiple modules match%s%s%s%s:\n",
2567                                                       path[0] ? " file=" : "",
2568                                                       path,
2569                                                       uuid_cstr[0] ? " uuid=" : "",
2570                                                       uuid_cstr);
2571                         for (size_t i=0; i<num_matches; ++i)
2572                         {
2573                             if (matching_modules.GetModulePointerAtIndex(i)->GetFileSpec().GetPath (path, sizeof(path)))
2574                                 result.AppendMessageWithFormat("%s\n", path);
2575                         }
2576                     }
2577                     else
2578                     {
2579                         result.AppendErrorWithFormat ("no modules were found  that match%s%s%s%s.\n",
2580                                                       path[0] ? " file=" : "",
2581                                                       path,
2582                                                       uuid_cstr[0] ? " uuid=" : "",
2583                                                       uuid_cstr);
2584                     }
2585                     result.SetStatus (eReturnStatusFailed);
2586                 }
2587             }
2588             else
2589             {
2590                 result.AppendError ("either the \"--file <module>\" or the \"--uuid <uuid>\" option must be specified.\n");
2591                 result.SetStatus (eReturnStatusFailed);
2592                 return false;
2593             }
2594         }
2595         return result.Succeeded();
2596     }
2597 
2598     virtual Options *
2599     GetOptions ()
2600     {
2601         return &m_option_group;
2602     }
2603 
2604 protected:
2605     OptionGroupOptions m_option_group;
2606     OptionGroupUUID m_uuid_option_group;
2607     OptionGroupFile m_file_option;
2608     OptionGroupUInt64 m_slide_option;
2609 };
2610 
2611 //----------------------------------------------------------------------
2612 // List images with associated information
2613 //----------------------------------------------------------------------
2614 class CommandObjectTargetModulesList : public CommandObject
2615 {
2616 public:
2617 
2618     class CommandOptions : public Options
2619     {
2620     public:
2621 
2622         CommandOptions (CommandInterpreter &interpreter) :
2623             Options(interpreter),
2624             m_format_array()
2625         {
2626         }
2627 
2628         virtual
2629         ~CommandOptions ()
2630         {
2631         }
2632 
2633         virtual Error
2634         SetOptionValue (uint32_t option_idx, const char *option_arg)
2635         {
2636             char short_option = (char) m_getopt_table[option_idx].val;
2637             if (short_option == 'g')
2638             {
2639                 m_use_global_module_list = true;
2640             }
2641             else
2642             {
2643                 uint32_t width = 0;
2644                 if (option_arg)
2645                     width = strtoul (option_arg, NULL, 0);
2646                 m_format_array.push_back(std::make_pair(short_option, width));
2647             }
2648             Error error;
2649             return error;
2650         }
2651 
2652         void
2653         OptionParsingStarting ()
2654         {
2655             m_format_array.clear();
2656             m_use_global_module_list = false;
2657         }
2658 
2659         const OptionDefinition*
2660         GetDefinitions ()
2661         {
2662             return g_option_table;
2663         }
2664 
2665         // Options table: Required for subclasses of Options.
2666 
2667         static OptionDefinition g_option_table[];
2668 
2669         // Instance variables to hold the values for command options.
2670         typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection;
2671         FormatWidthCollection m_format_array;
2672         bool m_use_global_module_list;
2673     };
2674 
2675     CommandObjectTargetModulesList (CommandInterpreter &interpreter) :
2676     CommandObject (interpreter,
2677                    "target modules list",
2678                    "List current executable and dependent shared library images.",
2679                    "target modules list [<cmd-options>]"),
2680         m_options (interpreter)
2681     {
2682     }
2683 
2684     virtual
2685     ~CommandObjectTargetModulesList ()
2686     {
2687     }
2688 
2689     virtual
2690     Options *
2691     GetOptions ()
2692     {
2693         return &m_options;
2694     }
2695 
2696     virtual bool
2697     Execute (Args& command,
2698              CommandReturnObject &result)
2699     {
2700         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2701         const bool use_global_module_list = m_options.m_use_global_module_list;
2702         if (target == NULL && use_global_module_list == false)
2703         {
2704             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2705             result.SetStatus (eReturnStatusFailed);
2706             return false;
2707         }
2708         else
2709         {
2710             if (target)
2711             {
2712                 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2713                 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2714                 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2715             }
2716             // Dump all sections for all modules images
2717             uint32_t num_modules = 0;
2718             Mutex::Locker locker;
2719             if (use_global_module_list)
2720             {
2721                 locker.Reset (Module::GetAllocationModuleCollectionMutex().GetMutex());
2722                 num_modules = Module::GetNumberAllocatedModules();
2723             }
2724             else
2725                 num_modules = target->GetImages().GetSize();
2726 
2727             if (num_modules > 0)
2728             {
2729                 Stream &strm = result.GetOutputStream();
2730 
2731                 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
2732                 {
2733                     ModuleSP module_sp;
2734                     Module *module;
2735                     if (use_global_module_list)
2736                     {
2737                         module = Module::GetAllocatedModuleAtIndex(image_idx);
2738                         module_sp = module;
2739                     }
2740                     else
2741                     {
2742                         module_sp = target->GetImages().GetModuleAtIndex(image_idx);
2743                         module = module_sp.get();
2744                     }
2745 
2746                     strm.Printf("[%3u] ", image_idx);
2747 
2748                     bool dump_object_name = false;
2749                     if (m_options.m_format_array.empty())
2750                     {
2751                         DumpFullpath(strm, &module->GetFileSpec(), 0);
2752                         dump_object_name = true;
2753                     }
2754                     else
2755                     {
2756                         const size_t num_entries = m_options.m_format_array.size();
2757                         for (size_t i=0; i<num_entries; ++i)
2758                         {
2759                             if (i > 0)
2760                                 strm.PutChar(' ');
2761                             char format_char = m_options.m_format_array[i].first;
2762                             uint32_t width = m_options.m_format_array[i].second;
2763                             switch (format_char)
2764                             {
2765                                 case 'a':
2766                                     DumpModuleArchitecture (strm, module, false, width);
2767                                     break;
2768 
2769                                 case 't':
2770                                     DumpModuleArchitecture (strm, module, true, width);
2771                                     break;
2772 
2773                                 case 'f':
2774                                     DumpFullpath (strm, &module->GetFileSpec(), width);
2775                                     dump_object_name = true;
2776                                     break;
2777 
2778                                 case 'd':
2779                                     DumpDirectory (strm, &module->GetFileSpec(), width);
2780                                     break;
2781 
2782                                 case 'b':
2783                                     DumpBasename (strm, &module->GetFileSpec(), width);
2784                                     dump_object_name = true;
2785                                     break;
2786 
2787                                 case 'r':
2788                                     {
2789                                         uint32_t ref_count = 0;
2790                                         if (module_sp)
2791                                         {
2792                                             // Take one away to make sure we don't count our local "module_sp"
2793                                             ref_count = module_sp.use_count() - 1;
2794                                         }
2795                                         if (width)
2796                                             strm.Printf("{%*u}", width, ref_count);
2797                                         else
2798                                             strm.Printf("{%u}", ref_count);
2799                                     }
2800                                     break;
2801 
2802                                 case 's':
2803                                 case 'S':
2804                                     {
2805                                         SymbolVendor *symbol_vendor = module->GetSymbolVendor();
2806                                         if (symbol_vendor)
2807                                         {
2808                                             SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
2809                                             if (symbol_file)
2810                                             {
2811                                                 if (format_char == 'S')
2812                                                     DumpBasename(strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
2813                                                 else
2814                                                     DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
2815                                                 dump_object_name = true;
2816                                                 break;
2817                                             }
2818                                         }
2819                                         strm.Printf("%.*s", width, "<NONE>");
2820                                     }
2821                                     break;
2822 
2823                                 case 'm':
2824                                     module->GetModificationTime().Dump(&strm, width);
2825                                     break;
2826 
2827                                 case 'p':
2828                                     strm.Printf("%p", module);
2829                                     break;
2830 
2831                                 case 'u':
2832                                     DumpModuleUUID(strm, module);
2833                                     break;
2834 
2835                                 default:
2836                                     break;
2837                             }
2838 
2839                         }
2840                     }
2841                     if (dump_object_name)
2842                     {
2843                         const char *object_name = module->GetObjectName().GetCString();
2844                         if (object_name)
2845                             strm.Printf ("(%s)", object_name);
2846                     }
2847                     strm.EOL();
2848                 }
2849                 result.SetStatus (eReturnStatusSuccessFinishResult);
2850             }
2851             else
2852             {
2853                 if (use_global_module_list)
2854                     result.AppendError ("the global module list is empty");
2855                 else
2856                     result.AppendError ("the target has no associated executable images");
2857                 result.SetStatus (eReturnStatusFailed);
2858                 return false;
2859             }
2860         }
2861         return result.Succeeded();
2862     }
2863 protected:
2864 
2865     CommandOptions m_options;
2866 };
2867 
2868 OptionDefinition
2869 CommandObjectTargetModulesList::CommandOptions::g_option_table[] =
2870 {
2871     { LLDB_OPT_SET_1, false, "arch",       'a', optional_argument, NULL, 0, eArgTypeWidth,   "Display the architecture when listing images."},
2872     { LLDB_OPT_SET_1, false, "triple",     't', optional_argument, NULL, 0, eArgTypeWidth,   "Display the triple when listing images."},
2873     { LLDB_OPT_SET_1, false, "uuid",       'u', no_argument,       NULL, 0, eArgTypeNone,    "Display the UUID when listing images."},
2874     { LLDB_OPT_SET_1, false, "fullpath",   'f', optional_argument, NULL, 0, eArgTypeWidth,   "Display the fullpath to the image object file."},
2875     { LLDB_OPT_SET_1, false, "directory",  'd', optional_argument, NULL, 0, eArgTypeWidth,   "Display the directory with optional width for the image object file."},
2876     { LLDB_OPT_SET_1, false, "basename",   'b', optional_argument, NULL, 0, eArgTypeWidth,   "Display the basename with optional width for the image object file."},
2877     { LLDB_OPT_SET_1, false, "symfile",    's', optional_argument, NULL, 0, eArgTypeWidth,   "Display the fullpath to the image symbol file with optional width."},
2878     { LLDB_OPT_SET_1, false, "symfile-basename", 'S', optional_argument, NULL, 0, eArgTypeWidth,   "Display the basename to the image symbol file with optional width."},
2879     { LLDB_OPT_SET_1, false, "mod-time",   'm', optional_argument, NULL, 0, eArgTypeWidth,   "Display the modification time with optional width of the module."},
2880     { 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."},
2881     { LLDB_OPT_SET_1, false, "pointer",    'p', optional_argument, NULL, 0, eArgTypeNone,    "Display the module pointer."},
2882     { 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."},
2883     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
2884 };
2885 
2886 
2887 
2888 //----------------------------------------------------------------------
2889 // Lookup information in images
2890 //----------------------------------------------------------------------
2891 class CommandObjectTargetModulesLookup : public CommandObject
2892 {
2893 public:
2894 
2895     enum
2896     {
2897         eLookupTypeInvalid = -1,
2898         eLookupTypeAddress = 0,
2899         eLookupTypeSymbol,
2900         eLookupTypeFileLine,    // Line is optional
2901         eLookupTypeFunction,
2902         eLookupTypeType,
2903         kNumLookupTypes
2904     };
2905 
2906     class CommandOptions : public Options
2907     {
2908     public:
2909 
2910         CommandOptions (CommandInterpreter &interpreter) :
2911         Options(interpreter)
2912         {
2913             OptionParsingStarting();
2914         }
2915 
2916         virtual
2917         ~CommandOptions ()
2918         {
2919         }
2920 
2921         virtual Error
2922         SetOptionValue (uint32_t option_idx, const char *option_arg)
2923         {
2924             Error error;
2925 
2926             char short_option = (char) m_getopt_table[option_idx].val;
2927 
2928             switch (short_option)
2929             {
2930                 case 'a':
2931                     m_type = eLookupTypeAddress;
2932                     m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
2933                     if (m_addr == LLDB_INVALID_ADDRESS)
2934                         error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", option_arg);
2935                     break;
2936 
2937                 case 'o':
2938                     m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
2939                     if (m_offset == LLDB_INVALID_ADDRESS)
2940                         error.SetErrorStringWithFormat ("Invalid offset string '%s'.\n", option_arg);
2941                     break;
2942 
2943                 case 's':
2944                     m_str = option_arg;
2945                     m_type = eLookupTypeSymbol;
2946                     break;
2947 
2948                 case 'f':
2949                     m_file.SetFile (option_arg, false);
2950                     m_type = eLookupTypeFileLine;
2951                     break;
2952 
2953                 case 'i':
2954                     m_check_inlines = false;
2955                     break;
2956 
2957                 case 'l':
2958                     m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX);
2959                     if (m_line_number == UINT32_MAX)
2960                         error.SetErrorStringWithFormat ("Invalid line number string '%s'.\n", option_arg);
2961                     else if (m_line_number == 0)
2962                         error.SetErrorString ("Zero is an invalid line number.");
2963                     m_type = eLookupTypeFileLine;
2964                     break;
2965 
2966                 case 'n':
2967                     m_str = option_arg;
2968                     m_type = eLookupTypeFunction;
2969                     break;
2970 
2971                 case 't':
2972                     m_str = option_arg;
2973                     m_type = eLookupTypeType;
2974                     break;
2975 
2976                 case 'v':
2977                     m_verbose = 1;
2978                     break;
2979 
2980                 case 'r':
2981                     m_use_regex = true;
2982                     break;
2983             }
2984 
2985             return error;
2986         }
2987 
2988         void
2989         OptionParsingStarting ()
2990         {
2991             m_type = eLookupTypeInvalid;
2992             m_str.clear();
2993             m_file.Clear();
2994             m_addr = LLDB_INVALID_ADDRESS;
2995             m_offset = 0;
2996             m_line_number = 0;
2997             m_use_regex = false;
2998             m_check_inlines = true;
2999             m_verbose = false;
3000         }
3001 
3002         const OptionDefinition*
3003         GetDefinitions ()
3004         {
3005             return g_option_table;
3006         }
3007 
3008         // Options table: Required for subclasses of Options.
3009 
3010         static OptionDefinition g_option_table[];
3011         int             m_type;         // Should be a eLookupTypeXXX enum after parsing options
3012         std::string     m_str;          // Holds name lookup
3013         FileSpec        m_file;         // Files for file lookups
3014         lldb::addr_t    m_addr;         // Holds the address to lookup
3015         lldb::addr_t    m_offset;       // Subtract this offset from m_addr before doing lookups.
3016         uint32_t        m_line_number;  // Line number for file+line lookups
3017         bool            m_use_regex;    // Name lookups in m_str are regular expressions.
3018         bool            m_check_inlines;// Check for inline entries when looking up by file/line.
3019         bool            m_verbose;      // Enable verbose lookup info
3020 
3021     };
3022 
3023     CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) :
3024     CommandObject (interpreter,
3025                    "target modules lookup",
3026                    "Look up information within executable and dependent shared library images.",
3027                    NULL),
3028     m_options (interpreter)
3029     {
3030         CommandArgumentEntry arg;
3031         CommandArgumentData file_arg;
3032 
3033         // Define the first (and only) variant of this arg.
3034         file_arg.arg_type = eArgTypeFilename;
3035         file_arg.arg_repetition = eArgRepeatStar;
3036 
3037         // There is only one variant this argument could be; put it into the argument entry.
3038         arg.push_back (file_arg);
3039 
3040         // Push the data for the first argument into the m_arguments vector.
3041         m_arguments.push_back (arg);
3042     }
3043 
3044     virtual
3045     ~CommandObjectTargetModulesLookup ()
3046     {
3047     }
3048 
3049     virtual Options *
3050     GetOptions ()
3051     {
3052         return &m_options;
3053     }
3054 
3055 
3056     bool
3057     LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
3058     {
3059         switch (m_options.m_type)
3060         {
3061             case eLookupTypeAddress:
3062                 if (m_options.m_addr != LLDB_INVALID_ADDRESS)
3063                 {
3064                     if (LookupAddressInModule (m_interpreter,
3065                                                result.GetOutputStream(),
3066                                                module,
3067                                                eSymbolContextEverything,
3068                                                m_options.m_addr,
3069                                                m_options.m_offset,
3070                                                m_options.m_verbose))
3071                     {
3072                         result.SetStatus(eReturnStatusSuccessFinishResult);
3073                         return true;
3074                     }
3075                 }
3076                 break;
3077 
3078             case eLookupTypeSymbol:
3079                 if (!m_options.m_str.empty())
3080                 {
3081                     if (LookupSymbolInModule (m_interpreter, result.GetOutputStream(), module, m_options.m_str.c_str(), m_options.m_use_regex))
3082                     {
3083                         result.SetStatus(eReturnStatusSuccessFinishResult);
3084                         return true;
3085                     }
3086                 }
3087                 break;
3088 
3089             case eLookupTypeFileLine:
3090                 if (m_options.m_file)
3091                 {
3092 
3093                     if (LookupFileAndLineInModule (m_interpreter,
3094                                                    result.GetOutputStream(),
3095                                                    module,
3096                                                    m_options.m_file,
3097                                                    m_options.m_line_number,
3098                                                    m_options.m_check_inlines,
3099                                                    m_options.m_verbose))
3100                     {
3101                         result.SetStatus(eReturnStatusSuccessFinishResult);
3102                         return true;
3103                     }
3104                 }
3105                 break;
3106 
3107             case eLookupTypeFunction:
3108                 if (!m_options.m_str.empty())
3109                 {
3110                     if (LookupFunctionInModule (m_interpreter,
3111                                                 result.GetOutputStream(),
3112                                                 module,
3113                                                 m_options.m_str.c_str(),
3114                                                 m_options.m_use_regex,
3115                                                 m_options.m_verbose))
3116                     {
3117                         result.SetStatus(eReturnStatusSuccessFinishResult);
3118                         return true;
3119                     }
3120                 }
3121                 break;
3122 
3123             case eLookupTypeType:
3124                 if (!m_options.m_str.empty())
3125                 {
3126                     if (LookupTypeInModule (m_interpreter,
3127                                             result.GetOutputStream(),
3128                                             module,
3129                                             m_options.m_str.c_str(),
3130                                             m_options.m_use_regex))
3131                     {
3132                         result.SetStatus(eReturnStatusSuccessFinishResult);
3133                         return true;
3134                     }
3135                 }
3136                 break;
3137 
3138             default:
3139                 m_options.GenerateOptionUsage (result.GetErrorStream(), this);
3140                 syntax_error = true;
3141                 break;
3142         }
3143 
3144         result.SetStatus (eReturnStatusFailed);
3145         return false;
3146     }
3147 
3148     virtual bool
3149     Execute (Args& command,
3150              CommandReturnObject &result)
3151     {
3152         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3153         if (target == NULL)
3154         {
3155             result.AppendError ("invalid target, create a debug target using the 'target create' command");
3156             result.SetStatus (eReturnStatusFailed);
3157             return false;
3158         }
3159         else
3160         {
3161             bool syntax_error = false;
3162             uint32_t i;
3163             uint32_t num_successful_lookups = 0;
3164             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3165             result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3166             result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3167             // Dump all sections for all modules images
3168 
3169             if (command.GetArgumentCount() == 0)
3170             {
3171                 // Dump all sections for all modules images
3172                 const uint32_t num_modules = target->GetImages().GetSize();
3173                 if (num_modules > 0)
3174                 {
3175                     for (i = 0; i<num_modules && syntax_error == false; ++i)
3176                     {
3177                         if (LookupInModule (m_interpreter, target->GetImages().GetModulePointerAtIndex(i), result, syntax_error))
3178                         {
3179                             result.GetOutputStream().EOL();
3180                             num_successful_lookups++;
3181                         }
3182                     }
3183                 }
3184                 else
3185                 {
3186                     result.AppendError ("the target has no associated executable images");
3187                     result.SetStatus (eReturnStatusFailed);
3188                     return false;
3189                 }
3190             }
3191             else
3192             {
3193                 // Dump specified images (by basename or fullpath)
3194                 const char *arg_cstr;
3195                 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i)
3196                 {
3197                     FileSpec image_file(arg_cstr, false);
3198                     ModuleList matching_modules;
3199                     size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
3200 
3201                     // Not found in our module list for our target, check the main
3202                     // shared module list in case it is a extra file used somewhere
3203                     // else
3204                     if (num_matching_modules == 0)
3205                         num_matching_modules = ModuleList::FindSharedModules (image_file,
3206                                                                               target->GetArchitecture(),
3207                                                                               NULL,
3208                                                                               NULL,
3209                                                                               matching_modules);
3210 
3211                     if (num_matching_modules > 0)
3212                     {
3213                         for (size_t j=0; j<num_matching_modules; ++j)
3214                         {
3215                             Module * image_module = matching_modules.GetModulePointerAtIndex(j);
3216                             if (image_module)
3217                             {
3218                                 if (LookupInModule (m_interpreter, image_module, result, syntax_error))
3219                                 {
3220                                     result.GetOutputStream().EOL();
3221                                     num_successful_lookups++;
3222                                 }
3223                             }
3224                         }
3225                     }
3226                     else
3227                         result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
3228                 }
3229             }
3230 
3231             if (num_successful_lookups > 0)
3232                 result.SetStatus (eReturnStatusSuccessFinishResult);
3233             else
3234                 result.SetStatus (eReturnStatusFailed);
3235         }
3236         return result.Succeeded();
3237     }
3238 protected:
3239 
3240     CommandOptions m_options;
3241 };
3242 
3243 OptionDefinition
3244 CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] =
3245 {
3246     { LLDB_OPT_SET_1,   true,  "address",    'a', required_argument, NULL, 0, eArgTypeAddress,      "Lookup an address in one or more target modules."},
3247     { 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."},
3248     { LLDB_OPT_SET_2| LLDB_OPT_SET_4
3249       /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_5 */ ,
3250                         false, "regex",      'r', no_argument,       NULL, 0, eArgTypeNone,         "The <name> argument for name lookups are regular expressions."},
3251     { 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."},
3252     { 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."},
3253     { 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)."},
3254     { LLDB_OPT_SET_3,   false, "no-inlines", 'i', no_argument,       NULL, 0, eArgTypeNone,         "Check inline line entries (must be used in conjunction with --file)."},
3255     { 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."},
3256     { 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."},
3257     { LLDB_OPT_SET_ALL, false, "verbose",    'v', no_argument,       NULL, 0, eArgTypeNone,         "Enable verbose lookup information."},
3258     { 0, false, NULL,           0, 0,                 NULL, 0, eArgTypeNone, NULL }
3259 };
3260 
3261 
3262 #pragma mark CommandObjectMultiwordImageSearchPaths
3263 
3264 //-------------------------------------------------------------------------
3265 // CommandObjectMultiwordImageSearchPaths
3266 //-------------------------------------------------------------------------
3267 
3268 class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword
3269 {
3270 public:
3271 
3272     CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) :
3273     CommandObjectMultiword (interpreter,
3274                             "target modules search-paths",
3275                             "A set of commands for operating on debugger target image search paths.",
3276                             "target modules search-paths <subcommand> [<subcommand-options>]")
3277     {
3278         LoadSubCommand ("add",     CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter)));
3279         LoadSubCommand ("clear",   CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter)));
3280         LoadSubCommand ("insert",  CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter)));
3281         LoadSubCommand ("list",    CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter)));
3282         LoadSubCommand ("query",   CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter)));
3283     }
3284 
3285     ~CommandObjectTargetModulesImageSearchPaths()
3286     {
3287     }
3288 };
3289 
3290 
3291 
3292 #pragma mark CommandObjectTargetModules
3293 
3294 //-------------------------------------------------------------------------
3295 // CommandObjectTargetModules
3296 //-------------------------------------------------------------------------
3297 
3298 class CommandObjectTargetModules : public CommandObjectMultiword
3299 {
3300 public:
3301     //------------------------------------------------------------------
3302     // Constructors and Destructors
3303     //------------------------------------------------------------------
3304     CommandObjectTargetModules(CommandInterpreter &interpreter) :
3305         CommandObjectMultiword (interpreter,
3306                                 "target modules",
3307                                 "A set of commands for accessing information for one or more target modules.",
3308                                 "target modules <sub-command> ...")
3309     {
3310         LoadSubCommand ("add",          CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter)));
3311         LoadSubCommand ("load",         CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter)));
3312         //LoadSubCommand ("unload",       CommandObjectSP (new CommandObjectTargetModulesUnload (interpreter)));
3313         LoadSubCommand ("dump",         CommandObjectSP (new CommandObjectTargetModulesDump (interpreter)));
3314         LoadSubCommand ("list",         CommandObjectSP (new CommandObjectTargetModulesList (interpreter)));
3315         LoadSubCommand ("lookup",       CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter)));
3316         LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter)));
3317 
3318     }
3319     virtual
3320     ~CommandObjectTargetModules()
3321     {
3322     }
3323 
3324 private:
3325     //------------------------------------------------------------------
3326     // For CommandObjectTargetModules only
3327     //------------------------------------------------------------------
3328     DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules);
3329 };
3330 
3331 
3332 #pragma mark CommandObjectTargetStopHookAdd
3333 
3334 //-------------------------------------------------------------------------
3335 // CommandObjectTargetStopHookAdd
3336 //-------------------------------------------------------------------------
3337 
3338 class CommandObjectTargetStopHookAdd : public CommandObject
3339 {
3340 public:
3341 
3342     class CommandOptions : public Options
3343     {
3344     public:
3345         CommandOptions (CommandInterpreter &interpreter) :
3346             Options(interpreter),
3347             m_line_start(0),
3348             m_line_end (UINT_MAX),
3349             m_func_name_type_mask (eFunctionNameTypeAuto),
3350             m_sym_ctx_specified (false),
3351             m_thread_specified (false),
3352             m_use_one_liner (false),
3353             m_one_liner()
3354         {
3355         }
3356 
3357         ~CommandOptions () {}
3358 
3359         const OptionDefinition*
3360         GetDefinitions ()
3361         {
3362             return g_option_table;
3363         }
3364 
3365         virtual Error
3366         SetOptionValue (uint32_t option_idx, const char *option_arg)
3367         {
3368             Error error;
3369             char short_option = (char) m_getopt_table[option_idx].val;
3370             bool success;
3371 
3372             switch (short_option)
3373             {
3374                 case 'c':
3375                     m_class_name = option_arg;
3376                     m_sym_ctx_specified = true;
3377                 break;
3378 
3379                 case 'e':
3380                     m_line_end = Args::StringToUInt32 (option_arg, UINT_MAX, 0, &success);
3381                     if (!success)
3382                     {
3383                         error.SetErrorStringWithFormat ("Invalid end line number: \"%s\".", option_arg);
3384                         break;
3385                     }
3386                     m_sym_ctx_specified = true;
3387                 break;
3388 
3389                 case 'l':
3390                     m_line_start = Args::StringToUInt32 (option_arg, 0, 0, &success);
3391                     if (!success)
3392                     {
3393                         error.SetErrorStringWithFormat ("Invalid start line number: \"%s\".", option_arg);
3394                         break;
3395                     }
3396                     m_sym_ctx_specified = true;
3397                 break;
3398 
3399                 case 'n':
3400                     m_function_name = option_arg;
3401                     m_func_name_type_mask |= eFunctionNameTypeAuto;
3402                     m_sym_ctx_specified = true;
3403                 break;
3404 
3405                 case 'f':
3406                     m_file_name = option_arg;
3407                     m_sym_ctx_specified = true;
3408                 break;
3409                 case 's':
3410                     m_module_name = option_arg;
3411                     m_sym_ctx_specified = true;
3412                 break;
3413                 case 't' :
3414                 {
3415                     m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
3416                     if (m_thread_id == LLDB_INVALID_THREAD_ID)
3417                        error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", option_arg);
3418                     m_thread_specified = true;
3419                 }
3420                 break;
3421                 case 'T':
3422                     m_thread_name = option_arg;
3423                     m_thread_specified = true;
3424                 break;
3425                 case 'q':
3426                     m_queue_name = option_arg;
3427                     m_thread_specified = true;
3428                     break;
3429                 case 'x':
3430                 {
3431                     m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
3432                     if (m_thread_id == UINT32_MAX)
3433                        error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", option_arg);
3434                     m_thread_specified = true;
3435                 }
3436                 break;
3437                 case 'o':
3438                     m_use_one_liner = true;
3439                     m_one_liner = option_arg;
3440                 break;
3441                 default:
3442                     error.SetErrorStringWithFormat ("Unrecognized option %c.", short_option);
3443                 break;
3444             }
3445             return error;
3446         }
3447 
3448         void
3449         OptionParsingStarting ()
3450         {
3451             m_class_name.clear();
3452             m_function_name.clear();
3453             m_line_start = 0;
3454             m_line_end = UINT_MAX;
3455             m_file_name.clear();
3456             m_module_name.clear();
3457             m_func_name_type_mask = eFunctionNameTypeAuto;
3458             m_thread_id = LLDB_INVALID_THREAD_ID;
3459             m_thread_index = UINT32_MAX;
3460             m_thread_name.clear();
3461             m_queue_name.clear();
3462 
3463             m_sym_ctx_specified = false;
3464             m_thread_specified = false;
3465 
3466             m_use_one_liner = false;
3467             m_one_liner.clear();
3468         }
3469 
3470 
3471         static OptionDefinition g_option_table[];
3472 
3473         std::string m_class_name;
3474         std::string m_function_name;
3475         uint32_t    m_line_start;
3476         uint32_t    m_line_end;
3477         std::string m_file_name;
3478         std::string m_module_name;
3479         uint32_t m_func_name_type_mask;  // A pick from lldb::FunctionNameType.
3480         lldb::tid_t m_thread_id;
3481         uint32_t m_thread_index;
3482         std::string m_thread_name;
3483         std::string m_queue_name;
3484         bool        m_sym_ctx_specified;
3485         bool        m_thread_specified;
3486         // Instance variables to hold the values for one_liner options.
3487         bool m_use_one_liner;
3488         std::string m_one_liner;
3489     };
3490 
3491     Options *
3492     GetOptions ()
3493     {
3494         return &m_options;
3495     }
3496 
3497     CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) :
3498         CommandObject (interpreter,
3499                        "target stop-hook add ",
3500                        "Add a hook to be executed when the target stops.",
3501                        "target stop-hook add"),
3502         m_options (interpreter)
3503     {
3504     }
3505 
3506     ~CommandObjectTargetStopHookAdd ()
3507     {
3508     }
3509 
3510     static size_t
3511     ReadCommandsCallbackFunction (void *baton,
3512                                   InputReader &reader,
3513                                   lldb::InputReaderAction notification,
3514                                   const char *bytes,
3515                                   size_t bytes_len)
3516     {
3517         StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
3518         Target::StopHook *new_stop_hook = ((Target::StopHook *) baton);
3519         static bool got_interrupted;
3520         bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
3521 
3522         switch (notification)
3523         {
3524         case eInputReaderActivate:
3525             if (!batch_mode)
3526             {
3527                 out_stream->Printf ("%s\n", "Enter your stop hook command(s).  Type 'DONE' to end.");
3528                 if (reader.GetPrompt())
3529                     out_stream->Printf ("%s", reader.GetPrompt());
3530                 out_stream->Flush();
3531             }
3532             got_interrupted = false;
3533             break;
3534 
3535         case eInputReaderDeactivate:
3536             break;
3537 
3538         case eInputReaderReactivate:
3539             if (reader.GetPrompt() && !batch_mode)
3540             {
3541                 out_stream->Printf ("%s", reader.GetPrompt());
3542                 out_stream->Flush();
3543             }
3544             got_interrupted = false;
3545             break;
3546 
3547         case eInputReaderAsynchronousOutputWritten:
3548             break;
3549 
3550         case eInputReaderGotToken:
3551             if (bytes && bytes_len && baton)
3552             {
3553                 StringList *commands = new_stop_hook->GetCommandPointer();
3554                 if (commands)
3555                 {
3556                     commands->AppendString (bytes, bytes_len);
3557                 }
3558             }
3559             if (!reader.IsDone() && reader.GetPrompt() && !batch_mode)
3560             {
3561                 out_stream->Printf ("%s", reader.GetPrompt());
3562                 out_stream->Flush();
3563             }
3564             break;
3565 
3566         case eInputReaderInterrupt:
3567             {
3568                 // Finish, and cancel the stop hook.
3569                 new_stop_hook->GetTarget()->RemoveStopHookByID(new_stop_hook->GetID());
3570                 if (!batch_mode)
3571                 {
3572                     out_stream->Printf ("Stop hook cancelled.\n");
3573                     out_stream->Flush();
3574                 }
3575 
3576                 reader.SetIsDone (true);
3577             }
3578             got_interrupted = true;
3579             break;
3580 
3581         case eInputReaderEndOfFile:
3582             reader.SetIsDone (true);
3583             break;
3584 
3585         case eInputReaderDone:
3586             if (!got_interrupted && !batch_mode)
3587             {
3588                 out_stream->Printf ("Stop hook #%d added.\n", new_stop_hook->GetID());
3589                 out_stream->Flush();
3590             }
3591             break;
3592         }
3593 
3594         return bytes_len;
3595     }
3596 
3597     bool
3598     Execute (Args& command,
3599              CommandReturnObject &result)
3600     {
3601         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3602         if (target)
3603         {
3604             Target::StopHookSP new_hook_sp;
3605             target->AddStopHook (new_hook_sp);
3606 
3607             //  First step, make the specifier.
3608             std::auto_ptr<SymbolContextSpecifier> specifier_ap;
3609             if (m_options.m_sym_ctx_specified)
3610             {
3611                 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget()));
3612 
3613                 if (!m_options.m_module_name.empty())
3614                 {
3615                     specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified);
3616                 }
3617 
3618                 if (!m_options.m_class_name.empty())
3619                 {
3620                     specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified);
3621                 }
3622 
3623                 if (!m_options.m_file_name.empty())
3624                 {
3625                     specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified);
3626                 }
3627 
3628                 if (m_options.m_line_start != 0)
3629                 {
3630                     specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified);
3631                 }
3632 
3633                 if (m_options.m_line_end != UINT_MAX)
3634                 {
3635                     specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
3636                 }
3637 
3638                 if (!m_options.m_function_name.empty())
3639                 {
3640                     specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified);
3641                 }
3642             }
3643 
3644             if (specifier_ap.get())
3645                 new_hook_sp->SetSpecifier (specifier_ap.release());
3646 
3647             // Next see if any of the thread options have been entered:
3648 
3649             if (m_options.m_thread_specified)
3650             {
3651                 ThreadSpec *thread_spec = new ThreadSpec();
3652 
3653                 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
3654                 {
3655                     thread_spec->SetTID (m_options.m_thread_id);
3656                 }
3657 
3658                 if (m_options.m_thread_index != UINT32_MAX)
3659                     thread_spec->SetIndex (m_options.m_thread_index);
3660 
3661                 if (!m_options.m_thread_name.empty())
3662                     thread_spec->SetName (m_options.m_thread_name.c_str());
3663 
3664                 if (!m_options.m_queue_name.empty())
3665                     thread_spec->SetQueueName (m_options.m_queue_name.c_str());
3666 
3667                 new_hook_sp->SetThreadSpecifier (thread_spec);
3668 
3669             }
3670             if (m_options.m_use_one_liner)
3671             {
3672                 // Use one-liner.
3673                 new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str());
3674                 result.AppendMessageWithFormat("Stop hook #%d added.\n", new_hook_sp->GetID());
3675             }
3676             else
3677             {
3678                 // Otherwise gather up the command list, we'll push an input reader and suck the data from that directly into
3679                 // the new stop hook's command string.
3680                 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
3681                 if (!reader_sp)
3682                 {
3683                     result.AppendError("out of memory\n");
3684                     result.SetStatus (eReturnStatusFailed);
3685                     target->RemoveStopHookByID (new_hook_sp->GetID());
3686                     return false;
3687                 }
3688 
3689                 Error err (reader_sp->Initialize (CommandObjectTargetStopHookAdd::ReadCommandsCallbackFunction,
3690                                                   new_hook_sp.get(), // baton
3691                                                   eInputReaderGranularityLine,  // token size, to pass to callback function
3692                                                   "DONE",                       // end token
3693                                                   "> ",                         // prompt
3694                                                   true));                       // echo input
3695                 if (!err.Success())
3696                 {
3697                     result.AppendError (err.AsCString());
3698                     result.SetStatus (eReturnStatusFailed);
3699                     target->RemoveStopHookByID (new_hook_sp->GetID());
3700                     return false;
3701                 }
3702                 m_interpreter.GetDebugger().PushInputReader (reader_sp);
3703             }
3704             result.SetStatus (eReturnStatusSuccessFinishNoResult);
3705         }
3706         else
3707         {
3708             result.AppendError ("invalid target\n");
3709             result.SetStatus (eReturnStatusFailed);
3710         }
3711 
3712         return result.Succeeded();
3713     }
3714 private:
3715     CommandOptions m_options;
3716 };
3717 
3718 OptionDefinition
3719 CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] =
3720 {
3721     { LLDB_OPT_SET_ALL, false, "one-liner", 'o', required_argument, NULL, NULL, eArgTypeOneLiner,
3722         "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
3723     { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
3724         "Set the module within which the stop-hook is to be run."},
3725     { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, NULL, eArgTypeThreadIndex,
3726         "The stop hook is run only for the thread whose index matches this argument."},
3727     { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, NULL, eArgTypeThreadID,
3728         "The stop hook is run only for the thread whose TID matches this argument."},
3729     { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, NULL, eArgTypeThreadName,
3730         "The stop hook is run only for the thread whose thread name matches this argument."},
3731     { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, NULL, eArgTypeQueueName,
3732         "The stop hook is run only for threads in the queue whose name is given by this argument."},
3733     { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
3734         "Specify the source file within which the stop-hook is to be run." },
3735     { LLDB_OPT_SET_1, false, "start-line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
3736         "Set the start of the line range for which the stop-hook is to be run."},
3737     { LLDB_OPT_SET_1, false, "end-line", 'e', required_argument, NULL, 0, eArgTypeLineNum,
3738         "Set the end of the line range for which the stop-hook is to be run."},
3739     { LLDB_OPT_SET_2, false, "classname", 'c', required_argument, NULL, NULL, eArgTypeClassName,
3740         "Specify the class within which the stop-hook is to be run." },
3741     { LLDB_OPT_SET_3, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
3742         "Set the function name within which the stop hook will be run." },
3743     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
3744 };
3745 
3746 #pragma mark CommandObjectTargetStopHookDelete
3747 
3748 //-------------------------------------------------------------------------
3749 // CommandObjectTargetStopHookDelete
3750 //-------------------------------------------------------------------------
3751 
3752 class CommandObjectTargetStopHookDelete : public CommandObject
3753 {
3754 public:
3755 
3756     CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) :
3757         CommandObject (interpreter,
3758                        "target stop-hook delete [<id>]",
3759                        "Delete a stop-hook.",
3760                        "target stop-hook delete")
3761     {
3762     }
3763 
3764     ~CommandObjectTargetStopHookDelete ()
3765     {
3766     }
3767 
3768     bool
3769     Execute (Args& command,
3770              CommandReturnObject &result)
3771     {
3772         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3773         if (target)
3774         {
3775             // FIXME: see if we can use the breakpoint id style parser?
3776             size_t num_args = command.GetArgumentCount();
3777             if (num_args == 0)
3778             {
3779                 if (!m_interpreter.Confirm ("Delete all stop hooks?", true))
3780                 {
3781                     result.SetStatus (eReturnStatusFailed);
3782                     return false;
3783                 }
3784                 else
3785                 {
3786                     target->RemoveAllStopHooks();
3787                 }
3788             }
3789             else
3790             {
3791                 bool success;
3792                 for (size_t i = 0; i < num_args; i++)
3793                 {
3794                     lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
3795                     if (!success)
3796                     {
3797                         result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
3798                         result.SetStatus(eReturnStatusFailed);
3799                         return false;
3800                     }
3801                     success = target->RemoveStopHookByID (user_id);
3802                     if (!success)
3803                     {
3804                         result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
3805                         result.SetStatus(eReturnStatusFailed);
3806                         return false;
3807                     }
3808                 }
3809             }
3810             result.SetStatus (eReturnStatusSuccessFinishNoResult);
3811         }
3812         else
3813         {
3814             result.AppendError ("invalid target\n");
3815             result.SetStatus (eReturnStatusFailed);
3816         }
3817 
3818         return result.Succeeded();
3819     }
3820 };
3821 #pragma mark CommandObjectTargetStopHookEnableDisable
3822 
3823 //-------------------------------------------------------------------------
3824 // CommandObjectTargetStopHookEnableDisable
3825 //-------------------------------------------------------------------------
3826 
3827 class CommandObjectTargetStopHookEnableDisable : public CommandObject
3828 {
3829 public:
3830 
3831     CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) :
3832         CommandObject (interpreter,
3833                        name,
3834                        help,
3835                        syntax),
3836         m_enable (enable)
3837     {
3838     }
3839 
3840     ~CommandObjectTargetStopHookEnableDisable ()
3841     {
3842     }
3843 
3844     bool
3845     Execute (Args& command,
3846              CommandReturnObject &result)
3847     {
3848         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3849         if (target)
3850         {
3851             // FIXME: see if we can use the breakpoint id style parser?
3852             size_t num_args = command.GetArgumentCount();
3853             bool success;
3854 
3855             if (num_args == 0)
3856             {
3857                 target->SetAllStopHooksActiveState (m_enable);
3858             }
3859             else
3860             {
3861                 for (size_t i = 0; i < num_args; i++)
3862                 {
3863                     lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
3864                     if (!success)
3865                     {
3866                         result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
3867                         result.SetStatus(eReturnStatusFailed);
3868                         return false;
3869                     }
3870                     success = target->SetStopHookActiveStateByID (user_id, m_enable);
3871                     if (!success)
3872                     {
3873                         result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
3874                         result.SetStatus(eReturnStatusFailed);
3875                         return false;
3876                     }
3877                 }
3878             }
3879             result.SetStatus (eReturnStatusSuccessFinishNoResult);
3880         }
3881         else
3882         {
3883             result.AppendError ("invalid target\n");
3884             result.SetStatus (eReturnStatusFailed);
3885         }
3886         return result.Succeeded();
3887     }
3888 private:
3889     bool m_enable;
3890 };
3891 
3892 #pragma mark CommandObjectTargetStopHookList
3893 
3894 //-------------------------------------------------------------------------
3895 // CommandObjectTargetStopHookList
3896 //-------------------------------------------------------------------------
3897 
3898 class CommandObjectTargetStopHookList : public CommandObject
3899 {
3900 public:
3901 
3902     CommandObjectTargetStopHookList (CommandInterpreter &interpreter) :
3903         CommandObject (interpreter,
3904                        "target stop-hook list [<type>]",
3905                        "List all stop-hooks.",
3906                        "target stop-hook list")
3907     {
3908     }
3909 
3910     ~CommandObjectTargetStopHookList ()
3911     {
3912     }
3913 
3914     bool
3915     Execute (Args& command,
3916              CommandReturnObject &result)
3917     {
3918         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3919         if (target)
3920         {
3921             bool notify = true;
3922             target->GetImageSearchPathList().Clear(notify);
3923             result.SetStatus (eReturnStatusSuccessFinishNoResult);
3924         }
3925         else
3926         {
3927             result.AppendError ("invalid target\n");
3928             result.SetStatus (eReturnStatusFailed);
3929             return result.Succeeded();
3930         }
3931 
3932         size_t num_hooks = target->GetNumStopHooks ();
3933         if (num_hooks == 0)
3934         {
3935             result.GetOutputStream().PutCString ("No stop hooks.\n");
3936         }
3937         else
3938         {
3939             for (size_t i = 0; i < num_hooks; i++)
3940             {
3941                 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i);
3942                 if (i > 0)
3943                     result.GetOutputStream().PutCString ("\n");
3944                 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull);
3945             }
3946         }
3947         return result.Succeeded();
3948     }
3949 };
3950 
3951 #pragma mark CommandObjectMultiwordTargetStopHooks
3952 //-------------------------------------------------------------------------
3953 // CommandObjectMultiwordTargetStopHooks
3954 //-------------------------------------------------------------------------
3955 
3956 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword
3957 {
3958 public:
3959 
3960     CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) :
3961         CommandObjectMultiword (interpreter,
3962                                 "target stop-hook",
3963                                 "A set of commands for operating on debugger target stop-hooks.",
3964                                 "target stop-hook <subcommand> [<subcommand-options>]")
3965     {
3966         LoadSubCommand ("add",      CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter)));
3967         LoadSubCommand ("delete",   CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter)));
3968         LoadSubCommand ("disable",  CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
3969                                                                                                    false,
3970                                                                                                    "target stop-hook disable [<id>]",
3971                                                                                                    "Disable a stop-hook.",
3972                                                                                                    "target stop-hook disable")));
3973         LoadSubCommand ("enable",   CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
3974                                                                                                    true,
3975                                                                                                    "target stop-hook enable [<id>]",
3976                                                                                                    "Enable a stop-hook.",
3977                                                                                                    "target stop-hook enable")));
3978         LoadSubCommand ("list",     CommandObjectSP (new CommandObjectTargetStopHookList (interpreter)));
3979     }
3980 
3981     ~CommandObjectMultiwordTargetStopHooks()
3982     {
3983     }
3984 };
3985 
3986 
3987 
3988 #pragma mark CommandObjectMultiwordTarget
3989 
3990 //-------------------------------------------------------------------------
3991 // CommandObjectMultiwordTarget
3992 //-------------------------------------------------------------------------
3993 
3994 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) :
3995     CommandObjectMultiword (interpreter,
3996                             "target",
3997                             "A set of commands for operating on debugger targets.",
3998                             "target <subcommand> [<subcommand-options>]")
3999 {
4000 
4001     LoadSubCommand ("create",    CommandObjectSP (new CommandObjectTargetCreate (interpreter)));
4002     LoadSubCommand ("delete",    CommandObjectSP (new CommandObjectTargetDelete (interpreter)));
4003     LoadSubCommand ("list",      CommandObjectSP (new CommandObjectTargetList   (interpreter)));
4004     LoadSubCommand ("select",    CommandObjectSP (new CommandObjectTargetSelect (interpreter)));
4005     LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter)));
4006     LoadSubCommand ("modules",   CommandObjectSP (new CommandObjectTargetModules (interpreter)));
4007     LoadSubCommand ("variable",  CommandObjectSP (new CommandObjectTargetVariable (interpreter)));
4008 }
4009 
4010 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget ()
4011 {
4012 }
4013 
4014 
4015