| // 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. |
| library zx; |
| |
| @transport("Syscall") |
| closed protocol Process { |
| /// ## Summary |
| /// |
| /// Exits the currently running process. |
| /// |
| /// ## Declaration |
| /// |
| /// ```c |
| /// #include <zircon/syscalls.h> |
| /// |
| /// [[noreturn]] void zx_process_exit(int64_t retcode); |
| /// ``` |
| /// |
| /// ## Description |
| /// |
| /// The `zx_process_exit()` call ends the calling process with the given |
| /// return code. The return code of a process can be queried via the |
| /// `ZX_INFO_PROCESS` request to [`zx_object_get_info()`]. |
| /// |
| /// ## Rights |
| /// |
| /// None. |
| /// |
| /// ## Return value |
| /// |
| /// `zx_process_exit()` does not return. |
| /// |
| /// ## Errors |
| /// |
| /// `zx_process_exit()` cannot fail. |
| /// |
| /// ## See also |
| /// |
| /// - [`zx_object_get_info()`] |
| /// - [`zx_process_create()`] |
| /// |
| /// [`zx_object_get_info()`]: object_get_info.md |
| /// [`zx_process_create()`]: process_create.md |
| @noreturn |
| strict Exit(struct { |
| retcode int64; |
| }); |
| |
| /// ## Summary |
| /// |
| /// Create a new process. |
| /// |
| /// ## Declaration |
| /// |
| /// ```c |
| /// #include <zircon/syscalls.h> |
| /// |
| /// zx_status_t zx_process_create(zx_handle_t job, |
| /// const char* name, |
| /// size_t name_size, |
| /// uint32_t options, |
| /// zx_handle_t* proc_handle, |
| /// zx_handle_t* vmar_handle); |
| /// ``` |
| /// |
| /// ## Description |
| /// |
| /// `zx_process_create()` creates a new process. |
| /// |
| /// Upon success, handles for the new process and the root of its address space |
| /// are returned. The thread will not start executing until [`zx_process_start()`] is |
| /// called. |
| /// |
| /// *name* is silently truncated to a maximum of `ZX_MAX_NAME_LEN-1` characters. |
| /// |
| /// When the last handle to a process is closed, the process is destroyed. |
| /// |
| /// Process handles may be waited on and will assert the signal |
| /// `ZX_PROCESS_TERMINATED` when the process exits. |
| /// |
| /// *job* is the controlling [job object](/docs/reference/kernel_objects/job.md) for the new |
| /// process, which will become a child of that job. |
| /// |
| /// *options* can contain zero or the following flag: |
| /// |
| /// - `ZX_PROCESS_SHARED` to create a process that can share its address space with another |
| /// process. Processes created with this flag can be passed to `zx_process_create_shared()`. |
| /// |
| /// ## Rights |
| /// |
| /// *job* must be of type `ZX_OBJ_TYPE_JOB` and have `ZX_RIGHT_MANAGE_PROCESS`. |
| /// |
| /// Caller job policy must allow `ZX_POL_NEW_PROCESS`. |
| /// |
| /// ## Return value |
| /// |
| /// On success, `zx_process_create()` returns `ZX_OK`, a handle to the new process |
| /// (via *proc_handle*), and a handle to the root of its address space (via |
| /// *vmar_handle*). In the event of failure, a negative error value is returned. |
| /// |
| /// ## Errors |
| /// |
| /// `ZX_ERR_BAD_HANDLE` *job* is not a valid handle. |
| /// |
| /// `ZX_ERR_WRONG_TYPE` *job* is not a job handle. |
| /// |
| /// `ZX_ERR_ACCESS_DENIED` *job* does not have the `ZX_RIGHT_WRITE` right |
| /// (only when not `ZX_HANDLE_INVALID`). |
| /// |
| /// `ZX_ERR_INVALID_ARGS` *name*, *proc_handle*, or *vmar_handle* was an invalid pointer, |
| /// or *options* contained invalid options. |
| /// |
| /// `ZX_ERR_NO_MEMORY` Failure due to lack of memory. |
| /// There is no good way for userspace to handle this (unlikely) error. |
| /// In a future build this error will no longer occur. |
| /// |
| /// `ZX_ERR_BAD_STATE` The job object is in the dead state. |
| /// |
| /// ## See also |
| /// |
| /// - [`zx_handle_close()`] |
| /// - [`zx_handle_duplicate()`] |
| /// - [`zx_job_create()`] |
| /// - [`zx_object_wait_async()`] |
| /// - [`zx_object_wait_many()`] |
| /// - [`zx_object_wait_one()`] |
| /// - [`zx_process_create_shared()`] |
| /// - [`zx_process_start()`] |
| /// - [`zx_task_kill()`] |
| /// - [`zx_thread_create()`] |
| /// - [`zx_thread_exit()`] |
| /// - [`zx_thread_start()`] |
| /// |
| /// [`zx_handle_close()`]: handle_close.md |
| /// [`zx_handle_duplicate()`]: handle_duplicate.md |
| /// [`zx_job_create()`]: job_create.md |
| /// [`zx_object_wait_async()`]: object_wait_async.md |
| /// [`zx_object_wait_many()`]: object_wait_many.md |
| /// [`zx_object_wait_one()`]: object_wait_one.md |
| /// [`zx_process_create_shared()`]: process_create_shared.md |
| /// [`zx_process_start()`]: process_start.md |
| /// [`zx_task_kill()`]: task_kill.md |
| /// [`zx_thread_create()`]: thread_create.md |
| /// [`zx_thread_exit()`]: thread_exit.md |
| /// [`zx_thread_start()`]: thread_start.md |
| strict Create(resource struct { |
| job Handle:JOB; |
| name vector<uchar>:MAX_NAME_LEN; |
| options uint32; |
| }) -> (resource struct { |
| proc_handle Handle:PROCESS; |
| vmar_handle Handle:VMAR; |
| }) error Status; |
| |
| /// ## Summary |
| /// |
| /// Create a new process that can share part of its address space with other processes. |
| /// |
| /// ## Declaration |
| /// |
| /// ```c |
| /// #include <zircon/syscalls.h> |
| /// |
| /// zx_status_t zx_process_create_shared(zx_handle_t shared_proc, |
| /// uint32_t options, |
| /// const char* name, |
| /// size_t name_size, |
| /// zx_handle_t* proc_handle, |
| /// zx_handle_t* restricted_vmar_handle); |
| /// ``` |
| /// |
| /// ## Description |
| /// |
| /// `zx_process_create_shared()` creates a new process that shares part of its address space |
| /// with `shared_proc`. The created process will be added to the same job as `shared_proc`. |
| /// |
| /// `shared_proc` must have been created with `ZX_PROCESS_SHARED`, or via |
| /// `zx_process_create_shared()`. |
| /// |
| /// The address space of the created process is split in two: the *shared* portion which is |
| /// shared with `shared_proc`, and the *restricted* portion which is private to the created |
| /// process. Each thread in the process begins executing with the shared portion active. |
| /// |
| /// For more detail, see [`zx_process_create()`]. |
| /// |
| /// ## Rights |
| /// |
| /// *shared_proc* must be of type `ZX_OBJ_TYPE_PROCESS` and have `ZX_RIGHT_MANAGE_PROCESS`. |
| /// |
| /// See [`zx_process_create()`]. |
| /// |
| /// ## Return value |
| /// |
| /// On success, `zx_process_create_shared()` returns `ZX_OK`, a handle to the new process |
| /// (via *proc_handle*), and a handle to the root of its restricted address space (via |
| /// *restricted_vmar_handle*). In the event of failure, a negative error value is returned. |
| /// |
| /// For more detail, see [`zx_process_create()`]. |
| /// |
| /// ## Errors |
| /// |
| /// `ZX_ERR_INVALID_ARGS` *shared_proc* is a valid handle, but pointed to a process that |
| /// was not created via `zx_process_create_shared()`, or `zx_process_create()` with |
| /// `ZX_PROCESS_SHARED`. |
| /// |
| /// `ZX_ERR_BAD_HANDLE` *shared_proc* is not a valid handle. |
| /// |
| /// `ZX_ERR_WRONG_TYPE` *shared_proc* is not a process handle. |
| /// |
| /// `ZX_ERR_BAD_STATE` *shared_proc* is a valid handle but the shared state is no longer valid |
| /// (likely due to all processes sharing the state terminating). |
| /// |
| /// `ZX_ERR_ACCESS_DENIED` *shared_proc* does not have the `ZX_RIGHT_MANAGE_PROCESS` right |
| /// (only when not `ZX_HANDLE_INVALID`). |
| /// |
| /// For other errors, see [`zx_process_create()`]. |
| /// |
| /// ## See also |
| /// |
| /// - [`zx_process_create()`] |
| /// |
| /// [`zx_process_create()`]: process_create.md |
| @next |
| strict CreateShared(resource struct { |
| shared_proc Handle:PROCESS; |
| options uint32; |
| name vector<uchar>:MAX_NAME_LEN; |
| }) -> (resource struct { |
| proc_handle Handle:PROCESS; |
| restricted_vmar_handle Handle:VMAR; |
| }) error Status; |
| |
| /// ## Summary |
| /// |
| /// Start execution on a process. |
| /// |
| /// ## Declaration |
| /// |
| /// ```c |
| /// #include <zircon/syscalls.h> |
| /// |
| /// zx_status_t zx_process_start(zx_handle_t handle, |
| /// zx_handle_t thread, |
| /// zx_vaddr_t entry, |
| /// zx_vaddr_t stack, |
| /// zx_handle_t arg1, |
| /// uintptr_t arg2); |
| /// ``` |
| /// |
| /// ## Description |
| /// |
| /// `zx_process_start()` is similar to [`zx_thread_start()`], but is used for the |
| /// purpose of starting the first thread in a process. |
| /// |
| /// `zx_process_start()` causes a thread to begin execution at the program |
| /// counter specified by *entry* and with the stack pointer set to *stack*. |
| /// The arguments *arg1* and *arg2* are arranged to be in the architecture |
| /// specific registers used for the first two arguments of a function call |
| /// before the thread is started. All other registers are zero upon start. |
| /// |
| /// The first argument (*arg1*) is a handle, which will be transferred from |
| /// the process of the caller to the process being started, and an |
| /// appropriate handle value will be placed in arg1 for the newly started |
| /// thread. If `zx_process_start()` returns an error, *arg1* is closed rather |
| /// than transferred to the process being started. |
| /// |
| /// Alternatively, *arg1* can be `ZX_HANDLE_INVALID` instead of a handle. |
| /// In this case the process starts with `ZX_HANDLE_INVALID` (i.e. zero) |
| /// in its first argument register instead of a handle. This means there |
| /// are *no* handles in the process and *can never* be any handles to any |
| /// objects shared outside the process. `zx_process_start()` is the only |
| /// way to transfer a handle into a process that doesn't involve the process |
| /// making some system call using a handle it already has (*arg1* is usually |
| /// the "bootstrap" handle). A process with no handles can make the few |
| /// system calls that don't require a handle, such as [`zx_process_exit()`], |
| /// if it's been provided with a vDSO mapping. It can create new kernel |
| /// objects with system calls that don't require a handle, such as |
| /// [`zx_vmo_create()`], but there is no way to make use of those objects |
| /// without more handles and no way to transfer them outside the process. |
| /// Its only means of communication is via the memory mapped into its |
| /// address space by others. |
| /// |
| /// ## Rights |
| /// |
| /// *handle* must be of type `ZX_OBJ_TYPE_PROCESS` and have `ZX_RIGHT_WRITE`. |
| /// |
| /// *thread* must be of type `ZX_OBJ_TYPE_THREAD` and have `ZX_RIGHT_WRITE`. |
| /// |
| /// *arg1* must have `ZX_RIGHT_TRANSFER`. |
| /// |
| /// ## Return value |
| /// |
| /// `zx_process_start()` returns `ZX_OK` on success. |
| /// In the event of failure, a negative error value is returned. |
| /// |
| /// ## Errors |
| /// |
| /// `ZX_ERR_BAD_HANDLE` *process* or *thread* or *arg1* is not a valid handle. |
| /// |
| /// `ZX_ERR_WRONG_TYPE` *process* is not a process handle or *thread* is |
| /// not a thread handle. |
| /// |
| /// `ZX_ERR_ACCESS_DENIED` The handle *thread* lacks `ZX_RIGHT_WRITE` or *thread* |
| /// does not belong to *process*, or the handle *process* lacks `ZX_RIGHT_WRITE` or |
| /// *arg1* lacks `ZX_RIGHT_TRANSFER`. |
| /// |
| /// `ZX_ERR_BAD_STATE` *process* is already running or has exited. |
| /// |
| /// `ZX_ERR_INVALID_ARGS` *entry* is not a userspace address, is not a |
| /// canonical address, or is not `0`. |
| /// |
| /// ## See also |
| /// |
| /// - [`zx_handle_close()`] |
| /// - [`zx_handle_duplicate()`] |
| /// - [`zx_object_wait_async()`] |
| /// - [`zx_object_wait_many()`] |
| /// - [`zx_object_wait_one()`] |
| /// - [`zx_process_create()`] |
| /// - [`zx_thread_create()`] |
| /// - [`zx_thread_exit()`] |
| /// - [`zx_thread_start()`] |
| /// |
| /// [`zx_handle_close()`]: handle_close.md |
| /// [`zx_handle_duplicate()`]: handle_duplicate.md |
| /// [`zx_object_wait_async()`]: object_wait_async.md |
| /// [`zx_object_wait_many()`]: object_wait_many.md |
| /// [`zx_object_wait_one()`]: object_wait_one.md |
| /// [`zx_process_create()`]: process_create.md |
| /// [`zx_process_exit()`]: process_exit.md |
| /// [`zx_thread_create()`]: thread_create.md |
| /// [`zx_thread_exit()`]: thread_exit.md |
| /// [`zx_thread_start()`]: thread_start.md |
| /// [`zx_vmo_create()`]: vmo_create.md |
| strict Start(resource struct { |
| handle Handle:PROCESS; |
| thread Handle:THREAD; |
| entry Vaddr; |
| stack Vaddr; |
| @release |
| arg1 Handle; |
| arg2 uintptr64; |
| }) -> () error Status; |
| |
| /// ## Summary |
| /// |
| /// Read from the given process's address space. |
| /// |
| /// ## Declaration |
| /// |
| /// ```c |
| /// #include <zircon/syscalls.h> |
| /// |
| /// zx_status_t zx_process_read_memory(zx_handle_t handle, |
| /// zx_vaddr_t vaddr, |
| /// void* buffer, |
| /// size_t buffer_size, |
| /// size_t* actual); |
| /// ``` |
| /// |
| /// ## Description |
| /// |
| /// `zx_process_read_memory()` attempts to read memory of the specified process. |
| /// |
| /// This function will eventually be replaced with something VMO-centric. |
| /// |
| /// *vaddr* the address of the block of memory to read. |
| /// |
| /// *buffer* pointer to a user buffer to read bytes into. |
| /// |
| /// *buffer_size* number of bytes to attempt to read. *buffer* buffer must be large |
| /// enough for at least this many bytes. *buffer_size* must be greater than zero |
| /// and less than or equal to 64MB. |
| /// |
| /// *actual* the actual number of bytes read is stored here. Less bytes than |
| /// requested may be returned if *vaddr*+*buffer_size* extends beyond the memory |
| /// mapped in the process. |
| /// |
| /// ## Rights |
| /// |
| /// *handle* must be of type `ZX_OBJ_TYPE_PROCESS` and have `ZX_RIGHT_READ` and have `ZX_RIGHT_WRITE`. |
| /// |
| /// ## Return value |
| /// |
| /// `zx_process_read_memory()` returns `ZX_OK` on success. |
| /// In the event of failure, a negative error value is returned, and the number of |
| /// bytes written to *buffer* is undefined. |
| /// |
| /// ## Errors |
| /// |
| /// `ZX_ERR_ACCESS_DENIED` *handle* does not have the `ZX_RIGHT_READ` right |
| /// or |
| /// `ZX_WRITE_RIGHT` is needed for historical reasons. |
| /// |
| /// `ZX_ERR_BAD_HANDLE` *handle* is not a valid handle. |
| /// |
| /// `ZX_ERR_BAD_STATE` the process's memory is not accessible (e.g., |
| /// the process is being terminated), |
| /// or the requested memory is not cacheable. |
| /// |
| /// `ZX_ERR_INVALID_ARGS` *buffer* is an invalid pointer or NULL, |
| /// or *buffer_size* is zero or greater than 64MB. |
| /// |
| /// `ZX_ERR_NOT_FOUND` if the process does not have any memory at the |
| /// requested address or `ZX_ERR_OUT_OF_RANGE` if the offset corresponding |
| /// to *vaddr* within the mapped VMO is greater than or equal to the VMO |
| /// size. These error codes are consistent with the error code that would be |
| /// generated by a page fault at the same address (i.e. the *synth_code* in |
| /// the page fault's exception report). |
| /// |
| /// `ZX_ERR_WRONG_TYPE` *handle* is not a process handle. |
| /// |
| /// ## See also |
| /// |
| /// - [`zx_process_write_memory()`] |
| /// |
| /// [`zx_process_write_memory()`]: process_write_memory.md |
| strict ReadMemory(resource struct { |
| handle Handle:PROCESS; |
| vaddr Vaddr; |
| }) -> (struct { |
| @voidptr |
| buffer vector<byte>:MAX; |
| actual usize64; |
| }) error Status; |
| |
| /// ## Summary |
| /// |
| /// Write into the given process's address space. |
| /// |
| /// ## Declaration |
| /// |
| /// ```c |
| /// #include <zircon/syscalls.h> |
| /// |
| /// zx_status_t zx_process_write_memory(zx_handle_t handle, |
| /// zx_vaddr_t vaddr, |
| /// const void* buffer, |
| /// size_t buffer_size, |
| /// size_t* actual); |
| /// ``` |
| /// |
| /// ## Description |
| /// |
| /// `zx_process_write_memory()` attempts to write memory of the specified process. |
| /// |
| /// This function will eventually be replaced with something VMO-centric. |
| /// |
| /// *vaddr* the address of the block of memory to write. |
| /// |
| /// *buffer* pointer to a user buffer containing the bytes to write. |
| /// |
| /// *buffer_size* number of bytes to attempt to write. *buffer* buffer must be |
| /// large enough for at least this many bytes. *buffer_size* must be greater than |
| /// zero and less than or equal to 64MB. |
| /// |
| /// *actual_size* the actual number of bytes written is stored here. Less bytes |
| /// than requested may be returned if *vaddr*+*buffer_size* extends beyond the |
| /// memory mapped in the process. |
| /// |
| /// To use the `zx_process_write_memory()` function, you must specify |
| /// `kernel.enable-debugging-syscalls=true` on the kernel command line. Otherwise, |
| /// the function returns `ZX_ERR_NOT_SUPPORTED`. |
| /// |
| /// ## Rights |
| /// |
| /// *handle* must be of type `ZX_OBJ_TYPE_PROCESS` and have `ZX_RIGHT_WRITE`. |
| /// |
| /// ## Return value |
| /// |
| /// `zx_process_write_memory()` returns `ZX_OK` on success. |
| /// In the event of failure, a negative error value is returned, and the number of |
| /// bytes written to *buffer* is undefined. |
| /// |
| /// ## Errors |
| /// |
| /// `ZX_ERR_ACCESS_DENIED` *handle* does not have the `ZX_RIGHT_WRITE` right or |
| /// the address range to write falls into a protected area like the vDSO. |
| /// |
| /// `ZX_ERR_BAD_HANDLE` *handle* is not a valid handle. |
| /// |
| /// `ZX_ERR_BAD_STATE` the process's memory is not accessible (e.g., |
| /// the process is being terminated), |
| /// or the requested memory is not cacheable. |
| /// |
| /// `ZX_ERR_INVALID_ARGS` *buffer* is an invalid pointer or NULL, |
| /// or *buffer_size* is zero or greater than 64MB. |
| /// |
| /// `ZX_ERR_NOT_FOUND` if the process does not have any memory at the |
| /// requested address or `ZX_ERR_OUT_OF_RANGE` if the offset corresponding |
| /// to *vaddr* within the mapped VMO is greater than or equal to the VMO |
| /// size. These error codes are consistent with the error code that would be |
| /// generated by a page fault at the same address (i.e. the *synth_code* in |
| /// the page fault's exception report). |
| /// |
| /// `ZX_ERR_NOT_SUPPORTED` `kernel.enable-debugging-syscalls` is not set to `true` |
| /// on the kernel command line. |
| /// |
| /// `ZX_ERR_WRONG_TYPE` *handle* is not a process handle. |
| /// |
| /// ## See also |
| /// |
| /// - [`zx_process_read_memory()`] |
| /// |
| /// [`zx_process_read_memory()`]: process_read_memory.md |
| strict WriteMemory(resource struct { |
| handle Handle:PROCESS; |
| vaddr Vaddr; |
| @voidptr |
| buffer vector<byte>:MAX; |
| }) -> (struct { |
| actual usize64; |
| }) error Status; |
| }; |