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