// 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:
      FX_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 {
    FX_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) {
    FX_NOTREACHED() << "Received invalid ESR value: 0x" << std::hex << esr << " (EC: 0x"
                    << (esr >> 26) << ").";
    return debug_ipc::ExceptionType::kUnknown;
  }

  return decoded_type;
}

}  // namespace debug_ipc
