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