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