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->GetClangFullType ();
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->GetClangFullType ();
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 
1922         TypeSP type_sp (type_list.GetTypeAtIndex(0));
1923         if (type_sp)
1924         {
1925             // Resolve the clang type so that any forward references
1926             // to types that haven't yet been parsed will get parsed.
1927             type_sp->GetClangFullType ();
1928             type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
1929             // Print all typedef chains
1930             TypeSP typedef_type_sp (type_sp);
1931             TypeSP typedefed_type_sp (typedef_type_sp->GetTypedefType());
1932             while (typedefed_type_sp)
1933             {
1934                 strm.EOL();
1935                 strm.Printf("     typedef '%s': ", typedef_type_sp->GetName().GetCString());
1936                 typedefed_type_sp->GetClangFullType ();
1937                 typedefed_type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
1938                 typedef_type_sp = typedefed_type_sp;
1939                 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1940             }
1941         }
1942         strm.EOL();
1943     }
1944     return num_matches;
1945 }
1946 
1947 static uint32_t
1948 LookupFileAndLineInModule (CommandInterpreter &interpreter,
1949                            Stream &strm,
1950                            Module *module,
1951                            const FileSpec &file_spec,
1952                            uint32_t line,
1953                            bool check_inlines,
1954                            bool verbose)
1955 {
1956     if (module && file_spec)
1957     {
1958         SymbolContextList sc_list;
1959         const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
1960                                                                               eSymbolContextEverything, sc_list);
1961         if (num_matches > 0)
1962         {
1963             strm.Indent ();
1964             strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1965             strm << file_spec;
1966             if (line > 0)
1967                 strm.Printf (":%u", line);
1968             strm << " in ";
1969             DumpFullpath (strm, &module->GetFileSpec(), 0);
1970             strm.PutCString(":\n");
1971             DumpSymbolContextList (interpreter.GetExecutionContext().GetBestExecutionContextScope(), strm, sc_list, verbose);
1972             return num_matches;
1973         }
1974     }
1975     return 0;
1976 }
1977 
1978 
1979 static size_t
1980 FindModulesByName (Target *target,
1981                    const char *module_name,
1982                    ModuleList &module_list,
1983                    bool check_global_list)
1984 {
1985 // Dump specified images (by basename or fullpath)
1986     FileSpec module_file_spec(module_name, false);
1987     ModuleSpec module_spec (module_file_spec);
1988 
1989     const size_t initial_size = module_list.GetSize ();
1990 
1991     if (check_global_list)
1992     {
1993         // Check the global list
1994         Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex());
1995         const size_t num_modules = Module::GetNumberAllocatedModules();
1996         ModuleSP module_sp;
1997         for (size_t image_idx = 0; image_idx<num_modules; ++image_idx)
1998         {
1999             Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
2000 
2001             if (module)
2002             {
2003                 if (module->MatchesModuleSpec (module_spec))
2004                 {
2005                     module_sp = module->shared_from_this();
2006                     module_list.AppendIfNeeded(module_sp);
2007                 }
2008             }
2009         }
2010     }
2011     else
2012     {
2013         if (target)
2014         {
2015             const size_t num_matches = target->GetImages().FindModules (module_spec, module_list);
2016 
2017             // Not found in our module list for our target, check the main
2018             // shared module list in case it is a extra file used somewhere
2019             // else
2020             if (num_matches == 0)
2021             {
2022                 module_spec.GetArchitecture() = target->GetArchitecture();
2023                 ModuleList::FindSharedModules (module_spec, module_list);
2024             }
2025         }
2026         else
2027         {
2028             ModuleList::FindSharedModules (module_spec,module_list);
2029         }
2030     }
2031 
2032     return module_list.GetSize () - initial_size;
2033 }
2034 
2035 #pragma mark CommandObjectTargetModulesModuleAutoComplete
2036 
2037 //----------------------------------------------------------------------
2038 // A base command object class that can auto complete with module file
2039 // paths
2040 //----------------------------------------------------------------------
2041 
2042 class CommandObjectTargetModulesModuleAutoComplete : public CommandObjectParsed
2043 {
2044 public:
2045     CommandObjectTargetModulesModuleAutoComplete (CommandInterpreter &interpreter,
2046                                       const char *name,
2047                                       const char *help,
2048                                       const char *syntax) :
2049         CommandObjectParsed (interpreter, name, help, syntax)
2050     {
2051         CommandArgumentEntry arg;
2052         CommandArgumentData file_arg;
2053 
2054         // Define the first (and only) variant of this arg.
2055         file_arg.arg_type = eArgTypeFilename;
2056         file_arg.arg_repetition = eArgRepeatStar;
2057 
2058         // There is only one variant this argument could be; put it into the argument entry.
2059         arg.push_back (file_arg);
2060 
2061         // Push the data for the first argument into the m_arguments vector.
2062         m_arguments.push_back (arg);
2063     }
2064 
2065     virtual
2066     ~CommandObjectTargetModulesModuleAutoComplete ()
2067     {
2068     }
2069 
2070     virtual int
2071     HandleArgumentCompletion (Args &input,
2072                               int &cursor_index,
2073                               int &cursor_char_position,
2074                               OptionElementVector &opt_element_vector,
2075                               int match_start_point,
2076                               int max_return_elements,
2077                               bool &word_complete,
2078                               StringList &matches)
2079     {
2080         // Arguments are the standard module completer.
2081         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2082         completion_str.erase (cursor_char_position);
2083 
2084         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
2085                                                              CommandCompletions::eModuleCompletion,
2086                                                              completion_str.c_str(),
2087                                                              match_start_point,
2088                                                              max_return_elements,
2089                                                              NULL,
2090                                                              word_complete,
2091                                                              matches);
2092         return matches.GetSize();
2093     }
2094 };
2095 
2096 #pragma mark CommandObjectTargetModulesSourceFileAutoComplete
2097 
2098 //----------------------------------------------------------------------
2099 // A base command object class that can auto complete with module source
2100 // file paths
2101 //----------------------------------------------------------------------
2102 
2103 class CommandObjectTargetModulesSourceFileAutoComplete : public CommandObjectParsed
2104 {
2105 public:
2106     CommandObjectTargetModulesSourceFileAutoComplete (CommandInterpreter &interpreter,
2107                                                       const char *name,
2108                                                       const char *help,
2109                                                       const char *syntax,
2110                                                       uint32_t flags) :
2111         CommandObjectParsed (interpreter, name, help, syntax, flags)
2112     {
2113         CommandArgumentEntry arg;
2114         CommandArgumentData source_file_arg;
2115 
2116         // Define the first (and only) variant of this arg.
2117         source_file_arg.arg_type = eArgTypeSourceFile;
2118         source_file_arg.arg_repetition = eArgRepeatPlus;
2119 
2120         // There is only one variant this argument could be; put it into the argument entry.
2121         arg.push_back (source_file_arg);
2122 
2123         // Push the data for the first argument into the m_arguments vector.
2124         m_arguments.push_back (arg);
2125     }
2126 
2127     virtual
2128     ~CommandObjectTargetModulesSourceFileAutoComplete ()
2129     {
2130     }
2131 
2132     virtual int
2133     HandleArgumentCompletion (Args &input,
2134                               int &cursor_index,
2135                               int &cursor_char_position,
2136                               OptionElementVector &opt_element_vector,
2137                               int match_start_point,
2138                               int max_return_elements,
2139                               bool &word_complete,
2140                               StringList &matches)
2141     {
2142         // Arguments are the standard source file completer.
2143         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2144         completion_str.erase (cursor_char_position);
2145 
2146         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
2147                                                              CommandCompletions::eSourceFileCompletion,
2148                                                              completion_str.c_str(),
2149                                                              match_start_point,
2150                                                              max_return_elements,
2151                                                              NULL,
2152                                                              word_complete,
2153                                                              matches);
2154         return matches.GetSize();
2155     }
2156 };
2157 
2158 
2159 #pragma mark CommandObjectTargetModulesDumpSymtab
2160 
2161 
2162 class CommandObjectTargetModulesDumpSymtab : public CommandObjectTargetModulesModuleAutoComplete
2163 {
2164 public:
2165     CommandObjectTargetModulesDumpSymtab (CommandInterpreter &interpreter) :
2166     CommandObjectTargetModulesModuleAutoComplete (interpreter,
2167                                       "target modules dump symtab",
2168                                       "Dump the symbol table from one or more target modules.",
2169                                       NULL),
2170     m_options (interpreter)
2171     {
2172     }
2173 
2174     virtual
2175     ~CommandObjectTargetModulesDumpSymtab ()
2176     {
2177     }
2178 
2179     virtual Options *
2180     GetOptions ()
2181     {
2182         return &m_options;
2183     }
2184 
2185     class CommandOptions : public Options
2186     {
2187     public:
2188         CommandOptions (CommandInterpreter &interpreter) :
2189         Options(interpreter),
2190         m_sort_order (eSortOrderNone)
2191         {
2192         }
2193 
2194         virtual
2195         ~CommandOptions ()
2196         {
2197         }
2198 
2199         virtual Error
2200         SetOptionValue (uint32_t option_idx, const char *option_arg)
2201         {
2202             Error error;
2203             const int short_option = m_getopt_table[option_idx].val;
2204 
2205             switch (short_option)
2206             {
2207                 case 's':
2208                     m_sort_order = (SortOrder) Args::StringToOptionEnum (option_arg,
2209                                                                          g_option_table[option_idx].enum_values,
2210                                                                          eSortOrderNone,
2211                                                                          error);
2212                     break;
2213 
2214                 default:
2215                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
2216                     break;
2217 
2218             }
2219             return error;
2220         }
2221 
2222         void
2223         OptionParsingStarting ()
2224         {
2225             m_sort_order = eSortOrderNone;
2226         }
2227 
2228         const OptionDefinition*
2229         GetDefinitions ()
2230         {
2231             return g_option_table;
2232         }
2233 
2234         // Options table: Required for subclasses of Options.
2235         static OptionDefinition g_option_table[];
2236 
2237         SortOrder m_sort_order;
2238     };
2239 
2240 protected:
2241     virtual bool
2242     DoExecute (Args& command,
2243              CommandReturnObject &result)
2244     {
2245         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2246         if (target == NULL)
2247         {
2248             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2249             result.SetStatus (eReturnStatusFailed);
2250             return false;
2251         }
2252         else
2253         {
2254             uint32_t num_dumped = 0;
2255 
2256             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2257             result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2258             result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2259 
2260             if (command.GetArgumentCount() == 0)
2261             {
2262                 // Dump all sections for all modules images
2263                 Mutex::Locker modules_locker(target->GetImages().GetMutex());
2264                 const size_t num_modules = target->GetImages().GetSize();
2265                 if (num_modules > 0)
2266                 {
2267                     result.GetOutputStream().Printf("Dumping symbol table for %" PRIu64 " modules.\n", (uint64_t)num_modules);
2268                     for (size_t image_idx = 0; image_idx<num_modules; ++image_idx)
2269                     {
2270                         if (num_dumped > 0)
2271                         {
2272                             result.GetOutputStream().EOL();
2273                             result.GetOutputStream().EOL();
2274                         }
2275                         num_dumped++;
2276                         DumpModuleSymtab (m_interpreter,
2277                                           result.GetOutputStream(),
2278                                           target->GetImages().GetModulePointerAtIndexUnlocked(image_idx),
2279                                           m_options.m_sort_order);
2280                     }
2281                 }
2282                 else
2283                 {
2284                     result.AppendError ("the target has no associated executable images");
2285                     result.SetStatus (eReturnStatusFailed);
2286                     return false;
2287                 }
2288             }
2289             else
2290             {
2291                 // Dump specified images (by basename or fullpath)
2292                 const char *arg_cstr;
2293                 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2294                 {
2295                     ModuleList module_list;
2296                     const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
2297                     if (num_matches > 0)
2298                     {
2299                         for (size_t i=0; i<num_matches; ++i)
2300                         {
2301                             Module *module = module_list.GetModulePointerAtIndex(i);
2302                             if (module)
2303                             {
2304                                 if (num_dumped > 0)
2305                                 {
2306                                     result.GetOutputStream().EOL();
2307                                     result.GetOutputStream().EOL();
2308                                 }
2309                                 num_dumped++;
2310                                 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), module, m_options.m_sort_order);
2311                             }
2312                         }
2313                     }
2314                     else
2315                         result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
2316                 }
2317             }
2318 
2319             if (num_dumped > 0)
2320                 result.SetStatus (eReturnStatusSuccessFinishResult);
2321             else
2322             {
2323                 result.AppendError ("no matching executable images found");
2324                 result.SetStatus (eReturnStatusFailed);
2325             }
2326         }
2327         return result.Succeeded();
2328     }
2329 
2330     CommandOptions m_options;
2331 };
2332 
2333 static OptionEnumValueElement
2334 g_sort_option_enumeration[4] =
2335 {
2336     { eSortOrderNone,       "none",     "No sorting, use the original symbol table order."},
2337     { eSortOrderByAddress,  "address",  "Sort output by symbol address."},
2338     { eSortOrderByName,     "name",     "Sort output by symbol name."},
2339     { 0,                    NULL,       NULL }
2340 };
2341 
2342 
2343 OptionDefinition
2344 CommandObjectTargetModulesDumpSymtab::CommandOptions::g_option_table[] =
2345 {
2346     { 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."},
2347     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2348 };
2349 
2350 #pragma mark CommandObjectTargetModulesDumpSections
2351 
2352 //----------------------------------------------------------------------
2353 // Image section dumping command
2354 //----------------------------------------------------------------------
2355 
2356 class CommandObjectTargetModulesDumpSections : public CommandObjectTargetModulesModuleAutoComplete
2357 {
2358 public:
2359     CommandObjectTargetModulesDumpSections (CommandInterpreter &interpreter) :
2360     CommandObjectTargetModulesModuleAutoComplete (interpreter,
2361                                       "target modules dump sections",
2362                                       "Dump the sections from one or more target modules.",
2363                                       //"target modules dump sections [<file1> ...]")
2364                                       NULL)
2365     {
2366     }
2367 
2368     virtual
2369     ~CommandObjectTargetModulesDumpSections ()
2370     {
2371     }
2372 
2373 protected:
2374     virtual bool
2375     DoExecute (Args& command,
2376              CommandReturnObject &result)
2377     {
2378         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2379         if (target == NULL)
2380         {
2381             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2382             result.SetStatus (eReturnStatusFailed);
2383             return false;
2384         }
2385         else
2386         {
2387             uint32_t num_dumped = 0;
2388 
2389             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2390             result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2391             result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2392 
2393             if (command.GetArgumentCount() == 0)
2394             {
2395                 // Dump all sections for all modules images
2396                 const size_t num_modules = target->GetImages().GetSize();
2397                 if (num_modules > 0)
2398                 {
2399                     result.GetOutputStream().Printf("Dumping sections for %" PRIu64 " modules.\n", (uint64_t)num_modules);
2400                     for (size_t image_idx = 0;  image_idx<num_modules; ++image_idx)
2401                     {
2402                         num_dumped++;
2403                         DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
2404                     }
2405                 }
2406                 else
2407                 {
2408                     result.AppendError ("the target has no associated executable images");
2409                     result.SetStatus (eReturnStatusFailed);
2410                     return false;
2411                 }
2412             }
2413             else
2414             {
2415                 // Dump specified images (by basename or fullpath)
2416                 const char *arg_cstr;
2417                 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2418                 {
2419                     ModuleList module_list;
2420                     const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
2421                     if (num_matches > 0)
2422                     {
2423                         for (size_t i=0; i<num_matches; ++i)
2424                         {
2425                             Module *module = module_list.GetModulePointerAtIndex(i);
2426                             if (module)
2427                             {
2428                                 num_dumped++;
2429                                 DumpModuleSections (m_interpreter, result.GetOutputStream(), module);
2430                             }
2431                         }
2432                     }
2433                     else
2434                     {
2435                         // Check the global list
2436                         Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex());
2437 
2438                         result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
2439                     }
2440                 }
2441             }
2442 
2443             if (num_dumped > 0)
2444                 result.SetStatus (eReturnStatusSuccessFinishResult);
2445             else
2446             {
2447                 result.AppendError ("no matching executable images found");
2448                 result.SetStatus (eReturnStatusFailed);
2449             }
2450         }
2451         return result.Succeeded();
2452     }
2453 };
2454 
2455 
2456 #pragma mark CommandObjectTargetModulesDumpSymfile
2457 
2458 //----------------------------------------------------------------------
2459 // Image debug symbol dumping command
2460 //----------------------------------------------------------------------
2461 
2462 class CommandObjectTargetModulesDumpSymfile : public CommandObjectTargetModulesModuleAutoComplete
2463 {
2464 public:
2465     CommandObjectTargetModulesDumpSymfile (CommandInterpreter &interpreter) :
2466     CommandObjectTargetModulesModuleAutoComplete (interpreter,
2467                                       "target modules dump symfile",
2468                                       "Dump the debug symbol file for one or more target modules.",
2469                                       //"target modules dump symfile [<file1> ...]")
2470                                       NULL)
2471     {
2472     }
2473 
2474     virtual
2475     ~CommandObjectTargetModulesDumpSymfile ()
2476     {
2477     }
2478 
2479 protected:
2480     virtual bool
2481     DoExecute (Args& command,
2482              CommandReturnObject &result)
2483     {
2484         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2485         if (target == NULL)
2486         {
2487             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2488             result.SetStatus (eReturnStatusFailed);
2489             return false;
2490         }
2491         else
2492         {
2493             uint32_t num_dumped = 0;
2494 
2495             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2496             result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2497             result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2498 
2499             if (command.GetArgumentCount() == 0)
2500             {
2501                 // Dump all sections for all modules images
2502                 const ModuleList &target_modules = target->GetImages();
2503                 Mutex::Locker modules_locker (target_modules.GetMutex());
2504                 const size_t num_modules = target_modules.GetSize();
2505                 if (num_modules > 0)
2506                 {
2507                     result.GetOutputStream().Printf("Dumping debug symbols for %" PRIu64 " modules.\n", (uint64_t)num_modules);
2508                     for (uint32_t image_idx = 0;  image_idx<num_modules; ++image_idx)
2509                     {
2510                         if (DumpModuleSymbolVendor (result.GetOutputStream(), target_modules.GetModulePointerAtIndexUnlocked(image_idx)))
2511                             num_dumped++;
2512                     }
2513                 }
2514                 else
2515                 {
2516                     result.AppendError ("the target has no associated executable images");
2517                     result.SetStatus (eReturnStatusFailed);
2518                     return false;
2519                 }
2520             }
2521             else
2522             {
2523                 // Dump specified images (by basename or fullpath)
2524                 const char *arg_cstr;
2525                 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2526                 {
2527                     ModuleList module_list;
2528                     const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
2529                     if (num_matches > 0)
2530                     {
2531                         for (size_t i=0; i<num_matches; ++i)
2532                         {
2533                             Module *module = module_list.GetModulePointerAtIndex(i);
2534                             if (module)
2535                             {
2536                                 if (DumpModuleSymbolVendor (result.GetOutputStream(), module))
2537                                     num_dumped++;
2538                             }
2539                         }
2540                     }
2541                     else
2542                         result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
2543                 }
2544             }
2545 
2546             if (num_dumped > 0)
2547                 result.SetStatus (eReturnStatusSuccessFinishResult);
2548             else
2549             {
2550                 result.AppendError ("no matching executable images found");
2551                 result.SetStatus (eReturnStatusFailed);
2552             }
2553         }
2554         return result.Succeeded();
2555     }
2556 };
2557 
2558 
2559 #pragma mark CommandObjectTargetModulesDumpLineTable
2560 
2561 //----------------------------------------------------------------------
2562 // Image debug line table dumping command
2563 //----------------------------------------------------------------------
2564 
2565 class CommandObjectTargetModulesDumpLineTable : public CommandObjectTargetModulesSourceFileAutoComplete
2566 {
2567 public:
2568     CommandObjectTargetModulesDumpLineTable (CommandInterpreter &interpreter) :
2569     CommandObjectTargetModulesSourceFileAutoComplete (interpreter,
2570                                                       "target modules dump line-table",
2571                                                       "Dump the line table for one or more compilation units.",
2572                                                       NULL,
2573                                                       eCommandRequiresTarget)
2574     {
2575     }
2576 
2577     virtual
2578     ~CommandObjectTargetModulesDumpLineTable ()
2579     {
2580     }
2581 
2582 protected:
2583     virtual bool
2584     DoExecute (Args& command,
2585              CommandReturnObject &result)
2586     {
2587         Target *target = m_exe_ctx.GetTargetPtr();
2588         uint32_t total_num_dumped = 0;
2589 
2590         uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2591         result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2592         result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2593 
2594         if (command.GetArgumentCount() == 0)
2595         {
2596             result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str());
2597             result.SetStatus (eReturnStatusFailed);
2598         }
2599         else
2600         {
2601             // Dump specified images (by basename or fullpath)
2602             const char *arg_cstr;
2603             for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2604             {
2605                 FileSpec file_spec(arg_cstr, false);
2606 
2607                 const ModuleList &target_modules = target->GetImages();
2608                 Mutex::Locker modules_locker(target_modules.GetMutex());
2609                 const size_t num_modules = target_modules.GetSize();
2610                 if (num_modules > 0)
2611                 {
2612                     uint32_t num_dumped = 0;
2613                     for (uint32_t i = 0; i<num_modules; ++i)
2614                     {
2615                         if (DumpCompileUnitLineTable (m_interpreter,
2616                                                       result.GetOutputStream(),
2617                                                       target_modules.GetModulePointerAtIndexUnlocked(i),
2618                                                       file_spec,
2619                                                       m_exe_ctx.GetProcessPtr() && m_exe_ctx.GetProcessRef().IsAlive()))
2620                             num_dumped++;
2621                     }
2622                     if (num_dumped == 0)
2623                         result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr);
2624                     else
2625                         total_num_dumped += num_dumped;
2626                 }
2627             }
2628         }
2629 
2630         if (total_num_dumped > 0)
2631             result.SetStatus (eReturnStatusSuccessFinishResult);
2632         else
2633         {
2634             result.AppendError ("no source filenames matched any command arguments");
2635             result.SetStatus (eReturnStatusFailed);
2636         }
2637         return result.Succeeded();
2638     }
2639 };
2640 
2641 
2642 #pragma mark CommandObjectTargetModulesDump
2643 
2644 //----------------------------------------------------------------------
2645 // Dump multi-word command for target modules
2646 //----------------------------------------------------------------------
2647 
2648 class CommandObjectTargetModulesDump : public CommandObjectMultiword
2649 {
2650 public:
2651     //------------------------------------------------------------------
2652     // Constructors and Destructors
2653     //------------------------------------------------------------------
2654     CommandObjectTargetModulesDump(CommandInterpreter &interpreter) :
2655     CommandObjectMultiword (interpreter,
2656                             "target modules dump",
2657                             "A set of commands for dumping information about one or more target modules.",
2658                             "target modules dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]")
2659     {
2660         LoadSubCommand ("symtab",      CommandObjectSP (new CommandObjectTargetModulesDumpSymtab (interpreter)));
2661         LoadSubCommand ("sections",    CommandObjectSP (new CommandObjectTargetModulesDumpSections (interpreter)));
2662         LoadSubCommand ("symfile",     CommandObjectSP (new CommandObjectTargetModulesDumpSymfile (interpreter)));
2663         LoadSubCommand ("line-table",  CommandObjectSP (new CommandObjectTargetModulesDumpLineTable (interpreter)));
2664     }
2665 
2666     virtual
2667     ~CommandObjectTargetModulesDump()
2668     {
2669     }
2670 };
2671 
2672 class CommandObjectTargetModulesAdd : public CommandObjectParsed
2673 {
2674 public:
2675     CommandObjectTargetModulesAdd (CommandInterpreter &interpreter) :
2676         CommandObjectParsed (interpreter,
2677                              "target modules add",
2678                              "Add a new module to the current target's modules.",
2679                              "target modules add [<module>]"),
2680         m_option_group (interpreter),
2681         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.")
2682     {
2683         m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2684         m_option_group.Append (&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2685         m_option_group.Finalize();
2686     }
2687 
2688     virtual
2689     ~CommandObjectTargetModulesAdd ()
2690     {
2691     }
2692 
2693     virtual Options *
2694     GetOptions ()
2695     {
2696         return &m_option_group;
2697     }
2698 
2699     virtual int
2700     HandleArgumentCompletion (Args &input,
2701                               int &cursor_index,
2702                               int &cursor_char_position,
2703                               OptionElementVector &opt_element_vector,
2704                               int match_start_point,
2705                               int max_return_elements,
2706                               bool &word_complete,
2707                               StringList &matches)
2708     {
2709         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2710         completion_str.erase (cursor_char_position);
2711 
2712         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
2713                                                              CommandCompletions::eDiskFileCompletion,
2714                                                              completion_str.c_str(),
2715                                                              match_start_point,
2716                                                              max_return_elements,
2717                                                              NULL,
2718                                                              word_complete,
2719                                                              matches);
2720         return matches.GetSize();
2721     }
2722 
2723 protected:
2724     OptionGroupOptions m_option_group;
2725     OptionGroupUUID m_uuid_option_group;
2726     OptionGroupFile m_symbol_file;
2727 
2728     virtual bool
2729     DoExecute (Args& args,
2730              CommandReturnObject &result)
2731     {
2732         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2733         if (target == NULL)
2734         {
2735             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2736             result.SetStatus (eReturnStatusFailed);
2737             return false;
2738         }
2739         else
2740         {
2741             bool flush = false;
2742 
2743             const size_t argc = args.GetArgumentCount();
2744             if (argc == 0)
2745             {
2746                 if (m_uuid_option_group.GetOptionValue ().OptionWasSet())
2747                 {
2748                     // We are given a UUID only, go locate the file
2749                     ModuleSpec module_spec;
2750                     module_spec.GetUUID() = m_uuid_option_group.GetOptionValue ().GetCurrentValue();
2751                     if (m_symbol_file.GetOptionValue().OptionWasSet())
2752                         module_spec.GetSymbolFileSpec() = m_symbol_file.GetOptionValue().GetCurrentValue();
2753                     if (Symbols::DownloadObjectAndSymbolFile (module_spec))
2754                     {
2755                         ModuleSP module_sp (target->GetSharedModule (module_spec));
2756                         if (module_sp)
2757                         {
2758                             result.SetStatus (eReturnStatusSuccessFinishResult);
2759                             return true;
2760                         }
2761                         else
2762                         {
2763                             StreamString strm;
2764                             module_spec.GetUUID().Dump (&strm);
2765                             if (module_spec.GetFileSpec())
2766                             {
2767                                 if (module_spec.GetSymbolFileSpec())
2768                                 {
2769                                     result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s with path %s and symbol file %s",
2770                                                                   strm.GetString().c_str(),
2771                                                                   module_spec.GetFileSpec().GetPath().c_str(),
2772                                                                   module_spec.GetSymbolFileSpec().GetPath().c_str());
2773                                 }
2774                                 else
2775                                 {
2776                                     result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s with path %s",
2777                                                                   strm.GetString().c_str(),
2778                                                                   module_spec.GetFileSpec().GetPath().c_str());
2779                                 }
2780                             }
2781                             else
2782                             {
2783                                 result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s",
2784                                                               strm.GetString().c_str());
2785                             }
2786                             result.SetStatus (eReturnStatusFailed);
2787                             return false;
2788                         }
2789                     }
2790                     else
2791                     {
2792                         StreamString strm;
2793                         module_spec.GetUUID().Dump (&strm);
2794                         result.AppendErrorWithFormat ("Unable to locate the executable or symbol file with UUID %s", strm.GetString().c_str());
2795                         result.SetStatus (eReturnStatusFailed);
2796                         return false;
2797                     }
2798                 }
2799                 else
2800                 {
2801                     result.AppendError ("one or more executable image paths must be specified");
2802                     result.SetStatus (eReturnStatusFailed);
2803                     return false;
2804                 }
2805             }
2806             else
2807             {
2808                 for (size_t i=0; i<argc; ++i)
2809                 {
2810                     const char *path = args.GetArgumentAtIndex(i);
2811                     if (path)
2812                     {
2813                         FileSpec file_spec(path, true);
2814                         if (file_spec.Exists())
2815                         {
2816                             ModuleSpec module_spec (file_spec);
2817                             if (m_uuid_option_group.GetOptionValue ().OptionWasSet())
2818                                 module_spec.GetUUID() = m_uuid_option_group.GetOptionValue ().GetCurrentValue();
2819                             if (m_symbol_file.GetOptionValue().OptionWasSet())
2820                                 module_spec.GetSymbolFileSpec() = m_symbol_file.GetOptionValue().GetCurrentValue();
2821                             if (!module_spec.GetArchitecture().IsValid())
2822                                 module_spec.GetArchitecture() = target->GetArchitecture();
2823                             Error error;
2824                             ModuleSP module_sp (target->GetSharedModule (module_spec, &error));
2825                             if (!module_sp)
2826                             {
2827                                 const char *error_cstr = error.AsCString();
2828                                 if (error_cstr)
2829                                     result.AppendError (error_cstr);
2830                                 else
2831                                     result.AppendErrorWithFormat ("unsupported module: %s", path);
2832                                 result.SetStatus (eReturnStatusFailed);
2833                                 return false;
2834                             }
2835                             else
2836                             {
2837                                 flush = true;
2838                             }
2839                             result.SetStatus (eReturnStatusSuccessFinishResult);
2840                         }
2841                         else
2842                         {
2843                             char resolved_path[PATH_MAX];
2844                             result.SetStatus (eReturnStatusFailed);
2845                             if (file_spec.GetPath (resolved_path, sizeof(resolved_path)))
2846                             {
2847                                 if (strcmp (resolved_path, path) != 0)
2848                                 {
2849                                     result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", path, resolved_path);
2850                                     break;
2851                                 }
2852                             }
2853                             result.AppendErrorWithFormat ("invalid module path '%s'\n", path);
2854                             break;
2855                         }
2856                     }
2857                 }
2858             }
2859 
2860             if (flush)
2861             {
2862                 ProcessSP process = target->GetProcessSP();
2863                 if (process)
2864                     process->Flush();
2865             }
2866         }
2867 
2868         return result.Succeeded();
2869     }
2870 
2871 };
2872 
2873 class CommandObjectTargetModulesLoad : public CommandObjectTargetModulesModuleAutoComplete
2874 {
2875 public:
2876     CommandObjectTargetModulesLoad (CommandInterpreter &interpreter) :
2877         CommandObjectTargetModulesModuleAutoComplete (interpreter,
2878                                                       "target modules load",
2879                                                       "Set the load addresses for one or more sections in a target module.",
2880                                                       "target modules load [--file <module> --uuid <uuid>] <sect-name> <address> [<sect-name> <address> ....]"),
2881         m_option_group (interpreter),
2882         m_file_option (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName, "Fullpath or basename for module to load.", ""),
2883         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)
2884     {
2885         m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2886         m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2887         m_option_group.Append (&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2888         m_option_group.Finalize();
2889     }
2890 
2891     virtual
2892     ~CommandObjectTargetModulesLoad ()
2893     {
2894     }
2895 
2896     virtual Options *
2897     GetOptions ()
2898     {
2899         return &m_option_group;
2900     }
2901 
2902 protected:
2903     virtual bool
2904     DoExecute (Args& args,
2905              CommandReturnObject &result)
2906     {
2907         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2908         if (target == NULL)
2909         {
2910             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2911             result.SetStatus (eReturnStatusFailed);
2912             return false;
2913         }
2914         else
2915         {
2916             const size_t argc = args.GetArgumentCount();
2917             ModuleSpec module_spec;
2918             bool search_using_module_spec = false;
2919             if (m_file_option.GetOptionValue().OptionWasSet())
2920             {
2921                 search_using_module_spec = true;
2922                 const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
2923                 const bool use_global_module_list = true;
2924                 ModuleList module_list;
2925                 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, use_global_module_list);
2926                 if (num_matches == 1)
2927                 {
2928                     module_spec.GetFileSpec() = module_list.GetModuleAtIndex(0)->GetFileSpec();
2929                 }
2930                 else if (num_matches > 1 )
2931                 {
2932                     search_using_module_spec = false;
2933                     result.AppendErrorWithFormat ("more than 1 module matched by name '%s'\n", arg_cstr);
2934                     result.SetStatus (eReturnStatusFailed);
2935                 }
2936                 else
2937                 {
2938                     search_using_module_spec = false;
2939                     result.AppendErrorWithFormat ("no object file for module '%s'\n", arg_cstr);
2940                     result.SetStatus (eReturnStatusFailed);
2941                 }
2942             }
2943 
2944             if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2945             {
2946                 search_using_module_spec = true;
2947                 module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue();
2948             }
2949 
2950             if (search_using_module_spec)
2951             {
2952                 ModuleList matching_modules;
2953                 const size_t num_matches = target->GetImages().FindModules (module_spec, matching_modules);
2954 
2955                 char path[PATH_MAX];
2956                 if (num_matches == 1)
2957                 {
2958                     Module *module = matching_modules.GetModulePointerAtIndex(0);
2959                     if (module)
2960                     {
2961                         ObjectFile *objfile = module->GetObjectFile();
2962                         if (objfile)
2963                         {
2964                             SectionList *section_list = module->GetSectionList();
2965                             if (section_list)
2966                             {
2967                                 bool changed = false;
2968                                 if (argc == 0)
2969                                 {
2970                                     if (m_slide_option.GetOptionValue().OptionWasSet())
2971                                     {
2972                                         const addr_t slide = m_slide_option.GetOptionValue().GetCurrentValue();
2973                                         const bool slide_is_offset = true;
2974                                         module->SetLoadAddress (*target, slide, slide_is_offset, changed);
2975                                     }
2976                                     else
2977                                     {
2978                                         result.AppendError ("one or more section name + load address pair must be specified");
2979                                         result.SetStatus (eReturnStatusFailed);
2980                                         return false;
2981                                     }
2982                                 }
2983                                 else
2984                                 {
2985                                     if (m_slide_option.GetOptionValue().OptionWasSet())
2986                                     {
2987                                         result.AppendError ("The \"--slide <offset>\" option can't be used in conjunction with setting section load addresses.\n");
2988                                         result.SetStatus (eReturnStatusFailed);
2989                                         return false;
2990                                     }
2991 
2992                                     for (size_t i=0; i<argc; i += 2)
2993                                     {
2994                                         const char *sect_name = args.GetArgumentAtIndex(i);
2995                                         const char *load_addr_cstr = args.GetArgumentAtIndex(i+1);
2996                                         if (sect_name && load_addr_cstr)
2997                                         {
2998                                             ConstString const_sect_name(sect_name);
2999                                             bool success = false;
3000                                             addr_t load_addr = StringConvert::ToUInt64(load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
3001                                             if (success)
3002                                             {
3003                                                 SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
3004                                                 if (section_sp)
3005                                                 {
3006                                                     if (section_sp->IsThreadSpecific())
3007                                                     {
3008                                                         result.AppendErrorWithFormat ("thread specific sections are not yet supported (section '%s')\n", sect_name);
3009                                                         result.SetStatus (eReturnStatusFailed);
3010                                                         break;
3011                                                     }
3012                                                     else
3013                                                     {
3014                                                         if (target->GetSectionLoadList().SetSectionLoadAddress (section_sp, load_addr))
3015                                                             changed = true;
3016                                                         result.AppendMessageWithFormat("section '%s' loaded at 0x%" PRIx64 "\n", sect_name, load_addr);
3017                                                     }
3018                                                 }
3019                                                 else
3020                                                 {
3021                                                     result.AppendErrorWithFormat ("no section found that matches the section name '%s'\n", sect_name);
3022                                                     result.SetStatus (eReturnStatusFailed);
3023                                                     break;
3024                                                 }
3025                                             }
3026                                             else
3027                                             {
3028                                                 result.AppendErrorWithFormat ("invalid load address string '%s'\n", load_addr_cstr);
3029                                                 result.SetStatus (eReturnStatusFailed);
3030                                                 break;
3031                                             }
3032                                         }
3033                                         else
3034                                         {
3035                                             if (sect_name)
3036                                                 result.AppendError ("section names must be followed by a load address.\n");
3037                                             else
3038                                                 result.AppendError ("one or more section name + load address pair must be specified.\n");
3039                                             result.SetStatus (eReturnStatusFailed);
3040                                             break;
3041                                         }
3042                                     }
3043                                 }
3044 
3045                                 if (changed)
3046                                 {
3047                                     target->ModulesDidLoad (matching_modules);
3048                                     Process *process = m_exe_ctx.GetProcessPtr();
3049                                     if (process)
3050                                         process->Flush();
3051                                 }
3052                             }
3053                             else
3054                             {
3055                                 module->GetFileSpec().GetPath (path, sizeof(path));
3056                                 result.AppendErrorWithFormat ("no sections in object file '%s'\n", path);
3057                                 result.SetStatus (eReturnStatusFailed);
3058                             }
3059                         }
3060                         else
3061                         {
3062                             module->GetFileSpec().GetPath (path, sizeof(path));
3063                             result.AppendErrorWithFormat ("no object file for module '%s'\n", path);
3064                             result.SetStatus (eReturnStatusFailed);
3065                         }
3066                     }
3067                     else
3068                     {
3069                         FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
3070                         if (module_spec_file)
3071                         {
3072                             module_spec_file->GetPath (path, sizeof(path));
3073                             result.AppendErrorWithFormat ("invalid module '%s'.\n", path);
3074                         }
3075                         else
3076                             result.AppendError ("no module spec");
3077                         result.SetStatus (eReturnStatusFailed);
3078                     }
3079                 }
3080                 else
3081                 {
3082                     std::string uuid_str;
3083 
3084                     if (module_spec.GetFileSpec())
3085                         module_spec.GetFileSpec().GetPath (path, sizeof(path));
3086                     else
3087                         path[0] = '\0';
3088 
3089                     if (module_spec.GetUUIDPtr())
3090                         uuid_str = module_spec.GetUUID().GetAsString();
3091                     if (num_matches > 1)
3092                     {
3093                         result.AppendErrorWithFormat ("multiple modules match%s%s%s%s:\n",
3094                                                       path[0] ? " file=" : "",
3095                                                       path,
3096                                                       !uuid_str.empty() ? " uuid=" : "",
3097                                                       uuid_str.c_str());
3098                         for (size_t i=0; i<num_matches; ++i)
3099                         {
3100                             if (matching_modules.GetModulePointerAtIndex(i)->GetFileSpec().GetPath (path, sizeof(path)))
3101                                 result.AppendMessageWithFormat("%s\n", path);
3102                         }
3103                     }
3104                     else
3105                     {
3106                         result.AppendErrorWithFormat ("no modules were found  that match%s%s%s%s.\n",
3107                                                       path[0] ? " file=" : "",
3108                                                       path,
3109                                                       !uuid_str.empty() ? " uuid=" : "",
3110                                                       uuid_str.c_str());
3111                     }
3112                     result.SetStatus (eReturnStatusFailed);
3113                 }
3114             }
3115             else
3116             {
3117                 result.AppendError ("either the \"--file <module>\" or the \"--uuid <uuid>\" option must be specified.\n");
3118                 result.SetStatus (eReturnStatusFailed);
3119                 return false;
3120             }
3121         }
3122         return result.Succeeded();
3123     }
3124 
3125     OptionGroupOptions m_option_group;
3126     OptionGroupUUID m_uuid_option_group;
3127     OptionGroupString m_file_option;
3128     OptionGroupUInt64 m_slide_option;
3129 };
3130 
3131 //----------------------------------------------------------------------
3132 // List images with associated information
3133 //----------------------------------------------------------------------
3134 class CommandObjectTargetModulesList : public CommandObjectParsed
3135 {
3136 public:
3137     class CommandOptions : public Options
3138     {
3139     public:
3140         CommandOptions (CommandInterpreter &interpreter) :
3141             Options(interpreter),
3142             m_format_array(),
3143             m_use_global_module_list (false),
3144             m_module_addr (LLDB_INVALID_ADDRESS)
3145         {
3146         }
3147 
3148         virtual
3149         ~CommandOptions ()
3150         {
3151         }
3152 
3153         virtual Error
3154         SetOptionValue (uint32_t option_idx, const char *option_arg)
3155         {
3156             Error error;
3157 
3158             const int short_option = m_getopt_table[option_idx].val;
3159             if (short_option == 'g')
3160             {
3161                 m_use_global_module_list = true;
3162             }
3163             else if (short_option == 'a')
3164             {
3165                 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
3166                 m_module_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
3167             }
3168             else
3169             {
3170                 unsigned long width = 0;
3171                 if (option_arg)
3172                     width = strtoul (option_arg, NULL, 0);
3173                 m_format_array.push_back(std::make_pair(short_option, width));
3174             }
3175             return error;
3176         }
3177 
3178         void
3179         OptionParsingStarting ()
3180         {
3181             m_format_array.clear();
3182             m_use_global_module_list = false;
3183             m_module_addr = LLDB_INVALID_ADDRESS;
3184         }
3185 
3186         const OptionDefinition*
3187         GetDefinitions ()
3188         {
3189             return g_option_table;
3190         }
3191 
3192         // Options table: Required for subclasses of Options.
3193 
3194         static OptionDefinition g_option_table[];
3195 
3196         // Instance variables to hold the values for command options.
3197         typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection;
3198         FormatWidthCollection m_format_array;
3199         bool m_use_global_module_list;
3200         lldb::addr_t m_module_addr;
3201     };
3202 
3203     CommandObjectTargetModulesList (CommandInterpreter &interpreter) :
3204         CommandObjectParsed (interpreter,
3205                              "target modules list",
3206                              "List current executable and dependent shared library images.",
3207                              "target modules list [<cmd-options>]"),
3208         m_options (interpreter)
3209     {
3210     }
3211 
3212     virtual
3213     ~CommandObjectTargetModulesList ()
3214     {
3215     }
3216 
3217     virtual
3218     Options *
3219     GetOptions ()
3220     {
3221         return &m_options;
3222     }
3223 
3224 protected:
3225     virtual bool
3226     DoExecute (Args& command,
3227              CommandReturnObject &result)
3228     {
3229         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3230         const bool use_global_module_list = m_options.m_use_global_module_list;
3231         // Define a local module list here to ensure it lives longer than any "locker"
3232         // object which might lock its contents below (through the "module_list_ptr"
3233         // variable).
3234         ModuleList module_list;
3235         if (target == NULL && use_global_module_list == false)
3236         {
3237             result.AppendError ("invalid target, create a debug target using the 'target create' command");
3238             result.SetStatus (eReturnStatusFailed);
3239             return false;
3240         }
3241         else
3242         {
3243             if (target)
3244             {
3245                 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3246                 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3247                 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3248             }
3249             // Dump all sections for all modules images
3250             Stream &strm = result.GetOutputStream();
3251 
3252             if (m_options.m_module_addr != LLDB_INVALID_ADDRESS)
3253             {
3254                 if (target)
3255                 {
3256                     Address module_address;
3257                     if (module_address.SetLoadAddress(m_options.m_module_addr, target))
3258                     {
3259                         ModuleSP module_sp (module_address.GetModule());
3260                         if (module_sp)
3261                         {
3262                             PrintModule (target, module_sp.get(), 0, strm);
3263                             result.SetStatus (eReturnStatusSuccessFinishResult);
3264                         }
3265                         else
3266                         {
3267                             result.AppendErrorWithFormat ("Couldn't find module matching address: 0x%" PRIx64 ".", m_options.m_module_addr);
3268                             result.SetStatus (eReturnStatusFailed);
3269                         }
3270                     }
3271                     else
3272                     {
3273                         result.AppendErrorWithFormat ("Couldn't find module containing address: 0x%" PRIx64 ".", m_options.m_module_addr);
3274                         result.SetStatus (eReturnStatusFailed);
3275                     }
3276                 }
3277                 else
3278                 {
3279                     result.AppendError ("Can only look up modules by address with a valid target.");
3280                     result.SetStatus (eReturnStatusFailed);
3281                 }
3282                 return result.Succeeded();
3283             }
3284 
3285             size_t num_modules = 0;
3286             Mutex::Locker locker;      // This locker will be locked on the mutex in module_list_ptr if it is non-NULL.
3287                                        // Otherwise it will lock the AllocationModuleCollectionMutex when accessing
3288                                        // the global module list directly.
3289             const ModuleList *module_list_ptr = NULL;
3290             const size_t argc = command.GetArgumentCount();
3291             if (argc == 0)
3292             {
3293                 if (use_global_module_list)
3294                 {
3295                     locker.Lock (Module::GetAllocationModuleCollectionMutex());
3296                     num_modules = Module::GetNumberAllocatedModules();
3297                 }
3298                 else
3299                 {
3300                     module_list_ptr = &target->GetImages();
3301                 }
3302             }
3303             else
3304             {
3305                 for (size_t i=0; i<argc; ++i)
3306                 {
3307                     // Dump specified images (by basename or fullpath)
3308                     const char *arg_cstr = command.GetArgumentAtIndex(i);
3309                     const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, use_global_module_list);
3310                     if (num_matches == 0)
3311                     {
3312                         if (argc == 1)
3313                         {
3314                             result.AppendErrorWithFormat ("no modules found that match '%s'", arg_cstr);
3315                             result.SetStatus (eReturnStatusFailed);
3316                             return false;
3317                         }
3318                     }
3319                 }
3320 
3321                 module_list_ptr = &module_list;
3322             }
3323 
3324             if (module_list_ptr != NULL)
3325             {
3326                 locker.Lock(module_list_ptr->GetMutex());
3327                 num_modules = module_list_ptr->GetSize();
3328             }
3329 
3330             if (num_modules > 0)
3331             {
3332                 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
3333                 {
3334                     ModuleSP module_sp;
3335                     Module *module;
3336                     if (module_list_ptr)
3337                     {
3338                         module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
3339                         module = module_sp.get();
3340                     }
3341                     else
3342                     {
3343                         module = Module::GetAllocatedModuleAtIndex(image_idx);
3344                         module_sp = module->shared_from_this();
3345                     }
3346 
3347                     const size_t indent = strm.Printf("[%3u] ", image_idx);
3348                     PrintModule (target, module, indent, strm);
3349 
3350                 }
3351                 result.SetStatus (eReturnStatusSuccessFinishResult);
3352             }
3353             else
3354             {
3355                 if (argc)
3356                 {
3357                     if (use_global_module_list)
3358                         result.AppendError ("the global module list has no matching modules");
3359                     else
3360                         result.AppendError ("the target has no matching modules");
3361                 }
3362                 else
3363                 {
3364                     if (use_global_module_list)
3365                         result.AppendError ("the global module list is empty");
3366                     else
3367                         result.AppendError ("the target has no associated executable images");
3368                 }
3369                 result.SetStatus (eReturnStatusFailed);
3370                 return false;
3371             }
3372         }
3373         return result.Succeeded();
3374     }
3375 
3376     void
3377     PrintModule (Target *target, Module *module, int indent, Stream &strm)
3378     {
3379 
3380         if (module == NULL)
3381         {
3382             strm.PutCString("Null module");
3383             return;
3384         }
3385 
3386         bool dump_object_name = false;
3387         if (m_options.m_format_array.empty())
3388         {
3389             m_options.m_format_array.push_back(std::make_pair('u', 0));
3390             m_options.m_format_array.push_back(std::make_pair('h', 0));
3391             m_options.m_format_array.push_back(std::make_pair('f', 0));
3392             m_options.m_format_array.push_back(std::make_pair('S', 0));
3393         }
3394         const size_t num_entries = m_options.m_format_array.size();
3395         bool print_space = false;
3396         for (size_t i=0; i<num_entries; ++i)
3397         {
3398             if (print_space)
3399                 strm.PutChar(' ');
3400             print_space = true;
3401             const char format_char = m_options.m_format_array[i].first;
3402             uint32_t width = m_options.m_format_array[i].second;
3403             switch (format_char)
3404             {
3405                 case 'A':
3406                     DumpModuleArchitecture (strm, module, false, width);
3407                     break;
3408 
3409                 case 't':
3410                     DumpModuleArchitecture (strm, module, true, width);
3411                     break;
3412 
3413                 case 'f':
3414                     DumpFullpath (strm, &module->GetFileSpec(), width);
3415                     dump_object_name = true;
3416                     break;
3417 
3418                 case 'd':
3419                     DumpDirectory (strm, &module->GetFileSpec(), width);
3420                     break;
3421 
3422                 case 'b':
3423                     DumpBasename (strm, &module->GetFileSpec(), width);
3424                     dump_object_name = true;
3425                     break;
3426 
3427                 case 'h':
3428                 case 'o':
3429                     // Image header address
3430                     {
3431                         uint32_t addr_nibble_width = target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16;
3432 
3433                         ObjectFile *objfile = module->GetObjectFile ();
3434                         if (objfile)
3435                         {
3436                             Address header_addr(objfile->GetHeaderAddress());
3437                             if (header_addr.IsValid())
3438                             {
3439                                 if (target && !target->GetSectionLoadList().IsEmpty())
3440                                 {
3441                                     lldb::addr_t header_load_addr = header_addr.GetLoadAddress (target);
3442                                     if (header_load_addr == LLDB_INVALID_ADDRESS)
3443                                     {
3444                                         header_addr.Dump (&strm, target, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleFileAddress);
3445                                     }
3446                                     else
3447                                     {
3448                                         if (format_char == 'o')
3449                                         {
3450                                             // Show the offset of slide for the image
3451                                             strm.Printf ("0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width, header_load_addr - header_addr.GetFileAddress());
3452                                         }
3453                                         else
3454                                         {
3455                                             // Show the load address of the image
3456                                             strm.Printf ("0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width, header_load_addr);
3457                                         }
3458                                     }
3459                                     break;
3460                                 }
3461                                 // The address was valid, but the image isn't loaded, output the address in an appropriate format
3462                                 header_addr.Dump (&strm, target, Address::DumpStyleFileAddress);
3463                                 break;
3464                             }
3465                         }
3466                         strm.Printf ("%*s", addr_nibble_width + 2, "");
3467                     }
3468                     break;
3469                 case 'r':
3470                     {
3471                         size_t ref_count = 0;
3472                         ModuleSP module_sp (module->shared_from_this());
3473                         if (module_sp)
3474                         {
3475                             // Take one away to make sure we don't count our local "module_sp"
3476                             ref_count = module_sp.use_count() - 1;
3477                         }
3478                         if (width)
3479                             strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count);
3480                         else
3481                             strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count);
3482                     }
3483                     break;
3484 
3485                 case 's':
3486                 case 'S':
3487                     {
3488                         const SymbolVendor *symbol_vendor = module->GetSymbolVendor();
3489                         if (symbol_vendor)
3490                         {
3491                             const FileSpec symfile_spec = symbol_vendor->GetMainFileSpec();
3492                             if (format_char == 'S')
3493                             {
3494                                 // Dump symbol file only if different from module file
3495                                 if (!symfile_spec || symfile_spec == module->GetFileSpec())
3496                                 {
3497                                     print_space = false;
3498                                     break;
3499                                 }
3500                                 // Add a newline and indent past the index
3501                                 strm.Printf ("\n%*s", indent, "");
3502                             }
3503                             DumpFullpath (strm, &symfile_spec, width);
3504                             dump_object_name = true;
3505                             break;
3506                         }
3507                         strm.Printf("%.*s", width, "<NONE>");
3508                     }
3509                     break;
3510 
3511                 case 'm':
3512                     module->GetModificationTime().Dump(&strm, width);
3513                     break;
3514 
3515                 case 'p':
3516                     strm.Printf("%p", static_cast<void*>(module));
3517                     break;
3518 
3519                 case 'u':
3520                     DumpModuleUUID(strm, module);
3521                     break;
3522 
3523                 default:
3524                     break;
3525             }
3526 
3527         }
3528         if (dump_object_name)
3529         {
3530             const char *object_name = module->GetObjectName().GetCString();
3531             if (object_name)
3532                 strm.Printf ("(%s)", object_name);
3533         }
3534         strm.EOL();
3535     }
3536 
3537     CommandOptions m_options;
3538 };
3539 
3540 OptionDefinition
3541 CommandObjectTargetModulesList::CommandOptions::g_option_table[] =
3542 {
3543     { LLDB_OPT_SET_1, false, "address",    'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Display the image at this address."},
3544     { LLDB_OPT_SET_1, false, "arch",       'A', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the architecture when listing images."},
3545     { LLDB_OPT_SET_1, false, "triple",     't', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the triple when listing images."},
3546     { 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."},
3547     { 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)."},
3548     { LLDB_OPT_SET_1, false, "uuid",       'u', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone,    "Display the UUID when listing images."},
3549     { LLDB_OPT_SET_1, false, "fullpath",   'f', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the fullpath to the image object file."},
3550     { LLDB_OPT_SET_1, false, "directory",  'd', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the directory with optional width for the image object file."},
3551     { LLDB_OPT_SET_1, false, "basename",   'b', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the basename with optional width for the image object file."},
3552     { LLDB_OPT_SET_1, false, "symfile",    's', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the fullpath to the image symbol file with optional width."},
3553     { 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."},
3554     { LLDB_OPT_SET_1, false, "mod-time",   'm', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the modification time with optional width of the module."},
3555     { 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."},
3556     { LLDB_OPT_SET_1, false, "pointer",    'p', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeNone,    "Display the module pointer."},
3557     { 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."},
3558     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
3559 };
3560 
3561 #pragma mark CommandObjectTargetModulesShowUnwind
3562 
3563 //----------------------------------------------------------------------
3564 // Lookup unwind information in images
3565 //----------------------------------------------------------------------
3566 
3567 class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed
3568 {
3569 public:
3570 
3571     enum
3572     {
3573         eLookupTypeInvalid = -1,
3574         eLookupTypeAddress = 0,
3575         eLookupTypeSymbol,
3576         eLookupTypeFunction,
3577         eLookupTypeFunctionOrSymbol,
3578         kNumLookupTypes
3579     };
3580 
3581     class CommandOptions : public Options
3582     {
3583     public:
3584 
3585         CommandOptions (CommandInterpreter &interpreter) :
3586             Options(interpreter),
3587             m_type(eLookupTypeInvalid),
3588             m_str(),
3589             m_addr(LLDB_INVALID_ADDRESS)
3590         {
3591         }
3592 
3593         virtual
3594         ~CommandOptions ()
3595         {
3596         }
3597 
3598         virtual Error
3599         SetOptionValue (uint32_t option_idx, const char *option_arg)
3600         {
3601             Error error;
3602 
3603             const int short_option = m_getopt_table[option_idx].val;
3604 
3605             switch (short_option)
3606             {
3607                 case 'a':
3608                 {
3609                     ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
3610                     m_str = option_arg;
3611                     m_type = eLookupTypeAddress;
3612                     m_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
3613                     if (m_addr == LLDB_INVALID_ADDRESS)
3614                         error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg);
3615                     break;
3616                 }
3617 
3618                 case 'n':
3619                 {
3620                     m_str = option_arg;
3621                     m_type = eLookupTypeFunctionOrSymbol;
3622                     break;
3623                 }
3624 
3625                 default:
3626                     error.SetErrorStringWithFormat ("unrecognized option %c.", short_option);
3627                     break;
3628             }
3629 
3630             return error;
3631         }
3632 
3633         void
3634         OptionParsingStarting ()
3635         {
3636             m_type = eLookupTypeInvalid;
3637             m_str.clear();
3638             m_addr = LLDB_INVALID_ADDRESS;
3639         }
3640 
3641         const OptionDefinition*
3642         GetDefinitions ()
3643         {
3644             return g_option_table;
3645         }
3646 
3647         // Options table: Required for subclasses of Options.
3648 
3649         static OptionDefinition g_option_table[];
3650 
3651         // Instance variables to hold the values for command options.
3652 
3653         int             m_type;         // Should be a eLookupTypeXXX enum after parsing options
3654         std::string     m_str;          // Holds name lookup
3655         lldb::addr_t    m_addr;         // Holds the address to lookup
3656     };
3657 
3658     CommandObjectTargetModulesShowUnwind (CommandInterpreter &interpreter) :
3659         CommandObjectParsed (interpreter,
3660                              "target modules show-unwind",
3661                              "Show synthesized unwind instructions for a function.",
3662                              NULL,
3663                              eCommandRequiresTarget        |
3664                              eCommandRequiresProcess       |
3665                              eCommandProcessMustBeLaunched |
3666                              eCommandProcessMustBePaused   ),
3667         m_options (interpreter)
3668     {
3669     }
3670 
3671     virtual
3672     ~CommandObjectTargetModulesShowUnwind ()
3673     {
3674     }
3675 
3676     virtual
3677     Options *
3678     GetOptions ()
3679     {
3680         return &m_options;
3681     }
3682 
3683 protected:
3684     bool
3685     DoExecute (Args& command,
3686              CommandReturnObject &result)
3687     {
3688         Target *target = m_exe_ctx.GetTargetPtr();
3689         Process *process = m_exe_ctx.GetProcessPtr();
3690         ABI *abi = NULL;
3691         if (process)
3692           abi = process->GetABI().get();
3693 
3694         if (process == NULL)
3695         {
3696             result.AppendError ("You must have a process running to use this command.");
3697             result.SetStatus (eReturnStatusFailed);
3698             return false;
3699         }
3700 
3701         ThreadList threads(process->GetThreadList());
3702         if (threads.GetSize() == 0)
3703         {
3704             result.AppendError ("The process must be paused to use this command.");
3705             result.SetStatus (eReturnStatusFailed);
3706             return false;
3707         }
3708 
3709         ThreadSP thread(threads.GetThreadAtIndex(0));
3710         if (thread.get() == NULL)
3711         {
3712             result.AppendError ("The process must be paused to use this command.");
3713             result.SetStatus (eReturnStatusFailed);
3714             return false;
3715         }
3716 
3717         SymbolContextList sc_list;
3718 
3719         if (m_options.m_type == eLookupTypeFunctionOrSymbol)
3720         {
3721             ConstString function_name (m_options.m_str.c_str());
3722             target->GetImages().FindFunctions (function_name, eFunctionNameTypeAuto, true, false, true, sc_list);
3723         }
3724         else if (m_options.m_type == eLookupTypeAddress && target)
3725         {
3726             Address addr;
3727             if (target->GetSectionLoadList().ResolveLoadAddress (m_options.m_addr, addr))
3728             {
3729                 SymbolContext sc;
3730                 ModuleSP module_sp (addr.GetModule());
3731                 module_sp->ResolveSymbolContextForAddress (addr, eSymbolContextEverything, sc);
3732                 if (sc.function || sc.symbol)
3733                 {
3734                     sc_list.Append(sc);
3735                 }
3736             }
3737         }
3738         else
3739         {
3740             result.AppendError ("address-expression or function name option must be specified.");
3741             result.SetStatus (eReturnStatusFailed);
3742             return false;
3743         }
3744 
3745         size_t num_matches = sc_list.GetSize();
3746         if (num_matches == 0)
3747         {
3748             result.AppendErrorWithFormat ("no unwind data found that matches '%s'.", m_options.m_str.c_str());
3749             result.SetStatus (eReturnStatusFailed);
3750             return false;
3751         }
3752 
3753         for (uint32_t idx = 0; idx < num_matches; idx++)
3754         {
3755             SymbolContext sc;
3756             sc_list.GetContextAtIndex(idx, sc);
3757             if (sc.symbol == NULL && sc.function == NULL)
3758                 continue;
3759             if (sc.module_sp.get() == NULL || sc.module_sp->GetObjectFile() == NULL)
3760                 continue;
3761             AddressRange range;
3762             if (!sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range))
3763                 continue;
3764             if (!range.GetBaseAddress().IsValid())
3765                 continue;
3766             ConstString funcname(sc.GetFunctionName());
3767             if (funcname.IsEmpty())
3768                 continue;
3769             addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
3770             if (abi)
3771                 start_addr = abi->FixCodeAddress(start_addr);
3772 
3773             FuncUnwindersSP func_unwinders_sp (sc.module_sp->GetObjectFile()->GetUnwindTable().GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
3774             if (func_unwinders_sp.get() == NULL)
3775                 continue;
3776 
3777             result.GetOutputStream().Printf("UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
3778 
3779             UnwindPlanSP non_callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread.get(), -1);
3780             if (non_callsite_unwind_plan.get())
3781             {
3782                 result.GetOutputStream().Printf("Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n", non_callsite_unwind_plan->GetSourceName().AsCString());
3783             }
3784             UnwindPlanSP callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(*target, -1);
3785             if (callsite_unwind_plan.get())
3786             {
3787                 result.GetOutputStream().Printf("Synchronous (restricted to call-sites) UnwindPlan is '%s'\n", callsite_unwind_plan->GetSourceName().AsCString());
3788             }
3789             UnwindPlanSP fast_unwind_plan = func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread.get());
3790             if (fast_unwind_plan.get())
3791             {
3792                 result.GetOutputStream().Printf("Fast UnwindPlan is '%s'\n", fast_unwind_plan->GetSourceName().AsCString());
3793             }
3794 
3795             result.GetOutputStream().Printf("\n");
3796 
3797             UnwindPlanSP assembly_sp = func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread.get(), 0);
3798             if (assembly_sp)
3799             {
3800                 result.GetOutputStream().Printf("Assembly language inspection UnwindPlan:\n");
3801                 assembly_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3802                 result.GetOutputStream().Printf("\n");
3803             }
3804 
3805 
3806             UnwindPlanSP ehframe_sp = func_unwinders_sp->GetEHFrameUnwindPlan(*target, 0);
3807             if (ehframe_sp)
3808             {
3809                 result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3810                 ehframe_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3811                 result.GetOutputStream().Printf("\n");
3812             }
3813 
3814             UnwindPlanSP ehframe_augmented_sp = func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread.get(), 0);
3815             if (ehframe_augmented_sp)
3816             {
3817                 result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3818                 ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3819                 result.GetOutputStream().Printf("\n");
3820             }
3821 
3822             UnwindPlanSP compact_unwind_sp = func_unwinders_sp->GetCompactUnwindUnwindPlan(*target, 0);
3823             if (compact_unwind_sp)
3824             {
3825                 result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3826                 compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3827                 result.GetOutputStream().Printf("\n");
3828             }
3829 
3830             if (fast_unwind_plan)
3831             {
3832                 result.GetOutputStream().Printf("Fast UnwindPlan:\n");
3833                 fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3834                 result.GetOutputStream().Printf("\n");
3835             }
3836 
3837             ABISP abi_sp = process->GetABI();
3838             if (abi_sp)
3839             {
3840                 UnwindPlan arch_default(lldb::eRegisterKindGeneric);
3841                 if (abi_sp->CreateDefaultUnwindPlan (arch_default))
3842                 {
3843                     result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3844                     arch_default.Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3845                     result.GetOutputStream().Printf("\n");
3846                 }
3847 
3848                 UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
3849                 if (abi_sp->CreateFunctionEntryUnwindPlan (arch_entry))
3850                 {
3851                     result.GetOutputStream().Printf("Arch default at entry point UnwindPlan:\n");
3852                     arch_entry.Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3853                     result.GetOutputStream().Printf("\n");
3854                 }
3855             }
3856 
3857             result.GetOutputStream().Printf ("\n");
3858         }
3859         return result.Succeeded();
3860     }
3861 
3862     CommandOptions m_options;
3863 };
3864 
3865 OptionDefinition
3866 CommandObjectTargetModulesShowUnwind::CommandOptions::g_option_table[] =
3867 {
3868     { LLDB_OPT_SET_1,   false,  "name",       'n', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name."},
3869     { LLDB_OPT_SET_2,   false,  "address",    'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address"},
3870     { 0,                false, NULL,           0, 0,                 NULL, NULL, 0, eArgTypeNone, NULL }
3871 };
3872 
3873 //----------------------------------------------------------------------
3874 // Lookup information in images
3875 //----------------------------------------------------------------------
3876 class CommandObjectTargetModulesLookup : public CommandObjectParsed
3877 {
3878 public:
3879     enum
3880     {
3881         eLookupTypeInvalid = -1,
3882         eLookupTypeAddress = 0,
3883         eLookupTypeSymbol,
3884         eLookupTypeFileLine,    // Line is optional
3885         eLookupTypeFunction,
3886         eLookupTypeFunctionOrSymbol,
3887         eLookupTypeType,
3888         kNumLookupTypes
3889     };
3890 
3891     class CommandOptions : public Options
3892     {
3893     public:
3894         CommandOptions (CommandInterpreter &interpreter) :
3895         Options(interpreter)
3896         {
3897             OptionParsingStarting();
3898         }
3899 
3900         virtual
3901         ~CommandOptions ()
3902         {
3903         }
3904 
3905         virtual Error
3906         SetOptionValue (uint32_t option_idx, const char *option_arg)
3907         {
3908             Error error;
3909 
3910             const int short_option = m_getopt_table[option_idx].val;
3911 
3912             switch (short_option)
3913             {
3914                 case 'a':
3915                     {
3916                         m_type = eLookupTypeAddress;
3917                         ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
3918                         m_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
3919                     }
3920                     break;
3921 
3922                 case 'o':
3923                     m_offset = StringConvert::ToUInt64(option_arg, LLDB_INVALID_ADDRESS);
3924                     if (m_offset == LLDB_INVALID_ADDRESS)
3925                         error.SetErrorStringWithFormat ("invalid offset string '%s'", option_arg);
3926                     break;
3927 
3928                 case 's':
3929                     m_str = option_arg;
3930                     m_type = eLookupTypeSymbol;
3931                     break;
3932 
3933                 case 'f':
3934                     m_file.SetFile (option_arg, false);
3935                     m_type = eLookupTypeFileLine;
3936                     break;
3937 
3938                 case 'i':
3939                     m_include_inlines = false;
3940                     break;
3941 
3942                 case 'l':
3943                     m_line_number = StringConvert::ToUInt32(option_arg, UINT32_MAX);
3944                     if (m_line_number == UINT32_MAX)
3945                         error.SetErrorStringWithFormat ("invalid line number string '%s'", option_arg);
3946                     else if (m_line_number == 0)
3947                         error.SetErrorString ("zero is an invalid line number");
3948                     m_type = eLookupTypeFileLine;
3949                     break;
3950 
3951                 case 'F':
3952                     m_str = option_arg;
3953                     m_type = eLookupTypeFunction;
3954                     break;
3955 
3956                 case 'n':
3957                     m_str = option_arg;
3958                     m_type = eLookupTypeFunctionOrSymbol;
3959                     break;
3960 
3961                 case 't':
3962                     m_str = option_arg;
3963                     m_type = eLookupTypeType;
3964                     break;
3965 
3966                 case 'v':
3967                     m_verbose = 1;
3968                     break;
3969 
3970                 case 'A':
3971                     m_print_all = true;
3972                     break;
3973 
3974                 case 'r':
3975                     m_use_regex = true;
3976                     break;
3977             }
3978 
3979             return error;
3980         }
3981 
3982         void
3983         OptionParsingStarting ()
3984         {
3985             m_type = eLookupTypeInvalid;
3986             m_str.clear();
3987             m_file.Clear();
3988             m_addr = LLDB_INVALID_ADDRESS;
3989             m_offset = 0;
3990             m_line_number = 0;
3991             m_use_regex = false;
3992             m_include_inlines = true;
3993             m_verbose = false;
3994             m_print_all = false;
3995         }
3996 
3997         const OptionDefinition*
3998         GetDefinitions ()
3999         {
4000             return g_option_table;
4001         }
4002 
4003         // Options table: Required for subclasses of Options.
4004 
4005         static OptionDefinition g_option_table[];
4006         int             m_type;         // Should be a eLookupTypeXXX enum after parsing options
4007         std::string     m_str;          // Holds name lookup
4008         FileSpec        m_file;         // Files for file lookups
4009         lldb::addr_t    m_addr;         // Holds the address to lookup
4010         lldb::addr_t    m_offset;       // Subtract this offset from m_addr before doing lookups.
4011         uint32_t        m_line_number;  // Line number for file+line lookups
4012         bool            m_use_regex;    // Name lookups in m_str are regular expressions.
4013         bool            m_include_inlines;// Check for inline entries when looking up by file/line.
4014         bool            m_verbose;      // Enable verbose lookup info
4015         bool            m_print_all;    // Print all matches, even in cases where there's a best match.
4016     };
4017 
4018     CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) :
4019         CommandObjectParsed (interpreter,
4020                              "target modules lookup",
4021                              "Look up information within executable and dependent shared library images.",
4022                              NULL,
4023                              eCommandRequiresTarget),
4024         m_options (interpreter)
4025     {
4026         CommandArgumentEntry arg;
4027         CommandArgumentData file_arg;
4028 
4029         // Define the first (and only) variant of this arg.
4030         file_arg.arg_type = eArgTypeFilename;
4031         file_arg.arg_repetition = eArgRepeatStar;
4032 
4033         // There is only one variant this argument could be; put it into the argument entry.
4034         arg.push_back (file_arg);
4035 
4036         // Push the data for the first argument into the m_arguments vector.
4037         m_arguments.push_back (arg);
4038     }
4039 
4040     virtual
4041     ~CommandObjectTargetModulesLookup ()
4042     {
4043     }
4044 
4045     virtual Options *
4046     GetOptions ()
4047     {
4048         return &m_options;
4049     }
4050 
4051     bool
4052     LookupHere (CommandInterpreter &interpreter, CommandReturnObject &result, bool &syntax_error)
4053     {
4054         switch (m_options.m_type)
4055         {
4056             case eLookupTypeAddress:
4057             case eLookupTypeFileLine:
4058             case eLookupTypeFunction:
4059             case eLookupTypeFunctionOrSymbol:
4060             case eLookupTypeSymbol:
4061             default:
4062                 return false;
4063             case eLookupTypeType:
4064                 break;
4065         }
4066 
4067         StackFrameSP frame = m_exe_ctx.GetFrameSP();
4068 
4069         if (!frame)
4070             return false;
4071 
4072         const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
4073 
4074         if (!sym_ctx.module_sp)
4075             return false;
4076 
4077         switch (m_options.m_type)
4078         {
4079         default:
4080             return false;
4081         case eLookupTypeType:
4082             if (!m_options.m_str.empty())
4083             {
4084                 if (LookupTypeHere (m_interpreter,
4085                                     result.GetOutputStream(),
4086                                     sym_ctx,
4087                                     m_options.m_str.c_str(),
4088                                     m_options.m_use_regex))
4089                 {
4090                     result.SetStatus(eReturnStatusSuccessFinishResult);
4091                     return true;
4092                 }
4093             }
4094             break;
4095         }
4096 
4097         return true;
4098     }
4099 
4100     bool
4101     LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
4102     {
4103         switch (m_options.m_type)
4104         {
4105             case eLookupTypeAddress:
4106                 if (m_options.m_addr != LLDB_INVALID_ADDRESS)
4107                 {
4108                     if (LookupAddressInModule (m_interpreter,
4109                                                result.GetOutputStream(),
4110                                                module,
4111                                                eSymbolContextEverything | (m_options.m_verbose ? eSymbolContextVariable : 0),
4112                                                m_options.m_addr,
4113                                                m_options.m_offset,
4114                                                m_options.m_verbose))
4115                     {
4116                         result.SetStatus(eReturnStatusSuccessFinishResult);
4117                         return true;
4118                     }
4119                 }
4120                 break;
4121 
4122             case eLookupTypeSymbol:
4123                 if (!m_options.m_str.empty())
4124                 {
4125                     if (LookupSymbolInModule (m_interpreter,
4126                                               result.GetOutputStream(),
4127                                               module,
4128                                               m_options.m_str.c_str(),
4129                                               m_options.m_use_regex,
4130                                               m_options.m_verbose))
4131                     {
4132                         result.SetStatus(eReturnStatusSuccessFinishResult);
4133                         return true;
4134                     }
4135                 }
4136                 break;
4137 
4138             case eLookupTypeFileLine:
4139                 if (m_options.m_file)
4140                 {
4141                     if (LookupFileAndLineInModule (m_interpreter,
4142                                                    result.GetOutputStream(),
4143                                                    module,
4144                                                    m_options.m_file,
4145                                                    m_options.m_line_number,
4146                                                    m_options.m_include_inlines,
4147                                                    m_options.m_verbose))
4148                     {
4149                         result.SetStatus(eReturnStatusSuccessFinishResult);
4150                         return true;
4151                     }
4152                 }
4153                 break;
4154 
4155             case eLookupTypeFunctionOrSymbol:
4156             case eLookupTypeFunction:
4157                 if (!m_options.m_str.empty())
4158                 {
4159                     if (LookupFunctionInModule (m_interpreter,
4160                                                 result.GetOutputStream(),
4161                                                 module,
4162                                                 m_options.m_str.c_str(),
4163                                                 m_options.m_use_regex,
4164                                                 m_options.m_include_inlines,
4165                                                 m_options.m_type == eLookupTypeFunctionOrSymbol, // include symbols
4166                                                 m_options.m_verbose))
4167                     {
4168                         result.SetStatus(eReturnStatusSuccessFinishResult);
4169                         return true;
4170                     }
4171                 }
4172                 break;
4173 
4174             case eLookupTypeType:
4175                 if (!m_options.m_str.empty())
4176                 {
4177                     if (LookupTypeInModule (m_interpreter,
4178                                             result.GetOutputStream(),
4179                                             module,
4180                                             m_options.m_str.c_str(),
4181                                             m_options.m_use_regex))
4182                     {
4183                         result.SetStatus(eReturnStatusSuccessFinishResult);
4184                         return true;
4185                     }
4186                 }
4187                 break;
4188 
4189             default:
4190                 m_options.GenerateOptionUsage (result.GetErrorStream(), this);
4191                 syntax_error = true;
4192                 break;
4193         }
4194 
4195         result.SetStatus (eReturnStatusFailed);
4196         return false;
4197     }
4198 
4199 protected:
4200     virtual bool
4201     DoExecute (Args& command,
4202              CommandReturnObject &result)
4203     {
4204         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
4205         if (target == NULL)
4206         {
4207             result.AppendError ("invalid target, create a debug target using the 'target create' command");
4208             result.SetStatus (eReturnStatusFailed);
4209             return false;
4210         }
4211         else
4212         {
4213             bool syntax_error = false;
4214             uint32_t i;
4215             uint32_t num_successful_lookups = 0;
4216             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
4217             result.GetOutputStream().SetAddressByteSize(addr_byte_size);
4218             result.GetErrorStream().SetAddressByteSize(addr_byte_size);
4219             // Dump all sections for all modules images
4220 
4221             if (command.GetArgumentCount() == 0)
4222             {
4223                 ModuleSP current_module;
4224 
4225                 // Where it is possible to look in the current symbol context
4226                 // first, try that.  If this search was successful and --all
4227                 // was not passed, don't print anything else.
4228                 if (LookupHere (m_interpreter, result, syntax_error))
4229                 {
4230                     result.GetOutputStream().EOL();
4231                     num_successful_lookups++;
4232                     if (!m_options.m_print_all)
4233                     {
4234                         result.SetStatus (eReturnStatusSuccessFinishResult);
4235                         return result.Succeeded();
4236                     }
4237                 }
4238 
4239                 // Dump all sections for all other modules
4240 
4241                 const ModuleList &target_modules = target->GetImages();
4242                 Mutex::Locker modules_locker(target_modules.GetMutex());
4243                 const size_t num_modules = target_modules.GetSize();
4244                 if (num_modules > 0)
4245                 {
4246                     for (i = 0; i<num_modules && syntax_error == false; ++i)
4247                     {
4248                         Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked(i);
4249 
4250                         if (module_pointer != current_module.get() &&
4251                             LookupInModule (m_interpreter, target_modules.GetModulePointerAtIndexUnlocked(i), result, syntax_error))
4252                         {
4253                             result.GetOutputStream().EOL();
4254                             num_successful_lookups++;
4255                         }
4256                     }
4257                 }
4258                 else
4259                 {
4260                     result.AppendError ("the target has no associated executable images");
4261                     result.SetStatus (eReturnStatusFailed);
4262                     return false;
4263                 }
4264             }
4265             else
4266             {
4267                 // Dump specified images (by basename or fullpath)
4268                 const char *arg_cstr;
4269                 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i)
4270                 {
4271                     ModuleList module_list;
4272                     const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, false);
4273                     if (num_matches > 0)
4274                     {
4275                         for (size_t j=0; j<num_matches; ++j)
4276                         {
4277                             Module *module = module_list.GetModulePointerAtIndex(j);
4278                             if (module)
4279                             {
4280                                 if (LookupInModule (m_interpreter, module, result, syntax_error))
4281                                 {
4282                                     result.GetOutputStream().EOL();
4283                                     num_successful_lookups++;
4284                                 }
4285                             }
4286                         }
4287                     }
4288                     else
4289                         result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
4290                 }
4291             }
4292 
4293             if (num_successful_lookups > 0)
4294                 result.SetStatus (eReturnStatusSuccessFinishResult);
4295             else
4296                 result.SetStatus (eReturnStatusFailed);
4297         }
4298         return result.Succeeded();
4299     }
4300 
4301     CommandOptions m_options;
4302 };
4303 
4304 OptionDefinition
4305 CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] =
4306 {
4307     { LLDB_OPT_SET_1,   true,  "address",    'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules."},
4308     { 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."},
4309     { LLDB_OPT_SET_2| LLDB_OPT_SET_4 | LLDB_OPT_SET_5
4310       /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */ ,
4311                         false, "regex",      'r', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone,             "The <name> argument for name lookups are regular expressions."},
4312     { 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."},
4313     { 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."},
4314     { 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)."},
4315     { LLDB_OPT_SET_FROM_TO(3,5),
4316                         false, "no-inlines", 'i', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone,             "Ignore inline entries (must be used in conjunction with --file or --function)."},
4317     { 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."},
4318     { 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."},
4319     { 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."},
4320     { LLDB_OPT_SET_ALL, false, "verbose",    'v', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone,             "Enable verbose lookup information."},
4321     { 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."},
4322     { 0,                false, NULL,           0, 0,                 NULL, NULL, 0, eArgTypeNone,             NULL }
4323 };
4324 
4325 
4326 #pragma mark CommandObjectMultiwordImageSearchPaths
4327 
4328 //-------------------------------------------------------------------------
4329 // CommandObjectMultiwordImageSearchPaths
4330 //-------------------------------------------------------------------------
4331 
4332 class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword
4333 {
4334 public:
4335     CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) :
4336     CommandObjectMultiword (interpreter,
4337                             "target modules search-paths",
4338                             "A set of commands for operating on debugger target image search paths.",
4339                             "target modules search-paths <subcommand> [<subcommand-options>]")
4340     {
4341         LoadSubCommand ("add",     CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter)));
4342         LoadSubCommand ("clear",   CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter)));
4343         LoadSubCommand ("insert",  CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter)));
4344         LoadSubCommand ("list",    CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter)));
4345         LoadSubCommand ("query",   CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter)));
4346     }
4347 
4348     ~CommandObjectTargetModulesImageSearchPaths()
4349     {
4350     }
4351 };
4352 
4353 
4354 
4355 #pragma mark CommandObjectTargetModules
4356 
4357 //-------------------------------------------------------------------------
4358 // CommandObjectTargetModules
4359 //-------------------------------------------------------------------------
4360 
4361 class CommandObjectTargetModules : public CommandObjectMultiword
4362 {
4363 public:
4364     //------------------------------------------------------------------
4365     // Constructors and Destructors
4366     //------------------------------------------------------------------
4367     CommandObjectTargetModules(CommandInterpreter &interpreter) :
4368         CommandObjectMultiword (interpreter,
4369                                 "target modules",
4370                                 "A set of commands for accessing information for one or more target modules.",
4371                                 "target modules <sub-command> ...")
4372     {
4373         LoadSubCommand ("add",          CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter)));
4374         LoadSubCommand ("load",         CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter)));
4375         LoadSubCommand ("dump",         CommandObjectSP (new CommandObjectTargetModulesDump (interpreter)));
4376         LoadSubCommand ("list",         CommandObjectSP (new CommandObjectTargetModulesList (interpreter)));
4377         LoadSubCommand ("lookup",       CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter)));
4378         LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter)));
4379         LoadSubCommand ("show-unwind",  CommandObjectSP (new CommandObjectTargetModulesShowUnwind (interpreter)));
4380 
4381     }
4382     virtual
4383     ~CommandObjectTargetModules()
4384     {
4385     }
4386 
4387 private:
4388     //------------------------------------------------------------------
4389     // For CommandObjectTargetModules only
4390     //------------------------------------------------------------------
4391     DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules);
4392 };
4393 
4394 
4395 
4396 class CommandObjectTargetSymbolsAdd : public CommandObjectParsed
4397 {
4398 public:
4399     CommandObjectTargetSymbolsAdd (CommandInterpreter &interpreter) :
4400         CommandObjectParsed (interpreter,
4401                              "target symbols add",
4402                              "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.",
4403                              "target symbols add [<symfile>]", eCommandRequiresTarget),
4404         m_option_group (interpreter),
4405         m_file_option (LLDB_OPT_SET_1, false, "shlib", 's', CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Fullpath or basename for module to find debug symbols for."),
4406         m_current_frame_option (LLDB_OPT_SET_2, false, "frame", 'F', "Locate the debug symbols the currently selected frame.", false, true)
4407 
4408     {
4409         m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
4410         m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
4411         m_option_group.Append (&m_current_frame_option, LLDB_OPT_SET_2, LLDB_OPT_SET_2);
4412         m_option_group.Finalize();
4413     }
4414 
4415     virtual
4416     ~CommandObjectTargetSymbolsAdd ()
4417     {
4418     }
4419 
4420     virtual int
4421     HandleArgumentCompletion (Args &input,
4422                               int &cursor_index,
4423                               int &cursor_char_position,
4424                               OptionElementVector &opt_element_vector,
4425                               int match_start_point,
4426                               int max_return_elements,
4427                               bool &word_complete,
4428                               StringList &matches)
4429     {
4430         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
4431         completion_str.erase (cursor_char_position);
4432 
4433         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
4434                                                              CommandCompletions::eDiskFileCompletion,
4435                                                              completion_str.c_str(),
4436                                                              match_start_point,
4437                                                              max_return_elements,
4438                                                              NULL,
4439                                                              word_complete,
4440                                                              matches);
4441         return matches.GetSize();
4442     }
4443 
4444     virtual Options *
4445     GetOptions ()
4446     {
4447         return &m_option_group;
4448     }
4449 
4450 protected:
4451     bool
4452     AddModuleSymbols (Target *target,
4453                       ModuleSpec &module_spec,
4454                       bool &flush,
4455                       CommandReturnObject &result)
4456     {
4457         const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
4458         if (symbol_fspec)
4459         {
4460             char symfile_path[PATH_MAX];
4461             symbol_fspec.GetPath (symfile_path, sizeof(symfile_path));
4462 
4463             if (!module_spec.GetUUID().IsValid())
4464             {
4465                 if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
4466                     module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
4467             }
4468             // We now have a module that represents a symbol file
4469             // that can be used for a module that might exist in the
4470             // current target, so we need to find that module in the
4471             // target
4472             ModuleList matching_module_list;
4473 
4474             size_t num_matches = 0;
4475             // First extract all module specs from the symbol file
4476             lldb_private::ModuleSpecList symfile_module_specs;
4477             if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(), 0, 0, symfile_module_specs))
4478             {
4479                 // Now extract the module spec that matches the target architecture
4480                 ModuleSpec target_arch_module_spec;
4481                 ModuleSpec symfile_module_spec;
4482                 target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
4483                 if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec, symfile_module_spec))
4484                 {
4485                     // See if it has a UUID?
4486                     if (symfile_module_spec.GetUUID().IsValid())
4487                     {
4488                         // It has a UUID, look for this UUID in the target modules
4489                         ModuleSpec symfile_uuid_module_spec;
4490                         symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4491                         num_matches = target->GetImages().FindModules (symfile_uuid_module_spec, matching_module_list);
4492                     }
4493                 }
4494 
4495                 if (num_matches == 0)
4496                 {
4497                     // No matches yet, iterate through the module specs to find a UUID value that
4498                     // we can match up to an image in our target
4499                     const size_t num_symfile_module_specs = symfile_module_specs.GetSize();
4500                     for (size_t i=0; i<num_symfile_module_specs && num_matches == 0; ++i)
4501                     {
4502                         if (symfile_module_specs.GetModuleSpecAtIndex(i, symfile_module_spec))
4503                         {
4504                             if (symfile_module_spec.GetUUID().IsValid())
4505                             {
4506                                 // It has a UUID, look for this UUID in the target modules
4507                                 ModuleSpec symfile_uuid_module_spec;
4508                                 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4509                                 num_matches = target->GetImages().FindModules (symfile_uuid_module_spec, matching_module_list);
4510                             }
4511                         }
4512                     }
4513                 }
4514             }
4515 
4516             // Just try to match up the file by basename if we have no matches at this point
4517             if (num_matches == 0)
4518                 num_matches = target->GetImages().FindModules (module_spec, matching_module_list);
4519 
4520             while (num_matches == 0)
4521             {
4522                 ConstString filename_no_extension(module_spec.GetFileSpec().GetFileNameStrippingExtension());
4523                 // Empty string returned, lets bail
4524                 if (!filename_no_extension)
4525                     break;
4526 
4527                 // Check if there was no extension to strip and the basename is the same
4528                 if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
4529                     break;
4530 
4531                 // Replace basename with one less extension
4532                 module_spec.GetFileSpec().GetFilename() = filename_no_extension;
4533 
4534                 num_matches = target->GetImages().FindModules (module_spec, matching_module_list);
4535             }
4536 
4537             if (num_matches > 1)
4538             {
4539                 result.AppendErrorWithFormat ("multiple modules match symbol file '%s', use the --uuid option to resolve the ambiguity.\n", symfile_path);
4540             }
4541             else if (num_matches == 1)
4542             {
4543                 ModuleSP module_sp (matching_module_list.GetModuleAtIndex(0));
4544 
4545                 // The module has not yet created its symbol vendor, we can just
4546                 // give the existing target module the symfile path to use for
4547                 // when it decides to create it!
4548                 module_sp->SetSymbolFileFileSpec (symbol_fspec);
4549 
4550                 SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(true, &result.GetErrorStream());
4551                 if (symbol_vendor)
4552                 {
4553                     SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
4554 
4555                     if (symbol_file)
4556                     {
4557                         ObjectFile *object_file = symbol_file->GetObjectFile();
4558 
4559                         if (object_file && object_file->GetFileSpec() == symbol_fspec)
4560                         {
4561                             // Provide feedback that the symfile has been successfully added.
4562                             const FileSpec &module_fs = module_sp->GetFileSpec();
4563                             result.AppendMessageWithFormat("symbol file '%s' has been added to '%s'\n",
4564                                                            symfile_path,
4565                                                            module_fs.GetPath().c_str());
4566 
4567                             // Let clients know something changed in the module
4568                             // if it is currently loaded
4569                             ModuleList module_list;
4570                             module_list.Append (module_sp);
4571                             target->SymbolsDidLoad (module_list);
4572 
4573                             // Make sure we load any scripting resources that may be embedded
4574                             // in the debug info files in case the platform supports that.
4575                             Error error;
4576                             StreamString feedback_stream;
4577                             module_sp->LoadScriptingResourceInTarget (target, error,&feedback_stream);
4578                             if (error.Fail() && error.AsCString())
4579                                 result.AppendWarningWithFormat("unable to load scripting data for module %s - error reported was %s",
4580                                                                module_sp->GetFileSpec().GetFileNameStrippingExtension().GetCString(),
4581                                                                error.AsCString());
4582                             else if (feedback_stream.GetSize())
4583                                 result.AppendWarningWithFormat("%s",feedback_stream.GetData());
4584 
4585                             flush = true;
4586                             result.SetStatus (eReturnStatusSuccessFinishResult);
4587                             return true;
4588                         }
4589                     }
4590                 }
4591                 // Clear the symbol file spec if anything went wrong
4592                 module_sp->SetSymbolFileFileSpec (FileSpec());
4593             }
4594 
4595             if (module_spec.GetUUID().IsValid())
4596             {
4597                 StreamString ss_symfile_uuid;
4598                 module_spec.GetUUID().Dump(&ss_symfile_uuid);
4599                 result.AppendErrorWithFormat ("symbol file '%s' (%s) does not match any existing module%s\n",
4600                                               symfile_path,
4601                                               ss_symfile_uuid.GetData(),
4602                                               (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
4603                                                 ? "\n       please specify the full path to the symbol file"
4604                                                 : "");
4605             }
4606             else
4607             {
4608                 result.AppendErrorWithFormat ("symbol file '%s' does not match any existing module%s\n",
4609                                               symfile_path,
4610                                               (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
4611                                                 ? "\n       please specify the full path to the symbol file"
4612                                                 : "");
4613             }
4614         }
4615         else
4616         {
4617             result.AppendError ("one or more executable image paths must be specified");
4618         }
4619         result.SetStatus (eReturnStatusFailed);
4620         return false;
4621     }
4622 
4623     virtual bool
4624     DoExecute (Args& args,
4625              CommandReturnObject &result)
4626     {
4627         Target *target = m_exe_ctx.GetTargetPtr();
4628         result.SetStatus (eReturnStatusFailed);
4629         bool flush = false;
4630         ModuleSpec module_spec;
4631         const bool uuid_option_set = m_uuid_option_group.GetOptionValue().OptionWasSet();
4632         const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4633         const bool frame_option_set = m_current_frame_option.GetOptionValue().OptionWasSet();
4634 
4635         const size_t argc = args.GetArgumentCount();
4636         if (argc == 0)
4637         {
4638             if (uuid_option_set || file_option_set || frame_option_set)
4639             {
4640                 bool success = false;
4641                 bool error_set = false;
4642                 if (frame_option_set)
4643                 {
4644                     Process *process = m_exe_ctx.GetProcessPtr();
4645                     if (process)
4646                     {
4647                         const StateType process_state = process->GetState();
4648                         if (StateIsStoppedState (process_state, true))
4649                         {
4650                             StackFrame *frame = m_exe_ctx.GetFramePtr();
4651                             if (frame)
4652                             {
4653                                 ModuleSP frame_module_sp (frame->GetSymbolContext(eSymbolContextModule).module_sp);
4654                                 if (frame_module_sp)
4655                                 {
4656                                     if (frame_module_sp->GetPlatformFileSpec().Exists())
4657                                     {
4658                                         module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
4659                                         module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
4660                                     }
4661                                     module_spec.GetUUID() = frame_module_sp->GetUUID();
4662                                     success = module_spec.GetUUID().IsValid() || module_spec.GetFileSpec();
4663                                 }
4664                                 else
4665                                 {
4666                                     result.AppendError ("frame has no module");
4667                                     error_set = true;
4668                                 }
4669                             }
4670                             else
4671                             {
4672                                 result.AppendError ("invalid current frame");
4673                                 error_set = true;
4674                             }
4675                         }
4676                         else
4677                         {
4678                             result.AppendErrorWithFormat ("process is not stopped: %s", StateAsCString(process_state));
4679                             error_set = true;
4680                         }
4681                     }
4682                     else
4683                     {
4684                         result.AppendError ("a process must exist in order to use the --frame option");
4685                         error_set = true;
4686                     }
4687                 }
4688                 else
4689                 {
4690                     if (uuid_option_set)
4691                     {
4692                         module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue();
4693                         success |= module_spec.GetUUID().IsValid();
4694                     }
4695                     else if (file_option_set)
4696                     {
4697                         module_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue();
4698                         ModuleSP module_sp (target->GetImages().FindFirstModule(module_spec));
4699                         if (module_sp)
4700                         {
4701                             module_spec.GetFileSpec() = module_sp->GetFileSpec();
4702                             module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();
4703                             module_spec.GetUUID() = module_sp->GetUUID();
4704                             module_spec.GetArchitecture() = module_sp->GetArchitecture();
4705                         }
4706                         else
4707                         {
4708                             module_spec.GetArchitecture() = target->GetArchitecture();
4709                         }
4710                         success |= module_spec.GetFileSpec().Exists();
4711                     }
4712                 }
4713 
4714                 if (success)
4715                 {
4716                     if (Symbols::DownloadObjectAndSymbolFile (module_spec))
4717                     {
4718                         if (module_spec.GetSymbolFileSpec())
4719                             success = AddModuleSymbols (target, module_spec, flush, result);
4720                     }
4721                 }
4722 
4723                 if (!success && !error_set)
4724                 {
4725                     StreamString error_strm;
4726                     if (uuid_option_set)
4727                     {
4728                         error_strm.PutCString("unable to find debug symbols for UUID ");
4729                         module_spec.GetUUID().Dump (&error_strm);
4730                     }
4731                     else if (file_option_set)
4732                     {
4733                         error_strm.PutCString("unable to find debug symbols for the executable file ");
4734                         error_strm << module_spec.GetFileSpec();
4735                     }
4736                     else if (frame_option_set)
4737                     {
4738                         error_strm.PutCString("unable to find debug symbols for the current frame");
4739                     }
4740                     result.AppendError (error_strm.GetData());
4741                 }
4742             }
4743             else
4744             {
4745                 result.AppendError ("one or more symbol file paths must be specified, or options must be specified");
4746             }
4747         }
4748         else
4749         {
4750             if (uuid_option_set)
4751             {
4752                 result.AppendError ("specify either one or more paths to symbol files or use the --uuid option without arguments");
4753             }
4754             else if (file_option_set)
4755             {
4756                 result.AppendError ("specify either one or more paths to symbol files or use the --file option without arguments");
4757             }
4758             else if (frame_option_set)
4759             {
4760                 result.AppendError ("specify either one or more paths to symbol files or use the --frame option without arguments");
4761             }
4762             else
4763             {
4764                 PlatformSP platform_sp (target->GetPlatform());
4765 
4766                 for (size_t i=0; i<argc; ++i)
4767                 {
4768                     const char *symfile_path = args.GetArgumentAtIndex(i);
4769                     if (symfile_path)
4770                     {
4771                         module_spec.GetSymbolFileSpec().SetFile(symfile_path, true);
4772                         if (platform_sp)
4773                         {
4774                             FileSpec symfile_spec;
4775                             if (platform_sp->ResolveSymbolFile(*target, module_spec, symfile_spec).Success())
4776                                 module_spec.GetSymbolFileSpec() = symfile_spec;
4777                         }
4778 
4779                         ArchSpec arch;
4780                         bool symfile_exists = module_spec.GetSymbolFileSpec().Exists();
4781 
4782                         if (symfile_exists)
4783                         {
4784                             if (!AddModuleSymbols (target, module_spec, flush, result))
4785                                 break;
4786                         }
4787                         else
4788                         {
4789                             char resolved_symfile_path[PATH_MAX];
4790                             if (module_spec.GetSymbolFileSpec().GetPath (resolved_symfile_path, sizeof(resolved_symfile_path)))
4791                             {
4792                                 if (strcmp (resolved_symfile_path, symfile_path) != 0)
4793                                 {
4794                                     result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", symfile_path, resolved_symfile_path);
4795                                     break;
4796                                 }
4797                             }
4798                             result.AppendErrorWithFormat ("invalid module path '%s'\n", symfile_path);
4799                             break;
4800                         }
4801                     }
4802                 }
4803             }
4804         }
4805 
4806         if (flush)
4807         {
4808             Process *process = m_exe_ctx.GetProcessPtr();
4809             if (process)
4810                 process->Flush();
4811         }
4812         return result.Succeeded();
4813     }
4814 
4815     OptionGroupOptions m_option_group;
4816     OptionGroupUUID m_uuid_option_group;
4817     OptionGroupFile m_file_option;
4818     OptionGroupBoolean m_current_frame_option;
4819 };
4820 
4821 
4822 #pragma mark CommandObjectTargetSymbols
4823 
4824 //-------------------------------------------------------------------------
4825 // CommandObjectTargetSymbols
4826 //-------------------------------------------------------------------------
4827 
4828 class CommandObjectTargetSymbols : public CommandObjectMultiword
4829 {
4830 public:
4831     //------------------------------------------------------------------
4832     // Constructors and Destructors
4833     //------------------------------------------------------------------
4834     CommandObjectTargetSymbols(CommandInterpreter &interpreter) :
4835         CommandObjectMultiword (interpreter,
4836                             "target symbols",
4837                             "A set of commands for adding and managing debug symbol files.",
4838                             "target symbols <sub-command> ...")
4839     {
4840         LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetSymbolsAdd (interpreter)));
4841 
4842     }
4843     virtual
4844     ~CommandObjectTargetSymbols()
4845     {
4846     }
4847 
4848 private:
4849     //------------------------------------------------------------------
4850     // For CommandObjectTargetModules only
4851     //------------------------------------------------------------------
4852     DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetSymbols);
4853 };
4854 
4855 
4856 #pragma mark CommandObjectTargetStopHookAdd
4857 
4858 //-------------------------------------------------------------------------
4859 // CommandObjectTargetStopHookAdd
4860 //-------------------------------------------------------------------------
4861 
4862 class CommandObjectTargetStopHookAdd :
4863     public CommandObjectParsed,
4864     public IOHandlerDelegateMultiline
4865 {
4866 public:
4867 
4868     class CommandOptions : public Options
4869     {
4870     public:
4871         CommandOptions (CommandInterpreter &interpreter) :
4872             Options(interpreter),
4873             m_line_start(0),
4874             m_line_end (UINT_MAX),
4875             m_func_name_type_mask (eFunctionNameTypeAuto),
4876             m_sym_ctx_specified (false),
4877             m_thread_specified (false),
4878             m_use_one_liner (false),
4879             m_one_liner()
4880         {
4881         }
4882 
4883         ~CommandOptions () {}
4884 
4885         const OptionDefinition*
4886         GetDefinitions ()
4887         {
4888             return g_option_table;
4889         }
4890 
4891         virtual Error
4892         SetOptionValue (uint32_t option_idx, const char *option_arg)
4893         {
4894             Error error;
4895             const int short_option = m_getopt_table[option_idx].val;
4896             bool success;
4897 
4898             switch (short_option)
4899             {
4900                 case 'c':
4901                     m_class_name = option_arg;
4902                     m_sym_ctx_specified = true;
4903                 break;
4904 
4905                 case 'e':
4906                     m_line_end = StringConvert::ToUInt32 (option_arg, UINT_MAX, 0, &success);
4907                     if (!success)
4908                     {
4909                         error.SetErrorStringWithFormat ("invalid end line number: \"%s\"", option_arg);
4910                         break;
4911                     }
4912                     m_sym_ctx_specified = true;
4913                 break;
4914 
4915                 case 'l':
4916                     m_line_start = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
4917                     if (!success)
4918                     {
4919                         error.SetErrorStringWithFormat ("invalid start line number: \"%s\"", option_arg);
4920                         break;
4921                     }
4922                     m_sym_ctx_specified = true;
4923                 break;
4924 
4925                 case 'i':
4926                     m_no_inlines = true;
4927                 break;
4928 
4929                 case 'n':
4930                     m_function_name = option_arg;
4931                     m_func_name_type_mask |= eFunctionNameTypeAuto;
4932                     m_sym_ctx_specified = true;
4933                 break;
4934 
4935                 case 'f':
4936                     m_file_name = option_arg;
4937                     m_sym_ctx_specified = true;
4938                 break;
4939                 case 's':
4940                     m_module_name = option_arg;
4941                     m_sym_ctx_specified = true;
4942                 break;
4943                 case 't' :
4944                 {
4945                     m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
4946                     if (m_thread_id == LLDB_INVALID_THREAD_ID)
4947                        error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
4948                     m_thread_specified = true;
4949                 }
4950                 break;
4951                 case 'T':
4952                     m_thread_name = option_arg;
4953                     m_thread_specified = true;
4954                 break;
4955                 case 'q':
4956                     m_queue_name = option_arg;
4957                     m_thread_specified = true;
4958                     break;
4959                 case 'x':
4960                 {
4961                     m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
4962                     if (m_thread_id == UINT32_MAX)
4963                        error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
4964                     m_thread_specified = true;
4965                 }
4966                 break;
4967                 case 'o':
4968                     m_use_one_liner = true;
4969                     m_one_liner = option_arg;
4970                 break;
4971                 default:
4972                     error.SetErrorStringWithFormat ("unrecognized option %c.", short_option);
4973                 break;
4974             }
4975             return error;
4976         }
4977 
4978         void
4979         OptionParsingStarting ()
4980         {
4981             m_class_name.clear();
4982             m_function_name.clear();
4983             m_line_start = 0;
4984             m_line_end = UINT_MAX;
4985             m_file_name.clear();
4986             m_module_name.clear();
4987             m_func_name_type_mask = eFunctionNameTypeAuto;
4988             m_thread_id = LLDB_INVALID_THREAD_ID;
4989             m_thread_index = UINT32_MAX;
4990             m_thread_name.clear();
4991             m_queue_name.clear();
4992 
4993             m_no_inlines = false;
4994             m_sym_ctx_specified = false;
4995             m_thread_specified = false;
4996 
4997             m_use_one_liner = false;
4998             m_one_liner.clear();
4999         }
5000 
5001 
5002         static OptionDefinition g_option_table[];
5003 
5004         std::string m_class_name;
5005         std::string m_function_name;
5006         uint32_t    m_line_start;
5007         uint32_t    m_line_end;
5008         std::string m_file_name;
5009         std::string m_module_name;
5010         uint32_t m_func_name_type_mask;  // A pick from lldb::FunctionNameType.
5011         lldb::tid_t m_thread_id;
5012         uint32_t m_thread_index;
5013         std::string m_thread_name;
5014         std::string m_queue_name;
5015         bool        m_sym_ctx_specified;
5016         bool        m_no_inlines;
5017         bool        m_thread_specified;
5018         // Instance variables to hold the values for one_liner options.
5019         bool m_use_one_liner;
5020         std::string m_one_liner;
5021     };
5022 
5023     Options *
5024     GetOptions ()
5025     {
5026         return &m_options;
5027     }
5028 
5029     CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) :
5030         CommandObjectParsed (interpreter,
5031                              "target stop-hook add",
5032                              "Add a hook to be executed when the target stops.",
5033                              "target stop-hook add"),
5034         IOHandlerDelegateMultiline ("DONE", IOHandlerDelegate::Completion::LLDBCommand),
5035         m_options (interpreter)
5036     {
5037     }
5038 
5039     ~CommandObjectTargetStopHookAdd ()
5040     {
5041     }
5042 
5043 protected:
5044     virtual void
5045     IOHandlerActivated (IOHandler &io_handler)
5046     {
5047         StreamFileSP output_sp(io_handler.GetOutputStreamFile());
5048         if (output_sp)
5049         {
5050             output_sp->PutCString("Enter your stop hook command(s).  Type 'DONE' to end.\n");
5051             output_sp->Flush();
5052         }
5053     }
5054 
5055     virtual void
5056     IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
5057     {
5058         if (m_stop_hook_sp)
5059         {
5060             if (line.empty())
5061             {
5062                 StreamFileSP error_sp(io_handler.GetErrorStreamFile());
5063                 if (error_sp)
5064                 {
5065                     error_sp->Printf("error: stop hook #%" PRIu64 " aborted, no commands.\n", m_stop_hook_sp->GetID());
5066                     error_sp->Flush();
5067                 }
5068                 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
5069                 if (target)
5070                     target->RemoveStopHookByID(m_stop_hook_sp->GetID());
5071             }
5072             else
5073             {
5074                 m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
5075                 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
5076                 if (output_sp)
5077                 {
5078                     output_sp->Printf("Stop hook #%" PRIu64 " added.\n", m_stop_hook_sp->GetID());
5079                     output_sp->Flush();
5080                 }
5081             }
5082             m_stop_hook_sp.reset();
5083         }
5084         io_handler.SetIsDone(true);
5085     }
5086 
5087     bool
5088     DoExecute (Args& command, CommandReturnObject &result)
5089     {
5090         m_stop_hook_sp.reset();
5091 
5092         Target *target = GetSelectedOrDummyTarget();
5093         if (target)
5094         {
5095             Target::StopHookSP new_hook_sp = target->CreateStopHook();
5096 
5097             //  First step, make the specifier.
5098             std::unique_ptr<SymbolContextSpecifier> specifier_ap;
5099             if (m_options.m_sym_ctx_specified)
5100             {
5101                 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget()));
5102 
5103                 if (!m_options.m_module_name.empty())
5104                 {
5105                     specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified);
5106                 }
5107 
5108                 if (!m_options.m_class_name.empty())
5109                 {
5110                     specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified);
5111                 }
5112 
5113                 if (!m_options.m_file_name.empty())
5114                 {
5115                     specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified);
5116                 }
5117 
5118                 if (m_options.m_line_start != 0)
5119                 {
5120                     specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified);
5121                 }
5122 
5123                 if (m_options.m_line_end != UINT_MAX)
5124                 {
5125                     specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
5126                 }
5127 
5128                 if (!m_options.m_function_name.empty())
5129                 {
5130                     specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified);
5131                 }
5132             }
5133 
5134             if (specifier_ap.get())
5135                 new_hook_sp->SetSpecifier (specifier_ap.release());
5136 
5137             // Next see if any of the thread options have been entered:
5138 
5139             if (m_options.m_thread_specified)
5140             {
5141                 ThreadSpec *thread_spec = new ThreadSpec();
5142 
5143                 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
5144                 {
5145                     thread_spec->SetTID (m_options.m_thread_id);
5146                 }
5147 
5148                 if (m_options.m_thread_index != UINT32_MAX)
5149                     thread_spec->SetIndex (m_options.m_thread_index);
5150 
5151                 if (!m_options.m_thread_name.empty())
5152                     thread_spec->SetName (m_options.m_thread_name.c_str());
5153 
5154                 if (!m_options.m_queue_name.empty())
5155                     thread_spec->SetQueueName (m_options.m_queue_name.c_str());
5156 
5157                 new_hook_sp->SetThreadSpecifier (thread_spec);
5158 
5159             }
5160             if (m_options.m_use_one_liner)
5161             {
5162                 // Use one-liner.
5163                 new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str());
5164                 result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n", new_hook_sp->GetID());
5165             }
5166             else
5167             {
5168                 m_stop_hook_sp = new_hook_sp;
5169                 m_interpreter.GetLLDBCommandsFromIOHandler ("> ",   // Prompt
5170                                                             *this,  // IOHandlerDelegate
5171                                                             true,   // Run IOHandler in async mode
5172                                                             NULL);  // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
5173 
5174             }
5175             result.SetStatus (eReturnStatusSuccessFinishNoResult);
5176         }
5177         else
5178         {
5179             result.AppendError ("invalid target\n");
5180             result.SetStatus (eReturnStatusFailed);
5181         }
5182 
5183         return result.Succeeded();
5184     }
5185 private:
5186     CommandOptions m_options;
5187     Target::StopHookSP m_stop_hook_sp;
5188 };
5189 
5190 OptionDefinition
5191 CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] =
5192 {
5193     { LLDB_OPT_SET_ALL, false, "one-liner", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOneLiner,
5194         "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
5195     { LLDB_OPT_SET_ALL, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
5196         "Set the module within which the stop-hook is to be run."},
5197     { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex,
5198         "The stop hook is run only for the thread whose index matches this argument."},
5199     { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID,
5200         "The stop hook is run only for the thread whose TID matches this argument."},
5201     { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName,
5202         "The stop hook is run only for the thread whose thread name matches this argument."},
5203     { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName,
5204         "The stop hook is run only for threads in the queue whose name is given by this argument."},
5205     { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
5206         "Specify the source file within which the stop-hook is to be run." },
5207     { LLDB_OPT_SET_1, false, "start-line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
5208         "Set the start of the line range for which the stop-hook is to be run."},
5209     { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
5210         "Set the end of the line range for which the stop-hook is to be run."},
5211     { LLDB_OPT_SET_2, false, "classname", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeClassName,
5212         "Specify the class within which the stop-hook is to be run." },
5213     { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
5214         "Set the function name within which the stop hook will be run." },
5215     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
5216 };
5217 
5218 #pragma mark CommandObjectTargetStopHookDelete
5219 
5220 //-------------------------------------------------------------------------
5221 // CommandObjectTargetStopHookDelete
5222 //-------------------------------------------------------------------------
5223 
5224 class CommandObjectTargetStopHookDelete : public CommandObjectParsed
5225 {
5226 public:
5227 
5228     CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) :
5229         CommandObjectParsed (interpreter,
5230                              "target stop-hook delete",
5231                              "Delete a stop-hook.",
5232                              "target stop-hook delete [<idx>]")
5233     {
5234     }
5235 
5236     ~CommandObjectTargetStopHookDelete ()
5237     {
5238     }
5239 
5240 protected:
5241     bool
5242     DoExecute (Args& command, CommandReturnObject &result)
5243     {
5244         Target *target = GetSelectedOrDummyTarget();
5245         if (target)
5246         {
5247             // FIXME: see if we can use the breakpoint id style parser?
5248             size_t num_args = command.GetArgumentCount();
5249             if (num_args == 0)
5250             {
5251                 if (!m_interpreter.Confirm ("Delete all stop hooks?", true))
5252                 {
5253                     result.SetStatus (eReturnStatusFailed);
5254                     return false;
5255                 }
5256                 else
5257                 {
5258                     target->RemoveAllStopHooks();
5259                 }
5260             }
5261             else
5262             {
5263                 bool success;
5264                 for (size_t i = 0; i < num_args; i++)
5265                 {
5266                     lldb::user_id_t user_id = StringConvert::ToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
5267                     if (!success)
5268                     {
5269                         result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
5270                         result.SetStatus(eReturnStatusFailed);
5271                         return false;
5272                     }
5273                     success = target->RemoveStopHookByID (user_id);
5274                     if (!success)
5275                     {
5276                         result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
5277                         result.SetStatus(eReturnStatusFailed);
5278                         return false;
5279                     }
5280                 }
5281             }
5282             result.SetStatus (eReturnStatusSuccessFinishNoResult);
5283         }
5284         else
5285         {
5286             result.AppendError ("invalid target\n");
5287             result.SetStatus (eReturnStatusFailed);
5288         }
5289 
5290         return result.Succeeded();
5291     }
5292 };
5293 #pragma mark CommandObjectTargetStopHookEnableDisable
5294 
5295 //-------------------------------------------------------------------------
5296 // CommandObjectTargetStopHookEnableDisable
5297 //-------------------------------------------------------------------------
5298 
5299 class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed
5300 {
5301 public:
5302 
5303     CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) :
5304         CommandObjectParsed (interpreter,
5305                              name,
5306                              help,
5307                              syntax),
5308         m_enable (enable)
5309     {
5310     }
5311 
5312     ~CommandObjectTargetStopHookEnableDisable ()
5313     {
5314     }
5315 
5316 protected:
5317     bool
5318     DoExecute (Args& command, CommandReturnObject &result)
5319     {
5320         Target *target = GetSelectedOrDummyTarget();
5321         if (target)
5322         {
5323             // FIXME: see if we can use the breakpoint id style parser?
5324             size_t num_args = command.GetArgumentCount();
5325             bool success;
5326 
5327             if (num_args == 0)
5328             {
5329                 target->SetAllStopHooksActiveState (m_enable);
5330             }
5331             else
5332             {
5333                 for (size_t i = 0; i < num_args; i++)
5334                 {
5335                     lldb::user_id_t user_id = StringConvert::ToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
5336                     if (!success)
5337                     {
5338                         result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
5339                         result.SetStatus(eReturnStatusFailed);
5340                         return false;
5341                     }
5342                     success = target->SetStopHookActiveStateByID (user_id, m_enable);
5343                     if (!success)
5344                     {
5345                         result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
5346                         result.SetStatus(eReturnStatusFailed);
5347                         return false;
5348                     }
5349                 }
5350             }
5351             result.SetStatus (eReturnStatusSuccessFinishNoResult);
5352         }
5353         else
5354         {
5355             result.AppendError ("invalid target\n");
5356             result.SetStatus (eReturnStatusFailed);
5357         }
5358         return result.Succeeded();
5359     }
5360 private:
5361     bool m_enable;
5362 };
5363 
5364 #pragma mark CommandObjectTargetStopHookList
5365 
5366 //-------------------------------------------------------------------------
5367 // CommandObjectTargetStopHookList
5368 //-------------------------------------------------------------------------
5369 
5370 class CommandObjectTargetStopHookList : public CommandObjectParsed
5371 {
5372 public:
5373 
5374     CommandObjectTargetStopHookList (CommandInterpreter &interpreter) :
5375         CommandObjectParsed (interpreter,
5376                              "target stop-hook list",
5377                              "List all stop-hooks.",
5378                              "target stop-hook list [<type>]")
5379     {
5380     }
5381 
5382     ~CommandObjectTargetStopHookList ()
5383     {
5384     }
5385 
5386 protected:
5387     bool
5388     DoExecute (Args& command, CommandReturnObject &result)
5389     {
5390         Target *target = GetSelectedOrDummyTarget();
5391         if (!target)
5392         {
5393             result.AppendError ("invalid target\n");
5394             result.SetStatus (eReturnStatusFailed);
5395             return result.Succeeded();
5396         }
5397 
5398         size_t num_hooks = target->GetNumStopHooks ();
5399         if (num_hooks == 0)
5400         {
5401             result.GetOutputStream().PutCString ("No stop hooks.\n");
5402         }
5403         else
5404         {
5405             for (size_t i = 0; i < num_hooks; i++)
5406             {
5407                 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i);
5408                 if (i > 0)
5409                     result.GetOutputStream().PutCString ("\n");
5410                 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull);
5411             }
5412         }
5413         result.SetStatus (eReturnStatusSuccessFinishResult);
5414         return result.Succeeded();
5415     }
5416 };
5417 
5418 #pragma mark CommandObjectMultiwordTargetStopHooks
5419 //-------------------------------------------------------------------------
5420 // CommandObjectMultiwordTargetStopHooks
5421 //-------------------------------------------------------------------------
5422 
5423 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword
5424 {
5425 public:
5426 
5427     CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) :
5428         CommandObjectMultiword (interpreter,
5429                                 "target stop-hook",
5430                                 "A set of commands for operating on debugger target stop-hooks.",
5431                                 "target stop-hook <subcommand> [<subcommand-options>]")
5432     {
5433         LoadSubCommand ("add",      CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter)));
5434         LoadSubCommand ("delete",   CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter)));
5435         LoadSubCommand ("disable",  CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
5436                                                                                                    false,
5437                                                                                                    "target stop-hook disable [<id>]",
5438                                                                                                    "Disable a stop-hook.",
5439                                                                                                    "target stop-hook disable")));
5440         LoadSubCommand ("enable",   CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
5441                                                                                                    true,
5442                                                                                                    "target stop-hook enable [<id>]",
5443                                                                                                    "Enable a stop-hook.",
5444                                                                                                    "target stop-hook enable")));
5445         LoadSubCommand ("list",     CommandObjectSP (new CommandObjectTargetStopHookList (interpreter)));
5446     }
5447 
5448     ~CommandObjectMultiwordTargetStopHooks()
5449     {
5450     }
5451 };
5452 
5453 
5454 
5455 #pragma mark CommandObjectMultiwordTarget
5456 
5457 //-------------------------------------------------------------------------
5458 // CommandObjectMultiwordTarget
5459 //-------------------------------------------------------------------------
5460 
5461 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) :
5462     CommandObjectMultiword (interpreter,
5463                             "target",
5464                             "A set of commands for operating on debugger targets.",
5465                             "target <subcommand> [<subcommand-options>]")
5466 {
5467 
5468     LoadSubCommand ("create",    CommandObjectSP (new CommandObjectTargetCreate (interpreter)));
5469     LoadSubCommand ("delete",    CommandObjectSP (new CommandObjectTargetDelete (interpreter)));
5470     LoadSubCommand ("list",      CommandObjectSP (new CommandObjectTargetList   (interpreter)));
5471     LoadSubCommand ("select",    CommandObjectSP (new CommandObjectTargetSelect (interpreter)));
5472     LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter)));
5473     LoadSubCommand ("modules",   CommandObjectSP (new CommandObjectTargetModules (interpreter)));
5474     LoadSubCommand ("symbols",   CommandObjectSP (new CommandObjectTargetSymbols (interpreter)));
5475     LoadSubCommand ("variable",  CommandObjectSP (new CommandObjectTargetVariable (interpreter)));
5476 }
5477 
5478 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget ()
5479 {
5480 }
5481 
5482 
5483