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