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