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