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