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