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