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