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