//===-- MachException.cpp ---------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  Created by Greg Clayton on 6/18/07.
//
//===----------------------------------------------------------------------===//

#include "MachException.h"
#include "MachProcess.h"
#include "DNB.h"
#include "DNBError.h"
#include <sys/types.h>
#include "DNBLog.h"
#include "PThreadMutex.h"
#include "SysSignal.h"
#include <errno.h>
#include <sys/ptrace.h>

// Routine mach_exception_raise
extern "C"
kern_return_t catch_mach_exception_raise
(
    mach_port_t exception_port,
    mach_port_t thread,
    mach_port_t task,
    exception_type_t exception,
    mach_exception_data_t code,
    mach_msg_type_number_t codeCnt
);

extern "C"
kern_return_t catch_mach_exception_raise_state
(
    mach_port_t exception_port,
    exception_type_t exception,
    const mach_exception_data_t code,
    mach_msg_type_number_t codeCnt,
    int *flavor,
    const thread_state_t old_state,
    mach_msg_type_number_t old_stateCnt,
    thread_state_t new_state,
    mach_msg_type_number_t *new_stateCnt
);

// Routine mach_exception_raise_state_identity
extern "C"
kern_return_t catch_mach_exception_raise_state_identity
(
    mach_port_t exception_port,
    mach_port_t thread,
    mach_port_t task,
    exception_type_t exception,
    mach_exception_data_t code,
    mach_msg_type_number_t codeCnt,
    int *flavor,
    thread_state_t old_state,
    mach_msg_type_number_t old_stateCnt,
    thread_state_t new_state,
    mach_msg_type_number_t *new_stateCnt
);

extern "C" boolean_t mach_exc_server(
        mach_msg_header_t *InHeadP,
        mach_msg_header_t *OutHeadP);

// Any access to the g_message variable should be done by locking the
// g_message_mutex first, using the g_message variable, then unlocking
// the g_message_mutex. See MachException::Message::CatchExceptionRaise()
// for sample code.

static MachException::Data *g_message = NULL;
//static pthread_mutex_t g_message_mutex = PTHREAD_MUTEX_INITIALIZER;


extern "C"
kern_return_t
catch_mach_exception_raise_state
(
    mach_port_t                 exc_port,
    exception_type_t            exc_type,
    const mach_exception_data_t exc_data,
    mach_msg_type_number_t      exc_data_count,
    int *                       flavor,
    const thread_state_t        old_state,
    mach_msg_type_number_t      old_stateCnt,
    thread_state_t              new_state,
    mach_msg_type_number_t *    new_stateCnt
)
{
    if (DNBLogCheckLogBit(LOG_EXCEPTIONS))
    {
        DNBLogThreaded ("::%s ( exc_port = 0x%4.4x, exc_type = %d ( %s ), exc_data = 0x%llx, exc_data_count = %d)",
                        __FUNCTION__,
                        exc_port,
                        exc_type, MachException::Name(exc_type),
                        (uint64_t)exc_data,
                        exc_data_count);
    }
    return KERN_FAILURE;
}

extern "C"
kern_return_t
catch_mach_exception_raise_state_identity
(
    mach_port_t             exc_port,
    mach_port_t             thread_port,
    mach_port_t             task_port,
    exception_type_t        exc_type,
    mach_exception_data_t   exc_data,
    mach_msg_type_number_t  exc_data_count,
    int *                   flavor,
    thread_state_t          old_state,
    mach_msg_type_number_t  old_stateCnt,
    thread_state_t          new_state,
    mach_msg_type_number_t *new_stateCnt
)
{
    if (DNBLogCheckLogBit(LOG_EXCEPTIONS))
    {
        DNBLogThreaded("::%s ( exc_port = 0x%4.4x, thd_port = 0x%4.4x, tsk_port = 0x%4.4x, exc_type = %d ( %s ), exc_data[%d] = { 0x%llx, 0x%llx })",
            __FUNCTION__,
            exc_port,
            thread_port,
            task_port,
            exc_type, MachException::Name(exc_type),
            exc_data_count,
            (uint64_t)(exc_data_count > 0 ? exc_data[0] : 0xBADDBADD),
            (uint64_t)(exc_data_count > 1 ? exc_data[1] : 0xBADDBADD));
    }
    mach_port_deallocate (mach_task_self (), task_port);
    mach_port_deallocate (mach_task_self (), thread_port);

    return KERN_FAILURE;
}

extern "C"
kern_return_t
catch_mach_exception_raise
(
    mach_port_t             exc_port,
    mach_port_t             thread_port,
    mach_port_t             task_port,
    exception_type_t        exc_type,
    mach_exception_data_t   exc_data,
    mach_msg_type_number_t  exc_data_count)
{
    if (DNBLogCheckLogBit(LOG_EXCEPTIONS))
    {
        DNBLogThreaded ("::%s ( exc_port = 0x%4.4x, thd_port = 0x%4.4x, tsk_port = 0x%4.4x, exc_type = %d ( %s ), exc_data[%d] = { 0x%llx, 0x%llx })",
                        __FUNCTION__,
                        exc_port,
                        thread_port,
                        task_port,
                        exc_type, MachException::Name(exc_type),
                        exc_data_count,
                        (uint64_t)(exc_data_count > 0 ? exc_data[0] : 0xBADDBADD),
                        (uint64_t)(exc_data_count > 1 ? exc_data[1] : 0xBADDBADD));
    }

    if (task_port == g_message->task_port)
    {
        g_message->task_port = task_port;
        g_message->thread_port = thread_port;
        g_message->exc_type = exc_type;
        g_message->exc_data.resize(exc_data_count);
        ::memcpy (&g_message->exc_data[0], exc_data, g_message->exc_data.size() * sizeof (mach_exception_data_type_t));
        return KERN_SUCCESS;
    }
    return KERN_FAILURE;
}


void
MachException::Message::Dump() const
{
    DNBLogThreadedIf(LOG_EXCEPTIONS,
        "  exc_msg { bits = 0x%8.8x size = 0x%8.8x remote-port = 0x%8.8x local-port = 0x%8.8x reserved = 0x%8.8x id = 0x%8.8x } ",
        exc_msg.hdr.msgh_bits,
        exc_msg.hdr.msgh_size,
        exc_msg.hdr.msgh_remote_port,
        exc_msg.hdr.msgh_local_port,
        exc_msg.hdr.msgh_reserved,
        exc_msg.hdr.msgh_id);

    DNBLogThreadedIf(LOG_EXCEPTIONS,
        "reply_msg { bits = 0x%8.8x size = 0x%8.8x remote-port = 0x%8.8x local-port = 0x%8.8x reserved = 0x%8.8x id = 0x%8.8x }",
        reply_msg.hdr.msgh_bits,
        reply_msg.hdr.msgh_size,
        reply_msg.hdr.msgh_remote_port,
        reply_msg.hdr.msgh_local_port,
        reply_msg.hdr.msgh_reserved,
        reply_msg.hdr.msgh_id);

    state.Dump();
}

bool
MachException::Data::GetStopInfo(struct DNBThreadStopInfo *stop_info) const
{
    // Zero out the structure.
    memset(stop_info, 0, sizeof(struct DNBThreadStopInfo));
    // We always stop with a mach exceptions
    stop_info->reason = eStopTypeException;
    // Save the EXC_XXXX exception type
    stop_info->details.exception.type = exc_type;

    // Fill in a text description
    const char * exc_name = MachException::Name(exc_type);
    char *desc = stop_info->description;
    const char *end_desc = desc + DNB_THREAD_STOP_INFO_MAX_DESC_LENGTH;
    if (exc_name)
        desc += snprintf(desc, DNB_THREAD_STOP_INFO_MAX_DESC_LENGTH, "%s", exc_name);
    else
        desc += snprintf(desc, DNB_THREAD_STOP_INFO_MAX_DESC_LENGTH, "%i", exc_type);

    stop_info->details.exception.data_count = exc_data.size();

    int soft_signal = SoftSignal();
    if (soft_signal)
    {
        if (desc < end_desc)
        {
            const char *sig_str = SysSignal::Name(soft_signal);
            snprintf(desc, end_desc - desc, " EXC_SOFT_SIGNAL( %i ( %s ))", soft_signal, sig_str ? sig_str : "unknown signal");
        }
    }
    else
    {
        // No special disassembly for exception data, just
        size_t idx;
        if (desc < end_desc)
        {
            desc += snprintf(desc, end_desc - desc, " data[%llu] = {", (uint64_t)stop_info->details.exception.data_count);

            for (idx = 0; desc < end_desc && idx < stop_info->details.exception.data_count; ++idx)
                desc += snprintf(desc, end_desc - desc, "0x%llx%c", (uint64_t)exc_data[idx], ((idx + 1 == stop_info->details.exception.data_count) ? '}' : ','));
        }
    }

    // Copy the exception data
    size_t i;
    for (i=0; i<stop_info->details.exception.data_count; i++)
        stop_info->details.exception.data[i] = exc_data[i];

    return true;
}


void
MachException::Data::DumpStopReason() const
{
    int soft_signal = SoftSignal();
    if (soft_signal)
    {
        const char *signal_str = SysSignal::Name(soft_signal);
        if (signal_str)
            DNBLog("signal(%s)", signal_str);
        else
            DNBLog("signal(%i)", soft_signal);
        return;
    }
    DNBLog("%s", Name(exc_type));
}

kern_return_t
MachException::Message::Receive(mach_port_t port, mach_msg_option_t options, mach_msg_timeout_t timeout, mach_port_t notify_port)
{
    DNBError err;
    const bool log_exceptions = DNBLogCheckLogBit(LOG_EXCEPTIONS);
    mach_msg_timeout_t mach_msg_timeout = options & MACH_RCV_TIMEOUT ? timeout : 0;
    if (log_exceptions && ((options & MACH_RCV_TIMEOUT) == 0))
    {
        // Dump this log message if we have no timeout in case it never returns
        DNBLogThreaded ("::mach_msg ( msg->{bits = %#x, size = %u remote_port = %#x, local_port = %#x, reserved = 0x%x, id = 0x%x}, option = %#x, send_size = 0, rcv_size = %llu, rcv_name = %#x, timeout = %u, notify = %#x)",
                        exc_msg.hdr.msgh_bits,
                        exc_msg.hdr.msgh_size,
                        exc_msg.hdr.msgh_remote_port,
                        exc_msg.hdr.msgh_local_port,
                        exc_msg.hdr.msgh_reserved,
                        exc_msg.hdr.msgh_id,
                        options,
                        (uint64_t)sizeof (exc_msg.data),
                        port,
                        mach_msg_timeout,
                        notify_port);
    }

    err = ::mach_msg (&exc_msg.hdr,
                      options,                  // options
                      0,                        // Send size
                      sizeof (exc_msg.data),    // Receive size
                      port,                     // exception port to watch for exception on
                      mach_msg_timeout,         // timeout in msec (obeyed only if MACH_RCV_TIMEOUT is ORed into the options parameter)
                      notify_port);

    // Dump any errors we get
    if (log_exceptions)
    {
        err.LogThreaded("::mach_msg ( msg->{bits = %#x, size = %u remote_port = %#x, local_port = %#x, reserved = 0x%x, id = 0x%x}, option = %#x, send_size = %u, rcv_size = %u, rcv_name = %#x, timeout = %u, notify = %#x)",
            exc_msg.hdr.msgh_bits,
            exc_msg.hdr.msgh_size,
            exc_msg.hdr.msgh_remote_port,
            exc_msg.hdr.msgh_local_port,
            exc_msg.hdr.msgh_reserved,
            exc_msg.hdr.msgh_id,
            options,
            0,
            sizeof (exc_msg.data),
            port,
            mach_msg_timeout,
            notify_port);
    }
    return err.Error();
}

bool
MachException::Message::CatchExceptionRaise(task_t task)
{
    bool success = false;
    // locker will keep a mutex locked until it goes out of scope
//    PThreadMutex::Locker locker(&g_message_mutex);
    //    DNBLogThreaded("calling  mach_exc_server");
    state.task_port = task;
    g_message = &state;
    // The exc_server function is the MIG generated server handling function
    // to handle messages from the kernel relating to the occurrence of an
    // exception in a thread. Such messages are delivered to the exception port
    // set via thread_set_exception_ports or task_set_exception_ports. When an
    // exception occurs in a thread, the thread sends an exception message to
    // its exception port, blocking in the kernel waiting for the receipt of a
    // reply. The exc_server function performs all necessary argument handling
    // for this kernel message and calls catch_exception_raise,
    // catch_exception_raise_state or catch_exception_raise_state_identity,
    // which should handle the exception. If the called routine returns
    // KERN_SUCCESS, a reply message will be sent, allowing the thread to
    // continue from the point of the exception; otherwise, no reply message
    // is sent and the called routine must have dealt with the exception
    // thread directly.
    if (mach_exc_server (&exc_msg.hdr, &reply_msg.hdr))
    {
        success = true;
    }
    else if (DNBLogCheckLogBit(LOG_EXCEPTIONS))
    {
        DNBLogThreaded("mach_exc_server returned zero...");
    }
    g_message = NULL;
    return success;
}



kern_return_t
MachException::Message::Reply(MachProcess *process, int signal)
{
    // Reply to the exception...
    DNBError err;

    // If we had a soft signal, we need to update the thread first so it can
    // continue without signaling
    int soft_signal = state.SoftSignal();
    if (soft_signal)
    {
        int state_pid = -1;
        if (process->Task().TaskPort() == state.task_port)
        {
            // This is our task, so we can update the signal to send to it
            state_pid = process->ProcessID();
            soft_signal = signal;
        }
        else
        {
            err = ::pid_for_task(state.task_port, &state_pid);
        }

        assert (state_pid != -1);
        if (state_pid != -1)
        {
            errno = 0;
            if (::ptrace (PT_THUPDATE, state_pid, (caddr_t)((uintptr_t)state.thread_port), soft_signal) != 0)
                err.SetError(errno, DNBError::POSIX);
            else
                err.Clear();

            if (DNBLogCheckLogBit(LOG_EXCEPTIONS) || err.Fail())
                err.LogThreaded("::ptrace (request = PT_THUPDATE, pid = 0x%4.4x, tid = 0x%4.4x, signal = %i)", state_pid, state.thread_port, soft_signal);
        }
    }

    DNBLogThreadedIf(LOG_EXCEPTIONS, "::mach_msg ( msg->{bits = %#x, size = %u, remote_port = %#x, local_port = %#x, reserved = 0x%x, id = 0x%x}, option = %#x, send_size = %u, rcv_size = %u, rcv_name = %#x, timeout = %u, notify = %#x)",
        reply_msg.hdr.msgh_bits,
        reply_msg.hdr.msgh_size,
        reply_msg.hdr.msgh_remote_port,
        reply_msg.hdr.msgh_local_port,
        reply_msg.hdr.msgh_reserved,
        reply_msg.hdr.msgh_id,
        MACH_SEND_MSG | MACH_SEND_INTERRUPT,
        reply_msg.hdr.msgh_size,
        0,
        MACH_PORT_NULL,
        MACH_MSG_TIMEOUT_NONE,
        MACH_PORT_NULL);

    err = ::mach_msg (  &reply_msg.hdr,
                        MACH_SEND_MSG | MACH_SEND_INTERRUPT,
                        reply_msg.hdr.msgh_size,
                        0,
                        MACH_PORT_NULL,
                        MACH_MSG_TIMEOUT_NONE,
                        MACH_PORT_NULL);

    if (err.Fail())
    {
        if (err.Error() == MACH_SEND_INTERRUPTED)
        {
            if (DNBLogCheckLogBit(LOG_EXCEPTIONS))
                err.LogThreaded("::mach_msg() - send interrupted");
            // TODO: keep retrying to reply???
        }
        else
        {
            if (state.task_port == process->Task().TaskPort())
            {
                DNBLogThreaded("error: mach_msg() returned an error when replying to a mach exception: error = %u", err.Error());
                abort ();
            }
            else
            {
                if (DNBLogCheckLogBit(LOG_EXCEPTIONS))
                    err.LogThreaded("::mach_msg() - failed (child of task)");
            }
        }
    }

    return err.Error();
}


void
MachException::Data::Dump() const
{
    const char *exc_type_name = MachException::Name(exc_type);
    DNBLogThreadedIf(LOG_EXCEPTIONS, "    state { task_port = 0x%4.4x, thread_port =  0x%4.4x, exc_type = %i (%s) ...", task_port, thread_port, exc_type, exc_type_name ? exc_type_name : "???");

    const size_t exc_data_count = exc_data.size();
    // Dump any special exception data contents
    int soft_signal = SoftSignal();
    if (soft_signal != 0)
    {
        const char *sig_str = SysSignal::Name(soft_signal);
        DNBLogThreadedIf(LOG_EXCEPTIONS, "            exc_data: EXC_SOFT_SIGNAL (%i (%s))", soft_signal, sig_str ? sig_str : "unknown signal");
    }
    else
    {
        // No special disassembly for this data, just dump the data
        size_t idx;
        for (idx = 0; idx < exc_data_count; ++idx)
        {
            DNBLogThreadedIf(LOG_EXCEPTIONS, "            exc_data[%llu]: 0x%llx", (uint64_t)idx, (uint64_t)exc_data[idx]);
        }
    }
}

#define PREV_EXC_MASK_ALL (EXC_MASK_BAD_ACCESS      | \
                           EXC_MASK_BAD_INSTRUCTION | \
                           EXC_MASK_ARITHMETIC      | \
                           EXC_MASK_EMULATION       | \
                           EXC_MASK_SOFTWARE        | \
                           EXC_MASK_BREAKPOINT      | \
                           EXC_MASK_SYSCALL         | \
                           EXC_MASK_MACH_SYSCALL    | \
                           EXC_MASK_RPC_ALERT       | \
                           EXC_MASK_MACHINE)

// Don't listen for EXC_RESOURCE, it should really get handled by the system handler.

#ifndef EXC_RESOURCE
#define EXC_RESOURCE 11
#endif

#ifndef EXC_MASK_RESOURCE
#define EXC_MASK_RESOURCE (1 << EXC_RESOURCE)
#endif

#define LLDB_EXC_MASK (EXC_MASK_ALL & ~EXC_MASK_RESOURCE)

kern_return_t
MachException::PortInfo::Save (task_t task)
{
    DNBLogThreadedIf(LOG_EXCEPTIONS | LOG_VERBOSE, "MachException::PortInfo::Save ( task = 0x%4.4x )", task);
    // Be careful to be able to have debugserver built on a newer OS than what
    // it is currently running on by being able to start with all exceptions
    // and back off to just what is supported on the current system
    DNBError err;

    mask = LLDB_EXC_MASK;

    count = (sizeof (ports) / sizeof (ports[0]));
    err = ::task_get_exception_ports (task, mask, masks, &count, ports, behaviors, flavors);
    if (DNBLogCheckLogBit(LOG_EXCEPTIONS) || err.Fail())
        err.LogThreaded("::task_get_exception_ports ( task = 0x%4.4x, mask = 0x%x, maskCnt => %u, ports, behaviors, flavors )", task, mask, count);

    if (err.Error() == KERN_INVALID_ARGUMENT && mask != PREV_EXC_MASK_ALL)
    {
        mask = PREV_EXC_MASK_ALL;
        count = (sizeof (ports) / sizeof (ports[0]));
        err = ::task_get_exception_ports (task, mask, masks, &count, ports, behaviors, flavors);
        if (DNBLogCheckLogBit(LOG_EXCEPTIONS) || err.Fail())
            err.LogThreaded("::task_get_exception_ports ( task = 0x%4.4x, mask = 0x%x, maskCnt => %u, ports, behaviors, flavors )", task, mask, count);
    }
    if (err.Fail())
    {
        mask = 0;
        count = 0;
    }
    return err.Error();
}

kern_return_t
MachException::PortInfo::Restore (task_t task)
{
    DNBLogThreadedIf(LOG_EXCEPTIONS | LOG_VERBOSE, "MachException::PortInfo::Restore( task = 0x%4.4x )", task);
    uint32_t i = 0;
    DNBError err;
    if (count > 0)
    {
        for (i = 0; i < count; i++)
        {
            err = ::task_set_exception_ports (task, masks[i], ports[i], behaviors[i], flavors[i]);
            if (DNBLogCheckLogBit(LOG_EXCEPTIONS) || err.Fail())
            {
                err.LogThreaded("::task_set_exception_ports ( task = 0x%4.4x, exception_mask = 0x%8.8x, new_port = 0x%4.4x, behavior = 0x%8.8x, new_flavor = 0x%8.8x )", task, masks[i], ports[i], behaviors[i], flavors[i]);
                // Bail if we encounter any errors
            }

            if (err.Fail())
                break;
        }
    }
    count = 0;
    return err.Error();
}

const char *
MachException::Name(exception_type_t exc_type)
{
    switch (exc_type)
    {
    case EXC_BAD_ACCESS:        return "EXC_BAD_ACCESS";
    case EXC_BAD_INSTRUCTION:   return "EXC_BAD_INSTRUCTION";
    case EXC_ARITHMETIC:        return "EXC_ARITHMETIC";
    case EXC_EMULATION:         return "EXC_EMULATION";
    case EXC_SOFTWARE:          return "EXC_SOFTWARE";
    case EXC_BREAKPOINT:        return "EXC_BREAKPOINT";
    case EXC_SYSCALL:           return "EXC_SYSCALL";
    case EXC_MACH_SYSCALL:      return "EXC_MACH_SYSCALL";
    case EXC_RPC_ALERT:         return "EXC_RPC_ALERT";
#ifdef EXC_CRASH
    case EXC_CRASH:             return "EXC_CRASH";
#endif
    default:
        break;
    }
    return NULL;
}



