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

// C Includes
#include <errno.h>
#include <stdlib.h>

// C++ Includes
#include <mutex>

// Other libraries and framework includes
#include "lldb/Core/Debugger.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/State.h"
#include "lldb/Core/UUID.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/Symbols.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Host/common/TCPSocket.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionGroupString.h"
#include "lldb/Interpreter/OptionGroupUInt64.h"
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/StringExtractor.h"

#define USEC_PER_SEC 1000000

// Project includes
#include "ProcessKDP.h"
#include "ProcessKDPLog.h"
#include "ThreadKDP.h"
#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"

using namespace lldb;
using namespace lldb_private;

namespace {

    static PropertyDefinition
    g_properties[] =
    {
        { "packet-timeout" , OptionValue::eTypeUInt64 , true , 5, NULL, NULL, "Specify the default packet timeout in seconds." },
        {  NULL            , OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL  }
    };
    
    enum
    {
        ePropertyPacketTimeout
    };

    class PluginProperties : public Properties
    {
    public:
        
        static ConstString
        GetSettingName ()
        {
            return ProcessKDP::GetPluginNameStatic();
        }

        PluginProperties() :
            Properties ()
        {
            m_collection_sp.reset (new OptionValueProperties(GetSettingName()));
            m_collection_sp->Initialize(g_properties);
        }
        
        virtual
        ~PluginProperties()
        {
        }
        
        uint64_t
        GetPacketTimeout()
        {
            const uint32_t idx = ePropertyPacketTimeout;
            return m_collection_sp->GetPropertyAtIndexAsUInt64(NULL, idx, g_properties[idx].default_uint_value);
        }
    };

    typedef std::shared_ptr<PluginProperties> ProcessKDPPropertiesSP;

    static const ProcessKDPPropertiesSP &
    GetGlobalPluginProperties()
    {
        static ProcessKDPPropertiesSP g_settings_sp;
        if (!g_settings_sp)
            g_settings_sp.reset (new PluginProperties ());
        return g_settings_sp;
    }
    
} // anonymous namespace end

static const lldb::tid_t g_kernel_tid = 1;

ConstString
ProcessKDP::GetPluginNameStatic()
{
    static ConstString g_name("kdp-remote");
    return g_name;
}

const char *
ProcessKDP::GetPluginDescriptionStatic()
{
    return "KDP Remote protocol based debugging plug-in for darwin kernel debugging.";
}

void
ProcessKDP::Terminate()
{
    PluginManager::UnregisterPlugin (ProcessKDP::CreateInstance);
}


lldb::ProcessSP
ProcessKDP::CreateInstance (TargetSP target_sp,
                            Listener &listener,
                            const FileSpec *crash_file_path)
{
    lldb::ProcessSP process_sp;
    if (crash_file_path == NULL)
        process_sp.reset(new ProcessKDP (target_sp, listener));
    return process_sp;
}

bool
ProcessKDP::CanDebug(TargetSP target_sp, bool plugin_specified_by_name)
{
    if (plugin_specified_by_name)
        return true;

    // For now we are just making sure the file exists for a given module
    Module *exe_module = target_sp->GetExecutableModulePointer();
    if (exe_module)
    {
        const llvm::Triple &triple_ref = target_sp->GetArchitecture().GetTriple();
        switch (triple_ref.getOS())
        {
            case llvm::Triple::Darwin:  // Should use "macosx" for desktop and "ios" for iOS, but accept darwin just in case
            case llvm::Triple::MacOSX:  // For desktop targets
            case llvm::Triple::IOS:     // For arm targets
            case llvm::Triple::TvOS:
            case llvm::Triple::WatchOS:
                if (triple_ref.getVendor() == llvm::Triple::Apple)
                {
                    ObjectFile *exe_objfile = exe_module->GetObjectFile();
                    if (exe_objfile->GetType() == ObjectFile::eTypeExecutable && 
                        exe_objfile->GetStrata() == ObjectFile::eStrataKernel)
                        return true;
                }
                break;

            default:
                break;
        }
    }
    return false;
}

//----------------------------------------------------------------------
// ProcessKDP constructor
//----------------------------------------------------------------------
ProcessKDP::ProcessKDP(TargetSP target_sp, Listener &listener) :
    Process (target_sp, listener),
    m_comm("lldb.process.kdp-remote.communication"),
    m_async_broadcaster (NULL, "lldb.process.kdp-remote.async-broadcaster"),
    m_dyld_plugin_name (),
    m_kernel_load_addr (LLDB_INVALID_ADDRESS),
    m_command_sp(),
    m_kernel_thread_wp()
{
    m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit,   "async thread should exit");
    m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue,           "async thread continue");
    const uint64_t timeout_seconds = GetGlobalPluginProperties()->GetPacketTimeout();
    if (timeout_seconds > 0)
        m_comm.SetPacketTimeout(timeout_seconds);
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
ProcessKDP::~ProcessKDP()
{
    Clear();
    // We need to call finalize on the process before destroying ourselves
    // to make sure all of the broadcaster cleanup goes as planned. If we
    // destruct this class, then Process::~Process() might have problems
    // trying to fully destroy the broadcaster.
    Finalize();
}

//----------------------------------------------------------------------
// PluginInterface
//----------------------------------------------------------------------
lldb_private::ConstString
ProcessKDP::GetPluginName()
{
    return GetPluginNameStatic();
}

uint32_t
ProcessKDP::GetPluginVersion()
{
    return 1;
}

Error
ProcessKDP::WillLaunch (Module* module)
{
    Error error;
    error.SetErrorString ("launching not supported in kdp-remote plug-in");
    return error;
}

Error
ProcessKDP::WillAttachToProcessWithID (lldb::pid_t pid)
{
    Error error;
    error.SetErrorString ("attaching to a by process ID not supported in kdp-remote plug-in");
    return error;
}

Error
ProcessKDP::WillAttachToProcessWithName (const char *process_name, bool wait_for_launch)
{
    Error error;
    error.SetErrorString ("attaching to a by process name not supported in kdp-remote plug-in");
    return error;
}

bool
ProcessKDP::GetHostArchitecture(ArchSpec &arch)
{
    uint32_t cpu = m_comm.GetCPUType();
    if (cpu)
    {
        uint32_t sub = m_comm.GetCPUSubtype();
        arch.SetArchitecture(eArchTypeMachO, cpu, sub);
        // Leave architecture vendor as unspecified unknown
        arch.GetTriple().setVendor(llvm::Triple::UnknownVendor);
        arch.GetTriple().setVendorName(llvm::StringRef());
        return true;
    }
    arch.Clear();
    return false;
}

Error
ProcessKDP::DoConnectRemote (Stream *strm, const char *remote_url)
{
    Error error;

    // Don't let any JIT happen when doing KDP as we can't allocate
    // memory and we don't want to be mucking with threads that might
    // already be handling exceptions
    SetCanJIT(false);

    if (remote_url == NULL || remote_url[0] == '\0')
    {
        error.SetErrorStringWithFormat ("invalid connection URL '%s'", remote_url);
        return error;
    }

    std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
    if (conn_ap.get())
    {
        // Only try once for now.
        // TODO: check if we should be retrying?
        const uint32_t max_retry_count = 1;
        for (uint32_t retry_count = 0; retry_count < max_retry_count; ++retry_count)
        {
            if (conn_ap->Connect(remote_url, &error) == eConnectionStatusSuccess)
                break;
            usleep (100000);
        }
    }

    if (conn_ap->IsConnected())
    {
        const TCPSocket& socket = static_cast<const TCPSocket&>(*conn_ap->GetReadObject());
        const uint16_t reply_port = socket.GetLocalPortNumber();

        if (reply_port != 0)
        {
            m_comm.SetConnection(conn_ap.release());

            if (m_comm.SendRequestReattach(reply_port))
            {
                if (m_comm.SendRequestConnect(reply_port, reply_port, "Greetings from LLDB..."))
                {
                    m_comm.GetVersion();

                    Target &target = GetTarget();
                    ArchSpec kernel_arch;
                    // The host architecture
                    GetHostArchitecture(kernel_arch);
                    ArchSpec target_arch = target.GetArchitecture();
                    // Merge in any unspecified stuff into the target architecture in
                    // case the target arch isn't set at all or incompletely.
                    target_arch.MergeFrom(kernel_arch);
                    target.SetArchitecture(target_arch);

                    /* Get the kernel's UUID and load address via KDP_KERNELVERSION packet.  */
                    /* An EFI kdp session has neither UUID nor load address. */

                    UUID kernel_uuid = m_comm.GetUUID ();
                    addr_t kernel_load_addr = m_comm.GetLoadAddress ();

                    if (m_comm.RemoteIsEFI ())
                    {
                        // Select an invalid plugin name for the dynamic loader so one doesn't get used
                        // since EFI does its own manual loading via python scripting
                        static ConstString g_none_dynamic_loader("none");
                        m_dyld_plugin_name = g_none_dynamic_loader;

                        if (kernel_uuid.IsValid()) {
                            // If EFI passed in a UUID= try to lookup UUID
                            // The slide will not be provided. But the UUID
                            // lookup will be used to launch EFI debug scripts
                            // from the dSYM, that can load all of the symbols.
                            ModuleSpec module_spec;
                            module_spec.GetUUID() = kernel_uuid;
                            module_spec.GetArchitecture() = target.GetArchitecture();

                            // Lookup UUID locally, before attempting dsymForUUID like action
                            module_spec.GetSymbolFileSpec() = Symbols::LocateExecutableSymbolFile(module_spec);
                            if (module_spec.GetSymbolFileSpec())
                            {
                                ModuleSpec executable_module_spec = Symbols::LocateExecutableObjectFile (module_spec);
                                if (executable_module_spec.GetFileSpec().Exists())
                                {
                                    module_spec.GetFileSpec() = executable_module_spec.GetFileSpec();
                                }
                            }
                            if (!module_spec.GetSymbolFileSpec() || !module_spec.GetSymbolFileSpec())
                                 Symbols::DownloadObjectAndSymbolFile (module_spec, true);

                            if (module_spec.GetFileSpec().Exists())
                            {
                                ModuleSP module_sp(new Module (module_spec));
                                if (module_sp.get() && module_sp->GetObjectFile())
                                {
                                    // Get the current target executable
                                    ModuleSP exe_module_sp (target.GetExecutableModule ());

                                    // Make sure you don't already have the right module loaded and they will be uniqued
                                    if (exe_module_sp.get() != module_sp.get())
                                        target.SetExecutableModule (module_sp, false);
                                }
                            }
                        }
                    }
                    else if (m_comm.RemoteIsDarwinKernel ())
                    {
                        m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
                        if (kernel_load_addr != LLDB_INVALID_ADDRESS)
                        {
                            m_kernel_load_addr = kernel_load_addr;
                        }
                    }

                    // Set the thread ID
                    UpdateThreadListIfNeeded ();
                    SetID (1);
                    GetThreadList ();
                    SetPrivateState (eStateStopped);
                    StreamSP async_strm_sp(target.GetDebugger().GetAsyncOutputStream());
                    if (async_strm_sp)
                    {
                        const char *cstr;
                        if ((cstr = m_comm.GetKernelVersion ()) != NULL)
                        {
                            async_strm_sp->Printf ("Version: %s\n", cstr);
                            async_strm_sp->Flush();
                        }
//                      if ((cstr = m_comm.GetImagePath ()) != NULL)
//                      {
//                          async_strm_sp->Printf ("Image Path: %s\n", cstr);
//                          async_strm_sp->Flush();
//                      }            
                    }
                }
                else
                {
                    error.SetErrorString("KDP_REATTACH failed");
                }
            }
            else
            {
                error.SetErrorString("KDP_REATTACH failed");
            }
        }
        else
        {
            error.SetErrorString("invalid reply port from UDP connection");
        }
    }
    else
    {
        if (error.Success())
            error.SetErrorStringWithFormat ("failed to connect to '%s'", remote_url);
    }
    if (error.Fail())
        m_comm.Disconnect();

    return error;
}

//----------------------------------------------------------------------
// Process Control
//----------------------------------------------------------------------
Error
ProcessKDP::DoLaunch (Module *exe_module, 
                      ProcessLaunchInfo &launch_info)
{
    Error error;
    error.SetErrorString ("launching not supported in kdp-remote plug-in");
    return error;
}

Error
ProcessKDP::DoAttachToProcessWithID (lldb::pid_t attach_pid, const ProcessAttachInfo &attach_info)
{
    Error error;
    error.SetErrorString ("attach to process by ID is not suppported in kdp remote debugging");
    return error;
}

Error
ProcessKDP::DoAttachToProcessWithName (const char *process_name, const ProcessAttachInfo &attach_info)
{
    Error error;
    error.SetErrorString ("attach to process by name is not suppported in kdp remote debugging");
    return error;
}


void
ProcessKDP::DidAttach (ArchSpec &process_arch)
{
    Process::DidAttach(process_arch);
    
    Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS));
    if (log)
        log->Printf ("ProcessKDP::DidAttach()");
    if (GetID() != LLDB_INVALID_PROCESS_ID)
    {
        GetHostArchitecture(process_arch);
    }
}

addr_t
ProcessKDP::GetImageInfoAddress()
{
    return m_kernel_load_addr;
}

lldb_private::DynamicLoader *
ProcessKDP::GetDynamicLoader ()
{
    if (m_dyld_ap.get() == NULL)
        m_dyld_ap.reset (DynamicLoader::FindPlugin(this, m_dyld_plugin_name.IsEmpty() ? NULL : m_dyld_plugin_name.GetCString()));
    return m_dyld_ap.get();
}

Error
ProcessKDP::WillResume ()
{
    return Error();
}

Error
ProcessKDP::DoResume ()
{
    Error error;
    Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS));
    // Only start the async thread if we try to do any process control
    if (!m_async_thread.IsJoinable())
        StartAsyncThread();

    bool resume = false;
    
    // With KDP there is only one thread we can tell what to do
    ThreadSP kernel_thread_sp (m_thread_list.FindThreadByProtocolID(g_kernel_tid));
                            
    if (kernel_thread_sp)
    {
        const StateType thread_resume_state = kernel_thread_sp->GetTemporaryResumeState();
        
        if (log)
            log->Printf ("ProcessKDP::DoResume() thread_resume_state = %s", StateAsCString(thread_resume_state));
        switch (thread_resume_state)
        {
            case eStateSuspended:
                // Nothing to do here when a thread will stay suspended
                // we just leave the CPU mask bit set to zero for the thread
                if (log)
                    log->Printf ("ProcessKDP::DoResume() = suspended???");
                break;
                
            case eStateStepping:
                {
                    lldb::RegisterContextSP reg_ctx_sp (kernel_thread_sp->GetRegisterContext());

                    if (reg_ctx_sp)
                    {
                        if (log)
                            log->Printf ("ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep (true);");
                        reg_ctx_sp->HardwareSingleStep (true);
                        resume = true;
                    }
                    else
                    {
                        error.SetErrorStringWithFormat("KDP thread 0x%llx has no register context", kernel_thread_sp->GetID());
                    }
                }
                break;
    
            case eStateRunning:
                {
                    lldb::RegisterContextSP reg_ctx_sp (kernel_thread_sp->GetRegisterContext());
                    
                    if (reg_ctx_sp)
                    {
                        if (log)
                            log->Printf ("ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep (false);");
                        reg_ctx_sp->HardwareSingleStep (false);
                        resume = true;
                    }
                    else
                    {
                        error.SetErrorStringWithFormat("KDP thread 0x%llx has no register context", kernel_thread_sp->GetID());
                    }
                }
                break;

            default:
                // The only valid thread resume states are listed above
                assert (!"invalid thread resume state");
                break;
        }
    }

    if (resume)
    {
        if (log)
            log->Printf ("ProcessKDP::DoResume () sending resume");
        
        if (m_comm.SendRequestResume ())
        {
            m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue);
            SetPrivateState(eStateRunning);
        }
        else
            error.SetErrorString ("KDP resume failed");
    }
    else
    {
        error.SetErrorString ("kernel thread is suspended");        
    }
    
    return error;
}

lldb::ThreadSP
ProcessKDP::GetKernelThread()
{
    // KDP only tells us about one thread/core. Any other threads will usually
    // be the ones that are read from memory by the OS plug-ins.
    
    ThreadSP thread_sp (m_kernel_thread_wp.lock());
    if (!thread_sp)
    {
        thread_sp.reset(new ThreadKDP (*this, g_kernel_tid));
        m_kernel_thread_wp = thread_sp;
    }
    return thread_sp;
}




bool
ProcessKDP::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
{
    // locker will keep a mutex locked until it goes out of scope
    Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_THREAD));
    if (log && log->GetMask().Test(KDP_LOG_VERBOSE))
        log->Printf ("ProcessKDP::%s (pid = %" PRIu64 ")", __FUNCTION__, GetID());
    
    // Even though there is a CPU mask, it doesn't mean we can see each CPU
    // individually, there is really only one. Lets call this thread 1.
    ThreadSP thread_sp (old_thread_list.FindThreadByProtocolID(g_kernel_tid, false));
    if (!thread_sp)
        thread_sp = GetKernelThread ();
    new_thread_list.AddThread(thread_sp);

    return new_thread_list.GetSize(false) > 0;
}

void
ProcessKDP::RefreshStateAfterStop ()
{
    // Let all threads recover from stopping and do any clean up based
    // on the previous thread state (if any).
    m_thread_list.RefreshStateAfterStop();
}

Error
ProcessKDP::DoHalt (bool &caused_stop)
{
    Error error;
    
    if (m_comm.IsRunning())
    {
        if (m_destroy_in_process)
        {
            // If we are attemping to destroy, we need to not return an error to
            // Halt or DoDestroy won't get called.
            // We are also currently running, so send a process stopped event
            SetPrivateState (eStateStopped);
        }
        else
        {
            error.SetErrorString ("KDP cannot interrupt a running kernel");
        }
    }
    return error;
}

Error
ProcessKDP::DoDetach(bool keep_stopped)
{
    Error error;
    Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
    if (log)
        log->Printf ("ProcessKDP::DoDetach(keep_stopped = %i)", keep_stopped);
    
    if (m_comm.IsRunning())
    {
        // We are running and we can't interrupt a running kernel, so we need
        // to just close the connection to the kernel and hope for the best
    }
    else
    {
        // If we are going to keep the target stopped, then don't send the disconnect message.
        if (!keep_stopped && m_comm.IsConnected())
        {
            const bool success = m_comm.SendRequestDisconnect();
            if (log)
            {
                if (success)
                    log->PutCString ("ProcessKDP::DoDetach() detach packet sent successfully");
                else
                    log->PutCString ("ProcessKDP::DoDetach() connection channel shutdown failed");
            }
            m_comm.Disconnect ();
        }
    }
    StopAsyncThread ();    
    m_comm.Clear();
    
    SetPrivateState (eStateDetached);
    ResumePrivateStateThread();
    
    //KillDebugserverProcess ();
    return error;
}

Error
ProcessKDP::DoDestroy ()
{
    // For KDP there really is no difference between destroy and detach
    bool keep_stopped = false;
    return DoDetach(keep_stopped);
}

//------------------------------------------------------------------
// Process Queries
//------------------------------------------------------------------

bool
ProcessKDP::IsAlive ()
{
    return m_comm.IsConnected() && Process::IsAlive();
}

//------------------------------------------------------------------
// Process Memory
//------------------------------------------------------------------
size_t
ProcessKDP::DoReadMemory (addr_t addr, void *buf, size_t size, Error &error)
{
    uint8_t *data_buffer = (uint8_t *) buf;
    if (m_comm.IsConnected())
    {
        const size_t max_read_size = 512;
        size_t total_bytes_read = 0;

        // Read the requested amount of memory in 512 byte chunks
        while (total_bytes_read < size)
        {
            size_t bytes_to_read_this_request = size - total_bytes_read;
            if (bytes_to_read_this_request > max_read_size)
            {
                bytes_to_read_this_request = max_read_size;
            }
            size_t bytes_read = m_comm.SendRequestReadMemory (addr + total_bytes_read, 
                                                              data_buffer + total_bytes_read, 
                                                              bytes_to_read_this_request, error);
            total_bytes_read += bytes_read;
            if (error.Fail() || bytes_read == 0)
            {
                return total_bytes_read;
            }
        }

        return total_bytes_read;
    }
    error.SetErrorString ("not connected");
    return 0;
}

size_t
ProcessKDP::DoWriteMemory (addr_t addr, const void *buf, size_t size, Error &error)
{
    if (m_comm.IsConnected())
        return m_comm.SendRequestWriteMemory (addr, buf, size, error);
    error.SetErrorString ("not connected");
    return 0;
}

lldb::addr_t
ProcessKDP::DoAllocateMemory (size_t size, uint32_t permissions, Error &error)
{
    error.SetErrorString ("memory allocation not suppported in kdp remote debugging");
    return LLDB_INVALID_ADDRESS;
}

Error
ProcessKDP::DoDeallocateMemory (lldb::addr_t addr)
{
    Error error;
    error.SetErrorString ("memory deallocation not suppported in kdp remote debugging");
    return error;
}

Error
ProcessKDP::EnableBreakpointSite (BreakpointSite *bp_site)
{
    if (m_comm.LocalBreakpointsAreSupported ())
    {
        Error error;
        if (!bp_site->IsEnabled())
        {
            if (m_comm.SendRequestBreakpoint(true, bp_site->GetLoadAddress()))
            {
                bp_site->SetEnabled(true);
                bp_site->SetType (BreakpointSite::eExternal);
            }
            else
            {
                error.SetErrorString ("KDP set breakpoint failed");
            }
        }
        return error;
    }
    return EnableSoftwareBreakpoint (bp_site);
}

Error
ProcessKDP::DisableBreakpointSite (BreakpointSite *bp_site)
{
    if (m_comm.LocalBreakpointsAreSupported ())
    {
        Error error;
        if (bp_site->IsEnabled())
        {
            BreakpointSite::Type bp_type = bp_site->GetType();
            if (bp_type == BreakpointSite::eExternal)
            {
                if (m_destroy_in_process && m_comm.IsRunning())
                {
                    // We are trying to destroy our connection and we are running
                    bp_site->SetEnabled(false);
                }
                else
                {
                    if (m_comm.SendRequestBreakpoint(false, bp_site->GetLoadAddress()))
                        bp_site->SetEnabled(false);
                    else
                        error.SetErrorString ("KDP remove breakpoint failed");
                }
            }
            else
            {
                error = DisableSoftwareBreakpoint (bp_site);
            }
        }
        return error;
    }
    return DisableSoftwareBreakpoint (bp_site);
}

Error
ProcessKDP::EnableWatchpoint (Watchpoint *wp, bool notify)
{
    Error error;
    error.SetErrorString ("watchpoints are not suppported in kdp remote debugging");
    return error;
}

Error
ProcessKDP::DisableWatchpoint (Watchpoint *wp, bool notify)
{
    Error error;
    error.SetErrorString ("watchpoints are not suppported in kdp remote debugging");
    return error;
}

void
ProcessKDP::Clear()
{
    m_thread_list.Clear();
}

Error
ProcessKDP::DoSignal (int signo)
{
    Error error;
    error.SetErrorString ("sending signals is not suppported in kdp remote debugging");
    return error;
}

void
ProcessKDP::Initialize()
{
    static std::once_flag g_once_flag;

    std::call_once(g_once_flag, []()
    {
        PluginManager::RegisterPlugin (GetPluginNameStatic(),
                                       GetPluginDescriptionStatic(),
                                       CreateInstance,
                                       DebuggerInitialize);

        Log::Callbacks log_callbacks = {
            ProcessKDPLog::DisableLog,
            ProcessKDPLog::EnableLog,
            ProcessKDPLog::ListLogCategories
        };

        Log::RegisterLogChannel (ProcessKDP::GetPluginNameStatic(), log_callbacks);
    });
}

void
ProcessKDP::DebuggerInitialize (lldb_private::Debugger &debugger)
{
    if (!PluginManager::GetSettingForProcessPlugin(debugger, PluginProperties::GetSettingName()))
    {
        const bool is_global_setting = true;
        PluginManager::CreateSettingForProcessPlugin (debugger,
                                                      GetGlobalPluginProperties()->GetValueProperties(),
                                                      ConstString ("Properties for the kdp-remote process plug-in."),
                                                      is_global_setting);
    }
}

bool
ProcessKDP::StartAsyncThread ()
{
    Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
    
    if (log)
        log->Printf ("ProcessKDP::StartAsyncThread ()");

    if (m_async_thread.IsJoinable())
        return true;

    m_async_thread = ThreadLauncher::LaunchThread("<lldb.process.kdp-remote.async>", ProcessKDP::AsyncThread, this, NULL);
    return m_async_thread.IsJoinable();
}

void
ProcessKDP::StopAsyncThread ()
{
    Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
    
    if (log)
        log->Printf ("ProcessKDP::StopAsyncThread ()");
    
    m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit);
    
    // Stop the stdio thread
    if (m_async_thread.IsJoinable())
        m_async_thread.Join(nullptr);
}


void *
ProcessKDP::AsyncThread (void *arg)
{
    ProcessKDP *process = (ProcessKDP*) arg;
    
    const lldb::pid_t pid = process->GetID();

    Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS));
    if (log)
        log->Printf ("ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64 ") thread starting...", arg, pid);
    
    Listener listener ("ProcessKDP::AsyncThread");
    EventSP event_sp;
    const uint32_t desired_event_mask = eBroadcastBitAsyncContinue |
                                        eBroadcastBitAsyncThreadShouldExit;
    
    
    if (listener.StartListeningForEvents (&process->m_async_broadcaster, desired_event_mask) == desired_event_mask)
    {
        bool done = false;
        while (!done)
        {
            if (log)
                log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp)...",
                             pid);
            if (listener.WaitForEvent (NULL, event_sp))
            {
                uint32_t event_type = event_sp->GetType();
                if (log)
                    log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") Got an event of type: %d...",
                                 pid,
                                 event_type);
                
                // When we are running, poll for 1 second to try and get an exception
                // to indicate the process has stopped. If we don't get one, check to
                // make sure no one asked us to exit
                bool is_running = false;
                DataExtractor exc_reply_packet;
                do
                {
                    switch (event_type)
                    {
                    case eBroadcastBitAsyncContinue:
                        {
                            is_running = true;
                            if (process->m_comm.WaitForPacketWithTimeoutMicroSeconds (exc_reply_packet, 1 * USEC_PER_SEC))
                            {
                                ThreadSP thread_sp (process->GetKernelThread());
                                if (thread_sp)
                                {
                                    lldb::RegisterContextSP reg_ctx_sp (thread_sp->GetRegisterContext());
                                    if (reg_ctx_sp)
                                        reg_ctx_sp->InvalidateAllRegisters();
                                    static_cast<ThreadKDP *>(thread_sp.get())->SetStopInfoFrom_KDP_EXCEPTION (exc_reply_packet);
                                }

                                // TODO: parse the stop reply packet
                                is_running = false;                                
                                process->SetPrivateState(eStateStopped);
                            }
                            else
                            {
                                // Check to see if we are supposed to exit. There is no way to
                                // interrupt a running kernel, so all we can do is wait for an
                                // exception or detach...
                                if (listener.GetNextEvent(event_sp))
                                {
                                    // We got an event, go through the loop again
                                    event_type = event_sp->GetType();
                                }
                            }
                        }
                        break;
                            
                    case eBroadcastBitAsyncThreadShouldExit:
                        if (log)
                            log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") got eBroadcastBitAsyncThreadShouldExit...",
                                         pid);
                        done = true;
                        is_running = false;
                        break;
                            
                    default:
                        if (log)
                            log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") got unknown event 0x%8.8x",
                                         pid,
                                         event_type);
                        done = true;
                        is_running = false;
                        break;
                    }
                } while (is_running);
            }
            else
            {
                if (log)
                    log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp) => false",
                                 pid);
                done = true;
            }
        }
    }
    
    if (log)
        log->Printf ("ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64 ") thread exiting...",
                     arg,
                     pid);

    process->m_async_thread.Reset();
    return NULL;
}


class CommandObjectProcessKDPPacketSend : public CommandObjectParsed
{
private:
    
    OptionGroupOptions m_option_group;
    OptionGroupUInt64 m_command_byte;
    OptionGroupString m_packet_data;
    
    virtual Options *
    GetOptions ()
    {
        return &m_option_group;
    }
    

public:
    CommandObjectProcessKDPPacketSend(CommandInterpreter &interpreter) :
        CommandObjectParsed (interpreter,
                             "process plugin packet send",
                             "Send a custom packet through the KDP protocol by specifying the command byte and the packet payload data. A packet will be sent with a correct header and payload, and the raw result bytes will be displayed as a string value. ",
                             NULL),
        m_option_group (interpreter),
        m_command_byte(LLDB_OPT_SET_1, true , "command", 'c', 0, eArgTypeNone, "Specify the command byte to use when sending the KDP request packet.", 0),
        m_packet_data (LLDB_OPT_SET_1, false, "payload", 'p', 0, eArgTypeNone, "Specify packet payload bytes as a hex ASCII string with no spaces or hex prefixes.", NULL)
    {
        m_option_group.Append (&m_command_byte, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
        m_option_group.Append (&m_packet_data , LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
        m_option_group.Finalize();
    }
    
    ~CommandObjectProcessKDPPacketSend ()
    {
    }
    
    bool
    DoExecute (Args& command, CommandReturnObject &result)
    {
        const size_t argc = command.GetArgumentCount();
        if (argc == 0)
        {
            if (!m_command_byte.GetOptionValue().OptionWasSet())
            {
                result.AppendError ("the --command option must be set to a valid command byte");
                result.SetStatus (eReturnStatusFailed);
            }
            else
            {
                const uint64_t command_byte = m_command_byte.GetOptionValue().GetUInt64Value(0);
                if (command_byte > 0 && command_byte <= UINT8_MAX)
                {
                    ProcessKDP *process = (ProcessKDP *)m_interpreter.GetExecutionContext().GetProcessPtr();
                    if (process)
                    {
                        const StateType state = process->GetState();
                        
                        if (StateIsStoppedState (state, true))
                        {
                            std::vector<uint8_t> payload_bytes;
                            const char *ascii_hex_bytes_cstr = m_packet_data.GetOptionValue().GetCurrentValue();
                            if (ascii_hex_bytes_cstr && ascii_hex_bytes_cstr[0])
                            {
                                StringExtractor extractor(ascii_hex_bytes_cstr);
                                const size_t ascii_hex_bytes_cstr_len = extractor.GetStringRef().size();
                                if (ascii_hex_bytes_cstr_len & 1)
                                {
                                    result.AppendErrorWithFormat ("payload data must contain an even number of ASCII hex characters: '%s'", ascii_hex_bytes_cstr);
                                    result.SetStatus (eReturnStatusFailed);
                                    return false;
                                }
                                payload_bytes.resize(ascii_hex_bytes_cstr_len/2);
                                if (extractor.GetHexBytes(&payload_bytes[0], payload_bytes.size(), '\xdd') != payload_bytes.size())
                                {
                                    result.AppendErrorWithFormat ("payload data must only contain ASCII hex characters (no spaces or hex prefixes): '%s'", ascii_hex_bytes_cstr);
                                    result.SetStatus (eReturnStatusFailed);
                                    return false;
                                }
                            }
                            Error error;
                            DataExtractor reply;
                            process->GetCommunication().SendRawRequest (command_byte,
                                                                        payload_bytes.empty() ? NULL : payload_bytes.data(),
                                                                        payload_bytes.size(),
                                                                        reply,
                                                                        error);
                            
                            if (error.Success())
                            {
                                // Copy the binary bytes into a hex ASCII string for the result
                                StreamString packet;
                                packet.PutBytesAsRawHex8(reply.GetDataStart(),
                                                         reply.GetByteSize(),
                                                         endian::InlHostByteOrder(),
                                                         endian::InlHostByteOrder());
                                result.AppendMessage(packet.GetString().c_str());
                                result.SetStatus (eReturnStatusSuccessFinishResult);
                                return true;
                            }
                            else
                            {
                                const char *error_cstr = error.AsCString();
                                if (error_cstr && error_cstr[0])
                                    result.AppendError (error_cstr);
                                else
                                    result.AppendErrorWithFormat ("unknown error 0x%8.8x", error.GetError());
                                result.SetStatus (eReturnStatusFailed);
                                return false;
                            }
                        }
                        else
                        {
                            result.AppendErrorWithFormat ("process must be stopped in order to send KDP packets, state is %s", StateAsCString (state));
                            result.SetStatus (eReturnStatusFailed);
                        }
                    }
                    else
                    {
                        result.AppendError ("invalid process");
                        result.SetStatus (eReturnStatusFailed);
                    }
                }
                else
                {
                    result.AppendErrorWithFormat ("invalid command byte 0x%" PRIx64 ", valid values are 1 - 255", command_byte);
                    result.SetStatus (eReturnStatusFailed);
                }
            }
        }
        else
        {
            result.AppendErrorWithFormat ("'%s' takes no arguments, only options.", m_cmd_name.c_str());
            result.SetStatus (eReturnStatusFailed);
        }
        return false;
    }
};

class CommandObjectProcessKDPPacket : public CommandObjectMultiword
{
private:

public:
    CommandObjectProcessKDPPacket(CommandInterpreter &interpreter) :
    CommandObjectMultiword (interpreter,
                            "process plugin packet",
                            "Commands that deal with KDP remote packets.",
                            NULL)
    {
        LoadSubCommand ("send", CommandObjectSP (new CommandObjectProcessKDPPacketSend (interpreter)));
    }
    
    ~CommandObjectProcessKDPPacket ()
    {
    }
};

class CommandObjectMultiwordProcessKDP : public CommandObjectMultiword
{
public:
    CommandObjectMultiwordProcessKDP (CommandInterpreter &interpreter) :
    CommandObjectMultiword (interpreter,
                            "process plugin",
                            "A set of commands for operating on a ProcessKDP process.",
                            "process plugin <subcommand> [<subcommand-options>]")
    {
        LoadSubCommand ("packet", CommandObjectSP (new CommandObjectProcessKDPPacket    (interpreter)));
    }
    
    ~CommandObjectMultiwordProcessKDP ()
    {
    }
};

CommandObject *
ProcessKDP::GetPluginCommandObject()
{
    if (!m_command_sp)
        m_command_sp.reset (new CommandObjectMultiwordProcessKDP (GetTarget().GetDebugger().GetCommandInterpreter()));
    return m_command_sp.get();
}

