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