// Copyright 2016 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.
#ifndef ZIRCON_SYSCALLS_EXCEPTION_H_
#define ZIRCON_SYSCALLS_EXCEPTION_H_
#include <zircon/compiler.h>
#include <zircon/syscalls/port.h>
#include <zircon/types.h>
__BEGIN_CDECLS
// ask clang format not to mess up the indentation:
// clang-format off
// This bit is set for synthetic exceptions to distinguish them from
// architectural exceptions.
// Note: Port packet types provide 8 bits to distinguish the exception type.
// See zircon/port.h.
#define ZX_EXCP_SYNTH ((uint8_t)0x80)
// The kind of an exception.
// Exception types are a subset of port packet types. See zircon/port.h.
// These are architectural exceptions.
// Depending on the exception, further information can be found in
// |report.context.arch|.
// General exception not covered by another value.
#define ZX_EXCP_GENERAL ZX_PKT_TYPE_EXCEPTION(0)
#define ZX_EXCP_FATAL_PAGE_FAULT ZX_PKT_TYPE_EXCEPTION(1)
#define ZX_EXCP_UNDEFINED_INSTRUCTION ZX_PKT_TYPE_EXCEPTION(2)
#define ZX_EXCP_SW_BREAKPOINT ZX_PKT_TYPE_EXCEPTION(3)
#define ZX_EXCP_HW_BREAKPOINT ZX_PKT_TYPE_EXCEPTION(4)
#define ZX_EXCP_UNALIGNED_ACCESS ZX_PKT_TYPE_EXCEPTION(5)
// Synthetic exceptions.
// A thread is starting.
// This exception is sent to debuggers only (ZX_EXCEPTION_PORT_TYPE_DEBUGGER).
// The thread is paused until it is resumed by the debugger
// with zx_task_resume_from_exception.
#define ZX_EXCP_THREAD_STARTING ZX_PKT_TYPE_EXCEPTION(ZX_EXCP_SYNTH | 0)
// A thread is exiting.
// This exception is sent to debuggers only (ZX_EXCEPTION_PORT_TYPE_DEBUGGER).
// This exception is different from ZX_EXCP_GONE in that a debugger can
// still examine thread state.
// The thread is paused until it is resumed by the debugger
// with zx_task_resume_from_exception.
#define ZX_EXCP_THREAD_EXITING ZX_PKT_TYPE_EXCEPTION(ZX_EXCP_SYNTH | 1)
// This exception is generated when a syscall fails with a job policy
// error (for example, an invalid handle argument is passed to the
// syscall when the ZX_POL_BAD_HANDLE policy is enabled) and
// ZX_POL_ACTION_EXCEPTION is set for the policy. The thread that
// invoked the syscall may be resumed with zx_task_resume_from_exception.
#define ZX_EXCP_POLICY_ERROR ZX_PKT_TYPE_EXCEPTION(ZX_EXCP_SYNTH | 2)
// A process is starting.
// This exception is sent to job debuggers only
// (ZX_EXCEPTION_PORT_TYPE_JOB_DEBUGGER).
// The initial thread is paused until it is resumed by the debugger with
// zx_task_resume_from_exception.
#define ZX_EXCP_PROCESS_STARTING ZX_PKT_TYPE_EXCEPTION(ZX_EXCP_SYNTH | 3)
typedef uint32_t zx_excp_type_t;
// Assuming |excp| is an exception type, return non-zero if it is an
// architectural exception.
#define ZX_EXCP_IS_ARCH(excp) \
(((excp) & (ZX_PKT_TYPE_EXCEPTION(ZX_EXCP_SYNTH) & ~ZX_PKT_TYPE_MASK)) == 0)
typedef struct zx_x86_64_exc_data {
uint64_t vector;
uint64_t err_code;
uint64_t cr2;
} zx_x86_64_exc_data_t;
typedef struct zx_arm64_exc_data {
uint32_t esr;
uint64_t far;
} zx_arm64_exc_data_t;
// data associated with an exception (siginfo in linux parlance)
// Things available from regsets (e.g., pc) are not included here.
// For an example list of things one might add, see linux siginfo.
typedef struct zx_exception_context {
struct {
union {
zx_x86_64_exc_data_t x86_64;
zx_arm64_exc_data_t arm_64;
} u;
} arch;
} zx_exception_context_t;
// The common header of all exception reports.
typedef struct zx_exception_header {
// The actual size, in bytes, of the report (including this field).
uint32_t size;
zx_excp_type_t type;
} zx_exception_header_t;
// Data reported to an exception handler for most exceptions.
typedef struct zx_exception_report {
zx_exception_header_t header;
// The remainder of the report is exception-specific.
zx_exception_context_t context;
} zx_exception_report_t;
// Options for zx_task_resume_from_exception()
#define ZX_RESUME_TRY_NEXT ((uint32_t)2)
// Indicates that instead of resuming from the faulting instruction we instead
// let the next exception handler in the search order, if any, process the
// exception. If there are no more then the entire process is killed.
// Options for zx_task_bind_exception_port.
#define ZX_EXCEPTION_PORT_DEBUGGER ((uint32_t)1)
// When binding an exception port to a process, set the process's debugger
// exception port.
// The type of exception port a thread may be waiting for a response from.
// These values are reported in zx_info_thread_t.wait_exception_port_type.
#define ZX_EXCEPTION_PORT_TYPE_NONE ((uint32_t)0u)
#define ZX_EXCEPTION_PORT_TYPE_DEBUGGER ((uint32_t)1u)
#define ZX_EXCEPTION_PORT_TYPE_THREAD ((uint32_t)2u)
#define ZX_EXCEPTION_PORT_TYPE_PROCESS ((uint32_t)3u)
#define ZX_EXCEPTION_PORT_TYPE_JOB ((uint32_t)4u)
#define ZX_EXCEPTION_PORT_TYPE_JOB_DEBUGGER ((uint32_t)5u)
__END_CDECLS
#endif // ZIRCON_SYSCALLS_EXCEPTION_H_