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