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