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