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

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