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