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