blob: 0b45efe8785d497a7cbab05ce8603818079fe382 [file] [log] [blame]
// 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")
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
Exit(struct {
retcode int64;
});
// TODO(fxbug.dev/32803): job with ZX_RIGHT_WRITE is also accepted.
/// ## 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
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
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
Start(resource struct {
handle handle:PROCESS;
thread handle:THREAD;
entry vaddr;
stack vaddr;
@release
arg1 handle;
arg2 uintptr;
}) -> () 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_NO_MEMORY** the process does not have any memory at the
/// requested address.
///
/// **ZX_ERR_WRONG_TYPE** *handle* is not a process handle.
///
/// ## See also
///
/// - [`zx_process_write_memory()`]
///
/// [`zx_process_write_memory()`]: process_write_memory.md
ReadMemory(resource struct {
handle handle:PROCESS;
vaddr vaddr;
}) -> (struct {
@voidptr
buffer vector<byte>;
actual usize;
}) 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_NO_MEMORY** the process does not have any memory at the
/// requested address.
///
/// **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
WriteMemory(resource struct {
handle handle:PROCESS;
vaddr vaddr;
@voidptr
buffer vector<byte>;
}) -> (struct {
actual usize;
}) error status;
};