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