//===-- SBTarget.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 "lldb/API/SBTarget.h"

#include "lldb/lldb-public.h"

#include "lldb/API/SBBreakpoint.h"
#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBExpressionOptions.h"
#include "lldb/API/SBFileSpec.h"
#include "lldb/API/SBListener.h"
#include "lldb/API/SBModule.h"
#include "lldb/API/SBModuleSpec.h"
#include "lldb/API/SBSourceManager.h"
#include "lldb/API/SBProcess.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBSymbolContextList.h"
#include "lldb/Breakpoint/BreakpointID.h"
#include "lldb/Breakpoint/BreakpointIDList.h"
#include "lldb/Breakpoint/BreakpointList.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/AddressResolver.h"
#include "lldb/Core/AddressResolverName.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/SearchFilter.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/STLUtils.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Core/ValueObjectList.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/Host.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/DeclVendor.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/TargetList.h"

#include "lldb/Interpreter/CommandReturnObject.h"
#include "../source/Commands/CommandObjectBreakpoint.h"
#include "llvm/Support/Regex.h"


using namespace lldb;
using namespace lldb_private;

#define DEFAULT_DISASM_BYTE_SIZE 32

namespace {

Error
AttachToProcess (ProcessAttachInfo &attach_info, Target &target)
{
    Mutex::Locker api_locker (target.GetAPIMutex ());

    auto process_sp = target.GetProcessSP ();
    if (process_sp)
    {
        const auto state = process_sp->GetState ();
        if (process_sp->IsAlive () && state == eStateConnected)
        {
            // If we are already connected, then we have already specified the
            // listener, so if a valid listener is supplied, we need to error out
            // to let the client know.
            if (attach_info.GetListener ())
                return Error ("process is connected and already has a listener, pass empty listener");
        }
    }

    return target.Attach (attach_info, nullptr);
}

}  // namespace

//----------------------------------------------------------------------
// SBTarget constructor
//----------------------------------------------------------------------
SBTarget::SBTarget () :
    m_opaque_sp ()
{
}

SBTarget::SBTarget (const SBTarget& rhs) :
    m_opaque_sp (rhs.m_opaque_sp)
{
}

SBTarget::SBTarget(const TargetSP& target_sp) :
    m_opaque_sp (target_sp)
{
}

const SBTarget&
SBTarget::operator = (const SBTarget& rhs)
{
    if (this != &rhs)
        m_opaque_sp = rhs.m_opaque_sp;
    return *this;
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
SBTarget::~SBTarget()
{
}

bool
SBTarget::EventIsTargetEvent (const SBEvent &event)
{
    return Target::TargetEventData::GetEventDataFromEvent(event.get()) != NULL;
}

SBTarget
SBTarget::GetTargetFromEvent (const SBEvent &event)
{
    return Target::TargetEventData::GetTargetFromEvent (event.get());
}

uint32_t
SBTarget::GetNumModulesFromEvent (const SBEvent &event)
{
    const ModuleList module_list = Target::TargetEventData::GetModuleListFromEvent (event.get());
    return module_list.GetSize();
}

SBModule
SBTarget::GetModuleAtIndexFromEvent (const uint32_t idx, const SBEvent &event)
{
    const ModuleList module_list = Target::TargetEventData::GetModuleListFromEvent (event.get());
    return SBModule(module_list.GetModuleAtIndex(idx));
}

const char *
SBTarget::GetBroadcasterClassName ()
{
    return Target::GetStaticBroadcasterClass().AsCString();
}

bool
SBTarget::IsValid () const
{
    return m_opaque_sp.get() != NULL && m_opaque_sp->IsValid();
}

SBProcess
SBTarget::GetProcess ()
{
    SBProcess sb_process;
    ProcessSP process_sp;
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        process_sp = target_sp->GetProcessSP();
        sb_process.SetSP (process_sp);
    }

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBTarget(%p)::GetProcess () => SBProcess(%p)",
                     static_cast<void*>(target_sp.get()),
                     static_cast<void*>(process_sp.get()));

    return sb_process;
}

SBPlatform
SBTarget::GetPlatform ()
{
    TargetSP target_sp(GetSP());
    if (!target_sp)
        return SBPlatform();

    SBPlatform platform;
    platform.m_opaque_sp = target_sp->GetPlatform();

    return platform;
}

SBDebugger
SBTarget::GetDebugger () const
{
    SBDebugger debugger;
    TargetSP target_sp(GetSP());
    if (target_sp)
        debugger.reset (target_sp->GetDebugger().shared_from_this());
    return debugger;
}

SBProcess
SBTarget::LoadCore (const char *core_file)
{
    SBProcess sb_process;
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        FileSpec filespec(core_file, true);
        ProcessSP process_sp (target_sp->CreateProcess(target_sp->GetDebugger().GetListener(),
                                                       NULL,
                                                       &filespec));
        if (process_sp)
        {
            process_sp->LoadCore();
            sb_process.SetSP (process_sp);
        }
    }
    return sb_process;
}

SBProcess
SBTarget::LaunchSimple
(
    char const **argv,
    char const **envp,
    const char *working_directory
)
{
    char *stdin_path = NULL;
    char *stdout_path = NULL;
    char *stderr_path = NULL;
    uint32_t launch_flags = 0;
    bool stop_at_entry = false;
    SBError error;
    SBListener listener = GetDebugger().GetListener();
    return Launch (listener,
                   argv,
                   envp,
                   stdin_path,
                   stdout_path,
                   stderr_path,
                   working_directory,
                   launch_flags,
                   stop_at_entry,
                   error);
}

SBError
SBTarget::Install()
{
    SBError sb_error;
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        sb_error.ref() = target_sp->Install(NULL);
    }
    return sb_error;
}

SBProcess
SBTarget::Launch 
(
    SBListener &listener, 
    char const **argv,
    char const **envp,
    const char *stdin_path,
    const char *stdout_path,
    const char *stderr_path,
    const char *working_directory,
    uint32_t launch_flags,   // See LaunchFlags
    bool stop_at_entry,
    lldb::SBError& error
)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBProcess sb_process;
    ProcessSP process_sp;
    TargetSP target_sp(GetSP());

    if (log)
        log->Printf ("SBTarget(%p)::Launch (argv=%p, envp=%p, stdin=%s, stdout=%s, stderr=%s, working-dir=%s, launch_flags=0x%x, stop_at_entry=%i, &error (%p))...",
                     static_cast<void*>(target_sp.get()),
                     static_cast<void*>(argv), static_cast<void*>(envp),
                     stdin_path ? stdin_path : "NULL",
                     stdout_path ? stdout_path : "NULL",
                     stderr_path ? stderr_path : "NULL",
                     working_directory ? working_directory : "NULL",
                     launch_flags, stop_at_entry,
                     static_cast<void*>(error.get()));

    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());

        if (stop_at_entry)
            launch_flags |= eLaunchFlagStopAtEntry;

        if (getenv("LLDB_LAUNCH_FLAG_DISABLE_ASLR"))
            launch_flags |= eLaunchFlagDisableASLR;

        StateType state = eStateInvalid;
        process_sp = target_sp->GetProcessSP();
        if (process_sp)
        {
            state = process_sp->GetState();

            if (process_sp->IsAlive() && state != eStateConnected)
            {
                if (state == eStateAttaching)
                    error.SetErrorString ("process attach is in progress");
                else
                    error.SetErrorString ("a process is already being debugged");
                return sb_process;
            }
        }

        if (state == eStateConnected)
        {
            // If we are already connected, then we have already specified the
            // listener, so if a valid listener is supplied, we need to error out
            // to let the client know.
            if (listener.IsValid())
            {
                error.SetErrorString ("process is connected and already has a listener, pass empty listener");
                return sb_process;
            }
        }

        if (getenv("LLDB_LAUNCH_FLAG_DISABLE_STDIO"))
            launch_flags |= eLaunchFlagDisableSTDIO;

        ProcessLaunchInfo launch_info (stdin_path, stdout_path, stderr_path, working_directory, launch_flags);

        Module *exe_module = target_sp->GetExecutableModulePointer();
        if (exe_module)
            launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true);
        if (argv)
            launch_info.GetArguments().AppendArguments (argv);
        if (envp)
            launch_info.GetEnvironmentEntries ().SetArguments (envp);

        if (listener.IsValid())
            launch_info.SetListener(listener.GetSP());

        error.SetError (target_sp->Launch(launch_info, NULL));

        sb_process.SetSP(target_sp->GetProcessSP());
    }
    else
    {
        error.SetErrorString ("SBTarget is invalid");
    }

    log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
    if (log)
        log->Printf ("SBTarget(%p)::Launch (...) => SBProcess(%p)",
                     static_cast<void*>(target_sp.get()),
                     static_cast<void*>(sb_process.GetSP().get()));

    return sb_process;
}

SBProcess
SBTarget::Launch (SBLaunchInfo &sb_launch_info, SBError& error)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBProcess sb_process;
    TargetSP target_sp(GetSP());

    if (log)
        log->Printf ("SBTarget(%p)::Launch (launch_info, error)...",
                     static_cast<void*>(target_sp.get()));

    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        StateType state = eStateInvalid;
        {
            ProcessSP process_sp = target_sp->GetProcessSP();
            if (process_sp)
            {
                state = process_sp->GetState();
                
                if (process_sp->IsAlive() && state != eStateConnected)
                {
                    if (state == eStateAttaching)
                        error.SetErrorString ("process attach is in progress");
                    else
                        error.SetErrorString ("a process is already being debugged");
                    return sb_process;
                }
            }
        }

        lldb_private::ProcessLaunchInfo &launch_info = sb_launch_info.ref();

        if (!launch_info.GetExecutableFile())
        {
            Module *exe_module = target_sp->GetExecutableModulePointer();
            if (exe_module)
                launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true);
        }

        const ArchSpec &arch_spec = target_sp->GetArchitecture();
        if (arch_spec.IsValid())
            launch_info.GetArchitecture () = arch_spec;

        error.SetError (target_sp->Launch (launch_info, NULL));
        sb_process.SetSP(target_sp->GetProcessSP());
    }
    else
    {
        error.SetErrorString ("SBTarget is invalid");
    }

    log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
    if (log)
        log->Printf ("SBTarget(%p)::Launch (...) => SBProcess(%p)",
                     static_cast<void*>(target_sp.get()),
                     static_cast<void*>(sb_process.GetSP().get()));

    return sb_process;
}

lldb::SBProcess
SBTarget::Attach (SBAttachInfo &sb_attach_info, SBError& error)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBProcess sb_process;
    TargetSP target_sp(GetSP());

    if (log)
        log->Printf ("SBTarget(%p)::Attach (sb_attach_info, error)...",
                     static_cast<void*>(target_sp.get()));

    if (target_sp)
    {
        ProcessAttachInfo &attach_info = sb_attach_info.ref();
        if (attach_info.ProcessIDIsValid() && !attach_info.UserIDIsValid())
        {
            PlatformSP platform_sp = target_sp->GetPlatform();
            // See if we can pre-verify if a process exists or not
            if (platform_sp && platform_sp->IsConnected())
            {
                lldb::pid_t attach_pid = attach_info.GetProcessID();
                ProcessInstanceInfo instance_info;
                if (platform_sp->GetProcessInfo(attach_pid, instance_info))
                {
                    attach_info.SetUserID(instance_info.GetEffectiveUserID());
                }
                else
                {
                    error.ref().SetErrorStringWithFormat("no process found with process ID %" PRIu64, attach_pid);
                    if (log)
                    {
                        log->Printf ("SBTarget(%p)::Attach (...) => error %s",
                                     static_cast<void*>(target_sp.get()), error.GetCString());
                    }
                    return sb_process;
                }
            }
        }
        error.SetError(AttachToProcess(attach_info, *target_sp));
        if (error.Success())
            sb_process.SetSP(target_sp->GetProcessSP());
    }
    else
    {
        error.SetErrorString ("SBTarget is invalid");
    }

    if (log)
        log->Printf ("SBTarget(%p)::Attach (...) => SBProcess(%p)",
                     static_cast<void*>(target_sp.get()),
                     static_cast<void*>(sb_process.GetSP().get()));

    return sb_process;
}


#if defined(__APPLE__)

lldb::SBProcess
SBTarget::AttachToProcessWithID (SBListener &listener,
                                ::pid_t pid,
                                 lldb::SBError& error)
{
    return AttachToProcessWithID (listener, (lldb::pid_t)pid, error);
}

#endif // #if defined(__APPLE__)

lldb::SBProcess
SBTarget::AttachToProcessWithID 
(
    SBListener &listener, 
    lldb::pid_t pid,// The process ID to attach to
    SBError& error  // An error explaining what went wrong if attach fails
)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBProcess sb_process;
    TargetSP target_sp(GetSP());

    if (log)
        log->Printf ("SBTarget(%p)::%s (listener, pid=%" PRId64 ", error)...",
                     static_cast<void*>(target_sp.get()),
                     __FUNCTION__,
                     pid);

    if (target_sp)
    {
        ProcessAttachInfo attach_info;
        attach_info.SetProcessID (pid);
        if (listener.IsValid())
            attach_info.SetListener(listener.GetSP());

        ProcessInstanceInfo instance_info;
        if (target_sp->GetPlatform ()->GetProcessInfo (pid, instance_info))
            attach_info.SetUserID (instance_info.GetEffectiveUserID ());

        error.SetError (AttachToProcess (attach_info, *target_sp));
        if (error.Success ())
            sb_process.SetSP (target_sp->GetProcessSP ());
    }
    else
        error.SetErrorString ("SBTarget is invalid");

    if (log)
        log->Printf ("SBTarget(%p)::%s (...) => SBProcess(%p)",
                     static_cast<void*>(target_sp.get ()),
                     __FUNCTION__,
                     static_cast<void*>(sb_process.GetSP().get ()));
    return sb_process;
}

lldb::SBProcess
SBTarget::AttachToProcessWithName 
(
    SBListener &listener, 
    const char *name,   // basename of process to attach to
    bool wait_for,      // if true wait for a new instance of "name" to be launched
    SBError& error      // An error explaining what went wrong if attach fails
)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBProcess sb_process;
    TargetSP target_sp(GetSP());

    if (log)
        log->Printf ("SBTarget(%p)::%s (listener, name=%s, wait_for=%s, error)...",
                     static_cast<void*>(target_sp.get()),
                     __FUNCTION__,
                     name,
                     wait_for ? "true" : "false");

    if (name && target_sp)
    {
        ProcessAttachInfo attach_info;
        attach_info.GetExecutableFile().SetFile(name, false);
        attach_info.SetWaitForLaunch(wait_for);
        if (listener.IsValid())
            attach_info.SetListener(listener.GetSP());

        error.SetError (AttachToProcess (attach_info, *target_sp));
        if (error.Success ())
            sb_process.SetSP (target_sp->GetProcessSP ());
    }
    else
        error.SetErrorString ("SBTarget is invalid");

    if (log)
        log->Printf ("SBTarget(%p)::%s (...) => SBProcess(%p)",
                     static_cast<void*>(target_sp.get()),
                     __FUNCTION__,
                     static_cast<void*>(sb_process.GetSP().get()));
    return sb_process;
}

lldb::SBProcess
SBTarget::ConnectRemote
(
    SBListener &listener,
    const char *url,
    const char *plugin_name,
    SBError& error
)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBProcess sb_process;
    ProcessSP process_sp;
    TargetSP target_sp(GetSP());

    if (log)
        log->Printf ("SBTarget(%p)::ConnectRemote (listener, url=%s, plugin_name=%s, error)...",
                     static_cast<void*>(target_sp.get()), url, plugin_name);

    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        if (listener.IsValid())
            process_sp = target_sp->CreateProcess (listener.ref(), plugin_name, NULL);
        else
            process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), plugin_name, NULL);

        if (process_sp)
        {
            sb_process.SetSP (process_sp);
            error.SetError (process_sp->ConnectRemote (NULL, url));
        }
        else
        {
            error.SetErrorString ("unable to create lldb_private::Process");
        }
    }
    else
    {
        error.SetErrorString ("SBTarget is invalid");
    }

    if (log)
        log->Printf ("SBTarget(%p)::ConnectRemote (...) => SBProcess(%p)",
                     static_cast<void*>(target_sp.get()),
                     static_cast<void*>(process_sp.get()));
    return sb_process;
}

SBFileSpec
SBTarget::GetExecutable ()
{

    SBFileSpec exe_file_spec;
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Module *exe_module = target_sp->GetExecutableModulePointer();
        if (exe_module)
            exe_file_spec.SetFileSpec (exe_module->GetFileSpec());
    }

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
    {
        log->Printf ("SBTarget(%p)::GetExecutable () => SBFileSpec(%p)",
                     static_cast<void*>(target_sp.get()),
                     static_cast<const void*>(exe_file_spec.get()));
    }

    return exe_file_spec;
}

bool
SBTarget::operator == (const SBTarget &rhs) const
{
    return m_opaque_sp.get() == rhs.m_opaque_sp.get();
}

bool
SBTarget::operator != (const SBTarget &rhs) const
{
    return m_opaque_sp.get() != rhs.m_opaque_sp.get();
}

lldb::TargetSP
SBTarget::GetSP () const
{
    return m_opaque_sp;
}

void
SBTarget::SetSP (const lldb::TargetSP& target_sp)
{
    m_opaque_sp = target_sp;
}

lldb::SBAddress
SBTarget::ResolveLoadAddress (lldb::addr_t vm_addr)
{
    lldb::SBAddress sb_addr;
    Address &addr = sb_addr.ref();
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        if (target_sp->ResolveLoadAddress (vm_addr, addr))
            return sb_addr;
    }

    // We have a load address that isn't in a section, just return an address
    // with the offset filled in (the address) and the section set to NULL
    addr.SetRawAddress(vm_addr);
    return sb_addr;
}

lldb::SBAddress
SBTarget::ResolveFileAddress (lldb::addr_t file_addr)
{
    lldb::SBAddress sb_addr;
    Address &addr = sb_addr.ref();
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        if (target_sp->ResolveFileAddress (file_addr, addr))
            return sb_addr;
    }

    addr.SetRawAddress(file_addr);
    return sb_addr;
}

lldb::SBAddress
SBTarget::ResolvePastLoadAddress (uint32_t stop_id, lldb::addr_t vm_addr)
{
    lldb::SBAddress sb_addr;
    Address &addr = sb_addr.ref();
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        if (target_sp->ResolveLoadAddress (vm_addr, addr))
            return sb_addr;
    }
    
    // We have a load address that isn't in a section, just return an address
    // with the offset filled in (the address) and the section set to NULL
    addr.SetRawAddress(vm_addr);
    return sb_addr;
}

SBSymbolContext
SBTarget::ResolveSymbolContextForAddress (const SBAddress& addr,
                                          uint32_t resolve_scope)
{
    SBSymbolContext sc;
    if (addr.IsValid())
    {
        TargetSP target_sp(GetSP());
        if (target_sp)
            target_sp->GetImages().ResolveSymbolContextForAddress (addr.ref(), resolve_scope, sc.ref());
    }
    return sc;
}

size_t
SBTarget::ReadMemory (const SBAddress addr,
                      void *buf,
                      size_t size,
                      lldb::SBError &error)
{
    SBError sb_error;
    size_t bytes_read = 0;
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        bytes_read = target_sp->ReadMemory(addr.ref(), false, buf, size, sb_error.ref());
    }
    else
    {
        sb_error.SetErrorString("invalid target");
    }

    return bytes_read;
}

SBBreakpoint
SBTarget::BreakpointCreateByLocation (const char *file,
                                      uint32_t line)
{
    return SBBreakpoint(BreakpointCreateByLocation (SBFileSpec (file, false), line));
}

SBBreakpoint
SBTarget::BreakpointCreateByLocation (const SBFileSpec &sb_file_spec,
                                      uint32_t line)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBBreakpoint sb_bp;
    TargetSP target_sp(GetSP());
    if (target_sp && line != 0)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());

        const LazyBool check_inlines = eLazyBoolCalculate;
        const LazyBool skip_prologue = eLazyBoolCalculate;
        const bool internal = false;
        const bool hardware = false;
        *sb_bp = target_sp->CreateBreakpoint (NULL, *sb_file_spec, line, check_inlines, skip_prologue, internal, hardware);
    }

    if (log)
    {
        SBStream sstr;
        sb_bp.GetDescription (sstr);
        char path[PATH_MAX];
        sb_file_spec->GetPath (path, sizeof(path));
        log->Printf ("SBTarget(%p)::BreakpointCreateByLocation ( %s:%u ) => SBBreakpoint(%p): %s",
                     static_cast<void*>(target_sp.get()), path, line,
                     static_cast<void*>(sb_bp.get()), sstr.GetData());
    }

    return sb_bp;
}

SBBreakpoint
SBTarget::BreakpointCreateByName (const char *symbol_name,
                                  const char *module_name)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBBreakpoint sb_bp;
    TargetSP target_sp(GetSP());
    if (target_sp.get())
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());

        const bool internal = false;
        const bool hardware = false;
        const LazyBool skip_prologue = eLazyBoolCalculate;
        if (module_name && module_name[0])
        {
            FileSpecList module_spec_list;
            module_spec_list.Append (FileSpec (module_name, false));
            *sb_bp = target_sp->CreateBreakpoint (&module_spec_list, NULL, symbol_name, eFunctionNameTypeAuto, skip_prologue, internal, hardware);
        }
        else
        {
            *sb_bp = target_sp->CreateBreakpoint (NULL, NULL, symbol_name, eFunctionNameTypeAuto, skip_prologue, internal, hardware);
        }
    }

    if (log)
        log->Printf ("SBTarget(%p)::BreakpointCreateByName (symbol=\"%s\", module=\"%s\") => SBBreakpoint(%p)",
                     static_cast<void*>(target_sp.get()), symbol_name,
                     module_name, static_cast<void*>(sb_bp.get()));

    return sb_bp;
}

lldb::SBBreakpoint
SBTarget::BreakpointCreateByName (const char *symbol_name, 
                                  const SBFileSpecList &module_list,
                                  const SBFileSpecList &comp_unit_list)
{
    uint32_t name_type_mask = eFunctionNameTypeAuto;
    return BreakpointCreateByName (symbol_name, name_type_mask, module_list, comp_unit_list);
}

lldb::SBBreakpoint
SBTarget::BreakpointCreateByName (const char *symbol_name,
                                  uint32_t name_type_mask,
                                  const SBFileSpecList &module_list,
                                  const SBFileSpecList &comp_unit_list)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBBreakpoint sb_bp;
    TargetSP target_sp(GetSP());
    if (target_sp && symbol_name && symbol_name[0])
    {
        const bool internal = false;
        const bool hardware = false;
        const LazyBool skip_prologue = eLazyBoolCalculate;
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        *sb_bp = target_sp->CreateBreakpoint (module_list.get(), 
                                              comp_unit_list.get(),
                                              symbol_name,
                                              name_type_mask,
                                              skip_prologue,
                                              internal,
                                              hardware);
    }

    if (log)
        log->Printf ("SBTarget(%p)::BreakpointCreateByName (symbol=\"%s\", name_type: %d) => SBBreakpoint(%p)",
                     static_cast<void*>(target_sp.get()), symbol_name,
                     name_type_mask, static_cast<void*>(sb_bp.get()));

    return sb_bp;
}

lldb::SBBreakpoint
SBTarget::BreakpointCreateByNames (const char *symbol_names[],
                                   uint32_t num_names,
                                   uint32_t name_type_mask,
                                   const SBFileSpecList &module_list,
                                   const SBFileSpecList &comp_unit_list)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBBreakpoint sb_bp;
    TargetSP target_sp(GetSP());
    if (target_sp && num_names > 0)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        const bool internal = false;
        const bool hardware = false;
        const LazyBool skip_prologue = eLazyBoolCalculate;
        *sb_bp = target_sp->CreateBreakpoint (module_list.get(), 
                                                comp_unit_list.get(), 
                                                symbol_names,
                                                num_names,
                                                name_type_mask, 
                                                skip_prologue,
                                                internal,
                                                hardware);
    }

    if (log)
    {
        log->Printf ("SBTarget(%p)::BreakpointCreateByName (symbols={",
                     static_cast<void*>(target_sp.get()));
        for (uint32_t i = 0 ; i < num_names; i++)
        {
            char sep;
            if (i < num_names - 1)
                sep = ',';
            else
                sep = '}';
            if (symbol_names[i] != NULL)
                log->Printf ("\"%s\"%c ", symbol_names[i], sep);
            else
                log->Printf ("\"<NULL>\"%c ", sep);
        }
        log->Printf ("name_type: %d) => SBBreakpoint(%p)", name_type_mask,
                     static_cast<void*>(sb_bp.get()));
    }

    return sb_bp;
}

SBBreakpoint
SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex,
                                   const char *module_name)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBBreakpoint sb_bp;
    TargetSP target_sp(GetSP());
    if (target_sp && symbol_name_regex && symbol_name_regex[0])
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        RegularExpression regexp(symbol_name_regex);
        const bool internal = false;
        const bool hardware = false;
        const LazyBool skip_prologue = eLazyBoolCalculate;

        if (module_name && module_name[0])
        {
            FileSpecList module_spec_list;
            module_spec_list.Append (FileSpec (module_name, false));

            *sb_bp = target_sp->CreateFuncRegexBreakpoint (&module_spec_list, NULL, regexp, skip_prologue, internal, hardware);
        }
        else
        {
            *sb_bp = target_sp->CreateFuncRegexBreakpoint (NULL, NULL, regexp, skip_prologue, internal, hardware);
        }
    }

    if (log)
        log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (symbol_regex=\"%s\", module_name=\"%s\") => SBBreakpoint(%p)",
                     static_cast<void*>(target_sp.get()), symbol_name_regex,
                     module_name, static_cast<void*>(sb_bp.get()));

    return sb_bp;
}

lldb::SBBreakpoint
SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, 
                                   const SBFileSpecList &module_list,
                                   const SBFileSpecList &comp_unit_list)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBBreakpoint sb_bp;
    TargetSP target_sp(GetSP());
    if (target_sp && symbol_name_regex && symbol_name_regex[0])
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        RegularExpression regexp(symbol_name_regex);
        const bool internal = false;
        const bool hardware = false;
        const LazyBool skip_prologue = eLazyBoolCalculate;

        *sb_bp = target_sp->CreateFuncRegexBreakpoint (module_list.get(), comp_unit_list.get(), regexp, skip_prologue, internal, hardware);
    }

    if (log)
        log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (symbol_regex=\"%s\") => SBBreakpoint(%p)",
                     static_cast<void*>(target_sp.get()), symbol_name_regex,
                     static_cast<void*>(sb_bp.get()));

    return sb_bp;
}

SBBreakpoint
SBTarget::BreakpointCreateByAddress (addr_t address)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBBreakpoint sb_bp;
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        const bool hardware = false;
        *sb_bp = target_sp->CreateBreakpoint (address, false, hardware);
    }

    if (log)
        log->Printf ("SBTarget(%p)::BreakpointCreateByAddress (address=%" PRIu64 ") => SBBreakpoint(%p)",
                     static_cast<void*>(target_sp.get()),
                     static_cast<uint64_t>(address),
                     static_cast<void*>(sb_bp.get()));

    return sb_bp;
}

lldb::SBBreakpoint
SBTarget::BreakpointCreateBySourceRegex (const char *source_regex,
                                         const lldb::SBFileSpec &source_file,
                                         const char *module_name)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBBreakpoint sb_bp;
    TargetSP target_sp(GetSP());
    if (target_sp && source_regex && source_regex[0])
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        RegularExpression regexp(source_regex);
        FileSpecList source_file_spec_list;
        const bool hardware = false;
        source_file_spec_list.Append (source_file.ref());

        if (module_name && module_name[0])
        {
            FileSpecList module_spec_list;
            module_spec_list.Append (FileSpec (module_name, false));

            *sb_bp = target_sp->CreateSourceRegexBreakpoint (&module_spec_list, &source_file_spec_list, regexp, false, hardware);
        }
        else
        {
            *sb_bp = target_sp->CreateSourceRegexBreakpoint (NULL, &source_file_spec_list, regexp, false, hardware);
        }
    }

    if (log)
    {
        char path[PATH_MAX];
        source_file->GetPath (path, sizeof(path));
        log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (source_regex=\"%s\", file=\"%s\", module_name=\"%s\") => SBBreakpoint(%p)",
                     static_cast<void*>(target_sp.get()), source_regex, path,
                     module_name, static_cast<void*>(sb_bp.get()));
    }

    return sb_bp;
}

lldb::SBBreakpoint
SBTarget::BreakpointCreateBySourceRegex (const char *source_regex,
                                                 const SBFileSpecList &module_list,
                                                 const lldb::SBFileSpecList &source_file_list)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBBreakpoint sb_bp;
    TargetSP target_sp(GetSP());
    if (target_sp && source_regex && source_regex[0])
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        const bool hardware = false;
        RegularExpression regexp(source_regex);
        *sb_bp = target_sp->CreateSourceRegexBreakpoint (module_list.get(), source_file_list.get(), regexp, false, hardware);
    }

    if (log)
        log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (source_regex=\"%s\") => SBBreakpoint(%p)",
                     static_cast<void*>(target_sp.get()), source_regex,
                     static_cast<void*>(sb_bp.get()));

    return sb_bp;
}

lldb::SBBreakpoint
SBTarget::BreakpointCreateForException  (lldb::LanguageType language,
                                         bool catch_bp,
                                         bool throw_bp)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBBreakpoint sb_bp;
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        const bool hardware = false;
        *sb_bp = target_sp->CreateExceptionBreakpoint (language, catch_bp, throw_bp, hardware);
    }

    if (log)
        log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (Language: %s, catch: %s throw: %s) => SBBreakpoint(%p)",
                     static_cast<void*>(target_sp.get()),
                     LanguageRuntime::GetNameForLanguageType(language),
                     catch_bp ? "on" : "off", throw_bp ? "on" : "off",
                     static_cast<void*>(sb_bp.get()));

    return sb_bp;
}

uint32_t
SBTarget::GetNumBreakpoints () const
{
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        // The breakpoint list is thread safe, no need to lock
        return target_sp->GetBreakpointList().GetSize();
    }
    return 0;
}

SBBreakpoint
SBTarget::GetBreakpointAtIndex (uint32_t idx) const
{
    SBBreakpoint sb_breakpoint;
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        // The breakpoint list is thread safe, no need to lock
        *sb_breakpoint = target_sp->GetBreakpointList().GetBreakpointAtIndex(idx);
    }
    return sb_breakpoint;
}

bool
SBTarget::BreakpointDelete (break_id_t bp_id)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    bool result = false;
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        result = target_sp->RemoveBreakpointByID (bp_id);
    }

    if (log)
        log->Printf ("SBTarget(%p)::BreakpointDelete (bp_id=%d) => %i",
                     static_cast<void*>(target_sp.get()),
                     static_cast<uint32_t>(bp_id), result);

    return result;
}

SBBreakpoint
SBTarget::FindBreakpointByID (break_id_t bp_id)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBBreakpoint sb_breakpoint;
    TargetSP target_sp(GetSP());
    if (target_sp && bp_id != LLDB_INVALID_BREAK_ID)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        *sb_breakpoint = target_sp->GetBreakpointByID (bp_id);
    }

    if (log)
        log->Printf ("SBTarget(%p)::FindBreakpointByID (bp_id=%d) => SBBreakpoint(%p)",
                     static_cast<void*>(target_sp.get()),
                     static_cast<uint32_t>(bp_id),
                     static_cast<void*>(sb_breakpoint.get()));

    return sb_breakpoint;
}

bool
SBTarget::EnableAllBreakpoints ()
{
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        target_sp->EnableAllBreakpoints ();
        return true;
    }
    return false;
}

bool
SBTarget::DisableAllBreakpoints ()
{
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        target_sp->DisableAllBreakpoints ();
        return true;
    }
    return false;
}

bool
SBTarget::DeleteAllBreakpoints ()
{
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        target_sp->RemoveAllBreakpoints ();
        return true;
    }
    return false;
}

uint32_t
SBTarget::GetNumWatchpoints () const
{
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        // The watchpoint list is thread safe, no need to lock
        return target_sp->GetWatchpointList().GetSize();
    }
    return 0;
}

SBWatchpoint
SBTarget::GetWatchpointAtIndex (uint32_t idx) const
{
    SBWatchpoint sb_watchpoint;
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        // The watchpoint list is thread safe, no need to lock
        sb_watchpoint.SetSP (target_sp->GetWatchpointList().GetByIndex(idx));
    }
    return sb_watchpoint;
}

bool
SBTarget::DeleteWatchpoint (watch_id_t wp_id)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    bool result = false;
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        Mutex::Locker locker;
        target_sp->GetWatchpointList().GetListMutex(locker);
        result = target_sp->RemoveWatchpointByID (wp_id);
    }

    if (log)
        log->Printf ("SBTarget(%p)::WatchpointDelete (wp_id=%d) => %i",
                     static_cast<void*>(target_sp.get()),
                     static_cast<uint32_t>(wp_id), result);

    return result;
}

SBWatchpoint
SBTarget::FindWatchpointByID (lldb::watch_id_t wp_id)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBWatchpoint sb_watchpoint;
    lldb::WatchpointSP watchpoint_sp;
    TargetSP target_sp(GetSP());
    if (target_sp && wp_id != LLDB_INVALID_WATCH_ID)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        Mutex::Locker locker;
        target_sp->GetWatchpointList().GetListMutex(locker);
        watchpoint_sp = target_sp->GetWatchpointList().FindByID(wp_id);
        sb_watchpoint.SetSP (watchpoint_sp);
    }

    if (log)
        log->Printf ("SBTarget(%p)::FindWatchpointByID (bp_id=%d) => SBWatchpoint(%p)",
                     static_cast<void*>(target_sp.get()),
                     static_cast<uint32_t>(wp_id),
                     static_cast<void*>(watchpoint_sp.get()));

    return sb_watchpoint;
}

lldb::SBWatchpoint
SBTarget::WatchAddress (lldb::addr_t addr, size_t size, bool read, bool write, SBError &error)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBWatchpoint sb_watchpoint;
    lldb::WatchpointSP watchpoint_sp;
    TargetSP target_sp(GetSP());
    if (target_sp && (read || write) && addr != LLDB_INVALID_ADDRESS && size > 0)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        uint32_t watch_type = 0;
        if (read)
            watch_type |= LLDB_WATCH_TYPE_READ;
        if (write)
            watch_type |= LLDB_WATCH_TYPE_WRITE;
        if (watch_type == 0)
        {
            error.SetErrorString("Can't create a watchpoint that is neither read nor write.");
            return sb_watchpoint;
        }

        // Target::CreateWatchpoint() is thread safe.
        Error cw_error;
        // This API doesn't take in a type, so we can't figure out what it is.
        ClangASTType *type = NULL;
        watchpoint_sp = target_sp->CreateWatchpoint(addr, size, type, watch_type, cw_error);
        error.SetError(cw_error);
        sb_watchpoint.SetSP (watchpoint_sp);
    }

    if (log)
        log->Printf ("SBTarget(%p)::WatchAddress (addr=0x%" PRIx64 ", 0x%u) => SBWatchpoint(%p)",
                     static_cast<void*>(target_sp.get()), addr,
                     static_cast<uint32_t>(size),
                     static_cast<void*>(watchpoint_sp.get()));

    return sb_watchpoint;
}

bool
SBTarget::EnableAllWatchpoints ()
{
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        Mutex::Locker locker;
        target_sp->GetWatchpointList().GetListMutex(locker);
        target_sp->EnableAllWatchpoints ();
        return true;
    }
    return false;
}

bool
SBTarget::DisableAllWatchpoints ()
{
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        Mutex::Locker locker;
        target_sp->GetWatchpointList().GetListMutex(locker);
        target_sp->DisableAllWatchpoints ();
        return true;
    }
    return false;
}

SBValue
SBTarget::CreateValueFromAddress (const char *name, SBAddress addr, SBType type)
{
    SBValue sb_value;
    lldb::ValueObjectSP new_value_sp;
    if (IsValid() && name && *name && addr.IsValid() && type.IsValid())
    {
        lldb::addr_t load_addr(addr.GetLoadAddress(*this));
        ExecutionContext exe_ctx (ExecutionContextRef(ExecutionContext(m_opaque_sp.get(),false)));
        ClangASTType ast_type(type.GetSP()->GetClangASTType(true));
        new_value_sp = ValueObject::CreateValueObjectFromAddress(name, load_addr, exe_ctx, ast_type);
    }
    sb_value.SetSP(new_value_sp);
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
    {
        if (new_value_sp)
            log->Printf ("SBTarget(%p)::CreateValueFromAddress => \"%s\"",
                         static_cast<void*>(m_opaque_sp.get()),
                         new_value_sp->GetName().AsCString());
        else
            log->Printf ("SBTarget(%p)::CreateValueFromAddress => NULL",
                         static_cast<void*>(m_opaque_sp.get()));
    }
    return sb_value;
}

lldb::SBValue
SBTarget::CreateValueFromData (const char *name, lldb::SBData data, lldb::SBType type)
{
    SBValue sb_value;
    lldb::ValueObjectSP new_value_sp;
    if (IsValid() && name && *name && data.IsValid() && type.IsValid())
    {
        DataExtractorSP extractor(*data);
        ExecutionContext exe_ctx (ExecutionContextRef(ExecutionContext(m_opaque_sp.get(),false)));
        ClangASTType ast_type(type.GetSP()->GetClangASTType(true));
        new_value_sp = ValueObject::CreateValueObjectFromData(name, *extractor, exe_ctx, ast_type);
    }
    sb_value.SetSP(new_value_sp);
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
    {
        if (new_value_sp)
            log->Printf ("SBTarget(%p)::CreateValueFromData => \"%s\"",
                         static_cast<void*>(m_opaque_sp.get()),
                         new_value_sp->GetName().AsCString());
        else
            log->Printf ("SBTarget(%p)::CreateValueFromData => NULL",
                         static_cast<void*>(m_opaque_sp.get()));
    }
    return sb_value;
}

lldb::SBValue
SBTarget::CreateValueFromExpression (const char *name, const char* expr)
{
    SBValue sb_value;
    lldb::ValueObjectSP new_value_sp;
    if (IsValid() && name && *name && expr && *expr)
    {
        ExecutionContext exe_ctx (ExecutionContextRef(ExecutionContext(m_opaque_sp.get(),false)));
        new_value_sp = ValueObject::CreateValueObjectFromExpression(name, expr, exe_ctx);
    }
    sb_value.SetSP(new_value_sp);
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
    {
        if (new_value_sp)
            log->Printf ("SBTarget(%p)::CreateValueFromExpression => \"%s\"",
                         static_cast<void*>(m_opaque_sp.get()),
                         new_value_sp->GetName().AsCString());
        else
            log->Printf ("SBTarget(%p)::CreateValueFromExpression => NULL",
                         static_cast<void*>(m_opaque_sp.get()));
    }
    return sb_value;
}

bool
SBTarget::DeleteAllWatchpoints ()
{
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        Mutex::Locker locker;
        target_sp->GetWatchpointList().GetListMutex(locker);
        target_sp->RemoveAllWatchpoints ();
        return true;
    }
    return false;
}


lldb::SBModule
SBTarget::AddModule (const char *path,
                     const char *triple,
                     const char *uuid_cstr)
{
    return AddModule (path, triple, uuid_cstr, NULL);
}

lldb::SBModule
SBTarget::AddModule (const char *path,
                     const char *triple,
                     const char *uuid_cstr,
                     const char *symfile)
{
    lldb::SBModule sb_module;
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        ModuleSpec module_spec;
        if (path)
            module_spec.GetFileSpec().SetFile(path, false);
        
        if (uuid_cstr)
            module_spec.GetUUID().SetFromCString(uuid_cstr);
        
        if (triple)
            module_spec.GetArchitecture().SetTriple (triple, target_sp->GetPlatform ().get());
        else
            module_spec.GetArchitecture() = target_sp->GetArchitecture();
        
        if (symfile)
            module_spec.GetSymbolFileSpec ().SetFile(symfile, false);

        sb_module.SetSP(target_sp->GetSharedModule (module_spec));
    }
    return sb_module;
}

lldb::SBModule
SBTarget::AddModule (const SBModuleSpec &module_spec)
{
    lldb::SBModule sb_module;
    TargetSP target_sp(GetSP());
    if (target_sp)
        sb_module.SetSP(target_sp->GetSharedModule (*module_spec.m_opaque_ap));
    return sb_module;
}

bool
SBTarget::AddModule (lldb::SBModule &module)
{
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        target_sp->GetImages().AppendIfNeeded (module.GetSP());
        return true;
    }
    return false;
}

uint32_t
SBTarget::GetNumModules () const
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    uint32_t num = 0;
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        // The module list is thread safe, no need to lock
        num = target_sp->GetImages().GetSize();
    }

    if (log)
        log->Printf ("SBTarget(%p)::GetNumModules () => %d",
                     static_cast<void*>(target_sp.get()), num);

    return num;
}

void
SBTarget::Clear ()
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    if (log)
        log->Printf ("SBTarget(%p)::Clear ()",
                     static_cast<void*>(m_opaque_sp.get()));

    m_opaque_sp.reset();
}


SBModule
SBTarget::FindModule (const SBFileSpec &sb_file_spec)
{
    SBModule sb_module;
    TargetSP target_sp(GetSP());
    if (target_sp && sb_file_spec.IsValid())
    {
        ModuleSpec module_spec(*sb_file_spec);
        // The module list is thread safe, no need to lock
        sb_module.SetSP (target_sp->GetImages().FindFirstModule (module_spec));
    }
    return sb_module;
}

lldb::ByteOrder
SBTarget::GetByteOrder ()
{
    TargetSP target_sp(GetSP());
    if (target_sp)
        return target_sp->GetArchitecture().GetByteOrder();
    return eByteOrderInvalid;
}

const char *
SBTarget::GetTriple ()
{
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        std::string triple (target_sp->GetArchitecture().GetTriple().str());
        // Unique the string so we don't run into ownership issues since
        // the const strings put the string into the string pool once and
        // the strings never comes out
        ConstString const_triple (triple.c_str());
        return const_triple.GetCString();
    }
    return NULL;
}

uint32_t
SBTarget::GetDataByteSize ()
{
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        return target_sp->GetArchitecture().GetDataByteSize() ;
    }
    return 0;
}

uint32_t
SBTarget::GetCodeByteSize ()
{
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        return target_sp->GetArchitecture().GetCodeByteSize() ;
    }
    return 0;
}

uint32_t
SBTarget::GetAddressByteSize()
{
    TargetSP target_sp(GetSP());
    if (target_sp)
        return target_sp->GetArchitecture().GetAddressByteSize();
    return sizeof(void*);
}


SBModule
SBTarget::GetModuleAtIndex (uint32_t idx)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBModule sb_module;
    ModuleSP module_sp;
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        // The module list is thread safe, no need to lock
        module_sp = target_sp->GetImages().GetModuleAtIndex(idx);
        sb_module.SetSP (module_sp);
    }

    if (log)
        log->Printf ("SBTarget(%p)::GetModuleAtIndex (idx=%d) => SBModule(%p)",
                     static_cast<void*>(target_sp.get()), idx,
                     static_cast<void*>(module_sp.get()));

    return sb_module;
}

bool
SBTarget::RemoveModule (lldb::SBModule module)
{
    TargetSP target_sp(GetSP());
    if (target_sp)
        return target_sp->GetImages().Remove(module.GetSP());
    return false;
}


SBBroadcaster
SBTarget::GetBroadcaster () const
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    TargetSP target_sp(GetSP());
    SBBroadcaster broadcaster(target_sp.get(), false);

    if (log)
        log->Printf ("SBTarget(%p)::GetBroadcaster () => SBBroadcaster(%p)",
                     static_cast<void*>(target_sp.get()),
                     static_cast<void*>(broadcaster.get()));

    return broadcaster;
}

bool
SBTarget::GetDescription (SBStream &description, lldb::DescriptionLevel description_level)
{
    Stream &strm = description.ref();

    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        target_sp->Dump (&strm, description_level);
    }
    else
        strm.PutCString ("No value");
    
    return true;
}

lldb::SBSymbolContextList
SBTarget::FindFunctions (const char *name, uint32_t name_type_mask)
{
    lldb::SBSymbolContextList sb_sc_list;
    if (name && name[0])
    {
        TargetSP target_sp(GetSP());
        if (target_sp)
        {
            const bool symbols_ok = true;
            const bool inlines_ok = true;
            const bool append = true;
            target_sp->GetImages().FindFunctions (ConstString(name), 
                                                  name_type_mask, 
                                                  symbols_ok,
                                                  inlines_ok,
                                                  append, 
                                                  *sb_sc_list);
        }
    }
    return sb_sc_list;
}

lldb::SBSymbolContextList 
SBTarget::FindGlobalFunctions(const char *name, uint32_t max_matches, MatchType matchtype)
{
    lldb::SBSymbolContextList sb_sc_list;
    if (name && name[0])
    {
        TargetSP target_sp(GetSP());
        if (target_sp)
        {
            std::string regexstr;
            switch (matchtype)
            {
            case eMatchTypeRegex:
                target_sp->GetImages().FindFunctions(RegularExpression(name), true, true, true, *sb_sc_list);
                break;
            case eMatchTypeStartsWith:
                regexstr = llvm::Regex::escape(name) + ".*";
                target_sp->GetImages().FindFunctions(RegularExpression(regexstr.c_str()), true, true, true, *sb_sc_list);
                break;
            default:
                target_sp->GetImages().FindFunctions(ConstString(name), eFunctionNameTypeAny, true, true, true, *sb_sc_list);
                break;
            }
        }
    }
    return sb_sc_list;
}

lldb::SBType
SBTarget::FindFirstType (const char* typename_cstr)
{
    TargetSP target_sp(GetSP());
    if (typename_cstr && typename_cstr[0] && target_sp)
    {
        ConstString const_typename(typename_cstr);
        SymbolContext sc;
        const bool exact_match = false;

        const ModuleList &module_list = target_sp->GetImages();
        size_t count = module_list.GetSize();
        for (size_t idx = 0; idx < count; idx++)
        {
            ModuleSP module_sp (module_list.GetModuleAtIndex(idx));
            if (module_sp)
            {
                TypeSP type_sp (module_sp->FindFirstType(sc, const_typename, exact_match));
                if (type_sp)
                    return SBType(type_sp);
            }
        }
        
        // Didn't find the type in the symbols; try the Objective-C runtime
        // if one is installed
        
        ProcessSP process_sp(target_sp->GetProcessSP());
        
        if (process_sp)
        {
            ObjCLanguageRuntime *objc_language_runtime = process_sp->GetObjCLanguageRuntime();
            
            if (objc_language_runtime)
            {
                DeclVendor *objc_decl_vendor = objc_language_runtime->GetDeclVendor();
                
                if (objc_decl_vendor)
                {
                    std::vector <clang::NamedDecl *> decls;
                    
                    if (objc_decl_vendor->FindDecls(const_typename, true, 1, decls) > 0)
                    {
                        if (ClangASTType type = ClangASTContext::GetTypeForDecl(decls[0]))
                        {
                            return SBType(type);
                        }
                    }
                }
            }
        }

        // No matches, search for basic typename matches
        ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext();
        if (clang_ast)
            return SBType (ClangASTContext::GetBasicType (clang_ast->getASTContext(), const_typename));
    }
    return SBType();
}

SBType
SBTarget::GetBasicType(lldb::BasicType type)
{
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext();
        if (clang_ast)
            return SBType (ClangASTContext::GetBasicType (clang_ast->getASTContext(), type));
    }
    return SBType();
}


lldb::SBTypeList
SBTarget::FindTypes (const char* typename_cstr)
{
    SBTypeList sb_type_list;
    TargetSP target_sp(GetSP());
    if (typename_cstr && typename_cstr[0] && target_sp)
    {
        ModuleList& images = target_sp->GetImages();
        ConstString const_typename(typename_cstr);
        bool exact_match = false;
        SymbolContext sc;
        TypeList type_list;
        
        uint32_t num_matches = images.FindTypes (sc,
                                                 const_typename,
                                                 exact_match,
                                                 UINT32_MAX,
                                                 type_list);
        
        if (num_matches > 0)
        {
            for (size_t idx = 0; idx < num_matches; idx++)
            {
                TypeSP type_sp (type_list.GetTypeAtIndex(idx));
                if (type_sp)
                    sb_type_list.Append(SBType(type_sp));
            }
        }
        
        // Try the Objective-C runtime if one is installed
        
        ProcessSP process_sp(target_sp->GetProcessSP());
        
        if (process_sp)
        {
            ObjCLanguageRuntime *objc_language_runtime = process_sp->GetObjCLanguageRuntime();
            
            if (objc_language_runtime)
            {
                DeclVendor *objc_decl_vendor = objc_language_runtime->GetDeclVendor();
                
                if (objc_decl_vendor)
                {
                    std::vector <clang::NamedDecl *> decls;
                    
                    if (objc_decl_vendor->FindDecls(const_typename, true, 1, decls) > 0)
                    {
                        for (clang::NamedDecl *decl : decls)
                        {
                            if (ClangASTType type = ClangASTContext::GetTypeForDecl(decl))
                            {
                                sb_type_list.Append(SBType(type));
                            }
                        }
                    }
                }
            }
        }
        
        if (sb_type_list.GetSize() == 0)
        {
            // No matches, search for basic typename matches
            ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext();
            if (clang_ast)
                sb_type_list.Append (SBType (ClangASTContext::GetBasicType (clang_ast->getASTContext(), const_typename)));
        }
    }
    return sb_type_list;
}

SBValueList
SBTarget::FindGlobalVariables (const char *name, uint32_t max_matches)
{
    SBValueList sb_value_list;
    
    TargetSP target_sp(GetSP());
    if (name && target_sp)
    {
        VariableList variable_list;
        const bool append = true;
        const uint32_t match_count = target_sp->GetImages().FindGlobalVariables (ConstString (name), 
                                                                                 append, 
                                                                                 max_matches,
                                                                                 variable_list);
        
        if (match_count > 0)
        {
            ExecutionContextScope *exe_scope = target_sp->GetProcessSP().get();
            if (exe_scope == NULL)
                exe_scope = target_sp.get();
            for (uint32_t i=0; i<match_count; ++i)
            {
                lldb::ValueObjectSP valobj_sp (ValueObjectVariable::Create (exe_scope, variable_list.GetVariableAtIndex(i)));
                if (valobj_sp)
                    sb_value_list.Append(SBValue(valobj_sp));
            }
        }
    }

    return sb_value_list;
}

SBValueList
SBTarget::FindGlobalVariables(const char *name, uint32_t max_matches, MatchType matchtype)
{
    SBValueList sb_value_list;

    TargetSP target_sp(GetSP());
    if (name && target_sp)
    {
        VariableList variable_list;
        const bool append = true;

        std::string regexstr;
        uint32_t match_count;
        switch (matchtype)
        {
        case eMatchTypeNormal:
            match_count = target_sp->GetImages().FindGlobalVariables(ConstString(name),
                append,
                max_matches,
                variable_list);
            break;
        case eMatchTypeRegex:
            match_count = target_sp->GetImages().FindGlobalVariables(RegularExpression(name),
                append,
                max_matches,
                variable_list);
            break;
        case eMatchTypeStartsWith:
            regexstr = llvm::Regex::escape(name) + ".*";
            match_count = target_sp->GetImages().FindGlobalVariables(RegularExpression(regexstr.c_str()),
                append,
                max_matches,
                variable_list);
            break;
        }


        if (match_count > 0)
        {
            ExecutionContextScope *exe_scope = target_sp->GetProcessSP().get();
            if (exe_scope == NULL)
                exe_scope = target_sp.get();
            for (uint32_t i = 0; i<match_count; ++i)
            {
                lldb::ValueObjectSP valobj_sp(ValueObjectVariable::Create(exe_scope, variable_list.GetVariableAtIndex(i)));
                if (valobj_sp)
                    sb_value_list.Append(SBValue(valobj_sp));
            }
        }
    }

    return sb_value_list;
}


lldb::SBValue
SBTarget::FindFirstGlobalVariable (const char* name)
{
    SBValueList sb_value_list(FindGlobalVariables(name, 1));
    if (sb_value_list.IsValid() && sb_value_list.GetSize() > 0)
        return sb_value_list.GetValueAtIndex(0);
    return SBValue();
}

SBSourceManager
SBTarget::GetSourceManager()
{
    SBSourceManager source_manager (*this);
    return source_manager;
}

lldb::SBInstructionList
SBTarget::ReadInstructions (lldb::SBAddress base_addr, uint32_t count)
{
    return ReadInstructions (base_addr, count, NULL);
}

lldb::SBInstructionList
SBTarget::ReadInstructions (lldb::SBAddress base_addr, uint32_t count, const char *flavor_string)
{
    SBInstructionList sb_instructions;
    
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Address *addr_ptr = base_addr.get();
        
        if (addr_ptr)
        {
            DataBufferHeap data (target_sp->GetArchitecture().GetMaximumOpcodeByteSize() * count, 0);
            bool prefer_file_cache = false;
            lldb_private::Error error;
            lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
            const size_t bytes_read = target_sp->ReadMemory(*addr_ptr,
                                                            prefer_file_cache,
                                                            data.GetBytes(),
                                                            data.GetByteSize(),
                                                            error,
                                                            &load_addr);
            const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
            sb_instructions.SetDisassembler (Disassembler::DisassembleBytes (target_sp->GetArchitecture(),
                                                                             NULL,
                                                                             flavor_string,
                                                                             *addr_ptr,
                                                                             data.GetBytes(),
                                                                             bytes_read,
                                                                             count,
                                                                             data_from_file));
        }
    }
    
    return sb_instructions;
    
}

lldb::SBInstructionList
SBTarget::GetInstructions (lldb::SBAddress base_addr, const void *buf, size_t size)
{
    return GetInstructionsWithFlavor (base_addr, NULL, buf, size);
}

lldb::SBInstructionList
SBTarget::GetInstructionsWithFlavor (lldb::SBAddress base_addr, const char *flavor_string, const void *buf, size_t size)
{
    SBInstructionList sb_instructions;
    
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Address addr;
        
        if (base_addr.get())
            addr = *base_addr.get();
        
        const bool data_from_file = true;

        sb_instructions.SetDisassembler (Disassembler::DisassembleBytes (target_sp->GetArchitecture(),
                                                                         NULL,
                                                                         flavor_string,
                                                                         addr,
                                                                         buf,
                                                                         size,
                                                                         UINT32_MAX,
                                                                         data_from_file));
    }

    return sb_instructions;
}

lldb::SBInstructionList
SBTarget::GetInstructions (lldb::addr_t base_addr, const void *buf, size_t size)
{
    return GetInstructionsWithFlavor (ResolveLoadAddress(base_addr), NULL, buf, size);
}

lldb::SBInstructionList
SBTarget::GetInstructionsWithFlavor (lldb::addr_t base_addr, const char *flavor_string, const void *buf, size_t size)
{
    return GetInstructionsWithFlavor (ResolveLoadAddress(base_addr), flavor_string, buf, size);
}

SBError
SBTarget::SetSectionLoadAddress (lldb::SBSection section,
                                 lldb::addr_t section_base_addr)
{
    SBError sb_error;
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        if (!section.IsValid())
        {
            sb_error.SetErrorStringWithFormat ("invalid section");
        }
        else
        {
            SectionSP section_sp (section.GetSP());
            if (section_sp)
            {
                if (section_sp->IsThreadSpecific())
                {
                    sb_error.SetErrorString ("thread specific sections are not yet supported");
                }
                else
                {
                    ProcessSP process_sp (target_sp->GetProcessSP());
                    if (target_sp->SetSectionLoadAddress (section_sp, section_base_addr))
                    {
                        // Flush info in the process (stack frames, etc)
                        if (process_sp)
                            process_sp->Flush();
                    }
                }
            }
        }
    }
    else
    {
        sb_error.SetErrorString ("invalid target");
    }
    return sb_error;
}

SBError
SBTarget::ClearSectionLoadAddress (lldb::SBSection section)
{
    SBError sb_error;
    
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        if (!section.IsValid())
        {
            sb_error.SetErrorStringWithFormat ("invalid section");
        }
        else
        {
            ProcessSP process_sp (target_sp->GetProcessSP());
            if (target_sp->SetSectionUnloaded (section.GetSP()))
            {
                // Flush info in the process (stack frames, etc)
                if (process_sp)
                    process_sp->Flush();                
            }
        }
    }
    else
    {
        sb_error.SetErrorStringWithFormat ("invalid target");
    }
    return sb_error;
}

SBError
SBTarget::SetModuleLoadAddress (lldb::SBModule module, int64_t slide_offset)
{
    SBError sb_error;
    
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        ModuleSP module_sp (module.GetSP());
        if (module_sp)
        {
            bool changed = false;
            if (module_sp->SetLoadAddress (*target_sp, slide_offset, true, changed))
            {
                // The load was successful, make sure that at least some sections
                // changed before we notify that our module was loaded.
                if (changed)
                {
                    ModuleList module_list;
                    module_list.Append(module_sp);
                    target_sp->ModulesDidLoad (module_list);
                    // Flush info in the process (stack frames, etc)
                    ProcessSP process_sp (target_sp->GetProcessSP());
                    if (process_sp)
                        process_sp->Flush();
                }
            }
        }
        else
        {
            sb_error.SetErrorStringWithFormat ("invalid module");
        }

    }
    else
    {
        sb_error.SetErrorStringWithFormat ("invalid target");
    }
    return sb_error;
}

SBError
SBTarget::ClearModuleLoadAddress (lldb::SBModule module)
{
    SBError sb_error;
    
    char path[PATH_MAX];
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        ModuleSP module_sp (module.GetSP());
        if (module_sp)
        {
            ObjectFile *objfile = module_sp->GetObjectFile();
            if (objfile)
            {
                SectionList *section_list = objfile->GetSectionList();
                if (section_list)
                {
                    ProcessSP process_sp (target_sp->GetProcessSP());

                    bool changed = false;
                    const size_t num_sections = section_list->GetSize();
                    for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
                    {
                        SectionSP section_sp (section_list->GetSectionAtIndex(sect_idx));
                        if (section_sp)
                            changed |= target_sp->SetSectionUnloaded (section_sp);
                    }
                    if (changed)
                    {
                        // Flush info in the process (stack frames, etc)
                        ProcessSP process_sp (target_sp->GetProcessSP());
                        if (process_sp)
                            process_sp->Flush();                        
                    }
                }
                else
                {
                    module_sp->GetFileSpec().GetPath (path, sizeof(path));
                    sb_error.SetErrorStringWithFormat ("no sections in object file '%s'", path);
                }
            }
            else
            {
                module_sp->GetFileSpec().GetPath (path, sizeof(path));
                sb_error.SetErrorStringWithFormat ("no object file for module '%s'", path);
            }
        }
        else
        {
            sb_error.SetErrorStringWithFormat ("invalid module");
        }
    }
    else
    {
        sb_error.SetErrorStringWithFormat ("invalid target");
    }
    return sb_error;
}


lldb::SBSymbolContextList
SBTarget::FindSymbols (const char *name, lldb::SymbolType symbol_type)
{
    SBSymbolContextList sb_sc_list;
    if (name && name[0])
    {
        TargetSP target_sp(GetSP());
        if (target_sp)
        {
            bool append = true;
            target_sp->GetImages().FindSymbolsWithNameAndType (ConstString(name),
                                                               symbol_type,
                                                               *sb_sc_list,
                                                               append);
        }
    }
    return sb_sc_list;
    
}


lldb::SBValue
SBTarget::EvaluateExpression (const char *expr, const SBExpressionOptions &options)
{
    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    Log * expr_log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
    SBValue expr_result;
    ExpressionResults exe_results = eExpressionSetupError;
    ValueObjectSP expr_value_sp;
    TargetSP target_sp(GetSP());
    StackFrame *frame = NULL;
    if (target_sp)
    {
        if (expr == NULL || expr[0] == '\0')
        {
            if (log)
                log->Printf ("SBTarget::EvaluateExpression called with an empty expression");
            return expr_result;
        }

        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        ExecutionContext exe_ctx (m_opaque_sp.get());

        if (log)
            log->Printf ("SBTarget()::EvaluateExpression (expr=\"%s\")...", expr);

        frame = exe_ctx.GetFramePtr();
        Target *target = exe_ctx.GetTargetPtr();

        if (target)
        {
#ifdef LLDB_CONFIGURATION_DEBUG
            StreamString frame_description;
            if (frame)
                frame->DumpUsingSettingsFormat (&frame_description);
            Host::SetCrashDescriptionWithFormat ("SBTarget::EvaluateExpression (expr = \"%s\", fetch_dynamic_value = %u) %s",
                                                 expr, options.GetFetchDynamicValue(), frame_description.GetString().c_str());
#endif
            exe_results = target->EvaluateExpression (expr,
                                                      frame,
                                                      expr_value_sp,
                                                      options.ref());

            expr_result.SetSP(expr_value_sp, options.GetFetchDynamicValue());
#ifdef LLDB_CONFIGURATION_DEBUG
            Host::SetCrashDescription (NULL);
#endif
        }
        else
        {
            if (log)
                log->Printf ("SBTarget::EvaluateExpression () => error: could not reconstruct frame object for this SBTarget.");
        }
    }
#ifndef LLDB_DISABLE_PYTHON
    if (expr_log)
        expr_log->Printf("** [SBTarget::EvaluateExpression] Expression result is %s, summary %s **",
                         expr_result.GetValue(), expr_result.GetSummary());

    if (log)
        log->Printf ("SBTarget(%p)::EvaluateExpression (expr=\"%s\") => SBValue(%p) (execution result=%d)",
                     static_cast<void*>(frame), expr,
                     static_cast<void*>(expr_value_sp.get()), exe_results);
#endif

    return expr_result;
}


lldb::addr_t
SBTarget::GetStackRedZoneSize()
{
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        ABISP abi_sp;
        ProcessSP process_sp (target_sp->GetProcessSP());
        if (process_sp)
            abi_sp = process_sp->GetABI();
        else
            abi_sp = ABI::FindPlugin(target_sp->GetArchitecture());
        if (abi_sp)
            return abi_sp->GetRedZoneSize();
    }
    return 0;
}

lldb::SBLaunchInfo
SBTarget::GetLaunchInfo () const
{
    lldb::SBLaunchInfo launch_info(NULL);
    TargetSP target_sp(GetSP());
    if (target_sp)
        launch_info.ref() = m_opaque_sp->GetProcessLaunchInfo();
    return launch_info;
}

void
SBTarget::SetLaunchInfo (const lldb::SBLaunchInfo &launch_info)
{
    TargetSP target_sp(GetSP());
    if (target_sp)
        m_opaque_sp->SetProcessLaunchInfo(launch_info.ref());
}
