// 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 <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"
#include "src/lib/fxl/logging.h"

namespace debug_ipc {
namespace {

// clang-format off
ExceptionType DecodeZircon(uint32_t code) {
  switch (code) {
    case ZX_EXCP_SW_BREAKPOINT: return ExceptionType::kSoftware;
    case ZX_EXCP_HW_BREAKPOINT: return ExceptionType::kHardware;
    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:
      FXL_NOTREACHED();
      return ExceptionType::kUnknown;
  }
  // clang-format on

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

}  // namespace

ExceptionType DecodeException(uint32_t code, X64ExceptionInfo* info) {
  // 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::kHardware)
    return type;

  std::optional<X64ExceptionInfo::DebugRegs> regs;
  if (auto got = info->FetchDebugRegs()) {
    DEBUG_LOG(Archx64) << "DR6: " << debug_ipc::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(DX-1445): 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 {
    FXL_NOTREACHED() << "x86: No known hw exception set in 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::kSoftware;
    case 0b110000: /* HW breakpoint from a lower level */
    case 0b110001: /* HW breakpoint from same level */
      return ExceptionType::kHardware;
    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 DecodeException(uint32_t code, Arm64ExceptionInfo* info) {
  // HW exceptions have to be analysed further.
  ExceptionType type = DecodeZircon(code);
  if (type != ExceptionType::kHardware)
    return type;

  uint32_t esr;

  if (auto got = info->FetchESR()) {
    esr = *got;
  } else {
    return ExceptionType::kUnknown;
  }

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

  return decoded_type;
}

}  // namespace debug_ipc
