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/Host/Symbols.h"
28 #include "lldb/Interpreter/CommandInterpreter.h"
29 #include "lldb/Interpreter/CommandReturnObject.h"
30 #include "lldb/Interpreter/Options.h"
31 #include "lldb/Interpreter/OptionGroupArchitecture.h"
32 #include "lldb/Interpreter/OptionGroupBoolean.h"
33 #include "lldb/Interpreter/OptionGroupFile.h"
34 #include "lldb/Interpreter/OptionGroupFormat.h"
35 #include "lldb/Interpreter/OptionGroupVariable.h"
36 #include "lldb/Interpreter/OptionGroupPlatform.h"
37 #include "lldb/Interpreter/OptionGroupUInt64.h"
38 #include "lldb/Interpreter/OptionGroupUUID.h"
39 #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
40 #include "lldb/Symbol/CompileUnit.h"
41 #include "lldb/Symbol/FuncUnwinders.h"
42 #include "lldb/Symbol/LineTable.h"
43 #include "lldb/Symbol/ObjectFile.h"
44 #include "lldb/Symbol/SymbolFile.h"
45 #include "lldb/Symbol/SymbolVendor.h"
46 #include "lldb/Symbol/UnwindPlan.h"
47 #include "lldb/Symbol/VariableList.h"
48 #include "lldb/Target/Process.h"
49 #include "lldb/Target/StackFrame.h"
50 #include "lldb/Target/Thread.h"
51 #include "lldb/Target/ThreadSpec.h"
52 
53 using namespace lldb;
54 using namespace lldb_private;
55 
56 
57 
58 static void
59 DumpTargetInfo (uint32_t target_idx, Target *target, const char *prefix_cstr, bool show_stopped_process_status, Stream &strm)
60 {
61     const ArchSpec &target_arch = target->GetArchitecture();
62 
63     Module *exe_module = target->GetExecutableModulePointer();
64     char exe_path[PATH_MAX];
65     bool exe_valid = false;
66     if (exe_module)
67         exe_valid = exe_module->GetFileSpec().GetPath (exe_path, sizeof(exe_path));
68 
69     if (!exe_valid)
70         ::strcpy (exe_path, "<none>");
71 
72     strm.Printf ("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx, exe_path);
73 
74     uint32_t properties = 0;
75     if (target_arch.IsValid())
76     {
77         strm.Printf ("%sarch=%s", properties++ > 0 ? ", " : " ( ", target_arch.GetTriple().str().c_str());
78         properties++;
79     }
80     PlatformSP platform_sp (target->GetPlatform());
81     if (platform_sp)
82         strm.Printf ("%splatform=%s", properties++ > 0 ? ", " : " ( ", platform_sp->GetName());
83 
84     ProcessSP process_sp (target->GetProcessSP());
85     bool show_process_status = false;
86     if (process_sp)
87     {
88         lldb::pid_t pid = process_sp->GetID();
89         StateType state = process_sp->GetState();
90         if (show_stopped_process_status)
91             show_process_status = StateIsStoppedState(state, true);
92         const char *state_cstr = StateAsCString (state);
93         if (pid != LLDB_INVALID_PROCESS_ID)
94             strm.Printf ("%spid=%llu", properties++ > 0 ? ", " : " ( ", pid);
95         strm.Printf ("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
96     }
97     if (properties > 0)
98         strm.PutCString (" )\n");
99     else
100         strm.EOL();
101     if (show_process_status)
102     {
103         const bool only_threads_with_stop_reason = true;
104         const uint32_t start_frame = 0;
105         const uint32_t num_frames = 1;
106         const uint32_t num_frames_with_source = 1;
107         process_sp->GetStatus (strm);
108         process_sp->GetThreadStatus (strm,
109                                      only_threads_with_stop_reason,
110                                      start_frame,
111                                      num_frames,
112                                      num_frames_with_source);
113 
114     }
115 }
116 
117 static uint32_t
118 DumpTargetList (TargetList &target_list, bool show_stopped_process_status, Stream &strm)
119 {
120     const uint32_t num_targets = target_list.GetNumTargets();
121     if (num_targets)
122     {
123         TargetSP selected_target_sp (target_list.GetSelectedTarget());
124         strm.PutCString ("Current targets:\n");
125         for (uint32_t i=0; i<num_targets; ++i)
126         {
127             TargetSP target_sp (target_list.GetTargetAtIndex (i));
128             if (target_sp)
129             {
130                 bool is_selected = target_sp.get() == selected_target_sp.get();
131                 DumpTargetInfo (i,
132                                 target_sp.get(),
133                                 is_selected ? "* " : "  ",
134                                 show_stopped_process_status,
135                                 strm);
136             }
137         }
138     }
139     return num_targets;
140 }
141 #pragma mark CommandObjectTargetCreate
142 
143 //-------------------------------------------------------------------------
144 // "target create"
145 //-------------------------------------------------------------------------
146 
147 class CommandObjectTargetCreate : public CommandObjectParsed
148 {
149 public:
150     CommandObjectTargetCreate(CommandInterpreter &interpreter) :
151         CommandObjectParsed (interpreter,
152                              "target create",
153                              "Create a target using the argument as the main executable.",
154                              NULL),
155         m_option_group (interpreter),
156         m_arch_option (),
157         m_platform_options(true), // Do include the "--platform" option in the platform settings by passing true
158         m_core_file (LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypePath, "Fullpath to a core file to use for this target.")
159     {
160         CommandArgumentEntry arg;
161         CommandArgumentData file_arg;
162 
163         // Define the first (and only) variant of this arg.
164             file_arg.arg_type = eArgTypeFilename;
165         file_arg.arg_repetition = eArgRepeatPlain;
166 
167         // There is only one variant this argument could be; put it into the argument entry.
168         arg.push_back (file_arg);
169 
170         // Push the data for the first argument into the m_arguments vector.
171         m_arguments.push_back (arg);
172 
173         m_option_group.Append (&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
174         m_option_group.Append (&m_platform_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
175         m_option_group.Append (&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
176         m_option_group.Finalize();
177     }
178 
179     ~CommandObjectTargetCreate ()
180     {
181     }
182 
183     Options *
184     GetOptions ()
185     {
186         return &m_option_group;
187     }
188 
189     int
190     HandleArgumentCompletion (Args &input,
191                               int &cursor_index,
192                               int &cursor_char_position,
193                               OptionElementVector &opt_element_vector,
194                               int match_start_point,
195                               int max_return_elements,
196                               bool &word_complete,
197                               StringList &matches)
198     {
199         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
200         completion_str.erase (cursor_char_position);
201 
202         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
203                                                              CommandCompletions::eDiskFileCompletion,
204                                                              completion_str.c_str(),
205                                                              match_start_point,
206                                                              max_return_elements,
207                                                              NULL,
208                                                              word_complete,
209                                                              matches);
210         return matches.GetSize();
211     }
212 
213 protected:
214     bool
215     DoExecute (Args& command, CommandReturnObject &result)
216     {
217         const int argc = command.GetArgumentCount();
218         FileSpec core_file (m_core_file.GetOptionValue().GetCurrentValue());
219 
220         if (argc == 1 || core_file)
221         {
222             const char *file_path = command.GetArgumentAtIndex(0);
223             Timer scoped_timer(__PRETTY_FUNCTION__, "(lldb) target create '%s'", file_path);
224             TargetSP target_sp;
225             Debugger &debugger = m_interpreter.GetDebugger();
226             const char *arch_cstr = m_arch_option.GetArchitectureName();
227             const bool get_dependent_files = true;
228             Error error (debugger.GetTargetList().CreateTarget (debugger,
229                                                                 file_path,
230                                                                 arch_cstr,
231                                                                 get_dependent_files,
232                                                                 &m_platform_options,
233                                                                 target_sp));
234 
235             if (target_sp)
236             {
237                 if (file_path)
238                 {
239                     // Use exactly what the user typed as the first argument
240                     // when we exec or posix_spawn
241                     target_sp->SetArg0 (file_path);
242                 }
243 
244                 debugger.GetTargetList().SetSelectedTarget(target_sp.get());
245                 if (core_file)
246                 {
247                     char core_path[PATH_MAX];
248                     core_file.GetPath(core_path, sizeof(core_path));
249                     if (core_file.Exists())
250                     {
251                         FileSpec core_file_dir;
252                         core_file_dir.GetDirectory() = core_file.GetDirectory();
253                         target_sp->GetExecutableSearchPaths ().Append (core_file_dir);
254 
255                         ProcessSP process_sp (target_sp->CreateProcess (m_interpreter.GetDebugger().GetListener(), NULL, &core_file));
256 
257                         if (process_sp)
258                         {
259                             // Seems wierd that we Launch a core file, but that is
260                             // what we do!
261                             error = process_sp->LoadCore();
262 
263                             if (error.Fail())
264                             {
265                                 result.AppendError(error.AsCString("can't find plug-in for core file"));
266                                 result.SetStatus (eReturnStatusFailed);
267                                 return false;
268                             }
269                             else
270                             {
271                                 result.AppendMessageWithFormat ("Core file '%s' (%s) was loaded.\n", core_path, target_sp->GetArchitecture().GetArchitectureName());
272                                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
273                             }
274                         }
275                         else
276                         {
277                             result.AppendErrorWithFormat ("Unable to find process plug-in for core file '%s'\n", core_path);
278                             result.SetStatus (eReturnStatusFailed);
279                         }
280                     }
281                     else
282                     {
283                         result.AppendErrorWithFormat ("Core file '%s' does not exist\n", core_path);
284                         result.SetStatus (eReturnStatusFailed);
285                     }
286                 }
287                 else
288                 {
289                     result.AppendMessageWithFormat ("Current executable set to '%s' (%s).\n", file_path, target_sp->GetArchitecture().GetArchitectureName());
290                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
291                 }
292             }
293             else
294             {
295                 result.AppendError(error.AsCString());
296                 result.SetStatus (eReturnStatusFailed);
297             }
298         }
299         else
300         {
301             result.AppendErrorWithFormat("'%s' takes exactly one executable path argument, or use the --core-file option.\n", m_cmd_name.c_str());
302             result.SetStatus (eReturnStatusFailed);
303         }
304         return result.Succeeded();
305 
306     }
307 
308 private:
309     OptionGroupOptions m_option_group;
310     OptionGroupArchitecture m_arch_option;
311     OptionGroupPlatform m_platform_options;
312     OptionGroupFile m_core_file;
313 
314 };
315 
316 #pragma mark CommandObjectTargetList
317 
318 //----------------------------------------------------------------------
319 // "target list"
320 //----------------------------------------------------------------------
321 
322 class CommandObjectTargetList : public CommandObjectParsed
323 {
324 public:
325     CommandObjectTargetList (CommandInterpreter &interpreter) :
326         CommandObjectParsed (interpreter,
327                              "target list",
328                              "List all current targets in the current debug session.",
329                              NULL,
330                              0)
331     {
332     }
333 
334     virtual
335     ~CommandObjectTargetList ()
336     {
337     }
338 
339 protected:
340     virtual bool
341     DoExecute (Args& args, CommandReturnObject &result)
342     {
343         if (args.GetArgumentCount() == 0)
344         {
345             Stream &strm = result.GetOutputStream();
346 
347             bool show_stopped_process_status = false;
348             if (DumpTargetList (m_interpreter.GetDebugger().GetTargetList(), show_stopped_process_status, strm) == 0)
349             {
350                 strm.PutCString ("No targets.\n");
351             }
352             result.SetStatus (eReturnStatusSuccessFinishResult);
353         }
354         else
355         {
356             result.AppendError ("the 'target list' command takes no arguments\n");
357             result.SetStatus (eReturnStatusFailed);
358         }
359         return result.Succeeded();
360     }
361 };
362 
363 
364 #pragma mark CommandObjectTargetSelect
365 
366 //----------------------------------------------------------------------
367 // "target select"
368 //----------------------------------------------------------------------
369 
370 class CommandObjectTargetSelect : public CommandObjectParsed
371 {
372 public:
373     CommandObjectTargetSelect (CommandInterpreter &interpreter) :
374         CommandObjectParsed (interpreter,
375                              "target select",
376                              "Select a target as the current target by target index.",
377                              NULL,
378                              0)
379     {
380     }
381 
382     virtual
383     ~CommandObjectTargetSelect ()
384     {
385     }
386 
387 protected:
388     virtual bool
389     DoExecute (Args& args, CommandReturnObject &result)
390     {
391         if (args.GetArgumentCount() == 1)
392         {
393             bool success = false;
394             const char *target_idx_arg = args.GetArgumentAtIndex(0);
395             uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success);
396             if (success)
397             {
398                 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
399                 const uint32_t num_targets = target_list.GetNumTargets();
400                 if (target_idx < num_targets)
401                 {
402                     TargetSP target_sp (target_list.GetTargetAtIndex (target_idx));
403                     if (target_sp)
404                     {
405                         Stream &strm = result.GetOutputStream();
406                         target_list.SetSelectedTarget (target_sp.get());
407                         bool show_stopped_process_status = false;
408                         DumpTargetList (target_list, show_stopped_process_status, strm);
409                         result.SetStatus (eReturnStatusSuccessFinishResult);
410                     }
411                     else
412                     {
413                         result.AppendErrorWithFormat ("target #%u is NULL in target list\n", target_idx);
414                         result.SetStatus (eReturnStatusFailed);
415                     }
416                 }
417                 else
418                 {
419                     result.AppendErrorWithFormat ("index %u is out of range, valid target indexes are 0 - %u\n",
420                                                   target_idx,
421                                                   num_targets - 1);
422                     result.SetStatus (eReturnStatusFailed);
423                 }
424             }
425             else
426             {
427                 result.AppendErrorWithFormat("invalid index string value '%s'\n", target_idx_arg);
428                 result.SetStatus (eReturnStatusFailed);
429             }
430         }
431         else
432         {
433             result.AppendError ("'target select' takes a single argument: a target index\n");
434             result.SetStatus (eReturnStatusFailed);
435         }
436         return result.Succeeded();
437     }
438 };
439 
440 #pragma mark CommandObjectTargetSelect
441 
442 //----------------------------------------------------------------------
443 // "target delete"
444 //----------------------------------------------------------------------
445 
446 class CommandObjectTargetDelete : public CommandObjectParsed
447 {
448 public:
449     CommandObjectTargetDelete (CommandInterpreter &interpreter) :
450         CommandObjectParsed (interpreter,
451                              "target delete",
452                              "Delete one or more targets by target index.",
453                              NULL,
454                              0),
455         m_option_group (interpreter),
456         m_cleanup_option (LLDB_OPT_SET_1, false, "clean", 'c', "Perform extra cleanup to minimize memory consumption after deleting the target.", false, false)
457     {
458         m_option_group.Append (&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
459         m_option_group.Finalize();
460     }
461 
462     virtual
463     ~CommandObjectTargetDelete ()
464     {
465     }
466 
467     Options *
468     GetOptions ()
469     {
470         return &m_option_group;
471     }
472 
473 protected:
474     virtual bool
475     DoExecute (Args& args, CommandReturnObject &result)
476     {
477         const size_t argc = args.GetArgumentCount();
478         std::vector<TargetSP> delete_target_list;
479         TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
480         bool success = true;
481         TargetSP target_sp;
482         if (argc > 0)
483         {
484             const uint32_t num_targets = target_list.GetNumTargets();
485             // Bail out if don't have any targets.
486             if (num_targets == 0) {
487                 result.AppendError("no targets to delete");
488                 result.SetStatus(eReturnStatusFailed);
489                 success = false;
490             }
491 
492             for (uint32_t arg_idx = 0; success && arg_idx < argc; ++arg_idx)
493             {
494                 const char *target_idx_arg = args.GetArgumentAtIndex(arg_idx);
495                 uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success);
496                 if (success)
497                 {
498                     if (target_idx < num_targets)
499                     {
500                         target_sp = target_list.GetTargetAtIndex (target_idx);
501                         if (target_sp)
502                         {
503                             delete_target_list.push_back (target_sp);
504                             continue;
505                         }
506                     }
507                     if (num_targets > 1)
508                         result.AppendErrorWithFormat ("target index %u is out of range, valid target indexes are 0 - %u\n",
509                                                       target_idx,
510                                                       num_targets - 1);
511                     else
512                         result.AppendErrorWithFormat("target index %u is out of range, the only valid index is 0\n",
513                                                     target_idx);
514 
515                     result.SetStatus (eReturnStatusFailed);
516                     success = false;
517                 }
518                 else
519                 {
520                     result.AppendErrorWithFormat("invalid target index '%s'\n", target_idx_arg);
521                     result.SetStatus (eReturnStatusFailed);
522                     success = false;
523                 }
524             }
525 
526         }
527         else
528         {
529             target_sp = target_list.GetSelectedTarget();
530             if (target_sp)
531             {
532                 delete_target_list.push_back (target_sp);
533             }
534             else
535             {
536                 result.AppendErrorWithFormat("no target is currently selected\n");
537                 result.SetStatus (eReturnStatusFailed);
538                 success = false;
539             }
540         }
541         if (success)
542         {
543             const size_t num_targets_to_delete = delete_target_list.size();
544             for (size_t idx = 0; idx < num_targets_to_delete; ++idx)
545             {
546                 target_sp = delete_target_list[idx];
547                 target_list.DeleteTarget(target_sp);
548                 target_sp->Destroy();
549             }
550             // If "--clean" was specified, prune any orphaned shared modules from
551             // the global shared module list
552             if (m_cleanup_option.GetOptionValue ())
553             {
554                 const bool mandatory = true;
555                 ModuleList::RemoveOrphanSharedModules(mandatory);
556             }
557             result.GetOutputStream().Printf("%u targets deleted.\n", (uint32_t)num_targets_to_delete);
558             result.SetStatus(eReturnStatusSuccessFinishResult);
559         }
560 
561         return result.Succeeded();
562     }
563 
564     OptionGroupOptions m_option_group;
565     OptionGroupBoolean m_cleanup_option;
566 };
567 
568 
569 #pragma mark CommandObjectTargetVariable
570 
571 //----------------------------------------------------------------------
572 // "target variable"
573 //----------------------------------------------------------------------
574 
575 class CommandObjectTargetVariable : public CommandObjectParsed
576 {
577 public:
578     CommandObjectTargetVariable (CommandInterpreter &interpreter) :
579         CommandObjectParsed (interpreter,
580                              "target variable",
581                              "Read global variable(s) prior to running your binary.",
582                              NULL,
583                              0),
584         m_option_group (interpreter),
585         m_option_variable (false), // Don't include frame options
586         m_option_format (eFormatDefault),
587         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."),
588         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."),
589         m_varobj_options()
590     {
591         CommandArgumentEntry arg;
592         CommandArgumentData var_name_arg;
593 
594         // Define the first (and only) variant of this arg.
595         var_name_arg.arg_type = eArgTypeVarName;
596         var_name_arg.arg_repetition = eArgRepeatPlus;
597 
598         // There is only one variant this argument could be; put it into the argument entry.
599         arg.push_back (var_name_arg);
600 
601         // Push the data for the first argument into the m_arguments vector.
602         m_arguments.push_back (arg);
603 
604         m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
605         m_option_group.Append (&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
606         m_option_group.Append (&m_option_format, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1);
607         m_option_group.Append (&m_option_compile_units, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
608         m_option_group.Append (&m_option_shared_libraries, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
609         m_option_group.Finalize();
610     }
611 
612     virtual
613     ~CommandObjectTargetVariable ()
614     {
615     }
616 
617     void
618     DumpValueObject (Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp, const char *root_name)
619     {
620         ValueObject::DumpValueObjectOptions options;
621 
622         options.SetMaximumPointerDepth(m_varobj_options.ptr_depth)
623                .SetMaximumDepth(m_varobj_options.max_depth)
624                .SetShowTypes(m_varobj_options.show_types)
625                .SetShowLocation(m_varobj_options.show_location)
626                .SetUseObjectiveC(m_varobj_options.use_objc)
627                .SetUseDynamicType(m_varobj_options.use_dynamic)
628                .SetUseSyntheticValue(m_varobj_options.use_synth)
629                .SetFlatOutput(m_varobj_options.flat_output)
630                .SetOmitSummaryDepth(m_varobj_options.no_summary_depth)
631                .SetIgnoreCap(m_varobj_options.ignore_cap);
632 
633         switch (var_sp->GetScope())
634         {
635             case eValueTypeVariableGlobal:
636                 if (m_option_variable.show_scope)
637                     s.PutCString("GLOBAL: ");
638                 break;
639 
640             case eValueTypeVariableStatic:
641                 if (m_option_variable.show_scope)
642                     s.PutCString("STATIC: ");
643                 break;
644 
645             case eValueTypeVariableArgument:
646                 if (m_option_variable.show_scope)
647                     s.PutCString("   ARG: ");
648                 break;
649 
650             case eValueTypeVariableLocal:
651                 if (m_option_variable.show_scope)
652                     s.PutCString(" LOCAL: ");
653                 break;
654 
655             default:
656                 break;
657         }
658 
659         if (m_option_variable.show_decl)
660         {
661             bool show_fullpaths = false;
662             bool show_module = true;
663             if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
664                 s.PutCString (": ");
665         }
666 
667         const Format format = m_option_format.GetFormat();
668         if (format != eFormatDefault)
669             options.SetFormat(format);
670 
671         options.SetRootValueObjectName(root_name);
672 
673         ValueObject::DumpValueObject (s,
674                                       valobj_sp.get(),
675                                       options);
676 
677     }
678 
679 
680     static uint32_t GetVariableCallback (void *baton,
681                                          const char *name,
682                                          VariableList &variable_list)
683     {
684         Target *target = static_cast<Target *>(baton);
685         if (target)
686         {
687             return target->GetImages().FindGlobalVariables (ConstString(name),
688                                                             true,
689                                                             UINT32_MAX,
690                                                             variable_list);
691         }
692         return 0;
693     }
694 
695 
696 
697     Options *
698     GetOptions ()
699     {
700         return &m_option_group;
701     }
702 
703 protected:
704     virtual bool
705     DoExecute (Args& args, CommandReturnObject &result)
706     {
707         ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
708         Target *target = exe_ctx.GetTargetPtr();
709         if (target)
710         {
711             const size_t argc = args.GetArgumentCount();
712             Stream &s = result.GetOutputStream();
713             if (argc > 0)
714             {
715 
716                 for (size_t idx = 0; idx < argc; ++idx)
717                 {
718                     VariableList variable_list;
719                     ValueObjectList valobj_list;
720 
721                     const char *arg = args.GetArgumentAtIndex(idx);
722                     uint32_t matches = 0;
723                     bool use_var_name = false;
724                     if (m_option_variable.use_regex)
725                     {
726                         RegularExpression regex(arg);
727                         if (!regex.IsValid ())
728                         {
729                             result.GetErrorStream().Printf ("error: invalid regular expression: '%s'\n", arg);
730                             result.SetStatus (eReturnStatusFailed);
731                             return false;
732                         }
733                         use_var_name = true;
734                         matches = target->GetImages().FindGlobalVariables (regex,
735                                                                            true,
736                                                                            UINT32_MAX,
737                                                                            variable_list);
738                     }
739                     else
740                     {
741                         Error error (Variable::GetValuesForVariableExpressionPath (arg,
742                                                                                    exe_ctx.GetBestExecutionContextScope(),
743                                                                                    GetVariableCallback,
744                                                                                    target,
745                                                                                    variable_list,
746                                                                                    valobj_list));
747                         matches = variable_list.GetSize();
748                     }
749 
750                     if (matches == 0)
751                     {
752                         result.GetErrorStream().Printf ("error: can't find global variable '%s'\n", arg);
753                         result.SetStatus (eReturnStatusFailed);
754                         return false;
755                     }
756                     else
757                     {
758                         for (uint32_t global_idx=0; global_idx<matches; ++global_idx)
759                         {
760                             VariableSP var_sp (variable_list.GetVariableAtIndex(global_idx));
761                             if (var_sp)
762                             {
763                                 ValueObjectSP valobj_sp (valobj_list.GetValueObjectAtIndex(global_idx));
764                                 if (!valobj_sp)
765                                     valobj_sp = ValueObjectVariable::Create (exe_ctx.GetBestExecutionContextScope(), var_sp);
766 
767                                 if (valobj_sp)
768                                     DumpValueObject (s, var_sp, valobj_sp, use_var_name ? var_sp->GetName().GetCString() : arg);
769                             }
770                         }
771                     }
772                 }
773             }
774             else
775             {
776                 bool success = false;
777                 StackFrame *frame = exe_ctx.GetFramePtr();
778                 CompileUnit *comp_unit = NULL;
779                 if (frame)
780                 {
781                     comp_unit = frame->GetSymbolContext (eSymbolContextCompUnit).comp_unit;
782                     if (comp_unit)
783                     {
784                         const bool can_create = true;
785                         VariableListSP comp_unit_varlist_sp (comp_unit->GetVariableList(can_create));
786                         if (comp_unit_varlist_sp)
787                         {
788                             size_t count = comp_unit_varlist_sp->GetSize();
789                             if (count > 0)
790                             {
791                                 s.Printf ("Global variables for %s/%s:\n",
792                                           comp_unit->GetDirectory().GetCString(),
793                                           comp_unit->GetFilename().GetCString());
794 
795                                 success = true;
796                                 for (uint32_t i=0; i<count; ++i)
797                                 {
798                                     VariableSP var_sp (comp_unit_varlist_sp->GetVariableAtIndex(i));
799                                     if (var_sp)
800                                     {
801                                         ValueObjectSP valobj_sp (ValueObjectVariable::Create (exe_ctx.GetBestExecutionContextScope(), var_sp));
802 
803                                         if (valobj_sp)
804                                             DumpValueObject (s, var_sp, valobj_sp, var_sp->GetName().GetCString());
805                                     }
806                                 }
807                             }
808                         }
809                     }
810                 }
811                 if (!success)
812                 {
813                     if (frame)
814                     {
815                         if (comp_unit)
816                             result.AppendErrorWithFormat ("no global variables in current compile unit: %s/%s\n",
817                                                           comp_unit->GetDirectory().GetCString(),
818                                                           comp_unit->GetFilename().GetCString());
819                         else
820                             result.AppendError ("no debug information for frame %u\n", frame->GetFrameIndex());
821                     }
822                     else
823                         result.AppendError ("'target variable' takes one or more global variable names as arguments\n");
824                     result.SetStatus (eReturnStatusFailed);
825                 }
826             }
827         }
828         else
829         {
830             result.AppendError ("invalid target, create a debug target using the 'target create' command");
831             result.SetStatus (eReturnStatusFailed);
832             return false;
833         }
834 
835         if (m_interpreter.TruncationWarningNecessary())
836         {
837             result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
838                                             m_cmd_name.c_str());
839             m_interpreter.TruncationWarningGiven();
840         }
841 
842         return result.Succeeded();
843     }
844 
845     OptionGroupOptions m_option_group;
846     OptionGroupVariable m_option_variable;
847     OptionGroupFormat m_option_format;
848     OptionGroupFileList m_option_compile_units;
849     OptionGroupFileList m_option_shared_libraries;
850     OptionGroupValueObjectDisplay m_varobj_options;
851 
852 };
853 
854 
855 #pragma mark CommandObjectTargetModulesSearchPathsAdd
856 
857 class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed
858 {
859 public:
860 
861     CommandObjectTargetModulesSearchPathsAdd (CommandInterpreter &interpreter) :
862         CommandObjectParsed (interpreter,
863                              "target modules search-paths add",
864                              "Add new image search paths substitution pairs to the current target.",
865                              NULL)
866     {
867         CommandArgumentEntry arg;
868         CommandArgumentData old_prefix_arg;
869         CommandArgumentData new_prefix_arg;
870 
871         // Define the first variant of this arg pair.
872         old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
873         old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
874 
875         // Define the first variant of this arg pair.
876         new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
877         new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
878 
879         // There are two required arguments that must always occur together, i.e. an argument "pair".  Because they
880         // must always occur together, they are treated as two variants of one argument rather than two independent
881         // arguments.  Push them both into the first argument position for m_arguments...
882 
883         arg.push_back (old_prefix_arg);
884         arg.push_back (new_prefix_arg);
885 
886         m_arguments.push_back (arg);
887     }
888 
889     ~CommandObjectTargetModulesSearchPathsAdd ()
890     {
891     }
892 
893 protected:
894     bool
895     DoExecute (Args& command,
896              CommandReturnObject &result)
897     {
898         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
899         if (target)
900         {
901             uint32_t argc = command.GetArgumentCount();
902             if (argc & 1)
903             {
904                 result.AppendError ("add requires an even number of arguments\n");
905                 result.SetStatus (eReturnStatusFailed);
906             }
907             else
908             {
909                 for (uint32_t i=0; i<argc; i+=2)
910                 {
911                     const char *from = command.GetArgumentAtIndex(i);
912                     const char *to = command.GetArgumentAtIndex(i+1);
913 
914                     if (from[0] && to[0])
915                     {
916                         bool last_pair = ((argc - i) == 2);
917                         target->GetImageSearchPathList().Append (ConstString(from),
918                                                                  ConstString(to),
919                                                                  last_pair); // Notify if this is the last pair
920                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
921                     }
922                     else
923                     {
924                         if (from[0])
925                             result.AppendError ("<path-prefix> can't be empty\n");
926                         else
927                             result.AppendError ("<new-path-prefix> can't be empty\n");
928                         result.SetStatus (eReturnStatusFailed);
929                     }
930                 }
931             }
932         }
933         else
934         {
935             result.AppendError ("invalid target\n");
936             result.SetStatus (eReturnStatusFailed);
937         }
938         return result.Succeeded();
939     }
940 };
941 
942 #pragma mark CommandObjectTargetModulesSearchPathsClear
943 
944 class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed
945 {
946 public:
947 
948     CommandObjectTargetModulesSearchPathsClear (CommandInterpreter &interpreter) :
949         CommandObjectParsed (interpreter,
950                              "target modules search-paths clear",
951                              "Clear all current image search path substitution pairs from the current target.",
952                              "target modules search-paths clear")
953     {
954     }
955 
956     ~CommandObjectTargetModulesSearchPathsClear ()
957     {
958     }
959 
960 protected:
961     bool
962     DoExecute (Args& command,
963              CommandReturnObject &result)
964     {
965         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
966         if (target)
967         {
968             bool notify = true;
969             target->GetImageSearchPathList().Clear(notify);
970             result.SetStatus (eReturnStatusSuccessFinishNoResult);
971         }
972         else
973         {
974             result.AppendError ("invalid target\n");
975             result.SetStatus (eReturnStatusFailed);
976         }
977         return result.Succeeded();
978     }
979 };
980 
981 #pragma mark CommandObjectTargetModulesSearchPathsInsert
982 
983 class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed
984 {
985 public:
986 
987     CommandObjectTargetModulesSearchPathsInsert (CommandInterpreter &interpreter) :
988         CommandObjectParsed (interpreter,
989                              "target modules search-paths insert",
990                              "Insert a new image search path substitution pair into the current target at the specified index.",
991                              NULL)
992     {
993         CommandArgumentEntry arg1;
994         CommandArgumentEntry arg2;
995         CommandArgumentData index_arg;
996         CommandArgumentData old_prefix_arg;
997         CommandArgumentData new_prefix_arg;
998 
999         // Define the first and only variant of this arg.
1000         index_arg.arg_type = eArgTypeIndex;
1001         index_arg.arg_repetition = eArgRepeatPlain;
1002 
1003         // Put the one and only variant into the first arg for m_arguments:
1004         arg1.push_back (index_arg);
1005 
1006         // Define the first variant of this arg pair.
1007         old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1008         old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1009 
1010         // Define the first variant of this arg pair.
1011         new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1012         new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1013 
1014         // There are two required arguments that must always occur together, i.e. an argument "pair".  Because they
1015         // must always occur together, they are treated as two variants of one argument rather than two independent
1016         // arguments.  Push them both into the same argument position for m_arguments...
1017 
1018         arg2.push_back (old_prefix_arg);
1019         arg2.push_back (new_prefix_arg);
1020 
1021         // Add arguments to m_arguments.
1022         m_arguments.push_back (arg1);
1023         m_arguments.push_back (arg2);
1024     }
1025 
1026     ~CommandObjectTargetModulesSearchPathsInsert ()
1027     {
1028     }
1029 
1030 protected:
1031     bool
1032     DoExecute (Args& command,
1033              CommandReturnObject &result)
1034     {
1035         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1036         if (target)
1037         {
1038             uint32_t argc = command.GetArgumentCount();
1039             // check for at least 3 arguments and an odd nubmer of parameters
1040             if (argc >= 3 && argc & 1)
1041             {
1042                 bool success = false;
1043 
1044                 uint32_t insert_idx = Args::StringToUInt32(command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
1045 
1046                 if (!success)
1047                 {
1048                     result.AppendErrorWithFormat("<index> parameter is not an integer: '%s'.\n", command.GetArgumentAtIndex(0));
1049                     result.SetStatus (eReturnStatusFailed);
1050                     return result.Succeeded();
1051                 }
1052 
1053                 // shift off the index
1054                 command.Shift();
1055                 argc = command.GetArgumentCount();
1056 
1057                 for (uint32_t i=0; i<argc; i+=2, ++insert_idx)
1058                 {
1059                     const char *from = command.GetArgumentAtIndex(i);
1060                     const char *to = command.GetArgumentAtIndex(i+1);
1061 
1062                     if (from[0] && to[0])
1063                     {
1064                         bool last_pair = ((argc - i) == 2);
1065                         target->GetImageSearchPathList().Insert (ConstString(from),
1066                                                                  ConstString(to),
1067                                                                  insert_idx,
1068                                                                  last_pair);
1069                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1070                     }
1071                     else
1072                     {
1073                         if (from[0])
1074                             result.AppendError ("<path-prefix> can't be empty\n");
1075                         else
1076                             result.AppendError ("<new-path-prefix> can't be empty\n");
1077                         result.SetStatus (eReturnStatusFailed);
1078                         return false;
1079                     }
1080                 }
1081             }
1082             else
1083             {
1084                 result.AppendError ("insert requires at least three arguments\n");
1085                 result.SetStatus (eReturnStatusFailed);
1086                 return result.Succeeded();
1087             }
1088 
1089         }
1090         else
1091         {
1092             result.AppendError ("invalid target\n");
1093             result.SetStatus (eReturnStatusFailed);
1094         }
1095         return result.Succeeded();
1096     }
1097 };
1098 
1099 
1100 #pragma mark CommandObjectTargetModulesSearchPathsList
1101 
1102 
1103 class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed
1104 {
1105 public:
1106 
1107     CommandObjectTargetModulesSearchPathsList (CommandInterpreter &interpreter) :
1108         CommandObjectParsed (interpreter,
1109                              "target modules search-paths list",
1110                              "List all current image search path substitution pairs in the current target.",
1111                              "target modules search-paths list")
1112     {
1113     }
1114 
1115     ~CommandObjectTargetModulesSearchPathsList ()
1116     {
1117     }
1118 
1119 protected:
1120     bool
1121     DoExecute (Args& command,
1122              CommandReturnObject &result)
1123     {
1124         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1125         if (target)
1126         {
1127             if (command.GetArgumentCount() != 0)
1128             {
1129                 result.AppendError ("list takes no arguments\n");
1130                 result.SetStatus (eReturnStatusFailed);
1131                 return result.Succeeded();
1132             }
1133 
1134             target->GetImageSearchPathList().Dump(&result.GetOutputStream());
1135             result.SetStatus (eReturnStatusSuccessFinishResult);
1136         }
1137         else
1138         {
1139             result.AppendError ("invalid target\n");
1140             result.SetStatus (eReturnStatusFailed);
1141         }
1142         return result.Succeeded();
1143     }
1144 };
1145 
1146 #pragma mark CommandObjectTargetModulesSearchPathsQuery
1147 
1148 class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed
1149 {
1150 public:
1151 
1152     CommandObjectTargetModulesSearchPathsQuery (CommandInterpreter &interpreter) :
1153         CommandObjectParsed (interpreter,
1154                              "target modules search-paths query",
1155                              "Transform a path using the first applicable image search path.",
1156                              NULL)
1157     {
1158         CommandArgumentEntry arg;
1159         CommandArgumentData path_arg;
1160 
1161         // Define the first (and only) variant of this arg.
1162         path_arg.arg_type = eArgTypePath;
1163         path_arg.arg_repetition = eArgRepeatPlain;
1164 
1165         // There is only one variant this argument could be; put it into the argument entry.
1166         arg.push_back (path_arg);
1167 
1168         // Push the data for the first argument into the m_arguments vector.
1169         m_arguments.push_back (arg);
1170     }
1171 
1172     ~CommandObjectTargetModulesSearchPathsQuery ()
1173     {
1174     }
1175 
1176 protected:
1177     bool
1178     DoExecute (Args& command,
1179              CommandReturnObject &result)
1180     {
1181         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1182         if (target)
1183         {
1184             if (command.GetArgumentCount() != 1)
1185             {
1186                 result.AppendError ("query requires one argument\n");
1187                 result.SetStatus (eReturnStatusFailed);
1188                 return result.Succeeded();
1189             }
1190 
1191             ConstString orig(command.GetArgumentAtIndex(0));
1192             ConstString transformed;
1193             if (target->GetImageSearchPathList().RemapPath(orig, transformed))
1194                 result.GetOutputStream().Printf("%s\n", transformed.GetCString());
1195             else
1196                 result.GetOutputStream().Printf("%s\n", orig.GetCString());
1197 
1198             result.SetStatus (eReturnStatusSuccessFinishResult);
1199         }
1200         else
1201         {
1202             result.AppendError ("invalid target\n");
1203             result.SetStatus (eReturnStatusFailed);
1204         }
1205         return result.Succeeded();
1206     }
1207 };
1208 
1209 //----------------------------------------------------------------------
1210 // Static Helper functions
1211 //----------------------------------------------------------------------
1212 static void
1213 DumpModuleArchitecture (Stream &strm, Module *module, bool full_triple, uint32_t width)
1214 {
1215     if (module)
1216     {
1217         const char *arch_cstr;
1218         if (full_triple)
1219             arch_cstr = module->GetArchitecture().GetTriple().str().c_str();
1220         else
1221             arch_cstr = module->GetArchitecture().GetArchitectureName();
1222         if (width)
1223             strm.Printf("%-*s", width, arch_cstr);
1224         else
1225             strm.PutCString(arch_cstr);
1226     }
1227 }
1228 
1229 static void
1230 DumpModuleUUID (Stream &strm, Module *module)
1231 {
1232     if (module && module->GetUUID().IsValid())
1233         module->GetUUID().Dump (&strm);
1234     else
1235         strm.PutCString("                                    ");
1236 }
1237 
1238 static uint32_t
1239 DumpCompileUnitLineTable (CommandInterpreter &interpreter,
1240                           Stream &strm,
1241                           Module *module,
1242                           const FileSpec &file_spec,
1243                           bool load_addresses)
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                         FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
2723                         if (module_spec_file)
2724                         {
2725                             module_spec_file->GetPath (path, sizeof(path));
2726                             result.AppendErrorWithFormat ("invalid module '%s'.\n", path);
2727                         }
2728                         else
2729                             result.AppendError ("no module spec");
2730                         result.SetStatus (eReturnStatusFailed);
2731                     }
2732                 }
2733                 else
2734                 {
2735                     char uuid_cstr[64];
2736 
2737                     if (module_spec.GetFileSpec())
2738                         module_spec.GetFileSpec().GetPath (path, sizeof(path));
2739                     else
2740                         path[0] = '\0';
2741 
2742                     if (module_spec.GetUUIDPtr())
2743                         module_spec.GetUUID().GetAsCString(uuid_cstr, sizeof(uuid_cstr));
2744                     else
2745                         uuid_cstr[0] = '\0';
2746                     if (num_matches > 1)
2747                     {
2748                         result.AppendErrorWithFormat ("multiple modules match%s%s%s%s:\n",
2749                                                       path[0] ? " file=" : "",
2750                                                       path,
2751                                                       uuid_cstr[0] ? " uuid=" : "",
2752                                                       uuid_cstr);
2753                         for (size_t i=0; i<num_matches; ++i)
2754                         {
2755                             if (matching_modules.GetModulePointerAtIndex(i)->GetFileSpec().GetPath (path, sizeof(path)))
2756                                 result.AppendMessageWithFormat("%s\n", path);
2757                         }
2758                     }
2759                     else
2760                     {
2761                         result.AppendErrorWithFormat ("no modules were found  that match%s%s%s%s.\n",
2762                                                       path[0] ? " file=" : "",
2763                                                       path,
2764                                                       uuid_cstr[0] ? " uuid=" : "",
2765                                                       uuid_cstr);
2766                     }
2767                     result.SetStatus (eReturnStatusFailed);
2768                 }
2769             }
2770             else
2771             {
2772                 result.AppendError ("either the \"--file <module>\" or the \"--uuid <uuid>\" option must be specified.\n");
2773                 result.SetStatus (eReturnStatusFailed);
2774                 return false;
2775             }
2776         }
2777         return result.Succeeded();
2778     }
2779 
2780     OptionGroupOptions m_option_group;
2781     OptionGroupUUID m_uuid_option_group;
2782     OptionGroupFile m_file_option;
2783     OptionGroupUInt64 m_slide_option;
2784 };
2785 
2786 //----------------------------------------------------------------------
2787 // List images with associated information
2788 //----------------------------------------------------------------------
2789 class CommandObjectTargetModulesList : public CommandObjectParsed
2790 {
2791 public:
2792 
2793     class CommandOptions : public Options
2794     {
2795     public:
2796 
2797         CommandOptions (CommandInterpreter &interpreter) :
2798             Options(interpreter),
2799             m_format_array(),
2800             m_use_global_module_list (false),
2801             m_module_addr (LLDB_INVALID_ADDRESS)
2802         {
2803         }
2804 
2805         virtual
2806         ~CommandOptions ()
2807         {
2808         }
2809 
2810         virtual Error
2811         SetOptionValue (uint32_t option_idx, const char *option_arg)
2812         {
2813             char short_option = (char) m_getopt_table[option_idx].val;
2814             if (short_option == 'g')
2815             {
2816                 m_use_global_module_list = true;
2817             }
2818             else if (short_option == 'a')
2819             {
2820                 bool success;
2821                 m_module_addr = Args::StringToAddress(option_arg, LLDB_INVALID_ADDRESS, &success);
2822                 if (!success)
2823                 {
2824                     Error error;
2825                     error.SetErrorStringWithFormat("invalid address: \"%s\"", option_arg);
2826                 }
2827             }
2828             else
2829             {
2830                 uint32_t width = 0;
2831                 if (option_arg)
2832                     width = strtoul (option_arg, NULL, 0);
2833                 m_format_array.push_back(std::make_pair(short_option, width));
2834             }
2835             Error error;
2836             return error;
2837         }
2838 
2839         void
2840         OptionParsingStarting ()
2841         {
2842             m_format_array.clear();
2843             m_use_global_module_list = false;
2844             m_module_addr = LLDB_INVALID_ADDRESS;
2845         }
2846 
2847         const OptionDefinition*
2848         GetDefinitions ()
2849         {
2850             return g_option_table;
2851         }
2852 
2853         // Options table: Required for subclasses of Options.
2854 
2855         static OptionDefinition g_option_table[];
2856 
2857         // Instance variables to hold the values for command options.
2858         typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection;
2859         FormatWidthCollection m_format_array;
2860         bool m_use_global_module_list;
2861         lldb::addr_t m_module_addr;
2862     };
2863 
2864     CommandObjectTargetModulesList (CommandInterpreter &interpreter) :
2865         CommandObjectParsed (interpreter,
2866                              "target modules list",
2867                              "List current executable and dependent shared library images.",
2868                              "target modules list [<cmd-options>]"),
2869         m_options (interpreter)
2870     {
2871     }
2872 
2873     virtual
2874     ~CommandObjectTargetModulesList ()
2875     {
2876     }
2877 
2878     virtual
2879     Options *
2880     GetOptions ()
2881     {
2882         return &m_options;
2883     }
2884 
2885 protected:
2886     virtual bool
2887     DoExecute (Args& command,
2888              CommandReturnObject &result)
2889     {
2890         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2891         const bool use_global_module_list = m_options.m_use_global_module_list;
2892         // Define a local module list here to ensure it lives longer than any "locker"
2893         // object which might lock its contents below (through the "module_list_ptr"
2894         // variable).
2895         ModuleList module_list;
2896         if (target == NULL && use_global_module_list == false)
2897         {
2898             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2899             result.SetStatus (eReturnStatusFailed);
2900             return false;
2901         }
2902         else
2903         {
2904             if (target)
2905             {
2906                 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2907                 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2908                 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2909             }
2910             // Dump all sections for all modules images
2911             Stream &strm = result.GetOutputStream();
2912 
2913             if (m_options.m_module_addr != LLDB_INVALID_ADDRESS)
2914             {
2915                 if (target)
2916                 {
2917                     Address module_address;
2918                     if (module_address.SetLoadAddress(m_options.m_module_addr, target))
2919                     {
2920                         ModuleSP module_sp (module_address.GetModule());
2921                         if (module_sp)
2922                         {
2923                             PrintModule (target, module_sp.get(), UINT32_MAX, 0, strm);
2924                             result.SetStatus (eReturnStatusSuccessFinishResult);
2925                         }
2926                         else
2927                         {
2928                             result.AppendError ("Couldn't find module matching address: 0x%llx.", m_options.m_module_addr);
2929                             result.SetStatus (eReturnStatusFailed);
2930                         }
2931                     }
2932                     else
2933                     {
2934                         result.AppendError ("Couldn't find module containing address: 0x%llx.", m_options.m_module_addr);
2935                         result.SetStatus (eReturnStatusFailed);
2936                     }
2937                 }
2938                 else
2939                 {
2940                     result.AppendError ("Can only look up modules by address with a valid target.");
2941                     result.SetStatus (eReturnStatusFailed);
2942                 }
2943                 return result.Succeeded();
2944             }
2945 
2946             uint32_t num_modules = 0;
2947             Mutex::Locker locker;      // This locker will be locked on the mutex in module_list_ptr if it is non-NULL.
2948                                        // Otherwise it will lock the AllocationModuleCollectionMutex when accessing
2949                                        // the global module list directly.
2950             ModuleList *module_list_ptr = NULL;
2951             const size_t argc = command.GetArgumentCount();
2952             if (argc == 0)
2953             {
2954                 if (use_global_module_list)
2955                 {
2956                     locker.Lock (Module::GetAllocationModuleCollectionMutex());
2957                     num_modules = Module::GetNumberAllocatedModules();
2958                 }
2959                 else
2960                 {
2961                     module_list_ptr = &target->GetImages();
2962                 }
2963             }
2964             else
2965             {
2966                 for (size_t i=0; i<argc; ++i)
2967                 {
2968                     // Dump specified images (by basename or fullpath)
2969                     const char *arg_cstr = command.GetArgumentAtIndex(i);
2970                     const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, use_global_module_list);
2971                     if (num_matches == 0)
2972                     {
2973                         if (argc == 1)
2974                         {
2975                             result.AppendErrorWithFormat ("no modules found that match '%s'", arg_cstr);
2976                             result.SetStatus (eReturnStatusFailed);
2977                             return false;
2978                         }
2979                     }
2980                 }
2981 
2982                 module_list_ptr = &module_list;
2983             }
2984 
2985             if (module_list_ptr != NULL)
2986             {
2987                 locker.Lock(module_list_ptr->GetMutex());
2988                 num_modules = module_list_ptr->GetSize();
2989             }
2990 
2991             if (num_modules > 0)
2992             {
2993                 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
2994                 {
2995                     ModuleSP module_sp;
2996                     Module *module;
2997                     if (module_list_ptr)
2998                     {
2999                         module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
3000                         module = module_sp.get();
3001                     }
3002                     else
3003                     {
3004                         module = Module::GetAllocatedModuleAtIndex(image_idx);
3005                         module_sp = module->shared_from_this();
3006                     }
3007 
3008                     int indent = strm.Printf("[%3u] ", image_idx);
3009                     PrintModule (target, module, image_idx, indent, strm);
3010 
3011                 }
3012                 result.SetStatus (eReturnStatusSuccessFinishResult);
3013             }
3014             else
3015             {
3016                 if (argc)
3017                 {
3018                     if (use_global_module_list)
3019                         result.AppendError ("the global module list has no matching modules");
3020                     else
3021                         result.AppendError ("the target has no matching modules");
3022                 }
3023                 else
3024                 {
3025                     if (use_global_module_list)
3026                         result.AppendError ("the global module list is empty");
3027                     else
3028                         result.AppendError ("the target has no associated executable images");
3029                 }
3030                 result.SetStatus (eReturnStatusFailed);
3031                 return false;
3032             }
3033         }
3034         return result.Succeeded();
3035     }
3036 
3037     void
3038     PrintModule (Target *target, Module *module, uint32_t idx, int indent, Stream &strm)
3039     {
3040 
3041         if (module == NULL)
3042         {
3043             strm.PutCString("Null module");
3044             return;
3045         }
3046 
3047         bool dump_object_name = false;
3048         if (m_options.m_format_array.empty())
3049         {
3050             m_options.m_format_array.push_back(std::make_pair('u', 0));
3051             m_options.m_format_array.push_back(std::make_pair('h', 0));
3052             m_options.m_format_array.push_back(std::make_pair('f', 0));
3053             m_options.m_format_array.push_back(std::make_pair('S', 0));
3054         }
3055         const size_t num_entries = m_options.m_format_array.size();
3056         bool print_space = false;
3057         for (size_t i=0; i<num_entries; ++i)
3058         {
3059             if (print_space)
3060                 strm.PutChar(' ');
3061             print_space = true;
3062             const char format_char = m_options.m_format_array[i].first;
3063             uint32_t width = m_options.m_format_array[i].second;
3064             switch (format_char)
3065             {
3066                 case 'A':
3067                     DumpModuleArchitecture (strm, module, false, width);
3068                     break;
3069 
3070                 case 't':
3071                     DumpModuleArchitecture (strm, module, true, width);
3072                     break;
3073 
3074                 case 'f':
3075                     DumpFullpath (strm, &module->GetFileSpec(), width);
3076                     dump_object_name = true;
3077                     break;
3078 
3079                 case 'd':
3080                     DumpDirectory (strm, &module->GetFileSpec(), width);
3081                     break;
3082 
3083                 case 'b':
3084                     DumpBasename (strm, &module->GetFileSpec(), width);
3085                     dump_object_name = true;
3086                     break;
3087 
3088                 case 'h':
3089                 case 'o':
3090                     // Image header address
3091                     {
3092                         uint32_t addr_nibble_width = target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16;
3093 
3094                         ObjectFile *objfile = module->GetObjectFile ();
3095                         if (objfile)
3096                         {
3097                             Address header_addr(objfile->GetHeaderAddress());
3098                             if (header_addr.IsValid())
3099                             {
3100                                 if (target && !target->GetSectionLoadList().IsEmpty())
3101                                 {
3102                                     lldb::addr_t header_load_addr = header_addr.GetLoadAddress (target);
3103                                     if (header_load_addr == LLDB_INVALID_ADDRESS)
3104                                     {
3105                                         header_addr.Dump (&strm, target, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleFileAddress);
3106                                     }
3107                                     else
3108                                     {
3109                                         if (format_char == 'o')
3110                                         {
3111                                             // Show the offset of slide for the image
3112                                             strm.Printf ("0x%*.*llx", addr_nibble_width, addr_nibble_width, header_load_addr - header_addr.GetFileAddress());
3113                                         }
3114                                         else
3115                                         {
3116                                             // Show the load address of the image
3117                                             strm.Printf ("0x%*.*llx", addr_nibble_width, addr_nibble_width, header_load_addr);
3118                                         }
3119                                     }
3120                                     break;
3121                                 }
3122                                 // The address was valid, but the image isn't loaded, output the address in an appropriate format
3123                                 header_addr.Dump (&strm, target, Address::DumpStyleFileAddress);
3124                                 break;
3125                             }
3126                         }
3127                         strm.Printf ("%*s", addr_nibble_width + 2, "");
3128                     }
3129                     break;
3130                 case 'r':
3131                     {
3132                         uint32_t ref_count = 0;
3133                         ModuleSP module_sp (module->shared_from_this());
3134                         if (module_sp)
3135                         {
3136                             // Take one away to make sure we don't count our local "module_sp"
3137                             ref_count = module_sp.use_count() - 1;
3138                         }
3139                         if (width)
3140                             strm.Printf("{%*u}", width, ref_count);
3141                         else
3142                             strm.Printf("{%u}", ref_count);
3143                     }
3144                     break;
3145 
3146                 case 's':
3147                 case 'S':
3148                     {
3149                         SymbolVendor *symbol_vendor = module->GetSymbolVendor();
3150                         if (symbol_vendor)
3151                         {
3152                             SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
3153                             if (symbol_file)
3154                             {
3155                                 if (format_char == 'S')
3156                                 {
3157                                     FileSpec &symfile_spec = symbol_file->GetObjectFile()->GetFileSpec();
3158                                     // Dump symbol file only if different from module file
3159                                     if (!symfile_spec || symfile_spec == module->GetFileSpec())
3160                                     {
3161                                         print_space = false;
3162                                         break;
3163                                     }
3164                                     // Add a newline and indent past the index
3165                                     strm.Printf ("\n%*s", indent, "");
3166                                 }
3167                                 DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
3168                                 dump_object_name = true;
3169                                 break;
3170                             }
3171                         }
3172                         strm.Printf("%.*s", width, "<NONE>");
3173                     }
3174                     break;
3175 
3176                 case 'm':
3177                     module->GetModificationTime().Dump(&strm, width);
3178                     break;
3179 
3180                 case 'p':
3181                     strm.Printf("%p", module);
3182                     break;
3183 
3184                 case 'u':
3185                     DumpModuleUUID(strm, module);
3186                     break;
3187 
3188                 default:
3189                     break;
3190             }
3191 
3192         }
3193         if (dump_object_name)
3194         {
3195             const char *object_name = module->GetObjectName().GetCString();
3196             if (object_name)
3197                 strm.Printf ("(%s)", object_name);
3198         }
3199         strm.EOL();
3200     }
3201 
3202     CommandOptions m_options;
3203 };
3204 
3205 OptionDefinition
3206 CommandObjectTargetModulesList::CommandOptions::g_option_table[] =
3207 {
3208     { LLDB_OPT_SET_1, false, "address",    'a', required_argument, NULL, 0, eArgTypeAddress, "Display the image at this address."},
3209     { LLDB_OPT_SET_1, false, "arch",       'A', optional_argument, NULL, 0, eArgTypeWidth,   "Display the architecture when listing images."},
3210     { LLDB_OPT_SET_1, false, "triple",     't', optional_argument, NULL, 0, eArgTypeWidth,   "Display the triple when listing images."},
3211     { 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."},
3212     { 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)."},
3213     { LLDB_OPT_SET_1, false, "uuid",       'u', no_argument,       NULL, 0, eArgTypeNone,    "Display the UUID when listing images."},
3214     { LLDB_OPT_SET_1, false, "fullpath",   'f', optional_argument, NULL, 0, eArgTypeWidth,   "Display the fullpath to the image object file."},
3215     { LLDB_OPT_SET_1, false, "directory",  'd', optional_argument, NULL, 0, eArgTypeWidth,   "Display the directory with optional width for the image object file."},
3216     { LLDB_OPT_SET_1, false, "basename",   'b', optional_argument, NULL, 0, eArgTypeWidth,   "Display the basename with optional width for the image object file."},
3217     { LLDB_OPT_SET_1, false, "symfile",    's', optional_argument, NULL, 0, eArgTypeWidth,   "Display the fullpath to the image symbol file with optional width."},
3218     { 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."},
3219     { LLDB_OPT_SET_1, false, "mod-time",   'm', optional_argument, NULL, 0, eArgTypeWidth,   "Display the modification time with optional width of the module."},
3220     { 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."},
3221     { LLDB_OPT_SET_1, false, "pointer",    'p', optional_argument, NULL, 0, eArgTypeNone,    "Display the module pointer."},
3222     { 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."},
3223     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
3224 };
3225 
3226 #pragma mark CommandObjectTargetModulesShowUnwind
3227 
3228 //----------------------------------------------------------------------
3229 // Lookup unwind information in images
3230 //----------------------------------------------------------------------
3231 
3232 class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed
3233 {
3234 public:
3235 
3236     enum
3237     {
3238         eLookupTypeInvalid = -1,
3239         eLookupTypeAddress = 0,
3240         eLookupTypeSymbol,
3241         eLookupTypeFunction,
3242         eLookupTypeFunctionOrSymbol,
3243         kNumLookupTypes
3244     };
3245 
3246     class CommandOptions : public Options
3247     {
3248     public:
3249 
3250         CommandOptions (CommandInterpreter &interpreter) :
3251         Options(interpreter),
3252         m_type(eLookupTypeInvalid),
3253         m_str(),
3254         m_addr(LLDB_INVALID_ADDRESS)
3255         {
3256         }
3257 
3258         virtual
3259         ~CommandOptions ()
3260         {
3261         }
3262 
3263         virtual Error
3264         SetOptionValue (uint32_t option_idx, const char *option_arg)
3265         {
3266             Error error;
3267 
3268             char short_option = (char) m_getopt_table[option_idx].val;
3269 
3270             switch (short_option)
3271             {
3272                 case 'a':
3273                     m_type = eLookupTypeAddress;
3274                     m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
3275                     if (m_addr == LLDB_INVALID_ADDRESS)
3276                         error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg);
3277                     break;
3278 
3279                 case 'n':
3280                     m_str = option_arg;
3281                     m_type = eLookupTypeFunctionOrSymbol;
3282                     break;
3283             }
3284 
3285             return error;
3286         }
3287 
3288         void
3289         OptionParsingStarting ()
3290         {
3291             m_type = eLookupTypeInvalid;
3292             m_str.clear();
3293             m_addr = LLDB_INVALID_ADDRESS;
3294         }
3295 
3296         const OptionDefinition*
3297         GetDefinitions ()
3298         {
3299             return g_option_table;
3300         }
3301 
3302         // Options table: Required for subclasses of Options.
3303 
3304         static OptionDefinition g_option_table[];
3305 
3306         // Instance variables to hold the values for command options.
3307 
3308         int             m_type;         // Should be a eLookupTypeXXX enum after parsing options
3309         std::string     m_str;          // Holds name lookup
3310         lldb::addr_t    m_addr;         // Holds the address to lookup
3311     };
3312 
3313     CommandObjectTargetModulesShowUnwind (CommandInterpreter &interpreter) :
3314         CommandObjectParsed (interpreter,
3315                              "target modules show-unwind",
3316                              "Show synthesized unwind instructions for a function.",
3317                              NULL),
3318         m_options (interpreter)
3319     {
3320     }
3321 
3322     virtual
3323     ~CommandObjectTargetModulesShowUnwind ()
3324     {
3325     }
3326 
3327     virtual
3328     Options *
3329     GetOptions ()
3330     {
3331         return &m_options;
3332     }
3333 
3334 protected:
3335     bool
3336     DoExecute (Args& command,
3337              CommandReturnObject &result)
3338     {
3339         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3340         if (!target)
3341         {
3342             result.AppendError ("invalid target, create a debug target using the 'target create' command");
3343             result.SetStatus (eReturnStatusFailed);
3344             return false;
3345         }
3346 
3347         ExecutionContext exe_ctx = m_interpreter.GetDebugger().GetSelectedExecutionContext();
3348         Process *process = exe_ctx.GetProcessPtr();
3349         ABI *abi = NULL;
3350         if (process)
3351           abi = process->GetABI().get();
3352 
3353         if (process == NULL)
3354         {
3355             result.AppendError ("You must have a process running to use this command.");
3356             result.SetStatus (eReturnStatusFailed);
3357             return false;
3358         }
3359 
3360         ThreadList threads(process->GetThreadList());
3361         if (threads.GetSize() == 0)
3362         {
3363             result.AppendError ("The process must be paused to use this command.");
3364             result.SetStatus (eReturnStatusFailed);
3365             return false;
3366         }
3367 
3368         ThreadSP thread(threads.GetThreadAtIndex(0));
3369         if (thread.get() == NULL)
3370         {
3371             result.AppendError ("The process must be paused to use this command.");
3372             result.SetStatus (eReturnStatusFailed);
3373             return false;
3374         }
3375 
3376         if (m_options.m_type == eLookupTypeFunctionOrSymbol)
3377         {
3378             SymbolContextList sc_list;
3379             uint32_t num_matches;
3380             ConstString function_name (m_options.m_str.c_str());
3381             num_matches = target->GetImages().FindFunctions (function_name, eFunctionNameTypeAuto, true, false, true, sc_list);
3382             for (uint32_t idx = 0; idx < num_matches; idx++)
3383             {
3384                 SymbolContext sc;
3385                 sc_list.GetContextAtIndex(idx, sc);
3386                 if (sc.symbol == NULL && sc.function == NULL)
3387                     continue;
3388                 if (sc.module_sp.get() == NULL || sc.module_sp->GetObjectFile() == NULL)
3389                     continue;
3390                 AddressRange range;
3391                 if (!sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range))
3392                     continue;
3393                 if (!range.GetBaseAddress().IsValid())
3394                     continue;
3395                 ConstString funcname(sc.GetFunctionName());
3396                 if (funcname.IsEmpty())
3397                     continue;
3398                 addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
3399                 if (abi)
3400                     start_addr = abi->FixCodeAddress(start_addr);
3401 
3402                 FuncUnwindersSP func_unwinders_sp (sc.module_sp->GetObjectFile()->GetUnwindTable().GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
3403                 if (func_unwinders_sp.get() == NULL)
3404                     continue;
3405 
3406                 Address first_non_prologue_insn (func_unwinders_sp->GetFirstNonPrologueInsn(*target));
3407                 if (first_non_prologue_insn.IsValid())
3408                 {
3409                     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);
3410                     result.GetOutputStream().Printf ("\n");
3411                 }
3412 
3413                 UnwindPlanSP non_callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtNonCallSite(*thread.get());
3414                 if (non_callsite_unwind_plan.get())
3415                 {
3416                     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);
3417                     non_callsite_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3418                     result.GetOutputStream().Printf ("\n");
3419                 }
3420 
3421                 UnwindPlanSP callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(-1);
3422                 if (callsite_unwind_plan.get())
3423                 {
3424                     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);
3425                     callsite_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3426                     result.GetOutputStream().Printf ("\n");
3427                 }
3428 
3429                 UnwindPlanSP arch_default_unwind_plan = func_unwinders_sp->GetUnwindPlanArchitectureDefault(*thread.get());
3430                 if (arch_default_unwind_plan.get())
3431                 {
3432                     result.GetOutputStream().Printf("Architecture default UnwindPlan for %s`%s (start addr 0x%llx):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
3433                     arch_default_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3434                     result.GetOutputStream().Printf ("\n");
3435                 }
3436 
3437                 UnwindPlanSP fast_unwind_plan = func_unwinders_sp->GetUnwindPlanFastUnwind(*thread.get());
3438                 if (fast_unwind_plan.get())
3439                 {
3440                     result.GetOutputStream().Printf("Fast UnwindPlan for %s`%s (start addr 0x%llx):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
3441                     fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3442                     result.GetOutputStream().Printf ("\n");
3443                 }
3444 
3445 
3446                 result.GetOutputStream().Printf ("\n");
3447             }
3448         }
3449         return result.Succeeded();
3450     }
3451 
3452     CommandOptions m_options;
3453 };
3454 
3455 OptionDefinition
3456 CommandObjectTargetModulesShowUnwind::CommandOptions::g_option_table[] =
3457 {
3458     { 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."},
3459     { 0,                false, NULL,           0, 0,                 NULL, 0, eArgTypeNone, NULL }
3460 };
3461 
3462 //----------------------------------------------------------------------
3463 // Lookup information in images
3464 //----------------------------------------------------------------------
3465 class CommandObjectTargetModulesLookup : public CommandObjectParsed
3466 {
3467 public:
3468 
3469     enum
3470     {
3471         eLookupTypeInvalid = -1,
3472         eLookupTypeAddress = 0,
3473         eLookupTypeSymbol,
3474         eLookupTypeFileLine,    // Line is optional
3475         eLookupTypeFunction,
3476         eLookupTypeFunctionOrSymbol,
3477         eLookupTypeType,
3478         kNumLookupTypes
3479     };
3480 
3481     class CommandOptions : public Options
3482     {
3483     public:
3484 
3485         CommandOptions (CommandInterpreter &interpreter) :
3486         Options(interpreter)
3487         {
3488             OptionParsingStarting();
3489         }
3490 
3491         virtual
3492         ~CommandOptions ()
3493         {
3494         }
3495 
3496         virtual Error
3497         SetOptionValue (uint32_t option_idx, const char *option_arg)
3498         {
3499             Error error;
3500 
3501             char short_option = (char) m_getopt_table[option_idx].val;
3502 
3503             switch (short_option)
3504             {
3505                 case 'a':
3506                     m_type = eLookupTypeAddress;
3507                     m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
3508                     if (m_addr == LLDB_INVALID_ADDRESS)
3509                         error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg);
3510                     break;
3511 
3512                 case 'o':
3513                     m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
3514                     if (m_offset == LLDB_INVALID_ADDRESS)
3515                         error.SetErrorStringWithFormat ("invalid offset string '%s'", option_arg);
3516                     break;
3517 
3518                 case 's':
3519                     m_str = option_arg;
3520                     m_type = eLookupTypeSymbol;
3521                     break;
3522 
3523                 case 'f':
3524                     m_file.SetFile (option_arg, false);
3525                     m_type = eLookupTypeFileLine;
3526                     break;
3527 
3528                 case 'i':
3529                     m_include_inlines = false;
3530                     break;
3531 
3532                 case 'l':
3533                     m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX);
3534                     if (m_line_number == UINT32_MAX)
3535                         error.SetErrorStringWithFormat ("invalid line number string '%s'", option_arg);
3536                     else if (m_line_number == 0)
3537                         error.SetErrorString ("zero is an invalid line number");
3538                     m_type = eLookupTypeFileLine;
3539                     break;
3540 
3541                 case 'F':
3542                     m_str = option_arg;
3543                     m_type = eLookupTypeFunction;
3544                     break;
3545 
3546                 case 'n':
3547                     m_str = option_arg;
3548                     m_type = eLookupTypeFunctionOrSymbol;
3549                     break;
3550 
3551                 case 't':
3552                     m_str = option_arg;
3553                     m_type = eLookupTypeType;
3554                     break;
3555 
3556                 case 'v':
3557                     m_verbose = 1;
3558                     break;
3559 
3560                 case 'A':
3561                     m_print_all = true;
3562                     break;
3563 
3564                 case 'r':
3565                     m_use_regex = true;
3566                     break;
3567             }
3568 
3569             return error;
3570         }
3571 
3572         void
3573         OptionParsingStarting ()
3574         {
3575             m_type = eLookupTypeInvalid;
3576             m_str.clear();
3577             m_file.Clear();
3578             m_addr = LLDB_INVALID_ADDRESS;
3579             m_offset = 0;
3580             m_line_number = 0;
3581             m_use_regex = false;
3582             m_include_inlines = true;
3583             m_verbose = false;
3584             m_print_all = false;
3585         }
3586 
3587         const OptionDefinition*
3588         GetDefinitions ()
3589         {
3590             return g_option_table;
3591         }
3592 
3593         // Options table: Required for subclasses of Options.
3594 
3595         static OptionDefinition g_option_table[];
3596         int             m_type;         // Should be a eLookupTypeXXX enum after parsing options
3597         std::string     m_str;          // Holds name lookup
3598         FileSpec        m_file;         // Files for file lookups
3599         lldb::addr_t    m_addr;         // Holds the address to lookup
3600         lldb::addr_t    m_offset;       // Subtract this offset from m_addr before doing lookups.
3601         uint32_t        m_line_number;  // Line number for file+line lookups
3602         bool            m_use_regex;    // Name lookups in m_str are regular expressions.
3603         bool            m_include_inlines;// Check for inline entries when looking up by file/line.
3604         bool            m_verbose;      // Enable verbose lookup info
3605         bool            m_print_all;    // Print all matches, even in cases where there's a best match.
3606 
3607     };
3608 
3609     CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) :
3610         CommandObjectParsed (interpreter,
3611                              "target modules lookup",
3612                              "Look up information within executable and dependent shared library images.",
3613                              NULL),
3614         m_options (interpreter)
3615     {
3616         CommandArgumentEntry arg;
3617         CommandArgumentData file_arg;
3618 
3619         // Define the first (and only) variant of this arg.
3620         file_arg.arg_type = eArgTypeFilename;
3621         file_arg.arg_repetition = eArgRepeatStar;
3622 
3623         // There is only one variant this argument could be; put it into the argument entry.
3624         arg.push_back (file_arg);
3625 
3626         // Push the data for the first argument into the m_arguments vector.
3627         m_arguments.push_back (arg);
3628     }
3629 
3630     virtual
3631     ~CommandObjectTargetModulesLookup ()
3632     {
3633     }
3634 
3635     virtual Options *
3636     GetOptions ()
3637     {
3638         return &m_options;
3639     }
3640 
3641     bool
3642     LookupHere (CommandInterpreter &interpreter, CommandReturnObject &result, bool &syntax_error)
3643     {
3644         switch (m_options.m_type)
3645         {
3646             case eLookupTypeAddress:
3647             case eLookupTypeFileLine:
3648             case eLookupTypeFunction:
3649             case eLookupTypeFunctionOrSymbol:
3650             case eLookupTypeSymbol:
3651             default:
3652                 return false;
3653             case eLookupTypeType:
3654                 break;
3655         }
3656 
3657         ExecutionContext exe_ctx = interpreter.GetDebugger().GetSelectedExecutionContext();
3658 
3659         StackFrameSP frame = exe_ctx.GetFrameSP();
3660 
3661         if (!frame)
3662             return false;
3663 
3664         const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
3665 
3666         if (!sym_ctx.module_sp)
3667             return false;
3668 
3669         switch (m_options.m_type)
3670         {
3671         default:
3672             return false;
3673         case eLookupTypeType:
3674             if (!m_options.m_str.empty())
3675             {
3676                 if (LookupTypeHere (m_interpreter,
3677                                     result.GetOutputStream(),
3678                                     sym_ctx,
3679                                     m_options.m_str.c_str(),
3680                                     m_options.m_use_regex))
3681                 {
3682                     result.SetStatus(eReturnStatusSuccessFinishResult);
3683                     return true;
3684                 }
3685             }
3686             break;
3687         }
3688 
3689         return true;
3690     }
3691 
3692     bool
3693     LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
3694     {
3695         switch (m_options.m_type)
3696         {
3697             case eLookupTypeAddress:
3698                 if (m_options.m_addr != LLDB_INVALID_ADDRESS)
3699                 {
3700                     if (LookupAddressInModule (m_interpreter,
3701                                                result.GetOutputStream(),
3702                                                module,
3703                                                eSymbolContextEverything,
3704                                                m_options.m_addr,
3705                                                m_options.m_offset,
3706                                                m_options.m_verbose))
3707                     {
3708                         result.SetStatus(eReturnStatusSuccessFinishResult);
3709                         return true;
3710                     }
3711                 }
3712                 break;
3713 
3714             case eLookupTypeSymbol:
3715                 if (!m_options.m_str.empty())
3716                 {
3717                     if (LookupSymbolInModule (m_interpreter,
3718                                               result.GetOutputStream(),
3719                                               module,
3720                                               m_options.m_str.c_str(),
3721                                               m_options.m_use_regex,
3722                                               m_options.m_verbose))
3723                     {
3724                         result.SetStatus(eReturnStatusSuccessFinishResult);
3725                         return true;
3726                     }
3727                 }
3728                 break;
3729 
3730             case eLookupTypeFileLine:
3731                 if (m_options.m_file)
3732                 {
3733 
3734                     if (LookupFileAndLineInModule (m_interpreter,
3735                                                    result.GetOutputStream(),
3736                                                    module,
3737                                                    m_options.m_file,
3738                                                    m_options.m_line_number,
3739                                                    m_options.m_include_inlines,
3740                                                    m_options.m_verbose))
3741                     {
3742                         result.SetStatus(eReturnStatusSuccessFinishResult);
3743                         return true;
3744                     }
3745                 }
3746                 break;
3747 
3748             case eLookupTypeFunctionOrSymbol:
3749             case eLookupTypeFunction:
3750                 if (!m_options.m_str.empty())
3751                 {
3752                     if (LookupFunctionInModule (m_interpreter,
3753                                                 result.GetOutputStream(),
3754                                                 module,
3755                                                 m_options.m_str.c_str(),
3756                                                 m_options.m_use_regex,
3757                                                 m_options.m_include_inlines,
3758                                                 m_options.m_type == eLookupTypeFunctionOrSymbol, // include symbols
3759                                                 m_options.m_verbose))
3760                     {
3761                         result.SetStatus(eReturnStatusSuccessFinishResult);
3762                         return true;
3763                     }
3764                 }
3765                 break;
3766 
3767 
3768             case eLookupTypeType:
3769                 if (!m_options.m_str.empty())
3770                 {
3771                     if (LookupTypeInModule (m_interpreter,
3772                                             result.GetOutputStream(),
3773                                             module,
3774                                             m_options.m_str.c_str(),
3775                                             m_options.m_use_regex))
3776                     {
3777                         result.SetStatus(eReturnStatusSuccessFinishResult);
3778                         return true;
3779                     }
3780                 }
3781                 break;
3782 
3783             default:
3784                 m_options.GenerateOptionUsage (result.GetErrorStream(), this);
3785                 syntax_error = true;
3786                 break;
3787         }
3788 
3789         result.SetStatus (eReturnStatusFailed);
3790         return false;
3791     }
3792 
3793 protected:
3794     virtual bool
3795     DoExecute (Args& command,
3796              CommandReturnObject &result)
3797     {
3798         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3799         if (target == NULL)
3800         {
3801             result.AppendError ("invalid target, create a debug target using the 'target create' command");
3802             result.SetStatus (eReturnStatusFailed);
3803             return false;
3804         }
3805         else
3806         {
3807             bool syntax_error = false;
3808             uint32_t i;
3809             uint32_t num_successful_lookups = 0;
3810             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3811             result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3812             result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3813             // Dump all sections for all modules images
3814 
3815             if (command.GetArgumentCount() == 0)
3816             {
3817                 ModuleSP current_module;
3818 
3819                 // Where it is possible to look in the current symbol context
3820                 // first, try that.  If this search was successful and --all
3821                 // was not passed, don't print anything else.
3822                 if (LookupHere (m_interpreter, result, syntax_error))
3823                 {
3824                     result.GetOutputStream().EOL();
3825                     num_successful_lookups++;
3826                     if (!m_options.m_print_all)
3827                     {
3828                         result.SetStatus (eReturnStatusSuccessFinishResult);
3829                         return result.Succeeded();
3830                     }
3831                 }
3832 
3833                 // Dump all sections for all other modules
3834 
3835                 ModuleList &target_modules = target->GetImages();
3836                 Mutex::Locker modules_locker(target_modules.GetMutex());
3837                 const uint32_t num_modules = target_modules.GetSize();
3838                 if (num_modules > 0)
3839                 {
3840                     for (i = 0; i<num_modules && syntax_error == false; ++i)
3841                     {
3842                         Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked(i);
3843 
3844                         if (module_pointer != current_module.get() &&
3845                             LookupInModule (m_interpreter, target_modules.GetModulePointerAtIndexUnlocked(i), result, syntax_error))
3846                         {
3847                             result.GetOutputStream().EOL();
3848                             num_successful_lookups++;
3849                         }
3850                     }
3851                 }
3852                 else
3853                 {
3854                     result.AppendError ("the target has no associated executable images");
3855                     result.SetStatus (eReturnStatusFailed);
3856                     return false;
3857                 }
3858             }
3859             else
3860             {
3861                 // Dump specified images (by basename or fullpath)
3862                 const char *arg_cstr;
3863                 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i)
3864                 {
3865                     ModuleList module_list;
3866                     const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, false);
3867                     if (num_matches > 0)
3868                     {
3869                         for (size_t j=0; j<num_matches; ++j)
3870                         {
3871                             Module *module = module_list.GetModulePointerAtIndex(j);
3872                             if (module)
3873                             {
3874                                 if (LookupInModule (m_interpreter, module, result, syntax_error))
3875                                 {
3876                                     result.GetOutputStream().EOL();
3877                                     num_successful_lookups++;
3878                                 }
3879                             }
3880                         }
3881                     }
3882                     else
3883                         result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
3884                 }
3885             }
3886 
3887             if (num_successful_lookups > 0)
3888                 result.SetStatus (eReturnStatusSuccessFinishResult);
3889             else
3890                 result.SetStatus (eReturnStatusFailed);
3891         }
3892         return result.Succeeded();
3893     }
3894 
3895     CommandOptions m_options;
3896 };
3897 
3898 OptionDefinition
3899 CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] =
3900 {
3901     { LLDB_OPT_SET_1,   true,  "address",    'a', required_argument, NULL, 0, eArgTypeAddress,          "Lookup an address in one or more target modules."},
3902     { 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."},
3903     { LLDB_OPT_SET_2| LLDB_OPT_SET_4 | LLDB_OPT_SET_5
3904       /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */ ,
3905                         false, "regex",      'r', no_argument,       NULL, 0, eArgTypeNone,             "The <name> argument for name lookups are regular expressions."},
3906     { 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."},
3907     { 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."},
3908     { 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)."},
3909     { LLDB_OPT_SET_FROM_TO(3,5),
3910                         false, "no-inlines", 'i', no_argument,       NULL, 0, eArgTypeNone,             "Ignore inline entries (must be used in conjunction with --file or --function)."},
3911     { 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."},
3912     { 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."},
3913     { 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."},
3914     { LLDB_OPT_SET_ALL, false, "verbose",    'v', no_argument,       NULL, 0, eArgTypeNone,             "Enable verbose lookup information."},
3915     { 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."},
3916     { 0,                false, NULL,           0, 0,                 NULL, 0, eArgTypeNone,             NULL }
3917 };
3918 
3919 
3920 #pragma mark CommandObjectMultiwordImageSearchPaths
3921 
3922 //-------------------------------------------------------------------------
3923 // CommandObjectMultiwordImageSearchPaths
3924 //-------------------------------------------------------------------------
3925 
3926 class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword
3927 {
3928 public:
3929 
3930     CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) :
3931     CommandObjectMultiword (interpreter,
3932                             "target modules search-paths",
3933                             "A set of commands for operating on debugger target image search paths.",
3934                             "target modules search-paths <subcommand> [<subcommand-options>]")
3935     {
3936         LoadSubCommand ("add",     CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter)));
3937         LoadSubCommand ("clear",   CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter)));
3938         LoadSubCommand ("insert",  CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter)));
3939         LoadSubCommand ("list",    CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter)));
3940         LoadSubCommand ("query",   CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter)));
3941     }
3942 
3943     ~CommandObjectTargetModulesImageSearchPaths()
3944     {
3945     }
3946 };
3947 
3948 
3949 
3950 #pragma mark CommandObjectTargetModules
3951 
3952 //-------------------------------------------------------------------------
3953 // CommandObjectTargetModules
3954 //-------------------------------------------------------------------------
3955 
3956 class CommandObjectTargetModules : public CommandObjectMultiword
3957 {
3958 public:
3959     //------------------------------------------------------------------
3960     // Constructors and Destructors
3961     //------------------------------------------------------------------
3962     CommandObjectTargetModules(CommandInterpreter &interpreter) :
3963         CommandObjectMultiword (interpreter,
3964                                 "target modules",
3965                                 "A set of commands for accessing information for one or more target modules.",
3966                                 "target modules <sub-command> ...")
3967     {
3968         LoadSubCommand ("add",          CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter)));
3969         LoadSubCommand ("load",         CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter)));
3970         //LoadSubCommand ("unload",       CommandObjectSP (new CommandObjectTargetModulesUnload (interpreter)));
3971         LoadSubCommand ("dump",         CommandObjectSP (new CommandObjectTargetModulesDump (interpreter)));
3972         LoadSubCommand ("list",         CommandObjectSP (new CommandObjectTargetModulesList (interpreter)));
3973         LoadSubCommand ("lookup",       CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter)));
3974         LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter)));
3975         LoadSubCommand ("show-unwind",  CommandObjectSP (new CommandObjectTargetModulesShowUnwind (interpreter)));
3976 
3977     }
3978     virtual
3979     ~CommandObjectTargetModules()
3980     {
3981     }
3982 
3983 private:
3984     //------------------------------------------------------------------
3985     // For CommandObjectTargetModules only
3986     //------------------------------------------------------------------
3987     DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules);
3988 };
3989 
3990 
3991 
3992 class CommandObjectTargetSymbolsAdd : public CommandObjectParsed
3993 {
3994 public:
3995     CommandObjectTargetSymbolsAdd (CommandInterpreter &interpreter) :
3996         CommandObjectParsed (interpreter,
3997                              "target symbols add",
3998                              "Add a debug symbol file to one of the target's current modules by specifying a path to a debug symbols file, or using the options to specify a module to download symbols for.",
3999                              "target symbols add [<symfile>]"),
4000         m_option_group (interpreter),
4001         m_file_option (LLDB_OPT_SET_1, false, "shlib", 's', CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Fullpath or basename for module to find debug symbols for."),
4002         m_current_frame_option (LLDB_OPT_SET_2, false, "frame", 'F', "Locate the debug symbols the currently selected frame.", false, true)
4003 
4004     {
4005         m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
4006         m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
4007         m_option_group.Append (&m_current_frame_option, LLDB_OPT_SET_2, LLDB_OPT_SET_2);
4008         m_option_group.Finalize();
4009     }
4010 
4011     virtual
4012     ~CommandObjectTargetSymbolsAdd ()
4013     {
4014     }
4015 
4016     int
4017     HandleArgumentCompletion (Args &input,
4018                               int &cursor_index,
4019                               int &cursor_char_position,
4020                               OptionElementVector &opt_element_vector,
4021                               int match_start_point,
4022                               int max_return_elements,
4023                               bool &word_complete,
4024                               StringList &matches)
4025     {
4026         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
4027         completion_str.erase (cursor_char_position);
4028 
4029         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
4030                                                              CommandCompletions::eDiskFileCompletion,
4031                                                              completion_str.c_str(),
4032                                                              match_start_point,
4033                                                              max_return_elements,
4034                                                              NULL,
4035                                                              word_complete,
4036                                                              matches);
4037         return matches.GetSize();
4038     }
4039 
4040     virtual Options *
4041     GetOptions ()
4042     {
4043         return &m_option_group;
4044     }
4045 
4046 
4047 protected:
4048 
4049     bool
4050     AddModuleSymbols (Target *target,
4051                       const FileSpec &symfile_spec,
4052                       bool &flush,
4053                       CommandReturnObject &result)
4054     {
4055         ModuleSP symfile_module_sp (new Module (symfile_spec, target->GetArchitecture()));
4056         const UUID &symfile_uuid = symfile_module_sp->GetUUID();
4057         StreamString ss_symfile_uuid;
4058         symfile_uuid.Dump(&ss_symfile_uuid);
4059 
4060         if (symfile_module_sp)
4061         {
4062             char symfile_path[PATH_MAX];
4063             symfile_spec.GetPath (symfile_path, sizeof(symfile_path));
4064             // We now have a module that represents a symbol file
4065             // that can be used for a module that might exist in the
4066             // current target, so we need to find that module in the
4067             // target
4068 
4069             ModuleSP old_module_sp (target->GetImages().FindModule (symfile_uuid));
4070             if (old_module_sp)
4071             {
4072                 // The module has not yet created its symbol vendor, we can just
4073                 // give the existing target module the symfile path to use for
4074                 // when it decides to create it!
4075                 old_module_sp->SetSymbolFileFileSpec (symfile_module_sp->GetFileSpec());
4076 
4077                 // Provide feedback that the symfile has been successfully added.
4078                 const FileSpec &module_fs = old_module_sp->GetFileSpec();
4079                 result.AppendMessageWithFormat("symbol file '%s' with UUID %s has been successfully added to the '%s/%s' module\n",
4080                                                symfile_path, ss_symfile_uuid.GetData(),
4081                                                module_fs.GetDirectory().AsCString(), module_fs.GetFilename().AsCString());
4082 
4083                 // Let clients know something changed in the module
4084                 // if it is currently loaded
4085                 ModuleList module_list;
4086                 module_list.Append (old_module_sp);
4087                 target->ModulesDidLoad (module_list);
4088                 flush = true;
4089             }
4090             else
4091             {
4092                 result.AppendErrorWithFormat ("symbol file '%s' with UUID %s does not match any existing module%s\n",
4093                                               symfile_path, ss_symfile_uuid.GetData(),
4094                                               (symfile_spec.GetFileType() != FileSpec::eFileTypeRegular)
4095                                               ? "\n       please specify the full path to the symbol file"
4096                                               : "");
4097                 return false;
4098             }
4099         }
4100         else
4101         {
4102             result.AppendError ("one or more executable image paths must be specified");
4103             result.SetStatus (eReturnStatusFailed);
4104             return false;
4105         }
4106         result.SetStatus (eReturnStatusSuccessFinishResult);
4107         return true;
4108     }
4109 
4110     virtual bool
4111     DoExecute (Args& args,
4112              CommandReturnObject &result)
4113     {
4114         ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
4115         Target *target = exe_ctx.GetTargetPtr();
4116         result.SetStatus (eReturnStatusFailed);
4117         if (target == NULL)
4118         {
4119             result.AppendError ("invalid target, create a debug target using the 'target create' command");
4120         }
4121         else
4122         {
4123             bool flush = false;
4124             ModuleSpec sym_spec;
4125             const bool uuid_option_set = m_uuid_option_group.GetOptionValue().OptionWasSet();
4126             const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4127             const bool frame_option_set = m_current_frame_option.GetOptionValue().OptionWasSet();
4128 
4129             const size_t argc = args.GetArgumentCount();
4130             if (argc == 0)
4131             {
4132                 if (uuid_option_set || file_option_set || frame_option_set)
4133                 {
4134                     bool success = false;
4135                     bool error_set = false;
4136                     if (frame_option_set)
4137                     {
4138                         Process *process = exe_ctx.GetProcessPtr();
4139                         if (process)
4140                         {
4141                             const StateType process_state = process->GetState();
4142                             if (StateIsStoppedState (process_state, true))
4143                             {
4144                                 StackFrame *frame = exe_ctx.GetFramePtr();
4145                                 if (frame)
4146                                 {
4147                                     ModuleSP frame_module_sp (frame->GetSymbolContext(eSymbolContextModule).module_sp);
4148                                     if (frame_module_sp)
4149                                     {
4150                                         if (frame_module_sp->GetPlatformFileSpec().Exists())
4151                                         {
4152                                             sym_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
4153                                             sym_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
4154                                         }
4155                                         sym_spec.GetUUID() = frame_module_sp->GetUUID();
4156                                         success = sym_spec.GetUUID().IsValid() || sym_spec.GetFileSpec();
4157                                     }
4158                                     else
4159                                     {
4160                                         result.AppendError ("frame has no module");
4161                                         error_set = true;
4162                                     }
4163                                 }
4164                                 else
4165                                 {
4166                                     result.AppendError ("invalid current frame");
4167                                     error_set = true;
4168                                 }
4169                             }
4170                             else
4171                             {
4172                                 result.AppendErrorWithFormat ("process is not stopped: %s", StateAsCString(process_state));
4173                                 error_set = true;
4174                             }
4175                         }
4176                         else
4177                         {
4178                             result.AppendError ("a process must exist in order to use the --frame option");
4179                             error_set = true;
4180                         }
4181                     }
4182                     else
4183                     {
4184                         if (uuid_option_set)
4185                         {
4186                             sym_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue();
4187                             success |= sym_spec.GetUUID().IsValid();
4188                         }
4189                         else if (file_option_set)
4190                         {
4191                             sym_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue();
4192                             ModuleSP module_sp (target->GetImages().FindFirstModule(sym_spec));
4193                             if (module_sp)
4194                             {
4195                                 sym_spec.GetFileSpec() = module_sp->GetFileSpec();
4196                                 sym_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();
4197                                 sym_spec.GetUUID() = module_sp->GetUUID();
4198                                 sym_spec.GetArchitecture() = module_sp->GetArchitecture();
4199                             }
4200                             else
4201                             {
4202                                 sym_spec.GetArchitecture() = target->GetArchitecture();
4203                             }
4204                             success |= sym_spec.GetFileSpec().Exists();
4205                         }
4206                     }
4207 
4208                     if (success)
4209                     {
4210                         if (Symbols::DownloadObjectAndSymbolFile (sym_spec))
4211                         {
4212                             if (sym_spec.GetSymbolFileSpec())
4213                                 success = AddModuleSymbols (target, sym_spec.GetSymbolFileSpec(), flush, result);
4214                         }
4215                     }
4216 
4217                     if (!success && !error_set)
4218                     {
4219                         StreamString error_strm;
4220                         if (uuid_option_set)
4221                         {
4222                             error_strm.PutCString("unable to find debug symbols for UUID ");
4223                             sym_spec.GetUUID().Dump (&error_strm);
4224                         }
4225                         else if (file_option_set)
4226                         {
4227                             error_strm.PutCString("unable to find debug symbols for the executable file ");
4228                             error_strm << sym_spec.GetFileSpec();
4229                         }
4230                         else if (frame_option_set)
4231                         {
4232                             error_strm.PutCString("unable to find debug symbols for the current frame");
4233                         }
4234                         result.AppendError (error_strm.GetData());
4235                     }
4236                 }
4237                 else
4238                 {
4239                     result.AppendError ("one or more symbol file paths must be specified, or options must be specified");
4240                 }
4241             }
4242             else
4243             {
4244                 if (uuid_option_set)
4245                 {
4246                     result.AppendError ("specify either one or more paths to symbol files or use the --uuid option without arguments");
4247                 }
4248                 else if (file_option_set)
4249                 {
4250                     result.AppendError ("specify either one or more paths to symbol files or use the --file option without arguments");
4251                 }
4252                 else if (frame_option_set)
4253                 {
4254                     result.AppendError ("specify either one or more paths to symbol files or use the --frame option without arguments");
4255                 }
4256                 else
4257                 {
4258                     PlatformSP platform_sp (target->GetPlatform());
4259 
4260                     for (size_t i=0; i<argc; ++i)
4261                     {
4262                         const char *symfile_path = args.GetArgumentAtIndex(i);
4263                         if (symfile_path)
4264                         {
4265                             FileSpec symfile_spec;
4266                             sym_spec.GetSymbolFileSpec().SetFile(symfile_path, true);
4267                             if (platform_sp)
4268                                 platform_sp->ResolveSymbolFile(*target, sym_spec, symfile_spec);
4269                             else
4270                                 symfile_spec.SetFile(symfile_path, true);
4271 
4272                             ArchSpec arch;
4273                             bool symfile_exists = symfile_spec.Exists();
4274 
4275                             if (symfile_exists)
4276                             {
4277                                 if (!AddModuleSymbols (target, symfile_spec, flush, result))
4278                                     break;
4279                             }
4280                             else
4281                             {
4282                                 char resolved_symfile_path[PATH_MAX];
4283                                 if (symfile_spec.GetPath (resolved_symfile_path, sizeof(resolved_symfile_path)))
4284                                 {
4285                                     if (strcmp (resolved_symfile_path, symfile_path) != 0)
4286                                     {
4287                                         result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", symfile_path, resolved_symfile_path);
4288                                         break;
4289                                     }
4290                                 }
4291                                 result.AppendErrorWithFormat ("invalid module path '%s'\n", symfile_path);
4292                                 break;
4293                             }
4294                         }
4295                     }
4296                 }
4297             }
4298 
4299             if (flush)
4300             {
4301                 Process *process = exe_ctx.GetProcessPtr();
4302                 if (process)
4303                     process->Flush();
4304             }
4305         }
4306         return result.Succeeded();
4307     }
4308 
4309     OptionGroupOptions m_option_group;
4310     OptionGroupUUID m_uuid_option_group;
4311     OptionGroupFile m_file_option;
4312     OptionGroupBoolean m_current_frame_option;
4313 
4314 
4315 };
4316 
4317 
4318 #pragma mark CommandObjectTargetSymbols
4319 
4320 //-------------------------------------------------------------------------
4321 // CommandObjectTargetSymbols
4322 //-------------------------------------------------------------------------
4323 
4324 class CommandObjectTargetSymbols : public CommandObjectMultiword
4325 {
4326 public:
4327     //------------------------------------------------------------------
4328     // Constructors and Destructors
4329     //------------------------------------------------------------------
4330     CommandObjectTargetSymbols(CommandInterpreter &interpreter) :
4331         CommandObjectMultiword (interpreter,
4332                             "target symbols",
4333                             "A set of commands for adding and managing debug symbol files.",
4334                             "target symbols <sub-command> ...")
4335     {
4336         LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetSymbolsAdd (interpreter)));
4337 
4338     }
4339     virtual
4340     ~CommandObjectTargetSymbols()
4341     {
4342     }
4343 
4344 private:
4345     //------------------------------------------------------------------
4346     // For CommandObjectTargetModules only
4347     //------------------------------------------------------------------
4348     DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetSymbols);
4349 };
4350 
4351 
4352 #pragma mark CommandObjectTargetStopHookAdd
4353 
4354 //-------------------------------------------------------------------------
4355 // CommandObjectTargetStopHookAdd
4356 //-------------------------------------------------------------------------
4357 
4358 class CommandObjectTargetStopHookAdd : public CommandObjectParsed
4359 {
4360 public:
4361 
4362     class CommandOptions : public Options
4363     {
4364     public:
4365         CommandOptions (CommandInterpreter &interpreter) :
4366             Options(interpreter),
4367             m_line_start(0),
4368             m_line_end (UINT_MAX),
4369             m_func_name_type_mask (eFunctionNameTypeAuto),
4370             m_sym_ctx_specified (false),
4371             m_thread_specified (false),
4372             m_use_one_liner (false),
4373             m_one_liner()
4374         {
4375         }
4376 
4377         ~CommandOptions () {}
4378 
4379         const OptionDefinition*
4380         GetDefinitions ()
4381         {
4382             return g_option_table;
4383         }
4384 
4385         virtual Error
4386         SetOptionValue (uint32_t option_idx, const char *option_arg)
4387         {
4388             Error error;
4389             char short_option = (char) m_getopt_table[option_idx].val;
4390             bool success;
4391 
4392             switch (short_option)
4393             {
4394                 case 'c':
4395                     m_class_name = option_arg;
4396                     m_sym_ctx_specified = true;
4397                 break;
4398 
4399                 case 'e':
4400                     m_line_end = Args::StringToUInt32 (option_arg, UINT_MAX, 0, &success);
4401                     if (!success)
4402                     {
4403                         error.SetErrorStringWithFormat ("invalid end line number: \"%s\"", option_arg);
4404                         break;
4405                     }
4406                     m_sym_ctx_specified = true;
4407                 break;
4408 
4409                 case 'l':
4410                     m_line_start = Args::StringToUInt32 (option_arg, 0, 0, &success);
4411                     if (!success)
4412                     {
4413                         error.SetErrorStringWithFormat ("invalid start line number: \"%s\"", option_arg);
4414                         break;
4415                     }
4416                     m_sym_ctx_specified = true;
4417                 break;
4418 
4419                 case 'i':
4420                     m_no_inlines = true;
4421                 break;
4422 
4423                 case 'n':
4424                     m_function_name = option_arg;
4425                     m_func_name_type_mask |= eFunctionNameTypeAuto;
4426                     m_sym_ctx_specified = true;
4427                 break;
4428 
4429                 case 'f':
4430                     m_file_name = option_arg;
4431                     m_sym_ctx_specified = true;
4432                 break;
4433                 case 's':
4434                     m_module_name = option_arg;
4435                     m_sym_ctx_specified = true;
4436                 break;
4437                 case 't' :
4438                 {
4439                     m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
4440                     if (m_thread_id == LLDB_INVALID_THREAD_ID)
4441                        error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
4442                     m_thread_specified = true;
4443                 }
4444                 break;
4445                 case 'T':
4446                     m_thread_name = option_arg;
4447                     m_thread_specified = true;
4448                 break;
4449                 case 'q':
4450                     m_queue_name = option_arg;
4451                     m_thread_specified = true;
4452                     break;
4453                 case 'x':
4454                 {
4455                     m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
4456                     if (m_thread_id == UINT32_MAX)
4457                        error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
4458                     m_thread_specified = true;
4459                 }
4460                 break;
4461                 case 'o':
4462                     m_use_one_liner = true;
4463                     m_one_liner = option_arg;
4464                 break;
4465                 default:
4466                     error.SetErrorStringWithFormat ("unrecognized option %c.", short_option);
4467                 break;
4468             }
4469             return error;
4470         }
4471 
4472         void
4473         OptionParsingStarting ()
4474         {
4475             m_class_name.clear();
4476             m_function_name.clear();
4477             m_line_start = 0;
4478             m_line_end = UINT_MAX;
4479             m_file_name.clear();
4480             m_module_name.clear();
4481             m_func_name_type_mask = eFunctionNameTypeAuto;
4482             m_thread_id = LLDB_INVALID_THREAD_ID;
4483             m_thread_index = UINT32_MAX;
4484             m_thread_name.clear();
4485             m_queue_name.clear();
4486 
4487             m_no_inlines = false;
4488             m_sym_ctx_specified = false;
4489             m_thread_specified = false;
4490 
4491             m_use_one_liner = false;
4492             m_one_liner.clear();
4493         }
4494 
4495 
4496         static OptionDefinition g_option_table[];
4497 
4498         std::string m_class_name;
4499         std::string m_function_name;
4500         uint32_t    m_line_start;
4501         uint32_t    m_line_end;
4502         std::string m_file_name;
4503         std::string m_module_name;
4504         uint32_t m_func_name_type_mask;  // A pick from lldb::FunctionNameType.
4505         lldb::tid_t m_thread_id;
4506         uint32_t m_thread_index;
4507         std::string m_thread_name;
4508         std::string m_queue_name;
4509         bool        m_sym_ctx_specified;
4510         bool        m_no_inlines;
4511         bool        m_thread_specified;
4512         // Instance variables to hold the values for one_liner options.
4513         bool m_use_one_liner;
4514         std::string m_one_liner;
4515     };
4516 
4517     Options *
4518     GetOptions ()
4519     {
4520         return &m_options;
4521     }
4522 
4523     CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) :
4524         CommandObjectParsed (interpreter,
4525                              "target stop-hook add ",
4526                              "Add a hook to be executed when the target stops.",
4527                              "target stop-hook add"),
4528         m_options (interpreter)
4529     {
4530     }
4531 
4532     ~CommandObjectTargetStopHookAdd ()
4533     {
4534     }
4535 
4536     static size_t
4537     ReadCommandsCallbackFunction (void *baton,
4538                                   InputReader &reader,
4539                                   lldb::InputReaderAction notification,
4540                                   const char *bytes,
4541                                   size_t bytes_len)
4542     {
4543         StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
4544         Target::StopHook *new_stop_hook = ((Target::StopHook *) baton);
4545         static bool got_interrupted;
4546         bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
4547 
4548         switch (notification)
4549         {
4550         case eInputReaderActivate:
4551             if (!batch_mode)
4552             {
4553                 out_stream->Printf ("%s\n", "Enter your stop hook command(s).  Type 'DONE' to end.");
4554                 if (reader.GetPrompt())
4555                     out_stream->Printf ("%s", reader.GetPrompt());
4556                 out_stream->Flush();
4557             }
4558             got_interrupted = false;
4559             break;
4560 
4561         case eInputReaderDeactivate:
4562             break;
4563 
4564         case eInputReaderReactivate:
4565             if (reader.GetPrompt() && !batch_mode)
4566             {
4567                 out_stream->Printf ("%s", reader.GetPrompt());
4568                 out_stream->Flush();
4569             }
4570             got_interrupted = false;
4571             break;
4572 
4573         case eInputReaderAsynchronousOutputWritten:
4574             break;
4575 
4576         case eInputReaderGotToken:
4577             if (bytes && bytes_len && baton)
4578             {
4579                 StringList *commands = new_stop_hook->GetCommandPointer();
4580                 if (commands)
4581                 {
4582                     commands->AppendString (bytes, bytes_len);
4583                 }
4584             }
4585             if (!reader.IsDone() && reader.GetPrompt() && !batch_mode)
4586             {
4587                 out_stream->Printf ("%s", reader.GetPrompt());
4588                 out_stream->Flush();
4589             }
4590             break;
4591 
4592         case eInputReaderInterrupt:
4593             {
4594                 // Finish, and cancel the stop hook.
4595                 new_stop_hook->GetTarget()->RemoveStopHookByID(new_stop_hook->GetID());
4596                 if (!batch_mode)
4597                 {
4598                     out_stream->Printf ("Stop hook cancelled.\n");
4599                     out_stream->Flush();
4600                 }
4601 
4602                 reader.SetIsDone (true);
4603             }
4604             got_interrupted = true;
4605             break;
4606 
4607         case eInputReaderEndOfFile:
4608             reader.SetIsDone (true);
4609             break;
4610 
4611         case eInputReaderDone:
4612             if (!got_interrupted && !batch_mode)
4613             {
4614                 out_stream->Printf ("Stop hook #%llu added.\n", new_stop_hook->GetID());
4615                 out_stream->Flush();
4616             }
4617             break;
4618         }
4619 
4620         return bytes_len;
4621     }
4622 
4623 protected:
4624     bool
4625     DoExecute (Args& command, CommandReturnObject &result)
4626     {
4627         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
4628         if (target)
4629         {
4630             Target::StopHookSP new_hook_sp;
4631             target->AddStopHook (new_hook_sp);
4632 
4633             //  First step, make the specifier.
4634             std::auto_ptr<SymbolContextSpecifier> specifier_ap;
4635             if (m_options.m_sym_ctx_specified)
4636             {
4637                 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget()));
4638 
4639                 if (!m_options.m_module_name.empty())
4640                 {
4641                     specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified);
4642                 }
4643 
4644                 if (!m_options.m_class_name.empty())
4645                 {
4646                     specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified);
4647                 }
4648 
4649                 if (!m_options.m_file_name.empty())
4650                 {
4651                     specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified);
4652                 }
4653 
4654                 if (m_options.m_line_start != 0)
4655                 {
4656                     specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified);
4657                 }
4658 
4659                 if (m_options.m_line_end != UINT_MAX)
4660                 {
4661                     specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
4662                 }
4663 
4664                 if (!m_options.m_function_name.empty())
4665                 {
4666                     specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified);
4667                 }
4668             }
4669 
4670             if (specifier_ap.get())
4671                 new_hook_sp->SetSpecifier (specifier_ap.release());
4672 
4673             // Next see if any of the thread options have been entered:
4674 
4675             if (m_options.m_thread_specified)
4676             {
4677                 ThreadSpec *thread_spec = new ThreadSpec();
4678 
4679                 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
4680                 {
4681                     thread_spec->SetTID (m_options.m_thread_id);
4682                 }
4683 
4684                 if (m_options.m_thread_index != UINT32_MAX)
4685                     thread_spec->SetIndex (m_options.m_thread_index);
4686 
4687                 if (!m_options.m_thread_name.empty())
4688                     thread_spec->SetName (m_options.m_thread_name.c_str());
4689 
4690                 if (!m_options.m_queue_name.empty())
4691                     thread_spec->SetQueueName (m_options.m_queue_name.c_str());
4692 
4693                 new_hook_sp->SetThreadSpecifier (thread_spec);
4694 
4695             }
4696             if (m_options.m_use_one_liner)
4697             {
4698                 // Use one-liner.
4699                 new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str());
4700                 result.AppendMessageWithFormat("Stop hook #%llu added.\n", new_hook_sp->GetID());
4701             }
4702             else
4703             {
4704                 // Otherwise gather up the command list, we'll push an input reader and suck the data from that directly into
4705                 // the new stop hook's command string.
4706                 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
4707                 if (!reader_sp)
4708                 {
4709                     result.AppendError("out of memory\n");
4710                     result.SetStatus (eReturnStatusFailed);
4711                     target->RemoveStopHookByID (new_hook_sp->GetID());
4712                     return false;
4713                 }
4714 
4715                 Error err (reader_sp->Initialize (CommandObjectTargetStopHookAdd::ReadCommandsCallbackFunction,
4716                                                   new_hook_sp.get(), // baton
4717                                                   eInputReaderGranularityLine,  // token size, to pass to callback function
4718                                                   "DONE",                       // end token
4719                                                   "> ",                         // prompt
4720                                                   true));                       // echo input
4721                 if (!err.Success())
4722                 {
4723                     result.AppendError (err.AsCString());
4724                     result.SetStatus (eReturnStatusFailed);
4725                     target->RemoveStopHookByID (new_hook_sp->GetID());
4726                     return false;
4727                 }
4728                 m_interpreter.GetDebugger().PushInputReader (reader_sp);
4729             }
4730             result.SetStatus (eReturnStatusSuccessFinishNoResult);
4731         }
4732         else
4733         {
4734             result.AppendError ("invalid target\n");
4735             result.SetStatus (eReturnStatusFailed);
4736         }
4737 
4738         return result.Succeeded();
4739     }
4740 private:
4741     CommandOptions m_options;
4742 };
4743 
4744 OptionDefinition
4745 CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] =
4746 {
4747     { LLDB_OPT_SET_ALL, false, "one-liner", 'o', required_argument, NULL, 0, eArgTypeOneLiner,
4748         "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
4749     { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
4750         "Set the module within which the stop-hook is to be run."},
4751     { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, 0, eArgTypeThreadIndex,
4752         "The stop hook is run only for the thread whose index matches this argument."},
4753     { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, 0, eArgTypeThreadID,
4754         "The stop hook is run only for the thread whose TID matches this argument."},
4755     { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, 0, eArgTypeThreadName,
4756         "The stop hook is run only for the thread whose thread name matches this argument."},
4757     { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, 0, eArgTypeQueueName,
4758         "The stop hook is run only for threads in the queue whose name is given by this argument."},
4759     { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
4760         "Specify the source file within which the stop-hook is to be run." },
4761     { LLDB_OPT_SET_1, false, "start-line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
4762         "Set the start of the line range for which the stop-hook is to be run."},
4763     { LLDB_OPT_SET_1, false, "end-line", 'e', required_argument, NULL, 0, eArgTypeLineNum,
4764         "Set the end of the line range for which the stop-hook is to be run."},
4765     { LLDB_OPT_SET_2, false, "classname", 'c', required_argument, NULL, 0, eArgTypeClassName,
4766         "Specify the class within which the stop-hook is to be run." },
4767     { LLDB_OPT_SET_3, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
4768         "Set the function name within which the stop hook will be run." },
4769     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
4770 };
4771 
4772 #pragma mark CommandObjectTargetStopHookDelete
4773 
4774 //-------------------------------------------------------------------------
4775 // CommandObjectTargetStopHookDelete
4776 //-------------------------------------------------------------------------
4777 
4778 class CommandObjectTargetStopHookDelete : public CommandObjectParsed
4779 {
4780 public:
4781 
4782     CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) :
4783         CommandObjectParsed (interpreter,
4784                              "target stop-hook delete",
4785                              "Delete a stop-hook.",
4786                              "target stop-hook delete [<idx>]")
4787     {
4788     }
4789 
4790     ~CommandObjectTargetStopHookDelete ()
4791     {
4792     }
4793 
4794 protected:
4795     bool
4796     DoExecute (Args& command, CommandReturnObject &result)
4797     {
4798         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
4799         if (target)
4800         {
4801             // FIXME: see if we can use the breakpoint id style parser?
4802             size_t num_args = command.GetArgumentCount();
4803             if (num_args == 0)
4804             {
4805                 if (!m_interpreter.Confirm ("Delete all stop hooks?", true))
4806                 {
4807                     result.SetStatus (eReturnStatusFailed);
4808                     return false;
4809                 }
4810                 else
4811                 {
4812                     target->RemoveAllStopHooks();
4813                 }
4814             }
4815             else
4816             {
4817                 bool success;
4818                 for (size_t i = 0; i < num_args; i++)
4819                 {
4820                     lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
4821                     if (!success)
4822                     {
4823                         result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
4824                         result.SetStatus(eReturnStatusFailed);
4825                         return false;
4826                     }
4827                     success = target->RemoveStopHookByID (user_id);
4828                     if (!success)
4829                     {
4830                         result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
4831                         result.SetStatus(eReturnStatusFailed);
4832                         return false;
4833                     }
4834                 }
4835             }
4836             result.SetStatus (eReturnStatusSuccessFinishNoResult);
4837         }
4838         else
4839         {
4840             result.AppendError ("invalid target\n");
4841             result.SetStatus (eReturnStatusFailed);
4842         }
4843 
4844         return result.Succeeded();
4845     }
4846 };
4847 #pragma mark CommandObjectTargetStopHookEnableDisable
4848 
4849 //-------------------------------------------------------------------------
4850 // CommandObjectTargetStopHookEnableDisable
4851 //-------------------------------------------------------------------------
4852 
4853 class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed
4854 {
4855 public:
4856 
4857     CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) :
4858         CommandObjectParsed (interpreter,
4859                              name,
4860                              help,
4861                              syntax),
4862         m_enable (enable)
4863     {
4864     }
4865 
4866     ~CommandObjectTargetStopHookEnableDisable ()
4867     {
4868     }
4869 
4870 protected:
4871     bool
4872     DoExecute (Args& command, CommandReturnObject &result)
4873     {
4874         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
4875         if (target)
4876         {
4877             // FIXME: see if we can use the breakpoint id style parser?
4878             size_t num_args = command.GetArgumentCount();
4879             bool success;
4880 
4881             if (num_args == 0)
4882             {
4883                 target->SetAllStopHooksActiveState (m_enable);
4884             }
4885             else
4886             {
4887                 for (size_t i = 0; i < num_args; i++)
4888                 {
4889                     lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
4890                     if (!success)
4891                     {
4892                         result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
4893                         result.SetStatus(eReturnStatusFailed);
4894                         return false;
4895                     }
4896                     success = target->SetStopHookActiveStateByID (user_id, m_enable);
4897                     if (!success)
4898                     {
4899                         result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
4900                         result.SetStatus(eReturnStatusFailed);
4901                         return false;
4902                     }
4903                 }
4904             }
4905             result.SetStatus (eReturnStatusSuccessFinishNoResult);
4906         }
4907         else
4908         {
4909             result.AppendError ("invalid target\n");
4910             result.SetStatus (eReturnStatusFailed);
4911         }
4912         return result.Succeeded();
4913     }
4914 private:
4915     bool m_enable;
4916 };
4917 
4918 #pragma mark CommandObjectTargetStopHookList
4919 
4920 //-------------------------------------------------------------------------
4921 // CommandObjectTargetStopHookList
4922 //-------------------------------------------------------------------------
4923 
4924 class CommandObjectTargetStopHookList : public CommandObjectParsed
4925 {
4926 public:
4927 
4928     CommandObjectTargetStopHookList (CommandInterpreter &interpreter) :
4929         CommandObjectParsed (interpreter,
4930                              "target stop-hook list",
4931                              "List all stop-hooks.",
4932                              "target stop-hook list [<type>]")
4933     {
4934     }
4935 
4936     ~CommandObjectTargetStopHookList ()
4937     {
4938     }
4939 
4940 protected:
4941     bool
4942     DoExecute (Args& command, CommandReturnObject &result)
4943     {
4944         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
4945         if (!target)
4946         {
4947             result.AppendError ("invalid target\n");
4948             result.SetStatus (eReturnStatusFailed);
4949             return result.Succeeded();
4950         }
4951 
4952         size_t num_hooks = target->GetNumStopHooks ();
4953         if (num_hooks == 0)
4954         {
4955             result.GetOutputStream().PutCString ("No stop hooks.\n");
4956         }
4957         else
4958         {
4959             for (size_t i = 0; i < num_hooks; i++)
4960             {
4961                 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i);
4962                 if (i > 0)
4963                     result.GetOutputStream().PutCString ("\n");
4964                 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull);
4965             }
4966         }
4967         result.SetStatus (eReturnStatusSuccessFinishResult);
4968         return result.Succeeded();
4969     }
4970 };
4971 
4972 #pragma mark CommandObjectMultiwordTargetStopHooks
4973 //-------------------------------------------------------------------------
4974 // CommandObjectMultiwordTargetStopHooks
4975 //-------------------------------------------------------------------------
4976 
4977 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword
4978 {
4979 public:
4980 
4981     CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) :
4982         CommandObjectMultiword (interpreter,
4983                                 "target stop-hook",
4984                                 "A set of commands for operating on debugger target stop-hooks.",
4985                                 "target stop-hook <subcommand> [<subcommand-options>]")
4986     {
4987         LoadSubCommand ("add",      CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter)));
4988         LoadSubCommand ("delete",   CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter)));
4989         LoadSubCommand ("disable",  CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
4990                                                                                                    false,
4991                                                                                                    "target stop-hook disable [<id>]",
4992                                                                                                    "Disable a stop-hook.",
4993                                                                                                    "target stop-hook disable")));
4994         LoadSubCommand ("enable",   CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
4995                                                                                                    true,
4996                                                                                                    "target stop-hook enable [<id>]",
4997                                                                                                    "Enable a stop-hook.",
4998                                                                                                    "target stop-hook enable")));
4999         LoadSubCommand ("list",     CommandObjectSP (new CommandObjectTargetStopHookList (interpreter)));
5000     }
5001 
5002     ~CommandObjectMultiwordTargetStopHooks()
5003     {
5004     }
5005 };
5006 
5007 
5008 
5009 #pragma mark CommandObjectMultiwordTarget
5010 
5011 //-------------------------------------------------------------------------
5012 // CommandObjectMultiwordTarget
5013 //-------------------------------------------------------------------------
5014 
5015 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) :
5016     CommandObjectMultiword (interpreter,
5017                             "target",
5018                             "A set of commands for operating on debugger targets.",
5019                             "target <subcommand> [<subcommand-options>]")
5020 {
5021 
5022     LoadSubCommand ("create",    CommandObjectSP (new CommandObjectTargetCreate (interpreter)));
5023     LoadSubCommand ("delete",    CommandObjectSP (new CommandObjectTargetDelete (interpreter)));
5024     LoadSubCommand ("list",      CommandObjectSP (new CommandObjectTargetList   (interpreter)));
5025     LoadSubCommand ("select",    CommandObjectSP (new CommandObjectTargetSelect (interpreter)));
5026     LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter)));
5027     LoadSubCommand ("modules",   CommandObjectSP (new CommandObjectTargetModules (interpreter)));
5028     LoadSubCommand ("symbols",   CommandObjectSP (new CommandObjectTargetSymbols (interpreter)));
5029     LoadSubCommand ("variable",  CommandObjectSP (new CommandObjectTargetVariable (interpreter)));
5030 }
5031 
5032 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget ()
5033 {
5034 }
5035 
5036 
5037