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                     //Symtab::DumpSymbolHeader (&strm);
1738                     for (i=0; i < num_matches; ++i)
1739                     {
1740                         Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
1741                         DumpAddress (interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1742                                      symbol->GetAddress(),
1743                                      verbose,
1744                                      strm);
1745 
1746 //                        strm.Indent ();
1747 //                        symbol->Dump (&strm, interpreter.GetExecutionContext().GetTargetPtr(), i);
1748                     }
1749                     strm.IndentLess ();
1750                     return num_matches;
1751                 }
1752             }
1753         }
1754     }
1755     return 0;
1756 }
1757 
1758 
1759 static void
1760 DumpSymbolContextList (ExecutionContextScope *exe_scope, Stream &strm, SymbolContextList &sc_list, bool verbose)
1761 {
1762     strm.IndentMore ();
1763     uint32_t i;
1764     const uint32_t num_matches = sc_list.GetSize();
1765 
1766     for (i=0; i<num_matches; ++i)
1767     {
1768         SymbolContext sc;
1769         if (sc_list.GetContextAtIndex(i, sc))
1770         {
1771             AddressRange range;
1772 
1773             sc.GetAddressRange(eSymbolContextEverything,
1774                                0,
1775                                true,
1776                                range);
1777 
1778             DumpAddress (exe_scope, range.GetBaseAddress(), verbose, strm);
1779         }
1780     }
1781     strm.IndentLess ();
1782 }
1783 
1784 static size_t
1785 LookupFunctionInModule (CommandInterpreter &interpreter,
1786                         Stream &strm,
1787                         Module *module,
1788                         const char *name,
1789                         bool name_is_regex,
1790                         bool include_inlines,
1791                         bool include_symbols,
1792                         bool verbose)
1793 {
1794     if (module && name && name[0])
1795     {
1796         SymbolContextList sc_list;
1797         const bool append = true;
1798         size_t num_matches = 0;
1799         if (name_is_regex)
1800         {
1801             RegularExpression function_name_regex (name);
1802             num_matches = module->FindFunctions (function_name_regex,
1803                                                  include_symbols,
1804                                                  include_inlines,
1805                                                  append,
1806                                                  sc_list);
1807         }
1808         else
1809         {
1810             ConstString function_name (name);
1811             num_matches = module->FindFunctions (function_name,
1812                                                  NULL,
1813                                                  eFunctionNameTypeAuto,
1814                                                  include_symbols,
1815                                                  include_inlines,
1816                                                  append,
1817                                                  sc_list);
1818         }
1819 
1820         if (num_matches)
1821         {
1822             strm.Indent ();
1823             strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches, num_matches > 1 ? "es" : "");
1824             DumpFullpath (strm, &module->GetFileSpec(), 0);
1825             strm.PutCString(":\n");
1826             DumpSymbolContextList (interpreter.GetExecutionContext().GetBestExecutionContextScope(), strm, sc_list, verbose);
1827         }
1828         return num_matches;
1829     }
1830     return 0;
1831 }
1832 
1833 static size_t
1834 LookupTypeInModule (CommandInterpreter &interpreter,
1835                     Stream &strm,
1836                     Module *module,
1837                     const char *name_cstr,
1838                     bool name_is_regex)
1839 {
1840     if (module && name_cstr && name_cstr[0])
1841     {
1842         TypeList type_list;
1843         const uint32_t max_num_matches = UINT32_MAX;
1844         size_t num_matches = 0;
1845         bool name_is_fully_qualified = false;
1846         SymbolContext sc;
1847 
1848         ConstString name(name_cstr);
1849         num_matches = module->FindTypes(sc, name, name_is_fully_qualified, max_num_matches, type_list);
1850 
1851         if (num_matches)
1852         {
1853             strm.Indent ();
1854             strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches, num_matches > 1 ? "es" : "");
1855             DumpFullpath (strm, &module->GetFileSpec(), 0);
1856             strm.PutCString(":\n");
1857             for (TypeSP type_sp : type_list.Types())
1858             {
1859                 if (type_sp)
1860                 {
1861                     // Resolve the clang type so that any forward references
1862                     // to types that haven't yet been parsed will get parsed.
1863                     type_sp->GetClangFullType ();
1864                     type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
1865                     // Print all typedef chains
1866                     TypeSP typedef_type_sp (type_sp);
1867                     TypeSP typedefed_type_sp (typedef_type_sp->GetTypedefType());
1868                     while (typedefed_type_sp)
1869                     {
1870                         strm.EOL();
1871                         strm.Printf("     typedef '%s': ", typedef_type_sp->GetName().GetCString());
1872                         typedefed_type_sp->GetClangFullType ();
1873                         typedefed_type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
1874                         typedef_type_sp = typedefed_type_sp;
1875                         typedefed_type_sp = typedef_type_sp->GetTypedefType();
1876                     }
1877                 }
1878                 strm.EOL();
1879             }
1880         }
1881         return num_matches;
1882     }
1883     return 0;
1884 }
1885 
1886 static size_t
1887 LookupTypeHere (CommandInterpreter &interpreter,
1888                 Stream &strm,
1889                 const SymbolContext &sym_ctx,
1890                 const char *name_cstr,
1891                 bool name_is_regex)
1892 {
1893     if (!sym_ctx.module_sp)
1894         return 0;
1895 
1896     TypeList type_list;
1897     const uint32_t max_num_matches = UINT32_MAX;
1898     size_t num_matches = 1;
1899     bool name_is_fully_qualified = false;
1900 
1901     ConstString name(name_cstr);
1902     num_matches = sym_ctx.module_sp->FindTypes(sym_ctx, name, name_is_fully_qualified, max_num_matches, type_list);
1903 
1904     if (num_matches)
1905     {
1906         strm.Indent ();
1907         strm.PutCString("Best match found in ");
1908         DumpFullpath (strm, &sym_ctx.module_sp->GetFileSpec(), 0);
1909         strm.PutCString(":\n");
1910 
1911         TypeSP type_sp (type_list.GetTypeAtIndex(0));
1912         if (type_sp)
1913         {
1914             // Resolve the clang type so that any forward references
1915             // to types that haven't yet been parsed will get parsed.
1916             type_sp->GetClangFullType ();
1917             type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
1918             // Print all typedef chains
1919             TypeSP typedef_type_sp (type_sp);
1920             TypeSP typedefed_type_sp (typedef_type_sp->GetTypedefType());
1921             while (typedefed_type_sp)
1922             {
1923                 strm.EOL();
1924                 strm.Printf("     typedef '%s': ", typedef_type_sp->GetName().GetCString());
1925                 typedefed_type_sp->GetClangFullType ();
1926                 typedefed_type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
1927                 typedef_type_sp = typedefed_type_sp;
1928                 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1929             }
1930         }
1931         strm.EOL();
1932     }
1933     return num_matches;
1934 }
1935 
1936 static uint32_t
1937 LookupFileAndLineInModule (CommandInterpreter &interpreter,
1938                            Stream &strm,
1939                            Module *module,
1940                            const FileSpec &file_spec,
1941                            uint32_t line,
1942                            bool check_inlines,
1943                            bool verbose)
1944 {
1945     if (module && file_spec)
1946     {
1947         SymbolContextList sc_list;
1948         const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
1949                                                                               eSymbolContextEverything, sc_list);
1950         if (num_matches > 0)
1951         {
1952             strm.Indent ();
1953             strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1954             strm << file_spec;
1955             if (line > 0)
1956                 strm.Printf (":%u", line);
1957             strm << " in ";
1958             DumpFullpath (strm, &module->GetFileSpec(), 0);
1959             strm.PutCString(":\n");
1960             DumpSymbolContextList (interpreter.GetExecutionContext().GetBestExecutionContextScope(), strm, sc_list, verbose);
1961             return num_matches;
1962         }
1963     }
1964     return 0;
1965 }
1966 
1967 
1968 static size_t
1969 FindModulesByName (Target *target,
1970                    const char *module_name,
1971                    ModuleList &module_list,
1972                    bool check_global_list)
1973 {
1974 // Dump specified images (by basename or fullpath)
1975     FileSpec module_file_spec(module_name, false);
1976     ModuleSpec module_spec (module_file_spec);
1977 
1978     const size_t initial_size = module_list.GetSize ();
1979 
1980     if (check_global_list)
1981     {
1982         // Check the global list
1983         Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex());
1984         const size_t num_modules = Module::GetNumberAllocatedModules();
1985         ModuleSP module_sp;
1986         for (size_t image_idx = 0; image_idx<num_modules; ++image_idx)
1987         {
1988             Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
1989 
1990             if (module)
1991             {
1992                 if (module->MatchesModuleSpec (module_spec))
1993                 {
1994                     module_sp = module->shared_from_this();
1995                     module_list.AppendIfNeeded(module_sp);
1996                 }
1997             }
1998         }
1999     }
2000     else
2001     {
2002         if (target)
2003         {
2004             const size_t num_matches = target->GetImages().FindModules (module_spec, module_list);
2005 
2006             // Not found in our module list for our target, check the main
2007             // shared module list in case it is a extra file used somewhere
2008             // else
2009             if (num_matches == 0)
2010             {
2011                 module_spec.GetArchitecture() = target->GetArchitecture();
2012                 ModuleList::FindSharedModules (module_spec, module_list);
2013             }
2014         }
2015         else
2016         {
2017             ModuleList::FindSharedModules (module_spec,module_list);
2018         }
2019     }
2020 
2021     return module_list.GetSize () - initial_size;
2022 }
2023 
2024 #pragma mark CommandObjectTargetModulesModuleAutoComplete
2025 
2026 //----------------------------------------------------------------------
2027 // A base command object class that can auto complete with module file
2028 // paths
2029 //----------------------------------------------------------------------
2030 
2031 class CommandObjectTargetModulesModuleAutoComplete : public CommandObjectParsed
2032 {
2033 public:
2034     CommandObjectTargetModulesModuleAutoComplete (CommandInterpreter &interpreter,
2035                                       const char *name,
2036                                       const char *help,
2037                                       const char *syntax) :
2038         CommandObjectParsed (interpreter, name, help, syntax)
2039     {
2040         CommandArgumentEntry arg;
2041         CommandArgumentData file_arg;
2042 
2043         // Define the first (and only) variant of this arg.
2044         file_arg.arg_type = eArgTypeFilename;
2045         file_arg.arg_repetition = eArgRepeatStar;
2046 
2047         // There is only one variant this argument could be; put it into the argument entry.
2048         arg.push_back (file_arg);
2049 
2050         // Push the data for the first argument into the m_arguments vector.
2051         m_arguments.push_back (arg);
2052     }
2053 
2054     virtual
2055     ~CommandObjectTargetModulesModuleAutoComplete ()
2056     {
2057     }
2058 
2059     virtual int
2060     HandleArgumentCompletion (Args &input,
2061                               int &cursor_index,
2062                               int &cursor_char_position,
2063                               OptionElementVector &opt_element_vector,
2064                               int match_start_point,
2065                               int max_return_elements,
2066                               bool &word_complete,
2067                               StringList &matches)
2068     {
2069         // Arguments are the standard module completer.
2070         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2071         completion_str.erase (cursor_char_position);
2072 
2073         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
2074                                                              CommandCompletions::eModuleCompletion,
2075                                                              completion_str.c_str(),
2076                                                              match_start_point,
2077                                                              max_return_elements,
2078                                                              NULL,
2079                                                              word_complete,
2080                                                              matches);
2081         return matches.GetSize();
2082     }
2083 };
2084 
2085 #pragma mark CommandObjectTargetModulesSourceFileAutoComplete
2086 
2087 //----------------------------------------------------------------------
2088 // A base command object class that can auto complete with module source
2089 // file paths
2090 //----------------------------------------------------------------------
2091 
2092 class CommandObjectTargetModulesSourceFileAutoComplete : public CommandObjectParsed
2093 {
2094 public:
2095     CommandObjectTargetModulesSourceFileAutoComplete (CommandInterpreter &interpreter,
2096                                                       const char *name,
2097                                                       const char *help,
2098                                                       const char *syntax,
2099                                                       uint32_t flags) :
2100         CommandObjectParsed (interpreter, name, help, syntax, flags)
2101     {
2102         CommandArgumentEntry arg;
2103         CommandArgumentData source_file_arg;
2104 
2105         // Define the first (and only) variant of this arg.
2106         source_file_arg.arg_type = eArgTypeSourceFile;
2107         source_file_arg.arg_repetition = eArgRepeatPlus;
2108 
2109         // There is only one variant this argument could be; put it into the argument entry.
2110         arg.push_back (source_file_arg);
2111 
2112         // Push the data for the first argument into the m_arguments vector.
2113         m_arguments.push_back (arg);
2114     }
2115 
2116     virtual
2117     ~CommandObjectTargetModulesSourceFileAutoComplete ()
2118     {
2119     }
2120 
2121     virtual int
2122     HandleArgumentCompletion (Args &input,
2123                               int &cursor_index,
2124                               int &cursor_char_position,
2125                               OptionElementVector &opt_element_vector,
2126                               int match_start_point,
2127                               int max_return_elements,
2128                               bool &word_complete,
2129                               StringList &matches)
2130     {
2131         // Arguments are the standard source file completer.
2132         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2133         completion_str.erase (cursor_char_position);
2134 
2135         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
2136                                                              CommandCompletions::eSourceFileCompletion,
2137                                                              completion_str.c_str(),
2138                                                              match_start_point,
2139                                                              max_return_elements,
2140                                                              NULL,
2141                                                              word_complete,
2142                                                              matches);
2143         return matches.GetSize();
2144     }
2145 };
2146 
2147 
2148 #pragma mark CommandObjectTargetModulesDumpSymtab
2149 
2150 
2151 class CommandObjectTargetModulesDumpSymtab : public CommandObjectTargetModulesModuleAutoComplete
2152 {
2153 public:
2154     CommandObjectTargetModulesDumpSymtab (CommandInterpreter &interpreter) :
2155     CommandObjectTargetModulesModuleAutoComplete (interpreter,
2156                                       "target modules dump symtab",
2157                                       "Dump the symbol table from one or more target modules.",
2158                                       NULL),
2159     m_options (interpreter)
2160     {
2161     }
2162 
2163     virtual
2164     ~CommandObjectTargetModulesDumpSymtab ()
2165     {
2166     }
2167 
2168     virtual Options *
2169     GetOptions ()
2170     {
2171         return &m_options;
2172     }
2173 
2174     class CommandOptions : public Options
2175     {
2176     public:
2177         CommandOptions (CommandInterpreter &interpreter) :
2178         Options(interpreter),
2179         m_sort_order (eSortOrderNone)
2180         {
2181         }
2182 
2183         virtual
2184         ~CommandOptions ()
2185         {
2186         }
2187 
2188         virtual Error
2189         SetOptionValue (uint32_t option_idx, const char *option_arg)
2190         {
2191             Error error;
2192             const int short_option = m_getopt_table[option_idx].val;
2193 
2194             switch (short_option)
2195             {
2196                 case 's':
2197                     m_sort_order = (SortOrder) Args::StringToOptionEnum (option_arg,
2198                                                                          g_option_table[option_idx].enum_values,
2199                                                                          eSortOrderNone,
2200                                                                          error);
2201                     break;
2202 
2203                 default:
2204                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
2205                     break;
2206 
2207             }
2208             return error;
2209         }
2210 
2211         void
2212         OptionParsingStarting ()
2213         {
2214             m_sort_order = eSortOrderNone;
2215         }
2216 
2217         const OptionDefinition*
2218         GetDefinitions ()
2219         {
2220             return g_option_table;
2221         }
2222 
2223         // Options table: Required for subclasses of Options.
2224         static OptionDefinition g_option_table[];
2225 
2226         SortOrder m_sort_order;
2227     };
2228 
2229 protected:
2230     virtual bool
2231     DoExecute (Args& command,
2232              CommandReturnObject &result)
2233     {
2234         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2235         if (target == NULL)
2236         {
2237             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2238             result.SetStatus (eReturnStatusFailed);
2239             return false;
2240         }
2241         else
2242         {
2243             uint32_t num_dumped = 0;
2244 
2245             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2246             result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2247             result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2248 
2249             if (command.GetArgumentCount() == 0)
2250             {
2251                 // Dump all sections for all modules images
2252                 Mutex::Locker modules_locker(target->GetImages().GetMutex());
2253                 const size_t num_modules = target->GetImages().GetSize();
2254                 if (num_modules > 0)
2255                 {
2256                     result.GetOutputStream().Printf("Dumping symbol table for %" PRIu64 " modules.\n", (uint64_t)num_modules);
2257                     for (size_t image_idx = 0; image_idx<num_modules; ++image_idx)
2258                     {
2259                         if (num_dumped > 0)
2260                         {
2261                             result.GetOutputStream().EOL();
2262                             result.GetOutputStream().EOL();
2263                         }
2264                         num_dumped++;
2265                         DumpModuleSymtab (m_interpreter,
2266                                           result.GetOutputStream(),
2267                                           target->GetImages().GetModulePointerAtIndexUnlocked(image_idx),
2268                                           m_options.m_sort_order);
2269                     }
2270                 }
2271                 else
2272                 {
2273                     result.AppendError ("the target has no associated executable images");
2274                     result.SetStatus (eReturnStatusFailed);
2275                     return false;
2276                 }
2277             }
2278             else
2279             {
2280                 // Dump specified images (by basename or fullpath)
2281                 const char *arg_cstr;
2282                 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2283                 {
2284                     ModuleList module_list;
2285                     const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
2286                     if (num_matches > 0)
2287                     {
2288                         for (size_t i=0; i<num_matches; ++i)
2289                         {
2290                             Module *module = module_list.GetModulePointerAtIndex(i);
2291                             if (module)
2292                             {
2293                                 if (num_dumped > 0)
2294                                 {
2295                                     result.GetOutputStream().EOL();
2296                                     result.GetOutputStream().EOL();
2297                                 }
2298                                 num_dumped++;
2299                                 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), module, m_options.m_sort_order);
2300                             }
2301                         }
2302                     }
2303                     else
2304                         result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
2305                 }
2306             }
2307 
2308             if (num_dumped > 0)
2309                 result.SetStatus (eReturnStatusSuccessFinishResult);
2310             else
2311             {
2312                 result.AppendError ("no matching executable images found");
2313                 result.SetStatus (eReturnStatusFailed);
2314             }
2315         }
2316         return result.Succeeded();
2317     }
2318 
2319     CommandOptions m_options;
2320 };
2321 
2322 static OptionEnumValueElement
2323 g_sort_option_enumeration[4] =
2324 {
2325     { eSortOrderNone,       "none",     "No sorting, use the original symbol table order."},
2326     { eSortOrderByAddress,  "address",  "Sort output by symbol address."},
2327     { eSortOrderByName,     "name",     "Sort output by symbol name."},
2328     { 0,                    NULL,       NULL }
2329 };
2330 
2331 
2332 OptionDefinition
2333 CommandObjectTargetModulesDumpSymtab::CommandOptions::g_option_table[] =
2334 {
2335     { 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."},
2336     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2337 };
2338 
2339 #pragma mark CommandObjectTargetModulesDumpSections
2340 
2341 //----------------------------------------------------------------------
2342 // Image section dumping command
2343 //----------------------------------------------------------------------
2344 
2345 class CommandObjectTargetModulesDumpSections : public CommandObjectTargetModulesModuleAutoComplete
2346 {
2347 public:
2348     CommandObjectTargetModulesDumpSections (CommandInterpreter &interpreter) :
2349     CommandObjectTargetModulesModuleAutoComplete (interpreter,
2350                                       "target modules dump sections",
2351                                       "Dump the sections from one or more target modules.",
2352                                       //"target modules dump sections [<file1> ...]")
2353                                       NULL)
2354     {
2355     }
2356 
2357     virtual
2358     ~CommandObjectTargetModulesDumpSections ()
2359     {
2360     }
2361 
2362 protected:
2363     virtual bool
2364     DoExecute (Args& command,
2365              CommandReturnObject &result)
2366     {
2367         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2368         if (target == NULL)
2369         {
2370             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2371             result.SetStatus (eReturnStatusFailed);
2372             return false;
2373         }
2374         else
2375         {
2376             uint32_t num_dumped = 0;
2377 
2378             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2379             result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2380             result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2381 
2382             if (command.GetArgumentCount() == 0)
2383             {
2384                 // Dump all sections for all modules images
2385                 const size_t num_modules = target->GetImages().GetSize();
2386                 if (num_modules > 0)
2387                 {
2388                     result.GetOutputStream().Printf("Dumping sections for %" PRIu64 " modules.\n", (uint64_t)num_modules);
2389                     for (size_t image_idx = 0;  image_idx<num_modules; ++image_idx)
2390                     {
2391                         num_dumped++;
2392                         DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
2393                     }
2394                 }
2395                 else
2396                 {
2397                     result.AppendError ("the target has no associated executable images");
2398                     result.SetStatus (eReturnStatusFailed);
2399                     return false;
2400                 }
2401             }
2402             else
2403             {
2404                 // Dump specified images (by basename or fullpath)
2405                 const char *arg_cstr;
2406                 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2407                 {
2408                     ModuleList module_list;
2409                     const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
2410                     if (num_matches > 0)
2411                     {
2412                         for (size_t i=0; i<num_matches; ++i)
2413                         {
2414                             Module *module = module_list.GetModulePointerAtIndex(i);
2415                             if (module)
2416                             {
2417                                 num_dumped++;
2418                                 DumpModuleSections (m_interpreter, result.GetOutputStream(), module);
2419                             }
2420                         }
2421                     }
2422                     else
2423                     {
2424                         // Check the global list
2425                         Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex());
2426 
2427                         result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
2428                     }
2429                 }
2430             }
2431 
2432             if (num_dumped > 0)
2433                 result.SetStatus (eReturnStatusSuccessFinishResult);
2434             else
2435             {
2436                 result.AppendError ("no matching executable images found");
2437                 result.SetStatus (eReturnStatusFailed);
2438             }
2439         }
2440         return result.Succeeded();
2441     }
2442 };
2443 
2444 
2445 #pragma mark CommandObjectTargetModulesDumpSymfile
2446 
2447 //----------------------------------------------------------------------
2448 // Image debug symbol dumping command
2449 //----------------------------------------------------------------------
2450 
2451 class CommandObjectTargetModulesDumpSymfile : public CommandObjectTargetModulesModuleAutoComplete
2452 {
2453 public:
2454     CommandObjectTargetModulesDumpSymfile (CommandInterpreter &interpreter) :
2455     CommandObjectTargetModulesModuleAutoComplete (interpreter,
2456                                       "target modules dump symfile",
2457                                       "Dump the debug symbol file for one or more target modules.",
2458                                       //"target modules dump symfile [<file1> ...]")
2459                                       NULL)
2460     {
2461     }
2462 
2463     virtual
2464     ~CommandObjectTargetModulesDumpSymfile ()
2465     {
2466     }
2467 
2468 protected:
2469     virtual bool
2470     DoExecute (Args& command,
2471              CommandReturnObject &result)
2472     {
2473         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2474         if (target == NULL)
2475         {
2476             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2477             result.SetStatus (eReturnStatusFailed);
2478             return false;
2479         }
2480         else
2481         {
2482             uint32_t num_dumped = 0;
2483 
2484             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2485             result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2486             result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2487 
2488             if (command.GetArgumentCount() == 0)
2489             {
2490                 // Dump all sections for all modules images
2491                 const ModuleList &target_modules = target->GetImages();
2492                 Mutex::Locker modules_locker (target_modules.GetMutex());
2493                 const size_t num_modules = target_modules.GetSize();
2494                 if (num_modules > 0)
2495                 {
2496                     result.GetOutputStream().Printf("Dumping debug symbols for %" PRIu64 " modules.\n", (uint64_t)num_modules);
2497                     for (uint32_t image_idx = 0;  image_idx<num_modules; ++image_idx)
2498                     {
2499                         if (DumpModuleSymbolVendor (result.GetOutputStream(), target_modules.GetModulePointerAtIndexUnlocked(image_idx)))
2500                             num_dumped++;
2501                     }
2502                 }
2503                 else
2504                 {
2505                     result.AppendError ("the target has no associated executable images");
2506                     result.SetStatus (eReturnStatusFailed);
2507                     return false;
2508                 }
2509             }
2510             else
2511             {
2512                 // Dump specified images (by basename or fullpath)
2513                 const char *arg_cstr;
2514                 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2515                 {
2516                     ModuleList module_list;
2517                     const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
2518                     if (num_matches > 0)
2519                     {
2520                         for (size_t i=0; i<num_matches; ++i)
2521                         {
2522                             Module *module = module_list.GetModulePointerAtIndex(i);
2523                             if (module)
2524                             {
2525                                 if (DumpModuleSymbolVendor (result.GetOutputStream(), module))
2526                                     num_dumped++;
2527                             }
2528                         }
2529                     }
2530                     else
2531                         result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
2532                 }
2533             }
2534 
2535             if (num_dumped > 0)
2536                 result.SetStatus (eReturnStatusSuccessFinishResult);
2537             else
2538             {
2539                 result.AppendError ("no matching executable images found");
2540                 result.SetStatus (eReturnStatusFailed);
2541             }
2542         }
2543         return result.Succeeded();
2544     }
2545 };
2546 
2547 
2548 #pragma mark CommandObjectTargetModulesDumpLineTable
2549 
2550 //----------------------------------------------------------------------
2551 // Image debug line table dumping command
2552 //----------------------------------------------------------------------
2553 
2554 class CommandObjectTargetModulesDumpLineTable : public CommandObjectTargetModulesSourceFileAutoComplete
2555 {
2556 public:
2557     CommandObjectTargetModulesDumpLineTable (CommandInterpreter &interpreter) :
2558     CommandObjectTargetModulesSourceFileAutoComplete (interpreter,
2559                                                       "target modules dump line-table",
2560                                                       "Dump the line table for one or more compilation units.",
2561                                                       NULL,
2562                                                       eCommandRequiresTarget)
2563     {
2564     }
2565 
2566     virtual
2567     ~CommandObjectTargetModulesDumpLineTable ()
2568     {
2569     }
2570 
2571 protected:
2572     virtual bool
2573     DoExecute (Args& command,
2574              CommandReturnObject &result)
2575     {
2576         Target *target = m_exe_ctx.GetTargetPtr();
2577         uint32_t total_num_dumped = 0;
2578 
2579         uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2580         result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2581         result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2582 
2583         if (command.GetArgumentCount() == 0)
2584         {
2585             result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str());
2586             result.SetStatus (eReturnStatusFailed);
2587         }
2588         else
2589         {
2590             // Dump specified images (by basename or fullpath)
2591             const char *arg_cstr;
2592             for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2593             {
2594                 FileSpec file_spec(arg_cstr, false);
2595 
2596                 const ModuleList &target_modules = target->GetImages();
2597                 Mutex::Locker modules_locker(target_modules.GetMutex());
2598                 const size_t num_modules = target_modules.GetSize();
2599                 if (num_modules > 0)
2600                 {
2601                     uint32_t num_dumped = 0;
2602                     for (uint32_t i = 0; i<num_modules; ++i)
2603                     {
2604                         if (DumpCompileUnitLineTable (m_interpreter,
2605                                                       result.GetOutputStream(),
2606                                                       target_modules.GetModulePointerAtIndexUnlocked(i),
2607                                                       file_spec,
2608                                                       m_exe_ctx.GetProcessPtr() && m_exe_ctx.GetProcessRef().IsAlive()))
2609                             num_dumped++;
2610                     }
2611                     if (num_dumped == 0)
2612                         result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr);
2613                     else
2614                         total_num_dumped += num_dumped;
2615                 }
2616             }
2617         }
2618 
2619         if (total_num_dumped > 0)
2620             result.SetStatus (eReturnStatusSuccessFinishResult);
2621         else
2622         {
2623             result.AppendError ("no source filenames matched any command arguments");
2624             result.SetStatus (eReturnStatusFailed);
2625         }
2626         return result.Succeeded();
2627     }
2628 };
2629 
2630 
2631 #pragma mark CommandObjectTargetModulesDump
2632 
2633 //----------------------------------------------------------------------
2634 // Dump multi-word command for target modules
2635 //----------------------------------------------------------------------
2636 
2637 class CommandObjectTargetModulesDump : public CommandObjectMultiword
2638 {
2639 public:
2640     //------------------------------------------------------------------
2641     // Constructors and Destructors
2642     //------------------------------------------------------------------
2643     CommandObjectTargetModulesDump(CommandInterpreter &interpreter) :
2644     CommandObjectMultiword (interpreter,
2645                             "target modules dump",
2646                             "A set of commands for dumping information about one or more target modules.",
2647                             "target modules dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]")
2648     {
2649         LoadSubCommand ("symtab",      CommandObjectSP (new CommandObjectTargetModulesDumpSymtab (interpreter)));
2650         LoadSubCommand ("sections",    CommandObjectSP (new CommandObjectTargetModulesDumpSections (interpreter)));
2651         LoadSubCommand ("symfile",     CommandObjectSP (new CommandObjectTargetModulesDumpSymfile (interpreter)));
2652         LoadSubCommand ("line-table",  CommandObjectSP (new CommandObjectTargetModulesDumpLineTable (interpreter)));
2653     }
2654 
2655     virtual
2656     ~CommandObjectTargetModulesDump()
2657     {
2658     }
2659 };
2660 
2661 class CommandObjectTargetModulesAdd : public CommandObjectParsed
2662 {
2663 public:
2664     CommandObjectTargetModulesAdd (CommandInterpreter &interpreter) :
2665         CommandObjectParsed (interpreter,
2666                              "target modules add",
2667                              "Add a new module to the current target's modules.",
2668                              "target modules add [<module>]"),
2669         m_option_group (interpreter),
2670         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.")
2671     {
2672         m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2673         m_option_group.Append (&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2674         m_option_group.Finalize();
2675     }
2676 
2677     virtual
2678     ~CommandObjectTargetModulesAdd ()
2679     {
2680     }
2681 
2682     virtual Options *
2683     GetOptions ()
2684     {
2685         return &m_option_group;
2686     }
2687 
2688     virtual int
2689     HandleArgumentCompletion (Args &input,
2690                               int &cursor_index,
2691                               int &cursor_char_position,
2692                               OptionElementVector &opt_element_vector,
2693                               int match_start_point,
2694                               int max_return_elements,
2695                               bool &word_complete,
2696                               StringList &matches)
2697     {
2698         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2699         completion_str.erase (cursor_char_position);
2700 
2701         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
2702                                                              CommandCompletions::eDiskFileCompletion,
2703                                                              completion_str.c_str(),
2704                                                              match_start_point,
2705                                                              max_return_elements,
2706                                                              NULL,
2707                                                              word_complete,
2708                                                              matches);
2709         return matches.GetSize();
2710     }
2711 
2712 protected:
2713     OptionGroupOptions m_option_group;
2714     OptionGroupUUID m_uuid_option_group;
2715     OptionGroupFile m_symbol_file;
2716 
2717     virtual bool
2718     DoExecute (Args& args,
2719              CommandReturnObject &result)
2720     {
2721         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2722         if (target == NULL)
2723         {
2724             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2725             result.SetStatus (eReturnStatusFailed);
2726             return false;
2727         }
2728         else
2729         {
2730             bool flush = false;
2731 
2732             const size_t argc = args.GetArgumentCount();
2733             if (argc == 0)
2734             {
2735                 if (m_uuid_option_group.GetOptionValue ().OptionWasSet())
2736                 {
2737                     // We are given a UUID only, go locate the file
2738                     ModuleSpec module_spec;
2739                     module_spec.GetUUID() = m_uuid_option_group.GetOptionValue ().GetCurrentValue();
2740                     if (m_symbol_file.GetOptionValue().OptionWasSet())
2741                         module_spec.GetSymbolFileSpec() = m_symbol_file.GetOptionValue().GetCurrentValue();
2742                     if (Symbols::DownloadObjectAndSymbolFile (module_spec))
2743                     {
2744                         ModuleSP module_sp (target->GetSharedModule (module_spec));
2745                         if (module_sp)
2746                         {
2747                             result.SetStatus (eReturnStatusSuccessFinishResult);
2748                             return true;
2749                         }
2750                         else
2751                         {
2752                             StreamString strm;
2753                             module_spec.GetUUID().Dump (&strm);
2754                             if (module_spec.GetFileSpec())
2755                             {
2756                                 if (module_spec.GetSymbolFileSpec())
2757                                 {
2758                                     result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s with path %s and symbol file %s",
2759                                                                   strm.GetString().c_str(),
2760                                                                   module_spec.GetFileSpec().GetPath().c_str(),
2761                                                                   module_spec.GetSymbolFileSpec().GetPath().c_str());
2762                                 }
2763                                 else
2764                                 {
2765                                     result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s with path %s",
2766                                                                   strm.GetString().c_str(),
2767                                                                   module_spec.GetFileSpec().GetPath().c_str());
2768                                 }
2769                             }
2770                             else
2771                             {
2772                                 result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s",
2773                                                               strm.GetString().c_str());
2774                             }
2775                             result.SetStatus (eReturnStatusFailed);
2776                             return false;
2777                         }
2778                     }
2779                     else
2780                     {
2781                         StreamString strm;
2782                         module_spec.GetUUID().Dump (&strm);
2783                         result.AppendErrorWithFormat ("Unable to locate the executable or symbol file with UUID %s", strm.GetString().c_str());
2784                         result.SetStatus (eReturnStatusFailed);
2785                         return false;
2786                     }
2787                 }
2788                 else
2789                 {
2790                     result.AppendError ("one or more executable image paths must be specified");
2791                     result.SetStatus (eReturnStatusFailed);
2792                     return false;
2793                 }
2794             }
2795             else
2796             {
2797                 for (size_t i=0; i<argc; ++i)
2798                 {
2799                     const char *path = args.GetArgumentAtIndex(i);
2800                     if (path)
2801                     {
2802                         FileSpec file_spec(path, true);
2803                         if (file_spec.Exists())
2804                         {
2805                             ModuleSpec module_spec (file_spec);
2806                             if (m_uuid_option_group.GetOptionValue ().OptionWasSet())
2807                                 module_spec.GetUUID() = m_uuid_option_group.GetOptionValue ().GetCurrentValue();
2808                             if (m_symbol_file.GetOptionValue().OptionWasSet())
2809                                 module_spec.GetSymbolFileSpec() = m_symbol_file.GetOptionValue().GetCurrentValue();
2810                             if (!module_spec.GetArchitecture().IsValid())
2811                                 module_spec.GetArchitecture() = target->GetArchitecture();
2812                             Error error;
2813                             ModuleSP module_sp (target->GetSharedModule (module_spec, &error));
2814                             if (!module_sp)
2815                             {
2816                                 const char *error_cstr = error.AsCString();
2817                                 if (error_cstr)
2818                                     result.AppendError (error_cstr);
2819                                 else
2820                                     result.AppendErrorWithFormat ("unsupported module: %s", path);
2821                                 result.SetStatus (eReturnStatusFailed);
2822                                 return false;
2823                             }
2824                             else
2825                             {
2826                                 flush = true;
2827                             }
2828                             result.SetStatus (eReturnStatusSuccessFinishResult);
2829                         }
2830                         else
2831                         {
2832                             char resolved_path[PATH_MAX];
2833                             result.SetStatus (eReturnStatusFailed);
2834                             if (file_spec.GetPath (resolved_path, sizeof(resolved_path)))
2835                             {
2836                                 if (strcmp (resolved_path, path) != 0)
2837                                 {
2838                                     result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", path, resolved_path);
2839                                     break;
2840                                 }
2841                             }
2842                             result.AppendErrorWithFormat ("invalid module path '%s'\n", path);
2843                             break;
2844                         }
2845                     }
2846                 }
2847             }
2848 
2849             if (flush)
2850             {
2851                 ProcessSP process = target->GetProcessSP();
2852                 if (process)
2853                     process->Flush();
2854             }
2855         }
2856 
2857         return result.Succeeded();
2858     }
2859 
2860 };
2861 
2862 class CommandObjectTargetModulesLoad : public CommandObjectTargetModulesModuleAutoComplete
2863 {
2864 public:
2865     CommandObjectTargetModulesLoad (CommandInterpreter &interpreter) :
2866         CommandObjectTargetModulesModuleAutoComplete (interpreter,
2867                                                       "target modules load",
2868                                                       "Set the load addresses for one or more sections in a target module.",
2869                                                       "target modules load [--file <module> --uuid <uuid>] <sect-name> <address> [<sect-name> <address> ....]"),
2870         m_option_group (interpreter),
2871         m_file_option (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName, "Fullpath or basename for module to load.", ""),
2872         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)
2873     {
2874         m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2875         m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2876         m_option_group.Append (&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2877         m_option_group.Finalize();
2878     }
2879 
2880     virtual
2881     ~CommandObjectTargetModulesLoad ()
2882     {
2883     }
2884 
2885     virtual Options *
2886     GetOptions ()
2887     {
2888         return &m_option_group;
2889     }
2890 
2891 protected:
2892     virtual bool
2893     DoExecute (Args& args,
2894              CommandReturnObject &result)
2895     {
2896         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2897         if (target == NULL)
2898         {
2899             result.AppendError ("invalid target, create a debug target using the 'target create' command");
2900             result.SetStatus (eReturnStatusFailed);
2901             return false;
2902         }
2903         else
2904         {
2905             const size_t argc = args.GetArgumentCount();
2906             ModuleSpec module_spec;
2907             bool search_using_module_spec = false;
2908             if (m_file_option.GetOptionValue().OptionWasSet())
2909             {
2910                 search_using_module_spec = true;
2911                 const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
2912                 const bool use_global_module_list = true;
2913                 ModuleList module_list;
2914                 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, use_global_module_list);
2915                 if (num_matches == 1)
2916                 {
2917                     module_spec.GetFileSpec() = module_list.GetModuleAtIndex(0)->GetFileSpec();
2918                 }
2919                 else if (num_matches > 1 )
2920                 {
2921                     search_using_module_spec = false;
2922                     result.AppendErrorWithFormat ("more than 1 module matched by name '%s'\n", arg_cstr);
2923                     result.SetStatus (eReturnStatusFailed);
2924                 }
2925                 else
2926                 {
2927                     search_using_module_spec = false;
2928                     result.AppendErrorWithFormat ("no object file for module '%s'\n", arg_cstr);
2929                     result.SetStatus (eReturnStatusFailed);
2930                 }
2931             }
2932 
2933             if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2934             {
2935                 search_using_module_spec = true;
2936                 module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue();
2937             }
2938 
2939             if (search_using_module_spec)
2940             {
2941                 ModuleList matching_modules;
2942                 const size_t num_matches = target->GetImages().FindModules (module_spec, matching_modules);
2943 
2944                 char path[PATH_MAX];
2945                 if (num_matches == 1)
2946                 {
2947                     Module *module = matching_modules.GetModulePointerAtIndex(0);
2948                     if (module)
2949                     {
2950                         ObjectFile *objfile = module->GetObjectFile();
2951                         if (objfile)
2952                         {
2953                             SectionList *section_list = module->GetSectionList();
2954                             if (section_list)
2955                             {
2956                                 bool changed = false;
2957                                 if (argc == 0)
2958                                 {
2959                                     if (m_slide_option.GetOptionValue().OptionWasSet())
2960                                     {
2961                                         const addr_t slide = m_slide_option.GetOptionValue().GetCurrentValue();
2962                                         const bool slide_is_offset = true;
2963                                         module->SetLoadAddress (*target, slide, slide_is_offset, changed);
2964                                     }
2965                                     else
2966                                     {
2967                                         result.AppendError ("one or more section name + load address pair must be specified");
2968                                         result.SetStatus (eReturnStatusFailed);
2969                                         return false;
2970                                     }
2971                                 }
2972                                 else
2973                                 {
2974                                     if (m_slide_option.GetOptionValue().OptionWasSet())
2975                                     {
2976                                         result.AppendError ("The \"--slide <offset>\" option can't be used in conjunction with setting section load addresses.\n");
2977                                         result.SetStatus (eReturnStatusFailed);
2978                                         return false;
2979                                     }
2980 
2981                                     for (size_t i=0; i<argc; i += 2)
2982                                     {
2983                                         const char *sect_name = args.GetArgumentAtIndex(i);
2984                                         const char *load_addr_cstr = args.GetArgumentAtIndex(i+1);
2985                                         if (sect_name && load_addr_cstr)
2986                                         {
2987                                             ConstString const_sect_name(sect_name);
2988                                             bool success = false;
2989                                             addr_t load_addr = StringConvert::ToUInt64(load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
2990                                             if (success)
2991                                             {
2992                                                 SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
2993                                                 if (section_sp)
2994                                                 {
2995                                                     if (section_sp->IsThreadSpecific())
2996                                                     {
2997                                                         result.AppendErrorWithFormat ("thread specific sections are not yet supported (section '%s')\n", sect_name);
2998                                                         result.SetStatus (eReturnStatusFailed);
2999                                                         break;
3000                                                     }
3001                                                     else
3002                                                     {
3003                                                         if (target->GetSectionLoadList().SetSectionLoadAddress (section_sp, load_addr))
3004                                                             changed = true;
3005                                                         result.AppendMessageWithFormat("section '%s' loaded at 0x%" PRIx64 "\n", sect_name, load_addr);
3006                                                     }
3007                                                 }
3008                                                 else
3009                                                 {
3010                                                     result.AppendErrorWithFormat ("no section found that matches the section name '%s'\n", sect_name);
3011                                                     result.SetStatus (eReturnStatusFailed);
3012                                                     break;
3013                                                 }
3014                                             }
3015                                             else
3016                                             {
3017                                                 result.AppendErrorWithFormat ("invalid load address string '%s'\n", load_addr_cstr);
3018                                                 result.SetStatus (eReturnStatusFailed);
3019                                                 break;
3020                                             }
3021                                         }
3022                                         else
3023                                         {
3024                                             if (sect_name)
3025                                                 result.AppendError ("section names must be followed by a load address.\n");
3026                                             else
3027                                                 result.AppendError ("one or more section name + load address pair must be specified.\n");
3028                                             result.SetStatus (eReturnStatusFailed);
3029                                             break;
3030                                         }
3031                                     }
3032                                 }
3033 
3034                                 if (changed)
3035                                 {
3036                                     target->ModulesDidLoad (matching_modules);
3037                                     Process *process = m_exe_ctx.GetProcessPtr();
3038                                     if (process)
3039                                         process->Flush();
3040                                 }
3041                             }
3042                             else
3043                             {
3044                                 module->GetFileSpec().GetPath (path, sizeof(path));
3045                                 result.AppendErrorWithFormat ("no sections in object file '%s'\n", path);
3046                                 result.SetStatus (eReturnStatusFailed);
3047                             }
3048                         }
3049                         else
3050                         {
3051                             module->GetFileSpec().GetPath (path, sizeof(path));
3052                             result.AppendErrorWithFormat ("no object file for module '%s'\n", path);
3053                             result.SetStatus (eReturnStatusFailed);
3054                         }
3055                     }
3056                     else
3057                     {
3058                         FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
3059                         if (module_spec_file)
3060                         {
3061                             module_spec_file->GetPath (path, sizeof(path));
3062                             result.AppendErrorWithFormat ("invalid module '%s'.\n", path);
3063                         }
3064                         else
3065                             result.AppendError ("no module spec");
3066                         result.SetStatus (eReturnStatusFailed);
3067                     }
3068                 }
3069                 else
3070                 {
3071                     std::string uuid_str;
3072 
3073                     if (module_spec.GetFileSpec())
3074                         module_spec.GetFileSpec().GetPath (path, sizeof(path));
3075                     else
3076                         path[0] = '\0';
3077 
3078                     if (module_spec.GetUUIDPtr())
3079                         uuid_str = module_spec.GetUUID().GetAsString();
3080                     if (num_matches > 1)
3081                     {
3082                         result.AppendErrorWithFormat ("multiple modules match%s%s%s%s:\n",
3083                                                       path[0] ? " file=" : "",
3084                                                       path,
3085                                                       !uuid_str.empty() ? " uuid=" : "",
3086                                                       uuid_str.c_str());
3087                         for (size_t i=0; i<num_matches; ++i)
3088                         {
3089                             if (matching_modules.GetModulePointerAtIndex(i)->GetFileSpec().GetPath (path, sizeof(path)))
3090                                 result.AppendMessageWithFormat("%s\n", path);
3091                         }
3092                     }
3093                     else
3094                     {
3095                         result.AppendErrorWithFormat ("no modules were found  that match%s%s%s%s.\n",
3096                                                       path[0] ? " file=" : "",
3097                                                       path,
3098                                                       !uuid_str.empty() ? " uuid=" : "",
3099                                                       uuid_str.c_str());
3100                     }
3101                     result.SetStatus (eReturnStatusFailed);
3102                 }
3103             }
3104             else
3105             {
3106                 result.AppendError ("either the \"--file <module>\" or the \"--uuid <uuid>\" option must be specified.\n");
3107                 result.SetStatus (eReturnStatusFailed);
3108                 return false;
3109             }
3110         }
3111         return result.Succeeded();
3112     }
3113 
3114     OptionGroupOptions m_option_group;
3115     OptionGroupUUID m_uuid_option_group;
3116     OptionGroupString m_file_option;
3117     OptionGroupUInt64 m_slide_option;
3118 };
3119 
3120 //----------------------------------------------------------------------
3121 // List images with associated information
3122 //----------------------------------------------------------------------
3123 class CommandObjectTargetModulesList : public CommandObjectParsed
3124 {
3125 public:
3126     class CommandOptions : public Options
3127     {
3128     public:
3129         CommandOptions (CommandInterpreter &interpreter) :
3130             Options(interpreter),
3131             m_format_array(),
3132             m_use_global_module_list (false),
3133             m_module_addr (LLDB_INVALID_ADDRESS)
3134         {
3135         }
3136 
3137         virtual
3138         ~CommandOptions ()
3139         {
3140         }
3141 
3142         virtual Error
3143         SetOptionValue (uint32_t option_idx, const char *option_arg)
3144         {
3145             Error error;
3146 
3147             const int short_option = m_getopt_table[option_idx].val;
3148             if (short_option == 'g')
3149             {
3150                 m_use_global_module_list = true;
3151             }
3152             else if (short_option == 'a')
3153             {
3154                 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
3155                 m_module_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
3156             }
3157             else
3158             {
3159                 unsigned long width = 0;
3160                 if (option_arg)
3161                     width = strtoul (option_arg, NULL, 0);
3162                 m_format_array.push_back(std::make_pair(short_option, width));
3163             }
3164             return error;
3165         }
3166 
3167         void
3168         OptionParsingStarting ()
3169         {
3170             m_format_array.clear();
3171             m_use_global_module_list = false;
3172             m_module_addr = LLDB_INVALID_ADDRESS;
3173         }
3174 
3175         const OptionDefinition*
3176         GetDefinitions ()
3177         {
3178             return g_option_table;
3179         }
3180 
3181         // Options table: Required for subclasses of Options.
3182 
3183         static OptionDefinition g_option_table[];
3184 
3185         // Instance variables to hold the values for command options.
3186         typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection;
3187         FormatWidthCollection m_format_array;
3188         bool m_use_global_module_list;
3189         lldb::addr_t m_module_addr;
3190     };
3191 
3192     CommandObjectTargetModulesList (CommandInterpreter &interpreter) :
3193         CommandObjectParsed (interpreter,
3194                              "target modules list",
3195                              "List current executable and dependent shared library images.",
3196                              "target modules list [<cmd-options>]"),
3197         m_options (interpreter)
3198     {
3199     }
3200 
3201     virtual
3202     ~CommandObjectTargetModulesList ()
3203     {
3204     }
3205 
3206     virtual
3207     Options *
3208     GetOptions ()
3209     {
3210         return &m_options;
3211     }
3212 
3213 protected:
3214     virtual bool
3215     DoExecute (Args& command,
3216              CommandReturnObject &result)
3217     {
3218         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3219         const bool use_global_module_list = m_options.m_use_global_module_list;
3220         // Define a local module list here to ensure it lives longer than any "locker"
3221         // object which might lock its contents below (through the "module_list_ptr"
3222         // variable).
3223         ModuleList module_list;
3224         if (target == NULL && use_global_module_list == false)
3225         {
3226             result.AppendError ("invalid target, create a debug target using the 'target create' command");
3227             result.SetStatus (eReturnStatusFailed);
3228             return false;
3229         }
3230         else
3231         {
3232             if (target)
3233             {
3234                 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3235                 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3236                 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3237             }
3238             // Dump all sections for all modules images
3239             Stream &strm = result.GetOutputStream();
3240 
3241             if (m_options.m_module_addr != LLDB_INVALID_ADDRESS)
3242             {
3243                 if (target)
3244                 {
3245                     Address module_address;
3246                     if (module_address.SetLoadAddress(m_options.m_module_addr, target))
3247                     {
3248                         ModuleSP module_sp (module_address.GetModule());
3249                         if (module_sp)
3250                         {
3251                             PrintModule (target, module_sp.get(), 0, strm);
3252                             result.SetStatus (eReturnStatusSuccessFinishResult);
3253                         }
3254                         else
3255                         {
3256                             result.AppendErrorWithFormat ("Couldn't find module matching address: 0x%" PRIx64 ".", m_options.m_module_addr);
3257                             result.SetStatus (eReturnStatusFailed);
3258                         }
3259                     }
3260                     else
3261                     {
3262                         result.AppendErrorWithFormat ("Couldn't find module containing address: 0x%" PRIx64 ".", m_options.m_module_addr);
3263                         result.SetStatus (eReturnStatusFailed);
3264                     }
3265                 }
3266                 else
3267                 {
3268                     result.AppendError ("Can only look up modules by address with a valid target.");
3269                     result.SetStatus (eReturnStatusFailed);
3270                 }
3271                 return result.Succeeded();
3272             }
3273 
3274             size_t num_modules = 0;
3275             Mutex::Locker locker;      // This locker will be locked on the mutex in module_list_ptr if it is non-NULL.
3276                                        // Otherwise it will lock the AllocationModuleCollectionMutex when accessing
3277                                        // the global module list directly.
3278             const ModuleList *module_list_ptr = NULL;
3279             const size_t argc = command.GetArgumentCount();
3280             if (argc == 0)
3281             {
3282                 if (use_global_module_list)
3283                 {
3284                     locker.Lock (Module::GetAllocationModuleCollectionMutex());
3285                     num_modules = Module::GetNumberAllocatedModules();
3286                 }
3287                 else
3288                 {
3289                     module_list_ptr = &target->GetImages();
3290                 }
3291             }
3292             else
3293             {
3294                 for (size_t i=0; i<argc; ++i)
3295                 {
3296                     // Dump specified images (by basename or fullpath)
3297                     const char *arg_cstr = command.GetArgumentAtIndex(i);
3298                     const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, use_global_module_list);
3299                     if (num_matches == 0)
3300                     {
3301                         if (argc == 1)
3302                         {
3303                             result.AppendErrorWithFormat ("no modules found that match '%s'", arg_cstr);
3304                             result.SetStatus (eReturnStatusFailed);
3305                             return false;
3306                         }
3307                     }
3308                 }
3309 
3310                 module_list_ptr = &module_list;
3311             }
3312 
3313             if (module_list_ptr != NULL)
3314             {
3315                 locker.Lock(module_list_ptr->GetMutex());
3316                 num_modules = module_list_ptr->GetSize();
3317             }
3318 
3319             if (num_modules > 0)
3320             {
3321                 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
3322                 {
3323                     ModuleSP module_sp;
3324                     Module *module;
3325                     if (module_list_ptr)
3326                     {
3327                         module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
3328                         module = module_sp.get();
3329                     }
3330                     else
3331                     {
3332                         module = Module::GetAllocatedModuleAtIndex(image_idx);
3333                         module_sp = module->shared_from_this();
3334                     }
3335 
3336                     const size_t indent = strm.Printf("[%3u] ", image_idx);
3337                     PrintModule (target, module, indent, strm);
3338 
3339                 }
3340                 result.SetStatus (eReturnStatusSuccessFinishResult);
3341             }
3342             else
3343             {
3344                 if (argc)
3345                 {
3346                     if (use_global_module_list)
3347                         result.AppendError ("the global module list has no matching modules");
3348                     else
3349                         result.AppendError ("the target has no matching modules");
3350                 }
3351                 else
3352                 {
3353                     if (use_global_module_list)
3354                         result.AppendError ("the global module list is empty");
3355                     else
3356                         result.AppendError ("the target has no associated executable images");
3357                 }
3358                 result.SetStatus (eReturnStatusFailed);
3359                 return false;
3360             }
3361         }
3362         return result.Succeeded();
3363     }
3364 
3365     void
3366     PrintModule (Target *target, Module *module, int indent, Stream &strm)
3367     {
3368 
3369         if (module == NULL)
3370         {
3371             strm.PutCString("Null module");
3372             return;
3373         }
3374 
3375         bool dump_object_name = false;
3376         if (m_options.m_format_array.empty())
3377         {
3378             m_options.m_format_array.push_back(std::make_pair('u', 0));
3379             m_options.m_format_array.push_back(std::make_pair('h', 0));
3380             m_options.m_format_array.push_back(std::make_pair('f', 0));
3381             m_options.m_format_array.push_back(std::make_pair('S', 0));
3382         }
3383         const size_t num_entries = m_options.m_format_array.size();
3384         bool print_space = false;
3385         for (size_t i=0; i<num_entries; ++i)
3386         {
3387             if (print_space)
3388                 strm.PutChar(' ');
3389             print_space = true;
3390             const char format_char = m_options.m_format_array[i].first;
3391             uint32_t width = m_options.m_format_array[i].second;
3392             switch (format_char)
3393             {
3394                 case 'A':
3395                     DumpModuleArchitecture (strm, module, false, width);
3396                     break;
3397 
3398                 case 't':
3399                     DumpModuleArchitecture (strm, module, true, width);
3400                     break;
3401 
3402                 case 'f':
3403                     DumpFullpath (strm, &module->GetFileSpec(), width);
3404                     dump_object_name = true;
3405                     break;
3406 
3407                 case 'd':
3408                     DumpDirectory (strm, &module->GetFileSpec(), width);
3409                     break;
3410 
3411                 case 'b':
3412                     DumpBasename (strm, &module->GetFileSpec(), width);
3413                     dump_object_name = true;
3414                     break;
3415 
3416                 case 'h':
3417                 case 'o':
3418                     // Image header address
3419                     {
3420                         uint32_t addr_nibble_width = target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16;
3421 
3422                         ObjectFile *objfile = module->GetObjectFile ();
3423                         if (objfile)
3424                         {
3425                             Address header_addr(objfile->GetHeaderAddress());
3426                             if (header_addr.IsValid())
3427                             {
3428                                 if (target && !target->GetSectionLoadList().IsEmpty())
3429                                 {
3430                                     lldb::addr_t header_load_addr = header_addr.GetLoadAddress (target);
3431                                     if (header_load_addr == LLDB_INVALID_ADDRESS)
3432                                     {
3433                                         header_addr.Dump (&strm, target, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleFileAddress);
3434                                     }
3435                                     else
3436                                     {
3437                                         if (format_char == 'o')
3438                                         {
3439                                             // Show the offset of slide for the image
3440                                             strm.Printf ("0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width, header_load_addr - header_addr.GetFileAddress());
3441                                         }
3442                                         else
3443                                         {
3444                                             // Show the load address of the image
3445                                             strm.Printf ("0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width, header_load_addr);
3446                                         }
3447                                     }
3448                                     break;
3449                                 }
3450                                 // The address was valid, but the image isn't loaded, output the address in an appropriate format
3451                                 header_addr.Dump (&strm, target, Address::DumpStyleFileAddress);
3452                                 break;
3453                             }
3454                         }
3455                         strm.Printf ("%*s", addr_nibble_width + 2, "");
3456                     }
3457                     break;
3458                 case 'r':
3459                     {
3460                         size_t ref_count = 0;
3461                         ModuleSP module_sp (module->shared_from_this());
3462                         if (module_sp)
3463                         {
3464                             // Take one away to make sure we don't count our local "module_sp"
3465                             ref_count = module_sp.use_count() - 1;
3466                         }
3467                         if (width)
3468                             strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count);
3469                         else
3470                             strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count);
3471                     }
3472                     break;
3473 
3474                 case 's':
3475                 case 'S':
3476                     {
3477                         const SymbolVendor *symbol_vendor = module->GetSymbolVendor();
3478                         if (symbol_vendor)
3479                         {
3480                             const FileSpec symfile_spec = symbol_vendor->GetMainFileSpec();
3481                             if (format_char == 'S')
3482                             {
3483                                 // Dump symbol file only if different from module file
3484                                 if (!symfile_spec || symfile_spec == module->GetFileSpec())
3485                                 {
3486                                     print_space = false;
3487                                     break;
3488                                 }
3489                                 // Add a newline and indent past the index
3490                                 strm.Printf ("\n%*s", indent, "");
3491                             }
3492                             DumpFullpath (strm, &symfile_spec, width);
3493                             dump_object_name = true;
3494                             break;
3495                         }
3496                         strm.Printf("%.*s", width, "<NONE>");
3497                     }
3498                     break;
3499 
3500                 case 'm':
3501                     module->GetModificationTime().Dump(&strm, width);
3502                     break;
3503 
3504                 case 'p':
3505                     strm.Printf("%p", static_cast<void*>(module));
3506                     break;
3507 
3508                 case 'u':
3509                     DumpModuleUUID(strm, module);
3510                     break;
3511 
3512                 default:
3513                     break;
3514             }
3515 
3516         }
3517         if (dump_object_name)
3518         {
3519             const char *object_name = module->GetObjectName().GetCString();
3520             if (object_name)
3521                 strm.Printf ("(%s)", object_name);
3522         }
3523         strm.EOL();
3524     }
3525 
3526     CommandOptions m_options;
3527 };
3528 
3529 OptionDefinition
3530 CommandObjectTargetModulesList::CommandOptions::g_option_table[] =
3531 {
3532     { LLDB_OPT_SET_1, false, "address",    'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Display the image at this address."},
3533     { LLDB_OPT_SET_1, false, "arch",       'A', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the architecture when listing images."},
3534     { LLDB_OPT_SET_1, false, "triple",     't', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the triple when listing images."},
3535     { 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."},
3536     { 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)."},
3537     { LLDB_OPT_SET_1, false, "uuid",       'u', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone,    "Display the UUID when listing images."},
3538     { LLDB_OPT_SET_1, false, "fullpath",   'f', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the fullpath to the image object file."},
3539     { LLDB_OPT_SET_1, false, "directory",  'd', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the directory with optional width for the image object file."},
3540     { LLDB_OPT_SET_1, false, "basename",   'b', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the basename with optional width for the image object file."},
3541     { LLDB_OPT_SET_1, false, "symfile",    's', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the fullpath to the image symbol file with optional width."},
3542     { 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."},
3543     { LLDB_OPT_SET_1, false, "mod-time",   'm', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the modification time with optional width of the module."},
3544     { 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."},
3545     { LLDB_OPT_SET_1, false, "pointer",    'p', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeNone,    "Display the module pointer."},
3546     { 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."},
3547     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
3548 };
3549 
3550 #pragma mark CommandObjectTargetModulesShowUnwind
3551 
3552 //----------------------------------------------------------------------
3553 // Lookup unwind information in images
3554 //----------------------------------------------------------------------
3555 
3556 class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed
3557 {
3558 public:
3559 
3560     enum
3561     {
3562         eLookupTypeInvalid = -1,
3563         eLookupTypeAddress = 0,
3564         eLookupTypeSymbol,
3565         eLookupTypeFunction,
3566         eLookupTypeFunctionOrSymbol,
3567         kNumLookupTypes
3568     };
3569 
3570     class CommandOptions : public Options
3571     {
3572     public:
3573 
3574         CommandOptions (CommandInterpreter &interpreter) :
3575             Options(interpreter),
3576             m_type(eLookupTypeInvalid),
3577             m_str(),
3578             m_addr(LLDB_INVALID_ADDRESS)
3579         {
3580         }
3581 
3582         virtual
3583         ~CommandOptions ()
3584         {
3585         }
3586 
3587         virtual Error
3588         SetOptionValue (uint32_t option_idx, const char *option_arg)
3589         {
3590             Error error;
3591 
3592             const int short_option = m_getopt_table[option_idx].val;
3593 
3594             switch (short_option)
3595             {
3596                 case 'a':
3597                 {
3598                     ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
3599                     m_str = option_arg;
3600                     m_type = eLookupTypeAddress;
3601                     m_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
3602                     if (m_addr == LLDB_INVALID_ADDRESS)
3603                         error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg);
3604                     break;
3605                 }
3606 
3607                 case 'n':
3608                 {
3609                     m_str = option_arg;
3610                     m_type = eLookupTypeFunctionOrSymbol;
3611                     break;
3612                 }
3613 
3614                 default:
3615                     error.SetErrorStringWithFormat ("unrecognized option %c.", short_option);
3616                     break;
3617             }
3618 
3619             return error;
3620         }
3621 
3622         void
3623         OptionParsingStarting ()
3624         {
3625             m_type = eLookupTypeInvalid;
3626             m_str.clear();
3627             m_addr = LLDB_INVALID_ADDRESS;
3628         }
3629 
3630         const OptionDefinition*
3631         GetDefinitions ()
3632         {
3633             return g_option_table;
3634         }
3635 
3636         // Options table: Required for subclasses of Options.
3637 
3638         static OptionDefinition g_option_table[];
3639 
3640         // Instance variables to hold the values for command options.
3641 
3642         int             m_type;         // Should be a eLookupTypeXXX enum after parsing options
3643         std::string     m_str;          // Holds name lookup
3644         lldb::addr_t    m_addr;         // Holds the address to lookup
3645     };
3646 
3647     CommandObjectTargetModulesShowUnwind (CommandInterpreter &interpreter) :
3648         CommandObjectParsed (interpreter,
3649                              "target modules show-unwind",
3650                              "Show synthesized unwind instructions for a function.",
3651                              NULL,
3652                              eCommandRequiresTarget        |
3653                              eCommandRequiresProcess       |
3654                              eCommandProcessMustBeLaunched |
3655                              eCommandProcessMustBePaused   ),
3656         m_options (interpreter)
3657     {
3658     }
3659 
3660     virtual
3661     ~CommandObjectTargetModulesShowUnwind ()
3662     {
3663     }
3664 
3665     virtual
3666     Options *
3667     GetOptions ()
3668     {
3669         return &m_options;
3670     }
3671 
3672 protected:
3673     bool
3674     DoExecute (Args& command,
3675              CommandReturnObject &result)
3676     {
3677         Target *target = m_exe_ctx.GetTargetPtr();
3678         Process *process = m_exe_ctx.GetProcessPtr();
3679         ABI *abi = NULL;
3680         if (process)
3681           abi = process->GetABI().get();
3682 
3683         if (process == NULL)
3684         {
3685             result.AppendError ("You must have a process running to use this command.");
3686             result.SetStatus (eReturnStatusFailed);
3687             return false;
3688         }
3689 
3690         ThreadList threads(process->GetThreadList());
3691         if (threads.GetSize() == 0)
3692         {
3693             result.AppendError ("The process must be paused to use this command.");
3694             result.SetStatus (eReturnStatusFailed);
3695             return false;
3696         }
3697 
3698         ThreadSP thread(threads.GetThreadAtIndex(0));
3699         if (thread.get() == NULL)
3700         {
3701             result.AppendError ("The process must be paused to use this command.");
3702             result.SetStatus (eReturnStatusFailed);
3703             return false;
3704         }
3705 
3706         SymbolContextList sc_list;
3707 
3708         if (m_options.m_type == eLookupTypeFunctionOrSymbol)
3709         {
3710             ConstString function_name (m_options.m_str.c_str());
3711             target->GetImages().FindFunctions (function_name, eFunctionNameTypeAuto, true, false, true, sc_list);
3712         }
3713         else if (m_options.m_type == eLookupTypeAddress && target)
3714         {
3715             Address addr;
3716             if (target->GetSectionLoadList().ResolveLoadAddress (m_options.m_addr, addr))
3717             {
3718                 SymbolContext sc;
3719                 ModuleSP module_sp (addr.GetModule());
3720                 module_sp->ResolveSymbolContextForAddress (addr, eSymbolContextEverything, sc);
3721                 if (sc.function || sc.symbol)
3722                 {
3723                     sc_list.Append(sc);
3724                 }
3725             }
3726         }
3727         else
3728         {
3729             result.AppendError ("address-expression or function name option must be specified.");
3730             result.SetStatus (eReturnStatusFailed);
3731             return false;
3732         }
3733 
3734         size_t num_matches = sc_list.GetSize();
3735         if (num_matches == 0)
3736         {
3737             result.AppendErrorWithFormat ("no unwind data found that matches '%s'.", m_options.m_str.c_str());
3738             result.SetStatus (eReturnStatusFailed);
3739             return false;
3740         }
3741 
3742         for (uint32_t idx = 0; idx < num_matches; idx++)
3743         {
3744             SymbolContext sc;
3745             sc_list.GetContextAtIndex(idx, sc);
3746             if (sc.symbol == NULL && sc.function == NULL)
3747                 continue;
3748             if (sc.module_sp.get() == NULL || sc.module_sp->GetObjectFile() == NULL)
3749                 continue;
3750             AddressRange range;
3751             if (!sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range))
3752                 continue;
3753             if (!range.GetBaseAddress().IsValid())
3754                 continue;
3755             ConstString funcname(sc.GetFunctionName());
3756             if (funcname.IsEmpty())
3757                 continue;
3758             addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
3759             if (abi)
3760                 start_addr = abi->FixCodeAddress(start_addr);
3761 
3762             FuncUnwindersSP func_unwinders_sp (sc.module_sp->GetObjectFile()->GetUnwindTable().GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
3763             if (func_unwinders_sp.get() == NULL)
3764                 continue;
3765 
3766             result.GetOutputStream().Printf("UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
3767 
3768             UnwindPlanSP non_callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread.get(), -1);
3769             if (non_callsite_unwind_plan.get())
3770             {
3771                 result.GetOutputStream().Printf("Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n", non_callsite_unwind_plan->GetSourceName().AsCString());
3772             }
3773             UnwindPlanSP callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(*target, -1);
3774             if (callsite_unwind_plan.get())
3775             {
3776                 result.GetOutputStream().Printf("Synchronous (restricted to call-sites) UnwindPlan is '%s'\n", callsite_unwind_plan->GetSourceName().AsCString());
3777             }
3778             UnwindPlanSP fast_unwind_plan = func_unwinders_sp->GetUnwindPlanFastUnwind(*thread.get());
3779             if (fast_unwind_plan.get())
3780             {
3781                 result.GetOutputStream().Printf("Fast UnwindPlan is '%s'\n", fast_unwind_plan->GetSourceName().AsCString());
3782             }
3783 
3784             result.GetOutputStream().Printf("\n");
3785 
3786             UnwindPlanSP assembly_sp = func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread.get(), 0);
3787             if (assembly_sp)
3788             {
3789                 result.GetOutputStream().Printf("Assembly language inspection UnwindPlan:\n");
3790                 assembly_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3791                 result.GetOutputStream().Printf("\n");
3792             }
3793 
3794 
3795             UnwindPlanSP ehframe_sp = func_unwinders_sp->GetEHFrameUnwindPlan(*target, 0);
3796             if (ehframe_sp)
3797             {
3798                 result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3799                 ehframe_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3800                 result.GetOutputStream().Printf("\n");
3801             }
3802 
3803             UnwindPlanSP ehframe_augmented_sp = func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread.get(), 0);
3804             if (ehframe_augmented_sp)
3805             {
3806                 result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3807                 ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3808                 result.GetOutputStream().Printf("\n");
3809             }
3810 
3811             UnwindPlanSP compact_unwind_sp = func_unwinders_sp->GetCompactUnwindUnwindPlan(*target, 0);
3812             if (compact_unwind_sp)
3813             {
3814                 result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3815                 compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3816                 result.GetOutputStream().Printf("\n");
3817             }
3818 
3819             if (fast_unwind_plan)
3820             {
3821                 result.GetOutputStream().Printf("Fast UnwindPlan:\n");
3822                 fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3823                 result.GetOutputStream().Printf("\n");
3824             }
3825 
3826             ABISP abi_sp = process->GetABI();
3827             if (abi_sp)
3828             {
3829                 UnwindPlan arch_default(lldb::eRegisterKindGeneric);
3830                 if (abi_sp->CreateDefaultUnwindPlan (arch_default))
3831                 {
3832                     result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3833                     arch_default.Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3834                     result.GetOutputStream().Printf("\n");
3835                 }
3836 
3837                 UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
3838                 if (abi_sp->CreateFunctionEntryUnwindPlan (arch_entry))
3839                 {
3840                     result.GetOutputStream().Printf("Arch default at entry point UnwindPlan:\n");
3841                     arch_entry.Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3842                     result.GetOutputStream().Printf("\n");
3843                 }
3844             }
3845 
3846             result.GetOutputStream().Printf ("\n");
3847         }
3848         return result.Succeeded();
3849     }
3850 
3851     CommandOptions m_options;
3852 };
3853 
3854 OptionDefinition
3855 CommandObjectTargetModulesShowUnwind::CommandOptions::g_option_table[] =
3856 {
3857     { LLDB_OPT_SET_1,   false,  "name",       'n', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name."},
3858     { LLDB_OPT_SET_2,   false,  "address",    'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address"},
3859     { 0,                false, NULL,           0, 0,                 NULL, NULL, 0, eArgTypeNone, NULL }
3860 };
3861 
3862 //----------------------------------------------------------------------
3863 // Lookup information in images
3864 //----------------------------------------------------------------------
3865 class CommandObjectTargetModulesLookup : public CommandObjectParsed
3866 {
3867 public:
3868     enum
3869     {
3870         eLookupTypeInvalid = -1,
3871         eLookupTypeAddress = 0,
3872         eLookupTypeSymbol,
3873         eLookupTypeFileLine,    // Line is optional
3874         eLookupTypeFunction,
3875         eLookupTypeFunctionOrSymbol,
3876         eLookupTypeType,
3877         kNumLookupTypes
3878     };
3879 
3880     class CommandOptions : public Options
3881     {
3882     public:
3883         CommandOptions (CommandInterpreter &interpreter) :
3884         Options(interpreter)
3885         {
3886             OptionParsingStarting();
3887         }
3888 
3889         virtual
3890         ~CommandOptions ()
3891         {
3892         }
3893 
3894         virtual Error
3895         SetOptionValue (uint32_t option_idx, const char *option_arg)
3896         {
3897             Error error;
3898 
3899             const int short_option = m_getopt_table[option_idx].val;
3900 
3901             switch (short_option)
3902             {
3903                 case 'a':
3904                     {
3905                         m_type = eLookupTypeAddress;
3906                         ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
3907                         m_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
3908                     }
3909                     break;
3910 
3911                 case 'o':
3912                     m_offset = StringConvert::ToUInt64(option_arg, LLDB_INVALID_ADDRESS);
3913                     if (m_offset == LLDB_INVALID_ADDRESS)
3914                         error.SetErrorStringWithFormat ("invalid offset string '%s'", option_arg);
3915                     break;
3916 
3917                 case 's':
3918                     m_str = option_arg;
3919                     m_type = eLookupTypeSymbol;
3920                     break;
3921 
3922                 case 'f':
3923                     m_file.SetFile (option_arg, false);
3924                     m_type = eLookupTypeFileLine;
3925                     break;
3926 
3927                 case 'i':
3928                     m_include_inlines = false;
3929                     break;
3930 
3931                 case 'l':
3932                     m_line_number = StringConvert::ToUInt32(option_arg, UINT32_MAX);
3933                     if (m_line_number == UINT32_MAX)
3934                         error.SetErrorStringWithFormat ("invalid line number string '%s'", option_arg);
3935                     else if (m_line_number == 0)
3936                         error.SetErrorString ("zero is an invalid line number");
3937                     m_type = eLookupTypeFileLine;
3938                     break;
3939 
3940                 case 'F':
3941                     m_str = option_arg;
3942                     m_type = eLookupTypeFunction;
3943                     break;
3944 
3945                 case 'n':
3946                     m_str = option_arg;
3947                     m_type = eLookupTypeFunctionOrSymbol;
3948                     break;
3949 
3950                 case 't':
3951                     m_str = option_arg;
3952                     m_type = eLookupTypeType;
3953                     break;
3954 
3955                 case 'v':
3956                     m_verbose = 1;
3957                     break;
3958 
3959                 case 'A':
3960                     m_print_all = true;
3961                     break;
3962 
3963                 case 'r':
3964                     m_use_regex = true;
3965                     break;
3966             }
3967 
3968             return error;
3969         }
3970 
3971         void
3972         OptionParsingStarting ()
3973         {
3974             m_type = eLookupTypeInvalid;
3975             m_str.clear();
3976             m_file.Clear();
3977             m_addr = LLDB_INVALID_ADDRESS;
3978             m_offset = 0;
3979             m_line_number = 0;
3980             m_use_regex = false;
3981             m_include_inlines = true;
3982             m_verbose = false;
3983             m_print_all = false;
3984         }
3985 
3986         const OptionDefinition*
3987         GetDefinitions ()
3988         {
3989             return g_option_table;
3990         }
3991 
3992         // Options table: Required for subclasses of Options.
3993 
3994         static OptionDefinition g_option_table[];
3995         int             m_type;         // Should be a eLookupTypeXXX enum after parsing options
3996         std::string     m_str;          // Holds name lookup
3997         FileSpec        m_file;         // Files for file lookups
3998         lldb::addr_t    m_addr;         // Holds the address to lookup
3999         lldb::addr_t    m_offset;       // Subtract this offset from m_addr before doing lookups.
4000         uint32_t        m_line_number;  // Line number for file+line lookups
4001         bool            m_use_regex;    // Name lookups in m_str are regular expressions.
4002         bool            m_include_inlines;// Check for inline entries when looking up by file/line.
4003         bool            m_verbose;      // Enable verbose lookup info
4004         bool            m_print_all;    // Print all matches, even in cases where there's a best match.
4005     };
4006 
4007     CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) :
4008         CommandObjectParsed (interpreter,
4009                              "target modules lookup",
4010                              "Look up information within executable and dependent shared library images.",
4011                              NULL,
4012                              eCommandRequiresTarget),
4013         m_options (interpreter)
4014     {
4015         CommandArgumentEntry arg;
4016         CommandArgumentData file_arg;
4017 
4018         // Define the first (and only) variant of this arg.
4019         file_arg.arg_type = eArgTypeFilename;
4020         file_arg.arg_repetition = eArgRepeatStar;
4021 
4022         // There is only one variant this argument could be; put it into the argument entry.
4023         arg.push_back (file_arg);
4024 
4025         // Push the data for the first argument into the m_arguments vector.
4026         m_arguments.push_back (arg);
4027     }
4028 
4029     virtual
4030     ~CommandObjectTargetModulesLookup ()
4031     {
4032     }
4033 
4034     virtual Options *
4035     GetOptions ()
4036     {
4037         return &m_options;
4038     }
4039 
4040     bool
4041     LookupHere (CommandInterpreter &interpreter, CommandReturnObject &result, bool &syntax_error)
4042     {
4043         switch (m_options.m_type)
4044         {
4045             case eLookupTypeAddress:
4046             case eLookupTypeFileLine:
4047             case eLookupTypeFunction:
4048             case eLookupTypeFunctionOrSymbol:
4049             case eLookupTypeSymbol:
4050             default:
4051                 return false;
4052             case eLookupTypeType:
4053                 break;
4054         }
4055 
4056         StackFrameSP frame = m_exe_ctx.GetFrameSP();
4057 
4058         if (!frame)
4059             return false;
4060 
4061         const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
4062 
4063         if (!sym_ctx.module_sp)
4064             return false;
4065 
4066         switch (m_options.m_type)
4067         {
4068         default:
4069             return false;
4070         case eLookupTypeType:
4071             if (!m_options.m_str.empty())
4072             {
4073                 if (LookupTypeHere (m_interpreter,
4074                                     result.GetOutputStream(),
4075                                     sym_ctx,
4076                                     m_options.m_str.c_str(),
4077                                     m_options.m_use_regex))
4078                 {
4079                     result.SetStatus(eReturnStatusSuccessFinishResult);
4080                     return true;
4081                 }
4082             }
4083             break;
4084         }
4085 
4086         return true;
4087     }
4088 
4089     bool
4090     LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
4091     {
4092         switch (m_options.m_type)
4093         {
4094             case eLookupTypeAddress:
4095                 if (m_options.m_addr != LLDB_INVALID_ADDRESS)
4096                 {
4097                     if (LookupAddressInModule (m_interpreter,
4098                                                result.GetOutputStream(),
4099                                                module,
4100                                                eSymbolContextEverything | (m_options.m_verbose ? eSymbolContextVariable : 0),
4101                                                m_options.m_addr,
4102                                                m_options.m_offset,
4103                                                m_options.m_verbose))
4104                     {
4105                         result.SetStatus(eReturnStatusSuccessFinishResult);
4106                         return true;
4107                     }
4108                 }
4109                 break;
4110 
4111             case eLookupTypeSymbol:
4112                 if (!m_options.m_str.empty())
4113                 {
4114                     if (LookupSymbolInModule (m_interpreter,
4115                                               result.GetOutputStream(),
4116                                               module,
4117                                               m_options.m_str.c_str(),
4118                                               m_options.m_use_regex,
4119                                               m_options.m_verbose))
4120                     {
4121                         result.SetStatus(eReturnStatusSuccessFinishResult);
4122                         return true;
4123                     }
4124                 }
4125                 break;
4126 
4127             case eLookupTypeFileLine:
4128                 if (m_options.m_file)
4129                 {
4130                     if (LookupFileAndLineInModule (m_interpreter,
4131                                                    result.GetOutputStream(),
4132                                                    module,
4133                                                    m_options.m_file,
4134                                                    m_options.m_line_number,
4135                                                    m_options.m_include_inlines,
4136                                                    m_options.m_verbose))
4137                     {
4138                         result.SetStatus(eReturnStatusSuccessFinishResult);
4139                         return true;
4140                     }
4141                 }
4142                 break;
4143 
4144             case eLookupTypeFunctionOrSymbol:
4145             case eLookupTypeFunction:
4146                 if (!m_options.m_str.empty())
4147                 {
4148                     if (LookupFunctionInModule (m_interpreter,
4149                                                 result.GetOutputStream(),
4150                                                 module,
4151                                                 m_options.m_str.c_str(),
4152                                                 m_options.m_use_regex,
4153                                                 m_options.m_include_inlines,
4154                                                 m_options.m_type == eLookupTypeFunctionOrSymbol, // include symbols
4155                                                 m_options.m_verbose))
4156                     {
4157                         result.SetStatus(eReturnStatusSuccessFinishResult);
4158                         return true;
4159                     }
4160                 }
4161                 break;
4162 
4163             case eLookupTypeType:
4164                 if (!m_options.m_str.empty())
4165                 {
4166                     if (LookupTypeInModule (m_interpreter,
4167                                             result.GetOutputStream(),
4168                                             module,
4169                                             m_options.m_str.c_str(),
4170                                             m_options.m_use_regex))
4171                     {
4172                         result.SetStatus(eReturnStatusSuccessFinishResult);
4173                         return true;
4174                     }
4175                 }
4176                 break;
4177 
4178             default:
4179                 m_options.GenerateOptionUsage (result.GetErrorStream(), this);
4180                 syntax_error = true;
4181                 break;
4182         }
4183 
4184         result.SetStatus (eReturnStatusFailed);
4185         return false;
4186     }
4187 
4188 protected:
4189     virtual bool
4190     DoExecute (Args& command,
4191              CommandReturnObject &result)
4192     {
4193         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
4194         if (target == NULL)
4195         {
4196             result.AppendError ("invalid target, create a debug target using the 'target create' command");
4197             result.SetStatus (eReturnStatusFailed);
4198             return false;
4199         }
4200         else
4201         {
4202             bool syntax_error = false;
4203             uint32_t i;
4204             uint32_t num_successful_lookups = 0;
4205             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
4206             result.GetOutputStream().SetAddressByteSize(addr_byte_size);
4207             result.GetErrorStream().SetAddressByteSize(addr_byte_size);
4208             // Dump all sections for all modules images
4209 
4210             if (command.GetArgumentCount() == 0)
4211             {
4212                 ModuleSP current_module;
4213 
4214                 // Where it is possible to look in the current symbol context
4215                 // first, try that.  If this search was successful and --all
4216                 // was not passed, don't print anything else.
4217                 if (LookupHere (m_interpreter, result, syntax_error))
4218                 {
4219                     result.GetOutputStream().EOL();
4220                     num_successful_lookups++;
4221                     if (!m_options.m_print_all)
4222                     {
4223                         result.SetStatus (eReturnStatusSuccessFinishResult);
4224                         return result.Succeeded();
4225                     }
4226                 }
4227 
4228                 // Dump all sections for all other modules
4229 
4230                 const ModuleList &target_modules = target->GetImages();
4231                 Mutex::Locker modules_locker(target_modules.GetMutex());
4232                 const size_t num_modules = target_modules.GetSize();
4233                 if (num_modules > 0)
4234                 {
4235                     for (i = 0; i<num_modules && syntax_error == false; ++i)
4236                     {
4237                         Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked(i);
4238 
4239                         if (module_pointer != current_module.get() &&
4240                             LookupInModule (m_interpreter, target_modules.GetModulePointerAtIndexUnlocked(i), result, syntax_error))
4241                         {
4242                             result.GetOutputStream().EOL();
4243                             num_successful_lookups++;
4244                         }
4245                     }
4246                 }
4247                 else
4248                 {
4249                     result.AppendError ("the target has no associated executable images");
4250                     result.SetStatus (eReturnStatusFailed);
4251                     return false;
4252                 }
4253             }
4254             else
4255             {
4256                 // Dump specified images (by basename or fullpath)
4257                 const char *arg_cstr;
4258                 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i)
4259                 {
4260                     ModuleList module_list;
4261                     const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, false);
4262                     if (num_matches > 0)
4263                     {
4264                         for (size_t j=0; j<num_matches; ++j)
4265                         {
4266                             Module *module = module_list.GetModulePointerAtIndex(j);
4267                             if (module)
4268                             {
4269                                 if (LookupInModule (m_interpreter, module, result, syntax_error))
4270                                 {
4271                                     result.GetOutputStream().EOL();
4272                                     num_successful_lookups++;
4273                                 }
4274                             }
4275                         }
4276                     }
4277                     else
4278                         result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
4279                 }
4280             }
4281 
4282             if (num_successful_lookups > 0)
4283                 result.SetStatus (eReturnStatusSuccessFinishResult);
4284             else
4285                 result.SetStatus (eReturnStatusFailed);
4286         }
4287         return result.Succeeded();
4288     }
4289 
4290     CommandOptions m_options;
4291 };
4292 
4293 OptionDefinition
4294 CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] =
4295 {
4296     { LLDB_OPT_SET_1,   true,  "address",    'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules."},
4297     { 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."},
4298     { LLDB_OPT_SET_2| LLDB_OPT_SET_4 | LLDB_OPT_SET_5
4299       /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */ ,
4300                         false, "regex",      'r', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone,             "The <name> argument for name lookups are regular expressions."},
4301     { 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."},
4302     { 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."},
4303     { 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)."},
4304     { LLDB_OPT_SET_FROM_TO(3,5),
4305                         false, "no-inlines", 'i', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone,             "Ignore inline entries (must be used in conjunction with --file or --function)."},
4306     { 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."},
4307     { 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."},
4308     { 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."},
4309     { LLDB_OPT_SET_ALL, false, "verbose",    'v', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone,             "Enable verbose lookup information."},
4310     { 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."},
4311     { 0,                false, NULL,           0, 0,                 NULL, NULL, 0, eArgTypeNone,             NULL }
4312 };
4313 
4314 
4315 #pragma mark CommandObjectMultiwordImageSearchPaths
4316 
4317 //-------------------------------------------------------------------------
4318 // CommandObjectMultiwordImageSearchPaths
4319 //-------------------------------------------------------------------------
4320 
4321 class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword
4322 {
4323 public:
4324     CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) :
4325     CommandObjectMultiword (interpreter,
4326                             "target modules search-paths",
4327                             "A set of commands for operating on debugger target image search paths.",
4328                             "target modules search-paths <subcommand> [<subcommand-options>]")
4329     {
4330         LoadSubCommand ("add",     CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter)));
4331         LoadSubCommand ("clear",   CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter)));
4332         LoadSubCommand ("insert",  CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter)));
4333         LoadSubCommand ("list",    CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter)));
4334         LoadSubCommand ("query",   CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter)));
4335     }
4336 
4337     ~CommandObjectTargetModulesImageSearchPaths()
4338     {
4339     }
4340 };
4341 
4342 
4343 
4344 #pragma mark CommandObjectTargetModules
4345 
4346 //-------------------------------------------------------------------------
4347 // CommandObjectTargetModules
4348 //-------------------------------------------------------------------------
4349 
4350 class CommandObjectTargetModules : public CommandObjectMultiword
4351 {
4352 public:
4353     //------------------------------------------------------------------
4354     // Constructors and Destructors
4355     //------------------------------------------------------------------
4356     CommandObjectTargetModules(CommandInterpreter &interpreter) :
4357         CommandObjectMultiword (interpreter,
4358                                 "target modules",
4359                                 "A set of commands for accessing information for one or more target modules.",
4360                                 "target modules <sub-command> ...")
4361     {
4362         LoadSubCommand ("add",          CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter)));
4363         LoadSubCommand ("load",         CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter)));
4364         LoadSubCommand ("dump",         CommandObjectSP (new CommandObjectTargetModulesDump (interpreter)));
4365         LoadSubCommand ("list",         CommandObjectSP (new CommandObjectTargetModulesList (interpreter)));
4366         LoadSubCommand ("lookup",       CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter)));
4367         LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter)));
4368         LoadSubCommand ("show-unwind",  CommandObjectSP (new CommandObjectTargetModulesShowUnwind (interpreter)));
4369 
4370     }
4371     virtual
4372     ~CommandObjectTargetModules()
4373     {
4374     }
4375 
4376 private:
4377     //------------------------------------------------------------------
4378     // For CommandObjectTargetModules only
4379     //------------------------------------------------------------------
4380     DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules);
4381 };
4382 
4383 
4384 
4385 class CommandObjectTargetSymbolsAdd : public CommandObjectParsed
4386 {
4387 public:
4388     CommandObjectTargetSymbolsAdd (CommandInterpreter &interpreter) :
4389         CommandObjectParsed (interpreter,
4390                              "target symbols add",
4391                              "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.",
4392                              "target symbols add [<symfile>]", eCommandRequiresTarget),
4393         m_option_group (interpreter),
4394         m_file_option (LLDB_OPT_SET_1, false, "shlib", 's', CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Fullpath or basename for module to find debug symbols for."),
4395         m_current_frame_option (LLDB_OPT_SET_2, false, "frame", 'F', "Locate the debug symbols the currently selected frame.", false, true)
4396 
4397     {
4398         m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
4399         m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
4400         m_option_group.Append (&m_current_frame_option, LLDB_OPT_SET_2, LLDB_OPT_SET_2);
4401         m_option_group.Finalize();
4402     }
4403 
4404     virtual
4405     ~CommandObjectTargetSymbolsAdd ()
4406     {
4407     }
4408 
4409     virtual int
4410     HandleArgumentCompletion (Args &input,
4411                               int &cursor_index,
4412                               int &cursor_char_position,
4413                               OptionElementVector &opt_element_vector,
4414                               int match_start_point,
4415                               int max_return_elements,
4416                               bool &word_complete,
4417                               StringList &matches)
4418     {
4419         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
4420         completion_str.erase (cursor_char_position);
4421 
4422         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
4423                                                              CommandCompletions::eDiskFileCompletion,
4424                                                              completion_str.c_str(),
4425                                                              match_start_point,
4426                                                              max_return_elements,
4427                                                              NULL,
4428                                                              word_complete,
4429                                                              matches);
4430         return matches.GetSize();
4431     }
4432 
4433     virtual Options *
4434     GetOptions ()
4435     {
4436         return &m_option_group;
4437     }
4438 
4439 protected:
4440     bool
4441     AddModuleSymbols (Target *target,
4442                       ModuleSpec &module_spec,
4443                       bool &flush,
4444                       CommandReturnObject &result)
4445     {
4446         const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
4447         if (symbol_fspec)
4448         {
4449             char symfile_path[PATH_MAX];
4450             symbol_fspec.GetPath (symfile_path, sizeof(symfile_path));
4451 
4452             if (!module_spec.GetUUID().IsValid())
4453             {
4454                 if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
4455                     module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
4456             }
4457             // We now have a module that represents a symbol file
4458             // that can be used for a module that might exist in the
4459             // current target, so we need to find that module in the
4460             // target
4461             ModuleList matching_module_list;
4462 
4463             size_t num_matches = 0;
4464             // First extract all module specs from the symbol file
4465             lldb_private::ModuleSpecList symfile_module_specs;
4466             if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(), 0, 0, symfile_module_specs))
4467             {
4468                 // Now extract the module spec that matches the target architecture
4469                 ModuleSpec target_arch_module_spec;
4470                 ModuleSpec symfile_module_spec;
4471                 target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
4472                 if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec, symfile_module_spec))
4473                 {
4474                     // See if it has a UUID?
4475                     if (symfile_module_spec.GetUUID().IsValid())
4476                     {
4477                         // It has a UUID, look for this UUID in the target modules
4478                         ModuleSpec symfile_uuid_module_spec;
4479                         symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4480                         num_matches = target->GetImages().FindModules (symfile_uuid_module_spec, matching_module_list);
4481                     }
4482                 }
4483 
4484                 if (num_matches == 0)
4485                 {
4486                     // No matches yet, iterate through the module specs to find a UUID value that
4487                     // we can match up to an image in our target
4488                     const size_t num_symfile_module_specs = symfile_module_specs.GetSize();
4489                     for (size_t i=0; i<num_symfile_module_specs && num_matches == 0; ++i)
4490                     {
4491                         if (symfile_module_specs.GetModuleSpecAtIndex(i, symfile_module_spec))
4492                         {
4493                             if (symfile_module_spec.GetUUID().IsValid())
4494                             {
4495                                 // It has a UUID, look for this UUID in the target modules
4496                                 ModuleSpec symfile_uuid_module_spec;
4497                                 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4498                                 num_matches = target->GetImages().FindModules (symfile_uuid_module_spec, matching_module_list);
4499                             }
4500                         }
4501                     }
4502                 }
4503             }
4504 
4505             // Just try to match up the file by basename if we have no matches at this point
4506             if (num_matches == 0)
4507                 num_matches = target->GetImages().FindModules (module_spec, matching_module_list);
4508 
4509             while (num_matches == 0)
4510             {
4511                 ConstString filename_no_extension(module_spec.GetFileSpec().GetFileNameStrippingExtension());
4512                 // Empty string returned, lets bail
4513                 if (!filename_no_extension)
4514                     break;
4515 
4516                 // Check if there was no extension to strip and the basename is the same
4517                 if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
4518                     break;
4519 
4520                 // Replace basename with one less extension
4521                 module_spec.GetFileSpec().GetFilename() = filename_no_extension;
4522 
4523                 num_matches = target->GetImages().FindModules (module_spec, matching_module_list);
4524             }
4525 
4526             if (num_matches > 1)
4527             {
4528                 result.AppendErrorWithFormat ("multiple modules match symbol file '%s', use the --uuid option to resolve the ambiguity.\n", symfile_path);
4529             }
4530             else if (num_matches == 1)
4531             {
4532                 ModuleSP module_sp (matching_module_list.GetModuleAtIndex(0));
4533 
4534                 // The module has not yet created its symbol vendor, we can just
4535                 // give the existing target module the symfile path to use for
4536                 // when it decides to create it!
4537                 module_sp->SetSymbolFileFileSpec (symbol_fspec);
4538 
4539                 SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(true, &result.GetErrorStream());
4540                 if (symbol_vendor)
4541                 {
4542                     SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
4543 
4544                     if (symbol_file)
4545                     {
4546                         ObjectFile *object_file = symbol_file->GetObjectFile();
4547 
4548                         if (object_file && object_file->GetFileSpec() == symbol_fspec)
4549                         {
4550                             // Provide feedback that the symfile has been successfully added.
4551                             const FileSpec &module_fs = module_sp->GetFileSpec();
4552                             result.AppendMessageWithFormat("symbol file '%s' has been added to '%s'\n",
4553                                                            symfile_path,
4554                                                            module_fs.GetPath().c_str());
4555 
4556                             // Let clients know something changed in the module
4557                             // if it is currently loaded
4558                             ModuleList module_list;
4559                             module_list.Append (module_sp);
4560                             target->SymbolsDidLoad (module_list);
4561 
4562                             // Make sure we load any scripting resources that may be embedded
4563                             // in the debug info files in case the platform supports that.
4564                             Error error;
4565                             StreamString feedback_stream;
4566                             module_sp->LoadScriptingResourceInTarget (target, error,&feedback_stream);
4567                             if (error.Fail() && error.AsCString())
4568                                 result.AppendWarningWithFormat("unable to load scripting data for module %s - error reported was %s",
4569                                                                module_sp->GetFileSpec().GetFileNameStrippingExtension().GetCString(),
4570                                                                error.AsCString());
4571                             else if (feedback_stream.GetSize())
4572                                 result.AppendWarningWithFormat("%s",feedback_stream.GetData());
4573 
4574                             flush = true;
4575                             result.SetStatus (eReturnStatusSuccessFinishResult);
4576                             return true;
4577                         }
4578                     }
4579                 }
4580                 // Clear the symbol file spec if anything went wrong
4581                 module_sp->SetSymbolFileFileSpec (FileSpec());
4582             }
4583 
4584             if (module_spec.GetUUID().IsValid())
4585             {
4586                 StreamString ss_symfile_uuid;
4587                 module_spec.GetUUID().Dump(&ss_symfile_uuid);
4588                 result.AppendErrorWithFormat ("symbol file '%s' (%s) does not match any existing module%s\n",
4589                                               symfile_path,
4590                                               ss_symfile_uuid.GetData(),
4591                                               (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
4592                                                 ? "\n       please specify the full path to the symbol file"
4593                                                 : "");
4594             }
4595             else
4596             {
4597                 result.AppendErrorWithFormat ("symbol file '%s' does not match any existing module%s\n",
4598                                               symfile_path,
4599                                               (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
4600                                                 ? "\n       please specify the full path to the symbol file"
4601                                                 : "");
4602             }
4603         }
4604         else
4605         {
4606             result.AppendError ("one or more executable image paths must be specified");
4607         }
4608         result.SetStatus (eReturnStatusFailed);
4609         return false;
4610     }
4611 
4612     virtual bool
4613     DoExecute (Args& args,
4614              CommandReturnObject &result)
4615     {
4616         Target *target = m_exe_ctx.GetTargetPtr();
4617         result.SetStatus (eReturnStatusFailed);
4618         bool flush = false;
4619         ModuleSpec module_spec;
4620         const bool uuid_option_set = m_uuid_option_group.GetOptionValue().OptionWasSet();
4621         const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4622         const bool frame_option_set = m_current_frame_option.GetOptionValue().OptionWasSet();
4623 
4624         const size_t argc = args.GetArgumentCount();
4625         if (argc == 0)
4626         {
4627             if (uuid_option_set || file_option_set || frame_option_set)
4628             {
4629                 bool success = false;
4630                 bool error_set = false;
4631                 if (frame_option_set)
4632                 {
4633                     Process *process = m_exe_ctx.GetProcessPtr();
4634                     if (process)
4635                     {
4636                         const StateType process_state = process->GetState();
4637                         if (StateIsStoppedState (process_state, true))
4638                         {
4639                             StackFrame *frame = m_exe_ctx.GetFramePtr();
4640                             if (frame)
4641                             {
4642                                 ModuleSP frame_module_sp (frame->GetSymbolContext(eSymbolContextModule).module_sp);
4643                                 if (frame_module_sp)
4644                                 {
4645                                     if (frame_module_sp->GetPlatformFileSpec().Exists())
4646                                     {
4647                                         module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
4648                                         module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
4649                                     }
4650                                     module_spec.GetUUID() = frame_module_sp->GetUUID();
4651                                     success = module_spec.GetUUID().IsValid() || module_spec.GetFileSpec();
4652                                 }
4653                                 else
4654                                 {
4655                                     result.AppendError ("frame has no module");
4656                                     error_set = true;
4657                                 }
4658                             }
4659                             else
4660                             {
4661                                 result.AppendError ("invalid current frame");
4662                                 error_set = true;
4663                             }
4664                         }
4665                         else
4666                         {
4667                             result.AppendErrorWithFormat ("process is not stopped: %s", StateAsCString(process_state));
4668                             error_set = true;
4669                         }
4670                     }
4671                     else
4672                     {
4673                         result.AppendError ("a process must exist in order to use the --frame option");
4674                         error_set = true;
4675                     }
4676                 }
4677                 else
4678                 {
4679                     if (uuid_option_set)
4680                     {
4681                         module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue();
4682                         success |= module_spec.GetUUID().IsValid();
4683                     }
4684                     else if (file_option_set)
4685                     {
4686                         module_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue();
4687                         ModuleSP module_sp (target->GetImages().FindFirstModule(module_spec));
4688                         if (module_sp)
4689                         {
4690                             module_spec.GetFileSpec() = module_sp->GetFileSpec();
4691                             module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();
4692                             module_spec.GetUUID() = module_sp->GetUUID();
4693                             module_spec.GetArchitecture() = module_sp->GetArchitecture();
4694                         }
4695                         else
4696                         {
4697                             module_spec.GetArchitecture() = target->GetArchitecture();
4698                         }
4699                         success |= module_spec.GetFileSpec().Exists();
4700                     }
4701                 }
4702 
4703                 if (success)
4704                 {
4705                     if (Symbols::DownloadObjectAndSymbolFile (module_spec))
4706                     {
4707                         if (module_spec.GetSymbolFileSpec())
4708                             success = AddModuleSymbols (target, module_spec, flush, result);
4709                     }
4710                 }
4711 
4712                 if (!success && !error_set)
4713                 {
4714                     StreamString error_strm;
4715                     if (uuid_option_set)
4716                     {
4717                         error_strm.PutCString("unable to find debug symbols for UUID ");
4718                         module_spec.GetUUID().Dump (&error_strm);
4719                     }
4720                     else if (file_option_set)
4721                     {
4722                         error_strm.PutCString("unable to find debug symbols for the executable file ");
4723                         error_strm << module_spec.GetFileSpec();
4724                     }
4725                     else if (frame_option_set)
4726                     {
4727                         error_strm.PutCString("unable to find debug symbols for the current frame");
4728                     }
4729                     result.AppendError (error_strm.GetData());
4730                 }
4731             }
4732             else
4733             {
4734                 result.AppendError ("one or more symbol file paths must be specified, or options must be specified");
4735             }
4736         }
4737         else
4738         {
4739             if (uuid_option_set)
4740             {
4741                 result.AppendError ("specify either one or more paths to symbol files or use the --uuid option without arguments");
4742             }
4743             else if (file_option_set)
4744             {
4745                 result.AppendError ("specify either one or more paths to symbol files or use the --file option without arguments");
4746             }
4747             else if (frame_option_set)
4748             {
4749                 result.AppendError ("specify either one or more paths to symbol files or use the --frame option without arguments");
4750             }
4751             else
4752             {
4753                 PlatformSP platform_sp (target->GetPlatform());
4754 
4755                 for (size_t i=0; i<argc; ++i)
4756                 {
4757                     const char *symfile_path = args.GetArgumentAtIndex(i);
4758                     if (symfile_path)
4759                     {
4760                         module_spec.GetSymbolFileSpec().SetFile(symfile_path, true);
4761                         if (platform_sp)
4762                         {
4763                             FileSpec symfile_spec;
4764                             if (platform_sp->ResolveSymbolFile(*target, module_spec, symfile_spec).Success())
4765                                 module_spec.GetSymbolFileSpec() = symfile_spec;
4766                         }
4767 
4768                         ArchSpec arch;
4769                         bool symfile_exists = module_spec.GetSymbolFileSpec().Exists();
4770 
4771                         if (symfile_exists)
4772                         {
4773                             if (!AddModuleSymbols (target, module_spec, flush, result))
4774                                 break;
4775                         }
4776                         else
4777                         {
4778                             char resolved_symfile_path[PATH_MAX];
4779                             if (module_spec.GetSymbolFileSpec().GetPath (resolved_symfile_path, sizeof(resolved_symfile_path)))
4780                             {
4781                                 if (strcmp (resolved_symfile_path, symfile_path) != 0)
4782                                 {
4783                                     result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", symfile_path, resolved_symfile_path);
4784                                     break;
4785                                 }
4786                             }
4787                             result.AppendErrorWithFormat ("invalid module path '%s'\n", symfile_path);
4788                             break;
4789                         }
4790                     }
4791                 }
4792             }
4793         }
4794 
4795         if (flush)
4796         {
4797             Process *process = m_exe_ctx.GetProcessPtr();
4798             if (process)
4799                 process->Flush();
4800         }
4801         return result.Succeeded();
4802     }
4803 
4804     OptionGroupOptions m_option_group;
4805     OptionGroupUUID m_uuid_option_group;
4806     OptionGroupFile m_file_option;
4807     OptionGroupBoolean m_current_frame_option;
4808 };
4809 
4810 
4811 #pragma mark CommandObjectTargetSymbols
4812 
4813 //-------------------------------------------------------------------------
4814 // CommandObjectTargetSymbols
4815 //-------------------------------------------------------------------------
4816 
4817 class CommandObjectTargetSymbols : public CommandObjectMultiword
4818 {
4819 public:
4820     //------------------------------------------------------------------
4821     // Constructors and Destructors
4822     //------------------------------------------------------------------
4823     CommandObjectTargetSymbols(CommandInterpreter &interpreter) :
4824         CommandObjectMultiword (interpreter,
4825                             "target symbols",
4826                             "A set of commands for adding and managing debug symbol files.",
4827                             "target symbols <sub-command> ...")
4828     {
4829         LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetSymbolsAdd (interpreter)));
4830 
4831     }
4832     virtual
4833     ~CommandObjectTargetSymbols()
4834     {
4835     }
4836 
4837 private:
4838     //------------------------------------------------------------------
4839     // For CommandObjectTargetModules only
4840     //------------------------------------------------------------------
4841     DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetSymbols);
4842 };
4843 
4844 
4845 #pragma mark CommandObjectTargetStopHookAdd
4846 
4847 //-------------------------------------------------------------------------
4848 // CommandObjectTargetStopHookAdd
4849 //-------------------------------------------------------------------------
4850 
4851 class CommandObjectTargetStopHookAdd :
4852     public CommandObjectParsed,
4853     public IOHandlerDelegateMultiline
4854 {
4855 public:
4856 
4857     class CommandOptions : public Options
4858     {
4859     public:
4860         CommandOptions (CommandInterpreter &interpreter) :
4861             Options(interpreter),
4862             m_line_start(0),
4863             m_line_end (UINT_MAX),
4864             m_func_name_type_mask (eFunctionNameTypeAuto),
4865             m_sym_ctx_specified (false),
4866             m_thread_specified (false),
4867             m_use_one_liner (false),
4868             m_one_liner()
4869         {
4870         }
4871 
4872         ~CommandOptions () {}
4873 
4874         const OptionDefinition*
4875         GetDefinitions ()
4876         {
4877             return g_option_table;
4878         }
4879 
4880         virtual Error
4881         SetOptionValue (uint32_t option_idx, const char *option_arg)
4882         {
4883             Error error;
4884             const int short_option = m_getopt_table[option_idx].val;
4885             bool success;
4886 
4887             switch (short_option)
4888             {
4889                 case 'c':
4890                     m_class_name = option_arg;
4891                     m_sym_ctx_specified = true;
4892                 break;
4893 
4894                 case 'e':
4895                     m_line_end = StringConvert::ToUInt32 (option_arg, UINT_MAX, 0, &success);
4896                     if (!success)
4897                     {
4898                         error.SetErrorStringWithFormat ("invalid end line number: \"%s\"", option_arg);
4899                         break;
4900                     }
4901                     m_sym_ctx_specified = true;
4902                 break;
4903 
4904                 case 'l':
4905                     m_line_start = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
4906                     if (!success)
4907                     {
4908                         error.SetErrorStringWithFormat ("invalid start line number: \"%s\"", option_arg);
4909                         break;
4910                     }
4911                     m_sym_ctx_specified = true;
4912                 break;
4913 
4914                 case 'i':
4915                     m_no_inlines = true;
4916                 break;
4917 
4918                 case 'n':
4919                     m_function_name = option_arg;
4920                     m_func_name_type_mask |= eFunctionNameTypeAuto;
4921                     m_sym_ctx_specified = true;
4922                 break;
4923 
4924                 case 'f':
4925                     m_file_name = option_arg;
4926                     m_sym_ctx_specified = true;
4927                 break;
4928                 case 's':
4929                     m_module_name = option_arg;
4930                     m_sym_ctx_specified = true;
4931                 break;
4932                 case 't' :
4933                 {
4934                     m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
4935                     if (m_thread_id == LLDB_INVALID_THREAD_ID)
4936                        error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
4937                     m_thread_specified = true;
4938                 }
4939                 break;
4940                 case 'T':
4941                     m_thread_name = option_arg;
4942                     m_thread_specified = true;
4943                 break;
4944                 case 'q':
4945                     m_queue_name = option_arg;
4946                     m_thread_specified = true;
4947                     break;
4948                 case 'x':
4949                 {
4950                     m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
4951                     if (m_thread_id == UINT32_MAX)
4952                        error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
4953                     m_thread_specified = true;
4954                 }
4955                 break;
4956                 case 'o':
4957                     m_use_one_liner = true;
4958                     m_one_liner = option_arg;
4959                 break;
4960                 default:
4961                     error.SetErrorStringWithFormat ("unrecognized option %c.", short_option);
4962                 break;
4963             }
4964             return error;
4965         }
4966 
4967         void
4968         OptionParsingStarting ()
4969         {
4970             m_class_name.clear();
4971             m_function_name.clear();
4972             m_line_start = 0;
4973             m_line_end = UINT_MAX;
4974             m_file_name.clear();
4975             m_module_name.clear();
4976             m_func_name_type_mask = eFunctionNameTypeAuto;
4977             m_thread_id = LLDB_INVALID_THREAD_ID;
4978             m_thread_index = UINT32_MAX;
4979             m_thread_name.clear();
4980             m_queue_name.clear();
4981 
4982             m_no_inlines = false;
4983             m_sym_ctx_specified = false;
4984             m_thread_specified = false;
4985 
4986             m_use_one_liner = false;
4987             m_one_liner.clear();
4988         }
4989 
4990 
4991         static OptionDefinition g_option_table[];
4992 
4993         std::string m_class_name;
4994         std::string m_function_name;
4995         uint32_t    m_line_start;
4996         uint32_t    m_line_end;
4997         std::string m_file_name;
4998         std::string m_module_name;
4999         uint32_t m_func_name_type_mask;  // A pick from lldb::FunctionNameType.
5000         lldb::tid_t m_thread_id;
5001         uint32_t m_thread_index;
5002         std::string m_thread_name;
5003         std::string m_queue_name;
5004         bool        m_sym_ctx_specified;
5005         bool        m_no_inlines;
5006         bool        m_thread_specified;
5007         // Instance variables to hold the values for one_liner options.
5008         bool m_use_one_liner;
5009         std::string m_one_liner;
5010     };
5011 
5012     Options *
5013     GetOptions ()
5014     {
5015         return &m_options;
5016     }
5017 
5018     CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) :
5019         CommandObjectParsed (interpreter,
5020                              "target stop-hook add",
5021                              "Add a hook to be executed when the target stops.",
5022                              "target stop-hook add"),
5023         IOHandlerDelegateMultiline ("DONE", IOHandlerDelegate::Completion::LLDBCommand),
5024         m_options (interpreter)
5025     {
5026     }
5027 
5028     ~CommandObjectTargetStopHookAdd ()
5029     {
5030     }
5031 
5032 protected:
5033     virtual void
5034     IOHandlerActivated (IOHandler &io_handler)
5035     {
5036         StreamFileSP output_sp(io_handler.GetOutputStreamFile());
5037         if (output_sp)
5038         {
5039             output_sp->PutCString("Enter your stop hook command(s).  Type 'DONE' to end.\n");
5040             output_sp->Flush();
5041         }
5042     }
5043 
5044     virtual void
5045     IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
5046     {
5047         if (m_stop_hook_sp)
5048         {
5049             if (line.empty())
5050             {
5051                 StreamFileSP error_sp(io_handler.GetErrorStreamFile());
5052                 if (error_sp)
5053                 {
5054                     error_sp->Printf("error: stop hook #%" PRIu64 " aborted, no commands.\n", m_stop_hook_sp->GetID());
5055                     error_sp->Flush();
5056                 }
5057                 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
5058                 if (target)
5059                     target->RemoveStopHookByID(m_stop_hook_sp->GetID());
5060             }
5061             else
5062             {
5063                 m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
5064                 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
5065                 if (output_sp)
5066                 {
5067                     output_sp->Printf("Stop hook #%" PRIu64 " added.\n", m_stop_hook_sp->GetID());
5068                     output_sp->Flush();
5069                 }
5070             }
5071             m_stop_hook_sp.reset();
5072         }
5073         io_handler.SetIsDone(true);
5074     }
5075 
5076     bool
5077     DoExecute (Args& command, CommandReturnObject &result)
5078     {
5079         m_stop_hook_sp.reset();
5080 
5081         Target *target = GetSelectedOrDummyTarget();
5082         if (target)
5083         {
5084             Target::StopHookSP new_hook_sp = target->CreateStopHook();
5085 
5086             //  First step, make the specifier.
5087             std::unique_ptr<SymbolContextSpecifier> specifier_ap;
5088             if (m_options.m_sym_ctx_specified)
5089             {
5090                 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget()));
5091 
5092                 if (!m_options.m_module_name.empty())
5093                 {
5094                     specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified);
5095                 }
5096 
5097                 if (!m_options.m_class_name.empty())
5098                 {
5099                     specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified);
5100                 }
5101 
5102                 if (!m_options.m_file_name.empty())
5103                 {
5104                     specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified);
5105                 }
5106 
5107                 if (m_options.m_line_start != 0)
5108                 {
5109                     specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified);
5110                 }
5111 
5112                 if (m_options.m_line_end != UINT_MAX)
5113                 {
5114                     specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
5115                 }
5116 
5117                 if (!m_options.m_function_name.empty())
5118                 {
5119                     specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified);
5120                 }
5121             }
5122 
5123             if (specifier_ap.get())
5124                 new_hook_sp->SetSpecifier (specifier_ap.release());
5125 
5126             // Next see if any of the thread options have been entered:
5127 
5128             if (m_options.m_thread_specified)
5129             {
5130                 ThreadSpec *thread_spec = new ThreadSpec();
5131 
5132                 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
5133                 {
5134                     thread_spec->SetTID (m_options.m_thread_id);
5135                 }
5136 
5137                 if (m_options.m_thread_index != UINT32_MAX)
5138                     thread_spec->SetIndex (m_options.m_thread_index);
5139 
5140                 if (!m_options.m_thread_name.empty())
5141                     thread_spec->SetName (m_options.m_thread_name.c_str());
5142 
5143                 if (!m_options.m_queue_name.empty())
5144                     thread_spec->SetQueueName (m_options.m_queue_name.c_str());
5145 
5146                 new_hook_sp->SetThreadSpecifier (thread_spec);
5147 
5148             }
5149             if (m_options.m_use_one_liner)
5150             {
5151                 // Use one-liner.
5152                 new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str());
5153                 result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n", new_hook_sp->GetID());
5154             }
5155             else
5156             {
5157                 m_stop_hook_sp = new_hook_sp;
5158                 m_interpreter.GetLLDBCommandsFromIOHandler ("> ",   // Prompt
5159                                                             *this,  // IOHandlerDelegate
5160                                                             true,   // Run IOHandler in async mode
5161                                                             NULL);  // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
5162 
5163             }
5164             result.SetStatus (eReturnStatusSuccessFinishNoResult);
5165         }
5166         else
5167         {
5168             result.AppendError ("invalid target\n");
5169             result.SetStatus (eReturnStatusFailed);
5170         }
5171 
5172         return result.Succeeded();
5173     }
5174 private:
5175     CommandOptions m_options;
5176     Target::StopHookSP m_stop_hook_sp;
5177 };
5178 
5179 OptionDefinition
5180 CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] =
5181 {
5182     { LLDB_OPT_SET_ALL, false, "one-liner", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOneLiner,
5183         "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
5184     { LLDB_OPT_SET_ALL, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
5185         "Set the module within which the stop-hook is to be run."},
5186     { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex,
5187         "The stop hook is run only for the thread whose index matches this argument."},
5188     { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID,
5189         "The stop hook is run only for the thread whose TID matches this argument."},
5190     { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName,
5191         "The stop hook is run only for the thread whose thread name matches this argument."},
5192     { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName,
5193         "The stop hook is run only for threads in the queue whose name is given by this argument."},
5194     { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
5195         "Specify the source file within which the stop-hook is to be run." },
5196     { LLDB_OPT_SET_1, false, "start-line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
5197         "Set the start of the line range for which the stop-hook is to be run."},
5198     { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
5199         "Set the end of the line range for which the stop-hook is to be run."},
5200     { LLDB_OPT_SET_2, false, "classname", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeClassName,
5201         "Specify the class within which the stop-hook is to be run." },
5202     { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
5203         "Set the function name within which the stop hook will be run." },
5204     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
5205 };
5206 
5207 #pragma mark CommandObjectTargetStopHookDelete
5208 
5209 //-------------------------------------------------------------------------
5210 // CommandObjectTargetStopHookDelete
5211 //-------------------------------------------------------------------------
5212 
5213 class CommandObjectTargetStopHookDelete : public CommandObjectParsed
5214 {
5215 public:
5216 
5217     CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) :
5218         CommandObjectParsed (interpreter,
5219                              "target stop-hook delete",
5220                              "Delete a stop-hook.",
5221                              "target stop-hook delete [<idx>]")
5222     {
5223     }
5224 
5225     ~CommandObjectTargetStopHookDelete ()
5226     {
5227     }
5228 
5229 protected:
5230     bool
5231     DoExecute (Args& command, CommandReturnObject &result)
5232     {
5233         Target *target = GetSelectedOrDummyTarget();
5234         if (target)
5235         {
5236             // FIXME: see if we can use the breakpoint id style parser?
5237             size_t num_args = command.GetArgumentCount();
5238             if (num_args == 0)
5239             {
5240                 if (!m_interpreter.Confirm ("Delete all stop hooks?", true))
5241                 {
5242                     result.SetStatus (eReturnStatusFailed);
5243                     return false;
5244                 }
5245                 else
5246                 {
5247                     target->RemoveAllStopHooks();
5248                 }
5249             }
5250             else
5251             {
5252                 bool success;
5253                 for (size_t i = 0; i < num_args; i++)
5254                 {
5255                     lldb::user_id_t user_id = StringConvert::ToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
5256                     if (!success)
5257                     {
5258                         result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
5259                         result.SetStatus(eReturnStatusFailed);
5260                         return false;
5261                     }
5262                     success = target->RemoveStopHookByID (user_id);
5263                     if (!success)
5264                     {
5265                         result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
5266                         result.SetStatus(eReturnStatusFailed);
5267                         return false;
5268                     }
5269                 }
5270             }
5271             result.SetStatus (eReturnStatusSuccessFinishNoResult);
5272         }
5273         else
5274         {
5275             result.AppendError ("invalid target\n");
5276             result.SetStatus (eReturnStatusFailed);
5277         }
5278 
5279         return result.Succeeded();
5280     }
5281 };
5282 #pragma mark CommandObjectTargetStopHookEnableDisable
5283 
5284 //-------------------------------------------------------------------------
5285 // CommandObjectTargetStopHookEnableDisable
5286 //-------------------------------------------------------------------------
5287 
5288 class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed
5289 {
5290 public:
5291 
5292     CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) :
5293         CommandObjectParsed (interpreter,
5294                              name,
5295                              help,
5296                              syntax),
5297         m_enable (enable)
5298     {
5299     }
5300 
5301     ~CommandObjectTargetStopHookEnableDisable ()
5302     {
5303     }
5304 
5305 protected:
5306     bool
5307     DoExecute (Args& command, CommandReturnObject &result)
5308     {
5309         Target *target = GetSelectedOrDummyTarget();
5310         if (target)
5311         {
5312             // FIXME: see if we can use the breakpoint id style parser?
5313             size_t num_args = command.GetArgumentCount();
5314             bool success;
5315 
5316             if (num_args == 0)
5317             {
5318                 target->SetAllStopHooksActiveState (m_enable);
5319             }
5320             else
5321             {
5322                 for (size_t i = 0; i < num_args; i++)
5323                 {
5324                     lldb::user_id_t user_id = StringConvert::ToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
5325                     if (!success)
5326                     {
5327                         result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
5328                         result.SetStatus(eReturnStatusFailed);
5329                         return false;
5330                     }
5331                     success = target->SetStopHookActiveStateByID (user_id, m_enable);
5332                     if (!success)
5333                     {
5334                         result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
5335                         result.SetStatus(eReturnStatusFailed);
5336                         return false;
5337                     }
5338                 }
5339             }
5340             result.SetStatus (eReturnStatusSuccessFinishNoResult);
5341         }
5342         else
5343         {
5344             result.AppendError ("invalid target\n");
5345             result.SetStatus (eReturnStatusFailed);
5346         }
5347         return result.Succeeded();
5348     }
5349 private:
5350     bool m_enable;
5351 };
5352 
5353 #pragma mark CommandObjectTargetStopHookList
5354 
5355 //-------------------------------------------------------------------------
5356 // CommandObjectTargetStopHookList
5357 //-------------------------------------------------------------------------
5358 
5359 class CommandObjectTargetStopHookList : public CommandObjectParsed
5360 {
5361 public:
5362 
5363     CommandObjectTargetStopHookList (CommandInterpreter &interpreter) :
5364         CommandObjectParsed (interpreter,
5365                              "target stop-hook list",
5366                              "List all stop-hooks.",
5367                              "target stop-hook list [<type>]")
5368     {
5369     }
5370 
5371     ~CommandObjectTargetStopHookList ()
5372     {
5373     }
5374 
5375 protected:
5376     bool
5377     DoExecute (Args& command, CommandReturnObject &result)
5378     {
5379         Target *target = GetSelectedOrDummyTarget();
5380         if (!target)
5381         {
5382             result.AppendError ("invalid target\n");
5383             result.SetStatus (eReturnStatusFailed);
5384             return result.Succeeded();
5385         }
5386 
5387         size_t num_hooks = target->GetNumStopHooks ();
5388         if (num_hooks == 0)
5389         {
5390             result.GetOutputStream().PutCString ("No stop hooks.\n");
5391         }
5392         else
5393         {
5394             for (size_t i = 0; i < num_hooks; i++)
5395             {
5396                 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i);
5397                 if (i > 0)
5398                     result.GetOutputStream().PutCString ("\n");
5399                 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull);
5400             }
5401         }
5402         result.SetStatus (eReturnStatusSuccessFinishResult);
5403         return result.Succeeded();
5404     }
5405 };
5406 
5407 #pragma mark CommandObjectMultiwordTargetStopHooks
5408 //-------------------------------------------------------------------------
5409 // CommandObjectMultiwordTargetStopHooks
5410 //-------------------------------------------------------------------------
5411 
5412 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword
5413 {
5414 public:
5415 
5416     CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) :
5417         CommandObjectMultiword (interpreter,
5418                                 "target stop-hook",
5419                                 "A set of commands for operating on debugger target stop-hooks.",
5420                                 "target stop-hook <subcommand> [<subcommand-options>]")
5421     {
5422         LoadSubCommand ("add",      CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter)));
5423         LoadSubCommand ("delete",   CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter)));
5424         LoadSubCommand ("disable",  CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
5425                                                                                                    false,
5426                                                                                                    "target stop-hook disable [<id>]",
5427                                                                                                    "Disable a stop-hook.",
5428                                                                                                    "target stop-hook disable")));
5429         LoadSubCommand ("enable",   CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
5430                                                                                                    true,
5431                                                                                                    "target stop-hook enable [<id>]",
5432                                                                                                    "Enable a stop-hook.",
5433                                                                                                    "target stop-hook enable")));
5434         LoadSubCommand ("list",     CommandObjectSP (new CommandObjectTargetStopHookList (interpreter)));
5435     }
5436 
5437     ~CommandObjectMultiwordTargetStopHooks()
5438     {
5439     }
5440 };
5441 
5442 
5443 
5444 #pragma mark CommandObjectMultiwordTarget
5445 
5446 //-------------------------------------------------------------------------
5447 // CommandObjectMultiwordTarget
5448 //-------------------------------------------------------------------------
5449 
5450 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) :
5451     CommandObjectMultiword (interpreter,
5452                             "target",
5453                             "A set of commands for operating on debugger targets.",
5454                             "target <subcommand> [<subcommand-options>]")
5455 {
5456 
5457     LoadSubCommand ("create",    CommandObjectSP (new CommandObjectTargetCreate (interpreter)));
5458     LoadSubCommand ("delete",    CommandObjectSP (new CommandObjectTargetDelete (interpreter)));
5459     LoadSubCommand ("list",      CommandObjectSP (new CommandObjectTargetList   (interpreter)));
5460     LoadSubCommand ("select",    CommandObjectSP (new CommandObjectTargetSelect (interpreter)));
5461     LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter)));
5462     LoadSubCommand ("modules",   CommandObjectSP (new CommandObjectTargetModules (interpreter)));
5463     LoadSubCommand ("symbols",   CommandObjectSP (new CommandObjectTargetSymbols (interpreter)));
5464     LoadSubCommand ("variable",  CommandObjectSP (new CommandObjectTargetVariable (interpreter)));
5465 }
5466 
5467 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget ()
5468 {
5469 }
5470 
5471 
5472