/// <summary>
        /// Allocate a new subregion
        /// </summary>
        /// <returns>
        /// <para>
        /// On success, Ok and the result parameter is set to the VirtualMemoryAddressRegion, on error,
        /// a different status code is returned and the result parameter is set to null.
        /// </para>
        ///    <list type="bullet">
        ///    <item>
        ///      <term>ErrBadHandle</term>
        ///      <description>
        ///        parent_vmar is not a valid handle.
        ///      </description>
        ///    </item>
        ///    <item>
        ///      <term>ErrWrongType</term>
        ///      <description>
        ///        parent_vmar is not a VMAR handle.
        ///      </description>
        ///    </item>
        ///    <item>
        ///      <term>ErrBadState</term>
        ///      <description>
        ///        parent_vmar refers to a destroyed VMAR.
        ///      </description>
        ///    </item>
        ///    <item>
        ///      <term>ErrInvalidArgs</term>
        ///      <description>
        ///        child_vmar or child_addr are not valid, offset is non-zero when ZX_VM_SPECIFIC is not given, offset and size describe an unsatisfiable allocation due to exceeding the region bounds, offset or size is not page-aligned, or size is 0.
        ///      </description>
        ///    </item>
        ///    <item>
        ///      <term>ErrNoMemory</term>
        ///      <description>
        ///        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.
        ///      </description>
        ///    </item>
        ///    <item>
        ///      <term>ErrAccessDenied</term>
        ///      <description>
        ///        Insufficient privileges to make the requested allocation.
        ///      </description>
        ///    </item>
        /// </list>
        /// </returns>
        /// <param name="parentVmar">Parent VMAR that will host this new VMAR.</param>
        /// <param name="options">
        /// <para>Options for creating the region.</para>
        ///    <list type="bullet">
        ///    <item>
        ///      <term>VmCompact</term>
        ///      <description>
        ///        A hint to the kernel that allocations and mappings within the newly created subregion should be kept close together. See the NOTES section below for discussion.
        ///      </description>
        ///    </item>
        ///    <item>
        ///      <term>VmSpecific</term>
        ///      <description>
        ///        Use the offset to place the mapping, invalid if vmar does not have the VmCanMapSpecific permission. offset is an offset relative to the base address of the parent region. It is an error to specify an address range that overlaps with another VMAR or mapping.
        ///      </description>
        ///    </item>
        ///    <item>
        ///      <term>VmCanMapSpecific</term>
        ///      <description>
        ///        The new VMAR can have subregions/mappings created with VmSpecific. It is NOT an error if the parent does not have VmCanMapSpecific permissions.
        ///      </description>
        ///    </item>
        ///    <item>
        ///      <term>VmCanMapRead</term>
        ///      <description>
        ///        The new VMAR can contain readable mappings. It is an error if the parent does not have VmCanMapRead permissions.
        ///      </description>
        ///    </item>
        ///    <item>
        ///      <term>VmCanMapWrite</term>
        ///      <description>
        ///        The new VMAR can contain writable mappings. It is an error if the parent does not have VmCanMapWrite permissions.
        ///      </description>
        ///    </item>
        ///    <item>
        ///      <term>VmCanMapExecute</term>
        ///      <description>
        ///        The new VMAR can contain executable mappings. It is an error if the parent does not have VmCanMapExecute permissions.
        ///      </description>
        ///    </item>
        /// </list>
        /// </param>
        /// <param name="offset">Offset, it must be zero if options does not have VmSpecific set.</param>
        /// <param name="size">Size for the region.</param>
        /// <param name="result">The newly created VirtualMemoryAddressRegion is returned in this parameter.</param>
        /// <remarks>
        /// <para>The address space occupied by a VMAR will remain allocated (within its parent VMAR) until the VMAR is destroyed by calling </para>
        /// <para>Note that just closing the VMAR's handle does not deallocate the address space occupied by the VMAR.</para>
        /// <para>Compact Flag: The kernel interprets this flag as a request to reduce sprawl in allocations. While this does not necessitate
        /// reducing the absolute entropy of the allocated addresses, there will potentially be a very high correlation between allocations.
        /// This is a trade-off that the developer can make to increase locality of allocations and reduce the number of page tables necessary,
        /// if they are willing to have certain addresses be more correlated.</para>
        /// </remarks>
        public static ZxStatus Allocate(VirtualMemoryAddressRegion parentVmar, ZxVmOption options, ulong offset, ulong size, out VirtualMemoryAddressRegion result)
        {
            uint   resultHandle;
            IntPtr address;
            var    ret = zx_vmar_allocate((uint)parentVmar.handle, options, offset, size, out resultHandle, out address);

            if (ret == ZxStatus.Ok)
            {
                result = new VirtualMemoryAddressRegion(resultHandle, address);
            }
            result = null;
            return(ret);
        }
        /// <summary>
        /// Creates a duplicate of the object with the specified rights, by requesting the kernel to duplicate the handle with those values
        /// </summary>
        /// <returns>
        ///    <list type="bullet">
        ///    <item>
        ///      <term>Ok</term>
        ///      <description>
        ///        and the duplicate in result
        ///      </description>
        ///    </item>
        ///    <item>
        ///      <term>ErrBadHandle</term>
        ///      <description>
        ///        handle isn't a valid handle.
        ///      </description>
        ///    </item>
        ///    <item>
        ///      <term>ErrInvalidArgs</term>
        ///      <description>
        ///        The rights requested are not a subset of handle rights or out is an invalid pointer.
        ///      </description>
        ///    </item>
        ///    <item>
        ///      <term>ErrAccessDenied</term>
        ///      <description>
        ///        handle does not have ZX_RIGHT_DUPLICATE and may not be duplicated.
        ///      </description>
        ///    </item>
        ///    <item>
        ///      <term>ErrNoMemory</term>
        ///      <description>
        ///        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.
        ///      </description>
        ///    </item>
        /// </list>
        /// </returns>
        /// <param name="rights">New desired access rights.</param>
        public ZxStatus Duplicate(ZxRights rights, out VirtualMemoryAddressRegion result)
        {
            uint rhandle;
            var  ret = zx_handle_duplicate((uint)handle, rights, out rhandle);

            if (ret == ZxStatus.Ok)
            {
                result = new VirtualMemoryAddressRegion(rhandle, address);
            }
            else
            {
                result = null;
            }
            return(ret);
        }
Пример #3
0
        /// <summary>
        /// Creates a new process.  Upon success, handles for the new process and the root of its address space are returned.   To start you must call Start().
        /// </summary>
        /// <returns>
        ///    <list type="bullet">
        ///    <item>
        ///      <term>Ok</term>
        ///      <description>
        ///        On success, a handle to the new process (via proc_handle), and a handle to the root of its address space (via vmar_handle).
        ///      </description>
        ///    </item>
        ///    <item>
        ///      <term>ErrBadHandle</term>
        ///      <description>
        ///        job is not a valid handle.
        ///      </description>
        ///    </item>
        ///    <item>
        ///      <term>ErrWrongType</term>
        ///      <description>
        ///        job is not a job handle.
        ///      </description>
        ///    </item>
        ///    <item>
        ///      <term>ErrAccessDenied</term>
        ///      <description>
        ///        job does not have the ZX_RIGHT_WRITE right (only when not ZX_HANDLE_INVALID).
        ///      </description>
        ///    </item>
        ///    <item>
        ///      <term>ErrInvalidArgs</term>
        ///      <description>
        ///        name, proc_handle, or vmar_handle was an invalid pointer, or options was non-zero.
        ///      </description>
        ///    </item>
        ///    <item>
        ///      <term>ErrNoMemory</term>
        ///      <description>
        ///        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.
        ///      </description>
        ///    </item>
        ///    <item>
        ///      <term>ErrBadState</term>
        ///      <description>
        ///        The job object is in the dead state.
        ///      </description>
        ///    </item>
        /// </list>
        /// </returns>
        /// <param name="name">Name for the new process.</param>
        /// <param name="process">On success, this contains the created Process, null on error.</param>
        /// <param name="vmar">On success, this contains the handle to the root address space, null on error..</param>
        /// <remarks>
        /// 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 for the new process, which will become a child of that job.
        /// </remarks>
        public ZxStatus CreateProcess(string name, out Process process, out VirtualMemoryAddressRegion vmar)
        {
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }
            uint processHandle, vmarHandle;
            var  ret = zx_process_create((uint)handle, name, (IntPtr)System.Text.Encoding.UTF8.GetBytes(name).Length, 0, out processHandle, out vmarHandle);

            if (ret != ZxStatus.Ok)
            {
                process = null;
                vmar    = null;
                return(ret);
            }
            process = new Process(processHandle, ownsHandle: true);
            vmar    = new VirtualMemoryAddressRegion(vmarHandle, (IntPtr)(-1));
            return(ZxStatus.Ok);
        }