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