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