//===-- CommandObjectTarget.cpp ---------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/lldb-python.h"

#include "CommandObjectTarget.h"

// C Includes
#include <errno.h>

// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Interpreter/Args.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/IOHandler.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/State.h"
#include "lldb/Core/Timer.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/DataFormatters/ValueObjectPrinter.h"
#include "lldb/Host/Symbols.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/OptionGroupArchitecture.h"
#include "lldb/Interpreter/OptionGroupBoolean.h"
#include "lldb/Interpreter/OptionGroupFile.h"
#include "lldb/Interpreter/OptionGroupFormat.h"
#include "lldb/Interpreter/OptionGroupVariable.h"
#include "lldb/Interpreter/OptionGroupPlatform.h"
#include "lldb/Interpreter/OptionGroupUInt64.h"
#include "lldb/Interpreter/OptionGroupUUID.h"
#include "lldb/Interpreter/OptionGroupString.h"
#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/FuncUnwinders.h"
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadSpec.h"

using namespace lldb;
using namespace lldb_private;



static void
DumpTargetInfo (uint32_t target_idx, Target *target, const char *prefix_cstr, bool show_stopped_process_status, Stream &strm)
{
    const ArchSpec &target_arch = target->GetArchitecture();

    Module *exe_module = target->GetExecutableModulePointer();
    char exe_path[PATH_MAX];
    bool exe_valid = false;
    if (exe_module)
        exe_valid = exe_module->GetFileSpec().GetPath (exe_path, sizeof(exe_path));

    if (!exe_valid)
        ::strcpy (exe_path, "<none>");

    strm.Printf ("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx, exe_path);

    uint32_t properties = 0;
    if (target_arch.IsValid())
    {
        strm.Printf ("%sarch=%s", properties++ > 0 ? ", " : " ( ", target_arch.GetTriple().str().c_str());
        properties++;
    }
    PlatformSP platform_sp (target->GetPlatform());
    if (platform_sp)
        strm.Printf ("%splatform=%s", properties++ > 0 ? ", " : " ( ", platform_sp->GetName().GetCString());

    ProcessSP process_sp (target->GetProcessSP());
    bool show_process_status = false;
    if (process_sp)
    {
        lldb::pid_t pid = process_sp->GetID();
        StateType state = process_sp->GetState();
        if (show_stopped_process_status)
            show_process_status = StateIsStoppedState(state, true);
        const char *state_cstr = StateAsCString (state);
        if (pid != LLDB_INVALID_PROCESS_ID)
            strm.Printf ("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid);
        strm.Printf ("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
    }
    if (properties > 0)
        strm.PutCString (" )\n");
    else
        strm.EOL();
    if (show_process_status)
    {
        const bool only_threads_with_stop_reason = true;
        const uint32_t start_frame = 0;
        const uint32_t num_frames = 1;
        const uint32_t num_frames_with_source = 1;
        process_sp->GetStatus (strm);
        process_sp->GetThreadStatus (strm, 
                                     only_threads_with_stop_reason, 
                                     start_frame,
                                     num_frames,
                                     num_frames_with_source);

    }
}

static uint32_t
DumpTargetList (TargetList &target_list, bool show_stopped_process_status, Stream &strm)
{
    const uint32_t num_targets = target_list.GetNumTargets();
    if (num_targets)
    {
        TargetSP selected_target_sp (target_list.GetSelectedTarget());
        strm.PutCString ("Current targets:\n");
        for (uint32_t i=0; i<num_targets; ++i)
        {
            TargetSP target_sp (target_list.GetTargetAtIndex (i));
            if (target_sp)
            {
                bool is_selected = target_sp.get() == selected_target_sp.get();
                DumpTargetInfo (i, 
                                target_sp.get(), 
                                is_selected ? "* " : "  ", 
                                show_stopped_process_status,
                                strm);
            }
        }
    }
    return num_targets;
}
#pragma mark CommandObjectTargetCreate

//-------------------------------------------------------------------------
// "target create"
//-------------------------------------------------------------------------

class CommandObjectTargetCreate : public CommandObjectParsed
{
public:
    CommandObjectTargetCreate(CommandInterpreter &interpreter) :
        CommandObjectParsed (interpreter,
                             "target create",
                             "Create a target using the argument as the main executable.",
                             NULL),
        m_option_group (interpreter),
        m_arch_option (),
        m_platform_options(true), // Do include the "--platform" option in the platform settings by passing true
        m_core_file (LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename, "Fullpath to a core file to use for this target."),
        m_platform_path (LLDB_OPT_SET_1, false, "platform-path", 'P', 0, eArgTypePath, "Path to the remote file to use for this target."),
        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."),
        m_remote_file (LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename, "Fullpath to the file on the remote host if debugging remotely."),
        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)
    {
        CommandArgumentEntry arg;
        CommandArgumentData file_arg;

        // Define the first (and only) variant of this arg.
            file_arg.arg_type = eArgTypeFilename;
        file_arg.arg_repetition = eArgRepeatPlain;

        // There is only one variant this argument could be; put it into the argument entry.
        arg.push_back (file_arg);

        // Push the data for the first argument into the m_arguments vector.
        m_arguments.push_back (arg);

        m_option_group.Append (&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
        m_option_group.Append (&m_platform_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
        m_option_group.Append (&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
        m_option_group.Append (&m_platform_path, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
        m_option_group.Append (&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
        m_option_group.Append (&m_remote_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
        m_option_group.Append (&m_add_dependents, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
        m_option_group.Finalize();
    }

    ~CommandObjectTargetCreate ()
    {
    }

    Options *
    GetOptions ()
    {
        return &m_option_group;
    }

    virtual int
    HandleArgumentCompletion (Args &input,
                              int &cursor_index,
                              int &cursor_char_position,
                              OptionElementVector &opt_element_vector,
                              int match_start_point,
                              int max_return_elements,
                              bool &word_complete,
                              StringList &matches)
    {
        std::string completion_str (input.GetArgumentAtIndex(cursor_index));
        completion_str.erase (cursor_char_position);

        CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 
                                                             CommandCompletions::eDiskFileCompletion,
                                                             completion_str.c_str(),
                                                             match_start_point,
                                                             max_return_elements,
                                                             NULL,
                                                             word_complete,
                                                             matches);
        return matches.GetSize();
    }

protected:
    bool
    DoExecute (Args& command, CommandReturnObject &result)
    {
        const size_t argc = command.GetArgumentCount();
        FileSpec core_file (m_core_file.GetOptionValue().GetCurrentValue());
        FileSpec remote_file (m_remote_file.GetOptionValue().GetCurrentValue());

        if (core_file)
        {
            if (!core_file.Exists())
            {
                result.AppendErrorWithFormat("core file '%s' doesn't exist", core_file.GetPath().c_str());
                result.SetStatus (eReturnStatusFailed);
                return false;
                
            }
            if (!core_file.Readable())
            {
                result.AppendErrorWithFormat("core file '%s' is not readable", core_file.GetPath().c_str());
                result.SetStatus (eReturnStatusFailed);
                return false;
            }
        }

        if (argc == 1 || core_file || remote_file)
        {
            FileSpec symfile (m_symbol_file.GetOptionValue().GetCurrentValue());
            if (symfile)
            {
                if (symfile.Exists())
                {
                    if (!symfile.Readable())
                    {
                        result.AppendErrorWithFormat("symbol file '%s' is not readable", core_file.GetPath().c_str());
                        result.SetStatus (eReturnStatusFailed);
                        return false;
                    }
                }
                else
                {
                    char symfile_path[PATH_MAX];
                    symfile.GetPath(symfile_path, sizeof(symfile_path));
                    result.AppendErrorWithFormat("invalid symbol file path '%s'", symfile_path);
                    result.SetStatus (eReturnStatusFailed);
                    return false;
                }
            }

            const char *file_path = command.GetArgumentAtIndex(0);
            Timer scoped_timer(__PRETTY_FUNCTION__, "(lldb) target create '%s'", file_path);
            FileSpec file_spec;

            if (file_path)
                file_spec.SetFile (file_path, true);

            bool must_set_platform_path = false;

            Debugger &debugger = m_interpreter.GetDebugger();
            PlatformSP platform_sp(debugger.GetPlatformList().GetSelectedPlatform ());

            if (remote_file)
            {
                // I have a remote file.. two possible cases
                if (file_spec && file_spec.Exists())
                {
                    // if the remote file does not exist, push it there
                    if (!platform_sp->GetFileExists (remote_file))
                    {
                        Error err = platform_sp->PutFile(file_spec, remote_file);
                        if (err.Fail())
                        {
                            result.AppendError(err.AsCString());
                            result.SetStatus (eReturnStatusFailed);
                            return false;
                        }
                    }
                }
                else
                {
                    // there is no local file and we need one
                    // in order to make the remote ---> local transfer we need a platform
                    // TODO: if the user has passed in a --platform argument, use it to fetch the right platform
                    if (!platform_sp)
                    {
                        result.AppendError("unable to perform remote debugging without a platform");
                        result.SetStatus (eReturnStatusFailed);
                        return false;
                    }
                    if (file_path)
                    {
                        // copy the remote file to the local file
                        Error err = platform_sp->GetFile(remote_file, file_spec);
                        if (err.Fail())
                        {
                            result.AppendError(err.AsCString());
                            result.SetStatus (eReturnStatusFailed);
                            return false;
                        }
                    }
                    else
                    {
                        // make up a local file
                        result.AppendError("remote --> local transfer without local path is not implemented yet");
                        result.SetStatus (eReturnStatusFailed);
                        return false;
                    }
                }
            }

            TargetSP target_sp;
            const char *arch_cstr = m_arch_option.GetArchitectureName();
            const bool get_dependent_files = m_add_dependents.GetOptionValue().GetCurrentValue();
            Error error (debugger.GetTargetList().CreateTarget (debugger,
//                                                                remote_file ? remote_file : file_spec,
                                                                file_path,
                                                                arch_cstr,
                                                                get_dependent_files,
                                                                &m_platform_options,
                                                                target_sp));

            if (target_sp)
            {
                if (symfile || remote_file)
                {
                    ModuleSP module_sp (target_sp->GetExecutableModule());
                    if (module_sp)
                    {
                        if (symfile)
                            module_sp->SetSymbolFileFileSpec(symfile);
                        if (remote_file)
                        {
                            std::string remote_path = remote_file.GetPath();
                            target_sp->SetArg0(remote_path.c_str());
                            module_sp->SetPlatformFileSpec(remote_file);
                        }
                    }
                }

                debugger.GetTargetList().SetSelectedTarget(target_sp.get());
                if (must_set_platform_path)
                {
                    ModuleSpec main_module_spec(file_spec);
                    ModuleSP module_sp = target_sp->GetSharedModule(main_module_spec);
                    if (module_sp)
                        module_sp->SetPlatformFileSpec(remote_file);
                }
                if (core_file)
                {
                    char core_path[PATH_MAX];
                    core_file.GetPath(core_path, sizeof(core_path));
                    if (core_file.Exists())
                    {
                        FileSpec core_file_dir;
                        core_file_dir.GetDirectory() = core_file.GetDirectory();
                        target_sp->GetExecutableSearchPaths ().Append (core_file_dir);

                        ProcessSP process_sp (target_sp->CreateProcess (m_interpreter.GetDebugger().GetListener(), NULL, &core_file));

                        if (process_sp)
                        {
                            // Seems wierd that we Launch a core file, but that is
                            // what we do!
                            error = process_sp->LoadCore();

                            if (error.Fail())
                            {
                                result.AppendError(error.AsCString("can't find plug-in for core file"));
                                result.SetStatus (eReturnStatusFailed);
                                return false;
                            }
                            else
                            {
                                result.AppendMessageWithFormat ("Core file '%s' (%s) was loaded.\n", core_path, target_sp->GetArchitecture().GetArchitectureName());
                                result.SetStatus (eReturnStatusSuccessFinishNoResult);
                            }
                        }
                        else
                        {
                            result.AppendErrorWithFormat ("Unable to find process plug-in for core file '%s'\n", core_path);
                            result.SetStatus (eReturnStatusFailed);
                        }
                    }
                    else
                    {
                        result.AppendErrorWithFormat ("Core file '%s' does not exist\n", core_path);
                        result.SetStatus (eReturnStatusFailed);
                    }
                }
                else
                {
                    result.AppendMessageWithFormat ("Current executable set to '%s' (%s).\n", file_path, target_sp->GetArchitecture().GetArchitectureName());
                    result.SetStatus (eReturnStatusSuccessFinishNoResult);
                }
            }
            else
            {
                result.AppendError(error.AsCString());
                result.SetStatus (eReturnStatusFailed);
            }
        }
        else
        {
            result.AppendErrorWithFormat("'%s' takes exactly one executable path argument, or use the --core-file option.\n", m_cmd_name.c_str());
            result.SetStatus (eReturnStatusFailed);
        }
        return result.Succeeded();
    }

private:
    OptionGroupOptions m_option_group;
    OptionGroupArchitecture m_arch_option;
    OptionGroupPlatform m_platform_options;
    OptionGroupFile m_core_file;
    OptionGroupFile m_platform_path;
    OptionGroupFile m_symbol_file;
    OptionGroupFile m_remote_file;
    OptionGroupBoolean m_add_dependents;
};

#pragma mark CommandObjectTargetList

//----------------------------------------------------------------------
// "target list"
//----------------------------------------------------------------------

class CommandObjectTargetList : public CommandObjectParsed
{
public:
    CommandObjectTargetList (CommandInterpreter &interpreter) :
        CommandObjectParsed (interpreter,
                             "target list",
                             "List all current targets in the current debug session.",
                             NULL,
                             0)
    {
    }

    virtual
    ~CommandObjectTargetList ()
    {
    }

protected:
    virtual bool
    DoExecute (Args& args, CommandReturnObject &result)
    {
        if (args.GetArgumentCount() == 0)
        {
            Stream &strm = result.GetOutputStream();

            bool show_stopped_process_status = false;
            if (DumpTargetList (m_interpreter.GetDebugger().GetTargetList(), show_stopped_process_status, strm) == 0)
            {
                strm.PutCString ("No targets.\n");
            }
            result.SetStatus (eReturnStatusSuccessFinishResult);
        }
        else
        {
            result.AppendError ("the 'target list' command takes no arguments\n");
            result.SetStatus (eReturnStatusFailed);
        }
        return result.Succeeded();
    }
};


#pragma mark CommandObjectTargetSelect

//----------------------------------------------------------------------
// "target select"
//----------------------------------------------------------------------

class CommandObjectTargetSelect : public CommandObjectParsed
{
public:
    CommandObjectTargetSelect (CommandInterpreter &interpreter) :
        CommandObjectParsed (interpreter,
                             "target select",
                             "Select a target as the current target by target index.",
                             NULL,
                             0)
    {
    }

    virtual
    ~CommandObjectTargetSelect ()
    {
    }

protected:
    virtual bool
    DoExecute (Args& args, CommandReturnObject &result)
    {
        if (args.GetArgumentCount() == 1)
        {
            bool success = false;
            const char *target_idx_arg = args.GetArgumentAtIndex(0);
            uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success);
            if (success)
            {
                TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
                const uint32_t num_targets = target_list.GetNumTargets();
                if (target_idx < num_targets)
                {        
                    TargetSP target_sp (target_list.GetTargetAtIndex (target_idx));
                    if (target_sp)
                    {
                        Stream &strm = result.GetOutputStream();
                        target_list.SetSelectedTarget (target_sp.get());
                        bool show_stopped_process_status = false;
                        DumpTargetList (target_list, show_stopped_process_status, strm);
                        result.SetStatus (eReturnStatusSuccessFinishResult);
                    }
                    else
                    {
                        result.AppendErrorWithFormat ("target #%u is NULL in target list\n", target_idx);
                        result.SetStatus (eReturnStatusFailed);
                    }
                }
                else
                {
                    if (num_targets > 0)
                    {
                        result.AppendErrorWithFormat ("index %u is out of range, valid target indexes are 0 - %u\n",
                                                      target_idx,
                                                      num_targets - 1);
                    } else
                    {
                        result.AppendErrorWithFormat ("index %u is out of range since there are no active targets\n",
                                                      target_idx);
                    }
                    result.SetStatus (eReturnStatusFailed);
                }
            }
            else
            {
                result.AppendErrorWithFormat("invalid index string value '%s'\n", target_idx_arg);
                result.SetStatus (eReturnStatusFailed);
            }
        }
        else
        {
            result.AppendError ("'target select' takes a single argument: a target index\n");
            result.SetStatus (eReturnStatusFailed);
        }
        return result.Succeeded();
    }
};

#pragma mark CommandObjectTargetSelect

//----------------------------------------------------------------------
// "target delete"
//----------------------------------------------------------------------

class CommandObjectTargetDelete : public CommandObjectParsed
{
public:
    CommandObjectTargetDelete (CommandInterpreter &interpreter) :
        CommandObjectParsed (interpreter,
                             "target delete",
                             "Delete one or more targets by target index.",
                             NULL,
                             0),
        m_option_group (interpreter),
        m_cleanup_option (LLDB_OPT_SET_1, false, "clean", 'c', "Perform extra cleanup to minimize memory consumption after deleting the target.", false, false)
    {
        m_option_group.Append (&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
        m_option_group.Finalize();
    }

    virtual
    ~CommandObjectTargetDelete ()
    {
    }

    Options *
    GetOptions ()
    {
        return &m_option_group;
    }

protected:
    virtual bool
    DoExecute (Args& args, CommandReturnObject &result)
    {
        const size_t argc = args.GetArgumentCount();
        std::vector<TargetSP> delete_target_list;
        TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
        bool success = true;
        TargetSP target_sp;
        if (argc > 0)
        {
            const uint32_t num_targets = target_list.GetNumTargets();
            // Bail out if don't have any targets.
            if (num_targets == 0) {
                result.AppendError("no targets to delete");
                result.SetStatus(eReturnStatusFailed);
                success = false;
            }

            for (uint32_t arg_idx = 0; success && arg_idx < argc; ++arg_idx)
            {
                const char *target_idx_arg = args.GetArgumentAtIndex(arg_idx);
                uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success);
                if (success)
                {
                    if (target_idx < num_targets)
                    {
                        target_sp = target_list.GetTargetAtIndex (target_idx);
                        if (target_sp)
                        {
                            delete_target_list.push_back (target_sp);
                            continue;
                        }
                    }
                    if (num_targets > 1)
                        result.AppendErrorWithFormat ("target index %u is out of range, valid target indexes are 0 - %u\n",
                                                      target_idx,
                                                      num_targets - 1);
                    else
                        result.AppendErrorWithFormat("target index %u is out of range, the only valid index is 0\n",
                                                    target_idx);

                    result.SetStatus (eReturnStatusFailed);
                    success = false;
                }
                else
                {
                    result.AppendErrorWithFormat("invalid target index '%s'\n", target_idx_arg);
                    result.SetStatus (eReturnStatusFailed);
                    success = false;
                }
            }
        }
        else
        {
            target_sp = target_list.GetSelectedTarget();
            if (target_sp)
            {
                delete_target_list.push_back (target_sp);
            }
            else
            {
                result.AppendErrorWithFormat("no target is currently selected\n");
                result.SetStatus (eReturnStatusFailed);
                success = false;
            }
        }
        if (success)
        {
            const size_t num_targets_to_delete = delete_target_list.size();
            for (size_t idx = 0; idx < num_targets_to_delete; ++idx)
            {
                target_sp = delete_target_list[idx];
                target_list.DeleteTarget(target_sp);
                target_sp->Destroy();
            }
            // If "--clean" was specified, prune any orphaned shared modules from
            // the global shared module list
            if (m_cleanup_option.GetOptionValue ())
            {
                const bool mandatory = true;
                ModuleList::RemoveOrphanSharedModules(mandatory);
            }
            result.GetOutputStream().Printf("%u targets deleted.\n", (uint32_t)num_targets_to_delete);
            result.SetStatus(eReturnStatusSuccessFinishResult);
        }

        return result.Succeeded();
    }

    OptionGroupOptions m_option_group;
    OptionGroupBoolean m_cleanup_option;
};


#pragma mark CommandObjectTargetVariable

//----------------------------------------------------------------------
// "target variable"
//----------------------------------------------------------------------

class CommandObjectTargetVariable : public CommandObjectParsed
{
    static const uint32_t SHORT_OPTION_FILE = 0x66696c65;   // 'file'
    static const uint32_t SHORT_OPTION_SHLB = 0x73686c62;   // 'shlb'

public:
    CommandObjectTargetVariable (CommandInterpreter &interpreter) :
        CommandObjectParsed (interpreter,
                             "target variable",
                             "Read global variable(s) prior to, or while running your binary.",
                             NULL,
                             eFlagRequiresTarget),
        m_option_group (interpreter),
        m_option_variable (false), // Don't include frame options
        m_option_format (eFormatDefault),
        m_option_compile_units    (LLDB_OPT_SET_1, false, "file",
                                   SHORT_OPTION_FILE, 0, eArgTypeFilename,
                                   "A basename or fullpath to a file that contains global variables. This option can be specified multiple times."),
        m_option_shared_libraries (LLDB_OPT_SET_1, false, "shlib",
                                   SHORT_OPTION_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."),
        m_varobj_options()
    {
        CommandArgumentEntry arg;
        CommandArgumentData var_name_arg;

        // Define the first (and only) variant of this arg.
        var_name_arg.arg_type = eArgTypeVarName;
        var_name_arg.arg_repetition = eArgRepeatPlus;

        // There is only one variant this argument could be; put it into the argument entry.
        arg.push_back (var_name_arg);

        // Push the data for the first argument into the m_arguments vector.
        m_arguments.push_back (arg);

        m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
        m_option_group.Append (&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
        m_option_group.Append (&m_option_format, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1);
        m_option_group.Append (&m_option_compile_units, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);   
        m_option_group.Append (&m_option_shared_libraries, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);   
        m_option_group.Finalize();
    }

    virtual
    ~CommandObjectTargetVariable ()
    {
    }

    void
    DumpValueObject (Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp, const char *root_name)
    {
        DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());

        switch (var_sp->GetScope())
        {
            case eValueTypeVariableGlobal:
                if (m_option_variable.show_scope)
                    s.PutCString("GLOBAL: ");
                break;

            case eValueTypeVariableStatic:
                if (m_option_variable.show_scope)
                    s.PutCString("STATIC: ");
                break;

            case eValueTypeVariableArgument:
                if (m_option_variable.show_scope)
                    s.PutCString("   ARG: ");
                break;

            case eValueTypeVariableLocal:
                if (m_option_variable.show_scope)
                    s.PutCString(" LOCAL: ");
                break;

            default:
                break;
        }

        if (m_option_variable.show_decl)
        {
            bool show_fullpaths = false;
            bool show_module = true;
            if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
                s.PutCString (": ");
        }

        const Format format = m_option_format.GetFormat();
        if (format != eFormatDefault)
            options.SetFormat(format);

        options.SetRootValueObjectName(root_name);

        valobj_sp->Dump(s,options);
    }

    static size_t GetVariableCallback (void *baton,
                                       const char *name,
                                       VariableList &variable_list)
    {
        Target *target = static_cast<Target *>(baton);
        if (target)
        {
            return target->GetImages().FindGlobalVariables (ConstString(name),
                                                            true, 
                                                            UINT32_MAX, 
                                                            variable_list);
        }
        return 0;
    }

    Options *
    GetOptions ()
    {
        return &m_option_group;
    }

protected:
    void
    DumpGlobalVariableList(const ExecutionContext &exe_ctx, const SymbolContext &sc, const VariableList &variable_list, Stream &s)
    {
        size_t count = variable_list.GetSize();
        if (count > 0)
        {
            if (sc.module_sp)
            {
                if (sc.comp_unit)
                {
                    s.Printf ("Global variables for %s in %s:\n",
                              sc.comp_unit->GetPath().c_str(),
                              sc.module_sp->GetFileSpec().GetPath().c_str());
                }
                else
                {
                    s.Printf ("Global variables for %s\n",
                              sc.module_sp->GetFileSpec().GetPath().c_str());
                }
            }
            else if (sc.comp_unit)
            {
                s.Printf ("Global variables for %s\n",
                          sc.comp_unit->GetPath().c_str());
            }

            for (uint32_t i=0; i<count; ++i)
            {
                VariableSP var_sp (variable_list.GetVariableAtIndex(i));
                if (var_sp)
                {
                    ValueObjectSP valobj_sp (ValueObjectVariable::Create (exe_ctx.GetBestExecutionContextScope(), var_sp));

                    if (valobj_sp)
                        DumpValueObject (s, var_sp, valobj_sp, var_sp->GetName().GetCString());
                }
            }
        }

    }
    virtual bool
    DoExecute (Args& args, CommandReturnObject &result)
    {
        Target *target = m_exe_ctx.GetTargetPtr();
        const size_t argc = args.GetArgumentCount();
        Stream &s = result.GetOutputStream();

        if (argc > 0)
        {

            for (size_t idx = 0; idx < argc; ++idx)
            {
                VariableList variable_list;
                ValueObjectList valobj_list;

                const char *arg = args.GetArgumentAtIndex(idx);
                size_t matches = 0;
                bool use_var_name = false;
                if (m_option_variable.use_regex)
                {
                    RegularExpression regex(arg);
                    if (!regex.IsValid ())
                    {
                        result.GetErrorStream().Printf ("error: invalid regular expression: '%s'\n", arg);
                        result.SetStatus (eReturnStatusFailed);
                        return false;
                    }
                    use_var_name = true;
                    matches = target->GetImages().FindGlobalVariables (regex,
                                                                       true, 
                                                                       UINT32_MAX, 
                                                                       variable_list);
                }
                else
                {
                    Error error (Variable::GetValuesForVariableExpressionPath (arg,
                                                                               m_exe_ctx.GetBestExecutionContextScope(),
                                                                               GetVariableCallback,
                                                                               target,
                                                                               variable_list,
                                                                               valobj_list));
                    matches = variable_list.GetSize();
                }

                if (matches == 0)
                {
                    result.GetErrorStream().Printf ("error: can't find global variable '%s'\n", arg);
                    result.SetStatus (eReturnStatusFailed);
                    return false;
                }
                else
                {
                    for (uint32_t global_idx=0; global_idx<matches; ++global_idx)
                    {
                        VariableSP var_sp (variable_list.GetVariableAtIndex(global_idx));
                        if (var_sp)
                        {
                            ValueObjectSP valobj_sp (valobj_list.GetValueObjectAtIndex(global_idx));
                            if (!valobj_sp)
                                valobj_sp = ValueObjectVariable::Create (m_exe_ctx.GetBestExecutionContextScope(), var_sp);

                            if (valobj_sp)
                                DumpValueObject (s, var_sp, valobj_sp, use_var_name ? var_sp->GetName().GetCString() : arg);
                        }
                    }
                }
            }
        }
        else
        {
            const FileSpecList &compile_units = m_option_compile_units.GetOptionValue().GetCurrentValue();
            const FileSpecList &shlibs = m_option_shared_libraries.GetOptionValue().GetCurrentValue();
            SymbolContextList sc_list;
            const size_t num_compile_units = compile_units.GetSize();
            const size_t num_shlibs = shlibs.GetSize();
            if (num_compile_units == 0 && num_shlibs == 0)
            {
                bool success = false;
                StackFrame *frame = m_exe_ctx.GetFramePtr();
                CompileUnit *comp_unit = NULL;
                if (frame)
                {
                    SymbolContext sc = frame->GetSymbolContext (eSymbolContextCompUnit);
                    if (sc.comp_unit)
                    {
                        const bool can_create = true;
                        VariableListSP comp_unit_varlist_sp (sc.comp_unit->GetVariableList(can_create));
                        if (comp_unit_varlist_sp)
                        {
                            size_t count = comp_unit_varlist_sp->GetSize();
                            if (count > 0)
                            {
                                DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
                                success = true;
                            }
                        }
                    }
                }
                if (!success)
                {
                    if (frame)
                    {
                        if (comp_unit)
                            result.AppendErrorWithFormat ("no global variables in current compile unit: %s\n",
                                                          comp_unit->GetPath().c_str());
                        else
                            result.AppendErrorWithFormat ("no debug information for frame %u\n", frame->GetFrameIndex());
                    }
                    else
                        result.AppendError ("'target variable' takes one or more global variable names as arguments\n");
                    result.SetStatus (eReturnStatusFailed);
                }
            }
            else
            {
                SymbolContextList sc_list;
                const bool append = true;
                // We have one or more compile unit or shlib
                if (num_shlibs > 0)
                {
                    for (size_t shlib_idx=0; shlib_idx<num_shlibs; ++shlib_idx)
                    {
                        const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));
                        ModuleSpec module_spec (module_file);

                        ModuleSP module_sp (target->GetImages().FindFirstModule(module_spec));
                        if (module_sp)
                        {
                            if (num_compile_units > 0)
                            {
                                for (size_t cu_idx=0; cu_idx<num_compile_units; ++cu_idx)
                                    module_sp->FindCompileUnits(compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list);
                            }
                            else
                            {
                                SymbolContext sc;
                                sc.module_sp = module_sp;
                                sc_list.Append(sc);
                            }
                        }
                        else
                        {
                            // Didn't find matching shlib/module in target...
                            result.AppendErrorWithFormat ("target doesn't contain the specified shared library: %s\n",
                                                          module_file.GetPath().c_str());
                        }
                    }
                }
                else
                {
                    // No shared libraries, we just want to find globals for the compile units files that were specified
                    for (size_t cu_idx=0; cu_idx<num_compile_units; ++cu_idx)
                        target->GetImages().FindCompileUnits(compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list);
                }

                const uint32_t num_scs = sc_list.GetSize();
                if (num_scs > 0)
                {
                    SymbolContext sc;
                    for (uint32_t sc_idx=0; sc_idx<num_scs; ++sc_idx)
                    {
                        if (sc_list.GetContextAtIndex(sc_idx, sc))
                        {
                            if (sc.comp_unit)
                            {
                                const bool can_create = true;
                                VariableListSP comp_unit_varlist_sp (sc.comp_unit->GetVariableList(can_create));
                                if (comp_unit_varlist_sp)
                                    DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
                            }
                            else if (sc.module_sp)
                            {
                                // Get all global variables for this module
                                lldb_private::RegularExpression all_globals_regex("."); // Any global with at least one character
                                VariableList variable_list;
                                sc.module_sp->FindGlobalVariables(all_globals_regex, append, UINT32_MAX, variable_list);
                                DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s);
                            }
                        }
                    }
                }
            }
        }

        if (m_interpreter.TruncationWarningNecessary())
        {
            result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
                                            m_cmd_name.c_str());
            m_interpreter.TruncationWarningGiven();
        }

        return result.Succeeded();
    }

    OptionGroupOptions m_option_group;
    OptionGroupVariable m_option_variable;
    OptionGroupFormat m_option_format;
    OptionGroupFileList m_option_compile_units;
    OptionGroupFileList m_option_shared_libraries;
    OptionGroupValueObjectDisplay m_varobj_options;

};


#pragma mark CommandObjectTargetModulesSearchPathsAdd

class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed
{
public:

    CommandObjectTargetModulesSearchPathsAdd (CommandInterpreter &interpreter) :
        CommandObjectParsed (interpreter,
                             "target modules search-paths add",
                             "Add new image search paths substitution pairs to the current target.",
                             NULL)
    {
        CommandArgumentEntry arg;
        CommandArgumentData old_prefix_arg;
        CommandArgumentData new_prefix_arg;

        // Define the first variant of this arg pair.
        old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
        old_prefix_arg.arg_repetition = eArgRepeatPairPlus;

        // Define the first variant of this arg pair.
        new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
        new_prefix_arg.arg_repetition = eArgRepeatPairPlus;

        // There are two required arguments that must always occur together, i.e. an argument "pair".  Because they
        // must always occur together, they are treated as two variants of one argument rather than two independent
        // arguments.  Push them both into the first argument position for m_arguments...

        arg.push_back (old_prefix_arg);
        arg.push_back (new_prefix_arg);

        m_arguments.push_back (arg);
    }

    ~CommandObjectTargetModulesSearchPathsAdd ()
    {
    }

protected:
    bool
    DoExecute (Args& command,
             CommandReturnObject &result)
    {
        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
        if (target)
        {
            const size_t argc = command.GetArgumentCount();
            if (argc & 1)
            {
                result.AppendError ("add requires an even number of arguments\n");
                result.SetStatus (eReturnStatusFailed);
            }
            else
            {
                for (size_t i=0; i<argc; i+=2)
                {
                    const char *from = command.GetArgumentAtIndex(i);
                    const char *to = command.GetArgumentAtIndex(i+1);

                    if (from[0] && to[0])
                    {
                        bool last_pair = ((argc - i) == 2);
                        target->GetImageSearchPathList().Append (ConstString(from),
                                                                 ConstString(to),
                                                                 last_pair); // Notify if this is the last pair
                        result.SetStatus (eReturnStatusSuccessFinishNoResult);
                    }
                    else
                    {
                        if (from[0])
                            result.AppendError ("<path-prefix> can't be empty\n");
                        else
                            result.AppendError ("<new-path-prefix> can't be empty\n");
                        result.SetStatus (eReturnStatusFailed);
                    }
                }
            }
        }
        else
        {
            result.AppendError ("invalid target\n");
            result.SetStatus (eReturnStatusFailed);
        }
        return result.Succeeded();
    }
};

#pragma mark CommandObjectTargetModulesSearchPathsClear

class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed
{
public:

    CommandObjectTargetModulesSearchPathsClear (CommandInterpreter &interpreter) :
        CommandObjectParsed (interpreter,
                             "target modules search-paths clear",
                             "Clear all current image search path substitution pairs from the current target.",
                             "target modules search-paths clear")
    {
    }

    ~CommandObjectTargetModulesSearchPathsClear ()
    {
    }

protected:
    bool
    DoExecute (Args& command,
             CommandReturnObject &result)
    {
        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
        if (target)
        {
            bool notify = true;
            target->GetImageSearchPathList().Clear(notify);
            result.SetStatus (eReturnStatusSuccessFinishNoResult);
        }
        else
        {
            result.AppendError ("invalid target\n");
            result.SetStatus (eReturnStatusFailed);
        }
        return result.Succeeded();
    }
};

#pragma mark CommandObjectTargetModulesSearchPathsInsert

class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed
{
public:

    CommandObjectTargetModulesSearchPathsInsert (CommandInterpreter &interpreter) :
        CommandObjectParsed (interpreter,
                             "target modules search-paths insert",
                             "Insert a new image search path substitution pair into the current target at the specified index.",
                             NULL)
    {
        CommandArgumentEntry arg1;
        CommandArgumentEntry arg2;
        CommandArgumentData index_arg;
        CommandArgumentData old_prefix_arg;
        CommandArgumentData new_prefix_arg;

        // Define the first and only variant of this arg.
        index_arg.arg_type = eArgTypeIndex;
        index_arg.arg_repetition = eArgRepeatPlain;

        // Put the one and only variant into the first arg for m_arguments:
        arg1.push_back (index_arg);

        // Define the first variant of this arg pair.
        old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
        old_prefix_arg.arg_repetition = eArgRepeatPairPlus;

        // Define the first variant of this arg pair.
        new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
        new_prefix_arg.arg_repetition = eArgRepeatPairPlus;

        // There are two required arguments that must always occur together, i.e. an argument "pair".  Because they
        // must always occur together, they are treated as two variants of one argument rather than two independent
        // arguments.  Push them both into the same argument position for m_arguments...

        arg2.push_back (old_prefix_arg);
        arg2.push_back (new_prefix_arg);

        // Add arguments to m_arguments.
        m_arguments.push_back (arg1);
        m_arguments.push_back (arg2);
    }

    ~CommandObjectTargetModulesSearchPathsInsert ()
    {
    }

protected:
    bool
    DoExecute (Args& command,
             CommandReturnObject &result)
    {
        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
        if (target)
        {
            size_t argc = command.GetArgumentCount();
            // check for at least 3 arguments and an odd nubmer of parameters
            if (argc >= 3 && argc & 1)
            {
                bool success = false;

                uint32_t insert_idx = Args::StringToUInt32(command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);

                if (!success)
                {
                    result.AppendErrorWithFormat("<index> parameter is not an integer: '%s'.\n", command.GetArgumentAtIndex(0));
                    result.SetStatus (eReturnStatusFailed);
                    return result.Succeeded();
                }

                // shift off the index
                command.Shift();
                argc = command.GetArgumentCount();

                for (uint32_t i=0; i<argc; i+=2, ++insert_idx)
                {
                    const char *from = command.GetArgumentAtIndex(i);
                    const char *to = command.GetArgumentAtIndex(i+1);

                    if (from[0] && to[0])
                    {
                        bool last_pair = ((argc - i) == 2);
                        target->GetImageSearchPathList().Insert (ConstString(from),
                                                                 ConstString(to),
                                                                 insert_idx,
                                                                 last_pair);
                        result.SetStatus (eReturnStatusSuccessFinishNoResult);
                    }
                    else
                    {
                        if (from[0])
                            result.AppendError ("<path-prefix> can't be empty\n");
                        else
                            result.AppendError ("<new-path-prefix> can't be empty\n");
                        result.SetStatus (eReturnStatusFailed);
                        return false;
                    }
                }
            }
            else
            {
                result.AppendError ("insert requires at least three arguments\n");
                result.SetStatus (eReturnStatusFailed);
                return result.Succeeded();
            }

        }
        else
        {
            result.AppendError ("invalid target\n");
            result.SetStatus (eReturnStatusFailed);
        }
        return result.Succeeded();
    }
};


#pragma mark CommandObjectTargetModulesSearchPathsList


class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed
{
public:

    CommandObjectTargetModulesSearchPathsList (CommandInterpreter &interpreter) :
        CommandObjectParsed (interpreter,
                             "target modules search-paths list",
                             "List all current image search path substitution pairs in the current target.",
                             "target modules search-paths list")
    {
    }

    ~CommandObjectTargetModulesSearchPathsList ()
    {
    }

protected:
    bool
    DoExecute (Args& command,
             CommandReturnObject &result)
    {
        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
        if (target)
        {
            if (command.GetArgumentCount() != 0)
            {
                result.AppendError ("list takes no arguments\n");
                result.SetStatus (eReturnStatusFailed);
                return result.Succeeded();
            }

            target->GetImageSearchPathList().Dump(&result.GetOutputStream());
            result.SetStatus (eReturnStatusSuccessFinishResult);
        }
        else
        {
            result.AppendError ("invalid target\n");
            result.SetStatus (eReturnStatusFailed);
        }
        return result.Succeeded();
    }
};

#pragma mark CommandObjectTargetModulesSearchPathsQuery

class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed
{
public:

    CommandObjectTargetModulesSearchPathsQuery (CommandInterpreter &interpreter) :
        CommandObjectParsed (interpreter,
                             "target modules search-paths query",
                             "Transform a path using the first applicable image search path.",
                             NULL)
    {
        CommandArgumentEntry arg;
        CommandArgumentData path_arg;

        // Define the first (and only) variant of this arg.
        path_arg.arg_type = eArgTypeDirectoryName;
        path_arg.arg_repetition = eArgRepeatPlain;

        // There is only one variant this argument could be; put it into the argument entry.
        arg.push_back (path_arg);

        // Push the data for the first argument into the m_arguments vector.
        m_arguments.push_back (arg);
    }

    ~CommandObjectTargetModulesSearchPathsQuery ()
    {
    }

protected:
    bool
    DoExecute (Args& command,
             CommandReturnObject &result)
    {
        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
        if (target)
        {
            if (command.GetArgumentCount() != 1)
            {
                result.AppendError ("query requires one argument\n");
                result.SetStatus (eReturnStatusFailed);
                return result.Succeeded();
            }

            ConstString orig(command.GetArgumentAtIndex(0));
            ConstString transformed;
            if (target->GetImageSearchPathList().RemapPath(orig, transformed))
                result.GetOutputStream().Printf("%s\n", transformed.GetCString());
            else
                result.GetOutputStream().Printf("%s\n", orig.GetCString());

            result.SetStatus (eReturnStatusSuccessFinishResult);
        }
        else
        {
            result.AppendError ("invalid target\n");
            result.SetStatus (eReturnStatusFailed);
        }
        return result.Succeeded();
    }
};

//----------------------------------------------------------------------
// Static Helper functions
//----------------------------------------------------------------------
static void
DumpModuleArchitecture (Stream &strm, Module *module, bool full_triple, uint32_t width)
{
    if (module)
    {
        const char *arch_cstr;
        if (full_triple)
            arch_cstr = module->GetArchitecture().GetTriple().str().c_str();
        else
            arch_cstr = module->GetArchitecture().GetArchitectureName();
        if (width)
            strm.Printf("%-*s", width, arch_cstr);
        else
            strm.PutCString(arch_cstr);
    }
}

static void
DumpModuleUUID (Stream &strm, Module *module)
{
    if (module && module->GetUUID().IsValid())
        module->GetUUID().Dump (&strm);
    else
        strm.PutCString("                                    ");
}

static uint32_t
DumpCompileUnitLineTable (CommandInterpreter &interpreter,
                          Stream &strm,
                          Module *module,
                          const FileSpec &file_spec,
                          bool load_addresses)
{
    uint32_t num_matches = 0;
    if (module)
    {
        SymbolContextList sc_list;
        num_matches = module->ResolveSymbolContextsForFileSpec (file_spec,
                                                                0,
                                                                false,
                                                                eSymbolContextCompUnit,
                                                                sc_list);

        for (uint32_t i=0; i<num_matches; ++i)
        {
            SymbolContext sc;
            if (sc_list.GetContextAtIndex(i, sc))
            {
                if (i > 0)
                    strm << "\n\n";

                strm << "Line table for " << *static_cast<FileSpec*> (sc.comp_unit) << " in `"
                << module->GetFileSpec().GetFilename() << "\n";
                LineTable *line_table = sc.comp_unit->GetLineTable();
                if (line_table)
                    line_table->GetDescription (&strm, 
                                                interpreter.GetExecutionContext().GetTargetPtr(), 
                                                lldb::eDescriptionLevelBrief);
                else
                    strm << "No line table";
            }
        }
    }
    return num_matches;
}

static void
DumpFullpath (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
{
    if (file_spec_ptr)
    {
        if (width > 0)
        {
            std::string fullpath = file_spec_ptr->GetPath();
            strm.Printf("%-*s", width, fullpath.c_str());
            return;
        }
        else
        {
            file_spec_ptr->Dump(&strm);
            return;
        }
    }
    // Keep the width spacing correct if things go wrong...
    if (width > 0)
        strm.Printf("%-*s", width, "");
}

static void
DumpDirectory (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
{
    if (file_spec_ptr)
    {
        if (width > 0)
            strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
        else
            file_spec_ptr->GetDirectory().Dump(&strm);
        return;
    }
    // Keep the width spacing correct if things go wrong...
    if (width > 0)
        strm.Printf("%-*s", width, "");
}

static void
DumpBasename (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
{
    if (file_spec_ptr)
    {
        if (width > 0)
            strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
        else
            file_spec_ptr->GetFilename().Dump(&strm);
        return;
    }
    // Keep the width spacing correct if things go wrong...
    if (width > 0)
        strm.Printf("%-*s", width, "");
}


static void
DumpModuleSymtab (CommandInterpreter &interpreter, Stream &strm, Module *module, SortOrder sort_order)
{
    if (module)
    {
        SymbolVendor *sym_vendor = module->GetSymbolVendor ();
        if (sym_vendor)
        {
            Symtab *symtab = sym_vendor->GetSymtab();
            if (symtab)
                symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), sort_order);
        }
    }
}

static void
DumpModuleSections (CommandInterpreter &interpreter, Stream &strm, Module *module)
{
    if (module)
    {
        SectionList *section_list = module->GetSectionList();
        if (section_list)
        {
            strm.Printf ("Sections for '%s' (%s):\n",
                         module->GetSpecificationDescription().c_str(),
                         module->GetArchitecture().GetArchitectureName());
            strm.IndentMore();
            section_list->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), true, UINT32_MAX);
            strm.IndentLess();
        }
    }
}

static bool
DumpModuleSymbolVendor (Stream &strm, Module *module)
{
    if (module)
    {
        SymbolVendor *symbol_vendor = module->GetSymbolVendor(true);
        if (symbol_vendor)
        {
            symbol_vendor->Dump(&strm);
            return true;
        }
    }
    return false;
}

static void
DumpAddress (ExecutionContextScope *exe_scope, const Address &so_addr, bool verbose, Stream &strm)
{
    strm.IndentMore();
    strm.Indent ("    Address: ");
    so_addr.Dump (&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
    strm.PutCString (" (");
    so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset);
    strm.PutCString (")\n");
    strm.Indent ("    Summary: ");
    const uint32_t save_indent = strm.GetIndentLevel ();
    strm.SetIndentLevel (save_indent + 13);
    so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription);
    strm.SetIndentLevel (save_indent);
    // Print out detailed address information when verbose is enabled
    if (verbose)
    {
        strm.EOL();
        so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
    }
    strm.IndentLess();
}

static bool
LookupAddressInModule (CommandInterpreter &interpreter, 
                       Stream &strm, 
                       Module *module, 
                       uint32_t resolve_mask, 
                       lldb::addr_t raw_addr, 
                       lldb::addr_t offset,
                       bool verbose)
{
    if (module)
    {
        lldb::addr_t addr = raw_addr - offset;
        Address so_addr;
        SymbolContext sc;
        Target *target = interpreter.GetExecutionContext().GetTargetPtr();
        if (target && !target->GetSectionLoadList().IsEmpty())
        {
            if (!target->GetSectionLoadList().ResolveLoadAddress (addr, so_addr))
                return false;
            else if (so_addr.GetModule().get() != module)
                return false;
        }
        else
        {
            if (!module->ResolveFileAddress (addr, so_addr))
                return false;
        }

        ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope();
        DumpAddress (exe_scope, so_addr, verbose, strm);
//        strm.IndentMore();
//        strm.Indent ("    Address: ");
//        so_addr.Dump (&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
//        strm.PutCString (" (");
//        so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset);
//        strm.PutCString (")\n");
//        strm.Indent ("    Summary: ");
//        const uint32_t save_indent = strm.GetIndentLevel ();
//        strm.SetIndentLevel (save_indent + 13);
//        so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription);
//        strm.SetIndentLevel (save_indent);
//        // Print out detailed address information when verbose is enabled
//        if (verbose)
//        {
//            strm.EOL();
//            so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
//        }
//        strm.IndentLess();
        return true;
    }

    return false;
}

static uint32_t
LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, bool verbose)
{
    if (module)
    {
        SymbolContext sc;

        SymbolVendor *sym_vendor = module->GetSymbolVendor ();
        if (sym_vendor)
        {
            Symtab *symtab = sym_vendor->GetSymtab();
            if (symtab)
            {
                uint32_t i;
                std::vector<uint32_t> match_indexes;
                ConstString symbol_name (name);
                uint32_t num_matches = 0;
                if (name_is_regex)
                {
                    RegularExpression name_regexp(name);
                    num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType (name_regexp, 
                                                                                   eSymbolTypeAny,
                                                                                   match_indexes);
                }
                else
                {
                    num_matches = symtab->AppendSymbolIndexesWithName (symbol_name, match_indexes);
                }

                if (num_matches > 0)
                {
                    strm.Indent ();
                    strm.Printf("%u symbols match %s'%s' in ", num_matches,
                                name_is_regex ? "the regular expression " : "", name);
                    DumpFullpath (strm, &module->GetFileSpec(), 0);
                    strm.PutCString(":\n");
                    strm.IndentMore ();
                    //Symtab::DumpSymbolHeader (&strm);
                    for (i=0; i < num_matches; ++i)
                    {
                        Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
                        DumpAddress (interpreter.GetExecutionContext().GetBestExecutionContextScope(),
                                     symbol->GetAddress(),
                                     verbose,
                                     strm);

//                        strm.Indent ();
//                        symbol->Dump (&strm, interpreter.GetExecutionContext().GetTargetPtr(), i);
                    }
                    strm.IndentLess ();
                    return num_matches;
                }
            }
        }
    }
    return 0;
}


static void
DumpSymbolContextList (ExecutionContextScope *exe_scope, Stream &strm, SymbolContextList &sc_list, bool verbose)
{
    strm.IndentMore ();
    uint32_t i;
    const uint32_t num_matches = sc_list.GetSize();

    for (i=0; i<num_matches; ++i)
    {
        SymbolContext sc;
        if (sc_list.GetContextAtIndex(i, sc))
        {
            AddressRange range;

            sc.GetAddressRange(eSymbolContextEverything, 
                               0, 
                               true, 
                               range);

            DumpAddress (exe_scope, range.GetBaseAddress(), verbose, strm);
        }
    }
    strm.IndentLess ();
}

static size_t
LookupFunctionInModule (CommandInterpreter &interpreter,
                        Stream &strm,
                        Module *module,
                        const char *name,
                        bool name_is_regex,
                        bool include_inlines,
                        bool include_symbols,
                        bool verbose)
{
    if (module && name && name[0])
    {
        SymbolContextList sc_list;
        const bool append = true;
        size_t num_matches = 0;
        if (name_is_regex)
        {
            RegularExpression function_name_regex (name);
            num_matches = module->FindFunctions (function_name_regex, 
                                                 include_symbols,
                                                 include_inlines, 
                                                 append, 
                                                 sc_list);
        }
        else
        {
            ConstString function_name (name);
            num_matches = module->FindFunctions (function_name,
                                                 NULL,
                                                 eFunctionNameTypeAuto,
                                                 include_symbols,
                                                 include_inlines, 
                                                 append, 
                                                 sc_list);
        }

        if (num_matches)
        {
            strm.Indent ();
            strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches, num_matches > 1 ? "es" : "");
            DumpFullpath (strm, &module->GetFileSpec(), 0);
            strm.PutCString(":\n");
            DumpSymbolContextList (interpreter.GetExecutionContext().GetBestExecutionContextScope(), strm, sc_list, verbose);
        }
        return num_matches;
    }
    return 0;
}

static size_t
LookupTypeInModule (CommandInterpreter &interpreter,
                    Stream &strm, 
                    Module *module, 
                    const char *name_cstr, 
                    bool name_is_regex)
{
    if (module && name_cstr && name_cstr[0])
    {
        TypeList type_list;
        const uint32_t max_num_matches = UINT32_MAX;
        size_t num_matches = 0;
        bool name_is_fully_qualified = false;
        SymbolContext sc;

        ConstString name(name_cstr);
        num_matches = module->FindTypes(sc, name, name_is_fully_qualified, max_num_matches, type_list);

        if (num_matches)
        {
            strm.Indent ();
            strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches, num_matches > 1 ? "es" : "");
            DumpFullpath (strm, &module->GetFileSpec(), 0);
            strm.PutCString(":\n");
            for (TypeSP type_sp : type_list.Types())
            {
                if (type_sp)
                {
                    // Resolve the clang type so that any forward references
                    // to types that haven't yet been parsed will get parsed.
                    type_sp->GetClangFullType ();
                    type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
                    // Print all typedef chains
                    TypeSP typedef_type_sp (type_sp);
                    TypeSP typedefed_type_sp (typedef_type_sp->GetTypedefType());
                    while (typedefed_type_sp)
                    {
                        strm.EOL();
                        strm.Printf("     typedef '%s': ", typedef_type_sp->GetName().GetCString());
                        typedefed_type_sp->GetClangFullType ();
                        typedefed_type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
                        typedef_type_sp = typedefed_type_sp;
                        typedefed_type_sp = typedef_type_sp->GetTypedefType();
                    }
                }
                strm.EOL();
            }
        }
        return num_matches;
    }
    return 0;
}

static size_t
LookupTypeHere (CommandInterpreter &interpreter,
                Stream &strm,
                const SymbolContext &sym_ctx,
                const char *name_cstr, 
                bool name_is_regex)
{
    if (!sym_ctx.module_sp)
        return 0;

    TypeList type_list;
    const uint32_t max_num_matches = UINT32_MAX;
    size_t num_matches = 1;
    bool name_is_fully_qualified = false;

    ConstString name(name_cstr);
    num_matches = sym_ctx.module_sp->FindTypes(sym_ctx, name, name_is_fully_qualified, max_num_matches, type_list);

    if (num_matches)
    {
        strm.Indent ();
        strm.PutCString("Best match found in ");
        DumpFullpath (strm, &sym_ctx.module_sp->GetFileSpec(), 0);
        strm.PutCString(":\n");

        TypeSP type_sp (type_list.GetTypeAtIndex(0));
        if (type_sp)
        {
            // Resolve the clang type so that any forward references
            // to types that haven't yet been parsed will get parsed.
            type_sp->GetClangFullType ();
            type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
            // Print all typedef chains
            TypeSP typedef_type_sp (type_sp);
            TypeSP typedefed_type_sp (typedef_type_sp->GetTypedefType());
            while (typedefed_type_sp)
            {
                strm.EOL();
                strm.Printf("     typedef '%s': ", typedef_type_sp->GetName().GetCString());
                typedefed_type_sp->GetClangFullType ();
                typedefed_type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
                typedef_type_sp = typedefed_type_sp;
                typedefed_type_sp = typedef_type_sp->GetTypedefType();
            }
        }
        strm.EOL();
    }
    return num_matches;
}

static uint32_t
LookupFileAndLineInModule (CommandInterpreter &interpreter, 
                           Stream &strm,
                           Module *module, 
                           const FileSpec &file_spec, 
                           uint32_t line, 
                           bool check_inlines,
                           bool verbose)
{
    if (module && file_spec)
    {
        SymbolContextList sc_list;
        const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
                                                                              eSymbolContextEverything, sc_list);
        if (num_matches > 0)
        {
            strm.Indent ();
            strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
            strm << file_spec;
            if (line > 0)
                strm.Printf (":%u", line);
            strm << " in ";
            DumpFullpath (strm, &module->GetFileSpec(), 0);
            strm.PutCString(":\n");
            DumpSymbolContextList (interpreter.GetExecutionContext().GetBestExecutionContextScope(), strm, sc_list, verbose);
            return num_matches;
        }
    }
    return 0;
}


static size_t
FindModulesByName (Target *target, 
                   const char *module_name, 
                   ModuleList &module_list, 
                   bool check_global_list)
{
// Dump specified images (by basename or fullpath)
    FileSpec module_file_spec(module_name, false);
    ModuleSpec module_spec (module_file_spec);

    const size_t initial_size = module_list.GetSize ();

    if (check_global_list)
    {
        // Check the global list
        Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex());
        const size_t num_modules = Module::GetNumberAllocatedModules();
        ModuleSP module_sp;
        for (size_t image_idx = 0; image_idx<num_modules; ++image_idx)
        {
            Module *module = Module::GetAllocatedModuleAtIndex(image_idx);

            if (module)
            {
                if (module->MatchesModuleSpec (module_spec))
                {
                    module_sp = module->shared_from_this();
                    module_list.AppendIfNeeded(module_sp);
                }
            }
        }
    }
    else
    {
        if (target)
        {
            const size_t num_matches = target->GetImages().FindModules (module_spec, module_list);

            // Not found in our module list for our target, check the main
            // shared module list in case it is a extra file used somewhere
            // else
            if (num_matches == 0)
            {
                module_spec.GetArchitecture() = target->GetArchitecture();
                ModuleList::FindSharedModules (module_spec, module_list);
            }
        }
        else
        {
            ModuleList::FindSharedModules (module_spec,module_list);
        }
    }

    return module_list.GetSize () - initial_size;
}

#pragma mark CommandObjectTargetModulesModuleAutoComplete

//----------------------------------------------------------------------
// A base command object class that can auto complete with module file
// paths
//----------------------------------------------------------------------

class CommandObjectTargetModulesModuleAutoComplete : public CommandObjectParsed
{
public:
    CommandObjectTargetModulesModuleAutoComplete (CommandInterpreter &interpreter,
                                      const char *name,
                                      const char *help,
                                      const char *syntax) :
        CommandObjectParsed (interpreter, name, help, syntax)
    {
        CommandArgumentEntry arg;
        CommandArgumentData file_arg;

        // Define the first (and only) variant of this arg.
        file_arg.arg_type = eArgTypeFilename;
        file_arg.arg_repetition = eArgRepeatStar;

        // There is only one variant this argument could be; put it into the argument entry.
        arg.push_back (file_arg);

        // Push the data for the first argument into the m_arguments vector.
        m_arguments.push_back (arg);
    }

    virtual
    ~CommandObjectTargetModulesModuleAutoComplete ()
    {
    }

    virtual int
    HandleArgumentCompletion (Args &input,
                              int &cursor_index,
                              int &cursor_char_position,
                              OptionElementVector &opt_element_vector,
                              int match_start_point,
                              int max_return_elements,
                              bool &word_complete,
                              StringList &matches)
    {
        // Arguments are the standard module completer.
        std::string completion_str (input.GetArgumentAtIndex(cursor_index));
        completion_str.erase (cursor_char_position);

        CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
                                                             CommandCompletions::eModuleCompletion,
                                                             completion_str.c_str(),
                                                             match_start_point,
                                                             max_return_elements,
                                                             NULL,
                                                             word_complete,
                                                             matches);
        return matches.GetSize();
    }
};

#pragma mark CommandObjectTargetModulesSourceFileAutoComplete

//----------------------------------------------------------------------
// A base command object class that can auto complete with module source
// file paths
//----------------------------------------------------------------------

class CommandObjectTargetModulesSourceFileAutoComplete : public CommandObjectParsed
{
public:
    CommandObjectTargetModulesSourceFileAutoComplete (CommandInterpreter &interpreter,
                                                      const char *name,
                                                      const char *help,
                                                      const char *syntax,
                                                      uint32_t flags) :
        CommandObjectParsed (interpreter, name, help, syntax, flags)
    {
        CommandArgumentEntry arg;
        CommandArgumentData source_file_arg;

        // Define the first (and only) variant of this arg.
        source_file_arg.arg_type = eArgTypeSourceFile;
        source_file_arg.arg_repetition = eArgRepeatPlus;

        // There is only one variant this argument could be; put it into the argument entry.
        arg.push_back (source_file_arg);

        // Push the data for the first argument into the m_arguments vector.
        m_arguments.push_back (arg);
    }

    virtual
    ~CommandObjectTargetModulesSourceFileAutoComplete ()
    {
    }

    virtual int
    HandleArgumentCompletion (Args &input,
                              int &cursor_index,
                              int &cursor_char_position,
                              OptionElementVector &opt_element_vector,
                              int match_start_point,
                              int max_return_elements,
                              bool &word_complete,
                              StringList &matches)
    {
        // Arguments are the standard source file completer.
        std::string completion_str (input.GetArgumentAtIndex(cursor_index));
        completion_str.erase (cursor_char_position);

        CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 
                                                             CommandCompletions::eSourceFileCompletion,
                                                             completion_str.c_str(),
                                                             match_start_point,
                                                             max_return_elements,
                                                             NULL,
                                                             word_complete,
                                                             matches);
        return matches.GetSize();
    }
};


#pragma mark CommandObjectTargetModulesDumpSymtab


class CommandObjectTargetModulesDumpSymtab : public CommandObjectTargetModulesModuleAutoComplete
{
public:
    CommandObjectTargetModulesDumpSymtab (CommandInterpreter &interpreter) :
    CommandObjectTargetModulesModuleAutoComplete (interpreter,
                                      "target modules dump symtab",
                                      "Dump the symbol table from one or more target modules.",
                                      NULL),
    m_options (interpreter)
    {
    }

    virtual
    ~CommandObjectTargetModulesDumpSymtab ()
    {
    }

    virtual Options *
    GetOptions ()
    {
        return &m_options;
    }

    class CommandOptions : public Options
    {
    public:
        CommandOptions (CommandInterpreter &interpreter) :
        Options(interpreter),
        m_sort_order (eSortOrderNone)
        {
        }

        virtual
        ~CommandOptions ()
        {
        }

        virtual Error
        SetOptionValue (uint32_t option_idx, const char *option_arg)
        {
            Error error;
            const int short_option = m_getopt_table[option_idx].val;

            switch (short_option)
            {
                case 's':
                    m_sort_order = (SortOrder) Args::StringToOptionEnum (option_arg, 
                                                                         g_option_table[option_idx].enum_values, 
                                                                         eSortOrderNone,
                                                                         error);
                    break;

                default:
                    error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
                    break;

            }
            return error;
        }

        void
        OptionParsingStarting ()
        {
            m_sort_order = eSortOrderNone;
        }

        const OptionDefinition*
        GetDefinitions ()
        {
            return g_option_table;
        }

        // Options table: Required for subclasses of Options.
        static OptionDefinition g_option_table[];

        SortOrder m_sort_order;
    };

protected:
    virtual bool
    DoExecute (Args& command,
             CommandReturnObject &result)
    {
        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
        if (target == NULL)
        {
            result.AppendError ("invalid target, create a debug target using the 'target create' command");
            result.SetStatus (eReturnStatusFailed);
            return false;
        }
        else
        {
            uint32_t num_dumped = 0;

            uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
            result.GetOutputStream().SetAddressByteSize(addr_byte_size);
            result.GetErrorStream().SetAddressByteSize(addr_byte_size);

            if (command.GetArgumentCount() == 0)
            {
                // Dump all sections for all modules images
                Mutex::Locker modules_locker(target->GetImages().GetMutex());
                const size_t num_modules = target->GetImages().GetSize();
                if (num_modules > 0)
                {
                    result.GetOutputStream().Printf("Dumping symbol table for %" PRIu64 " modules.\n", (uint64_t)num_modules);
                    for (size_t image_idx = 0; image_idx<num_modules; ++image_idx)
                    {
                        if (num_dumped > 0)
                        {
                            result.GetOutputStream().EOL();
                            result.GetOutputStream().EOL();
                        }
                        num_dumped++;
                        DumpModuleSymtab (m_interpreter,
                                          result.GetOutputStream(),
                                          target->GetImages().GetModulePointerAtIndexUnlocked(image_idx),
                                          m_options.m_sort_order);
                    }
                }
                else
                {
                    result.AppendError ("the target has no associated executable images");
                    result.SetStatus (eReturnStatusFailed);
                    return false;
                }
            }
            else
            {
                // Dump specified images (by basename or fullpath)
                const char *arg_cstr;
                for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
                {
                    ModuleList module_list;
                    const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
                    if (num_matches > 0)
                    {
                        for (size_t i=0; i<num_matches; ++i)
                        {
                            Module *module = module_list.GetModulePointerAtIndex(i);
                            if (module)
                            {
                                if (num_dumped > 0)
                                {
                                    result.GetOutputStream().EOL();
                                    result.GetOutputStream().EOL();
                                }
                                num_dumped++;
                                DumpModuleSymtab (m_interpreter, result.GetOutputStream(), module, m_options.m_sort_order);
                            }
                        }
                    }
                    else
                        result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
                }
            }

            if (num_dumped > 0)
                result.SetStatus (eReturnStatusSuccessFinishResult);
            else
            {
                result.AppendError ("no matching executable images found");
                result.SetStatus (eReturnStatusFailed);
            }
        }
        return result.Succeeded();
    }

    CommandOptions m_options;
};

static OptionEnumValueElement
g_sort_option_enumeration[4] =
{
    { eSortOrderNone,       "none",     "No sorting, use the original symbol table order."},
    { eSortOrderByAddress,  "address",  "Sort output by symbol address."},
    { eSortOrderByName,     "name",     "Sort output by symbol name."},
    { 0,                    NULL,       NULL }
};


OptionDefinition
CommandObjectTargetModulesDumpSymtab::CommandOptions::g_option_table[] =
{
    { LLDB_OPT_SET_1, false, "sort", 's', OptionParser::eRequiredArgument, NULL, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."},
    { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
};

#pragma mark CommandObjectTargetModulesDumpSections

//----------------------------------------------------------------------
// Image section dumping command
//----------------------------------------------------------------------

class CommandObjectTargetModulesDumpSections : public CommandObjectTargetModulesModuleAutoComplete
{
public:
    CommandObjectTargetModulesDumpSections (CommandInterpreter &interpreter) :
    CommandObjectTargetModulesModuleAutoComplete (interpreter,
                                      "target modules dump sections",
                                      "Dump the sections from one or more target modules.",
                                      //"target modules dump sections [<file1> ...]")
                                      NULL)
    {
    }

    virtual
    ~CommandObjectTargetModulesDumpSections ()
    {
    }

protected:
    virtual bool
    DoExecute (Args& command,
             CommandReturnObject &result)
    {
        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
        if (target == NULL)
        {
            result.AppendError ("invalid target, create a debug target using the 'target create' command");
            result.SetStatus (eReturnStatusFailed);
            return false;
        }
        else
        {
            uint32_t num_dumped = 0;

            uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
            result.GetOutputStream().SetAddressByteSize(addr_byte_size);
            result.GetErrorStream().SetAddressByteSize(addr_byte_size);

            if (command.GetArgumentCount() == 0)
            {
                // Dump all sections for all modules images
                const size_t num_modules = target->GetImages().GetSize();
                if (num_modules > 0)
                {
                    result.GetOutputStream().Printf("Dumping sections for %" PRIu64 " modules.\n", (uint64_t)num_modules);
                    for (size_t image_idx = 0;  image_idx<num_modules; ++image_idx)
                    {
                        num_dumped++;
                        DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
                    }
                }
                else
                {
                    result.AppendError ("the target has no associated executable images");
                    result.SetStatus (eReturnStatusFailed);
                    return false;
                }
            }
            else
            {
                // Dump specified images (by basename or fullpath)
                const char *arg_cstr;
                for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
                {
                    ModuleList module_list;
                    const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
                    if (num_matches > 0)
                    {
                        for (size_t i=0; i<num_matches; ++i)
                        {
                            Module *module = module_list.GetModulePointerAtIndex(i);
                            if (module)
                            {
                                num_dumped++;
                                DumpModuleSections (m_interpreter, result.GetOutputStream(), module);
                            }
                        }
                    }
                    else
                    {
                        // Check the global list
                        Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex());

                        result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
                    }
                }
            }

            if (num_dumped > 0)
                result.SetStatus (eReturnStatusSuccessFinishResult);
            else
            {
                result.AppendError ("no matching executable images found");
                result.SetStatus (eReturnStatusFailed);
            }
        }
        return result.Succeeded();
    }
};


#pragma mark CommandObjectTargetModulesDumpSymfile

//----------------------------------------------------------------------
// Image debug symbol dumping command
//----------------------------------------------------------------------

class CommandObjectTargetModulesDumpSymfile : public CommandObjectTargetModulesModuleAutoComplete
{
public:
    CommandObjectTargetModulesDumpSymfile (CommandInterpreter &interpreter) :
    CommandObjectTargetModulesModuleAutoComplete (interpreter,
                                      "target modules dump symfile",
                                      "Dump the debug symbol file for one or more target modules.",
                                      //"target modules dump symfile [<file1> ...]")
                                      NULL)
    {
    }

    virtual
    ~CommandObjectTargetModulesDumpSymfile ()
    {
    }

protected:
    virtual bool
    DoExecute (Args& command,
             CommandReturnObject &result)
    {
        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
        if (target == NULL)
        {
            result.AppendError ("invalid target, create a debug target using the 'target create' command");
            result.SetStatus (eReturnStatusFailed);
            return false;
        }
        else
        {
            uint32_t num_dumped = 0;

            uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
            result.GetOutputStream().SetAddressByteSize(addr_byte_size);
            result.GetErrorStream().SetAddressByteSize(addr_byte_size);

            if (command.GetArgumentCount() == 0)
            {
                // Dump all sections for all modules images
                const ModuleList &target_modules = target->GetImages();
                Mutex::Locker modules_locker (target_modules.GetMutex());
                const size_t num_modules = target_modules.GetSize();
                if (num_modules > 0)
                {
                    result.GetOutputStream().Printf("Dumping debug symbols for %" PRIu64 " modules.\n", (uint64_t)num_modules);
                    for (uint32_t image_idx = 0;  image_idx<num_modules; ++image_idx)
                    {
                        if (DumpModuleSymbolVendor (result.GetOutputStream(), target_modules.GetModulePointerAtIndexUnlocked(image_idx)))
                            num_dumped++;
                    }
                }
                else
                {
                    result.AppendError ("the target has no associated executable images");
                    result.SetStatus (eReturnStatusFailed);
                    return false;
                }
            }
            else
            {
                // Dump specified images (by basename or fullpath)
                const char *arg_cstr;
                for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
                {
                    ModuleList module_list;
                    const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
                    if (num_matches > 0)
                    {
                        for (size_t i=0; i<num_matches; ++i)
                        {
                            Module *module = module_list.GetModulePointerAtIndex(i);
                            if (module)
                            {
                                if (DumpModuleSymbolVendor (result.GetOutputStream(), module))
                                    num_dumped++;
                            }
                        }
                    }
                    else
                        result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
                }
            }

            if (num_dumped > 0)
                result.SetStatus (eReturnStatusSuccessFinishResult);
            else
            {
                result.AppendError ("no matching executable images found");
                result.SetStatus (eReturnStatusFailed);
            }
        }
        return result.Succeeded();
    }
};


#pragma mark CommandObjectTargetModulesDumpLineTable

//----------------------------------------------------------------------
// Image debug line table dumping command
//----------------------------------------------------------------------

class CommandObjectTargetModulesDumpLineTable : public CommandObjectTargetModulesSourceFileAutoComplete
{
public:
    CommandObjectTargetModulesDumpLineTable (CommandInterpreter &interpreter) :
    CommandObjectTargetModulesSourceFileAutoComplete (interpreter,
                                                      "target modules dump line-table",
                                                      "Dump the line table for one or more compilation units.",
                                                      NULL,
                                                      eFlagRequiresTarget)
    {
    }

    virtual
    ~CommandObjectTargetModulesDumpLineTable ()
    {
    }

protected:
    virtual bool
    DoExecute (Args& command,
             CommandReturnObject &result)
    {
        Target *target = m_exe_ctx.GetTargetPtr();
        uint32_t total_num_dumped = 0;

        uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
        result.GetOutputStream().SetAddressByteSize(addr_byte_size);
        result.GetErrorStream().SetAddressByteSize(addr_byte_size);

        if (command.GetArgumentCount() == 0)
        {
            result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str());
            result.SetStatus (eReturnStatusFailed);
        }
        else
        {
            // Dump specified images (by basename or fullpath)
            const char *arg_cstr;
            for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
            {
                FileSpec file_spec(arg_cstr, false);

                const ModuleList &target_modules = target->GetImages();
                Mutex::Locker modules_locker(target_modules.GetMutex());
                const size_t num_modules = target_modules.GetSize();
                if (num_modules > 0)
                {
                    uint32_t num_dumped = 0;
                    for (uint32_t i = 0; i<num_modules; ++i)
                    {
                        if (DumpCompileUnitLineTable (m_interpreter,
                                                      result.GetOutputStream(),
                                                      target_modules.GetModulePointerAtIndexUnlocked(i),
                                                      file_spec,
                                                      m_exe_ctx.GetProcessPtr() && m_exe_ctx.GetProcessRef().IsAlive()))
                            num_dumped++;
                    }
                    if (num_dumped == 0)
                        result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr);
                    else
                        total_num_dumped += num_dumped;
                }
            }
        }

        if (total_num_dumped > 0)
            result.SetStatus (eReturnStatusSuccessFinishResult);
        else
        {
            result.AppendError ("no source filenames matched any command arguments");
            result.SetStatus (eReturnStatusFailed);
        }
        return result.Succeeded();
    }
};


#pragma mark CommandObjectTargetModulesDump

//----------------------------------------------------------------------
// Dump multi-word command for target modules
//----------------------------------------------------------------------

class CommandObjectTargetModulesDump : public CommandObjectMultiword
{
public:
    //------------------------------------------------------------------
    // Constructors and Destructors
    //------------------------------------------------------------------
    CommandObjectTargetModulesDump(CommandInterpreter &interpreter) :
    CommandObjectMultiword (interpreter, 
                            "target modules dump",
                            "A set of commands for dumping information about one or more target modules.",
                            "target modules dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]")
    {
        LoadSubCommand ("symtab",      CommandObjectSP (new CommandObjectTargetModulesDumpSymtab (interpreter)));
        LoadSubCommand ("sections",    CommandObjectSP (new CommandObjectTargetModulesDumpSections (interpreter)));
        LoadSubCommand ("symfile",     CommandObjectSP (new CommandObjectTargetModulesDumpSymfile (interpreter)));
        LoadSubCommand ("line-table",  CommandObjectSP (new CommandObjectTargetModulesDumpLineTable (interpreter)));
    }

    virtual
    ~CommandObjectTargetModulesDump()
    {
    }
};

class CommandObjectTargetModulesAdd : public CommandObjectParsed
{
public:
    CommandObjectTargetModulesAdd (CommandInterpreter &interpreter) :
        CommandObjectParsed (interpreter,
                             "target modules add",
                             "Add a new module to the current target's modules.",
                             "target modules add [<module>]"),
        m_option_group (interpreter),
        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.")
    {
        m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
        m_option_group.Append (&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
        m_option_group.Finalize();
    }

    virtual
    ~CommandObjectTargetModulesAdd ()
    {
    }

    virtual Options *
    GetOptions ()
    {
        return &m_option_group;
    }

    virtual int
    HandleArgumentCompletion (Args &input,
                              int &cursor_index,
                              int &cursor_char_position,
                              OptionElementVector &opt_element_vector,
                              int match_start_point,
                              int max_return_elements,
                              bool &word_complete,
                              StringList &matches)
    {
        std::string completion_str (input.GetArgumentAtIndex(cursor_index));
        completion_str.erase (cursor_char_position);

        CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 
                                                             CommandCompletions::eDiskFileCompletion,
                                                             completion_str.c_str(),
                                                             match_start_point,
                                                             max_return_elements,
                                                             NULL,
                                                             word_complete,
                                                             matches);
        return matches.GetSize();
    }

protected:
    OptionGroupOptions m_option_group;
    OptionGroupUUID m_uuid_option_group;
    OptionGroupFile m_symbol_file;

    virtual bool
    DoExecute (Args& args,
             CommandReturnObject &result)
    {
        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
        if (target == NULL)
        {
            result.AppendError ("invalid target, create a debug target using the 'target create' command");
            result.SetStatus (eReturnStatusFailed);
            return false;
        }
        else
        {
            bool flush = false;

            const size_t argc = args.GetArgumentCount();
            if (argc == 0)
            {
                if (m_uuid_option_group.GetOptionValue ().OptionWasSet())
                {
                    // We are given a UUID only, go locate the file
                    ModuleSpec module_spec;
                    module_spec.GetUUID() = m_uuid_option_group.GetOptionValue ().GetCurrentValue();
                    if (m_symbol_file.GetOptionValue().OptionWasSet())
                        module_spec.GetSymbolFileSpec() = m_symbol_file.GetOptionValue().GetCurrentValue();
                    if (Symbols::DownloadObjectAndSymbolFile (module_spec))
                    {
                        ModuleSP module_sp (target->GetSharedModule (module_spec));
                        if (module_sp)
                        {
                            result.SetStatus (eReturnStatusSuccessFinishResult);
                            return true;
                        }
                        else
                        {
                            StreamString strm;
                            module_spec.GetUUID().Dump (&strm);
                            if (module_spec.GetFileSpec())
                            {
                                if (module_spec.GetSymbolFileSpec())
                                {
                                    result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s with path %s and symbol file %s",
                                                                  strm.GetString().c_str(),
                                                                  module_spec.GetFileSpec().GetPath().c_str(),
                                                                  module_spec.GetSymbolFileSpec().GetPath().c_str());
                                }
                                else
                                {
                                    result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s with path %s",
                                                                  strm.GetString().c_str(),
                                                                  module_spec.GetFileSpec().GetPath().c_str());
                                }
                            }
                            else
                            {
                                result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s",
                                                              strm.GetString().c_str());
                            }
                            result.SetStatus (eReturnStatusFailed);
                            return false;
                        }
                    }
                    else
                    {
                        StreamString strm;
                        module_spec.GetUUID().Dump (&strm);
                        result.AppendErrorWithFormat ("Unable to locate the executable or symbol file with UUID %s", strm.GetString().c_str());
                        result.SetStatus (eReturnStatusFailed);
                        return false;
                    }
                }
                else
                {
                    result.AppendError ("one or more executable image paths must be specified");
                    result.SetStatus (eReturnStatusFailed);
                    return false;
                }
            }
            else
            {
                for (size_t i=0; i<argc; ++i)
                {
                    const char *path = args.GetArgumentAtIndex(i);
                    if (path)
                    {
                        FileSpec file_spec(path, true);
                        if (file_spec.Exists())
                        {
                            ModuleSpec module_spec (file_spec);
                            if (m_uuid_option_group.GetOptionValue ().OptionWasSet())
                                module_spec.GetUUID() = m_uuid_option_group.GetOptionValue ().GetCurrentValue();
                            if (m_symbol_file.GetOptionValue().OptionWasSet())
                                module_spec.GetSymbolFileSpec() = m_symbol_file.GetOptionValue().GetCurrentValue();
                            if (!module_spec.GetArchitecture().IsValid())
                                module_spec.GetArchitecture() = target->GetArchitecture();
                            Error error;
                            ModuleSP module_sp (target->GetSharedModule (module_spec, &error));
                            if (!module_sp)
                            {
                                const char *error_cstr = error.AsCString();
                                if (error_cstr)
                                    result.AppendError (error_cstr);
                                else
                                    result.AppendErrorWithFormat ("unsupported module: %s", path);
                                result.SetStatus (eReturnStatusFailed);
                                return false;
                            }
                            else
                            {
                                flush = true;
                            }
                            result.SetStatus (eReturnStatusSuccessFinishResult);
                        }
                        else
                        {
                            char resolved_path[PATH_MAX];
                            result.SetStatus (eReturnStatusFailed);
                            if (file_spec.GetPath (resolved_path, sizeof(resolved_path)))
                            {
                                if (strcmp (resolved_path, path) != 0)
                                {
                                    result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", path, resolved_path);
                                    break;
                                }
                            }
                            result.AppendErrorWithFormat ("invalid module path '%s'\n", path);
                            break;
                        }
                    }
                }
            }

            if (flush)
            {
                ProcessSP process = target->GetProcessSP();
                if (process)
                    process->Flush();
            }
        }

        return result.Succeeded();
    }

};

class CommandObjectTargetModulesLoad : public CommandObjectTargetModulesModuleAutoComplete
{
public:
    CommandObjectTargetModulesLoad (CommandInterpreter &interpreter) : 
        CommandObjectTargetModulesModuleAutoComplete (interpreter,
                                                      "target modules load",
                                                      "Set the load addresses for one or more sections in a target module.",
                                                      "target modules load [--file <module> --uuid <uuid>] <sect-name> <address> [<sect-name> <address> ....]"),
        m_option_group (interpreter),
        m_file_option (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName, "Fullpath or basename for module to load.", ""),
        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)
    {
        m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
        m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
        m_option_group.Append (&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 
        m_option_group.Finalize();
    }

    virtual
    ~CommandObjectTargetModulesLoad ()
    {
    }

    virtual Options *
    GetOptions ()
    {
        return &m_option_group;
    }

protected:
    virtual bool
    DoExecute (Args& args,
             CommandReturnObject &result)
    {
        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
        if (target == NULL)
        {
            result.AppendError ("invalid target, create a debug target using the 'target create' command");
            result.SetStatus (eReturnStatusFailed);
            return false;
        }
        else
        {
            const size_t argc = args.GetArgumentCount();
            ModuleSpec module_spec;
            bool search_using_module_spec = false;
            if (m_file_option.GetOptionValue().OptionWasSet())
            {
                search_using_module_spec = true;
                const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
                const bool use_global_module_list = true;
                ModuleList module_list;
                const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, use_global_module_list);
                if (num_matches == 1)
                {
                    module_spec.GetFileSpec() = module_list.GetModuleAtIndex(0)->GetFileSpec();
                }
                else if (num_matches > 1 )
                {
                    search_using_module_spec = false;
                    result.AppendErrorWithFormat ("more than 1 module matched by name '%s'\n", arg_cstr);
                    result.SetStatus (eReturnStatusFailed);
                }
                else
                {
                    search_using_module_spec = false;
                    result.AppendErrorWithFormat ("no object file for module '%s'\n", arg_cstr);
                    result.SetStatus (eReturnStatusFailed);
                }
            }

            if (m_uuid_option_group.GetOptionValue().OptionWasSet())
            {
                search_using_module_spec = true;
                module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue();
            }

            if (search_using_module_spec)
            {
                ModuleList matching_modules;
                const size_t num_matches = target->GetImages().FindModules (module_spec, matching_modules);

                char path[PATH_MAX];
                if (num_matches == 1)
                {
                    Module *module = matching_modules.GetModulePointerAtIndex(0);
                    if (module)
                    {
                        ObjectFile *objfile = module->GetObjectFile();
                        if (objfile)
                        {
                            SectionList *section_list = module->GetSectionList();
                            if (section_list)
                            {
                                bool changed = false;
                                if (argc == 0)
                                {
                                    if (m_slide_option.GetOptionValue().OptionWasSet())
                                    {
                                        const addr_t slide = m_slide_option.GetOptionValue().GetCurrentValue();
                                        const bool slide_is_offset = true;
                                        module->SetLoadAddress (*target, slide, slide_is_offset, changed);
                                    }
                                    else
                                    {
                                        result.AppendError ("one or more section name + load address pair must be specified");
                                        result.SetStatus (eReturnStatusFailed);
                                        return false;
                                    }
                                }
                                else
                                {
                                    if (m_slide_option.GetOptionValue().OptionWasSet())
                                    {
                                        result.AppendError ("The \"--slide <offset>\" option can't be used in conjunction with setting section load addresses.\n");
                                        result.SetStatus (eReturnStatusFailed);
                                        return false;
                                    }

                                    for (size_t i=0; i<argc; i += 2)
                                    {
                                        const char *sect_name = args.GetArgumentAtIndex(i);
                                        const char *load_addr_cstr = args.GetArgumentAtIndex(i+1);
                                        if (sect_name && load_addr_cstr)
                                        {
                                            ConstString const_sect_name(sect_name);
                                            bool success = false;
                                            addr_t load_addr = Args::StringToUInt64(load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
                                            if (success)
                                            {
                                                SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
                                                if (section_sp)
                                                {
                                                    if (section_sp->IsThreadSpecific())
                                                    {
                                                        result.AppendErrorWithFormat ("thread specific sections are not yet supported (section '%s')\n", sect_name);
                                                        result.SetStatus (eReturnStatusFailed);
                                                        break;
                                                    }
                                                    else
                                                    {
                                                        if (target->GetSectionLoadList().SetSectionLoadAddress (section_sp, load_addr))
                                                            changed = true;
                                                        result.AppendMessageWithFormat("section '%s' loaded at 0x%" PRIx64 "\n", sect_name, load_addr);
                                                    }
                                                }
                                                else
                                                {
                                                    result.AppendErrorWithFormat ("no section found that matches the section name '%s'\n", sect_name);
                                                    result.SetStatus (eReturnStatusFailed);
                                                    break;
                                                }
                                            }
                                            else
                                            {
                                                result.AppendErrorWithFormat ("invalid load address string '%s'\n", load_addr_cstr);
                                                result.SetStatus (eReturnStatusFailed);
                                                break;
                                            }
                                        }
                                        else
                                        {
                                            if (sect_name)
                                                result.AppendError ("section names must be followed by a load address.\n");
                                            else
                                                result.AppendError ("one or more section name + load address pair must be specified.\n");
                                            result.SetStatus (eReturnStatusFailed);
                                            break;
                                        }
                                    }
                                }

                                if (changed)
                                {
                                    target->ModulesDidLoad (matching_modules);
                                    Process *process = m_exe_ctx.GetProcessPtr();
                                    if (process)
                                        process->Flush();
                                }
                            }
                            else
                            {
                                module->GetFileSpec().GetPath (path, sizeof(path));
                                result.AppendErrorWithFormat ("no sections in object file '%s'\n", path);
                                result.SetStatus (eReturnStatusFailed);
                            }
                        }
                        else
                        {
                            module->GetFileSpec().GetPath (path, sizeof(path));
                            result.AppendErrorWithFormat ("no object file for module '%s'\n", path);
                            result.SetStatus (eReturnStatusFailed);
                        }
                    }
                    else
                    {
                        FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
                        if (module_spec_file)
                        {
                            module_spec_file->GetPath (path, sizeof(path));
                            result.AppendErrorWithFormat ("invalid module '%s'.\n", path);
                        }
                        else
                            result.AppendError ("no module spec");
                        result.SetStatus (eReturnStatusFailed);
                    }
                }
                else
                {
                    std::string uuid_str;

                    if (module_spec.GetFileSpec())
                        module_spec.GetFileSpec().GetPath (path, sizeof(path));
                    else
                        path[0] = '\0';

                    if (module_spec.GetUUIDPtr())
                        uuid_str = module_spec.GetUUID().GetAsString();
                    if (num_matches > 1)
                    {
                        result.AppendErrorWithFormat ("multiple modules match%s%s%s%s:\n", 
                                                      path[0] ? " file=" : "", 
                                                      path,
                                                      !uuid_str.empty() ? " uuid=" : "", 
                                                      uuid_str.c_str());
                        for (size_t i=0; i<num_matches; ++i)
                        {
                            if (matching_modules.GetModulePointerAtIndex(i)->GetFileSpec().GetPath (path, sizeof(path)))
                                result.AppendMessageWithFormat("%s\n", path);
                        }
                    }
                    else
                    {
                        result.AppendErrorWithFormat ("no modules were found  that match%s%s%s%s.\n", 
                                                      path[0] ? " file=" : "", 
                                                      path,
                                                      !uuid_str.empty() ? " uuid=" : "", 
                                                      uuid_str.c_str());
                    }
                    result.SetStatus (eReturnStatusFailed);
                }
            }
            else
            {
                result.AppendError ("either the \"--file <module>\" or the \"--uuid <uuid>\" option must be specified.\n");
                result.SetStatus (eReturnStatusFailed);
                return false;
            }
        }
        return result.Succeeded();
    }

    OptionGroupOptions m_option_group;
    OptionGroupUUID m_uuid_option_group;
    OptionGroupString m_file_option;
    OptionGroupUInt64 m_slide_option;
};

//----------------------------------------------------------------------
// List images with associated information
//----------------------------------------------------------------------
class CommandObjectTargetModulesList : public CommandObjectParsed
{
public:
    class CommandOptions : public Options
    {
    public:
        CommandOptions (CommandInterpreter &interpreter) :
            Options(interpreter),
            m_format_array(),
            m_use_global_module_list (false),
            m_module_addr (LLDB_INVALID_ADDRESS)
        {
        }

        virtual
        ~CommandOptions ()
        {
        }

        virtual Error
        SetOptionValue (uint32_t option_idx, const char *option_arg)
        {
            Error error;

            const int short_option = m_getopt_table[option_idx].val;
            if (short_option == 'g')
            {
                m_use_global_module_list = true;
            }
            else if (short_option == 'a')
            {
                ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
                m_module_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
            }
            else
            {
                unsigned long width = 0;
                if (option_arg)
                    width = strtoul (option_arg, NULL, 0);
                m_format_array.push_back(std::make_pair(short_option, width));
            }
            return error;
        }

        void
        OptionParsingStarting ()
        {
            m_format_array.clear();
            m_use_global_module_list = false;
            m_module_addr = LLDB_INVALID_ADDRESS;
        }

        const OptionDefinition*
        GetDefinitions ()
        {
            return g_option_table;
        }

        // Options table: Required for subclasses of Options.

        static OptionDefinition g_option_table[];

        // Instance variables to hold the values for command options.
        typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection;
        FormatWidthCollection m_format_array;
        bool m_use_global_module_list;
        lldb::addr_t m_module_addr;
    };

    CommandObjectTargetModulesList (CommandInterpreter &interpreter) :
        CommandObjectParsed (interpreter,
                             "target modules list",
                             "List current executable and dependent shared library images.",
                             "target modules list [<cmd-options>]"),
        m_options (interpreter)
    {
    }

    virtual
    ~CommandObjectTargetModulesList ()
    {
    }

    virtual
    Options *
    GetOptions ()
    {
        return &m_options;
    }

protected:
    virtual bool
    DoExecute (Args& command,
             CommandReturnObject &result)
    {
        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
        const bool use_global_module_list = m_options.m_use_global_module_list;
        // Define a local module list here to ensure it lives longer than any "locker"
        // object which might lock its contents below (through the "module_list_ptr"
        // variable).
        ModuleList module_list;
        if (target == NULL && use_global_module_list == false)
        {
            result.AppendError ("invalid target, create a debug target using the 'target create' command");
            result.SetStatus (eReturnStatusFailed);
            return false;
        }
        else
        {
            if (target)
            {
                uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
                result.GetOutputStream().SetAddressByteSize(addr_byte_size);
                result.GetErrorStream().SetAddressByteSize(addr_byte_size);
            }
            // Dump all sections for all modules images
            Stream &strm = result.GetOutputStream();

            if (m_options.m_module_addr != LLDB_INVALID_ADDRESS)
            {
                if (target)
                {
                    Address module_address;
                    if (module_address.SetLoadAddress(m_options.m_module_addr, target))
                    {
                        ModuleSP module_sp (module_address.GetModule());
                        if (module_sp)
                        {
                            PrintModule (target, module_sp.get(), 0, strm);
                            result.SetStatus (eReturnStatusSuccessFinishResult);
                        }
                        else
                        {
                            result.AppendErrorWithFormat ("Couldn't find module matching address: 0x%" PRIx64 ".", m_options.m_module_addr);
                            result.SetStatus (eReturnStatusFailed);
                        }
                    }
                    else
                    {
                        result.AppendErrorWithFormat ("Couldn't find module containing address: 0x%" PRIx64 ".", m_options.m_module_addr);
                        result.SetStatus (eReturnStatusFailed);
                    }
                }
                else
                {
                    result.AppendError ("Can only look up modules by address with a valid target.");
                    result.SetStatus (eReturnStatusFailed);
                }
                return result.Succeeded();
            }

            size_t num_modules = 0;
            Mutex::Locker locker;      // This locker will be locked on the mutex in module_list_ptr if it is non-NULL.
                                       // Otherwise it will lock the AllocationModuleCollectionMutex when accessing
                                       // the global module list directly.
            const ModuleList *module_list_ptr = NULL;
            const size_t argc = command.GetArgumentCount();
            if (argc == 0)
            {
                if (use_global_module_list)
                {
                    locker.Lock (Module::GetAllocationModuleCollectionMutex());
                    num_modules = Module::GetNumberAllocatedModules();
                }
                else
                {
                    module_list_ptr = &target->GetImages();
                }
            }
            else
            {
                for (size_t i=0; i<argc; ++i)
                {
                    // Dump specified images (by basename or fullpath)
                    const char *arg_cstr = command.GetArgumentAtIndex(i);
                    const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, use_global_module_list);
                    if (num_matches == 0)
                    {
                        if (argc == 1)
                        {
                            result.AppendErrorWithFormat ("no modules found that match '%s'", arg_cstr);
                            result.SetStatus (eReturnStatusFailed);
                            return false;
                        }
                    }
                }

                module_list_ptr = &module_list;
            }

            if (module_list_ptr != NULL)
            {
                locker.Lock(module_list_ptr->GetMutex());
                num_modules = module_list_ptr->GetSize();
            }

            if (num_modules > 0)
            {
                for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
                {
                    ModuleSP module_sp;
                    Module *module;
                    if (module_list_ptr)
                    {
                        module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
                        module = module_sp.get();
                    }
                    else
                    {
                        module = Module::GetAllocatedModuleAtIndex(image_idx);
                        module_sp = module->shared_from_this();
                    }

                    const size_t indent = strm.Printf("[%3u] ", image_idx);
                    PrintModule (target, module, indent, strm);

                }
                result.SetStatus (eReturnStatusSuccessFinishResult);
            }
            else
            {
                if (argc)
                {
                    if (use_global_module_list)
                        result.AppendError ("the global module list has no matching modules");
                    else
                        result.AppendError ("the target has no matching modules");
                }
                else
                {
                    if (use_global_module_list)
                        result.AppendError ("the global module list is empty");
                    else
                        result.AppendError ("the target has no associated executable images");
                }
                result.SetStatus (eReturnStatusFailed);
                return false;
            }
        }
        return result.Succeeded();
    }

    void
    PrintModule (Target *target, Module *module, int indent, Stream &strm)
    {

        if (module == NULL)
        {
            strm.PutCString("Null module");
            return;
        }

        bool dump_object_name = false;
        if (m_options.m_format_array.empty())
        {
            m_options.m_format_array.push_back(std::make_pair('u', 0));
            m_options.m_format_array.push_back(std::make_pair('h', 0));
            m_options.m_format_array.push_back(std::make_pair('f', 0));
            m_options.m_format_array.push_back(std::make_pair('S', 0));
        }
        const size_t num_entries = m_options.m_format_array.size();
        bool print_space = false;
        for (size_t i=0; i<num_entries; ++i)
        {
            if (print_space)
                strm.PutChar(' ');
            print_space = true;
            const char format_char = m_options.m_format_array[i].first;
            uint32_t width = m_options.m_format_array[i].second;
            switch (format_char)
            {
                case 'A':
                    DumpModuleArchitecture (strm, module, false, width);
                    break;

                case 't':
                    DumpModuleArchitecture (strm, module, true, width);
                    break;

                case 'f':
                    DumpFullpath (strm, &module->GetFileSpec(), width);
                    dump_object_name = true;
                    break;

                case 'd':
                    DumpDirectory (strm, &module->GetFileSpec(), width);
                    break;

                case 'b':
                    DumpBasename (strm, &module->GetFileSpec(), width);
                    dump_object_name = true;
                    break;

                case 'h':
                case 'o':
                    // Image header address
                    {
                        uint32_t addr_nibble_width = target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16;

                        ObjectFile *objfile = module->GetObjectFile ();
                        if (objfile)
                        {
                            Address header_addr(objfile->GetHeaderAddress());
                            if (header_addr.IsValid())
                            {
                                if (target && !target->GetSectionLoadList().IsEmpty())
                                {
                                    lldb::addr_t header_load_addr = header_addr.GetLoadAddress (target);
                                    if (header_load_addr == LLDB_INVALID_ADDRESS)
                                    {
                                        header_addr.Dump (&strm, target, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleFileAddress);
                                    }
                                    else
                                    {
                                        if (format_char == 'o')
                                        {
                                            // Show the offset of slide for the image
                                            strm.Printf ("0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width, header_load_addr - header_addr.GetFileAddress());
                                        }
                                        else
                                        {
                                            // Show the load address of the image
                                            strm.Printf ("0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width, header_load_addr);
                                        }
                                    }
                                    break;
                                }
                                // The address was valid, but the image isn't loaded, output the address in an appropriate format
                                header_addr.Dump (&strm, target, Address::DumpStyleFileAddress);
                                break;
                            }
                        }
                        strm.Printf ("%*s", addr_nibble_width + 2, "");
                    }
                    break;
                case 'r':
                    {
                        size_t ref_count = 0;
                        ModuleSP module_sp (module->shared_from_this());
                        if (module_sp)
                        {
                            // Take one away to make sure we don't count our local "module_sp"
                            ref_count = module_sp.use_count() - 1;
                        }
                        if (width)
                            strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count);
                        else
                            strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count);
                    }
                    break;

                case 's':
                case 'S':
                    {
                        SymbolVendor *symbol_vendor = module->GetSymbolVendor();
                        if (symbol_vendor)
                        {
                            SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
                            if (symbol_file)
                            {
                                if (format_char == 'S')
                                {
                                    FileSpec &symfile_spec = symbol_file->GetObjectFile()->GetFileSpec();
                                    // Dump symbol file only if different from module file
                                    if (!symfile_spec || symfile_spec == module->GetFileSpec())
                                    {
                                        print_space = false;
                                        break;
                                    }
                                    // Add a newline and indent past the index
                                    strm.Printf ("\n%*s", indent, "");
                                }
                                DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
                                dump_object_name = true;
                                break;
                            }
                        }
                        strm.Printf("%.*s", width, "<NONE>");
                    }
                    break;

                case 'm':
                    module->GetModificationTime().Dump(&strm, width);
                    break;

                case 'p':
                    strm.Printf("%p", static_cast<void*>(module));
                    break;

                case 'u':
                    DumpModuleUUID(strm, module);
                    break;

                default:
                    break;
            }

        }
        if (dump_object_name)
        {
            const char *object_name = module->GetObjectName().GetCString();
            if (object_name)
                strm.Printf ("(%s)", object_name);
        }
        strm.EOL();
    }

    CommandOptions m_options;
};

OptionDefinition
CommandObjectTargetModulesList::CommandOptions::g_option_table[] =
{
    { LLDB_OPT_SET_1, false, "address",    'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Display the image at this address."},
    { LLDB_OPT_SET_1, false, "arch",       'A', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the architecture when listing images."},
    { LLDB_OPT_SET_1, false, "triple",     't', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the triple when listing images."},
    { LLDB_OPT_SET_1, false, "header",     'h', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone,    "Display the image header address as a load address if debugging, a file address otherwise."},
    { LLDB_OPT_SET_1, false, "offset",     'o', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone,    "Display the image header address offset from the header file address (the slide amount)."},
    { LLDB_OPT_SET_1, false, "uuid",       'u', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone,    "Display the UUID when listing images."},
    { LLDB_OPT_SET_1, false, "fullpath",   'f', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the fullpath to the image object file."},
    { LLDB_OPT_SET_1, false, "directory",  'd', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the directory with optional width for the image object file."},
    { LLDB_OPT_SET_1, false, "basename",   'b', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the basename with optional width for the image object file."},
    { LLDB_OPT_SET_1, false, "symfile",    's', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the fullpath to the image symbol file with optional width."},
    { LLDB_OPT_SET_1, false, "symfile-unique", 'S', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the symbol file with optional width only if it is different from the executable object file."},
    { LLDB_OPT_SET_1, false, "mod-time",   'm', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the modification time with optional width of the module."},
    { LLDB_OPT_SET_1, false, "ref-count",  'r', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth,   "Display the reference count if the module is still in the shared module cache."},
    { LLDB_OPT_SET_1, false, "pointer",    'p', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeNone,    "Display the module pointer."},
    { LLDB_OPT_SET_1, false, "global",     'g', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone,    "Display the modules from the global module list, not just the current target."},
    { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
};

#pragma mark CommandObjectTargetModulesShowUnwind

//----------------------------------------------------------------------
// Lookup unwind information in images
//----------------------------------------------------------------------

class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed
{
public:

    enum
    {
        eLookupTypeInvalid = -1,
        eLookupTypeAddress = 0,
        eLookupTypeSymbol,
        eLookupTypeFunction,
        eLookupTypeFunctionOrSymbol,
        kNumLookupTypes
    };

    class CommandOptions : public Options
    {
    public:

        CommandOptions (CommandInterpreter &interpreter) :
            Options(interpreter),
            m_type(eLookupTypeInvalid),
            m_str(),
            m_addr(LLDB_INVALID_ADDRESS)
        {
        }

        virtual
        ~CommandOptions ()
        {
        }

        virtual Error
        SetOptionValue (uint32_t option_idx, const char *option_arg)
        {
            Error error;

            const int short_option = m_getopt_table[option_idx].val;

            switch (short_option)
            {
                case 'a':
                {
                    ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
                    m_str = option_arg;
                    m_type = eLookupTypeAddress;
                    m_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
                    if (m_addr == LLDB_INVALID_ADDRESS)
                        error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg);
                    break;
                }

                case 'n':
                {
                    m_str = option_arg;
                    m_type = eLookupTypeFunctionOrSymbol;
                    break;
                }

                default:
                    error.SetErrorStringWithFormat ("unrecognized option %c.", short_option);
                    break;
            }

            return error;
        }

        void
        OptionParsingStarting ()
        {
            m_type = eLookupTypeInvalid;
            m_str.clear();
            m_addr = LLDB_INVALID_ADDRESS;
        }

        const OptionDefinition*
        GetDefinitions ()
        {
            return g_option_table;
        }

        // Options table: Required for subclasses of Options.

        static OptionDefinition g_option_table[];

        // Instance variables to hold the values for command options.

        int             m_type;         // Should be a eLookupTypeXXX enum after parsing options
        std::string     m_str;          // Holds name lookup
        lldb::addr_t    m_addr;         // Holds the address to lookup
    };

    CommandObjectTargetModulesShowUnwind (CommandInterpreter &interpreter) :
        CommandObjectParsed (interpreter,
                             "target modules show-unwind",
                             "Show synthesized unwind instructions for a function.",
                             NULL,
                             eFlagRequiresTarget        |
                             eFlagRequiresProcess       |
                             eFlagProcessMustBeLaunched |
                             eFlagProcessMustBePaused   ),
        m_options (interpreter)
    {
    }

    virtual
    ~CommandObjectTargetModulesShowUnwind ()
    {
    }

    virtual
    Options *
    GetOptions ()
    {
        return &m_options;
    }

protected:
    bool
    DoExecute (Args& command,
             CommandReturnObject &result)
    {
        Target *target = m_exe_ctx.GetTargetPtr();
        Process *process = m_exe_ctx.GetProcessPtr();
        ABI *abi = NULL;
        if (process)
          abi = process->GetABI().get();

        if (process == NULL)
        {
            result.AppendError ("You must have a process running to use this command.");
            result.SetStatus (eReturnStatusFailed);
            return false;
        }

        ThreadList threads(process->GetThreadList());
        if (threads.GetSize() == 0)
        {
            result.AppendError ("The process must be paused to use this command.");
            result.SetStatus (eReturnStatusFailed);
            return false;
        }

        ThreadSP thread(threads.GetThreadAtIndex(0));
        if (thread.get() == NULL)
        {
            result.AppendError ("The process must be paused to use this command.");
            result.SetStatus (eReturnStatusFailed);
            return false;
        }

        SymbolContextList sc_list;

        if (m_options.m_type == eLookupTypeFunctionOrSymbol)
        {
            ConstString function_name (m_options.m_str.c_str());
            target->GetImages().FindFunctions (function_name, eFunctionNameTypeAuto, true, false, true, sc_list);
        }
        else if (m_options.m_type == eLookupTypeAddress && target)
        {
            Address addr;
            if (target->GetSectionLoadList().ResolveLoadAddress (m_options.m_addr, addr))
            {
                SymbolContext sc;
                ModuleSP module_sp (addr.GetModule());
                module_sp->ResolveSymbolContextForAddress (addr, eSymbolContextEverything, sc);
                if (sc.function || sc.symbol)
                {
                    sc_list.Append(sc);
                }
            }
        }
        else
        {
            result.AppendError ("address-expression or function name option must be specified.");
            result.SetStatus (eReturnStatusFailed);
            return false;
        }

        size_t num_matches = sc_list.GetSize();
        if (num_matches == 0)
        {
            result.AppendErrorWithFormat ("no unwind data found that matches '%s'.", m_options.m_str.c_str());
            result.SetStatus (eReturnStatusFailed);
            return false;
        }

        for (uint32_t idx = 0; idx < num_matches; idx++)
        {
            SymbolContext sc;
            sc_list.GetContextAtIndex(idx, sc);
            if (sc.symbol == NULL && sc.function == NULL)
                continue;
            if (sc.module_sp.get() == NULL || sc.module_sp->GetObjectFile() == NULL)
                continue;
            AddressRange range;
            if (!sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range))
                continue;
            if (!range.GetBaseAddress().IsValid())
                continue;
            ConstString funcname(sc.GetFunctionName());
            if (funcname.IsEmpty())
                continue;
            addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
            if (abi)
                start_addr = abi->FixCodeAddress(start_addr);

            FuncUnwindersSP func_unwinders_sp (sc.module_sp->GetObjectFile()->GetUnwindTable().GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
            if (func_unwinders_sp.get() == NULL)
                continue;

            result.GetOutputStream().Printf("UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);

            UnwindPlanSP non_callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread.get(), -1);
            if (non_callsite_unwind_plan.get())
            {
                result.GetOutputStream().Printf("Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n", non_callsite_unwind_plan->GetSourceName().AsCString());
            }
            UnwindPlanSP callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(*target, -1);
            if (callsite_unwind_plan.get())
            {
                result.GetOutputStream().Printf("Synchronous (restricted to call-sites) UnwindPlan is '%s'\n", callsite_unwind_plan->GetSourceName().AsCString());
            }
            UnwindPlanSP fast_unwind_plan = func_unwinders_sp->GetUnwindPlanFastUnwind(*thread.get());
            if (fast_unwind_plan.get())
            {
                result.GetOutputStream().Printf("Fast UnwindPlan is '%s'\n", fast_unwind_plan->GetSourceName().AsCString());
            }

            result.GetOutputStream().Printf("\n");

            UnwindPlanSP assembly_sp = func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread.get(), 0);
            if (assembly_sp)
            {
                result.GetOutputStream().Printf("Assembly language inspection UnwindPlan:\n");
                assembly_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
                result.GetOutputStream().Printf("\n");
            }
            

            UnwindPlanSP ehframe_sp = func_unwinders_sp->GetEHFrameUnwindPlan(*target, 0);
            if (ehframe_sp)
            {
                result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
                ehframe_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
                result.GetOutputStream().Printf("\n");
            }

            UnwindPlanSP ehframe_augmented_sp = func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread.get(), 0);
            if (ehframe_augmented_sp)
            {
                result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
                ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
                result.GetOutputStream().Printf("\n");
            }

            UnwindPlanSP compact_unwind_sp = func_unwinders_sp->GetCompactUnwindUnwindPlan(*target, 0);
            if (compact_unwind_sp)
            {
                result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
                compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
                result.GetOutputStream().Printf("\n");
            }

            if (fast_unwind_plan)
            {
                result.GetOutputStream().Printf("Fast UnwindPlan:\n");
                fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
                result.GetOutputStream().Printf("\n");
            }

            ABISP abi_sp = process->GetABI();
            if (abi_sp)
            {
                UnwindPlan arch_default(lldb::eRegisterKindGeneric);
                if (abi_sp->CreateDefaultUnwindPlan (arch_default))
                {
                    result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
                    arch_default.Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
                    result.GetOutputStream().Printf("\n");
                }

                UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
                if (abi_sp->CreateFunctionEntryUnwindPlan (arch_entry))
                {
                    result.GetOutputStream().Printf("Arch default at entry point UnwindPlan:\n");
                    arch_entry.Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
                    result.GetOutputStream().Printf("\n");
                }
            }

            result.GetOutputStream().Printf ("\n");
        }
        return result.Succeeded();
    }

    CommandOptions m_options;
};

OptionDefinition
CommandObjectTargetModulesShowUnwind::CommandOptions::g_option_table[] =
{
    { LLDB_OPT_SET_1,   false,  "name",       'n', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name."},
    { LLDB_OPT_SET_2,   false,  "address",    'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address"},
    { 0,                false, NULL,           0, 0,                 NULL, NULL, 0, eArgTypeNone, NULL }
};

//----------------------------------------------------------------------
// Lookup information in images
//----------------------------------------------------------------------
class CommandObjectTargetModulesLookup : public CommandObjectParsed
{
public:
    enum
    {
        eLookupTypeInvalid = -1,
        eLookupTypeAddress = 0,
        eLookupTypeSymbol,
        eLookupTypeFileLine,    // Line is optional
        eLookupTypeFunction,
        eLookupTypeFunctionOrSymbol,
        eLookupTypeType,
        kNumLookupTypes
    };

    class CommandOptions : public Options
    {
    public:
        CommandOptions (CommandInterpreter &interpreter) :
        Options(interpreter)
        {
            OptionParsingStarting();
        }

        virtual
        ~CommandOptions ()
        {
        }

        virtual Error
        SetOptionValue (uint32_t option_idx, const char *option_arg)
        {
            Error error;

            const int short_option = m_getopt_table[option_idx].val;

            switch (short_option)
            {
                case 'a':
                    {
                        m_type = eLookupTypeAddress;
                        ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
                        m_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
                    }
                    break;

                case 'o':
                    m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
                    if (m_offset == LLDB_INVALID_ADDRESS)
                        error.SetErrorStringWithFormat ("invalid offset string '%s'", option_arg);
                    break;

                case 's':
                    m_str = option_arg;
                    m_type = eLookupTypeSymbol;
                    break;

                case 'f':
                    m_file.SetFile (option_arg, false);
                    m_type = eLookupTypeFileLine;
                    break;

                case 'i':
                    m_include_inlines = false;
                    break;

                case 'l':
                    m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX);
                    if (m_line_number == UINT32_MAX)
                        error.SetErrorStringWithFormat ("invalid line number string '%s'", option_arg);
                    else if (m_line_number == 0)
                        error.SetErrorString ("zero is an invalid line number");
                    m_type = eLookupTypeFileLine;
                    break;

                case 'F':
                    m_str = option_arg;
                    m_type = eLookupTypeFunction;
                    break;

                case 'n':
                    m_str = option_arg;
                    m_type = eLookupTypeFunctionOrSymbol;
                    break;

                case 't':
                    m_str = option_arg;
                    m_type = eLookupTypeType;
                    break;

                case 'v':
                    m_verbose = 1;
                    break;

                case 'A':
                    m_print_all = true;
                    break;

                case 'r':
                    m_use_regex = true;
                    break;
            }

            return error;
        }

        void
        OptionParsingStarting ()
        {
            m_type = eLookupTypeInvalid;
            m_str.clear();
            m_file.Clear();
            m_addr = LLDB_INVALID_ADDRESS;
            m_offset = 0;
            m_line_number = 0;
            m_use_regex = false;
            m_include_inlines = true;
            m_verbose = false;
            m_print_all = false;
        }

        const OptionDefinition*
        GetDefinitions ()
        {
            return g_option_table;
        }

        // Options table: Required for subclasses of Options.

        static OptionDefinition g_option_table[];
        int             m_type;         // Should be a eLookupTypeXXX enum after parsing options
        std::string     m_str;          // Holds name lookup
        FileSpec        m_file;         // Files for file lookups
        lldb::addr_t    m_addr;         // Holds the address to lookup
        lldb::addr_t    m_offset;       // Subtract this offset from m_addr before doing lookups.
        uint32_t        m_line_number;  // Line number for file+line lookups
        bool            m_use_regex;    // Name lookups in m_str are regular expressions.
        bool            m_include_inlines;// Check for inline entries when looking up by file/line.
        bool            m_verbose;      // Enable verbose lookup info
        bool            m_print_all;    // Print all matches, even in cases where there's a best match.
    };

    CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) :
        CommandObjectParsed (interpreter,
                             "target modules lookup",
                             "Look up information within executable and dependent shared library images.",
                             NULL,
                             eFlagRequiresTarget),
        m_options (interpreter)
    {
        CommandArgumentEntry arg;
        CommandArgumentData file_arg;

        // Define the first (and only) variant of this arg.
        file_arg.arg_type = eArgTypeFilename;
        file_arg.arg_repetition = eArgRepeatStar;

        // There is only one variant this argument could be; put it into the argument entry.
        arg.push_back (file_arg);

        // Push the data for the first argument into the m_arguments vector.
        m_arguments.push_back (arg);
    }

    virtual
    ~CommandObjectTargetModulesLookup ()
    {
    }

    virtual Options *
    GetOptions ()
    {
        return &m_options;
    }

    bool
    LookupHere (CommandInterpreter &interpreter, CommandReturnObject &result, bool &syntax_error)
    {
        switch (m_options.m_type)
        {
            case eLookupTypeAddress:
            case eLookupTypeFileLine:
            case eLookupTypeFunction:
            case eLookupTypeFunctionOrSymbol:
            case eLookupTypeSymbol:
            default:
                return false;
            case eLookupTypeType:
                break;
        }

        StackFrameSP frame = m_exe_ctx.GetFrameSP();

        if (!frame)
            return false;

        const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));

        if (!sym_ctx.module_sp)
            return false;

        switch (m_options.m_type)
        {
        default:
            return false;
        case eLookupTypeType:
            if (!m_options.m_str.empty())
            {
                if (LookupTypeHere (m_interpreter,
                                    result.GetOutputStream(),
                                    sym_ctx,
                                    m_options.m_str.c_str(),
                                    m_options.m_use_regex))
                {
                    result.SetStatus(eReturnStatusSuccessFinishResult);
                    return true;
                }
            }
            break;
        }

        return true;
    }

    bool
    LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
    {
        switch (m_options.m_type)
        {
            case eLookupTypeAddress:
                if (m_options.m_addr != LLDB_INVALID_ADDRESS)
                {
                    if (LookupAddressInModule (m_interpreter, 
                                               result.GetOutputStream(), 
                                               module, 
                                               eSymbolContextEverything, 
                                               m_options.m_addr, 
                                               m_options.m_offset,
                                               m_options.m_verbose))
                    {
                        result.SetStatus(eReturnStatusSuccessFinishResult);
                        return true;
                    }
                }
                break;

            case eLookupTypeSymbol:
                if (!m_options.m_str.empty())
                {
                    if (LookupSymbolInModule (m_interpreter,
                                              result.GetOutputStream(),
                                              module,
                                              m_options.m_str.c_str(),
                                              m_options.m_use_regex,
                                              m_options.m_verbose))
                    {
                        result.SetStatus(eReturnStatusSuccessFinishResult);
                        return true;
                    }
                }
                break;

            case eLookupTypeFileLine:
                if (m_options.m_file)
                {
                    if (LookupFileAndLineInModule (m_interpreter,
                                                   result.GetOutputStream(),
                                                   module,
                                                   m_options.m_file,
                                                   m_options.m_line_number,
                                                   m_options.m_include_inlines,
                                                   m_options.m_verbose))
                    {
                        result.SetStatus(eReturnStatusSuccessFinishResult);
                        return true;
                    }
                }
                break;

            case eLookupTypeFunctionOrSymbol:
            case eLookupTypeFunction:
                if (!m_options.m_str.empty())
                {
                    if (LookupFunctionInModule (m_interpreter,
                                                result.GetOutputStream(),
                                                module,
                                                m_options.m_str.c_str(),
                                                m_options.m_use_regex,
                                                m_options.m_include_inlines,
                                                m_options.m_type == eLookupTypeFunctionOrSymbol, // include symbols
                                                m_options.m_verbose))
                    {
                        result.SetStatus(eReturnStatusSuccessFinishResult);
                        return true;
                    }
                }
                break;

            case eLookupTypeType:
                if (!m_options.m_str.empty())
                {
                    if (LookupTypeInModule (m_interpreter,
                                            result.GetOutputStream(),
                                            module,
                                            m_options.m_str.c_str(),
                                            m_options.m_use_regex))
                    {
                        result.SetStatus(eReturnStatusSuccessFinishResult);
                        return true;
                    }
                }
                break;

            default:
                m_options.GenerateOptionUsage (result.GetErrorStream(), this);
                syntax_error = true;
                break;
        }

        result.SetStatus (eReturnStatusFailed);
        return false;
    }

protected:
    virtual bool
    DoExecute (Args& command,
             CommandReturnObject &result)
    {
        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
        if (target == NULL)
        {
            result.AppendError ("invalid target, create a debug target using the 'target create' command");
            result.SetStatus (eReturnStatusFailed);
            return false;
        }
        else
        {
            bool syntax_error = false;
            uint32_t i;
            uint32_t num_successful_lookups = 0;
            uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
            result.GetOutputStream().SetAddressByteSize(addr_byte_size);
            result.GetErrorStream().SetAddressByteSize(addr_byte_size);
            // Dump all sections for all modules images

            if (command.GetArgumentCount() == 0)
            {
                ModuleSP current_module;

                // Where it is possible to look in the current symbol context
                // first, try that.  If this search was successful and --all
                // was not passed, don't print anything else.
                if (LookupHere (m_interpreter, result, syntax_error))
                {
                    result.GetOutputStream().EOL();
                    num_successful_lookups++;
                    if (!m_options.m_print_all)
                    {
                        result.SetStatus (eReturnStatusSuccessFinishResult);
                        return result.Succeeded();
                    }
                }

                // Dump all sections for all other modules

                const ModuleList &target_modules = target->GetImages();
                Mutex::Locker modules_locker(target_modules.GetMutex());
                const size_t num_modules = target_modules.GetSize();
                if (num_modules > 0)
                {
                    for (i = 0; i<num_modules && syntax_error == false; ++i)
                    {
                        Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked(i);

                        if (module_pointer != current_module.get() &&
                            LookupInModule (m_interpreter, target_modules.GetModulePointerAtIndexUnlocked(i), result, syntax_error))
                        {
                            result.GetOutputStream().EOL();
                            num_successful_lookups++;
                        }
                    }
                }
                else
                {
                    result.AppendError ("the target has no associated executable images");
                    result.SetStatus (eReturnStatusFailed);
                    return false;
                }
            }
            else
            {
                // Dump specified images (by basename or fullpath)
                const char *arg_cstr;
                for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i)
                {
                    ModuleList module_list;
                    const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, false);
                    if (num_matches > 0)
                    {
                        for (size_t j=0; j<num_matches; ++j)
                        {
                            Module *module = module_list.GetModulePointerAtIndex(j);
                            if (module)
                            {
                                if (LookupInModule (m_interpreter, module, result, syntax_error))
                                {
                                    result.GetOutputStream().EOL();
                                    num_successful_lookups++;
                                }
                            }
                        }
                    }
                    else
                        result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
                }
            }

            if (num_successful_lookups > 0)
                result.SetStatus (eReturnStatusSuccessFinishResult);
            else
                result.SetStatus (eReturnStatusFailed);
        }
        return result.Succeeded();
    }

    CommandOptions m_options;
};

OptionDefinition
CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] =
{
    { LLDB_OPT_SET_1,   true,  "address",    'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules."},
    { LLDB_OPT_SET_1,   false, "offset",     'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOffset,           "When looking up an address subtract <offset> from any addresses before doing the lookup."},
    { LLDB_OPT_SET_2| LLDB_OPT_SET_4 | LLDB_OPT_SET_5
      /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */ ,
                        false, "regex",      'r', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone,             "The <name> argument for name lookups are regular expressions."},
    { LLDB_OPT_SET_2,   true,  "symbol",     's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeSymbol,           "Lookup a symbol by name in the symbol tables in one or more target modules."},
    { LLDB_OPT_SET_3,   true,  "file",       'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFilename,         "Lookup a file by fullpath or basename in one or more target modules."},
    { LLDB_OPT_SET_3,   false, "line",       'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,          "Lookup a line number in a file (must be used in conjunction with --file)."},
    { LLDB_OPT_SET_FROM_TO(3,5),
                        false, "no-inlines", 'i', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone,             "Ignore inline entries (must be used in conjunction with --file or --function)."},
    { LLDB_OPT_SET_4,   true,  "function",   'F', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFunctionName,     "Lookup a function by name in the debug symbols in one or more target modules."},
    { LLDB_OPT_SET_5,   true,  "name",       'n', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFunctionOrSymbol, "Lookup a function or symbol by name in one or more target modules."},
    { LLDB_OPT_SET_6,   true,  "type",       't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,             "Lookup a type by name in the debug symbols in one or more target modules."},
    { LLDB_OPT_SET_ALL, false, "verbose",    'v', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone,             "Enable verbose lookup information."},
    { LLDB_OPT_SET_ALL, false, "all",        'A', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone,             "Print all matches, not just the best match, if a best match is available."},
    { 0,                false, NULL,           0, 0,                 NULL, NULL, 0, eArgTypeNone,             NULL }
};


#pragma mark CommandObjectMultiwordImageSearchPaths

//-------------------------------------------------------------------------
// CommandObjectMultiwordImageSearchPaths
//-------------------------------------------------------------------------

class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword
{
public:
    CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) :
    CommandObjectMultiword (interpreter, 
                            "target modules search-paths",
                            "A set of commands for operating on debugger target image search paths.",
                            "target modules search-paths <subcommand> [<subcommand-options>]")
    {
        LoadSubCommand ("add",     CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter)));
        LoadSubCommand ("clear",   CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter)));
        LoadSubCommand ("insert",  CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter)));
        LoadSubCommand ("list",    CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter)));
        LoadSubCommand ("query",   CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter)));
    }

    ~CommandObjectTargetModulesImageSearchPaths()
    {
    }
};



#pragma mark CommandObjectTargetModules

//-------------------------------------------------------------------------
// CommandObjectTargetModules
//-------------------------------------------------------------------------

class CommandObjectTargetModules : public CommandObjectMultiword
{
public:
    //------------------------------------------------------------------
    // Constructors and Destructors
    //------------------------------------------------------------------
    CommandObjectTargetModules(CommandInterpreter &interpreter) :
        CommandObjectMultiword (interpreter,
                                "target modules",
                                "A set of commands for accessing information for one or more target modules.",
                                "target modules <sub-command> ...")
    {
        LoadSubCommand ("add",          CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter)));
        LoadSubCommand ("load",         CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter)));
        LoadSubCommand ("dump",         CommandObjectSP (new CommandObjectTargetModulesDump (interpreter)));
        LoadSubCommand ("list",         CommandObjectSP (new CommandObjectTargetModulesList (interpreter)));
        LoadSubCommand ("lookup",       CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter)));
        LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter)));
        LoadSubCommand ("show-unwind",  CommandObjectSP (new CommandObjectTargetModulesShowUnwind (interpreter)));

    }
    virtual
    ~CommandObjectTargetModules()
    {
    }

private:
    //------------------------------------------------------------------
    // For CommandObjectTargetModules only
    //------------------------------------------------------------------
    DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules);
};



class CommandObjectTargetSymbolsAdd : public CommandObjectParsed
{
public:
    CommandObjectTargetSymbolsAdd (CommandInterpreter &interpreter) :
        CommandObjectParsed (interpreter,
                             "target symbols add",
                             "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.",
                             "target symbols add [<symfile>]", eFlagRequiresTarget),
        m_option_group (interpreter),
        m_file_option (LLDB_OPT_SET_1, false, "shlib", 's', CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Fullpath or basename for module to find debug symbols for."),
        m_current_frame_option (LLDB_OPT_SET_2, false, "frame", 'F', "Locate the debug symbols the currently selected frame.", false, true)

    {
        m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
        m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
        m_option_group.Append (&m_current_frame_option, LLDB_OPT_SET_2, LLDB_OPT_SET_2);
        m_option_group.Finalize();
    }

    virtual
    ~CommandObjectTargetSymbolsAdd ()
    {
    }

    virtual int
    HandleArgumentCompletion (Args &input,
                              int &cursor_index,
                              int &cursor_char_position,
                              OptionElementVector &opt_element_vector,
                              int match_start_point,
                              int max_return_elements,
                              bool &word_complete,
                              StringList &matches)
    {
        std::string completion_str (input.GetArgumentAtIndex(cursor_index));
        completion_str.erase (cursor_char_position);

        CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 
                                                             CommandCompletions::eDiskFileCompletion,
                                                             completion_str.c_str(),
                                                             match_start_point,
                                                             max_return_elements,
                                                             NULL,
                                                             word_complete,
                                                             matches);
        return matches.GetSize();
    }

    virtual Options *
    GetOptions ()
    {
        return &m_option_group;
    }

protected:
    bool
    AddModuleSymbols (Target *target,
                      ModuleSpec &module_spec,
                      bool &flush,
                      CommandReturnObject &result)
    {
        const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
        if (symbol_fspec)
        {
            char symfile_path[PATH_MAX];
            symbol_fspec.GetPath (symfile_path, sizeof(symfile_path));

            if (!module_spec.GetUUID().IsValid())
            {
                if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
                    module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
            }
            // We now have a module that represents a symbol file
            // that can be used for a module that might exist in the
            // current target, so we need to find that module in the
            // target
            ModuleList matching_module_list;

            size_t num_matches = 0;
            // First extract all module specs from the symbol file
            lldb_private::ModuleSpecList symfile_module_specs;
            if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(), 0, 0, symfile_module_specs))
            {
                // Now extract the module spec that matches the target architecture
                ModuleSpec target_arch_module_spec;
                ModuleSpec symfile_module_spec;
                target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
                if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec, symfile_module_spec))
                {
                    // See if it has a UUID?
                    if (symfile_module_spec.GetUUID().IsValid())
                    {
                        // It has a UUID, look for this UUID in the target modules
                        ModuleSpec symfile_uuid_module_spec;
                        symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
                        num_matches = target->GetImages().FindModules (symfile_uuid_module_spec, matching_module_list);
                    }
                }

                if (num_matches == 0)
                {
                    // No matches yet, iterate through the module specs to find a UUID value that
                    // we can match up to an image in our target
                    const size_t num_symfile_module_specs = symfile_module_specs.GetSize();
                    for (size_t i=0; i<num_symfile_module_specs && num_matches == 0; ++i)
                    {
                        if (symfile_module_specs.GetModuleSpecAtIndex(i, symfile_module_spec))
                        {
                            if (symfile_module_spec.GetUUID().IsValid())
                            {
                                // It has a UUID, look for this UUID in the target modules
                                ModuleSpec symfile_uuid_module_spec;
                                symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
                                num_matches = target->GetImages().FindModules (symfile_uuid_module_spec, matching_module_list);
                            }
                        }
                    }
                }
            }

            // Just try to match up the file by basename if we have no matches at this point
            if (num_matches == 0)
                num_matches = target->GetImages().FindModules (module_spec, matching_module_list);

            while (num_matches == 0)
            {
                ConstString filename_no_extension(module_spec.GetFileSpec().GetFileNameStrippingExtension());
                // Empty string returned, lets bail
                if (!filename_no_extension)
                    break;

                // Check if there was no extension to strip and the basename is the same
                if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
                    break;

                // Replace basename with one less extension
                module_spec.GetFileSpec().GetFilename() = filename_no_extension;

                num_matches = target->GetImages().FindModules (module_spec, matching_module_list);
            }

            if (num_matches > 1)
            {
                result.AppendErrorWithFormat ("multiple modules match symbol file '%s', use the --uuid option to resolve the ambiguity.\n", symfile_path);
            }
            else if (num_matches == 1)
            {
                ModuleSP module_sp (matching_module_list.GetModuleAtIndex(0));

                // The module has not yet created its symbol vendor, we can just
                // give the existing target module the symfile path to use for
                // when it decides to create it!
                module_sp->SetSymbolFileFileSpec (symbol_fspec);

                SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(true, &result.GetErrorStream());
                if (symbol_vendor)
                {
                    SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();

                    if (symbol_file)
                    {
                        ObjectFile *object_file = symbol_file->GetObjectFile();

                        if (object_file && object_file->GetFileSpec() == symbol_fspec)
                        {
                            // Provide feedback that the symfile has been successfully added.
                            const FileSpec &module_fs = module_sp->GetFileSpec();
                            result.AppendMessageWithFormat("symbol file '%s' has been added to '%s'\n",
                                                           symfile_path,
                                                           module_fs.GetPath().c_str());

                            // Let clients know something changed in the module
                            // if it is currently loaded
                            ModuleList module_list;
                            module_list.Append (module_sp);
                            target->SymbolsDidLoad (module_list);

                            // Make sure we load any scripting resources that may be embedded
                            // in the debug info files in case the platform supports that.
                            Error error;
                            StreamString feedback_stream;
                            module_sp->LoadScriptingResourceInTarget (target, error,&feedback_stream);
                            if (error.Fail() && error.AsCString())
                                result.AppendWarningWithFormat("unable to load scripting data for module %s - error reported was %s",
                                                               module_sp->GetFileSpec().GetFileNameStrippingExtension().GetCString(),
                                                               error.AsCString());
                            else if (feedback_stream.GetSize())
                                result.AppendWarningWithFormat("%s",feedback_stream.GetData());

                            flush = true;
                            result.SetStatus (eReturnStatusSuccessFinishResult);
                            return true;
                        }
                    }
                }
                // Clear the symbol file spec if anything went wrong
                module_sp->SetSymbolFileFileSpec (FileSpec());
            }

            if (module_spec.GetUUID().IsValid())
            {
                StreamString ss_symfile_uuid;
                module_spec.GetUUID().Dump(&ss_symfile_uuid);
                result.AppendErrorWithFormat ("symbol file '%s' (%s) does not match any existing module%s\n",
                                              symfile_path,
                                              ss_symfile_uuid.GetData(),
                                              (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
                                                ? "\n       please specify the full path to the symbol file"
                                                : "");
            }
            else
            {
                result.AppendErrorWithFormat ("symbol file '%s' does not match any existing module%s\n",
                                              symfile_path,
                                              (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
                                                ? "\n       please specify the full path to the symbol file"
                                                : "");
            }
        }
        else
        {
            result.AppendError ("one or more executable image paths must be specified");
        }
        result.SetStatus (eReturnStatusFailed);
        return false;
    }

    virtual bool
    DoExecute (Args& args,
             CommandReturnObject &result)
    {
        Target *target = m_exe_ctx.GetTargetPtr();
        result.SetStatus (eReturnStatusFailed);
        bool flush = false;
        ModuleSpec module_spec;
        const bool uuid_option_set = m_uuid_option_group.GetOptionValue().OptionWasSet();
        const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
        const bool frame_option_set = m_current_frame_option.GetOptionValue().OptionWasSet();

        const size_t argc = args.GetArgumentCount();
        if (argc == 0)
        {
            if (uuid_option_set || file_option_set || frame_option_set)
            {
                bool success = false;
                bool error_set = false;
                if (frame_option_set)
                {
                    Process *process = m_exe_ctx.GetProcessPtr();
                    if (process)
                    {
                        const StateType process_state = process->GetState();
                        if (StateIsStoppedState (process_state, true))
                        {
                            StackFrame *frame = m_exe_ctx.GetFramePtr();
                            if (frame)
                            {
                                ModuleSP frame_module_sp (frame->GetSymbolContext(eSymbolContextModule).module_sp);
                                if (frame_module_sp)
                                {
                                    if (frame_module_sp->GetPlatformFileSpec().Exists())
                                    {
                                        module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
                                        module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
                                    }
                                    module_spec.GetUUID() = frame_module_sp->GetUUID();
                                    success = module_spec.GetUUID().IsValid() || module_spec.GetFileSpec();
                                }
                                else
                                {
                                    result.AppendError ("frame has no module");
                                    error_set = true;
                                }
                            }
                            else
                            {
                                result.AppendError ("invalid current frame");
                                error_set = true;
                            }
                        }
                        else
                        {
                            result.AppendErrorWithFormat ("process is not stopped: %s", StateAsCString(process_state));
                            error_set = true;
                        }
                    }
                    else
                    {
                        result.AppendError ("a process must exist in order to use the --frame option");
                        error_set = true;
                    }
                }
                else
                {
                    if (uuid_option_set)
                    {
                        module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue();
                        success |= module_spec.GetUUID().IsValid();
                    }
                    else if (file_option_set)
                    {
                        module_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue();
                        ModuleSP module_sp (target->GetImages().FindFirstModule(module_spec));
                        if (module_sp)
                        {
                            module_spec.GetFileSpec() = module_sp->GetFileSpec();
                            module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();
                            module_spec.GetUUID() = module_sp->GetUUID();
                            module_spec.GetArchitecture() = module_sp->GetArchitecture();
                        }
                        else
                        {
                            module_spec.GetArchitecture() = target->GetArchitecture();
                        }
                        success |= module_spec.GetFileSpec().Exists();
                    }
                }

                if (success)
                {
                    if (Symbols::DownloadObjectAndSymbolFile (module_spec))
                    {
                        if (module_spec.GetSymbolFileSpec())
                            success = AddModuleSymbols (target, module_spec, flush, result);
                    }
                }

                if (!success && !error_set)
                {
                    StreamString error_strm;
                    if (uuid_option_set)
                    {
                        error_strm.PutCString("unable to find debug symbols for UUID ");
                        module_spec.GetUUID().Dump (&error_strm);
                    }
                    else if (file_option_set)
                    {
                        error_strm.PutCString("unable to find debug symbols for the executable file ");
                        error_strm << module_spec.GetFileSpec();
                    }
                    else if (frame_option_set)
                    {
                        error_strm.PutCString("unable to find debug symbols for the current frame");                            
                    }
                    result.AppendError (error_strm.GetData());
                }
            }
            else
            {
                result.AppendError ("one or more symbol file paths must be specified, or options must be specified");
            }
        }
        else
        {
            if (uuid_option_set)
            {
                result.AppendError ("specify either one or more paths to symbol files or use the --uuid option without arguments");
            }
            else if (file_option_set)
            {
                result.AppendError ("specify either one or more paths to symbol files or use the --file option without arguments");
            }
            else if (frame_option_set)
            {
                result.AppendError ("specify either one or more paths to symbol files or use the --frame option without arguments");
            }
            else
            {
                PlatformSP platform_sp (target->GetPlatform());

                for (size_t i=0; i<argc; ++i)
                {
                    const char *symfile_path = args.GetArgumentAtIndex(i);
                    if (symfile_path)
                    {
                        module_spec.GetSymbolFileSpec().SetFile(symfile_path, true);
                        if (platform_sp)
                        {
                            FileSpec symfile_spec;
                            if (platform_sp->ResolveSymbolFile(*target, module_spec, symfile_spec).Success())
                                module_spec.GetSymbolFileSpec() = symfile_spec;
                        }

                        ArchSpec arch;
                        bool symfile_exists = module_spec.GetSymbolFileSpec().Exists();

                        if (symfile_exists)
                        {
                            if (!AddModuleSymbols (target, module_spec, flush, result))
                                break;
                        }
                        else
                        {
                            char resolved_symfile_path[PATH_MAX];
                            if (module_spec.GetSymbolFileSpec().GetPath (resolved_symfile_path, sizeof(resolved_symfile_path)))
                            {
                                if (strcmp (resolved_symfile_path, symfile_path) != 0)
                                {
                                    result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", symfile_path, resolved_symfile_path);
                                    break;
                                }
                            }
                            result.AppendErrorWithFormat ("invalid module path '%s'\n", symfile_path);
                            break;
                        }
                    }
                }
            }
        }

        if (flush)
        {
            Process *process = m_exe_ctx.GetProcessPtr();
            if (process)
                process->Flush();
        }
        return result.Succeeded();
    }

    OptionGroupOptions m_option_group;
    OptionGroupUUID m_uuid_option_group;
    OptionGroupFile m_file_option;
    OptionGroupBoolean m_current_frame_option;
};


#pragma mark CommandObjectTargetSymbols

//-------------------------------------------------------------------------
// CommandObjectTargetSymbols
//-------------------------------------------------------------------------

class CommandObjectTargetSymbols : public CommandObjectMultiword
{
public:
    //------------------------------------------------------------------
    // Constructors and Destructors
    //------------------------------------------------------------------
    CommandObjectTargetSymbols(CommandInterpreter &interpreter) :
        CommandObjectMultiword (interpreter,
                            "target symbols",
                            "A set of commands for adding and managing debug symbol files.",
                            "target symbols <sub-command> ...")
    {
        LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetSymbolsAdd (interpreter)));

    }
    virtual
    ~CommandObjectTargetSymbols()
    {
    }

private:
    //------------------------------------------------------------------
    // For CommandObjectTargetModules only
    //------------------------------------------------------------------
    DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetSymbols);
};


#pragma mark CommandObjectTargetStopHookAdd

//-------------------------------------------------------------------------
// CommandObjectTargetStopHookAdd
//-------------------------------------------------------------------------

class CommandObjectTargetStopHookAdd :
    public CommandObjectParsed,
    public IOHandlerDelegateMultiline
{
public:

    class CommandOptions : public Options
    {
    public:
        CommandOptions (CommandInterpreter &interpreter) :
            Options(interpreter),
            m_line_start(0),
            m_line_end (UINT_MAX),
            m_func_name_type_mask (eFunctionNameTypeAuto),
            m_sym_ctx_specified (false),
            m_thread_specified (false),
            m_use_one_liner (false),
            m_one_liner()
        {
        }

        ~CommandOptions () {}

        const OptionDefinition*
        GetDefinitions ()
        {
            return g_option_table;
        }

        virtual Error
        SetOptionValue (uint32_t option_idx, const char *option_arg)
        {
            Error error;
            const int short_option = m_getopt_table[option_idx].val;
            bool success;

            switch (short_option)
            {
                case 'c':
                    m_class_name = option_arg;
                    m_sym_ctx_specified = true;
                break;

                case 'e':
                    m_line_end = Args::StringToUInt32 (option_arg, UINT_MAX, 0, &success);
                    if (!success)
                    {
                        error.SetErrorStringWithFormat ("invalid end line number: \"%s\"", option_arg);
                        break;
                    }
                    m_sym_ctx_specified = true;
                break;

                case 'l':
                    m_line_start = Args::StringToUInt32 (option_arg, 0, 0, &success);
                    if (!success)
                    {
                        error.SetErrorStringWithFormat ("invalid start line number: \"%s\"", option_arg);
                        break;
                    }
                    m_sym_ctx_specified = true;
                break;

                case 'i':
                    m_no_inlines = true;
                break;

                case 'n':
                    m_function_name = option_arg;
                    m_func_name_type_mask |= eFunctionNameTypeAuto;
                    m_sym_ctx_specified = true;
                break;

                case 'f':
                    m_file_name = option_arg;
                    m_sym_ctx_specified = true;
                break;
                case 's':
                    m_module_name = option_arg;
                    m_sym_ctx_specified = true;
                break;
                case 't' :
                {
                    m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
                    if (m_thread_id == LLDB_INVALID_THREAD_ID)
                       error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
                    m_thread_specified = true;
                }
                break;
                case 'T':
                    m_thread_name = option_arg;
                    m_thread_specified = true;
                break;
                case 'q':
                    m_queue_name = option_arg;
                    m_thread_specified = true;
                    break;
                case 'x':
                {
                    m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
                    if (m_thread_id == UINT32_MAX)
                       error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
                    m_thread_specified = true;
                }
                break;
                case 'o':
                    m_use_one_liner = true;
                    m_one_liner = option_arg;
                break;
                default:
                    error.SetErrorStringWithFormat ("unrecognized option %c.", short_option);
                break;
            }
            return error;
        }

        void
        OptionParsingStarting ()
        {
            m_class_name.clear();
            m_function_name.clear();
            m_line_start = 0;
            m_line_end = UINT_MAX;
            m_file_name.clear();
            m_module_name.clear();
            m_func_name_type_mask = eFunctionNameTypeAuto;
            m_thread_id = LLDB_INVALID_THREAD_ID;
            m_thread_index = UINT32_MAX;
            m_thread_name.clear();
            m_queue_name.clear();

            m_no_inlines = false;
            m_sym_ctx_specified = false;
            m_thread_specified = false;

            m_use_one_liner = false;
            m_one_liner.clear();
        }


        static OptionDefinition g_option_table[];

        std::string m_class_name;
        std::string m_function_name;
        uint32_t    m_line_start;
        uint32_t    m_line_end;
        std::string m_file_name;
        std::string m_module_name;
        uint32_t m_func_name_type_mask;  // A pick from lldb::FunctionNameType.
        lldb::tid_t m_thread_id;
        uint32_t m_thread_index;
        std::string m_thread_name;
        std::string m_queue_name;
        bool        m_sym_ctx_specified;
        bool        m_no_inlines;
        bool        m_thread_specified;
        // Instance variables to hold the values for one_liner options.
        bool m_use_one_liner;
        std::string m_one_liner;
    };

    Options *
    GetOptions ()
    {
        return &m_options;
    }

    CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) :
        CommandObjectParsed (interpreter,
                             "target stop-hook add",
                             "Add a hook to be executed when the target stops.",
                             "target stop-hook add"),
        IOHandlerDelegateMultiline ("DONE", IOHandlerDelegate::Completion::LLDBCommand),
        m_options (interpreter)
    {
    }

    ~CommandObjectTargetStopHookAdd ()
    {
    }

protected:
    virtual void
    IOHandlerActivated (IOHandler &io_handler)
    {
        StreamFileSP output_sp(io_handler.GetOutputStreamFile());
        if (output_sp)
        {
            output_sp->PutCString("Enter your stop hook command(s).  Type 'DONE' to end.\n");
            output_sp->Flush();
        }
    }

    virtual void
    IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
    {
        if (m_stop_hook_sp)
        {
            if (line.empty())
            {
                StreamFileSP error_sp(io_handler.GetErrorStreamFile());
                if (error_sp)
                {
                    error_sp->Printf("error: stop hook #%" PRIu64 " aborted, no commands.\n", m_stop_hook_sp->GetID());
                    error_sp->Flush();
                }
                Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
                if (target)
                    target->RemoveStopHookByID(m_stop_hook_sp->GetID());
            }
            else
            {
                m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
                StreamFileSP output_sp(io_handler.GetOutputStreamFile());
                if (output_sp)
                {
                    output_sp->Printf("Stop hook #%" PRIu64 " added.\n", m_stop_hook_sp->GetID());
                    output_sp->Flush();
                }
            }
            m_stop_hook_sp.reset();
        }
        io_handler.SetIsDone(true);
    }

    bool
    DoExecute (Args& command, CommandReturnObject &result)
    {
        m_stop_hook_sp.reset();

        Target *target = GetSelectedOrDummyTarget();
        if (target)
        {
            Target::StopHookSP new_hook_sp = target->CreateStopHook();

            //  First step, make the specifier.
            std::unique_ptr<SymbolContextSpecifier> specifier_ap;
            if (m_options.m_sym_ctx_specified)
            {
                specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget()));

                if (!m_options.m_module_name.empty())
                {
                    specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified);
                }

                if (!m_options.m_class_name.empty())
                {
                    specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified);
                }

                if (!m_options.m_file_name.empty())
                {
                    specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified);
                }

                if (m_options.m_line_start != 0)
                {
                    specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified);
                }

                if (m_options.m_line_end != UINT_MAX)
                {
                    specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
                }

                if (!m_options.m_function_name.empty())
                {
                    specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified);
                }
            }

            if (specifier_ap.get())
                new_hook_sp->SetSpecifier (specifier_ap.release());

            // Next see if any of the thread options have been entered:

            if (m_options.m_thread_specified)
            {
                ThreadSpec *thread_spec = new ThreadSpec();

                if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
                {
                    thread_spec->SetTID (m_options.m_thread_id);
                }

                if (m_options.m_thread_index != UINT32_MAX)
                    thread_spec->SetIndex (m_options.m_thread_index);

                if (!m_options.m_thread_name.empty())
                    thread_spec->SetName (m_options.m_thread_name.c_str());

                if (!m_options.m_queue_name.empty())
                    thread_spec->SetQueueName (m_options.m_queue_name.c_str());

                new_hook_sp->SetThreadSpecifier (thread_spec);

            }
            if (m_options.m_use_one_liner)
            {
                // Use one-liner.
                new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str());
                result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n", new_hook_sp->GetID());
            }
            else
            {
                m_stop_hook_sp = new_hook_sp;
                m_interpreter.GetLLDBCommandsFromIOHandler ("> ",   // Prompt
                                                            *this,  // IOHandlerDelegate
                                                            true,   // Run IOHandler in async mode
                                                            NULL);  // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions

            }
            result.SetStatus (eReturnStatusSuccessFinishNoResult);
        }
        else
        {
            result.AppendError ("invalid target\n");
            result.SetStatus (eReturnStatusFailed);
        }

        return result.Succeeded();
    }
private:
    CommandOptions m_options;
    Target::StopHookSP m_stop_hook_sp;
};

OptionDefinition
CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] =
{
    { LLDB_OPT_SET_ALL, false, "one-liner", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOneLiner,
        "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
    { LLDB_OPT_SET_ALL, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
        "Set the module within which the stop-hook is to be run."},
    { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex,
        "The stop hook is run only for the thread whose index matches this argument."},
    { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID,
        "The stop hook is run only for the thread whose TID matches this argument."},
    { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName,
        "The stop hook is run only for the thread whose thread name matches this argument."},
    { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName,
        "The stop hook is run only for threads in the queue whose name is given by this argument."},
    { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
        "Specify the source file within which the stop-hook is to be run." },
    { LLDB_OPT_SET_1, false, "start-line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
        "Set the start of the line range for which the stop-hook is to be run."},
    { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
        "Set the end of the line range for which the stop-hook is to be run."},
    { LLDB_OPT_SET_2, false, "classname", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeClassName,
        "Specify the class within which the stop-hook is to be run." },
    { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
        "Set the function name within which the stop hook will be run." },
    { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
};

#pragma mark CommandObjectTargetStopHookDelete

//-------------------------------------------------------------------------
// CommandObjectTargetStopHookDelete
//-------------------------------------------------------------------------

class CommandObjectTargetStopHookDelete : public CommandObjectParsed
{
public:

    CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) :
        CommandObjectParsed (interpreter,
                             "target stop-hook delete",
                             "Delete a stop-hook.",
                             "target stop-hook delete [<idx>]")
    {
    }

    ~CommandObjectTargetStopHookDelete ()
    {
    }

protected:
    bool
    DoExecute (Args& command, CommandReturnObject &result)
    {
        Target *target = GetSelectedOrDummyTarget();
        if (target)
        {
            // FIXME: see if we can use the breakpoint id style parser?
            size_t num_args = command.GetArgumentCount();
            if (num_args == 0)
            {
                if (!m_interpreter.Confirm ("Delete all stop hooks?", true))
                {
                    result.SetStatus (eReturnStatusFailed);
                    return false;
                }
                else
                {
                    target->RemoveAllStopHooks();
                }
            }
            else
            {
                bool success;
                for (size_t i = 0; i < num_args; i++)
                {
                    lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
                    if (!success)
                    {
                        result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
                        result.SetStatus(eReturnStatusFailed);
                        return false;
                    }
                    success = target->RemoveStopHookByID (user_id);
                    if (!success)
                    {
                        result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
                        result.SetStatus(eReturnStatusFailed);
                        return false;
                    }
                }
            }
            result.SetStatus (eReturnStatusSuccessFinishNoResult);
        }
        else
        {
            result.AppendError ("invalid target\n");
            result.SetStatus (eReturnStatusFailed);
        }

        return result.Succeeded();
    }
};
#pragma mark CommandObjectTargetStopHookEnableDisable

//-------------------------------------------------------------------------
// CommandObjectTargetStopHookEnableDisable
//-------------------------------------------------------------------------

class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed
{
public:

    CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) :
        CommandObjectParsed (interpreter,
                             name,
                             help,
                             syntax),
        m_enable (enable)
    {
    }

    ~CommandObjectTargetStopHookEnableDisable ()
    {
    }

protected:
    bool
    DoExecute (Args& command, CommandReturnObject &result)
    {
        Target *target = GetSelectedOrDummyTarget();
        if (target)
        {
            // FIXME: see if we can use the breakpoint id style parser?
            size_t num_args = command.GetArgumentCount();
            bool success;

            if (num_args == 0)
            {
                target->SetAllStopHooksActiveState (m_enable);
            }
            else
            {
                for (size_t i = 0; i < num_args; i++)
                {
                    lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
                    if (!success)
                    {
                        result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
                        result.SetStatus(eReturnStatusFailed);
                        return false;
                    }
                    success = target->SetStopHookActiveStateByID (user_id, m_enable);
                    if (!success)
                    {
                        result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
                        result.SetStatus(eReturnStatusFailed);
                        return false;
                    }
                }
            }
            result.SetStatus (eReturnStatusSuccessFinishNoResult);
        }
        else
        {
            result.AppendError ("invalid target\n");
            result.SetStatus (eReturnStatusFailed);
        }
        return result.Succeeded();
    }
private:
    bool m_enable;
};

#pragma mark CommandObjectTargetStopHookList

//-------------------------------------------------------------------------
// CommandObjectTargetStopHookList
//-------------------------------------------------------------------------

class CommandObjectTargetStopHookList : public CommandObjectParsed
{
public:

    CommandObjectTargetStopHookList (CommandInterpreter &interpreter) :
        CommandObjectParsed (interpreter,
                             "target stop-hook list",
                             "List all stop-hooks.",
                             "target stop-hook list [<type>]")
    {
    }

    ~CommandObjectTargetStopHookList ()
    {
    }

protected:
    bool
    DoExecute (Args& command, CommandReturnObject &result)
    {
        Target *target = GetSelectedOrDummyTarget();
        if (!target)
        {
            result.AppendError ("invalid target\n");
            result.SetStatus (eReturnStatusFailed);
            return result.Succeeded();
        }

        size_t num_hooks = target->GetNumStopHooks ();
        if (num_hooks == 0)
        {
            result.GetOutputStream().PutCString ("No stop hooks.\n");
        }
        else
        {
            for (size_t i = 0; i < num_hooks; i++)
            {
                Target::StopHookSP this_hook = target->GetStopHookAtIndex (i);
                if (i > 0)
                    result.GetOutputStream().PutCString ("\n");
                this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull);
            }
        }
        result.SetStatus (eReturnStatusSuccessFinishResult);
        return result.Succeeded();
    }
};

#pragma mark CommandObjectMultiwordTargetStopHooks
//-------------------------------------------------------------------------
// CommandObjectMultiwordTargetStopHooks
//-------------------------------------------------------------------------

class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword
{
public:

    CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) :
        CommandObjectMultiword (interpreter, 
                                "target stop-hook",
                                "A set of commands for operating on debugger target stop-hooks.",
                                "target stop-hook <subcommand> [<subcommand-options>]")
    {
        LoadSubCommand ("add",      CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter)));
        LoadSubCommand ("delete",   CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter)));
        LoadSubCommand ("disable",  CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter, 
                                                                                                   false, 
                                                                                                   "target stop-hook disable [<id>]",
                                                                                                   "Disable a stop-hook.",
                                                                                                   "target stop-hook disable")));
        LoadSubCommand ("enable",   CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter, 
                                                                                                   true, 
                                                                                                   "target stop-hook enable [<id>]",
                                                                                                   "Enable a stop-hook.",
                                                                                                   "target stop-hook enable")));
        LoadSubCommand ("list",     CommandObjectSP (new CommandObjectTargetStopHookList (interpreter)));
    }

    ~CommandObjectMultiwordTargetStopHooks()
    {
    }
};



#pragma mark CommandObjectMultiwordTarget

//-------------------------------------------------------------------------
// CommandObjectMultiwordTarget
//-------------------------------------------------------------------------

CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) :
    CommandObjectMultiword (interpreter,
                            "target",
                            "A set of commands for operating on debugger targets.",
                            "target <subcommand> [<subcommand-options>]")
{

    LoadSubCommand ("create",    CommandObjectSP (new CommandObjectTargetCreate (interpreter)));
    LoadSubCommand ("delete",    CommandObjectSP (new CommandObjectTargetDelete (interpreter)));
    LoadSubCommand ("list",      CommandObjectSP (new CommandObjectTargetList   (interpreter)));
    LoadSubCommand ("select",    CommandObjectSP (new CommandObjectTargetSelect (interpreter)));
    LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter)));
    LoadSubCommand ("modules",   CommandObjectSP (new CommandObjectTargetModules (interpreter)));
    LoadSubCommand ("symbols",   CommandObjectSP (new CommandObjectTargetSymbols (interpreter)));
    LoadSubCommand ("variable",  CommandObjectSP (new CommandObjectTargetVariable (interpreter)));
}

CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget ()
{
}


