|  | // 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(). | 
|  | #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() | 
|  | #define ZX_RESUME_EXCEPTION ((uint32_t)1) | 
|  | // Indicates that we should resume the thread from stopped-in-exception state | 
|  | // (default resume does not do so) | 
|  |  | 
|  | #define ZX_RESUME_TRY_NEXT ((uint32_t)2) | 
|  | // Only meaningful when combined with ZX_RESUME_EXCEPTION | 
|  | // 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. | 
|  | #define ZX_EXCEPTION_PORT_UNBIND_QUIETLY ((uint32_t)2) | 
|  | // When unbinding an exception port from a thread or process, any threads that | 
|  | // got an exception and are waiting for a response from this exception port | 
|  | // will continue to wait for a response. | 
|  |  | 
|  | // 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_ |