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