// 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;
};
