// Copyright 2020 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 "snapshot/ios/exception_snapshot_ios.h"

#include "base/logging.h"
#include "base/mac/mach_logging.h"
#include "base/strings/stringprintf.h"
#include "snapshot/cpu_context.h"
#include "snapshot/mac/cpu_context_mac.h"
#include "util/misc/from_pointer_cast.h"

namespace crashpad {

namespace internal {

ExceptionSnapshotIOS::ExceptionSnapshotIOS()
    : ExceptionSnapshot(),
      context_(),
      codes_(),
      thread_id_(0),
      exception_address_(0),
      exception_(0),
      exception_info_(0),
      initialized_() {}

ExceptionSnapshotIOS::~ExceptionSnapshotIOS() {}

void ExceptionSnapshotIOS::InitializeFromSignal(const siginfo_t* siginfo,
                                                const ucontext_t* context) {
  INITIALIZATION_STATE_SET_INITIALIZING(initialized_);

  mcontext_t mcontext = context->uc_mcontext;
#if defined(ARCH_CPU_X86_64)
  context_.architecture = kCPUArchitectureX86_64;
  context_.x86_64 = &context_x86_64_;
  x86_debug_state64_t empty_debug_state = {};
  InitializeCPUContextX86_64(&context_x86_64_,
                             THREAD_STATE_NONE,
                             nullptr,
                             0,
                             &mcontext->__ss,
                             &mcontext->__fs,
                             &empty_debug_state);
#elif defined(ARCH_CPU_ARM64)
  context_.architecture = kCPUArchitectureARM64;
  context_.arm64 = &context_arm64_;
  arm_debug_state64_t empty_debug_state = {};
  InitializeCPUContextARM64(&context_arm64_,
                            THREAD_STATE_NONE,
                            nullptr,
                            0,
                            &mcontext->__ss,
                            &mcontext->__ns,
                            &empty_debug_state);
#else
#error Port to your CPU architecture
#endif

  // Thread ID.
  thread_identifier_info identifier_info;
  mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
  kern_return_t kr =
      thread_info(mach_thread_self(),
                  THREAD_IDENTIFIER_INFO,
                  reinterpret_cast<thread_info_t>(&identifier_info),
                  &count);
  if (kr != KERN_SUCCESS) {
    MACH_LOG(ERROR, kr) << "thread_identifier_info";
  } else {
    thread_id_ = identifier_info.thread_id;
  }

  exception_ = siginfo->si_signo;
  exception_info_ = siginfo->si_code;

  // TODO(justincohen): Investigate recording more codes_.

  exception_address_ = FromPointerCast<uintptr_t>(siginfo->si_addr);

  // TODO(justincohen): Record the source of the exception (signal, mach, etc).

  INITIALIZATION_STATE_SET_VALID(initialized_);
}

void ExceptionSnapshotIOS::InitializeFromMachException(
    exception_behavior_t behavior,
    thread_t exception_thread,
    exception_type_t exception,
    const mach_exception_data_type_t* code,
    mach_msg_type_number_t code_count,
    thread_state_flavor_t flavor,
    ConstThreadState state,
    mach_msg_type_number_t state_count) {
  INITIALIZATION_STATE_SET_INITIALIZING(initialized_);

  codes_.push_back(exception);
  // TODO: rationalize with the macOS implementation.
  for (mach_msg_type_number_t code_index = 0; code_index < code_count;
       ++code_index) {
    codes_.push_back(code[code_index]);
  }
  exception_ = exception;
  exception_info_ = code[0];

  // For serialization, float_state and, on x86, debug_state, will be identical
  // between here and the thread_snapshot version for thread_id.  That means
  // this block getting float_state and debug_state can be skipped when doing
  // proper serialization.
#if defined(ARCH_CPU_X86_64)
  x86_thread_state64_t thread_state;
  x86_float_state64_t float_state;
  x86_debug_state64_t debug_state;
  mach_msg_type_number_t thread_state_count = x86_THREAD_STATE64_COUNT;
  mach_msg_type_number_t float_state_count = x86_FLOAT_STATE64_COUNT;
  mach_msg_type_number_t debug_state_count = x86_DEBUG_STATE64_COUNT;
  const thread_state_flavor_t kThreadStateFlavor = x86_THREAD_STATE64;
  const thread_state_flavor_t kFloatStateFlavor = x86_FLOAT_STATE64;
  const thread_state_flavor_t kDebugStateFlavor = x86_DEBUG_STATE64;
#elif defined(ARCH_CPU_ARM64)
  arm_thread_state64_t thread_state;
  arm_neon_state64_t float_state;
  arm_debug_state64_t debug_state;
  mach_msg_type_number_t float_state_count = ARM_NEON_STATE64_COUNT;
  mach_msg_type_number_t thread_state_count = ARM_THREAD_STATE64_COUNT;
  mach_msg_type_number_t debug_state_count = ARM_DEBUG_STATE64_COUNT;
  const thread_state_flavor_t kThreadStateFlavor = ARM_THREAD_STATE64;
  const thread_state_flavor_t kFloatStateFlavor = ARM_NEON_STATE64;
  const thread_state_flavor_t kDebugStateFlavor = ARM_DEBUG_STATE64;
#endif

  kern_return_t kr =
      thread_get_state(exception_thread,
                       kThreadStateFlavor,
                       reinterpret_cast<thread_state_t>(&thread_state),
                       &thread_state_count);
  if (kr != KERN_SUCCESS) {
    MACH_LOG(ERROR, kr) << "thread_get_state(" << kThreadStateFlavor << ")";
  }

  kr = thread_get_state(exception_thread,
                        kFloatStateFlavor,
                        reinterpret_cast<thread_state_t>(&float_state),
                        &float_state_count);
  if (kr != KERN_SUCCESS) {
    MACH_LOG(ERROR, kr) << "thread_get_state(" << kFloatStateFlavor << ")";
  }

  kr = thread_get_state(exception_thread,
                        kDebugStateFlavor,
                        reinterpret_cast<thread_state_t>(&debug_state),
                        &debug_state_count);
  if (kr != KERN_SUCCESS) {
    MACH_LOG(ERROR, kr) << "thread_get_state(" << kDebugStateFlavor << ")";
  }

#if defined(ARCH_CPU_X86_64)
  context_.architecture = kCPUArchitectureX86_64;
  context_.x86_64 = &context_x86_64_;
  InitializeCPUContextX86_64(&context_x86_64_,
                             flavor,
                             state,
                             state_count,
                             &thread_state,
                             &float_state,
                             &debug_state);
#elif defined(ARCH_CPU_ARM64)
  context_.architecture = kCPUArchitectureARM64;
  context_.arm64 = &context_arm64_;
  InitializeCPUContextARM64(&context_arm64_,
                            flavor,
                            state,
                            state_count,
                            &thread_state,
                            &float_state,
                            &debug_state);
#else
#error Port to your CPU architecture
#endif

  // Thread ID.
  thread_identifier_info identifier_info;
  mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
  kr = thread_info(mach_thread_self(),
                   THREAD_IDENTIFIER_INFO,
                   reinterpret_cast<thread_info_t>(&identifier_info),
                   &count);
  if (kr != KERN_SUCCESS) {
    MACH_LOG(ERROR, kr) << "thread_identifier_info";
  } else {
    thread_id_ = identifier_info.thread_id;
  }

  // Normally, for EXC_BAD_ACCESS exceptions, the exception address is present
  // in code[1]. It may or may not be the instruction pointer address (usually
  // it’s not). code[1] may carry the exception address for other exception
  // types too, but it’s not guaranteed. But for all other exception types, the
  // instruction pointer will be the exception address, and in fact will be
  // equal to codes[1] when it’s carrying the exception address. In those cases,
  // just use the instruction pointer directly.
  bool code_1_is_exception_address = exception_ == EXC_BAD_ACCESS;

#if defined(ARCH_CPU_X86_64)
  // For x86 and x86_64 EXC_BAD_ACCESS exceptions, some code[0] values
  // indicate that code[1] does not (or may not) carry the exception address:
  // EXC_I386_GPFLT (10.9.5 xnu-2422.115.4/osfmk/i386/trap.c user_trap() for
  // T_GENERAL_PROTECTION) and the oddball (VM_PROT_READ | VM_PROT_EXECUTE)
  // which collides with EXC_I386_BOUNDFLT (10.9.5
  // xnu-2422.115.4/osfmk/i386/fpu.c fpextovrflt()). Other EXC_BAD_ACCESS
  // exceptions come through 10.9.5 xnu-2422.115.4/osfmk/i386/trap.c
  // user_page_fault_continue() and do contain the exception address in
  // code[1].
  if (exception_ == EXC_BAD_ACCESS &&
      (exception_info_ == EXC_I386_GPFLT ||
       exception_info_ == (VM_PROT_READ | VM_PROT_EXECUTE))) {
    code_1_is_exception_address = false;
  }
#endif

  if (code_1_is_exception_address) {
    exception_address_ = code[1];
  } else {
    exception_address_ = context_.InstructionPointer();
  }

  INITIALIZATION_STATE_SET_VALID(initialized_);
}

const CPUContext* ExceptionSnapshotIOS::Context() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return &context_;
}

uint64_t ExceptionSnapshotIOS::ThreadID() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return thread_id_;
}

uint32_t ExceptionSnapshotIOS::Exception() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return exception_;
}

uint32_t ExceptionSnapshotIOS::ExceptionInfo() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return exception_info_;
}

uint64_t ExceptionSnapshotIOS::ExceptionAddress() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return exception_address_;
}

const std::vector<uint64_t>& ExceptionSnapshotIOS::Codes() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return codes_;
}

std::vector<const MemorySnapshot*> ExceptionSnapshotIOS::ExtraMemory() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return std::vector<const MemorySnapshot*>();
}

}  // namespace internal
}  // namespace crashpad
