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