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