// Copyright 2014 The Crashpad Authors. All rights reserved.
//
// 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 "util/mach/exc_server_variants.h"

#include <Availability.h>
#include <string.h>

#include <algorithm>
#include <vector>

#include "base/cxx17_backports.h"
#include "build/build_config.h"
#include "util/mac/mac_util.h"
#include "util/mach/composite_mach_message_server.h"
#include "util/mach/exc.h"
#include "util/mach/excServer.h"
#include "util/mach/exception_behaviors.h"
#include "util/mach/mach_exc.h"
#include "util/mach/mach_excServer.h"
#include "util/mach/mach_message.h"

namespace crashpad {

namespace {

// Traits for ExcServer<> and SimplifiedExcServer<> adapting them for use with
// the exc subsystem.
struct ExcTraits {
  using ExceptionCode = exception_data_type_t;

  using RequestUnion = __RequestUnion__exc_subsystem;
  using ReplyUnion = __ReplyUnion__exc_subsystem;

  using ExceptionRaiseRequest = __Request__exception_raise_t;
  using ExceptionRaiseStateRequest = __Request__exception_raise_state_t;
  using ExceptionRaiseStateIdentityRequest =
      __Request__exception_raise_state_identity_t;

  using ExceptionRaiseReply = __Reply__exception_raise_t;
  using ExceptionRaiseStateReply = __Reply__exception_raise_state_t;
  using ExceptionRaiseStateIdentityReply =
      __Reply__exception_raise_state_identity_t;

  // The MIG-generated __MIG_check__Request__*() functions are not declared as
  // accepting const data, but they could have been because they in fact do not
  // modify the data.

  static kern_return_t MIGCheckRequestExceptionRaise(
      const ExceptionRaiseRequest* in_request) {
    return __MIG_check__Request__exception_raise_t(
        const_cast<ExceptionRaiseRequest*>(in_request));
  }

  static kern_return_t MIGCheckRequestExceptionRaiseState(
      const ExceptionRaiseStateRequest* in_request,
      const ExceptionRaiseStateRequest** in_request_1) {
    return __MIG_check__Request__exception_raise_state_t(
        const_cast<ExceptionRaiseStateRequest*>(in_request),
        const_cast<ExceptionRaiseStateRequest**>(in_request_1));
  }

  static kern_return_t MIGCheckRequestExceptionRaiseStateIdentity(
      const ExceptionRaiseStateIdentityRequest* in_request,
      const ExceptionRaiseStateIdentityRequest** in_request_1) {
    return __MIG_check__Request__exception_raise_state_identity_t(
        const_cast<ExceptionRaiseStateIdentityRequest*>(in_request),
        const_cast<ExceptionRaiseStateIdentityRequest**>(in_request_1));
  }

  // There are no predefined constants for these.
  static const mach_msg_id_t kMachMessageIDExceptionRaise = 2401;
  static const mach_msg_id_t kMachMessageIDExceptionRaiseState = 2402;
  static const mach_msg_id_t kMachMessageIDExceptionRaiseStateIdentity = 2403;

  static const exception_behavior_t kExceptionBehavior = 0;
};

// Traits for ExcServer<> and SimplifiedExcServer<> adapting them for use with
// the mach_exc subsystem.
struct MachExcTraits {
  using ExceptionCode = mach_exception_data_type_t;

  using RequestUnion = __RequestUnion__mach_exc_subsystem;
  using ReplyUnion = __ReplyUnion__mach_exc_subsystem;

  using ExceptionRaiseRequest = __Request__mach_exception_raise_t;
  using ExceptionRaiseStateRequest = __Request__mach_exception_raise_state_t;
  using ExceptionRaiseStateIdentityRequest =
      __Request__mach_exception_raise_state_identity_t;

  using ExceptionRaiseReply = __Reply__mach_exception_raise_t;
  using ExceptionRaiseStateReply = __Reply__mach_exception_raise_state_t;
  using ExceptionRaiseStateIdentityReply =
      __Reply__mach_exception_raise_state_identity_t;

  // The MIG-generated __MIG_check__Request__*() functions are not declared as
  // accepting const data, but they could have been because they in fact do not
  // modify the data.

  static kern_return_t MIGCheckRequestExceptionRaise(
      const ExceptionRaiseRequest* in_request) {
    return __MIG_check__Request__mach_exception_raise_t(
        const_cast<ExceptionRaiseRequest*>(in_request));
  }

  static kern_return_t MIGCheckRequestExceptionRaiseState(
      const ExceptionRaiseStateRequest* in_request,
      const ExceptionRaiseStateRequest** in_request_1) {
    return __MIG_check__Request__mach_exception_raise_state_t(
        const_cast<ExceptionRaiseStateRequest*>(in_request),
        const_cast<ExceptionRaiseStateRequest**>(in_request_1));
  }

  static kern_return_t MIGCheckRequestExceptionRaiseStateIdentity(
      const ExceptionRaiseStateIdentityRequest* in_request,
      const ExceptionRaiseStateIdentityRequest** in_request_1) {
    return __MIG_check__Request__mach_exception_raise_state_identity_t(
        const_cast<ExceptionRaiseStateIdentityRequest*>(in_request),
        const_cast<ExceptionRaiseStateIdentityRequest**>(in_request_1));
  }

  // There are no predefined constants for these.
  static const mach_msg_id_t kMachMessageIDExceptionRaise = 2405;
  static const mach_msg_id_t kMachMessageIDExceptionRaiseState = 2406;
  static const mach_msg_id_t kMachMessageIDExceptionRaiseStateIdentity = 2407;

  static const exception_behavior_t kExceptionBehavior = MACH_EXCEPTION_CODES;
};

//! \brief A server interface for the `exc` or `mach_exc` Mach subsystems.
template <typename Traits>
class ExcServer : public MachMessageServer::Interface {
 public:
  //! \brief An interface that the different request messages that are a part of
  //!     the `exc` or `mach_exc` Mach subsystems can be dispatched to.
  class Interface {
   public:
    //! \brief Handles exceptions raised by `exception_raise()` or
    //!     `mach_exception_raise()`.
    //!
    //! This behaves equivalently to a `catch_exception_raise()` function used
    //! with `exc_server()`, or a `catch_mach_exception_raise()` function used
    //! with `mach_exc_server()`.
    //!
    //! \param[in] trailer The trailer received with the request message.
    //! \param[out] destroy_request `true` if the request message is to be
    //!     destroyed even when this method returns success. See
    //!     MachMessageServer::Interface.
    virtual kern_return_t CatchExceptionRaise(
        exception_handler_t exception_port,
        thread_t thread,
        task_t task,
        exception_type_t exception,
        const typename Traits::ExceptionCode* code,
        mach_msg_type_number_t code_count,
        const mach_msg_trailer_t* trailer,
        bool* destroy_request) = 0;

    //! \brief Handles exceptions raised by `exception_raise_state()` or
    //!     `mach_exception_raise_state()`.
    //!
    //! This behaves equivalently to a `catch_exception_raise_state()` function
    //! used with `exc_server()`, or a `catch_mach_exception_raise_state()`
    //! function used with `mach_exc_server()`.
    //!
    //! There is no \a destroy_request parameter because, unlike
    //! CatchExceptionRaise() and CatchExceptionRaiseStateIdentity(), the
    //! request message is not complex (it does not carry the \a thread or \a
    //! task port rights) and thus there is nothing to destroy.
    //!
    //! \param[in] trailer The trailer received with the request message.
    virtual kern_return_t CatchExceptionRaiseState(
        exception_handler_t exception_port,
        exception_type_t exception,
        const typename Traits::ExceptionCode* code,
        mach_msg_type_number_t code_count,
        thread_state_flavor_t* flavor,
        ConstThreadState old_state,
        mach_msg_type_number_t old_state_count,
        thread_state_t new_state,
        mach_msg_type_number_t* new_state_count,
        const mach_msg_trailer_t* trailer) = 0;

    //! \brief Handles exceptions raised by `exception_raise_state_identity()`
    //!     or `mach_exception_raise_state_identity()`.
    //!
    //! This behaves equivalently to a `catch_exception_raise_state_identity()`
    //! function used with `exc_server()`, or a
    //! `catch_mach_exception_raise_state_identity()` function used with
    //! `mach_exc_server()`.
    //!
    //! \param[in] trailer The trailer received with the request message.
    //! \param[out] destroy_request `true` if the request message is to be
    //!     destroyed even when this method returns success. See
    //!     MachMessageServer::Interface.
    virtual kern_return_t CatchExceptionRaiseStateIdentity(
        exception_handler_t exception_port,
        thread_t thread,
        task_t task,
        exception_type_t exception,
        const typename Traits::ExceptionCode* code,
        mach_msg_type_number_t code_count,
        thread_state_flavor_t* flavor,
        ConstThreadState old_state,
        mach_msg_type_number_t old_state_count,
        thread_state_t new_state,
        mach_msg_type_number_t* new_state_count,
        const mach_msg_trailer_t* trailer,
        bool* destroy_request) = 0;

   protected:
    ~Interface() {}
  };

  //! \brief Constructs an object of this class.
  //!
  //! \param[in] interface The interface to dispatch requests to. Weak.
  explicit ExcServer(Interface* interface)
      : MachMessageServer::Interface(), interface_(interface) {}

  ExcServer(const ExcServer&) = delete;
  ExcServer& operator=(const ExcServer&) = delete;

  // MachMessageServer::Interface:

  bool MachMessageServerFunction(const mach_msg_header_t* in_header,
                                 mach_msg_header_t* out_header,
                                 bool* destroy_complex_request) override;

  std::set<mach_msg_id_t> MachMessageServerRequestIDs() override {
    constexpr mach_msg_id_t request_ids[] = {
        Traits::kMachMessageIDExceptionRaise,
        Traits::kMachMessageIDExceptionRaiseState,
        Traits::kMachMessageIDExceptionRaiseStateIdentity,
    };
    return std::set<mach_msg_id_t>(&request_ids[0],
                                   &request_ids[base::size(request_ids)]);
  }

  mach_msg_size_t MachMessageServerRequestSize() override {
    return sizeof(typename Traits::RequestUnion);
  }

  mach_msg_size_t MachMessageServerReplySize() override {
    return sizeof(typename Traits::ReplyUnion);
  }

 private:
  Interface* interface_;  // weak
};

template <typename Traits>
bool ExcServer<Traits>::MachMessageServerFunction(
    const mach_msg_header_t* in_header,
    mach_msg_header_t* out_header,
    bool* destroy_complex_request) {
  PrepareMIGReplyFromRequest(in_header, out_header);

  const mach_msg_trailer_t* in_trailer =
      MachMessageTrailerFromHeader(in_header);

  switch (in_header->msgh_id) {
    case Traits::kMachMessageIDExceptionRaise: {
      // exception_raise(), catch_exception_raise(), mach_exception_raise(),
      // catch_mach_exception_raise().
      using Request = typename Traits::ExceptionRaiseRequest;
      const Request* in_request = reinterpret_cast<const Request*>(in_header);
      kern_return_t kr = Traits::MIGCheckRequestExceptionRaise(in_request);
      if (kr != MACH_MSG_SUCCESS) {
        SetMIGReplyError(out_header, kr);
        return true;
      }

      using Reply = typename Traits::ExceptionRaiseReply;
      Reply* out_reply = reinterpret_cast<Reply*>(out_header);
      out_reply->RetCode =
          interface_->CatchExceptionRaise(in_header->msgh_local_port,
                                          in_request->thread.name,
                                          in_request->task.name,
                                          in_request->exception,
                                          in_request->code,
                                          in_request->codeCnt,
                                          in_trailer,
                                          destroy_complex_request);
      if (out_reply->RetCode != KERN_SUCCESS) {
        return true;
      }

      out_header->msgh_size = sizeof(*out_reply);
      return true;
    }

    case Traits::kMachMessageIDExceptionRaiseState: {
      // exception_raise_state(), catch_exception_raise_state(),
      // mach_exception_raise_state(), catch_mach_exception_raise_state().
      using Request = typename Traits::ExceptionRaiseStateRequest;
      const Request* in_request = reinterpret_cast<const Request*>(in_header);

      // in_request_1 is used for the portion of the request after the codes,
      // which in theory can be variable-length. The check function will set it.
      const Request* in_request_1;
      kern_return_t kr =
          Traits::MIGCheckRequestExceptionRaiseState(in_request, &in_request_1);
      if (kr != MACH_MSG_SUCCESS) {
        SetMIGReplyError(out_header, kr);
        return true;
      }

      using Reply = typename Traits::ExceptionRaiseStateReply;
      Reply* out_reply = reinterpret_cast<Reply*>(out_header);
      out_reply->flavor = in_request_1->flavor;
      out_reply->new_stateCnt = base::size(out_reply->new_state);
      out_reply->RetCode =
          interface_->CatchExceptionRaiseState(in_header->msgh_local_port,
                                               in_request->exception,
                                               in_request->code,
                                               in_request->codeCnt,
                                               &out_reply->flavor,
                                               in_request_1->old_state,
                                               in_request_1->old_stateCnt,
                                               out_reply->new_state,
                                               &out_reply->new_stateCnt,
                                               in_trailer);
      if (out_reply->RetCode != KERN_SUCCESS) {
        return true;
      }

      out_header->msgh_size =
          sizeof(*out_reply) - sizeof(out_reply->new_state) +
          sizeof(out_reply->new_state[0]) * out_reply->new_stateCnt;
      return true;
    }

    case Traits::kMachMessageIDExceptionRaiseStateIdentity: {
      // exception_raise_state_identity(),
      // catch_exception_raise_state_identity(),
      // mach_exception_raise_state_identity(),
      // catch_mach_exception_raise_state_identity().
      using Request = typename Traits::ExceptionRaiseStateIdentityRequest;
      const Request* in_request = reinterpret_cast<const Request*>(in_header);

      // in_request_1 is used for the portion of the request after the codes,
      // which in theory can be variable-length. The check function will set it.
      const Request* in_request_1;
      kern_return_t kr = Traits::MIGCheckRequestExceptionRaiseStateIdentity(
          in_request, &in_request_1);
      if (kr != MACH_MSG_SUCCESS) {
        SetMIGReplyError(out_header, kr);
        return true;
      }

      using Reply = typename Traits::ExceptionRaiseStateIdentityReply;
      Reply* out_reply = reinterpret_cast<Reply*>(out_header);
      out_reply->flavor = in_request_1->flavor;
      out_reply->new_stateCnt = base::size(out_reply->new_state);
      out_reply->RetCode = interface_->CatchExceptionRaiseStateIdentity(
          in_header->msgh_local_port,
          in_request->thread.name,
          in_request->task.name,
          in_request->exception,
          in_request->code,
          in_request->codeCnt,
          &out_reply->flavor,
          in_request_1->old_state,
          in_request_1->old_stateCnt,
          out_reply->new_state,
          &out_reply->new_stateCnt,
          in_trailer,
          destroy_complex_request);
      if (out_reply->RetCode != KERN_SUCCESS) {
        return true;
      }

      out_header->msgh_size =
          sizeof(*out_reply) - sizeof(out_reply->new_state) +
          sizeof(out_reply->new_state[0]) * out_reply->new_stateCnt;
      return true;
    }

    default: {
      SetMIGReplyError(out_header, MIG_BAD_ID);
      return false;
    }
  }
}

//! \brief A server interface for the `exc` or `mach_exc` Mach subsystems,
//!     simplified to have only a single interface method needing
//!     implementation.
template <typename Traits>
class SimplifiedExcServer final : public ExcServer<Traits>,
                                  public ExcServer<Traits>::Interface {
 public:
  //! \brief An interface that the different request messages that are a part of
  //!     the `exc` or `mach_exc` Mach subsystems can be dispatched to.
  class Interface {
   public:
    //! \brief Handles exceptions raised by `exception_raise()`,
    //!     `exception_raise_state()`, and `exception_raise_state_identity()`;
    //!     or `mach_exception_raise()`, `mach_exception_raise_state()`, and
    //!     `mach_exception_raise_state_identity()`.
    //!
    //! For convenience in implementation, these different “behaviors” of
    //! exception messages are all mapped to a single interface method. The
    //! exception’s original “behavior” is specified in the \a behavior
    //! parameter. Only parameters that were supplied in the request message
    //! are populated, other parameters are set to reasonable default values.
    //!
    //! The meanings of most parameters are identical to that of
    //! ExcServer<>::Interface::CatchExceptionRaiseStateIdentity().
    //!
    //! \param[in] behavior `EXCEPTION_DEFAULT`, `EXCEPTION_STATE`, or
    //!     `EXCEPTION_STATE_IDENTITY`, identifying which exception request
    //!     message was processed and thus which other parameters are valid.
    //!     When used with the `mach_exc` subsystem, `MACH_EXCEPTION_CODES` will
    //!     be ORed in to this parameter.
    virtual kern_return_t CatchException(
        exception_behavior_t behavior,
        exception_handler_t exception_port,
        thread_t thread,
        task_t task,
        exception_type_t exception,
        const typename Traits::ExceptionCode* code,
        mach_msg_type_number_t code_count,
        thread_state_flavor_t* flavor,
        ConstThreadState old_state,
        mach_msg_type_number_t old_state_count,
        thread_state_t new_state,
        mach_msg_type_number_t* new_state_count,
        const mach_msg_trailer_t* trailer,
        bool* destroy_complex_request) = 0;

   protected:
    ~Interface() {}
  };

  //! \brief Constructs an object of this class.
  //!
  //! \param[in] interface The interface to dispatch requests to. Weak.
  explicit SimplifiedExcServer(Interface* interface)
      : ExcServer<Traits>(this),
        ExcServer<Traits>::Interface(),
        interface_(interface) {}

  SimplifiedExcServer(const SimplifiedExcServer&) = delete;
  SimplifiedExcServer& operator=(const SimplifiedExcServer&) = delete;

  // ExcServer::Interface:

  kern_return_t CatchExceptionRaise(exception_handler_t exception_port,
                                    thread_t thread,
                                    task_t task,
                                    exception_type_t exception,
                                    const typename Traits::ExceptionCode* code,
                                    mach_msg_type_number_t code_count,
                                    const mach_msg_trailer_t* trailer,
                                    bool* destroy_request) override {
    thread_state_flavor_t flavor = THREAD_STATE_NONE;
    mach_msg_type_number_t new_state_count = 0;
    return interface_->CatchException(
        Traits::kExceptionBehavior | EXCEPTION_DEFAULT,
        exception_port,
        thread,
        task,
        exception,
        code_count ? code : nullptr,
        code_count,
        &flavor,
        nullptr,
        0,
        nullptr,
        &new_state_count,
        trailer,
        destroy_request);
  }

  kern_return_t CatchExceptionRaiseState(
      exception_handler_t exception_port,
      exception_type_t exception,
      const typename Traits::ExceptionCode* code,
      mach_msg_type_number_t code_count,
      thread_state_flavor_t* flavor,
      ConstThreadState old_state,
      mach_msg_type_number_t old_state_count,
      thread_state_t new_state,
      mach_msg_type_number_t* new_state_count,
      const mach_msg_trailer_t* trailer) override {
    bool destroy_complex_request = false;
    return interface_->CatchException(
        Traits::kExceptionBehavior | EXCEPTION_STATE,
        exception_port,
        THREAD_NULL,
        TASK_NULL,
        exception,
        code_count ? code : nullptr,
        code_count,
        flavor,
        old_state_count ? old_state : nullptr,
        old_state_count,
        new_state_count ? new_state : nullptr,
        new_state_count,
        trailer,
        &destroy_complex_request);
  }

  kern_return_t CatchExceptionRaiseStateIdentity(
      exception_handler_t exception_port,
      thread_t thread,
      task_t task,
      exception_type_t exception,
      const typename Traits::ExceptionCode* code,
      mach_msg_type_number_t code_count,
      thread_state_flavor_t* flavor,
      ConstThreadState old_state,
      mach_msg_type_number_t old_state_count,
      thread_state_t new_state,
      mach_msg_type_number_t* new_state_count,
      const mach_msg_trailer_t* trailer,
      bool* destroy_request) override {
    return interface_->CatchException(
        Traits::kExceptionBehavior | EXCEPTION_STATE_IDENTITY,
        exception_port,
        thread,
        task,
        exception,
        code_count ? code : nullptr,
        code_count,
        flavor,
        old_state_count ? old_state : nullptr,
        old_state_count,
        new_state_count ? new_state : nullptr,
        new_state_count,
        trailer,
        destroy_request);
  }

 private:
  Interface* interface_;  // weak
};

}  // namespace

namespace internal {

class UniversalMachExcServerImpl final
    : public CompositeMachMessageServer,
      public SimplifiedExcServer<ExcTraits>::Interface,
      public SimplifiedExcServer<MachExcTraits>::Interface {
 public:
  explicit UniversalMachExcServerImpl(
      UniversalMachExcServer::Interface* interface)
      : CompositeMachMessageServer(),
        SimplifiedExcServer<ExcTraits>::Interface(),
        SimplifiedExcServer<MachExcTraits>::Interface(),
        exc_server_(this),
        mach_exc_server_(this),
        interface_(interface) {
    AddHandler(&exc_server_);
    AddHandler(&mach_exc_server_);
  }

  UniversalMachExcServerImpl(const UniversalMachExcServerImpl&) = delete;
  UniversalMachExcServerImpl& operator=(const UniversalMachExcServerImpl&) =
      delete;

  ~UniversalMachExcServerImpl() {}

  // SimplifiedExcServer<ExcTraits>::Interface:
  kern_return_t CatchException(exception_behavior_t behavior,
                               exception_handler_t exception_port,
                               thread_t thread,
                               task_t task,
                               exception_type_t exception,
                               const exception_data_type_t* code,
                               mach_msg_type_number_t code_count,
                               thread_state_flavor_t* flavor,
                               ConstThreadState old_state,
                               mach_msg_type_number_t old_state_count,
                               thread_state_t new_state,
                               mach_msg_type_number_t* new_state_count,
                               const mach_msg_trailer_t* trailer,
                               bool* destroy_complex_request) {
    std::vector<mach_exception_data_type_t> mach_codes;
    mach_codes.reserve(code_count);
    for (size_t index = 0; index < code_count; ++index) {
      mach_codes.push_back(code[index]);
    }

    return interface_->CatchMachException(behavior,
                                          exception_port,
                                          thread,
                                          task,
                                          exception,
                                          code_count ? &mach_codes[0] : nullptr,
                                          code_count,
                                          flavor,
                                          old_state_count ? old_state : nullptr,
                                          old_state_count,
                                          new_state_count ? new_state : nullptr,
                                          new_state_count,
                                          trailer,
                                          destroy_complex_request);
  }

  // SimplifiedExcServer<MachExcTraits>::Interface:
  kern_return_t CatchException(exception_behavior_t behavior,
                               exception_handler_t exception_port,
                               thread_t thread,
                               task_t task,
                               exception_type_t exception,
                               const mach_exception_data_type_t* code,
                               mach_msg_type_number_t code_count,
                               thread_state_flavor_t* flavor,
                               ConstThreadState old_state,
                               mach_msg_type_number_t old_state_count,
                               thread_state_t new_state,
                               mach_msg_type_number_t* new_state_count,
                               const mach_msg_trailer_t* trailer,
                               bool* destroy_complex_request) {
    return interface_->CatchMachException(behavior,
                                          exception_port,
                                          thread,
                                          task,
                                          exception,
                                          code_count ? code : nullptr,
                                          code_count,
                                          flavor,
                                          old_state_count ? old_state : nullptr,
                                          old_state_count,
                                          new_state_count ? new_state : nullptr,
                                          new_state_count,
                                          trailer,
                                          destroy_complex_request);
  }

 private:
  SimplifiedExcServer<ExcTraits> exc_server_;
  SimplifiedExcServer<MachExcTraits> mach_exc_server_;
  UniversalMachExcServer::Interface* interface_;  // weak
};

}  // namespace internal

UniversalMachExcServer::UniversalMachExcServer(
    UniversalMachExcServer::Interface* interface)
    : MachMessageServer::Interface(),
      impl_(new internal::UniversalMachExcServerImpl(interface)) {
}

UniversalMachExcServer::~UniversalMachExcServer() {
}

bool UniversalMachExcServer::MachMessageServerFunction(
    const mach_msg_header_t* in_header,
    mach_msg_header_t* out_header,
    bool* destroy_complex_request) {
  return impl_->MachMessageServerFunction(
      in_header, out_header, destroy_complex_request);
}

std::set<mach_msg_id_t> UniversalMachExcServer::MachMessageServerRequestIDs() {
  return impl_->MachMessageServerRequestIDs();
}

mach_msg_size_t UniversalMachExcServer::MachMessageServerRequestSize() {
  return impl_->MachMessageServerRequestSize();
}

mach_msg_size_t UniversalMachExcServer::MachMessageServerReplySize() {
  return impl_->MachMessageServerReplySize();
}

kern_return_t ExcServerSuccessfulReturnValue(exception_type_t exception,
                                             exception_behavior_t behavior,
                                             bool set_thread_state) {
  if (exception == EXC_CRASH
#if defined(OS_MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_11
      && MacOSVersionNumber() >= 10'11'00
#endif
     ) {
    return KERN_SUCCESS;
  }

  if (!set_thread_state && ExceptionBehaviorHasState(behavior)) {
    return MACH_RCV_PORT_DIED;
  }

  return KERN_SUCCESS;
}

void ExcServerCopyState(exception_behavior_t behavior,
                        ConstThreadState old_state,
                        mach_msg_type_number_t old_state_count,
                        thread_state_t new_state,
                        mach_msg_type_number_t* new_state_count) {
  if (ExceptionBehaviorHasState(behavior)) {
    *new_state_count = std::min(old_state_count, *new_state_count);
    memcpy(new_state, old_state, *new_state_count * sizeof(old_state[0]));
  }
}

}  // namespace crashpad
