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