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