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