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