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             result.GetOutputStream().Printf("UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
3748 
3749             UnwindPlanSP non_callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread.get(), -1);
3750             if (non_callsite_unwind_plan.get())
3751             {
3752                 result.GetOutputStream().Printf("Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n", non_callsite_unwind_plan->GetSourceName().AsCString());
3753             }
3754             UnwindPlanSP callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(*target, -1);
3755             if (callsite_unwind_plan.get())
3756             {
3757                 result.GetOutputStream().Printf("Synchronous (restricted to call-sites) UnwindPlan is '%s'\n", callsite_unwind_plan->GetSourceName().AsCString());
3758             }
3759             UnwindPlanSP fast_unwind_plan = func_unwinders_sp->GetUnwindPlanFastUnwind(*thread.get());
3760             if (fast_unwind_plan.get())
3761             {
3762                 result.GetOutputStream().Printf("Fast UnwindPlan is '%s'\n", fast_unwind_plan->GetSourceName().AsCString());
3763             }
3764 
3765             result.GetOutputStream().Printf("\n");
3766 
3767             UnwindPlanSP assembly_sp = func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread.get(), 0);
3768             if (assembly_sp)
3769             {
3770                 result.GetOutputStream().Printf("Assembly language inspection UnwindPlan:\n");
3771                 assembly_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3772                 result.GetOutputStream().Printf("\n");
3773             }
3774 
3775 
3776             UnwindPlanSP ehframe_sp = func_unwinders_sp->GetEHFrameUnwindPlan(*target, 0);
3777             if (ehframe_sp)
3778             {
3779                 result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3780                 ehframe_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3781                 result.GetOutputStream().Printf("\n");
3782             }
3783 
3784             UnwindPlanSP ehframe_augmented_sp = func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread.get(), 0);
3785             if (ehframe_augmented_sp)
3786             {
3787                 result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3788                 ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3789                 result.GetOutputStream().Printf("\n");
3790             }
3791 
3792             UnwindPlanSP compact_unwind_sp = func_unwinders_sp->GetCompactUnwindUnwindPlan(*target, 0);
3793             if (compact_unwind_sp)
3794             {
3795                 result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3796                 compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3797                 result.GetOutputStream().Printf("\n");
3798             }
3799 
3800             if (fast_unwind_plan)
3801             {
3802                 result.GetOutputStream().Printf("Fast UnwindPlan:\n");
3803                 fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3804                 result.GetOutputStream().Printf("\n");
3805             }
3806 
3807             ABISP abi_sp = process->GetABI();
3808             if (abi_sp)
3809             {
3810                 UnwindPlan arch_default(lldb::eRegisterKindGeneric);
3811                 if (abi_sp->CreateDefaultUnwindPlan (arch_default))
3812                 {
3813                     result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3814                     arch_default.Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3815                     result.GetOutputStream().Printf("\n");
3816                 }
3817 
3818                 UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
3819                 if (abi_sp->CreateFunctionEntryUnwindPlan (arch_entry))
3820                 {
3821                     result.GetOutputStream().Printf("Arch default at entry point UnwindPlan:\n");
3822                     arch_entry.Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3823                     result.GetOutputStream().Printf("\n");
3824                 }
3825             }
3826 
3827             result.GetOutputStream().Printf ("\n");
3828         }
3829         return result.Succeeded();
3830     }
3831 
3832     CommandOptions m_options;
3833 };
3834 
3835 OptionDefinition
3836 CommandObjectTargetModulesShowUnwind::CommandOptions::g_option_table[] =
3837 {
3838     { LLDB_OPT_SET_1,   false,  "name",       'n', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name."},
3839     { LLDB_OPT_SET_2,   false,  "address",    'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address"},
3840     { 0,                false, NULL,           0, 0,                 NULL, NULL, 0, eArgTypeNone, NULL }
3841 };
3842 
3843 //----------------------------------------------------------------------
3844 // Lookup information in images
3845 //----------------------------------------------------------------------
3846 class CommandObjectTargetModulesLookup : public CommandObjectParsed
3847 {
3848 public:
3849     enum
3850     {
3851         eLookupTypeInvalid = -1,
3852         eLookupTypeAddress = 0,
3853         eLookupTypeSymbol,
3854         eLookupTypeFileLine,    // Line is optional
3855         eLookupTypeFunction,
3856         eLookupTypeFunctionOrSymbol,
3857         eLookupTypeType,
3858         kNumLookupTypes
3859     };
3860 
3861     class CommandOptions : public Options
3862     {
3863     public:
3864         CommandOptions (CommandInterpreter &interpreter) :
3865         Options(interpreter)
3866         {
3867             OptionParsingStarting();
3868         }
3869 
3870         virtual
3871         ~CommandOptions ()
3872         {
3873         }
3874 
3875         virtual Error
3876         SetOptionValue (uint32_t option_idx, const char *option_arg)
3877         {
3878             Error error;
3879 
3880             const int short_option = m_getopt_table[option_idx].val;
3881 
3882             switch (short_option)
3883             {
3884                 case 'a':
3885                     {
3886                         m_type = eLookupTypeAddress;
3887                         ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
3888                         m_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
3889                     }
3890                     break;
3891 
3892                 case 'o':
3893                     m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
3894                     if (m_offset == LLDB_INVALID_ADDRESS)
3895                         error.SetErrorStringWithFormat ("invalid offset string '%s'", option_arg);
3896                     break;
3897 
3898                 case 's':
3899                     m_str = option_arg;
3900                     m_type = eLookupTypeSymbol;
3901                     break;
3902 
3903                 case 'f':
3904                     m_file.SetFile (option_arg, false);
3905                     m_type = eLookupTypeFileLine;
3906                     break;
3907 
3908                 case 'i':
3909                     m_include_inlines = false;
3910                     break;
3911 
3912                 case 'l':
3913                     m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX);
3914                     if (m_line_number == UINT32_MAX)
3915                         error.SetErrorStringWithFormat ("invalid line number string '%s'", option_arg);
3916                     else if (m_line_number == 0)
3917                         error.SetErrorString ("zero is an invalid line number");
3918                     m_type = eLookupTypeFileLine;
3919                     break;
3920 
3921                 case 'F':
3922                     m_str = option_arg;
3923                     m_type = eLookupTypeFunction;
3924                     break;
3925 
3926                 case 'n':
3927                     m_str = option_arg;
3928                     m_type = eLookupTypeFunctionOrSymbol;
3929                     break;
3930 
3931                 case 't':
3932                     m_str = option_arg;
3933                     m_type = eLookupTypeType;
3934                     break;
3935 
3936                 case 'v':
3937                     m_verbose = 1;
3938                     break;
3939 
3940                 case 'A':
3941                     m_print_all = true;
3942                     break;
3943 
3944                 case 'r':
3945                     m_use_regex = true;
3946                     break;
3947             }
3948 
3949             return error;
3950         }
3951 
3952         void
3953         OptionParsingStarting ()
3954         {
3955             m_type = eLookupTypeInvalid;
3956             m_str.clear();
3957             m_file.Clear();
3958             m_addr = LLDB_INVALID_ADDRESS;
3959             m_offset = 0;
3960             m_line_number = 0;
3961             m_use_regex = false;
3962             m_include_inlines = true;
3963             m_verbose = false;
3964             m_print_all = false;
3965         }
3966 
3967         const OptionDefinition*
3968         GetDefinitions ()
3969         {
3970             return g_option_table;
3971         }
3972 
3973         // Options table: Required for subclasses of Options.
3974 
3975         static OptionDefinition g_option_table[];
3976         int             m_type;         // Should be a eLookupTypeXXX enum after parsing options
3977         std::string     m_str;          // Holds name lookup
3978         FileSpec        m_file;         // Files for file lookups
3979         lldb::addr_t    m_addr;         // Holds the address to lookup
3980         lldb::addr_t    m_offset;       // Subtract this offset from m_addr before doing lookups.
3981         uint32_t        m_line_number;  // Line number for file+line lookups
3982         bool            m_use_regex;    // Name lookups in m_str are regular expressions.
3983         bool            m_include_inlines;// Check for inline entries when looking up by file/line.
3984         bool            m_verbose;      // Enable verbose lookup info
3985         bool            m_print_all;    // Print all matches, even in cases where there's a best match.
3986     };
3987 
3988     CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) :
3989         CommandObjectParsed (interpreter,
3990                              "target modules lookup",
3991                              "Look up information within executable and dependent shared library images.",
3992                              NULL,
3993                              eFlagRequiresTarget),
3994         m_options (interpreter)
3995     {
3996         CommandArgumentEntry arg;
3997         CommandArgumentData file_arg;
3998 
3999         // Define the first (and only) variant of this arg.
4000         file_arg.arg_type = eArgTypeFilename;
4001         file_arg.arg_repetition = eArgRepeatStar;
4002 
4003         // There is only one variant this argument could be; put it into the argument entry.
4004         arg.push_back (file_arg);
4005 
4006         // Push the data for the first argument into the m_arguments vector.
4007         m_arguments.push_back (arg);
4008     }
4009 
4010     virtual
4011     ~CommandObjectTargetModulesLookup ()
4012     {
4013     }
4014 
4015     virtual Options *
4016     GetOptions ()
4017     {
4018         return &m_options;
4019     }
4020 
4021     bool
4022     LookupHere (CommandInterpreter &interpreter, CommandReturnObject &result, bool &syntax_error)
4023     {
4024         switch (m_options.m_type)
4025         {
4026             case eLookupTypeAddress:
4027             case eLookupTypeFileLine:
4028             case eLookupTypeFunction:
4029             case eLookupTypeFunctionOrSymbol:
4030             case eLookupTypeSymbol:
4031             default:
4032                 return false;
4033             case eLookupTypeType:
4034                 break;
4035         }
4036 
4037         StackFrameSP frame = m_exe_ctx.GetFrameSP();
4038 
4039         if (!frame)
4040             return false;
4041 
4042         const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
4043 
4044         if (!sym_ctx.module_sp)
4045             return false;
4046 
4047         switch (m_options.m_type)
4048         {
4049         default:
4050             return false;
4051         case eLookupTypeType:
4052             if (!m_options.m_str.empty())
4053             {
4054                 if (LookupTypeHere (m_interpreter,
4055                                     result.GetOutputStream(),
4056                                     sym_ctx,
4057                                     m_options.m_str.c_str(),
4058                                     m_options.m_use_regex))
4059                 {
4060                     result.SetStatus(eReturnStatusSuccessFinishResult);
4061                     return true;
4062                 }
4063             }
4064             break;
4065         }
4066 
4067         return true;
4068     }
4069 
4070     bool
4071     LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
4072     {
4073         switch (m_options.m_type)
4074         {
4075             case eLookupTypeAddress:
4076                 if (m_options.m_addr != LLDB_INVALID_ADDRESS)
4077                 {
4078                     if (LookupAddressInModule (m_interpreter,
4079                                                result.GetOutputStream(),
4080                                                module,
4081                                                eSymbolContextEverything,
4082                                                m_options.m_addr,
4083                                                m_options.m_offset,
4084                                                m_options.m_verbose))
4085                     {
4086                         result.SetStatus(eReturnStatusSuccessFinishResult);
4087                         return true;
4088                     }
4089                 }
4090                 break;
4091 
4092             case eLookupTypeSymbol:
4093                 if (!m_options.m_str.empty())
4094                 {
4095                     if (LookupSymbolInModule (m_interpreter,
4096                                               result.GetOutputStream(),
4097                                               module,
4098                                               m_options.m_str.c_str(),
4099                                               m_options.m_use_regex,
4100                                               m_options.m_verbose))
4101                     {
4102                         result.SetStatus(eReturnStatusSuccessFinishResult);
4103                         return true;
4104                     }
4105                 }
4106                 break;
4107 
4108             case eLookupTypeFileLine:
4109                 if (m_options.m_file)
4110                 {
4111                     if (LookupFileAndLineInModule (m_interpreter,
4112                                                    result.GetOutputStream(),
4113                                                    module,
4114                                                    m_options.m_file,
4115                                                    m_options.m_line_number,
4116                                                    m_options.m_include_inlines,
4117                                                    m_options.m_verbose))
4118                     {
4119                         result.SetStatus(eReturnStatusSuccessFinishResult);
4120                         return true;
4121                     }
4122                 }
4123                 break;
4124 
4125             case eLookupTypeFunctionOrSymbol:
4126             case eLookupTypeFunction:
4127                 if (!m_options.m_str.empty())
4128                 {
4129                     if (LookupFunctionInModule (m_interpreter,
4130                                                 result.GetOutputStream(),
4131                                                 module,
4132                                                 m_options.m_str.c_str(),
4133                                                 m_options.m_use_regex,
4134                                                 m_options.m_include_inlines,
4135                                                 m_options.m_type == eLookupTypeFunctionOrSymbol, // include symbols
4136                                                 m_options.m_verbose))
4137                     {
4138                         result.SetStatus(eReturnStatusSuccessFinishResult);
4139                         return true;
4140                     }
4141                 }
4142                 break;
4143 
4144             case eLookupTypeType:
4145                 if (!m_options.m_str.empty())
4146                 {
4147                     if (LookupTypeInModule (m_interpreter,
4148                                             result.GetOutputStream(),
4149                                             module,
4150                                             m_options.m_str.c_str(),
4151                                             m_options.m_use_regex))
4152                     {
4153                         result.SetStatus(eReturnStatusSuccessFinishResult);
4154                         return true;
4155                     }
4156                 }
4157                 break;
4158 
4159             default:
4160                 m_options.GenerateOptionUsage (result.GetErrorStream(), this);
4161                 syntax_error = true;
4162                 break;
4163         }
4164 
4165         result.SetStatus (eReturnStatusFailed);
4166         return false;
4167     }
4168 
4169 protected:
4170     virtual bool
4171     DoExecute (Args& command,
4172              CommandReturnObject &result)
4173     {
4174         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
4175         if (target == NULL)
4176         {
4177             result.AppendError ("invalid target, create a debug target using the 'target create' command");
4178             result.SetStatus (eReturnStatusFailed);
4179             return false;
4180         }
4181         else
4182         {
4183             bool syntax_error = false;
4184             uint32_t i;
4185             uint32_t num_successful_lookups = 0;
4186             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
4187             result.GetOutputStream().SetAddressByteSize(addr_byte_size);
4188             result.GetErrorStream().SetAddressByteSize(addr_byte_size);
4189             // Dump all sections for all modules images
4190 
4191             if (command.GetArgumentCount() == 0)
4192             {
4193                 ModuleSP current_module;
4194 
4195                 // Where it is possible to look in the current symbol context
4196                 // first, try that.  If this search was successful and --all
4197                 // was not passed, don't print anything else.
4198                 if (LookupHere (m_interpreter, result, syntax_error))
4199                 {
4200                     result.GetOutputStream().EOL();
4201                     num_successful_lookups++;
4202                     if (!m_options.m_print_all)
4203                     {
4204                         result.SetStatus (eReturnStatusSuccessFinishResult);
4205                         return result.Succeeded();
4206                     }
4207                 }
4208 
4209                 // Dump all sections for all other modules
4210 
4211                 const ModuleList &target_modules = target->GetImages();
4212                 Mutex::Locker modules_locker(target_modules.GetMutex());
4213                 const size_t num_modules = target_modules.GetSize();
4214                 if (num_modules > 0)
4215                 {
4216                     for (i = 0; i<num_modules && syntax_error == false; ++i)
4217                     {
4218                         Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked(i);
4219 
4220                         if (module_pointer != current_module.get() &&
4221                             LookupInModule (m_interpreter, target_modules.GetModulePointerAtIndexUnlocked(i), result, syntax_error))
4222                         {
4223                             result.GetOutputStream().EOL();
4224                             num_successful_lookups++;
4225                         }
4226                     }
4227                 }
4228                 else
4229                 {
4230                     result.AppendError ("the target has no associated executable images");
4231                     result.SetStatus (eReturnStatusFailed);
4232                     return false;
4233                 }
4234             }
4235             else
4236             {
4237                 // Dump specified images (by basename or fullpath)
4238                 const char *arg_cstr;
4239                 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i)
4240                 {
4241                     ModuleList module_list;
4242                     const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, false);
4243                     if (num_matches > 0)
4244                     {
4245                         for (size_t j=0; j<num_matches; ++j)
4246                         {
4247                             Module *module = module_list.GetModulePointerAtIndex(j);
4248                             if (module)
4249                             {
4250                                 if (LookupInModule (m_interpreter, module, result, syntax_error))
4251                                 {
4252                                     result.GetOutputStream().EOL();
4253                                     num_successful_lookups++;
4254                                 }
4255                             }
4256                         }
4257                     }
4258                     else
4259                         result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
4260                 }
4261             }
4262 
4263             if (num_successful_lookups > 0)
4264                 result.SetStatus (eReturnStatusSuccessFinishResult);
4265             else
4266                 result.SetStatus (eReturnStatusFailed);
4267         }
4268         return result.Succeeded();
4269     }
4270 
4271     CommandOptions m_options;
4272 };
4273 
4274 OptionDefinition
4275 CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] =
4276 {
4277     { LLDB_OPT_SET_1,   true,  "address",    'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules."},
4278     { 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."},
4279     { LLDB_OPT_SET_2| LLDB_OPT_SET_4 | LLDB_OPT_SET_5
4280       /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */ ,
4281                         false, "regex",      'r', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone,             "The <name> argument for name lookups are regular expressions."},
4282     { 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."},
4283     { 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."},
4284     { 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)."},
4285     { LLDB_OPT_SET_FROM_TO(3,5),
4286                         false, "no-inlines", 'i', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone,             "Ignore inline entries (must be used in conjunction with --file or --function)."},
4287     { 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."},
4288     { 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."},
4289     { 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."},
4290     { LLDB_OPT_SET_ALL, false, "verbose",    'v', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone,             "Enable verbose lookup information."},
4291     { 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."},
4292     { 0,                false, NULL,           0, 0,                 NULL, NULL, 0, eArgTypeNone,             NULL }
4293 };
4294 
4295 
4296 #pragma mark CommandObjectMultiwordImageSearchPaths
4297 
4298 //-------------------------------------------------------------------------
4299 // CommandObjectMultiwordImageSearchPaths
4300 //-------------------------------------------------------------------------
4301 
4302 class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword
4303 {
4304 public:
4305     CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) :
4306     CommandObjectMultiword (interpreter,
4307                             "target modules search-paths",
4308                             "A set of commands for operating on debugger target image search paths.",
4309                             "target modules search-paths <subcommand> [<subcommand-options>]")
4310     {
4311         LoadSubCommand ("add",     CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter)));
4312         LoadSubCommand ("clear",   CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter)));
4313         LoadSubCommand ("insert",  CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter)));
4314         LoadSubCommand ("list",    CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter)));
4315         LoadSubCommand ("query",   CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter)));
4316     }
4317 
4318     ~CommandObjectTargetModulesImageSearchPaths()
4319     {
4320     }
4321 };
4322 
4323 
4324 
4325 #pragma mark CommandObjectTargetModules
4326 
4327 //-------------------------------------------------------------------------
4328 // CommandObjectTargetModules
4329 //-------------------------------------------------------------------------
4330 
4331 class CommandObjectTargetModules : public CommandObjectMultiword
4332 {
4333 public:
4334     //------------------------------------------------------------------
4335     // Constructors and Destructors
4336     //------------------------------------------------------------------
4337     CommandObjectTargetModules(CommandInterpreter &interpreter) :
4338         CommandObjectMultiword (interpreter,
4339                                 "target modules",
4340                                 "A set of commands for accessing information for one or more target modules.",
4341                                 "target modules <sub-command> ...")
4342     {
4343         LoadSubCommand ("add",          CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter)));
4344         LoadSubCommand ("load",         CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter)));
4345         LoadSubCommand ("dump",         CommandObjectSP (new CommandObjectTargetModulesDump (interpreter)));
4346         LoadSubCommand ("list",         CommandObjectSP (new CommandObjectTargetModulesList (interpreter)));
4347         LoadSubCommand ("lookup",       CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter)));
4348         LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter)));
4349         LoadSubCommand ("show-unwind",  CommandObjectSP (new CommandObjectTargetModulesShowUnwind (interpreter)));
4350 
4351     }
4352     virtual
4353     ~CommandObjectTargetModules()
4354     {
4355     }
4356 
4357 private:
4358     //------------------------------------------------------------------
4359     // For CommandObjectTargetModules only
4360     //------------------------------------------------------------------
4361     DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules);
4362 };
4363 
4364 
4365 
4366 class CommandObjectTargetSymbolsAdd : public CommandObjectParsed
4367 {
4368 public:
4369     CommandObjectTargetSymbolsAdd (CommandInterpreter &interpreter) :
4370         CommandObjectParsed (interpreter,
4371                              "target symbols add",
4372                              "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.",
4373                              "target symbols add [<symfile>]", eFlagRequiresTarget),
4374         m_option_group (interpreter),
4375         m_file_option (LLDB_OPT_SET_1, false, "shlib", 's', CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Fullpath or basename for module to find debug symbols for."),
4376         m_current_frame_option (LLDB_OPT_SET_2, false, "frame", 'F', "Locate the debug symbols the currently selected frame.", false, true)
4377 
4378     {
4379         m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
4380         m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
4381         m_option_group.Append (&m_current_frame_option, LLDB_OPT_SET_2, LLDB_OPT_SET_2);
4382         m_option_group.Finalize();
4383     }
4384 
4385     virtual
4386     ~CommandObjectTargetSymbolsAdd ()
4387     {
4388     }
4389 
4390     virtual int
4391     HandleArgumentCompletion (Args &input,
4392                               int &cursor_index,
4393                               int &cursor_char_position,
4394                               OptionElementVector &opt_element_vector,
4395                               int match_start_point,
4396                               int max_return_elements,
4397                               bool &word_complete,
4398                               StringList &matches)
4399     {
4400         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
4401         completion_str.erase (cursor_char_position);
4402 
4403         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
4404                                                              CommandCompletions::eDiskFileCompletion,
4405                                                              completion_str.c_str(),
4406                                                              match_start_point,
4407                                                              max_return_elements,
4408                                                              NULL,
4409                                                              word_complete,
4410                                                              matches);
4411         return matches.GetSize();
4412     }
4413 
4414     virtual Options *
4415     GetOptions ()
4416     {
4417         return &m_option_group;
4418     }
4419 
4420 protected:
4421     bool
4422     AddModuleSymbols (Target *target,
4423                       ModuleSpec &module_spec,
4424                       bool &flush,
4425                       CommandReturnObject &result)
4426     {
4427         const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
4428         if (symbol_fspec)
4429         {
4430             char symfile_path[PATH_MAX];
4431             symbol_fspec.GetPath (symfile_path, sizeof(symfile_path));
4432 
4433             if (!module_spec.GetUUID().IsValid())
4434             {
4435                 if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
4436                     module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
4437             }
4438             // We now have a module that represents a symbol file
4439             // that can be used for a module that might exist in the
4440             // current target, so we need to find that module in the
4441             // target
4442             ModuleList matching_module_list;
4443 
4444             size_t num_matches = 0;
4445             // First extract all module specs from the symbol file
4446             lldb_private::ModuleSpecList symfile_module_specs;
4447             if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(), 0, 0, symfile_module_specs))
4448             {
4449                 // Now extract the module spec that matches the target architecture
4450                 ModuleSpec target_arch_module_spec;
4451                 ModuleSpec symfile_module_spec;
4452                 target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
4453                 if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec, symfile_module_spec))
4454                 {
4455                     // See if it has a UUID?
4456                     if (symfile_module_spec.GetUUID().IsValid())
4457                     {
4458                         // It has a UUID, look for this UUID in the target modules
4459                         ModuleSpec symfile_uuid_module_spec;
4460                         symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4461                         num_matches = target->GetImages().FindModules (symfile_uuid_module_spec, matching_module_list);
4462                     }
4463                 }
4464 
4465                 if (num_matches == 0)
4466                 {
4467                     // No matches yet, iterate through the module specs to find a UUID value that
4468                     // we can match up to an image in our target
4469                     const size_t num_symfile_module_specs = symfile_module_specs.GetSize();
4470                     for (size_t i=0; i<num_symfile_module_specs && num_matches == 0; ++i)
4471                     {
4472                         if (symfile_module_specs.GetModuleSpecAtIndex(i, symfile_module_spec))
4473                         {
4474                             if (symfile_module_spec.GetUUID().IsValid())
4475                             {
4476                                 // It has a UUID, look for this UUID in the target modules
4477                                 ModuleSpec symfile_uuid_module_spec;
4478                                 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4479                                 num_matches = target->GetImages().FindModules (symfile_uuid_module_spec, matching_module_list);
4480                             }
4481                         }
4482                     }
4483                 }
4484             }
4485 
4486             // Just try to match up the file by basename if we have no matches at this point
4487             if (num_matches == 0)
4488                 num_matches = target->GetImages().FindModules (module_spec, matching_module_list);
4489 
4490             while (num_matches == 0)
4491             {
4492                 ConstString filename_no_extension(module_spec.GetFileSpec().GetFileNameStrippingExtension());
4493                 // Empty string returned, lets bail
4494                 if (!filename_no_extension)
4495                     break;
4496 
4497                 // Check if there was no extension to strip and the basename is the same
4498                 if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
4499                     break;
4500 
4501                 // Replace basename with one less extension
4502                 module_spec.GetFileSpec().GetFilename() = filename_no_extension;
4503 
4504                 num_matches = target->GetImages().FindModules (module_spec, matching_module_list);
4505             }
4506 
4507             if (num_matches > 1)
4508             {
4509                 result.AppendErrorWithFormat ("multiple modules match symbol file '%s', use the --uuid option to resolve the ambiguity.\n", symfile_path);
4510             }
4511             else if (num_matches == 1)
4512             {
4513                 ModuleSP module_sp (matching_module_list.GetModuleAtIndex(0));
4514 
4515                 // The module has not yet created its symbol vendor, we can just
4516                 // give the existing target module the symfile path to use for
4517                 // when it decides to create it!
4518                 module_sp->SetSymbolFileFileSpec (symbol_fspec);
4519 
4520                 SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(true, &result.GetErrorStream());
4521                 if (symbol_vendor)
4522                 {
4523                     SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
4524 
4525                     if (symbol_file)
4526                     {
4527                         ObjectFile *object_file = symbol_file->GetObjectFile();
4528 
4529                         if (object_file && object_file->GetFileSpec() == symbol_fspec)
4530                         {
4531                             // Provide feedback that the symfile has been successfully added.
4532                             const FileSpec &module_fs = module_sp->GetFileSpec();
4533                             result.AppendMessageWithFormat("symbol file '%s' has been added to '%s'\n",
4534                                                            symfile_path,
4535                                                            module_fs.GetPath().c_str());
4536 
4537                             // Let clients know something changed in the module
4538                             // if it is currently loaded
4539                             ModuleList module_list;
4540                             module_list.Append (module_sp);
4541                             target->SymbolsDidLoad (module_list);
4542 
4543                             // Make sure we load any scripting resources that may be embedded
4544                             // in the debug info files in case the platform supports that.
4545                             Error error;
4546                             StreamString feedback_stream;
4547                             module_sp->LoadScriptingResourceInTarget (target, error,&feedback_stream);
4548                             if (error.Fail() && error.AsCString())
4549                                 result.AppendWarningWithFormat("unable to load scripting data for module %s - error reported was %s",
4550                                                                module_sp->GetFileSpec().GetFileNameStrippingExtension().GetCString(),
4551                                                                error.AsCString());
4552                             else if (feedback_stream.GetSize())
4553                                 result.AppendWarningWithFormat("%s",feedback_stream.GetData());
4554 
4555                             flush = true;
4556                             result.SetStatus (eReturnStatusSuccessFinishResult);
4557                             return true;
4558                         }
4559                     }
4560                 }
4561                 // Clear the symbol file spec if anything went wrong
4562                 module_sp->SetSymbolFileFileSpec (FileSpec());
4563             }
4564 
4565             if (module_spec.GetUUID().IsValid())
4566             {
4567                 StreamString ss_symfile_uuid;
4568                 module_spec.GetUUID().Dump(&ss_symfile_uuid);
4569                 result.AppendErrorWithFormat ("symbol file '%s' (%s) does not match any existing module%s\n",
4570                                               symfile_path,
4571                                               ss_symfile_uuid.GetData(),
4572                                               (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
4573                                                 ? "\n       please specify the full path to the symbol file"
4574                                                 : "");
4575             }
4576             else
4577             {
4578                 result.AppendErrorWithFormat ("symbol file '%s' does not match any existing module%s\n",
4579                                               symfile_path,
4580                                               (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
4581                                                 ? "\n       please specify the full path to the symbol file"
4582                                                 : "");
4583             }
4584         }
4585         else
4586         {
4587             result.AppendError ("one or more executable image paths must be specified");
4588         }
4589         result.SetStatus (eReturnStatusFailed);
4590         return false;
4591     }
4592 
4593     virtual bool
4594     DoExecute (Args& args,
4595              CommandReturnObject &result)
4596     {
4597         Target *target = m_exe_ctx.GetTargetPtr();
4598         result.SetStatus (eReturnStatusFailed);
4599         bool flush = false;
4600         ModuleSpec module_spec;
4601         const bool uuid_option_set = m_uuid_option_group.GetOptionValue().OptionWasSet();
4602         const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4603         const bool frame_option_set = m_current_frame_option.GetOptionValue().OptionWasSet();
4604 
4605         const size_t argc = args.GetArgumentCount();
4606         if (argc == 0)
4607         {
4608             if (uuid_option_set || file_option_set || frame_option_set)
4609             {
4610                 bool success = false;
4611                 bool error_set = false;
4612                 if (frame_option_set)
4613                 {
4614                     Process *process = m_exe_ctx.GetProcessPtr();
4615                     if (process)
4616                     {
4617                         const StateType process_state = process->GetState();
4618                         if (StateIsStoppedState (process_state, true))
4619                         {
4620                             StackFrame *frame = m_exe_ctx.GetFramePtr();
4621                             if (frame)
4622                             {
4623                                 ModuleSP frame_module_sp (frame->GetSymbolContext(eSymbolContextModule).module_sp);
4624                                 if (frame_module_sp)
4625                                 {
4626                                     if (frame_module_sp->GetPlatformFileSpec().Exists())
4627                                     {
4628                                         module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
4629                                         module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
4630                                     }
4631                                     module_spec.GetUUID() = frame_module_sp->GetUUID();
4632                                     success = module_spec.GetUUID().IsValid() || module_spec.GetFileSpec();
4633                                 }
4634                                 else
4635                                 {
4636                                     result.AppendError ("frame has no module");
4637                                     error_set = true;
4638                                 }
4639                             }
4640                             else
4641                             {
4642                                 result.AppendError ("invalid current frame");
4643                                 error_set = true;
4644                             }
4645                         }
4646                         else
4647                         {
4648                             result.AppendErrorWithFormat ("process is not stopped: %s", StateAsCString(process_state));
4649                             error_set = true;
4650                         }
4651                     }
4652                     else
4653                     {
4654                         result.AppendError ("a process must exist in order to use the --frame option");
4655                         error_set = true;
4656                     }
4657                 }
4658                 else
4659                 {
4660                     if (uuid_option_set)
4661                     {
4662                         module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue();
4663                         success |= module_spec.GetUUID().IsValid();
4664                     }
4665                     else if (file_option_set)
4666                     {
4667                         module_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue();
4668                         ModuleSP module_sp (target->GetImages().FindFirstModule(module_spec));
4669                         if (module_sp)
4670                         {
4671                             module_spec.GetFileSpec() = module_sp->GetFileSpec();
4672                             module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();
4673                             module_spec.GetUUID() = module_sp->GetUUID();
4674                             module_spec.GetArchitecture() = module_sp->GetArchitecture();
4675                         }
4676                         else
4677                         {
4678                             module_spec.GetArchitecture() = target->GetArchitecture();
4679                         }
4680                         success |= module_spec.GetFileSpec().Exists();
4681                     }
4682                 }
4683 
4684                 if (success)
4685                 {
4686                     if (Symbols::DownloadObjectAndSymbolFile (module_spec))
4687                     {
4688                         if (module_spec.GetSymbolFileSpec())
4689                             success = AddModuleSymbols (target, module_spec, flush, result);
4690                     }
4691                 }
4692 
4693                 if (!success && !error_set)
4694                 {
4695                     StreamString error_strm;
4696                     if (uuid_option_set)
4697                     {
4698                         error_strm.PutCString("unable to find debug symbols for UUID ");
4699                         module_spec.GetUUID().Dump (&error_strm);
4700                     }
4701                     else if (file_option_set)
4702                     {
4703                         error_strm.PutCString("unable to find debug symbols for the executable file ");
4704                         error_strm << module_spec.GetFileSpec();
4705                     }
4706                     else if (frame_option_set)
4707                     {
4708                         error_strm.PutCString("unable to find debug symbols for the current frame");
4709                     }
4710                     result.AppendError (error_strm.GetData());
4711                 }
4712             }
4713             else
4714             {
4715                 result.AppendError ("one or more symbol file paths must be specified, or options must be specified");
4716             }
4717         }
4718         else
4719         {
4720             if (uuid_option_set)
4721             {
4722                 result.AppendError ("specify either one or more paths to symbol files or use the --uuid option without arguments");
4723             }
4724             else if (file_option_set)
4725             {
4726                 result.AppendError ("specify either one or more paths to symbol files or use the --file option without arguments");
4727             }
4728             else if (frame_option_set)
4729             {
4730                 result.AppendError ("specify either one or more paths to symbol files or use the --frame option without arguments");
4731             }
4732             else
4733             {
4734                 PlatformSP platform_sp (target->GetPlatform());
4735 
4736                 for (size_t i=0; i<argc; ++i)
4737                 {
4738                     const char *symfile_path = args.GetArgumentAtIndex(i);
4739                     if (symfile_path)
4740                     {
4741                         module_spec.GetSymbolFileSpec().SetFile(symfile_path, true);
4742                         if (platform_sp)
4743                         {
4744                             FileSpec symfile_spec;
4745                             if (platform_sp->ResolveSymbolFile(*target, module_spec, symfile_spec).Success())
4746                                 module_spec.GetSymbolFileSpec() = symfile_spec;
4747                         }
4748 
4749                         ArchSpec arch;
4750                         bool symfile_exists = module_spec.GetSymbolFileSpec().Exists();
4751 
4752                         if (symfile_exists)
4753                         {
4754                             if (!AddModuleSymbols (target, module_spec, flush, result))
4755                                 break;
4756                         }
4757                         else
4758                         {
4759                             char resolved_symfile_path[PATH_MAX];
4760                             if (module_spec.GetSymbolFileSpec().GetPath (resolved_symfile_path, sizeof(resolved_symfile_path)))
4761                             {
4762                                 if (strcmp (resolved_symfile_path, symfile_path) != 0)
4763                                 {
4764                                     result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", symfile_path, resolved_symfile_path);
4765                                     break;
4766                                 }
4767                             }
4768                             result.AppendErrorWithFormat ("invalid module path '%s'\n", symfile_path);
4769                             break;
4770                         }
4771                     }
4772                 }
4773             }
4774         }
4775 
4776         if (flush)
4777         {
4778             Process *process = m_exe_ctx.GetProcessPtr();
4779             if (process)
4780                 process->Flush();
4781         }
4782         return result.Succeeded();
4783     }
4784 
4785     OptionGroupOptions m_option_group;
4786     OptionGroupUUID m_uuid_option_group;
4787     OptionGroupFile m_file_option;
4788     OptionGroupBoolean m_current_frame_option;
4789 };
4790 
4791 
4792 #pragma mark CommandObjectTargetSymbols
4793 
4794 //-------------------------------------------------------------------------
4795 // CommandObjectTargetSymbols
4796 //-------------------------------------------------------------------------
4797 
4798 class CommandObjectTargetSymbols : public CommandObjectMultiword
4799 {
4800 public:
4801     //------------------------------------------------------------------
4802     // Constructors and Destructors
4803     //------------------------------------------------------------------
4804     CommandObjectTargetSymbols(CommandInterpreter &interpreter) :
4805         CommandObjectMultiword (interpreter,
4806                             "target symbols",
4807                             "A set of commands for adding and managing debug symbol files.",
4808                             "target symbols <sub-command> ...")
4809     {
4810         LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetSymbolsAdd (interpreter)));
4811 
4812     }
4813     virtual
4814     ~CommandObjectTargetSymbols()
4815     {
4816     }
4817 
4818 private:
4819     //------------------------------------------------------------------
4820     // For CommandObjectTargetModules only
4821     //------------------------------------------------------------------
4822     DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetSymbols);
4823 };
4824 
4825 
4826 #pragma mark CommandObjectTargetStopHookAdd
4827 
4828 //-------------------------------------------------------------------------
4829 // CommandObjectTargetStopHookAdd
4830 //-------------------------------------------------------------------------
4831 
4832 class CommandObjectTargetStopHookAdd :
4833     public CommandObjectParsed,
4834     public IOHandlerDelegateMultiline
4835 {
4836 public:
4837 
4838     class CommandOptions : public Options
4839     {
4840     public:
4841         CommandOptions (CommandInterpreter &interpreter) :
4842             Options(interpreter),
4843             m_line_start(0),
4844             m_line_end (UINT_MAX),
4845             m_func_name_type_mask (eFunctionNameTypeAuto),
4846             m_sym_ctx_specified (false),
4847             m_thread_specified (false),
4848             m_use_one_liner (false),
4849             m_one_liner()
4850         {
4851         }
4852 
4853         ~CommandOptions () {}
4854 
4855         const OptionDefinition*
4856         GetDefinitions ()
4857         {
4858             return g_option_table;
4859         }
4860 
4861         virtual Error
4862         SetOptionValue (uint32_t option_idx, const char *option_arg)
4863         {
4864             Error error;
4865             const int short_option = m_getopt_table[option_idx].val;
4866             bool success;
4867 
4868             switch (short_option)
4869             {
4870                 case 'c':
4871                     m_class_name = option_arg;
4872                     m_sym_ctx_specified = true;
4873                 break;
4874 
4875                 case 'e':
4876                     m_line_end = Args::StringToUInt32 (option_arg, UINT_MAX, 0, &success);
4877                     if (!success)
4878                     {
4879                         error.SetErrorStringWithFormat ("invalid end line number: \"%s\"", option_arg);
4880                         break;
4881                     }
4882                     m_sym_ctx_specified = true;
4883                 break;
4884 
4885                 case 'l':
4886                     m_line_start = Args::StringToUInt32 (option_arg, 0, 0, &success);
4887                     if (!success)
4888                     {
4889                         error.SetErrorStringWithFormat ("invalid start line number: \"%s\"", option_arg);
4890                         break;
4891                     }
4892                     m_sym_ctx_specified = true;
4893                 break;
4894 
4895                 case 'i':
4896                     m_no_inlines = true;
4897                 break;
4898 
4899                 case 'n':
4900                     m_function_name = option_arg;
4901                     m_func_name_type_mask |= eFunctionNameTypeAuto;
4902                     m_sym_ctx_specified = true;
4903                 break;
4904 
4905                 case 'f':
4906                     m_file_name = option_arg;
4907                     m_sym_ctx_specified = true;
4908                 break;
4909                 case 's':
4910                     m_module_name = option_arg;
4911                     m_sym_ctx_specified = true;
4912                 break;
4913                 case 't' :
4914                 {
4915                     m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
4916                     if (m_thread_id == LLDB_INVALID_THREAD_ID)
4917                        error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
4918                     m_thread_specified = true;
4919                 }
4920                 break;
4921                 case 'T':
4922                     m_thread_name = option_arg;
4923                     m_thread_specified = true;
4924                 break;
4925                 case 'q':
4926                     m_queue_name = option_arg;
4927                     m_thread_specified = true;
4928                     break;
4929                 case 'x':
4930                 {
4931                     m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
4932                     if (m_thread_id == UINT32_MAX)
4933                        error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
4934                     m_thread_specified = true;
4935                 }
4936                 break;
4937                 case 'o':
4938                     m_use_one_liner = true;
4939                     m_one_liner = option_arg;
4940                 break;
4941                 default:
4942                     error.SetErrorStringWithFormat ("unrecognized option %c.", short_option);
4943                 break;
4944             }
4945             return error;
4946         }
4947 
4948         void
4949         OptionParsingStarting ()
4950         {
4951             m_class_name.clear();
4952             m_function_name.clear();
4953             m_line_start = 0;
4954             m_line_end = UINT_MAX;
4955             m_file_name.clear();
4956             m_module_name.clear();
4957             m_func_name_type_mask = eFunctionNameTypeAuto;
4958             m_thread_id = LLDB_INVALID_THREAD_ID;
4959             m_thread_index = UINT32_MAX;
4960             m_thread_name.clear();
4961             m_queue_name.clear();
4962 
4963             m_no_inlines = false;
4964             m_sym_ctx_specified = false;
4965             m_thread_specified = false;
4966 
4967             m_use_one_liner = false;
4968             m_one_liner.clear();
4969         }
4970 
4971 
4972         static OptionDefinition g_option_table[];
4973 
4974         std::string m_class_name;
4975         std::string m_function_name;
4976         uint32_t    m_line_start;
4977         uint32_t    m_line_end;
4978         std::string m_file_name;
4979         std::string m_module_name;
4980         uint32_t m_func_name_type_mask;  // A pick from lldb::FunctionNameType.
4981         lldb::tid_t m_thread_id;
4982         uint32_t m_thread_index;
4983         std::string m_thread_name;
4984         std::string m_queue_name;
4985         bool        m_sym_ctx_specified;
4986         bool        m_no_inlines;
4987         bool        m_thread_specified;
4988         // Instance variables to hold the values for one_liner options.
4989         bool m_use_one_liner;
4990         std::string m_one_liner;
4991     };
4992 
4993     Options *
4994     GetOptions ()
4995     {
4996         return &m_options;
4997     }
4998 
4999     CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) :
5000         CommandObjectParsed (interpreter,
5001                              "target stop-hook add",
5002                              "Add a hook to be executed when the target stops.",
5003                              "target stop-hook add"),
5004         IOHandlerDelegateMultiline ("DONE", IOHandlerDelegate::Completion::LLDBCommand),
5005         m_options (interpreter)
5006     {
5007     }
5008 
5009     ~CommandObjectTargetStopHookAdd ()
5010     {
5011     }
5012 
5013 protected:
5014     virtual void
5015     IOHandlerActivated (IOHandler &io_handler)
5016     {
5017         StreamFileSP output_sp(io_handler.GetOutputStreamFile());
5018         if (output_sp)
5019         {
5020             output_sp->PutCString("Enter your stop hook command(s).  Type 'DONE' to end.\n");
5021             output_sp->Flush();
5022         }
5023     }
5024 
5025     virtual void
5026     IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
5027     {
5028         if (m_stop_hook_sp)
5029         {
5030             if (line.empty())
5031             {
5032                 StreamFileSP error_sp(io_handler.GetErrorStreamFile());
5033                 if (error_sp)
5034                 {
5035                     error_sp->Printf("error: stop hook #%" PRIu64 " aborted, no commands.\n", m_stop_hook_sp->GetID());
5036                     error_sp->Flush();
5037                 }
5038                 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
5039                 if (target)
5040                     target->RemoveStopHookByID(m_stop_hook_sp->GetID());
5041             }
5042             else
5043             {
5044                 m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
5045                 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
5046                 if (output_sp)
5047                 {
5048                     output_sp->Printf("Stop hook #%" PRIu64 " added.\n", m_stop_hook_sp->GetID());
5049                     output_sp->Flush();
5050                 }
5051             }
5052             m_stop_hook_sp.reset();
5053         }
5054         io_handler.SetIsDone(true);
5055     }
5056 
5057     bool
5058     DoExecute (Args& command, CommandReturnObject &result)
5059     {
5060         m_stop_hook_sp.reset();
5061 
5062         Target *target = GetSelectedOrDummyTarget();
5063         if (target)
5064         {
5065             Target::StopHookSP new_hook_sp = target->CreateStopHook();
5066 
5067             //  First step, make the specifier.
5068             std::unique_ptr<SymbolContextSpecifier> specifier_ap;
5069             if (m_options.m_sym_ctx_specified)
5070             {
5071                 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget()));
5072 
5073                 if (!m_options.m_module_name.empty())
5074                 {
5075                     specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified);
5076                 }
5077 
5078                 if (!m_options.m_class_name.empty())
5079                 {
5080                     specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified);
5081                 }
5082 
5083                 if (!m_options.m_file_name.empty())
5084                 {
5085                     specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified);
5086                 }
5087 
5088                 if (m_options.m_line_start != 0)
5089                 {
5090                     specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified);
5091                 }
5092 
5093                 if (m_options.m_line_end != UINT_MAX)
5094                 {
5095                     specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
5096                 }
5097 
5098                 if (!m_options.m_function_name.empty())
5099                 {
5100                     specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified);
5101                 }
5102             }
5103 
5104             if (specifier_ap.get())
5105                 new_hook_sp->SetSpecifier (specifier_ap.release());
5106 
5107             // Next see if any of the thread options have been entered:
5108 
5109             if (m_options.m_thread_specified)
5110             {
5111                 ThreadSpec *thread_spec = new ThreadSpec();
5112 
5113                 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
5114                 {
5115                     thread_spec->SetTID (m_options.m_thread_id);
5116                 }
5117 
5118                 if (m_options.m_thread_index != UINT32_MAX)
5119                     thread_spec->SetIndex (m_options.m_thread_index);
5120 
5121                 if (!m_options.m_thread_name.empty())
5122                     thread_spec->SetName (m_options.m_thread_name.c_str());
5123 
5124                 if (!m_options.m_queue_name.empty())
5125                     thread_spec->SetQueueName (m_options.m_queue_name.c_str());
5126 
5127                 new_hook_sp->SetThreadSpecifier (thread_spec);
5128 
5129             }
5130             if (m_options.m_use_one_liner)
5131             {
5132                 // Use one-liner.
5133                 new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str());
5134                 result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n", new_hook_sp->GetID());
5135             }
5136             else
5137             {
5138                 m_stop_hook_sp = new_hook_sp;
5139                 m_interpreter.GetLLDBCommandsFromIOHandler ("> ",   // Prompt
5140                                                             *this,  // IOHandlerDelegate
5141                                                             true,   // Run IOHandler in async mode
5142                                                             NULL);  // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
5143 
5144             }
5145             result.SetStatus (eReturnStatusSuccessFinishNoResult);
5146         }
5147         else
5148         {
5149             result.AppendError ("invalid target\n");
5150             result.SetStatus (eReturnStatusFailed);
5151         }
5152 
5153         return result.Succeeded();
5154     }
5155 private:
5156     CommandOptions m_options;
5157     Target::StopHookSP m_stop_hook_sp;
5158 };
5159 
5160 OptionDefinition
5161 CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] =
5162 {
5163     { LLDB_OPT_SET_ALL, false, "one-liner", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOneLiner,
5164         "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
5165     { LLDB_OPT_SET_ALL, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
5166         "Set the module within which the stop-hook is to be run."},
5167     { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex,
5168         "The stop hook is run only for the thread whose index matches this argument."},
5169     { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID,
5170         "The stop hook is run only for the thread whose TID matches this argument."},
5171     { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName,
5172         "The stop hook is run only for the thread whose thread name matches this argument."},
5173     { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName,
5174         "The stop hook is run only for threads in the queue whose name is given by this argument."},
5175     { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
5176         "Specify the source file within which the stop-hook is to be run." },
5177     { LLDB_OPT_SET_1, false, "start-line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
5178         "Set the start of the line range for which the stop-hook is to be run."},
5179     { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
5180         "Set the end of the line range for which the stop-hook is to be run."},
5181     { LLDB_OPT_SET_2, false, "classname", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeClassName,
5182         "Specify the class within which the stop-hook is to be run." },
5183     { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
5184         "Set the function name within which the stop hook will be run." },
5185     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
5186 };
5187 
5188 #pragma mark CommandObjectTargetStopHookDelete
5189 
5190 //-------------------------------------------------------------------------
5191 // CommandObjectTargetStopHookDelete
5192 //-------------------------------------------------------------------------
5193 
5194 class CommandObjectTargetStopHookDelete : public CommandObjectParsed
5195 {
5196 public:
5197 
5198     CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) :
5199         CommandObjectParsed (interpreter,
5200                              "target stop-hook delete",
5201                              "Delete a stop-hook.",
5202                              "target stop-hook delete [<idx>]")
5203     {
5204     }
5205 
5206     ~CommandObjectTargetStopHookDelete ()
5207     {
5208     }
5209 
5210 protected:
5211     bool
5212     DoExecute (Args& command, CommandReturnObject &result)
5213     {
5214         Target *target = GetSelectedOrDummyTarget();
5215         if (target)
5216         {
5217             // FIXME: see if we can use the breakpoint id style parser?
5218             size_t num_args = command.GetArgumentCount();
5219             if (num_args == 0)
5220             {
5221                 if (!m_interpreter.Confirm ("Delete all stop hooks?", true))
5222                 {
5223                     result.SetStatus (eReturnStatusFailed);
5224                     return false;
5225                 }
5226                 else
5227                 {
5228                     target->RemoveAllStopHooks();
5229                 }
5230             }
5231             else
5232             {
5233                 bool success;
5234                 for (size_t i = 0; i < num_args; i++)
5235                 {
5236                     lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
5237                     if (!success)
5238                     {
5239                         result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
5240                         result.SetStatus(eReturnStatusFailed);
5241                         return false;
5242                     }
5243                     success = target->RemoveStopHookByID (user_id);
5244                     if (!success)
5245                     {
5246                         result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
5247                         result.SetStatus(eReturnStatusFailed);
5248                         return false;
5249                     }
5250                 }
5251             }
5252             result.SetStatus (eReturnStatusSuccessFinishNoResult);
5253         }
5254         else
5255         {
5256             result.AppendError ("invalid target\n");
5257             result.SetStatus (eReturnStatusFailed);
5258         }
5259 
5260         return result.Succeeded();
5261     }
5262 };
5263 #pragma mark CommandObjectTargetStopHookEnableDisable
5264 
5265 //-------------------------------------------------------------------------
5266 // CommandObjectTargetStopHookEnableDisable
5267 //-------------------------------------------------------------------------
5268 
5269 class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed
5270 {
5271 public:
5272 
5273     CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) :
5274         CommandObjectParsed (interpreter,
5275                              name,
5276                              help,
5277                              syntax),
5278         m_enable (enable)
5279     {
5280     }
5281 
5282     ~CommandObjectTargetStopHookEnableDisable ()
5283     {
5284     }
5285 
5286 protected:
5287     bool
5288     DoExecute (Args& command, CommandReturnObject &result)
5289     {
5290         Target *target = GetSelectedOrDummyTarget();
5291         if (target)
5292         {
5293             // FIXME: see if we can use the breakpoint id style parser?
5294             size_t num_args = command.GetArgumentCount();
5295             bool success;
5296 
5297             if (num_args == 0)
5298             {
5299                 target->SetAllStopHooksActiveState (m_enable);
5300             }
5301             else
5302             {
5303                 for (size_t i = 0; i < num_args; i++)
5304                 {
5305                     lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
5306                     if (!success)
5307                     {
5308                         result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
5309                         result.SetStatus(eReturnStatusFailed);
5310                         return false;
5311                     }
5312                     success = target->SetStopHookActiveStateByID (user_id, m_enable);
5313                     if (!success)
5314                     {
5315                         result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
5316                         result.SetStatus(eReturnStatusFailed);
5317                         return false;
5318                     }
5319                 }
5320             }
5321             result.SetStatus (eReturnStatusSuccessFinishNoResult);
5322         }
5323         else
5324         {
5325             result.AppendError ("invalid target\n");
5326             result.SetStatus (eReturnStatusFailed);
5327         }
5328         return result.Succeeded();
5329     }
5330 private:
5331     bool m_enable;
5332 };
5333 
5334 #pragma mark CommandObjectTargetStopHookList
5335 
5336 //-------------------------------------------------------------------------
5337 // CommandObjectTargetStopHookList
5338 //-------------------------------------------------------------------------
5339 
5340 class CommandObjectTargetStopHookList : public CommandObjectParsed
5341 {
5342 public:
5343 
5344     CommandObjectTargetStopHookList (CommandInterpreter &interpreter) :
5345         CommandObjectParsed (interpreter,
5346                              "target stop-hook list",
5347                              "List all stop-hooks.",
5348                              "target stop-hook list [<type>]")
5349     {
5350     }
5351 
5352     ~CommandObjectTargetStopHookList ()
5353     {
5354     }
5355 
5356 protected:
5357     bool
5358     DoExecute (Args& command, CommandReturnObject &result)
5359     {
5360         Target *target = GetSelectedOrDummyTarget();
5361         if (!target)
5362         {
5363             result.AppendError ("invalid target\n");
5364             result.SetStatus (eReturnStatusFailed);
5365             return result.Succeeded();
5366         }
5367 
5368         size_t num_hooks = target->GetNumStopHooks ();
5369         if (num_hooks == 0)
5370         {
5371             result.GetOutputStream().PutCString ("No stop hooks.\n");
5372         }
5373         else
5374         {
5375             for (size_t i = 0; i < num_hooks; i++)
5376             {
5377                 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i);
5378                 if (i > 0)
5379                     result.GetOutputStream().PutCString ("\n");
5380                 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull);
5381             }
5382         }
5383         result.SetStatus (eReturnStatusSuccessFinishResult);
5384         return result.Succeeded();
5385     }
5386 };
5387 
5388 #pragma mark CommandObjectMultiwordTargetStopHooks
5389 //-------------------------------------------------------------------------
5390 // CommandObjectMultiwordTargetStopHooks
5391 //-------------------------------------------------------------------------
5392 
5393 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword
5394 {
5395 public:
5396 
5397     CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) :
5398         CommandObjectMultiword (interpreter,
5399                                 "target stop-hook",
5400                                 "A set of commands for operating on debugger target stop-hooks.",
5401                                 "target stop-hook <subcommand> [<subcommand-options>]")
5402     {
5403         LoadSubCommand ("add",      CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter)));
5404         LoadSubCommand ("delete",   CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter)));
5405         LoadSubCommand ("disable",  CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
5406                                                                                                    false,
5407                                                                                                    "target stop-hook disable [<id>]",
5408                                                                                                    "Disable a stop-hook.",
5409                                                                                                    "target stop-hook disable")));
5410         LoadSubCommand ("enable",   CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
5411                                                                                                    true,
5412                                                                                                    "target stop-hook enable [<id>]",
5413                                                                                                    "Enable a stop-hook.",
5414                                                                                                    "target stop-hook enable")));
5415         LoadSubCommand ("list",     CommandObjectSP (new CommandObjectTargetStopHookList (interpreter)));
5416     }
5417 
5418     ~CommandObjectMultiwordTargetStopHooks()
5419     {
5420     }
5421 };
5422 
5423 
5424 
5425 #pragma mark CommandObjectMultiwordTarget
5426 
5427 //-------------------------------------------------------------------------
5428 // CommandObjectMultiwordTarget
5429 //-------------------------------------------------------------------------
5430 
5431 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) :
5432     CommandObjectMultiword (interpreter,
5433                             "target",
5434                             "A set of commands for operating on debugger targets.",
5435                             "target <subcommand> [<subcommand-options>]")
5436 {
5437 
5438     LoadSubCommand ("create",    CommandObjectSP (new CommandObjectTargetCreate (interpreter)));
5439     LoadSubCommand ("delete",    CommandObjectSP (new CommandObjectTargetDelete (interpreter)));
5440     LoadSubCommand ("list",      CommandObjectSP (new CommandObjectTargetList   (interpreter)));
5441     LoadSubCommand ("select",    CommandObjectSP (new CommandObjectTargetSelect (interpreter)));
5442     LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter)));
5443     LoadSubCommand ("modules",   CommandObjectSP (new CommandObjectTargetModules (interpreter)));
5444     LoadSubCommand ("symbols",   CommandObjectSP (new CommandObjectTargetSymbols (interpreter)));
5445     LoadSubCommand ("variable",  CommandObjectSP (new CommandObjectTargetVariable (interpreter)));
5446 }
5447 
5448 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget ()
5449 {
5450 }
5451 
5452 
5453