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