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