// 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 DecodeException(uint32_t code, const 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::kHardwareBreakpoint)
    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::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 DecodeException(uint32_t code, const Arm64ExceptionInfo& info) {
  // HW exceptions have to be analysed further.
  ExceptionType type = DecodeZircon(code);
  if (type != ExceptionType::kHardwareBreakpoint)
    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
