// Copyright 2018 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 "snapshot/fuchsia/exception_snapshot_fuchsia.h"

#include "base/numerics/safe_conversions.h"
#include "snapshot/fuchsia/cpu_context_fuchsia.h"
#include "snapshot/fuchsia/process_reader_fuchsia.h"

namespace crashpad {
namespace internal {

ExceptionSnapshotFuchsia::ExceptionSnapshotFuchsia() = default;
ExceptionSnapshotFuchsia::~ExceptionSnapshotFuchsia() = default;

bool ExceptionSnapshotFuchsia::Initialize(
    ProcessReaderFuchsia* process_reader,
    zx_koid_t thread_id,
    const zx_exception_report_t& exception_report) {
  INITIALIZATION_STATE_SET_INITIALIZING(initialized_);

  exception_ = exception_report.header.type;
  thread_id_ = thread_id;

  // TODO(scottmg): Not sure whether these values for exception_info_ are
  // helpful or correct. Other values in the structures are stored below into
  // Codes() in case they are useful.
#if defined(ARCH_CPU_X86_64)
  DCHECK(base::IsValueInRangeForNumericType<uint32_t>(
      exception_report.context.arch.u.x86_64.err_code));
  exception_info_ = exception_report.context.arch.u.x86_64.err_code;
#elif defined(ARCH_CPU_ARM64)
  exception_info_ = exception_report.context.arch.u.arm_64.esr;
#elif defined(ARCH_CPU_RISCV64)
  exception_info_ = exception_report.context.arch.u.riscv_64.cause;
#endif

  codes_.push_back(exception_);
  codes_.push_back(exception_info_);

#if defined(ARCH_CPU_X86_64)
  codes_.push_back(exception_report.context.arch.u.x86_64.vector);
  codes_.push_back(exception_report.context.arch.u.x86_64.cr2);
#elif defined(ARCH_CPU_ARM64)
  codes_.push_back(exception_report.context.arch.u.arm_64.far);
#elif defined(ARCH_CPU_RISCV64)
  codes_.push_back(exception_report.context.arch.u.riscv_64.tval);
#endif

  const auto threads = process_reader->Threads();
  const auto& t =
      std::find_if(threads.begin(),
                   threads.end(),
                   [thread_id](const ProcessReaderFuchsia::Thread& thread) {
                     return thread.id == thread_id;
                   });
  if (t == threads.end()) {
    // If no threads have been read, then context_ can't be initalized, and the
    // exception snapshot can't be considered initialized_.
    return false;
  }

#if defined(ARCH_CPU_X86_64)
  context_.architecture = kCPUArchitectureX86_64;
  context_.x86_64 = &context_arch_;
  // TODO(fxbug.dev/42132536): Add vector context.
  InitializeCPUContextX86_64(
      t->general_registers, t->fp_registers, context_.x86_64);
#elif defined(ARCH_CPU_ARM64)
  context_.architecture = kCPUArchitectureARM64;
  context_.arm64 = &context_arch_;
  InitializeCPUContextARM64(
      t->general_registers, t->vector_registers, context_.arm64);
#elif defined(ARCH_CPU_RISCV64)
  context_.architecture = kCPUArchitectureRISCV64;
  context_.riscv64 = &context_arch_;
  InitializeCPUContextRISCV64(
      t->general_registers, t->fp_registers, context_.riscv64);
#else
#error Port.
#endif

  if (context_.InstructionPointer() != 0 &&
      (exception_ == ZX_EXCP_UNDEFINED_INSTRUCTION ||
       exception_ == ZX_EXCP_SW_BREAKPOINT ||
       exception_ == ZX_EXCP_HW_BREAKPOINT)) {
    exception_address_ = context_.InstructionPointer();
  } else {
#if defined(ARCH_CPU_X86_64)
    exception_address_ = exception_report.context.arch.u.x86_64.cr2;
#elif defined(ARCH_CPU_ARM64)
    exception_address_ = exception_report.context.arch.u.arm_64.far;
#elif defined(ARCH_CPU_RISCV64)
    exception_address_ = exception_report.context.arch.u.riscv_64.tval;
#else
#error Port.
#endif
  }

  INITIALIZATION_STATE_SET_VALID(initialized_);
  return true;
}

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

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

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

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

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

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

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

}  // namespace internal
}  // namespace crashpad
