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