//===-- 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));

    if (exc_type == 0)
    {
        stop_info->reason = eStopTypeInvalid;
        return true;
    }

    // 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;
}



