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