// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/developer/debug/ipc/decode_exception.h"

#include <lib/syslog/cpp/macros.h>
#include <zircon/hw/debug/x86.h>
#include <zircon/syscalls/exception.h>

#include "src/developer/debug/shared/arch_arm64.h"
#include "src/developer/debug/shared/arch_x86.h"
#include "src/developer/debug/shared/logging/logging.h"

namespace debug_ipc {
namespace {

// clang-format off
ExceptionType DecodeZircon(uint32_t code) {
  switch (code) {
    case ZX_EXCP_SW_BREAKPOINT: return ExceptionType::kSoftwareBreakpoint;
    case ZX_EXCP_HW_BREAKPOINT: return ExceptionType::kHardwareBreakpoint;
    case ZX_EXCP_GENERAL: return ExceptionType::kGeneral;
    case ZX_EXCP_FATAL_PAGE_FAULT: return ExceptionType::kPageFault;
    case ZX_EXCP_UNDEFINED_INSTRUCTION: return ExceptionType::kUndefinedInstruction;
    case ZX_EXCP_UNALIGNED_ACCESS: return ExceptionType::kUnalignedAccess;
    case ZX_EXCP_THREAD_STARTING: return ExceptionType::kThreadStarting;
    case ZX_EXCP_PROCESS_STARTING: return ExceptionType::kProcessStarting;
    case ZX_EXCP_THREAD_EXITING: return ExceptionType::kThreadExiting;
    case ZX_EXCP_POLICY_ERROR: return ExceptionType::kPolicyError;
    default:
      return ExceptionType::kUnknown;
  }
}
// clang-format on

}  // namespace

// x64 ---------------------------------------------------------------------------------------------

namespace {

ExceptionType DecodeHardwareRegister(uint64_t dr7, int slot) {
  // clang-format off
  bool is_watchpoint = false;
  switch (slot) {
    case 0: is_watchpoint = X86_DBG_CONTROL_RW0_GET(dr7) != 0; break;
    case 1: is_watchpoint = X86_DBG_CONTROL_RW1_GET(dr7) != 0; break;
    case 2: is_watchpoint = X86_DBG_CONTROL_RW2_GET(dr7) != 0; break;
    case 3: is_watchpoint = X86_DBG_CONTROL_RW3_GET(dr7) != 0; break;
    default:
      FX_NOTREACHED();
      return ExceptionType::kUnknown;
  }
  // clang-format on

  return is_watchpoint ? ExceptionType::kWatchpoint : ExceptionType::kHardwareBreakpoint;
}

}  // namespace

ExceptionType DecodeX64Exception(uint32_t code,
                                 fit::function<std::optional<X64DebugRegs>()> fetch_debug_regs) {
  // All zircon exceptions don't need further analysis, except hardware which can represent a single
  // step, a hw breakpoint or a watchpoint.
  ExceptionType type = DecodeZircon(code);
  if (type != ExceptionType::kHardwareBreakpoint)
    return type;

  std::optional<X64DebugRegs> regs;
  if (auto got = fetch_debug_regs()) {
    DEBUG_LOG(Archx64) << "DR6: " << debug::DR6ToString(got->dr6);
    regs = std::move(got.value());
  }

  // If we could not get the registers, we return the zircon exception. In the case of the ambiguous
  // hardware type, we assume single step.
  if (!regs.has_value())
    return ExceptionType::kSingleStep;

  // TODO(https://fxbug.dev/42140857): This permits only one trigger per exception, when overlaps
  //                could occur. For a first pass this is acceptable.

  if (X86_DBG_STATUS_BS_GET(regs->dr6))
    return ExceptionType::kSingleStep;

  if (X86_DBG_STATUS_B0_GET(regs->dr6)) {
    return DecodeHardwareRegister(regs->dr7, 0);
  } else if (X86_DBG_STATUS_B1_GET(regs->dr6)) {
    return DecodeHardwareRegister(regs->dr7, 1);
  } else if (X86_DBG_STATUS_B2_GET(regs->dr6)) {
    return DecodeHardwareRegister(regs->dr7, 2);
  } else if (X86_DBG_STATUS_B3_GET(regs->dr6)) {
    return DecodeHardwareRegister(regs->dr7, 3);
  } else {
    FX_NOTREACHED() << "x86: No known hw exception set in DR6. Got: " << std::hex << regs->dr6;
    return ExceptionType::kUnknown;
  }
}

// arm64 -------------------------------------------------------------------------------------------

namespace {

ExceptionType DecodeESR(uint32_t esr) {
  // The ESR register holds information about the last exception in the form of:
  // |31      26|25|24                              0|
  // |    EC    |IL|             ISS                 |
  //
  // Where:
  // - EC: Exception class field (what exception occurred).
  // - IL: Instruction length (whether the trap was 16-bit of 32-bit instruction).
  // - ISS: Instruction Specific Syndrome. The value is specific to each EC.
  uint32_t ec = esr >> 26;

  switch (ec) {
    case 0b111000: /* BRK from arm32 */
    case 0b111100: /* BRK from arm64 */
      return ExceptionType::kSoftwareBreakpoint;
    case 0b110000: /* HW breakpoint from a lower level */
    case 0b110001: /* HW breakpoint from same level */
      return ExceptionType::kHardwareBreakpoint;
    case 0b110010: /* software step from lower level */
    case 0b110011: /* software step from same level */
      return ExceptionType::kSingleStep;
    case 0b110100: /* HW watchpoint from a lower level */
    case 0b110101: /* HW watchpoint from same level */
      return ExceptionType::kWatchpoint;
    default:
      break;
  }

  return ExceptionType::kUnknown;
}

}  // namespace

ExceptionType DecodeArm64Exception(uint32_t code,
                                   fit::function<std::optional<uint32_t>()> fetch_esr) {
  // HW exceptions have to be analysed further.
  ExceptionType type = DecodeZircon(code);
  if (type != ExceptionType::kHardwareBreakpoint)
    return type;

  uint32_t esr;

  if (auto got = fetch_esr()) {
    esr = *got;
  } else {
    return ExceptionType::kUnknown;
  }

  auto decoded_type = DecodeESR(esr);
  if (decoded_type == ExceptionType::kUnknown) {
    FX_NOTREACHED() << "Received invalid ESR value: 0x" << std::hex << esr << " (EC: 0x"
                    << (esr >> 26) << ").";
    return debug_ipc::ExceptionType::kUnknown;
  }

  return decoded_type;
}

ExceptionType DecodeRiscv64Exception(uint32_t code) {
  // RV64 doesn't support single-stepping/hardware breakpoints/watchpoints yet.
  return DecodeZircon(code);
}

}  // namespace debug_ipc
