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