//===-- StopInfoMachException.cpp -----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "StopInfoMachException.h"

#include "lldb/lldb-forward.h"

#if defined(__APPLE__)
// Needed for the EXC_RESOURCE interpretation macros
#include <kern/exc_resource.h>
#endif

#include "lldb/Breakpoint/Watchpoint.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"
#include "lldb/Target/UnixSignals.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"
#include <optional>

using namespace lldb;
using namespace lldb_private;

/// Information about a pointer-authentication related instruction.
struct PtrauthInstructionInfo {
  bool IsAuthenticated;
  bool IsLoad;
  bool DoesBranch;
};

/// Get any pointer-authentication related information about the instruction
/// at address \p at_addr.
static std::optional<PtrauthInstructionInfo>
GetPtrauthInstructionInfo(Target &target, const ArchSpec &arch,
                          const Address &at_addr) {
  const char *plugin_name = nullptr;
  const char *flavor = nullptr;
  const char *cpu = nullptr;
  const char *features = nullptr;
  AddressRange range_bounds(at_addr, 4);
  const bool prefer_file_cache = true;
  DisassemblerSP disassembler_sp =
      Disassembler::DisassembleRange(arch, plugin_name, flavor, cpu, features,
                                     target, range_bounds, prefer_file_cache);
  if (!disassembler_sp)
    return std::nullopt;

  InstructionList &insn_list = disassembler_sp->GetInstructionList();
  InstructionSP insn = insn_list.GetInstructionAtIndex(0);
  if (!insn)
    return std::nullopt;

  return PtrauthInstructionInfo{insn->IsAuthenticated(), insn->IsLoad(),
                                insn->DoesBranch()};
}

/// Describe the load address of \p addr using the format filename:line:col.
static void DescribeAddressBriefly(Stream &strm, const Address &addr,
                                   Target &target) {
  strm.Printf("at address=0x%" PRIx64, addr.GetLoadAddress(&target));
  StreamString s;
  if (addr.GetDescription(s, target, eDescriptionLevelBrief))
    strm.Printf(" %s", s.GetString().data());
  strm.Printf(".\n");
}

std::optional<addr_t> StopInfoMachException::GetTagFaultAddress() const {
  const bool bad_access =
      (m_value == 1 || m_value == 12);          // EXC_BAD_ACCESS or EXC_GUARD
  const bool tag_fault = (m_exc_code == 0x106); // EXC_ARM_MTE_TAG_FAULT
  // Whether the subcode (m_exc_subcode) holds the fault address.
  const bool has_fault_addr = (m_exc_data_count >= 2);

  if (bad_access && tag_fault && has_fault_addr)
    return m_exc_subcode; // The subcode is the fault address.

  return std::nullopt;
}

static constexpr uint8_t g_mte_tag_shift = 64 - 8;
static constexpr addr_t g_mte_tag_mask = (addr_t)0x0f << g_mte_tag_shift;

bool StopInfoMachException::DetermineTagMismatch() {
  std::optional<addr_t> fault_address = GetTagFaultAddress();
  if (!fault_address)
    return false;

  const uint64_t bad_address = *fault_address;

  StreamString strm;
  strm.Printf("EXC_ARM_MTE_TAG_FAULT (code=%" PRIu64 ", address=0x%" PRIx64
              ")\n",
              m_exc_code, bad_address);

  const uint8_t tag = (bad_address & g_mte_tag_mask) >> g_mte_tag_shift;
  const addr_t canonical_addr = bad_address & ~g_mte_tag_mask;
  strm.Printf(
      "Note: MTE tag mismatch detected: pointer tag=%d, address=0x%" PRIx64,
      tag, canonical_addr);
  m_description = std::string(strm.GetString());

  return true;
}

bool StopInfoMachException::DeterminePtrauthFailure(ExecutionContext &exe_ctx) {
  bool IsBreakpoint = m_value == 6; // EXC_BREAKPOINT
  bool IsBadAccess = m_value == 1;  // EXC_BAD_ACCESS
  if (!IsBreakpoint && !IsBadAccess)
    return false;

  // Check that we have a live process.
  if (!exe_ctx.HasProcessScope() || !exe_ctx.HasThreadScope() ||
      !exe_ctx.HasTargetScope())
    return false;

  Thread &thread = *exe_ctx.GetThreadPtr();
  StackFrameSP current_frame = thread.GetStackFrameAtIndex(0);
  if (!current_frame)
    return false;

  Target &target = *exe_ctx.GetTargetPtr();
  Process &process = *exe_ctx.GetProcessPtr();
  const ArchSpec &arch = target.GetArchitecture();

  // Check for a ptrauth-enabled target.
  const bool ptrauth_enabled_target =
      arch.GetCore() == ArchSpec::eCore_arm_arm64e;
  if (!ptrauth_enabled_target)
    return false;

  // Set up a stream we can write a diagnostic into.
  StreamString strm;
  auto emit_ptrauth_prologue = [&](uint64_t at_address) {
    strm.Printf("EXC_BAD_ACCESS (code=%" PRIu64 ", address=0x%" PRIx64 ")\n",
                m_exc_code, at_address);
    strm.Printf("Note: Possible pointer authentication failure detected.\n");
  };

  ABISP abi_sp = process.GetABI();
  assert(abi_sp && "Missing ABI info");

  // Check if we have a "brk 0xc47x" trap, where the value that failed to
  // authenticate is in x16.
  Address current_address = current_frame->GetFrameCodeAddress();
  if (IsBreakpoint) {
    RegisterContext *reg_ctx = exe_ctx.GetRegisterContext();
    if (!reg_ctx)
      return false;

    const RegisterInfo *X16Info = reg_ctx->GetRegisterInfoByName("x16");
    RegisterValue X16Val;
    if (!reg_ctx->ReadRegister(X16Info, X16Val))
      return false;
    uint64_t bad_address = X16Val.GetAsUInt64();

    uint64_t fixed_bad_address = abi_sp->FixCodeAddress(bad_address);
    Address brk_address;
    if (!target.ResolveLoadAddress(fixed_bad_address, brk_address))
      return false;

    auto brk_ptrauth_info =
        GetPtrauthInstructionInfo(target, arch, current_address);
    if (brk_ptrauth_info && brk_ptrauth_info->IsAuthenticated) {
      emit_ptrauth_prologue(bad_address);
      strm.Printf("Found value that failed to authenticate ");
      DescribeAddressBriefly(strm, brk_address, target);
      m_description = std::string(strm.GetString());
      return true;
    }
    return false;
  }

  assert(IsBadAccess && "Handle EXC_BAD_ACCESS only after this point");

  // Check that we have the "bad address" from an EXC_BAD_ACCESS.
  if (m_exc_data_count < 2)
    return false;

  // Ok, we know the Target is valid and that it describes a ptrauth-enabled
  // device. Now, we need to determine whether this exception was caused by a
  // ptrauth failure.

  uint64_t bad_address = m_exc_subcode;
  uint64_t fixed_bad_address = abi_sp->FixCodeAddress(bad_address);
  uint64_t current_pc = current_address.GetLoadAddress(&target);

  // Detect: LDRAA, LDRAB (Load Register, with pointer authentication).
  //
  // If an authenticated load results in an exception, the instruction at the
  // current PC should be one of LDRAx.
  if (bad_address != current_pc && fixed_bad_address != current_pc) {
    auto ptrauth_info =
        GetPtrauthInstructionInfo(target, arch, current_address);
    if (ptrauth_info && ptrauth_info->IsAuthenticated && ptrauth_info->IsLoad) {
      emit_ptrauth_prologue(bad_address);
      strm.Printf("Found authenticated load instruction ");
      DescribeAddressBriefly(strm, current_address, target);
      m_description = std::string(strm.GetString());
      return true;
    }
  }

  // Detect: BLRAA, BLRAAZ, BLRAB, BLRABZ (Branch with Link to Register, with
  // pointer authentication).
  //
  // TODO: Detect: BRAA, BRAAZ, BRAB, BRABZ (Branch to Register, with pointer
  // authentication). At a minimum, this requires call site info support for
  // indirect calls.
  //
  // If an authenticated call or tail call results in an exception, stripping
  // the bad address should give the current PC, which points to the address
  // we tried to branch to.
  if (bad_address != current_pc && fixed_bad_address == current_pc) {
    if (StackFrameSP parent_frame = thread.GetStackFrameAtIndex(1)) {
      addr_t return_pc =
          parent_frame->GetFrameCodeAddress().GetLoadAddress(&target);
      Address blr_address;
      if (!target.ResolveLoadAddress(return_pc - 4, blr_address))
        return false;

      auto blr_ptrauth_info =
          GetPtrauthInstructionInfo(target, arch, blr_address);
      if (blr_ptrauth_info && blr_ptrauth_info->IsAuthenticated &&
          blr_ptrauth_info->DoesBranch) {
        emit_ptrauth_prologue(bad_address);
        strm.Printf("Found authenticated indirect branch ");
        DescribeAddressBriefly(strm, blr_address, target);
        m_description = std::string(strm.GetString());
        return true;
      }
    }
  }

  // TODO: Detect: RETAA, RETAB (Return from subroutine, with pointer
  // authentication).
  //
  // Is there a motivating, non-malicious code snippet that corrupts LR?

  return false;
}

bool StopInfoMachException::DetermineCPA2Failure() {
  const bool is_bad_access = (m_value == 1);
  const bool is_cpa2_fault = (m_exc_code == 0x108);

  // Check if subcode has address.
  const bool has_fault_addr = (m_exc_data_count >= 2);

  if (!is_bad_access || !is_cpa2_fault || !has_fault_addr)
    return false;

  const addr_t fault_address = m_exc_subcode;

  StreamString strm;
  strm.Printf("EXC_ARM_CPA_FAIL (code=%" PRIu64 ", address=0x%" PRIx64 ")\n",
              m_exc_code, fault_address);
  strm.Printf("Note: Checked Pointer Arithmetic failure detected.\n");

  m_description = std::string(strm.GetString());
  return true;
}

const char *StopInfoMachException::GetDescription() {
  if (!m_description.empty())
    return m_description.c_str();
  if (GetValue() == eStopReasonInvalid)
    return "invalid stop reason!";

  ExecutionContext exe_ctx(m_thread_wp.lock());
  Target *target = exe_ctx.GetTargetPtr();
  const llvm::Triple::ArchType cpu =
      target ? target->GetArchitecture().GetMachine()
             : llvm::Triple::UnknownArch;

  const char *exc_desc = nullptr;
  const char *code_label = "code";
  const char *code_desc = nullptr;
  const char *subcode_label = "subcode";
  const char *subcode_desc = nullptr;

#if defined(__APPLE__)
  char code_desc_buf[32];
  char subcode_desc_buf[32];
#endif

  switch (m_value) {
  case 1: // EXC_BAD_ACCESS
    exc_desc = "EXC_BAD_ACCESS";
    subcode_label = "address";
    switch (cpu) {
    case llvm::Triple::x86:
    case llvm::Triple::x86_64:
      switch (m_exc_code) {
      case 0xd:
        code_desc = "EXC_I386_GPFLT";
        m_exc_data_count = 1;
        break;
      }
      break;
    case llvm::Triple::arm:
    case llvm::Triple::thumb:
      switch (m_exc_code) {
      case 0x101:
        code_desc = "EXC_ARM_DA_ALIGN";
        break;
      case 0x102:
        code_desc = "EXC_ARM_DA_DEBUG";
        break;
      }
      break;

    case llvm::Triple::aarch64:
      if (DeterminePtrauthFailure(exe_ctx))
        return m_description.c_str();
      if (DetermineTagMismatch())
        return m_description.c_str();
      if (DetermineCPA2Failure())
        return m_description.c_str();
      break;

    default:
      break;
    }
    break;

  case 2: // EXC_BAD_INSTRUCTION
    exc_desc = "EXC_BAD_INSTRUCTION";
    switch (cpu) {
    case llvm::Triple::x86:
    case llvm::Triple::x86_64:
      if (m_exc_code == 1)
        code_desc = "EXC_I386_INVOP";
      break;

    case llvm::Triple::arm:
    case llvm::Triple::thumb:
      if (m_exc_code == 1)
        code_desc = "EXC_ARM_UNDEFINED";
      break;

    default:
      break;
    }
    break;

  case 3: // EXC_ARITHMETIC
    exc_desc = "EXC_ARITHMETIC";
    switch (cpu) {
    case llvm::Triple::x86:
    case llvm::Triple::x86_64:
      switch (m_exc_code) {
      case 1:
        code_desc = "EXC_I386_DIV";
        break;
      case 2:
        code_desc = "EXC_I386_INTO";
        break;
      case 3:
        code_desc = "EXC_I386_NOEXT";
        break;
      case 4:
        code_desc = "EXC_I386_EXTOVR";
        break;
      case 5:
        code_desc = "EXC_I386_EXTERR";
        break;
      case 6:
        code_desc = "EXC_I386_EMERR";
        break;
      case 7:
        code_desc = "EXC_I386_BOUND";
        break;
      case 8:
        code_desc = "EXC_I386_SSEEXTERR";
        break;
      }
      break;

    default:
      break;
    }
    break;

  case 4: // EXC_EMULATION
    exc_desc = "EXC_EMULATION";
    break;

  case 5: // EXC_SOFTWARE
    exc_desc = "EXC_SOFTWARE";
    if (m_exc_code == 0x10003) {
      subcode_desc = "EXC_SOFT_SIGNAL";
      subcode_label = "signo";
    }
    break;

  case 6: // EXC_BREAKPOINT
  {
    exc_desc = "EXC_BREAKPOINT";
    switch (cpu) {
    case llvm::Triple::x86:
    case llvm::Triple::x86_64:
      switch (m_exc_code) {
      case 1:
        code_desc = "EXC_I386_SGL";
        break;
      case 2:
        code_desc = "EXC_I386_BPT";
        break;
      }
      break;

    case llvm::Triple::arm:
    case llvm::Triple::thumb:
      switch (m_exc_code) {
      case 0x101:
        code_desc = "EXC_ARM_DA_ALIGN";
        break;
      case 0x102:
        code_desc = "EXC_ARM_DA_DEBUG";
        break;
      case 1:
        code_desc = "EXC_ARM_BREAKPOINT";
        break;
      // FIXME temporary workaround, exc_code 0 does not really mean
      // EXC_ARM_BREAKPOINT
      case 0:
        code_desc = "EXC_ARM_BREAKPOINT";
        break;
      }
      break;

    case llvm::Triple::aarch64:
      if (DeterminePtrauthFailure(exe_ctx))
        return m_description.c_str();
      break;

    default:
      break;
    }
  } break;

  case 7:
    exc_desc = "EXC_SYSCALL";
    break;

  case 8:
    exc_desc = "EXC_MACH_SYSCALL";
    break;

  case 9:
    exc_desc = "EXC_RPC_ALERT";
    break;

  case 10:
    exc_desc = "EXC_CRASH";
    break;
  case 11:
    exc_desc = "EXC_RESOURCE";
#if defined(__APPLE__)
    {
      int resource_type = EXC_RESOURCE_DECODE_RESOURCE_TYPE(m_exc_code);

      code_label = "limit";
      code_desc = code_desc_buf;
      subcode_label = "observed";
      subcode_desc = subcode_desc_buf;

      switch (resource_type) {
      case RESOURCE_TYPE_CPU:
        exc_desc =
            "EXC_RESOURCE (RESOURCE_TYPE_CPU: CPU usage monitor tripped)";
        snprintf(code_desc_buf, sizeof(code_desc_buf), "%d%%",
                 (int)EXC_RESOURCE_CPUMONITOR_DECODE_PERCENTAGE(m_exc_code));
        snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d%%",
                 (int)EXC_RESOURCE_CPUMONITOR_DECODE_PERCENTAGE_OBSERVED(
                     m_exc_subcode));
        break;
      case RESOURCE_TYPE_WAKEUPS:
        exc_desc = "EXC_RESOURCE (RESOURCE_TYPE_WAKEUPS: idle wakeups monitor "
                   "tripped)";
        snprintf(
            code_desc_buf, sizeof(code_desc_buf), "%d w/s",
            (int)EXC_RESOURCE_CPUMONITOR_DECODE_WAKEUPS_PERMITTED(m_exc_code));
        snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d w/s",
                 (int)EXC_RESOURCE_CPUMONITOR_DECODE_WAKEUPS_OBSERVED(
                     m_exc_subcode));
        break;
      case RESOURCE_TYPE_MEMORY:
        exc_desc = "EXC_RESOURCE (RESOURCE_TYPE_MEMORY: high watermark memory "
                   "limit exceeded)";
        snprintf(code_desc_buf, sizeof(code_desc_buf), "%d MB",
                 (int)EXC_RESOURCE_HWM_DECODE_LIMIT(m_exc_code));
        subcode_desc = nullptr;
        subcode_label = nullptr;
        break;
#if defined(RESOURCE_TYPE_IO)
      // RESOURCE_TYPE_IO is introduced in macOS SDK 10.12.
      case RESOURCE_TYPE_IO:
        exc_desc = "EXC_RESOURCE RESOURCE_TYPE_IO";
        snprintf(code_desc_buf, sizeof(code_desc_buf), "%d MB",
                 (int)EXC_RESOURCE_IO_DECODE_LIMIT(m_exc_code));
        snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d MB",
                 (int)EXC_RESOURCE_IO_OBSERVED(m_exc_subcode));
        ;
        break;
#endif
      }
    }
#endif
    break;
  case 12:
    if (DetermineTagMismatch())
      return m_description.c_str();
    exc_desc = "EXC_GUARD";
    break;
  }

  StreamString strm;

  if (exc_desc)
    strm.PutCString(exc_desc);
  else
    strm.Printf("EXC_??? (%" PRIu64 ")", m_value);

  if (m_exc_data_count >= 1) {
    if (code_desc)
      strm.Printf(" (%s=%s", code_label, code_desc);
    else
      strm.Printf(" (%s=%" PRIu64, code_label, m_exc_code);
  }

  if (m_exc_data_count >= 2) {
    if (subcode_label && subcode_desc)
      strm.Printf(", %s=%s", subcode_label, subcode_desc);
    else if (subcode_label)
      strm.Printf(", %s=0x%" PRIx64, subcode_label, m_exc_subcode);
  }

  if (m_exc_data_count > 0)
    strm.PutChar(')');

  m_description = std::string(strm.GetString());
  return m_description.c_str();
}

#if defined(__APPLE__)
const char *
StopInfoMachException::MachException::Name(exception_type_t exc_type) {
  switch (exc_type) {
  case EXC_BAD_ACCESS:
    return "EXC_BAD_ACCESS";
  case EXC_BAD_INSTRUCTION:
    return "EXC_BAD_INSTRUCTION";
  case EXC_ARITHMETIC:
    return "EXC_ARITHMETIC";
  case EXC_EMULATION:
    return "EXC_EMULATION";
  case EXC_SOFTWARE:
    return "EXC_SOFTWARE";
  case EXC_BREAKPOINT:
    return "EXC_BREAKPOINT";
  case EXC_SYSCALL:
    return "EXC_SYSCALL";
  case EXC_MACH_SYSCALL:
    return "EXC_MACH_SYSCALL";
  case EXC_RPC_ALERT:
    return "EXC_RPC_ALERT";
#ifdef EXC_CRASH
  case EXC_CRASH:
    return "EXC_CRASH";
#endif
  case EXC_RESOURCE:
    return "EXC_RESOURCE";
#ifdef EXC_GUARD
  case EXC_GUARD:
    return "EXC_GUARD";
#endif
#ifdef EXC_CORPSE_NOTIFY
  case EXC_CORPSE_NOTIFY:
    return "EXC_CORPSE_NOTIFY";
#endif
#ifdef EXC_CORPSE_VARIANT_BIT
  case EXC_CORPSE_VARIANT_BIT:
    return "EXC_CORPSE_VARIANT_BIT";
#endif
  default:
    break;
  }
  return NULL;
}

std::optional<exception_type_t>
StopInfoMachException::MachException::ExceptionCode(const char *name) {
  return llvm::StringSwitch<std::optional<exception_type_t>>(name)
      .Case("EXC_BAD_ACCESS", EXC_BAD_ACCESS)
      .Case("EXC_BAD_INSTRUCTION", EXC_BAD_INSTRUCTION)
      .Case("EXC_ARITHMETIC", EXC_ARITHMETIC)
      .Case("EXC_EMULATION", EXC_EMULATION)
      .Case("EXC_SOFTWARE", EXC_SOFTWARE)
      .Case("EXC_BREAKPOINT", EXC_BREAKPOINT)
      .Case("EXC_SYSCALL", EXC_SYSCALL)
      .Case("EXC_MACH_SYSCALL", EXC_MACH_SYSCALL)
      .Case("EXC_RPC_ALERT", EXC_RPC_ALERT)
#ifdef EXC_CRASH
      .Case("EXC_CRASH", EXC_CRASH)
#endif
      .Case("EXC_RESOURCE", EXC_RESOURCE)
#ifdef EXC_GUARD
      .Case("EXC_GUARD", EXC_GUARD)
#endif
#ifdef EXC_CORPSE_NOTIFY
      .Case("EXC_CORPSE_NOTIFY", EXC_CORPSE_NOTIFY)
#endif
      .Default(std::nullopt);
}
#endif

StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
    Thread &thread, uint32_t exc_type, uint32_t exc_data_count,
    uint64_t exc_code, uint64_t exc_sub_code, uint64_t exc_sub_sub_code,
    bool pc_already_adjusted, bool adjust_pc_if_needed) {
  if (exc_type == 0)
    return StopInfoSP();

  bool not_stepping_but_got_singlestep_exception = false;
  uint32_t pc_decrement = 0;
  ExecutionContext exe_ctx(thread.shared_from_this());
  Target *target = exe_ctx.GetTargetPtr();
  const llvm::Triple::ArchType cpu =
      target ? target->GetArchitecture().GetMachine()
             : llvm::Triple::UnknownArch;

  ProcessSP process_sp(thread.GetProcess());
  RegisterContextSP reg_ctx_sp(thread.GetRegisterContext());
  // Caveat: with x86 KDP if we've hit a breakpoint, the pc we
  // receive is past the breakpoint instruction.
  // If we have a breakpoints at 0x100 and 0x101, we hit the
  // 0x100 breakpoint and the pc is reported at 0x101.
  // We will initially mark this thread as being stopped at an
  // unexecuted breakpoint at 0x101. Later when we see that
  // we stopped for a Breakpoint reason, we will decrement the
  // pc, and update the thread to record that we hit the
  // breakpoint at 0x100.
  // The fact that the pc may be off by one at this point
  // (for an x86 KDP breakpoint hit) is not a problem.
  addr_t pc = reg_ctx_sp->GetPC();
  BreakpointSiteSP bp_site_sp =
      process_sp->GetBreakpointSiteList().FindByAddress(pc);
  if (bp_site_sp && process_sp->IsBreakpointSitePhysicallyEnabled(*bp_site_sp))
    thread.SetThreadStoppedAtUnexecutedBP(pc);

  switch (exc_type) {
  case 1: // EXC_BAD_ACCESS
  case 2: // EXC_BAD_INSTRUCTION
  case 3: // EXC_ARITHMETIC
  case 4: // EXC_EMULATION
    break;

  case 5:                    // EXC_SOFTWARE
    if (exc_code == 0x10003) // EXC_SOFT_SIGNAL
    {
      if (exc_sub_code == 5) {
        // On MacOSX, a SIGTRAP can signify that a process has called exec,
        // so we should check with our dynamic loader to verify.
        ProcessSP process_sp(thread.GetProcess());
        if (process_sp) {
          DynamicLoader *dynamic_loader = process_sp->GetDynamicLoader();
          if (dynamic_loader && dynamic_loader->ProcessDidExec()) {
            // The program was re-exec'ed
            return StopInfo::CreateStopReasonWithExec(thread);
          }
        }
      }
      return StopInfo::CreateStopReasonWithSignal(thread, exc_sub_code);
    }
    break;

    // A mach exception comes with 2-4 pieces of data.
    // The sub-codes are only provided for certain types
    // of mach exceptions.
    // [exc_type, exc_code, exc_sub_code, exc_sub_sub_code]
    //
    // Here are all of the EXC_BREAKPOINT, exc_type==6,
    // exceptions we can receive.
    //
    // Instruction step:
    //   [6, 1, 0]
    //   Intel KDP [6, 3, ??]
    //   armv7 [6, 0x102, <stop-pc>]  Same as software breakpoint!
    //
    // Software breakpoint:
    //   x86 [6, 2, 0]
    //   Intel KDP [6, 2, <bp-addr + 1>]
    //   arm64 [6, 1, <bp-addr>]
    //   armv7 [6, 0x102, <bp-addr>]  Same as instruction step!
    //
    // Hardware breakpoint:
    //   x86 [6, 1, <bp-addr>, 0]
    //   x86/Rosetta not implemented, see software breakpoint
    //   arm64 [6, 1, <bp-addr>]
    //   armv7 not implemented, see software breakpoint
    //
    // Hardware watchpoint:
    //   x86 [6, 1, <accessed-addr>, 0] (both Intel hw and Rosetta)
    //   arm64 [6, 0x102, <accessed-addr>, 0]
    //   armv7 [6, 0x102, <accessed-addr>, 0]
    //
    // arm64 BRK instruction (imm arg not reflected in the ME)
    //   [ 6, 1, <addr-of-BRK-insn>]
    //
    // In order of codes mach exceptions:
    //   [6, 1, 0] - instruction step
    //   [6, 1, <bp-addr>] - hardware breakpoint or watchpoint
    //
    //   [6, 2, 0] - software breakpoint
    //   [6, 2, <bp-addr + 1>] - software breakpoint
    //
    //   [6, 3] - instruction step
    //
    //   [6, 0x102, <stop-pc>] armv7 instruction step
    //   [6, 0x102, <bp-addr>] armv7 software breakpoint
    //   [6, 0x102, <accessed-addr>, 0] arm64/armv7 watchpoint

  case 6: // EXC_BREAKPOINT
  {
    bool stopped_by_hitting_breakpoint = false;
    bool stopped_by_completing_stepi = false;
    bool stopped_watchpoint = false;
    std::optional<addr_t> address;

    // exc_code 1
    if (exc_code == 1) {
      if (exc_sub_code == 0) {
        stopped_by_completing_stepi = true;
      } else {
        // Ambiguous: could be signalling a
        // breakpoint or watchpoint hit.
        stopped_by_hitting_breakpoint = true;
        stopped_watchpoint = true;
        address = exc_sub_code;
      }
    }

    // exc_code 2
    if (exc_code == 2) {
      if (exc_sub_code == 0)
        stopped_by_hitting_breakpoint = true;
      else {
        stopped_by_hitting_breakpoint = true;
        // Intel KDP software breakpoint
        if (!pc_already_adjusted)
          pc_decrement = 1;
      }
    }

    // exc_code 3
    if (exc_code == 3)
      stopped_by_completing_stepi = true;

    // exc_code 0x102
    if (exc_code == 0x102 && exc_sub_code != 0) {
      if (cpu == llvm::Triple::arm || cpu == llvm::Triple::thumb) {
        stopped_by_hitting_breakpoint = true;
        stopped_by_completing_stepi = true;
      }
      stopped_watchpoint = true;
      address = exc_sub_code;
    }

    // The Mach Exception may have been ambiguous --
    // e.g. we stopped either because of a breakpoint
    // or a watchpoint.  We'll disambiguate which it
    // really was.

    if (stopped_by_hitting_breakpoint) {
      addr_t pc = reg_ctx_sp->GetPC() - pc_decrement;

      if (address)
        bp_site_sp =
            process_sp->GetBreakpointSiteList().FindByAddress(*address);
      if (!bp_site_sp && reg_ctx_sp) {
        bp_site_sp = process_sp->GetBreakpointSiteList().FindByAddress(pc);
      }
      if (bp_site_sp &&
          process_sp->IsBreakpointSitePhysicallyEnabled(*bp_site_sp)) {
        // We've hit this breakpoint, whether it was intended for this thread
        // or not.  Clear this in the Tread object so we step past it on resume.
        thread.SetThreadHitBreakpointSite();

        if (bp_site_sp->ValidForThisThread(thread)) {
          // Update the PC if we were asked to do so, but only do so if we find
          // a breakpoint that we know about because this could be a trap
          // instruction in the code.
          if (pc_decrement > 0 && adjust_pc_if_needed && reg_ctx_sp)
            reg_ctx_sp->SetPC(pc);

          return StopInfo::CreateStopReasonWithBreakpointSiteID(
              thread, bp_site_sp->GetID());
        } else {
          return StopInfoSP();
        }
      }
    }

    // Breakpoint-hit events are handled.
    // Now handle watchpoints.

    if (stopped_watchpoint && address) {
      WatchpointResourceSP wp_rsrc_sp =
          target->GetProcessSP()->GetWatchpointResourceList().FindByAddress(
              *address);
      if (wp_rsrc_sp && wp_rsrc_sp->GetNumberOfConstituents() > 0) {
        return StopInfo::CreateStopReasonWithWatchpointID(
            thread, wp_rsrc_sp->GetConstituentAtIndex(0)->GetID());
      }
    }

    // Finally, handle instruction step.

    if (stopped_by_completing_stepi) {
      if (thread.GetTemporaryResumeState() != eStateStepping)
        not_stepping_but_got_singlestep_exception = true;
      else
        return StopInfo::CreateStopReasonToTrace(thread);
    }

  } break;

  case 7:  // EXC_SYSCALL
  case 8:  // EXC_MACH_SYSCALL
  case 9:  // EXC_RPC_ALERT
  case 10: // EXC_CRASH
    break;
  }

  return std::make_shared<StopInfoMachException>(
      thread, exc_type, exc_data_count, exc_code, exc_sub_code,
      not_stepping_but_got_singlestep_exception);
}

void StopInfoMachException::PerformAction([[maybe_unused]] Event *event_ptr) {
  // This action currently only fires if the exception is an ARM breakpoint
  // and if the PC is still at the instruction that caused the exception.
  if (!(m_value == 6 /*EXC_BREAKPOINT*/ &&
        m_exc_code == 1 /*EXC_ARM_BREAKPOINT*/) ||
      m_exc_subcode != m_thread_wp.lock()->GetRegisterContext()->GetPC())
    return;
  SkipOverTrapInstruction();
}

// Detect an unusual situation on Darwin where:
//
//   0. We did an instruction-step before this.
//   1. We have a hardware breakpoint or watchpoint set.
//   2. We resumed the process, but not with an instruction-step.
//   3. The thread gets an "instruction-step completed" mach exception.
//   4. The pc has not advanced - it is the same as before.
//
// This method returns true for that combination of events.
bool StopInfoMachException::WasContinueInterrupted(Thread &thread) {
  Log *log = GetLog(LLDBLog::Step);

  // We got an instruction-step completed mach exception but we were not
  // doing an instruction step on this thread.
  if (!m_not_stepping_but_got_singlestep_exception)
    return false;

  RegisterContextSP reg_ctx_sp(thread.GetRegisterContext());
  std::optional<addr_t> prev_pc = thread.GetPreviousFrameZeroPC();
  if (!reg_ctx_sp || !prev_pc)
    return false;

  // The previous pc value and current pc value are the same.
  if (*prev_pc != reg_ctx_sp->GetPC())
    return false;

  // We have a watchpoint -- this is the kernel bug.
  ProcessSP process_sp = thread.GetProcess();
  if (process_sp->GetWatchpointResourceList().GetSize()) {
    LLDB_LOGF(log,
              "Thread stopped with insn-step completed mach exception but "
              "thread was not stepping; there is a hardware watchpoint set.");
    return true;
  }

  // We have a hardware breakpoint -- this is the kernel bug.
  auto &bp_site_list = process_sp->GetBreakpointSiteList();
  for (auto &site : bp_site_list.Sites()) {
    if (site->IsHardware() &&
        process_sp->IsBreakpointSitePhysicallyEnabled(*site)) {
      LLDB_LOGF(log,
                "Thread stopped with insn-step completed mach exception but "
                "thread was not stepping; there is a hardware breakpoint set.");
      return true;
    }
  }

  return false;
}
