// Copyright 2014 The Crashpad Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "client/simulate_crash_mac.h"

#include <string.h>
#include <sys/types.h>

#include <iterator>

#include "base/apple/mach_logging.h"
#include "base/apple/scoped_mach_port.h"
#include "base/check_op.h"
#include "base/logging.h"
#include "build/build_config.h"
#include "util/mach/exc_client_variants.h"
#include "util/mach/exception_behaviors.h"
#include "util/mach/exception_ports.h"
#include "util/mach/mach_extensions.h"
#include "util/misc/implicit_cast.h"

namespace crashpad {

namespace {

//! \brief Sends an exception message to an exception port in accordance with
//!     the behavior and thread state flavor it’s registered to receive.
//!
//! \param[in] thread, task, exception, code, code_count These parameters will
//!     be passed to the exception handler as appropriate.
//! \param[in] cpu_context The value to use for the thread state, if \a behavior
//!     indicates that the handler should receive a thread state and if the
//!     supplied thread state matches or can be converted to \a flavor. If \a
//!     behavior requires a thread state but this argument cannot be converted
//!     to match \a flavor, `thread_get_state()` will be called to obtain a
//!     suitable thread state value.
//! \param[in] handler The Mach exception handler to deliver the exception to.
//! \param[in] set_state If `true` and \a behavior indicates that the handler
//!     should receive and return a thread state, a new thread state will be set
//!     by `thread_set_state()` upon successful completion of the exception
//!     handler. If `false`, this will be suppressed, even when \a behavior
//!     indicates that the handler receives and returns a thread state.
//!
//! \return `true` if the exception was delivered to the handler and the handler
//!     indicated success. `false` otherwise, with a warning message logged.
bool DeliverException(thread_t thread,
                      task_t task,
                      exception_type_t exception,
                      const mach_exception_data_t code,
                      mach_msg_type_number_t code_count,
                      const NativeCPUContext& cpu_context,
                      const ExceptionPorts::ExceptionHandler& handler,
                      bool set_state) {
  kern_return_t kr;

  bool handler_wants_state = ExceptionBehaviorHasState(handler.behavior);
  if (!handler_wants_state) {
    // Regardless of the passed-in value of |set_state|, if the handler won’t be
    // dealing with any state at all, no state should be set.
    set_state = false;
  }

  // old_state is only used if the context already captured doesn’t match (or
  // can’t be converted to) what’s registered for the handler.
  thread_state_data_t old_state;

  thread_state_flavor_t flavor = handler.flavor;
  ConstThreadState state;
  mach_msg_type_number_t state_count;
  switch (flavor) {
#if defined(ARCH_CPU_X86_FAMILY)
    case x86_THREAD_STATE:
      state = reinterpret_cast<ConstThreadState>(&cpu_context);
      state_count = x86_THREAD_STATE_COUNT;
      break;
#if defined(ARCH_CPU_X86)
    case x86_THREAD_STATE32:
      state = reinterpret_cast<ConstThreadState>(&cpu_context.uts.ts32);
      state_count = cpu_context.tsh.count;
      break;
#elif defined(ARCH_CPU_X86_64)
    case x86_THREAD_STATE64:
      state = reinterpret_cast<ConstThreadState>(&cpu_context.uts.ts64);
      state_count = cpu_context.tsh.count;
      break;
#endif
#elif defined(ARCH_CPU_ARM64)
    case ARM_UNIFIED_THREAD_STATE:
      state = reinterpret_cast<ConstThreadState>(&cpu_context);
      state_count = ARM_UNIFIED_THREAD_STATE_COUNT;
      break;
    case ARM_THREAD_STATE64:
      state = reinterpret_cast<ConstThreadState>(&cpu_context.ts_64);
      state_count = cpu_context.ash.count;
      break;
#else
#error Port to your CPU architecture
#endif

    case THREAD_STATE_NONE:
      // This is only acceptable if the handler doesn’t have one of the “state”
      // behaviors. Otherwise, if the kernel were attempting to send an
      // exception message to this port, it would call thread_getstatus() (known
      // outside the kernel as thread_get_state()) which would fail because
      // THREAD_STATE_NONE is not a valid state to get. See 10.9.5
      // xnu-2422.115.4/osfmk/kern/exception.c exception_deliver() and
      // xnu-2422.115.4/osfmk/i386/pcb.c machine_thread_get_state().
      if (!handler_wants_state) {
        state = nullptr;
        state_count = 0;
        break;
      }

      LOG(WARNING) << "exception handler has unexpected state flavor" << flavor;
      return false;

    default:
      if (!handler_wants_state) {
        // Don’t bother getting any thread state if the handler’s not actually
        // going to use it.
        state = nullptr;
        state_count = 0;
      } else {
        state = old_state;
        state_count = THREAD_STATE_MAX;
        kr = thread_get_state(thread, flavor, old_state, &state_count);
        if (kr != KERN_SUCCESS) {
          MACH_LOG(WARNING, kr) << "thread_get_state";
          return false;
        }
      }
      break;
  }

  // new_state is supposed to be an out parameter only, but in case the handler
  // doesn't touch it, make sure it's initialized to a valid thread state.
  // Otherwise, the thread_set_state() call below would set a garbage thread
  // state.
  thread_state_data_t new_state;
  size_t state_size =
      sizeof(natural_t) *
      std::min(state_count, implicit_cast<unsigned int>(THREAD_STATE_MAX));
  memcpy(new_state, state, state_size);
  mach_msg_type_number_t new_state_count = THREAD_STATE_MAX;

  kr = UniversalExceptionRaise(handler.behavior,
                               handler.port,
                               thread,
                               task,
                               exception,
                               code,
                               code_count,
                               &flavor,
                               state,
                               state_count,
                               new_state,
                               &new_state_count);

  // The kernel treats a return value of MACH_RCV_PORT_DIED as successful,
  // although it will not set a new thread state in that case. See 10.9.5
  // xnu-2422.115.4/osfmk/kern/exception.c exception_deliver(), and the more
  // elaborate comment at util/mach/exc_server_variants.h
  // ExcServerSuccessfulReturnValue(). Duplicate that behavior.
  bool success = kr == KERN_SUCCESS || kr == MACH_RCV_PORT_DIED;
  MACH_LOG_IF(WARNING, !success, kr) << "UniversalExceptionRaise";

  if (kr == KERN_SUCCESS && set_state) {
    kr = thread_set_state(thread, flavor, new_state, new_state_count);
    MACH_LOG_IF(WARNING, kr != KERN_SUCCESS, kr) << "thread_set_state";
  }

  return success;
}

}  // namespace

void SimulateCrash(const NativeCPUContext& cpu_context) {
#if defined(ARCH_CPU_X86)
  DCHECK_EQ(implicit_cast<thread_state_flavor_t>(cpu_context.tsh.flavor),
            implicit_cast<thread_state_flavor_t>(x86_THREAD_STATE32));
  DCHECK_EQ(implicit_cast<mach_msg_type_number_t>(cpu_context.tsh.count),
            x86_THREAD_STATE32_COUNT);
#elif defined(ARCH_CPU_X86_64)
  DCHECK_EQ(implicit_cast<thread_state_flavor_t>(cpu_context.tsh.flavor),
            implicit_cast<thread_state_flavor_t>(x86_THREAD_STATE64));
  DCHECK_EQ(implicit_cast<mach_msg_type_number_t>(cpu_context.tsh.count),
            x86_THREAD_STATE64_COUNT);
#elif defined(ARCH_CPU_ARM64)
  DCHECK_EQ(implicit_cast<thread_state_flavor_t>(cpu_context.ash.flavor),
            implicit_cast<thread_state_flavor_t>(ARM_THREAD_STATE64));
  DCHECK_EQ(implicit_cast<mach_msg_type_number_t>(cpu_context.ash.count),
            ARM_THREAD_STATE64_COUNT);
#else
#error Port to your CPU architecture
#endif

  base::apple::ScopedMachSendRight thread(mach_thread_self());
  exception_type_t exception = kMachExceptionSimulated;
  mach_exception_data_type_t codes[] = {0, 0};
  mach_msg_type_number_t code_count = std::size(codes);

  // Look up the handler for EXC_CRASH exceptions in the same way that the
  // kernel would: try a thread handler, then a task handler, and finally a host
  // handler. 10.9.5 xnu-2422.115.4/osfmk/kern/exception.c exception_triage().
  static constexpr ExceptionPorts::TargetType kTargetTypes[] = {
      ExceptionPorts::kTargetTypeThread,
      ExceptionPorts::kTargetTypeTask,

      // This is not expected to succeed, because mach_host_self() doesn’t
      // return the host_priv port to non-root users, and this is the port
      // that’s required for host_get_exception_ports().
      //
      // See 10.9.5 xnu-2422.115.4/bsd/kern/kern_prot.c set_security_token(),
      // xnu-2422.115.4/osfmk/kern/task.c host_security_set_task_token(), and
      // xnu-2422.115.4/osfmk/kern/ipc_host.c host_get_exception_ports().
      ExceptionPorts::kTargetTypeHost,
  };

  bool success = false;

  for (size_t target_type_index = 0;
       !success && target_type_index < std::size(kTargetTypes);
       ++target_type_index) {
    ExceptionPorts::ExceptionHandlerVector handlers;
    ExceptionPorts exception_ports(kTargetTypes[target_type_index],
                                   MACH_PORT_NULL);
    if (exception_ports.GetExceptionPorts(EXC_MASK_CRASH, &handlers)) {
      DCHECK_LE(handlers.size(), 1u);
      if (handlers.size() == 1) {
        DCHECK(handlers[0].mask & EXC_MASK_CRASH);
        success = DeliverException(thread.get(),
                                   mach_task_self(),
                                   exception,
                                   codes,
                                   code_count,
                                   cpu_context,
                                   handlers[0],
                                   false);
      }
    }
  }

  LOG_IF(WARNING, !success)
      << "SimulateCrash did not find an appropriate exception handler";
}

}  // namespace crashpad
