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