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