Overview

The execve() system call executes a new program, replacing the current process image. It loads ELF executables from the filesystem, sets up the execution environment, and transfers control to the program entry point.

✅ Fully Implemented

Function Signature

int execve(const char *pathname, char *const argv[], char *const envp[]);

Parameters

  • pathname - Path to executable file (e.g., "/usr/lib/nodejs/bin/node")
  • argv - Array of command-line argument strings (NULL-terminated)
  • envp - Array of environment variable strings (NULL-terminated)

Return Value

  • On success: Does not return (process is replaced)
  • On error: Returns -1 and sets errno

Implementation

Main Handler

Function: syscall_execve()

System call handler registered as syscall #11 (Linux-compatible).

Execution Flow

  1. Load ELF File: Uses elf_load_file() to read executable from filesystem
  2. Get Entry Point: Extracts program entry point from ELF header
  3. Count Arguments: Counts argc from argv array
  4. Set Up Stack: Allocates stack and sets up argc, argv, envp
  5. Execute Program: Calls elf_execute() to run the program
  6. Cleanup: Frees resources if execution fails

Process Spawning

Function: execve_spawn_process()

Creates a new process and executes a program in it:

  1. Creates new process via create_process()
  2. Loads ELF file into new process
  3. Sets up process address space
  4. Sets up process stack
  5. Executes program in new process context
  6. Returns new process ID

Address Space Setup

Function: execve_setup_address_space()

Sets up the process virtual address space (currently a placeholder for future implementation):

  • Create new page directory for process
  • Map ELF segments to their virtual addresses
  • Set up stack mapping
  • Set up heap mapping
  • Update process CR3 register

Stack Building Utilities

Build Argument Vector

Function: execve_build_argv_stack()

Builds the argument vector on the program stack:

  1. Counts arguments in argv array
  2. Allocates space for argv pointers on stack
  3. Copies argument strings to stack
  4. Sets up argv pointer array
  5. Adds NULL terminator

Build Environment Vector

Function: execve_build_envp_stack()

Builds the environment variable vector on the program stack:

  1. Counts environment variables in envp array
  2. Allocates space for envp pointers on stack
  3. Copies environment strings to stack
  4. Sets up envp pointer array
  5. Adds NULL terminator

Integration

With ELF Loader

execve() uses the ELF loader to:

  • Load ELF files from filesystem
  • Parse ELF headers
  • Load program segments
  • Get entry point address
  • Execute the program

With Filesystem

execve() uses the filesystem to:

  • Open executable files by path
  • Read ELF file data
  • Handle file errors

With Process Management

execve() integrates with:

  • Process creation (create_process())
  • Process state management
  • Process address space setup

Usage Example

// Execute a program
char *argv[] = {"/usr/lib/nodejs/bin/node", "app.js", NULL};
char *envp[] = {"PATH=/usr/bin", "HOME=/root", NULL};

int result = execve("/usr/lib/nodejs/bin/node", argv, envp);
if (result == -1) {
    // Error: program failed to execute
    perror("execve");
}

Error Handling

execve() can fail with:

  • ENOENT - File not found
  • EACCES - Permission denied
  • ENOMEM - Out of memory
  • ENOEXEC - Not an executable file
  • EFAULT - Invalid pointer

Build System

The execve implementation is built as part of the process management system:

cd kernel/process
make

This compiles execve.asm along with other process management files.

System Call Registration

execve() is registered in the system call table as syscall #11 (Linux-compatible):

// In kernel/syscalls/syscall_table.asm
mov eax, 11  ; SYS_EXECVE
mov ebx, syscall_execve
call register_syscall

Related Documentation