// 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/exception_ports.h"

#include "base/logging.h"
#include "base/mac/mach_logging.h"
#include "base/notreached.h"

namespace crashpad {

ExceptionPorts::ExceptionHandlerVector::ExceptionHandlerVector()
    : vector_() {
}

ExceptionPorts::ExceptionHandlerVector::~ExceptionHandlerVector() {
  Deallocate();
}

void ExceptionPorts::ExceptionHandlerVector::clear() {
  Deallocate();
  vector_.clear();
}

void ExceptionPorts::ExceptionHandlerVector::Deallocate() {
  for (ExceptionHandler& exception_handler : vector_) {
    if (exception_handler.port != MACH_PORT_NULL) {
      kern_return_t kr =
          mach_port_deallocate(mach_task_self(), exception_handler.port);
      MACH_LOG_IF(ERROR, kr != KERN_SUCCESS, kr) << "mach_port_deallocate";
    }
  }
}

ExceptionPorts::ExceptionPorts(TargetType target_type, mach_port_t target_port)
    : target_port_(target_port), dealloc_target_port_(false) {
  switch (target_type) {
    case kTargetTypeHost:
      get_exception_ports_ = host_get_exception_ports;
      set_exception_ports_ = host_set_exception_ports;
      swap_exception_ports_ = host_swap_exception_ports;
      target_name_ = "host";
      if (target_port_ == HOST_NULL) {
        target_port_ = mach_host_self();
        dealloc_target_port_ = true;
      }
      break;

    case kTargetTypeTask:
      get_exception_ports_ = task_get_exception_ports;
      set_exception_ports_ = task_set_exception_ports;
      swap_exception_ports_ = task_swap_exception_ports;
      target_name_ = "task";
      if (target_port_ == TASK_NULL) {
        target_port_ = mach_task_self();
        // Don’t deallocate mach_task_self().
      }
      break;

    case kTargetTypeThread:
      get_exception_ports_ = thread_get_exception_ports;
      set_exception_ports_ = thread_set_exception_ports;
      swap_exception_ports_ = thread_swap_exception_ports;
      target_name_ = "thread";
      if (target_port_ == THREAD_NULL) {
        target_port_ = mach_thread_self();
        dealloc_target_port_ = true;
      }
      break;

    default:
      NOTREACHED();
      get_exception_ports_ = nullptr;
      set_exception_ports_ = nullptr;
      target_name_ = nullptr;
      target_port_ = MACH_PORT_NULL;
      break;
  }
}

ExceptionPorts::~ExceptionPorts() {
  if (dealloc_target_port_) {
    kern_return_t kr = mach_port_deallocate(mach_task_self(), target_port_);
    MACH_LOG_IF(ERROR, kr != KERN_SUCCESS, kr) << "mach_port_deallocate";
  }
}

bool ExceptionPorts::GetExceptionPorts(exception_mask_t mask,
                                       ExceptionHandlerVector* handlers) const {
  // <mach/mach_types.defs> says that these arrays have room for 32 elements,
  // despite EXC_TYPES_COUNT only being as low as 11 (in the 10.6 SDK), and
  // later operating system versions have defined more exception types. The
  // generated task_get_exception_ports() in taskUser.c expects there to be room
  // for 32.
  constexpr int kMaxPorts = 32;

  // task_get_exception_ports() doesn’t actually use the initial value of
  // handler_count, but 10.9.4
  // xnu-2422.110.17/osfmk/man/task_get_exception_ports.html says it does. Humor
  // the documentation.
  mach_msg_type_number_t handler_count = kMaxPorts;

  exception_mask_t masks[kMaxPorts];
  exception_handler_t ports[kMaxPorts];
  exception_behavior_t behaviors[kMaxPorts];
  thread_state_flavor_t flavors[kMaxPorts];

  kern_return_t kr = get_exception_ports_(
      target_port_, mask, masks, &handler_count, ports, behaviors, flavors);
  if (kr != KERN_SUCCESS) {
    MACH_LOG(ERROR, kr) << TargetTypeName() << "_get_exception_ports";
    return false;
  }

  handlers->clear();
  for (mach_msg_type_number_t index = 0; index < handler_count; ++index) {
    if (ports[index] != MACH_PORT_NULL) {
      ExceptionHandler handler;
      handler.mask = masks[index];
      handler.port = ports[index];
      handler.behavior = behaviors[index];
      handler.flavor = flavors[index];
      handlers->push_back(handler);
    }
  }

  return true;
}

bool ExceptionPorts::SetExceptionPort(exception_mask_t mask,
                                      exception_handler_t port,
                                      exception_behavior_t behavior,
                                      thread_state_flavor_t flavor) const {
  kern_return_t kr =
      set_exception_ports_(target_port_, mask, port, behavior, flavor);
  if (kr != KERN_SUCCESS) {
    MACH_LOG(ERROR, kr) << TargetTypeName() << "_set_exception_ports";
    return false;
  }

  return true;
}

bool ExceptionPorts::SwapExceptionPorts(
    exception_mask_t mask,
    exception_handler_t new_port,
    exception_behavior_t new_behavior,
    thread_state_flavor_t new_flavor,
    ExceptionHandlerVector* old_handlers) const {
  // <mach/mach_types.defs> says that these arrays have room for 32 elements,
  // despite EXC_TYPES_COUNT only being as low as 11 (in the 10.6 SDK), and
  // later operating system versions have defined more exception types. The
  // generated task_swap_exception_ports() in taskUser.c expects there to be
  // room for 32.
  constexpr int kMaxPorts = 32;

  // task_swap_exception_ports() doesn’t actually use the initial value of
  // handler_count, but 10.15.1
  // xnu-6153.41.3/osfmk/man/task_get_exception_ports.html says it does. Humor
  // the documentation.
  mach_msg_type_number_t old_handler_count = kMaxPorts;

  exception_mask_t old_masks[kMaxPorts];
  exception_handler_t old_ports[kMaxPorts];
  exception_behavior_t old_behaviors[kMaxPorts];
  thread_state_flavor_t old_flavors[kMaxPorts];

  kern_return_t kr = swap_exception_ports_(target_port_,
                                           mask,
                                           new_port,
                                           new_behavior,
                                           new_flavor,
                                           old_masks,
                                           &old_handler_count,
                                           old_ports,
                                           old_behaviors,
                                           old_flavors);
  if (kr != KERN_SUCCESS) {
    MACH_LOG(ERROR, kr) << TargetTypeName() << "_swap_exception_ports";
    return false;
  }

  old_handlers->clear();
  for (mach_msg_type_number_t index = 0; index < old_handler_count; ++index) {
    if (old_ports[index] != MACH_PORT_NULL) {
      ExceptionHandler old_handler;
      old_handler.mask = old_masks[index];
      old_handler.port = old_ports[index];
      old_handler.behavior = old_behaviors[index];
      old_handler.flavor = old_flavors[index];
      old_handlers->push_back(old_handler);
    }
  }

  return true;
}

const char* ExceptionPorts::TargetTypeName() const {
  return target_name_;
}

}  // namespace crashpad
