Create a new process # Input - Pointer to ELF binary data (Arg1, syscall RDI) - Length of ELF binary data (high 32 bits of syscall_id) - STDIN & STDOUT rendezvous handles (Arg2, syscall RSI) - Pointer to parameter string (Arg3, syscall RDX) - Length of parameter string (16 bits of syscall_id) - Flags controlling permissions (8 bits of syscall_id) - I/O privileges: EXEC_PERM_IO - Thread fork? -
(
context_ptr: *mut Context,
syscall_id: u64,
bin: *const u8, // Binary data (ELF format)
stdio: u64, // The stdin/stdout rendezvous handles
param: *const u8)
| 580 | /// - Exec? |
| 581 | /// - Interrupts |
| 582 | fn sys_exec( |
| 583 | context_ptr: *mut Context, |
| 584 | syscall_id: u64, |
| 585 | bin: *const u8, // Binary data (ELF format) |
| 586 | stdio: u64, // The stdin/stdout rendezvous handles |
| 587 | param: *const u8) { // String specifying the process VFS, command-line arguments, and environment variales |
| 588 | |
| 589 | let context = unsafe {&mut (*context_ptr)}; |
| 590 | |
| 591 | // Low 8 bits of syscall_id contain syscall number |
| 592 | // Remaining 48 bits are used to store the length |
| 593 | // of the bin and param parameters, and the |
| 594 | // capability flags. |
| 595 | let bin_length = syscall_id >> 32; // High 32 bits |
| 596 | let param_length = (syscall_id >> 16) & 0xFFFF; |
| 597 | let flags = (syscall_id >> 8) & 0xFF; |
| 598 | |
| 599 | // Handles |
| 600 | let stdin_handle = (stdio >> 32) & 0xFFFF_FFFF; // High 32 bits |
| 601 | let stdout_handle = stdio & 0xFFFF_FFFF; // Low 32 bits |
| 602 | |
| 603 | if let Some(mut thread) = process::take_current_thread() { |
| 604 | thread.set_context(context_ptr); |
| 605 | |
| 606 | if bin_length == 0 { |
| 607 | // No data |
| 608 | thread.return_error(SYSCALL_ERROR_PARAM); |
| 609 | process::set_current_thread(thread); |
| 610 | return; |
| 611 | } |
| 612 | |
| 613 | // Get the Rendezvous handles for stdin & stdout |
| 614 | let stdin = if let Some(rdv) = thread.take_rendezvous(stdin_handle) { |
| 615 | rdv |
| 616 | } else { |
| 617 | // Invalid handle |
| 618 | thread.return_error(SYSCALL_ERROR_INVALID_HANDLE); |
| 619 | process::set_current_thread(thread); |
| 620 | return; |
| 621 | }; |
| 622 | |
| 623 | let stdout = if let Some(rdv) = thread.take_rendezvous(stdout_handle) { |
| 624 | rdv |
| 625 | } else { |
| 626 | // Invalid handle |
| 627 | thread.return_error(SYSCALL_ERROR_INVALID_HANDLE); |
| 628 | process::set_current_thread(thread); |
| 629 | return; |
| 630 | }; |
| 631 | |
| 632 | // Check I/O privileges. Caller must have I/O privileges |
| 633 | let io_privileges = (flags & EXEC_PERM_IO == EXEC_PERM_IO) && |
| 634 | ((context.rflags & 0x3000) == 0x3000); |
| 635 | |
| 636 | // Get the arguments and VFS for this process |
| 637 | |
| 638 | let (mounts, args, envs) = if param_length == 0 { |
| 639 | // Default is shared VFS and no arguments |
no test coverage detected