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