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