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