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                         const SymbolVendor *symbol_vendor = module->GetSymbolVendor();
3471                         if (symbol_vendor)
3472                         {
3473                             const FileSpec symfile_spec = symbol_vendor->GetMainFileSpec();
3474                             if (format_char == 'S')
3475                             {
3476                                 // Dump symbol file only if different from module file
3477                                 if (!symfile_spec || symfile_spec == module->GetFileSpec())
3478                                 {
3479                                     print_space = false;
3480                                     break;
3481                                 }
3482                                 // Add a newline and indent past the index
3483                                 strm.Printf ("\n%*s", indent, "");
3484                             }
3485                             DumpFullpath (strm, &symfile_spec, width);
3486                             dump_object_name = true;
3487                             break;
3488                         }
3489                         strm.Printf("%.*s", width, "<NONE>");
3490                     }
3491                     break;
3492 
3493                 case 'm':
3494                     module->GetModificationTime().Dump(&strm, width);
3495                     break;
3496 
3497                 case 'p':
3498                     strm.Printf("%p", static_cast<void*>(module));
3499                     break;
3500 
3501                 case 'u':
3502                     DumpModuleUUID(strm, module);
3503                     break;
3504 
3505                 default:
3506                     break;
3507             }
3508 
3509         }
3510         if (dump_object_name)
3511         {
3512             const char *object_name = module->GetObjectName().GetCString();
3513             if (object_name)
3514                 strm.Printf ("(%s)", object_name);
3515         }
3516         strm.EOL();
3517     }
3518 
3519     CommandOptions m_options;
3520 };
3521 
3522 OptionDefinition
3523 CommandObjectTargetModulesList::CommandOptions::g_option_table[] =
3524 {
3525     { LLDB_OPT_SET_1, false, "address",    'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Display the image at this address."},
3526     { LLDB_OPT_SET_1, false, "arch",       'A', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the architecture when listing images."},
3527     { LLDB_OPT_SET_1, false, "triple",     't', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the triple when listing images."},
3528     { 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."},
3529     { 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)."},
3530     { LLDB_OPT_SET_1, false, "uuid",       'u', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone,    "Display the UUID when listing images."},
3531     { LLDB_OPT_SET_1, false, "fullpath",   'f', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the fullpath to the image object file."},
3532     { LLDB_OPT_SET_1, false, "directory",  'd', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the directory with optional width for the image object file."},
3533     { LLDB_OPT_SET_1, false, "basename",   'b', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the basename with optional width for the image object file."},
3534     { LLDB_OPT_SET_1, false, "symfile",    's', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the fullpath to the image symbol file with optional width."},
3535     { 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."},
3536     { LLDB_OPT_SET_1, false, "mod-time",   'm', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the modification time with optional width of the module."},
3537     { 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."},
3538     { LLDB_OPT_SET_1, false, "pointer",    'p', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeNone,    "Display the module pointer."},
3539     { 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."},
3540     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
3541 };
3542 
3543 #pragma mark CommandObjectTargetModulesShowUnwind
3544 
3545 //----------------------------------------------------------------------
3546 // Lookup unwind information in images
3547 //----------------------------------------------------------------------
3548 
3549 class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed
3550 {
3551 public:
3552 
3553     enum
3554     {
3555         eLookupTypeInvalid = -1,
3556         eLookupTypeAddress = 0,
3557         eLookupTypeSymbol,
3558         eLookupTypeFunction,
3559         eLookupTypeFunctionOrSymbol,
3560         kNumLookupTypes
3561     };
3562 
3563     class CommandOptions : public Options
3564     {
3565     public:
3566 
3567         CommandOptions (CommandInterpreter &interpreter) :
3568             Options(interpreter),
3569             m_type(eLookupTypeInvalid),
3570             m_str(),
3571             m_addr(LLDB_INVALID_ADDRESS)
3572         {
3573         }
3574 
3575         virtual
3576         ~CommandOptions ()
3577         {
3578         }
3579 
3580         virtual Error
3581         SetOptionValue (uint32_t option_idx, const char *option_arg)
3582         {
3583             Error error;
3584 
3585             const int short_option = m_getopt_table[option_idx].val;
3586 
3587             switch (short_option)
3588             {
3589                 case 'a':
3590                 {
3591                     ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
3592                     m_str = option_arg;
3593                     m_type = eLookupTypeAddress;
3594                     m_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
3595                     if (m_addr == LLDB_INVALID_ADDRESS)
3596                         error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg);
3597                     break;
3598                 }
3599 
3600                 case 'n':
3601                 {
3602                     m_str = option_arg;
3603                     m_type = eLookupTypeFunctionOrSymbol;
3604                     break;
3605                 }
3606 
3607                 default:
3608                     error.SetErrorStringWithFormat ("unrecognized option %c.", short_option);
3609                     break;
3610             }
3611 
3612             return error;
3613         }
3614 
3615         void
3616         OptionParsingStarting ()
3617         {
3618             m_type = eLookupTypeInvalid;
3619             m_str.clear();
3620             m_addr = LLDB_INVALID_ADDRESS;
3621         }
3622 
3623         const OptionDefinition*
3624         GetDefinitions ()
3625         {
3626             return g_option_table;
3627         }
3628 
3629         // Options table: Required for subclasses of Options.
3630 
3631         static OptionDefinition g_option_table[];
3632 
3633         // Instance variables to hold the values for command options.
3634 
3635         int             m_type;         // Should be a eLookupTypeXXX enum after parsing options
3636         std::string     m_str;          // Holds name lookup
3637         lldb::addr_t    m_addr;         // Holds the address to lookup
3638     };
3639 
3640     CommandObjectTargetModulesShowUnwind (CommandInterpreter &interpreter) :
3641         CommandObjectParsed (interpreter,
3642                              "target modules show-unwind",
3643                              "Show synthesized unwind instructions for a function.",
3644                              NULL,
3645                              eFlagRequiresTarget        |
3646                              eFlagRequiresProcess       |
3647                              eFlagProcessMustBeLaunched |
3648                              eFlagProcessMustBePaused   ),
3649         m_options (interpreter)
3650     {
3651     }
3652 
3653     virtual
3654     ~CommandObjectTargetModulesShowUnwind ()
3655     {
3656     }
3657 
3658     virtual
3659     Options *
3660     GetOptions ()
3661     {
3662         return &m_options;
3663     }
3664 
3665 protected:
3666     bool
3667     DoExecute (Args& command,
3668              CommandReturnObject &result)
3669     {
3670         Target *target = m_exe_ctx.GetTargetPtr();
3671         Process *process = m_exe_ctx.GetProcessPtr();
3672         ABI *abi = NULL;
3673         if (process)
3674           abi = process->GetABI().get();
3675 
3676         if (process == NULL)
3677         {
3678             result.AppendError ("You must have a process running to use this command.");
3679             result.SetStatus (eReturnStatusFailed);
3680             return false;
3681         }
3682 
3683         ThreadList threads(process->GetThreadList());
3684         if (threads.GetSize() == 0)
3685         {
3686             result.AppendError ("The process must be paused to use this command.");
3687             result.SetStatus (eReturnStatusFailed);
3688             return false;
3689         }
3690 
3691         ThreadSP thread(threads.GetThreadAtIndex(0));
3692         if (thread.get() == NULL)
3693         {
3694             result.AppendError ("The process must be paused to use this command.");
3695             result.SetStatus (eReturnStatusFailed);
3696             return false;
3697         }
3698 
3699         SymbolContextList sc_list;
3700 
3701         if (m_options.m_type == eLookupTypeFunctionOrSymbol)
3702         {
3703             ConstString function_name (m_options.m_str.c_str());
3704             target->GetImages().FindFunctions (function_name, eFunctionNameTypeAuto, true, false, true, sc_list);
3705         }
3706         else if (m_options.m_type == eLookupTypeAddress && target)
3707         {
3708             Address addr;
3709             if (target->GetSectionLoadList().ResolveLoadAddress (m_options.m_addr, addr))
3710             {
3711                 SymbolContext sc;
3712                 ModuleSP module_sp (addr.GetModule());
3713                 module_sp->ResolveSymbolContextForAddress (addr, eSymbolContextEverything, sc);
3714                 if (sc.function || sc.symbol)
3715                 {
3716                     sc_list.Append(sc);
3717                 }
3718             }
3719         }
3720         else
3721         {
3722             result.AppendError ("address-expression or function name option must be specified.");
3723             result.SetStatus (eReturnStatusFailed);
3724             return false;
3725         }
3726 
3727         size_t num_matches = sc_list.GetSize();
3728         if (num_matches == 0)
3729         {
3730             result.AppendErrorWithFormat ("no unwind data found that matches '%s'.", m_options.m_str.c_str());
3731             result.SetStatus (eReturnStatusFailed);
3732             return false;
3733         }
3734 
3735         for (uint32_t idx = 0; idx < num_matches; idx++)
3736         {
3737             SymbolContext sc;
3738             sc_list.GetContextAtIndex(idx, sc);
3739             if (sc.symbol == NULL && sc.function == NULL)
3740                 continue;
3741             if (sc.module_sp.get() == NULL || sc.module_sp->GetObjectFile() == NULL)
3742                 continue;
3743             AddressRange range;
3744             if (!sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range))
3745                 continue;
3746             if (!range.GetBaseAddress().IsValid())
3747                 continue;
3748             ConstString funcname(sc.GetFunctionName());
3749             if (funcname.IsEmpty())
3750                 continue;
3751             addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
3752             if (abi)
3753                 start_addr = abi->FixCodeAddress(start_addr);
3754 
3755             FuncUnwindersSP func_unwinders_sp (sc.module_sp->GetObjectFile()->GetUnwindTable().GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
3756             if (func_unwinders_sp.get() == NULL)
3757                 continue;
3758 
3759             result.GetOutputStream().Printf("UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
3760 
3761             UnwindPlanSP non_callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread.get(), -1);
3762             if (non_callsite_unwind_plan.get())
3763             {
3764                 result.GetOutputStream().Printf("Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n", non_callsite_unwind_plan->GetSourceName().AsCString());
3765             }
3766             UnwindPlanSP callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(*target, -1);
3767             if (callsite_unwind_plan.get())
3768             {
3769                 result.GetOutputStream().Printf("Synchronous (restricted to call-sites) UnwindPlan is '%s'\n", callsite_unwind_plan->GetSourceName().AsCString());
3770             }
3771             UnwindPlanSP fast_unwind_plan = func_unwinders_sp->GetUnwindPlanFastUnwind(*thread.get());
3772             if (fast_unwind_plan.get())
3773             {
3774                 result.GetOutputStream().Printf("Fast UnwindPlan is '%s'\n", fast_unwind_plan->GetSourceName().AsCString());
3775             }
3776 
3777             result.GetOutputStream().Printf("\n");
3778 
3779             UnwindPlanSP assembly_sp = func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread.get(), 0);
3780             if (assembly_sp)
3781             {
3782                 result.GetOutputStream().Printf("Assembly language inspection UnwindPlan:\n");
3783                 assembly_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3784                 result.GetOutputStream().Printf("\n");
3785             }
3786 
3787 
3788             UnwindPlanSP ehframe_sp = func_unwinders_sp->GetEHFrameUnwindPlan(*target, 0);
3789             if (ehframe_sp)
3790             {
3791                 result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3792                 ehframe_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3793                 result.GetOutputStream().Printf("\n");
3794             }
3795 
3796             UnwindPlanSP ehframe_augmented_sp = func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread.get(), 0);
3797             if (ehframe_augmented_sp)
3798             {
3799                 result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3800                 ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3801                 result.GetOutputStream().Printf("\n");
3802             }
3803 
3804             UnwindPlanSP compact_unwind_sp = func_unwinders_sp->GetCompactUnwindUnwindPlan(*target, 0);
3805             if (compact_unwind_sp)
3806             {
3807                 result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3808                 compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3809                 result.GetOutputStream().Printf("\n");
3810             }
3811 
3812             if (fast_unwind_plan)
3813             {
3814                 result.GetOutputStream().Printf("Fast UnwindPlan:\n");
3815                 fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3816                 result.GetOutputStream().Printf("\n");
3817             }
3818 
3819             ABISP abi_sp = process->GetABI();
3820             if (abi_sp)
3821             {
3822                 UnwindPlan arch_default(lldb::eRegisterKindGeneric);
3823                 if (abi_sp->CreateDefaultUnwindPlan (arch_default))
3824                 {
3825                     result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3826                     arch_default.Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3827                     result.GetOutputStream().Printf("\n");
3828                 }
3829 
3830                 UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
3831                 if (abi_sp->CreateFunctionEntryUnwindPlan (arch_entry))
3832                 {
3833                     result.GetOutputStream().Printf("Arch default at entry point UnwindPlan:\n");
3834                     arch_entry.Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3835                     result.GetOutputStream().Printf("\n");
3836                 }
3837             }
3838 
3839             result.GetOutputStream().Printf ("\n");
3840         }
3841         return result.Succeeded();
3842     }
3843 
3844     CommandOptions m_options;
3845 };
3846 
3847 OptionDefinition
3848 CommandObjectTargetModulesShowUnwind::CommandOptions::g_option_table[] =
3849 {
3850     { LLDB_OPT_SET_1,   false,  "name",       'n', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name."},
3851     { LLDB_OPT_SET_2,   false,  "address",    'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address"},
3852     { 0,                false, NULL,           0, 0,                 NULL, NULL, 0, eArgTypeNone, NULL }
3853 };
3854 
3855 //----------------------------------------------------------------------
3856 // Lookup information in images
3857 //----------------------------------------------------------------------
3858 class CommandObjectTargetModulesLookup : public CommandObjectParsed
3859 {
3860 public:
3861     enum
3862     {
3863         eLookupTypeInvalid = -1,
3864         eLookupTypeAddress = 0,
3865         eLookupTypeSymbol,
3866         eLookupTypeFileLine,    // Line is optional
3867         eLookupTypeFunction,
3868         eLookupTypeFunctionOrSymbol,
3869         eLookupTypeType,
3870         kNumLookupTypes
3871     };
3872 
3873     class CommandOptions : public Options
3874     {
3875     public:
3876         CommandOptions (CommandInterpreter &interpreter) :
3877         Options(interpreter)
3878         {
3879             OptionParsingStarting();
3880         }
3881 
3882         virtual
3883         ~CommandOptions ()
3884         {
3885         }
3886 
3887         virtual Error
3888         SetOptionValue (uint32_t option_idx, const char *option_arg)
3889         {
3890             Error error;
3891 
3892             const int short_option = m_getopt_table[option_idx].val;
3893 
3894             switch (short_option)
3895             {
3896                 case 'a':
3897                     {
3898                         m_type = eLookupTypeAddress;
3899                         ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
3900                         m_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
3901                     }
3902                     break;
3903 
3904                 case 'o':
3905                     m_offset = StringConvert::ToUInt64(option_arg, LLDB_INVALID_ADDRESS);
3906                     if (m_offset == LLDB_INVALID_ADDRESS)
3907                         error.SetErrorStringWithFormat ("invalid offset string '%s'", option_arg);
3908                     break;
3909 
3910                 case 's':
3911                     m_str = option_arg;
3912                     m_type = eLookupTypeSymbol;
3913                     break;
3914 
3915                 case 'f':
3916                     m_file.SetFile (option_arg, false);
3917                     m_type = eLookupTypeFileLine;
3918                     break;
3919 
3920                 case 'i':
3921                     m_include_inlines = false;
3922                     break;
3923 
3924                 case 'l':
3925                     m_line_number = StringConvert::ToUInt32(option_arg, UINT32_MAX);
3926                     if (m_line_number == UINT32_MAX)
3927                         error.SetErrorStringWithFormat ("invalid line number string '%s'", option_arg);
3928                     else if (m_line_number == 0)
3929                         error.SetErrorString ("zero is an invalid line number");
3930                     m_type = eLookupTypeFileLine;
3931                     break;
3932 
3933                 case 'F':
3934                     m_str = option_arg;
3935                     m_type = eLookupTypeFunction;
3936                     break;
3937 
3938                 case 'n':
3939                     m_str = option_arg;
3940                     m_type = eLookupTypeFunctionOrSymbol;
3941                     break;
3942 
3943                 case 't':
3944                     m_str = option_arg;
3945                     m_type = eLookupTypeType;
3946                     break;
3947 
3948                 case 'v':
3949                     m_verbose = 1;
3950                     break;
3951 
3952                 case 'A':
3953                     m_print_all = true;
3954                     break;
3955 
3956                 case 'r':
3957                     m_use_regex = true;
3958                     break;
3959             }
3960 
3961             return error;
3962         }
3963 
3964         void
3965         OptionParsingStarting ()
3966         {
3967             m_type = eLookupTypeInvalid;
3968             m_str.clear();
3969             m_file.Clear();
3970             m_addr = LLDB_INVALID_ADDRESS;
3971             m_offset = 0;
3972             m_line_number = 0;
3973             m_use_regex = false;
3974             m_include_inlines = true;
3975             m_verbose = false;
3976             m_print_all = false;
3977         }
3978 
3979         const OptionDefinition*
3980         GetDefinitions ()
3981         {
3982             return g_option_table;
3983         }
3984 
3985         // Options table: Required for subclasses of Options.
3986 
3987         static OptionDefinition g_option_table[];
3988         int             m_type;         // Should be a eLookupTypeXXX enum after parsing options
3989         std::string     m_str;          // Holds name lookup
3990         FileSpec        m_file;         // Files for file lookups
3991         lldb::addr_t    m_addr;         // Holds the address to lookup
3992         lldb::addr_t    m_offset;       // Subtract this offset from m_addr before doing lookups.
3993         uint32_t        m_line_number;  // Line number for file+line lookups
3994         bool            m_use_regex;    // Name lookups in m_str are regular expressions.
3995         bool            m_include_inlines;// Check for inline entries when looking up by file/line.
3996         bool            m_verbose;      // Enable verbose lookup info
3997         bool            m_print_all;    // Print all matches, even in cases where there's a best match.
3998     };
3999 
4000     CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) :
4001         CommandObjectParsed (interpreter,
4002                              "target modules lookup",
4003                              "Look up information within executable and dependent shared library images.",
4004                              NULL,
4005                              eFlagRequiresTarget),
4006         m_options (interpreter)
4007     {
4008         CommandArgumentEntry arg;
4009         CommandArgumentData file_arg;
4010 
4011         // Define the first (and only) variant of this arg.
4012         file_arg.arg_type = eArgTypeFilename;
4013         file_arg.arg_repetition = eArgRepeatStar;
4014 
4015         // There is only one variant this argument could be; put it into the argument entry.
4016         arg.push_back (file_arg);
4017 
4018         // Push the data for the first argument into the m_arguments vector.
4019         m_arguments.push_back (arg);
4020     }
4021 
4022     virtual
4023     ~CommandObjectTargetModulesLookup ()
4024     {
4025     }
4026 
4027     virtual Options *
4028     GetOptions ()
4029     {
4030         return &m_options;
4031     }
4032 
4033     bool
4034     LookupHere (CommandInterpreter &interpreter, CommandReturnObject &result, bool &syntax_error)
4035     {
4036         switch (m_options.m_type)
4037         {
4038             case eLookupTypeAddress:
4039             case eLookupTypeFileLine:
4040             case eLookupTypeFunction:
4041             case eLookupTypeFunctionOrSymbol:
4042             case eLookupTypeSymbol:
4043             default:
4044                 return false;
4045             case eLookupTypeType:
4046                 break;
4047         }
4048 
4049         StackFrameSP frame = m_exe_ctx.GetFrameSP();
4050 
4051         if (!frame)
4052             return false;
4053 
4054         const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
4055 
4056         if (!sym_ctx.module_sp)
4057             return false;
4058 
4059         switch (m_options.m_type)
4060         {
4061         default:
4062             return false;
4063         case eLookupTypeType:
4064             if (!m_options.m_str.empty())
4065             {
4066                 if (LookupTypeHere (m_interpreter,
4067                                     result.GetOutputStream(),
4068                                     sym_ctx,
4069                                     m_options.m_str.c_str(),
4070                                     m_options.m_use_regex))
4071                 {
4072                     result.SetStatus(eReturnStatusSuccessFinishResult);
4073                     return true;
4074                 }
4075             }
4076             break;
4077         }
4078 
4079         return true;
4080     }
4081 
4082     bool
4083     LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
4084     {
4085         switch (m_options.m_type)
4086         {
4087             case eLookupTypeAddress:
4088                 if (m_options.m_addr != LLDB_INVALID_ADDRESS)
4089                 {
4090                     if (LookupAddressInModule (m_interpreter,
4091                                                result.GetOutputStream(),
4092                                                module,
4093                                                eSymbolContextEverything | (m_options.m_verbose ? eSymbolContextVariable : 0),
4094                                                m_options.m_addr,
4095                                                m_options.m_offset,
4096                                                m_options.m_verbose))
4097                     {
4098                         result.SetStatus(eReturnStatusSuccessFinishResult);
4099                         return true;
4100                     }
4101                 }
4102                 break;
4103 
4104             case eLookupTypeSymbol:
4105                 if (!m_options.m_str.empty())
4106                 {
4107                     if (LookupSymbolInModule (m_interpreter,
4108                                               result.GetOutputStream(),
4109                                               module,
4110                                               m_options.m_str.c_str(),
4111                                               m_options.m_use_regex,
4112                                               m_options.m_verbose))
4113                     {
4114                         result.SetStatus(eReturnStatusSuccessFinishResult);
4115                         return true;
4116                     }
4117                 }
4118                 break;
4119 
4120             case eLookupTypeFileLine:
4121                 if (m_options.m_file)
4122                 {
4123                     if (LookupFileAndLineInModule (m_interpreter,
4124                                                    result.GetOutputStream(),
4125                                                    module,
4126                                                    m_options.m_file,
4127                                                    m_options.m_line_number,
4128                                                    m_options.m_include_inlines,
4129                                                    m_options.m_verbose))
4130                     {
4131                         result.SetStatus(eReturnStatusSuccessFinishResult);
4132                         return true;
4133                     }
4134                 }
4135                 break;
4136 
4137             case eLookupTypeFunctionOrSymbol:
4138             case eLookupTypeFunction:
4139                 if (!m_options.m_str.empty())
4140                 {
4141                     if (LookupFunctionInModule (m_interpreter,
4142                                                 result.GetOutputStream(),
4143                                                 module,
4144                                                 m_options.m_str.c_str(),
4145                                                 m_options.m_use_regex,
4146                                                 m_options.m_include_inlines,
4147                                                 m_options.m_type == eLookupTypeFunctionOrSymbol, // include symbols
4148                                                 m_options.m_verbose))
4149                     {
4150                         result.SetStatus(eReturnStatusSuccessFinishResult);
4151                         return true;
4152                     }
4153                 }
4154                 break;
4155 
4156             case eLookupTypeType:
4157                 if (!m_options.m_str.empty())
4158                 {
4159                     if (LookupTypeInModule (m_interpreter,
4160                                             result.GetOutputStream(),
4161                                             module,
4162                                             m_options.m_str.c_str(),
4163                                             m_options.m_use_regex))
4164                     {
4165                         result.SetStatus(eReturnStatusSuccessFinishResult);
4166                         return true;
4167                     }
4168                 }
4169                 break;
4170 
4171             default:
4172                 m_options.GenerateOptionUsage (result.GetErrorStream(), this);
4173                 syntax_error = true;
4174                 break;
4175         }
4176 
4177         result.SetStatus (eReturnStatusFailed);
4178         return false;
4179     }
4180 
4181 protected:
4182     virtual bool
4183     DoExecute (Args& command,
4184              CommandReturnObject &result)
4185     {
4186         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
4187         if (target == NULL)
4188         {
4189             result.AppendError ("invalid target, create a debug target using the 'target create' command");
4190             result.SetStatus (eReturnStatusFailed);
4191             return false;
4192         }
4193         else
4194         {
4195             bool syntax_error = false;
4196             uint32_t i;
4197             uint32_t num_successful_lookups = 0;
4198             uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
4199             result.GetOutputStream().SetAddressByteSize(addr_byte_size);
4200             result.GetErrorStream().SetAddressByteSize(addr_byte_size);
4201             // Dump all sections for all modules images
4202 
4203             if (command.GetArgumentCount() == 0)
4204             {
4205                 ModuleSP current_module;
4206 
4207                 // Where it is possible to look in the current symbol context
4208                 // first, try that.  If this search was successful and --all
4209                 // was not passed, don't print anything else.
4210                 if (LookupHere (m_interpreter, result, syntax_error))
4211                 {
4212                     result.GetOutputStream().EOL();
4213                     num_successful_lookups++;
4214                     if (!m_options.m_print_all)
4215                     {
4216                         result.SetStatus (eReturnStatusSuccessFinishResult);
4217                         return result.Succeeded();
4218                     }
4219                 }
4220 
4221                 // Dump all sections for all other modules
4222 
4223                 const ModuleList &target_modules = target->GetImages();
4224                 Mutex::Locker modules_locker(target_modules.GetMutex());
4225                 const size_t num_modules = target_modules.GetSize();
4226                 if (num_modules > 0)
4227                 {
4228                     for (i = 0; i<num_modules && syntax_error == false; ++i)
4229                     {
4230                         Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked(i);
4231 
4232                         if (module_pointer != current_module.get() &&
4233                             LookupInModule (m_interpreter, target_modules.GetModulePointerAtIndexUnlocked(i), result, syntax_error))
4234                         {
4235                             result.GetOutputStream().EOL();
4236                             num_successful_lookups++;
4237                         }
4238                     }
4239                 }
4240                 else
4241                 {
4242                     result.AppendError ("the target has no associated executable images");
4243                     result.SetStatus (eReturnStatusFailed);
4244                     return false;
4245                 }
4246             }
4247             else
4248             {
4249                 // Dump specified images (by basename or fullpath)
4250                 const char *arg_cstr;
4251                 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i)
4252                 {
4253                     ModuleList module_list;
4254                     const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, false);
4255                     if (num_matches > 0)
4256                     {
4257                         for (size_t j=0; j<num_matches; ++j)
4258                         {
4259                             Module *module = module_list.GetModulePointerAtIndex(j);
4260                             if (module)
4261                             {
4262                                 if (LookupInModule (m_interpreter, module, result, syntax_error))
4263                                 {
4264                                     result.GetOutputStream().EOL();
4265                                     num_successful_lookups++;
4266                                 }
4267                             }
4268                         }
4269                     }
4270                     else
4271                         result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
4272                 }
4273             }
4274 
4275             if (num_successful_lookups > 0)
4276                 result.SetStatus (eReturnStatusSuccessFinishResult);
4277             else
4278                 result.SetStatus (eReturnStatusFailed);
4279         }
4280         return result.Succeeded();
4281     }
4282 
4283     CommandOptions m_options;
4284 };
4285 
4286 OptionDefinition
4287 CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] =
4288 {
4289     { LLDB_OPT_SET_1,   true,  "address",    'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules."},
4290     { 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."},
4291     { LLDB_OPT_SET_2| LLDB_OPT_SET_4 | LLDB_OPT_SET_5
4292       /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */ ,
4293                         false, "regex",      'r', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone,             "The <name> argument for name lookups are regular expressions."},
4294     { 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."},
4295     { 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."},
4296     { 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)."},
4297     { LLDB_OPT_SET_FROM_TO(3,5),
4298                         false, "no-inlines", 'i', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone,             "Ignore inline entries (must be used in conjunction with --file or --function)."},
4299     { 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."},
4300     { 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."},
4301     { 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."},
4302     { LLDB_OPT_SET_ALL, false, "verbose",    'v', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone,             "Enable verbose lookup information."},
4303     { 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."},
4304     { 0,                false, NULL,           0, 0,                 NULL, NULL, 0, eArgTypeNone,             NULL }
4305 };
4306 
4307 
4308 #pragma mark CommandObjectMultiwordImageSearchPaths
4309 
4310 //-------------------------------------------------------------------------
4311 // CommandObjectMultiwordImageSearchPaths
4312 //-------------------------------------------------------------------------
4313 
4314 class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword
4315 {
4316 public:
4317     CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) :
4318     CommandObjectMultiword (interpreter,
4319                             "target modules search-paths",
4320                             "A set of commands for operating on debugger target image search paths.",
4321                             "target modules search-paths <subcommand> [<subcommand-options>]")
4322     {
4323         LoadSubCommand ("add",     CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter)));
4324         LoadSubCommand ("clear",   CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter)));
4325         LoadSubCommand ("insert",  CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter)));
4326         LoadSubCommand ("list",    CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter)));
4327         LoadSubCommand ("query",   CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter)));
4328     }
4329 
4330     ~CommandObjectTargetModulesImageSearchPaths()
4331     {
4332     }
4333 };
4334 
4335 
4336 
4337 #pragma mark CommandObjectTargetModules
4338 
4339 //-------------------------------------------------------------------------
4340 // CommandObjectTargetModules
4341 //-------------------------------------------------------------------------
4342 
4343 class CommandObjectTargetModules : public CommandObjectMultiword
4344 {
4345 public:
4346     //------------------------------------------------------------------
4347     // Constructors and Destructors
4348     //------------------------------------------------------------------
4349     CommandObjectTargetModules(CommandInterpreter &interpreter) :
4350         CommandObjectMultiword (interpreter,
4351                                 "target modules",
4352                                 "A set of commands for accessing information for one or more target modules.",
4353                                 "target modules <sub-command> ...")
4354     {
4355         LoadSubCommand ("add",          CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter)));
4356         LoadSubCommand ("load",         CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter)));
4357         LoadSubCommand ("dump",         CommandObjectSP (new CommandObjectTargetModulesDump (interpreter)));
4358         LoadSubCommand ("list",         CommandObjectSP (new CommandObjectTargetModulesList (interpreter)));
4359         LoadSubCommand ("lookup",       CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter)));
4360         LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter)));
4361         LoadSubCommand ("show-unwind",  CommandObjectSP (new CommandObjectTargetModulesShowUnwind (interpreter)));
4362 
4363     }
4364     virtual
4365     ~CommandObjectTargetModules()
4366     {
4367     }
4368 
4369 private:
4370     //------------------------------------------------------------------
4371     // For CommandObjectTargetModules only
4372     //------------------------------------------------------------------
4373     DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules);
4374 };
4375 
4376 
4377 
4378 class CommandObjectTargetSymbolsAdd : public CommandObjectParsed
4379 {
4380 public:
4381     CommandObjectTargetSymbolsAdd (CommandInterpreter &interpreter) :
4382         CommandObjectParsed (interpreter,
4383                              "target symbols add",
4384                              "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.",
4385                              "target symbols add [<symfile>]", eFlagRequiresTarget),
4386         m_option_group (interpreter),
4387         m_file_option (LLDB_OPT_SET_1, false, "shlib", 's', CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Fullpath or basename for module to find debug symbols for."),
4388         m_current_frame_option (LLDB_OPT_SET_2, false, "frame", 'F', "Locate the debug symbols the currently selected frame.", false, true)
4389 
4390     {
4391         m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
4392         m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
4393         m_option_group.Append (&m_current_frame_option, LLDB_OPT_SET_2, LLDB_OPT_SET_2);
4394         m_option_group.Finalize();
4395     }
4396 
4397     virtual
4398     ~CommandObjectTargetSymbolsAdd ()
4399     {
4400     }
4401 
4402     virtual int
4403     HandleArgumentCompletion (Args &input,
4404                               int &cursor_index,
4405                               int &cursor_char_position,
4406                               OptionElementVector &opt_element_vector,
4407                               int match_start_point,
4408                               int max_return_elements,
4409                               bool &word_complete,
4410                               StringList &matches)
4411     {
4412         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
4413         completion_str.erase (cursor_char_position);
4414 
4415         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
4416                                                              CommandCompletions::eDiskFileCompletion,
4417                                                              completion_str.c_str(),
4418                                                              match_start_point,
4419                                                              max_return_elements,
4420                                                              NULL,
4421                                                              word_complete,
4422                                                              matches);
4423         return matches.GetSize();
4424     }
4425 
4426     virtual Options *
4427     GetOptions ()
4428     {
4429         return &m_option_group;
4430     }
4431 
4432 protected:
4433     bool
4434     AddModuleSymbols (Target *target,
4435                       ModuleSpec &module_spec,
4436                       bool &flush,
4437                       CommandReturnObject &result)
4438     {
4439         const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
4440         if (symbol_fspec)
4441         {
4442             char symfile_path[PATH_MAX];
4443             symbol_fspec.GetPath (symfile_path, sizeof(symfile_path));
4444 
4445             if (!module_spec.GetUUID().IsValid())
4446             {
4447                 if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
4448                     module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
4449             }
4450             // We now have a module that represents a symbol file
4451             // that can be used for a module that might exist in the
4452             // current target, so we need to find that module in the
4453             // target
4454             ModuleList matching_module_list;
4455 
4456             size_t num_matches = 0;
4457             // First extract all module specs from the symbol file
4458             lldb_private::ModuleSpecList symfile_module_specs;
4459             if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(), 0, 0, symfile_module_specs))
4460             {
4461                 // Now extract the module spec that matches the target architecture
4462                 ModuleSpec target_arch_module_spec;
4463                 ModuleSpec symfile_module_spec;
4464                 target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
4465                 if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec, symfile_module_spec))
4466                 {
4467                     // See if it has a UUID?
4468                     if (symfile_module_spec.GetUUID().IsValid())
4469                     {
4470                         // It has a UUID, look for this UUID in the target modules
4471                         ModuleSpec symfile_uuid_module_spec;
4472                         symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4473                         num_matches = target->GetImages().FindModules (symfile_uuid_module_spec, matching_module_list);
4474                     }
4475                 }
4476 
4477                 if (num_matches == 0)
4478                 {
4479                     // No matches yet, iterate through the module specs to find a UUID value that
4480                     // we can match up to an image in our target
4481                     const size_t num_symfile_module_specs = symfile_module_specs.GetSize();
4482                     for (size_t i=0; i<num_symfile_module_specs && num_matches == 0; ++i)
4483                     {
4484                         if (symfile_module_specs.GetModuleSpecAtIndex(i, symfile_module_spec))
4485                         {
4486                             if (symfile_module_spec.GetUUID().IsValid())
4487                             {
4488                                 // It has a UUID, look for this UUID in the target modules
4489                                 ModuleSpec symfile_uuid_module_spec;
4490                                 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4491                                 num_matches = target->GetImages().FindModules (symfile_uuid_module_spec, matching_module_list);
4492                             }
4493                         }
4494                     }
4495                 }
4496             }
4497 
4498             // Just try to match up the file by basename if we have no matches at this point
4499             if (num_matches == 0)
4500                 num_matches = target->GetImages().FindModules (module_spec, matching_module_list);
4501 
4502             while (num_matches == 0)
4503             {
4504                 ConstString filename_no_extension(module_spec.GetFileSpec().GetFileNameStrippingExtension());
4505                 // Empty string returned, lets bail
4506                 if (!filename_no_extension)
4507                     break;
4508 
4509                 // Check if there was no extension to strip and the basename is the same
4510                 if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
4511                     break;
4512 
4513                 // Replace basename with one less extension
4514                 module_spec.GetFileSpec().GetFilename() = filename_no_extension;
4515 
4516                 num_matches = target->GetImages().FindModules (module_spec, matching_module_list);
4517             }
4518 
4519             if (num_matches > 1)
4520             {
4521                 result.AppendErrorWithFormat ("multiple modules match symbol file '%s', use the --uuid option to resolve the ambiguity.\n", symfile_path);
4522             }
4523             else if (num_matches == 1)
4524             {
4525                 ModuleSP module_sp (matching_module_list.GetModuleAtIndex(0));
4526 
4527                 // The module has not yet created its symbol vendor, we can just
4528                 // give the existing target module the symfile path to use for
4529                 // when it decides to create it!
4530                 module_sp->SetSymbolFileFileSpec (symbol_fspec);
4531 
4532                 SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(true, &result.GetErrorStream());
4533                 if (symbol_vendor)
4534                 {
4535                     SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
4536 
4537                     if (symbol_file)
4538                     {
4539                         ObjectFile *object_file = symbol_file->GetObjectFile();
4540 
4541                         if (object_file && object_file->GetFileSpec() == symbol_fspec)
4542                         {
4543                             // Provide feedback that the symfile has been successfully added.
4544                             const FileSpec &module_fs = module_sp->GetFileSpec();
4545                             result.AppendMessageWithFormat("symbol file '%s' has been added to '%s'\n",
4546                                                            symfile_path,
4547                                                            module_fs.GetPath().c_str());
4548 
4549                             // Let clients know something changed in the module
4550                             // if it is currently loaded
4551                             ModuleList module_list;
4552                             module_list.Append (module_sp);
4553                             target->SymbolsDidLoad (module_list);
4554 
4555                             // Make sure we load any scripting resources that may be embedded
4556                             // in the debug info files in case the platform supports that.
4557                             Error error;
4558                             StreamString feedback_stream;
4559                             module_sp->LoadScriptingResourceInTarget (target, error,&feedback_stream);
4560                             if (error.Fail() && error.AsCString())
4561                                 result.AppendWarningWithFormat("unable to load scripting data for module %s - error reported was %s",
4562                                                                module_sp->GetFileSpec().GetFileNameStrippingExtension().GetCString(),
4563                                                                error.AsCString());
4564                             else if (feedback_stream.GetSize())
4565                                 result.AppendWarningWithFormat("%s",feedback_stream.GetData());
4566 
4567                             flush = true;
4568                             result.SetStatus (eReturnStatusSuccessFinishResult);
4569                             return true;
4570                         }
4571                     }
4572                 }
4573                 // Clear the symbol file spec if anything went wrong
4574                 module_sp->SetSymbolFileFileSpec (FileSpec());
4575             }
4576 
4577             if (module_spec.GetUUID().IsValid())
4578             {
4579                 StreamString ss_symfile_uuid;
4580                 module_spec.GetUUID().Dump(&ss_symfile_uuid);
4581                 result.AppendErrorWithFormat ("symbol file '%s' (%s) does not match any existing module%s\n",
4582                                               symfile_path,
4583                                               ss_symfile_uuid.GetData(),
4584                                               (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
4585                                                 ? "\n       please specify the full path to the symbol file"
4586                                                 : "");
4587             }
4588             else
4589             {
4590                 result.AppendErrorWithFormat ("symbol file '%s' does not match any existing module%s\n",
4591                                               symfile_path,
4592                                               (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
4593                                                 ? "\n       please specify the full path to the symbol file"
4594                                                 : "");
4595             }
4596         }
4597         else
4598         {
4599             result.AppendError ("one or more executable image paths must be specified");
4600         }
4601         result.SetStatus (eReturnStatusFailed);
4602         return false;
4603     }
4604 
4605     virtual bool
4606     DoExecute (Args& args,
4607              CommandReturnObject &result)
4608     {
4609         Target *target = m_exe_ctx.GetTargetPtr();
4610         result.SetStatus (eReturnStatusFailed);
4611         bool flush = false;
4612         ModuleSpec module_spec;
4613         const bool uuid_option_set = m_uuid_option_group.GetOptionValue().OptionWasSet();
4614         const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4615         const bool frame_option_set = m_current_frame_option.GetOptionValue().OptionWasSet();
4616 
4617         const size_t argc = args.GetArgumentCount();
4618         if (argc == 0)
4619         {
4620             if (uuid_option_set || file_option_set || frame_option_set)
4621             {
4622                 bool success = false;
4623                 bool error_set = false;
4624                 if (frame_option_set)
4625                 {
4626                     Process *process = m_exe_ctx.GetProcessPtr();
4627                     if (process)
4628                     {
4629                         const StateType process_state = process->GetState();
4630                         if (StateIsStoppedState (process_state, true))
4631                         {
4632                             StackFrame *frame = m_exe_ctx.GetFramePtr();
4633                             if (frame)
4634                             {
4635                                 ModuleSP frame_module_sp (frame->GetSymbolContext(eSymbolContextModule).module_sp);
4636                                 if (frame_module_sp)
4637                                 {
4638                                     if (frame_module_sp->GetPlatformFileSpec().Exists())
4639                                     {
4640                                         module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
4641                                         module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
4642                                     }
4643                                     module_spec.GetUUID() = frame_module_sp->GetUUID();
4644                                     success = module_spec.GetUUID().IsValid() || module_spec.GetFileSpec();
4645                                 }
4646                                 else
4647                                 {
4648                                     result.AppendError ("frame has no module");
4649                                     error_set = true;
4650                                 }
4651                             }
4652                             else
4653                             {
4654                                 result.AppendError ("invalid current frame");
4655                                 error_set = true;
4656                             }
4657                         }
4658                         else
4659                         {
4660                             result.AppendErrorWithFormat ("process is not stopped: %s", StateAsCString(process_state));
4661                             error_set = true;
4662                         }
4663                     }
4664                     else
4665                     {
4666                         result.AppendError ("a process must exist in order to use the --frame option");
4667                         error_set = true;
4668                     }
4669                 }
4670                 else
4671                 {
4672                     if (uuid_option_set)
4673                     {
4674                         module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue();
4675                         success |= module_spec.GetUUID().IsValid();
4676                     }
4677                     else if (file_option_set)
4678                     {
4679                         module_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue();
4680                         ModuleSP module_sp (target->GetImages().FindFirstModule(module_spec));
4681                         if (module_sp)
4682                         {
4683                             module_spec.GetFileSpec() = module_sp->GetFileSpec();
4684                             module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();
4685                             module_spec.GetUUID() = module_sp->GetUUID();
4686                             module_spec.GetArchitecture() = module_sp->GetArchitecture();
4687                         }
4688                         else
4689                         {
4690                             module_spec.GetArchitecture() = target->GetArchitecture();
4691                         }
4692                         success |= module_spec.GetFileSpec().Exists();
4693                     }
4694                 }
4695 
4696                 if (success)
4697                 {
4698                     if (Symbols::DownloadObjectAndSymbolFile (module_spec))
4699                     {
4700                         if (module_spec.GetSymbolFileSpec())
4701                             success = AddModuleSymbols (target, module_spec, flush, result);
4702                     }
4703                 }
4704 
4705                 if (!success && !error_set)
4706                 {
4707                     StreamString error_strm;
4708                     if (uuid_option_set)
4709                     {
4710                         error_strm.PutCString("unable to find debug symbols for UUID ");
4711                         module_spec.GetUUID().Dump (&error_strm);
4712                     }
4713                     else if (file_option_set)
4714                     {
4715                         error_strm.PutCString("unable to find debug symbols for the executable file ");
4716                         error_strm << module_spec.GetFileSpec();
4717                     }
4718                     else if (frame_option_set)
4719                     {
4720                         error_strm.PutCString("unable to find debug symbols for the current frame");
4721                     }
4722                     result.AppendError (error_strm.GetData());
4723                 }
4724             }
4725             else
4726             {
4727                 result.AppendError ("one or more symbol file paths must be specified, or options must be specified");
4728             }
4729         }
4730         else
4731         {
4732             if (uuid_option_set)
4733             {
4734                 result.AppendError ("specify either one or more paths to symbol files or use the --uuid option without arguments");
4735             }
4736             else if (file_option_set)
4737             {
4738                 result.AppendError ("specify either one or more paths to symbol files or use the --file option without arguments");
4739             }
4740             else if (frame_option_set)
4741             {
4742                 result.AppendError ("specify either one or more paths to symbol files or use the --frame option without arguments");
4743             }
4744             else
4745             {
4746                 PlatformSP platform_sp (target->GetPlatform());
4747 
4748                 for (size_t i=0; i<argc; ++i)
4749                 {
4750                     const char *symfile_path = args.GetArgumentAtIndex(i);
4751                     if (symfile_path)
4752                     {
4753                         module_spec.GetSymbolFileSpec().SetFile(symfile_path, true);
4754                         if (platform_sp)
4755                         {
4756                             FileSpec symfile_spec;
4757                             if (platform_sp->ResolveSymbolFile(*target, module_spec, symfile_spec).Success())
4758                                 module_spec.GetSymbolFileSpec() = symfile_spec;
4759                         }
4760 
4761                         ArchSpec arch;
4762                         bool symfile_exists = module_spec.GetSymbolFileSpec().Exists();
4763 
4764                         if (symfile_exists)
4765                         {
4766                             if (!AddModuleSymbols (target, module_spec, flush, result))
4767                                 break;
4768                         }
4769                         else
4770                         {
4771                             char resolved_symfile_path[PATH_MAX];
4772                             if (module_spec.GetSymbolFileSpec().GetPath (resolved_symfile_path, sizeof(resolved_symfile_path)))
4773                             {
4774                                 if (strcmp (resolved_symfile_path, symfile_path) != 0)
4775                                 {
4776                                     result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", symfile_path, resolved_symfile_path);
4777                                     break;
4778                                 }
4779                             }
4780                             result.AppendErrorWithFormat ("invalid module path '%s'\n", symfile_path);
4781                             break;
4782                         }
4783                     }
4784                 }
4785             }
4786         }
4787 
4788         if (flush)
4789         {
4790             Process *process = m_exe_ctx.GetProcessPtr();
4791             if (process)
4792                 process->Flush();
4793         }
4794         return result.Succeeded();
4795     }
4796 
4797     OptionGroupOptions m_option_group;
4798     OptionGroupUUID m_uuid_option_group;
4799     OptionGroupFile m_file_option;
4800     OptionGroupBoolean m_current_frame_option;
4801 };
4802 
4803 
4804 #pragma mark CommandObjectTargetSymbols
4805 
4806 //-------------------------------------------------------------------------
4807 // CommandObjectTargetSymbols
4808 //-------------------------------------------------------------------------
4809 
4810 class CommandObjectTargetSymbols : public CommandObjectMultiword
4811 {
4812 public:
4813     //------------------------------------------------------------------
4814     // Constructors and Destructors
4815     //------------------------------------------------------------------
4816     CommandObjectTargetSymbols(CommandInterpreter &interpreter) :
4817         CommandObjectMultiword (interpreter,
4818                             "target symbols",
4819                             "A set of commands for adding and managing debug symbol files.",
4820                             "target symbols <sub-command> ...")
4821     {
4822         LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetSymbolsAdd (interpreter)));
4823 
4824     }
4825     virtual
4826     ~CommandObjectTargetSymbols()
4827     {
4828     }
4829 
4830 private:
4831     //------------------------------------------------------------------
4832     // For CommandObjectTargetModules only
4833     //------------------------------------------------------------------
4834     DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetSymbols);
4835 };
4836 
4837 
4838 #pragma mark CommandObjectTargetStopHookAdd
4839 
4840 //-------------------------------------------------------------------------
4841 // CommandObjectTargetStopHookAdd
4842 //-------------------------------------------------------------------------
4843 
4844 class CommandObjectTargetStopHookAdd :
4845     public CommandObjectParsed,
4846     public IOHandlerDelegateMultiline
4847 {
4848 public:
4849 
4850     class CommandOptions : public Options
4851     {
4852     public:
4853         CommandOptions (CommandInterpreter &interpreter) :
4854             Options(interpreter),
4855             m_line_start(0),
4856             m_line_end (UINT_MAX),
4857             m_func_name_type_mask (eFunctionNameTypeAuto),
4858             m_sym_ctx_specified (false),
4859             m_thread_specified (false),
4860             m_use_one_liner (false),
4861             m_one_liner()
4862         {
4863         }
4864 
4865         ~CommandOptions () {}
4866 
4867         const OptionDefinition*
4868         GetDefinitions ()
4869         {
4870             return g_option_table;
4871         }
4872 
4873         virtual Error
4874         SetOptionValue (uint32_t option_idx, const char *option_arg)
4875         {
4876             Error error;
4877             const int short_option = m_getopt_table[option_idx].val;
4878             bool success;
4879 
4880             switch (short_option)
4881             {
4882                 case 'c':
4883                     m_class_name = option_arg;
4884                     m_sym_ctx_specified = true;
4885                 break;
4886 
4887                 case 'e':
4888                     m_line_end = StringConvert::ToUInt32 (option_arg, UINT_MAX, 0, &success);
4889                     if (!success)
4890                     {
4891                         error.SetErrorStringWithFormat ("invalid end line number: \"%s\"", option_arg);
4892                         break;
4893                     }
4894                     m_sym_ctx_specified = true;
4895                 break;
4896 
4897                 case 'l':
4898                     m_line_start = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
4899                     if (!success)
4900                     {
4901                         error.SetErrorStringWithFormat ("invalid start line number: \"%s\"", option_arg);
4902                         break;
4903                     }
4904                     m_sym_ctx_specified = true;
4905                 break;
4906 
4907                 case 'i':
4908                     m_no_inlines = true;
4909                 break;
4910 
4911                 case 'n':
4912                     m_function_name = option_arg;
4913                     m_func_name_type_mask |= eFunctionNameTypeAuto;
4914                     m_sym_ctx_specified = true;
4915                 break;
4916 
4917                 case 'f':
4918                     m_file_name = option_arg;
4919                     m_sym_ctx_specified = true;
4920                 break;
4921                 case 's':
4922                     m_module_name = option_arg;
4923                     m_sym_ctx_specified = true;
4924                 break;
4925                 case 't' :
4926                 {
4927                     m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
4928                     if (m_thread_id == LLDB_INVALID_THREAD_ID)
4929                        error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
4930                     m_thread_specified = true;
4931                 }
4932                 break;
4933                 case 'T':
4934                     m_thread_name = option_arg;
4935                     m_thread_specified = true;
4936                 break;
4937                 case 'q':
4938                     m_queue_name = option_arg;
4939                     m_thread_specified = true;
4940                     break;
4941                 case 'x':
4942                 {
4943                     m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
4944                     if (m_thread_id == UINT32_MAX)
4945                        error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
4946                     m_thread_specified = true;
4947                 }
4948                 break;
4949                 case 'o':
4950                     m_use_one_liner = true;
4951                     m_one_liner = option_arg;
4952                 break;
4953                 default:
4954                     error.SetErrorStringWithFormat ("unrecognized option %c.", short_option);
4955                 break;
4956             }
4957             return error;
4958         }
4959 
4960         void
4961         OptionParsingStarting ()
4962         {
4963             m_class_name.clear();
4964             m_function_name.clear();
4965             m_line_start = 0;
4966             m_line_end = UINT_MAX;
4967             m_file_name.clear();
4968             m_module_name.clear();
4969             m_func_name_type_mask = eFunctionNameTypeAuto;
4970             m_thread_id = LLDB_INVALID_THREAD_ID;
4971             m_thread_index = UINT32_MAX;
4972             m_thread_name.clear();
4973             m_queue_name.clear();
4974 
4975             m_no_inlines = false;
4976             m_sym_ctx_specified = false;
4977             m_thread_specified = false;
4978 
4979             m_use_one_liner = false;
4980             m_one_liner.clear();
4981         }
4982 
4983 
4984         static OptionDefinition g_option_table[];
4985 
4986         std::string m_class_name;
4987         std::string m_function_name;
4988         uint32_t    m_line_start;
4989         uint32_t    m_line_end;
4990         std::string m_file_name;
4991         std::string m_module_name;
4992         uint32_t m_func_name_type_mask;  // A pick from lldb::FunctionNameType.
4993         lldb::tid_t m_thread_id;
4994         uint32_t m_thread_index;
4995         std::string m_thread_name;
4996         std::string m_queue_name;
4997         bool        m_sym_ctx_specified;
4998         bool        m_no_inlines;
4999         bool        m_thread_specified;
5000         // Instance variables to hold the values for one_liner options.
5001         bool m_use_one_liner;
5002         std::string m_one_liner;
5003     };
5004 
5005     Options *
5006     GetOptions ()
5007     {
5008         return &m_options;
5009     }
5010 
5011     CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) :
5012         CommandObjectParsed (interpreter,
5013                              "target stop-hook add",
5014                              "Add a hook to be executed when the target stops.",
5015                              "target stop-hook add"),
5016         IOHandlerDelegateMultiline ("DONE", IOHandlerDelegate::Completion::LLDBCommand),
5017         m_options (interpreter)
5018     {
5019     }
5020 
5021     ~CommandObjectTargetStopHookAdd ()
5022     {
5023     }
5024 
5025 protected:
5026     virtual void
5027     IOHandlerActivated (IOHandler &io_handler)
5028     {
5029         StreamFileSP output_sp(io_handler.GetOutputStreamFile());
5030         if (output_sp)
5031         {
5032             output_sp->PutCString("Enter your stop hook command(s).  Type 'DONE' to end.\n");
5033             output_sp->Flush();
5034         }
5035     }
5036 
5037     virtual void
5038     IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
5039     {
5040         if (m_stop_hook_sp)
5041         {
5042             if (line.empty())
5043             {
5044                 StreamFileSP error_sp(io_handler.GetErrorStreamFile());
5045                 if (error_sp)
5046                 {
5047                     error_sp->Printf("error: stop hook #%" PRIu64 " aborted, no commands.\n", m_stop_hook_sp->GetID());
5048                     error_sp->Flush();
5049                 }
5050                 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
5051                 if (target)
5052                     target->RemoveStopHookByID(m_stop_hook_sp->GetID());
5053             }
5054             else
5055             {
5056                 m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
5057                 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
5058                 if (output_sp)
5059                 {
5060                     output_sp->Printf("Stop hook #%" PRIu64 " added.\n", m_stop_hook_sp->GetID());
5061                     output_sp->Flush();
5062                 }
5063             }
5064             m_stop_hook_sp.reset();
5065         }
5066         io_handler.SetIsDone(true);
5067     }
5068 
5069     bool
5070     DoExecute (Args& command, CommandReturnObject &result)
5071     {
5072         m_stop_hook_sp.reset();
5073 
5074         Target *target = GetSelectedOrDummyTarget();
5075         if (target)
5076         {
5077             Target::StopHookSP new_hook_sp = target->CreateStopHook();
5078 
5079             //  First step, make the specifier.
5080             std::unique_ptr<SymbolContextSpecifier> specifier_ap;
5081             if (m_options.m_sym_ctx_specified)
5082             {
5083                 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget()));
5084 
5085                 if (!m_options.m_module_name.empty())
5086                 {
5087                     specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified);
5088                 }
5089 
5090                 if (!m_options.m_class_name.empty())
5091                 {
5092                     specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified);
5093                 }
5094 
5095                 if (!m_options.m_file_name.empty())
5096                 {
5097                     specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified);
5098                 }
5099 
5100                 if (m_options.m_line_start != 0)
5101                 {
5102                     specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified);
5103                 }
5104 
5105                 if (m_options.m_line_end != UINT_MAX)
5106                 {
5107                     specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
5108                 }
5109 
5110                 if (!m_options.m_function_name.empty())
5111                 {
5112                     specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified);
5113                 }
5114             }
5115 
5116             if (specifier_ap.get())
5117                 new_hook_sp->SetSpecifier (specifier_ap.release());
5118 
5119             // Next see if any of the thread options have been entered:
5120 
5121             if (m_options.m_thread_specified)
5122             {
5123                 ThreadSpec *thread_spec = new ThreadSpec();
5124 
5125                 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
5126                 {
5127                     thread_spec->SetTID (m_options.m_thread_id);
5128                 }
5129 
5130                 if (m_options.m_thread_index != UINT32_MAX)
5131                     thread_spec->SetIndex (m_options.m_thread_index);
5132 
5133                 if (!m_options.m_thread_name.empty())
5134                     thread_spec->SetName (m_options.m_thread_name.c_str());
5135 
5136                 if (!m_options.m_queue_name.empty())
5137                     thread_spec->SetQueueName (m_options.m_queue_name.c_str());
5138 
5139                 new_hook_sp->SetThreadSpecifier (thread_spec);
5140 
5141             }
5142             if (m_options.m_use_one_liner)
5143             {
5144                 // Use one-liner.
5145                 new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str());
5146                 result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n", new_hook_sp->GetID());
5147             }
5148             else
5149             {
5150                 m_stop_hook_sp = new_hook_sp;
5151                 m_interpreter.GetLLDBCommandsFromIOHandler ("> ",   // Prompt
5152                                                             *this,  // IOHandlerDelegate
5153                                                             true,   // Run IOHandler in async mode
5154                                                             NULL);  // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
5155 
5156             }
5157             result.SetStatus (eReturnStatusSuccessFinishNoResult);
5158         }
5159         else
5160         {
5161             result.AppendError ("invalid target\n");
5162             result.SetStatus (eReturnStatusFailed);
5163         }
5164 
5165         return result.Succeeded();
5166     }
5167 private:
5168     CommandOptions m_options;
5169     Target::StopHookSP m_stop_hook_sp;
5170 };
5171 
5172 OptionDefinition
5173 CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] =
5174 {
5175     { LLDB_OPT_SET_ALL, false, "one-liner", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOneLiner,
5176         "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
5177     { LLDB_OPT_SET_ALL, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
5178         "Set the module within which the stop-hook is to be run."},
5179     { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex,
5180         "The stop hook is run only for the thread whose index matches this argument."},
5181     { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID,
5182         "The stop hook is run only for the thread whose TID matches this argument."},
5183     { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName,
5184         "The stop hook is run only for the thread whose thread name matches this argument."},
5185     { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName,
5186         "The stop hook is run only for threads in the queue whose name is given by this argument."},
5187     { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
5188         "Specify the source file within which the stop-hook is to be run." },
5189     { LLDB_OPT_SET_1, false, "start-line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
5190         "Set the start of the line range for which the stop-hook is to be run."},
5191     { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
5192         "Set the end of the line range for which the stop-hook is to be run."},
5193     { LLDB_OPT_SET_2, false, "classname", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeClassName,
5194         "Specify the class within which the stop-hook is to be run." },
5195     { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
5196         "Set the function name within which the stop hook will be run." },
5197     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
5198 };
5199 
5200 #pragma mark CommandObjectTargetStopHookDelete
5201 
5202 //-------------------------------------------------------------------------
5203 // CommandObjectTargetStopHookDelete
5204 //-------------------------------------------------------------------------
5205 
5206 class CommandObjectTargetStopHookDelete : public CommandObjectParsed
5207 {
5208 public:
5209 
5210     CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) :
5211         CommandObjectParsed (interpreter,
5212                              "target stop-hook delete",
5213                              "Delete a stop-hook.",
5214                              "target stop-hook delete [<idx>]")
5215     {
5216     }
5217 
5218     ~CommandObjectTargetStopHookDelete ()
5219     {
5220     }
5221 
5222 protected:
5223     bool
5224     DoExecute (Args& command, CommandReturnObject &result)
5225     {
5226         Target *target = GetSelectedOrDummyTarget();
5227         if (target)
5228         {
5229             // FIXME: see if we can use the breakpoint id style parser?
5230             size_t num_args = command.GetArgumentCount();
5231             if (num_args == 0)
5232             {
5233                 if (!m_interpreter.Confirm ("Delete all stop hooks?", true))
5234                 {
5235                     result.SetStatus (eReturnStatusFailed);
5236                     return false;
5237                 }
5238                 else
5239                 {
5240                     target->RemoveAllStopHooks();
5241                 }
5242             }
5243             else
5244             {
5245                 bool success;
5246                 for (size_t i = 0; i < num_args; i++)
5247                 {
5248                     lldb::user_id_t user_id = StringConvert::ToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
5249                     if (!success)
5250                     {
5251                         result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
5252                         result.SetStatus(eReturnStatusFailed);
5253                         return false;
5254                     }
5255                     success = target->RemoveStopHookByID (user_id);
5256                     if (!success)
5257                     {
5258                         result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
5259                         result.SetStatus(eReturnStatusFailed);
5260                         return false;
5261                     }
5262                 }
5263             }
5264             result.SetStatus (eReturnStatusSuccessFinishNoResult);
5265         }
5266         else
5267         {
5268             result.AppendError ("invalid target\n");
5269             result.SetStatus (eReturnStatusFailed);
5270         }
5271 
5272         return result.Succeeded();
5273     }
5274 };
5275 #pragma mark CommandObjectTargetStopHookEnableDisable
5276 
5277 //-------------------------------------------------------------------------
5278 // CommandObjectTargetStopHookEnableDisable
5279 //-------------------------------------------------------------------------
5280 
5281 class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed
5282 {
5283 public:
5284 
5285     CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) :
5286         CommandObjectParsed (interpreter,
5287                              name,
5288                              help,
5289                              syntax),
5290         m_enable (enable)
5291     {
5292     }
5293 
5294     ~CommandObjectTargetStopHookEnableDisable ()
5295     {
5296     }
5297 
5298 protected:
5299     bool
5300     DoExecute (Args& command, CommandReturnObject &result)
5301     {
5302         Target *target = GetSelectedOrDummyTarget();
5303         if (target)
5304         {
5305             // FIXME: see if we can use the breakpoint id style parser?
5306             size_t num_args = command.GetArgumentCount();
5307             bool success;
5308 
5309             if (num_args == 0)
5310             {
5311                 target->SetAllStopHooksActiveState (m_enable);
5312             }
5313             else
5314             {
5315                 for (size_t i = 0; i < num_args; i++)
5316                 {
5317                     lldb::user_id_t user_id = StringConvert::ToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
5318                     if (!success)
5319                     {
5320                         result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
5321                         result.SetStatus(eReturnStatusFailed);
5322                         return false;
5323                     }
5324                     success = target->SetStopHookActiveStateByID (user_id, m_enable);
5325                     if (!success)
5326                     {
5327                         result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
5328                         result.SetStatus(eReturnStatusFailed);
5329                         return false;
5330                     }
5331                 }
5332             }
5333             result.SetStatus (eReturnStatusSuccessFinishNoResult);
5334         }
5335         else
5336         {
5337             result.AppendError ("invalid target\n");
5338             result.SetStatus (eReturnStatusFailed);
5339         }
5340         return result.Succeeded();
5341     }
5342 private:
5343     bool m_enable;
5344 };
5345 
5346 #pragma mark CommandObjectTargetStopHookList
5347 
5348 //-------------------------------------------------------------------------
5349 // CommandObjectTargetStopHookList
5350 //-------------------------------------------------------------------------
5351 
5352 class CommandObjectTargetStopHookList : public CommandObjectParsed
5353 {
5354 public:
5355 
5356     CommandObjectTargetStopHookList (CommandInterpreter &interpreter) :
5357         CommandObjectParsed (interpreter,
5358                              "target stop-hook list",
5359                              "List all stop-hooks.",
5360                              "target stop-hook list [<type>]")
5361     {
5362     }
5363 
5364     ~CommandObjectTargetStopHookList ()
5365     {
5366     }
5367 
5368 protected:
5369     bool
5370     DoExecute (Args& command, CommandReturnObject &result)
5371     {
5372         Target *target = GetSelectedOrDummyTarget();
5373         if (!target)
5374         {
5375             result.AppendError ("invalid target\n");
5376             result.SetStatus (eReturnStatusFailed);
5377             return result.Succeeded();
5378         }
5379 
5380         size_t num_hooks = target->GetNumStopHooks ();
5381         if (num_hooks == 0)
5382         {
5383             result.GetOutputStream().PutCString ("No stop hooks.\n");
5384         }
5385         else
5386         {
5387             for (size_t i = 0; i < num_hooks; i++)
5388             {
5389                 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i);
5390                 if (i > 0)
5391                     result.GetOutputStream().PutCString ("\n");
5392                 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull);
5393             }
5394         }
5395         result.SetStatus (eReturnStatusSuccessFinishResult);
5396         return result.Succeeded();
5397     }
5398 };
5399 
5400 #pragma mark CommandObjectMultiwordTargetStopHooks
5401 //-------------------------------------------------------------------------
5402 // CommandObjectMultiwordTargetStopHooks
5403 //-------------------------------------------------------------------------
5404 
5405 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword
5406 {
5407 public:
5408 
5409     CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) :
5410         CommandObjectMultiword (interpreter,
5411                                 "target stop-hook",
5412                                 "A set of commands for operating on debugger target stop-hooks.",
5413                                 "target stop-hook <subcommand> [<subcommand-options>]")
5414     {
5415         LoadSubCommand ("add",      CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter)));
5416         LoadSubCommand ("delete",   CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter)));
5417         LoadSubCommand ("disable",  CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
5418                                                                                                    false,
5419                                                                                                    "target stop-hook disable [<id>]",
5420                                                                                                    "Disable a stop-hook.",
5421                                                                                                    "target stop-hook disable")));
5422         LoadSubCommand ("enable",   CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
5423                                                                                                    true,
5424                                                                                                    "target stop-hook enable [<id>]",
5425                                                                                                    "Enable a stop-hook.",
5426                                                                                                    "target stop-hook enable")));
5427         LoadSubCommand ("list",     CommandObjectSP (new CommandObjectTargetStopHookList (interpreter)));
5428     }
5429 
5430     ~CommandObjectMultiwordTargetStopHooks()
5431     {
5432     }
5433 };
5434 
5435 
5436 
5437 #pragma mark CommandObjectMultiwordTarget
5438 
5439 //-------------------------------------------------------------------------
5440 // CommandObjectMultiwordTarget
5441 //-------------------------------------------------------------------------
5442 
5443 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) :
5444     CommandObjectMultiword (interpreter,
5445                             "target",
5446                             "A set of commands for operating on debugger targets.",
5447                             "target <subcommand> [<subcommand-options>]")
5448 {
5449 
5450     LoadSubCommand ("create",    CommandObjectSP (new CommandObjectTargetCreate (interpreter)));
5451     LoadSubCommand ("delete",    CommandObjectSP (new CommandObjectTargetDelete (interpreter)));
5452     LoadSubCommand ("list",      CommandObjectSP (new CommandObjectTargetList   (interpreter)));
5453     LoadSubCommand ("select",    CommandObjectSP (new CommandObjectTargetSelect (interpreter)));
5454     LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter)));
5455     LoadSubCommand ("modules",   CommandObjectSP (new CommandObjectTargetModules (interpreter)));
5456     LoadSubCommand ("symbols",   CommandObjectSP (new CommandObjectTargetSymbols (interpreter)));
5457     LoadSubCommand ("variable",  CommandObjectSP (new CommandObjectTargetVariable (interpreter)));
5458 }
5459 
5460 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget ()
5461 {
5462 }
5463 
5464 
5465