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