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