// 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 fuchsia.process.init;

using fuchsia.ldsvc;
using fuchsia.mem;
using fuchsia.process;

/// The protocol used to initialize processes.
protocol Bootstrap {
    /// Provide the interpreter (in the sense of PT_INTERP) with the capabilities and information it
    /// needs to load code.
    ///
    /// This method must be called at most once, and must come before all other method calls if it
    /// is sent at all.
    InitializeInterpreter(InterpreterInfo info);

    /// Provide the program with the capabilities and information it needs for runtime support.
    ///
    /// This method must be called exactly once. It must proceed all other messages except the
    /// optional call to `InitializeInterpreter`.
    InitializeRuntime(RuntimeInfo info);

    /// Add the given handles to set of startup handles for the process.
    ///
    /// Must be called after `InitializeInterpreter` and `InitializeRuntime`, and before
    /// `Start`. Can be called multiple times.
    AddHandles(vector<fuchsia.process.HandleInfo>:64 handles);

    /// Add the given names to the namespace of the new process.
    ///
    /// Must be called after `InitializeInterpreter` and `InitializeRuntime`, and before
    /// `Start`. Can be called multiple times.
    AddNames(vector<fuchsia.process.NameInfo>:64 names);

    /// Start the process.
    ///
    /// This must be called last, and exactly once, after initialization and after all handles and
    /// names have been added.
    ///
    ///  * argc: The number of arguments in `argv`.
    ///  * environc: The number of variables in the `environ`.
    ///
    /// The command line arguments and environment variables for the process.
    ///
    /// Each byte sequence in `data` is terminated by a single 0x00 byte. The
    /// first `argc` byte sequences in the payload are the command line
    /// arguments. The next `environc` byte sequences are the environment
    /// variables.
    Start(uint32 argc, uint32 environc, fuchsia.mem.Data data);
};

struct RuntimeInfo {
    /// The process being bootstrapped.
    zx.handle:PROCESS process;

    /// The initial thread of the process being bootstrapped.
    zx.handle:THREAD initial_thread;

    /// REVIEW: What VMAR(s) does the program runtime receive?
    zx.handle:VMAR vmars;
};

/// Flags to modulate the behavior of the interpreter for a process.
bits InterpreterFlags : uint64 {
    DEBUG = 0x1;
    TRACE = 0x2;
};

/// Information need by the interpreter to initialize a process.
struct InterpreterInfo {
    /// Flags to modulate the behavior of the interpreter.
    /// REVIEW: Can this be removed?
    InterpreterFlags flags;

    /// The VMAR into which the interpreter should load code.
    zx.handle:VMAR target_vmar;

    /// The VMAR into which the interpreter was loaded.
    zx.handle:VMAR interpreter_vmar;

    /// The executable to load.
    zx.handle:VMO executable;

    /// The shared library loader to use for the process.
    fuchsia.ldsvc.Loader loader;
};
