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