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