//===-- 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 "DNB.h"
#include "DNBError.h"
#include "DNBLog.h"
#include "MachProcess.h"
#include "PThreadMutex.h"
#include "SysSignal.h"
#include <errno.h>
#include <sys/ptrace.h>
#include <sys/types.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);

// Note: g_message points to the storage allocated to catch the data from
// catching the current exception raise. It's populated when we catch a raised
// exception which can't immediately be replied to.
//
// If it becomes possible to catch exceptions from multiple threads
// simultaneously, accesses to g_message would need to be mutually exclusive.
static MachException::Data *g_message = NULL;

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

  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));
  }
  g_message->exc_type = 0;
  g_message->exc_data.clear();

  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->AppendExceptionData(exc_data, exc_data_count);
    return KERN_SUCCESS;
  } else if (!MachTask::IsValid(g_message->task_port)) {
    // Our original exception port isn't valid anymore check for a SIGTRAP
    if (exc_type == EXC_SOFTWARE && exc_data_count == 2 &&
        exc_data[0] == EXC_SOFT_SIGNAL && exc_data[1] == SIGTRAP) {
      // We got a SIGTRAP which indicates we might have exec'ed and possibly
      // lost our old task port during the exec, so we just need to switch over
      // to using this new task port
      g_message->task_port = task_port;
      g_message->thread_port = thread_port;
      g_message->exc_type = exc_type;
      g_message->AppendExceptionData(exc_data, exc_data_count);
      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.Status();
}

bool MachException::Message::CatchExceptionRaise(task_t task) {
  bool success = false;
  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.Status() == 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.Status());
      } else {
        if (DNBLogCheckLogBit(LOG_EXCEPTIONS))
          err.LogThreaded("::mach_msg() - failed (child of task)");
      }
    }
  }

  return err.Status();
}

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]);
    }
  }
}

// The EXC_MASK_ALL value hard-coded here so that lldb can be built
// on a new OS with an older deployment target .  The new OS may have
// an addition to its EXC_MASK_ALL that the old OS will not recognize -
// <mach/exception_types.h> doesn't vary the value based on the deployment
// target.  So we need a known set of masks that can be assumed to be
// valid when running on an older OS.  We'll fall back to trying
// PREV_EXC_MASK_ALL if the EXC_MASK_ALL value lldb was compiled with is
// not recognized.

#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_RESOURCE |                    \
                         EXC_MASK_GUARD |                       \
                         EXC_MASK_MACHINE)

#define LLDB_EXC_MASK EXC_MASK_ALL

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.Status() == 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.Status();
}

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.Status();
}

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";
  case EXC_CRASH:
    return "EXC_CRASH";
  case EXC_RESOURCE:
    return "EXC_RESOURCE";
#ifdef EXC_GUARD
  case EXC_GUARD:
    return "EXC_GUARD";
#endif
#ifdef EXC_CORPSE_NOTIFY
  case EXC_CORPSE_NOTIFY:
    return "EXC_CORPSE_NOTIFY";
#endif
#ifdef EXC_CORPSE_VARIANT_BIT
  case EXC_CORPSE_VARIANT_BIT:
    return "EXC_CORPSE_VARIANT_BIT";
#endif
  default:
    break;
  }
  return NULL;
}
