Trait AbiModule

Source
pub trait AbiModule: 'static {
    // Required methods
    fn name() -> &'static str
       where Self: Sized;
    fn get_name(&self) -> String;
    fn clone_boxed(&self) -> Box<dyn AbiModule>;
    fn handle_syscall(
        &mut self,
        trapframe: &mut Trapframe,
    ) -> Result<usize, &'static str>;
    fn execute_binary(
        &self,
        file_object: &KernelObject,
        argv: &[&str],
        envp: &[&str],
        task: &mut Task,
        trapframe: &mut Trapframe,
    ) -> Result<(), &'static str>;

    // Provided methods
    fn can_execute_binary(
        &self,
        _file_object: &KernelObject,
        _file_path: &str,
        _current_abi: Option<&dyn AbiModule>,
    ) -> Option<u8> { ... }
    fn initialize_from_existing_handles(
        &self,
        _task: &mut Task,
    ) -> Result<(), &'static str> { ... }
    fn normalize_env_to_scarlet(&self, _envp: &mut Vec<String>) { ... }
    fn denormalize_env_from_scarlet(&self, _envp: &mut Vec<String>) { ... }
    fn get_default_cwd(&self) -> &str { ... }
    fn setup_overlay_environment(
        &self,
        target_vfs: &Arc<VfsManager>,
        base_vfs: &Arc<VfsManager>,
        system_path: &str,
        config_path: &str,
    ) -> Result<(), &'static str> { ... }
    fn setup_shared_resources(
        &self,
        _target_vfs: &Arc<VfsManager>,
        _base_vfs: &Arc<VfsManager>,
    ) -> Result<(), &'static str> { ... }
}
Expand description

ABI module trait.

This trait defines the interface for ABI modules in the Scarlet kernel. ABI modules are responsible for handling system calls and providing the necessary functionality for different application binary interfaces.

Each ABI module must implement Clone to support task cloning with independent ABI state per task.

Required Methods§

Source

fn name() -> &'static str
where Self: Sized,

Source

fn get_name(&self) -> String

Source

fn clone_boxed(&self) -> Box<dyn AbiModule>

Clone this ABI module into a boxed trait object

This method enables cloning ABI modules as trait objects, allowing each task to have its own independent ABI instance.

Source

fn handle_syscall( &mut self, trapframe: &mut Trapframe, ) -> Result<usize, &'static str>

Source

fn execute_binary( &self, file_object: &KernelObject, argv: &[&str], envp: &[&str], task: &mut Task, trapframe: &mut Trapframe, ) -> Result<(), &'static str>

Binary execution (each ABI supports its own binary format)

This method actually executes a binary that has already been verified by can_execute_binary. Use file_object.as_file() to access FileObject, and call ABI-specific loaders (ELF, PE, etc.) to load and execute the binary.

Environment variables are passed directly as envp array, not stored in task.

§Arguments
  • file_object - Binary file to execute (already opened, in KernelObject format)
  • argv - Command line arguments
  • envp - Environment variables in “KEY=VALUE” format
  • task - Target task (modified by this method)
  • trapframe - Execution context (modified by this method)
§Implementation Notes
  • Use file_object.as_file() to get FileObject
  • Use ABI-specific loaders (e.g., task::elf_loader)
  • Environment variables are passed directly as envp parameter
  • Set task’s memory space, registers, and entry point
  • Update trapframe registers (PC, SP) for the new process
  • Recommended to restore original state on execution failure
§Return Value Handling in Syscall Context

The Scarlet syscall mechanism works as follows:

  1. sys_execve() calls this method
  2. sys_execve() returns usize to syscall_handler()
  3. syscall_handler() returns Ok(usize) to syscall_dispatcher()
  4. syscall_dispatcher() returns Ok(usize) to trap handler
  5. Trap handler calls trapframe.set_return_value(usize) automatically

Provided Methods§

Source

fn can_execute_binary( &self, _file_object: &KernelObject, _file_path: &str, _current_abi: Option<&dyn AbiModule>, ) -> Option<u8>

Determine if a binary can be executed by this ABI and return confidence

This method reads binary content directly from the file object and executes ABI-specific detection logic (magic bytes, header structure, entry point validation, etc.).

§Arguments
  • file_object - Binary file to check (in KernelObject format)
  • file_path - File path (for auxiliary detection like file extensions)
  • current_abi - Current task’s ABI reference for inheritance/compatibility decisions
§Returns
  • Some(confidence) - Confidence level (0-100) if executable by this ABI
  • None - Not executable by this ABI
§Implementation Guidelines
  • Use file_object.as_file() to access FileObject
  • Use StreamOps::read() to directly read file content
  • Check ABI-specific magic bytes and header structures
  • Validate entry point and architecture compatibility
  • Consider current_abi for inheritance/compatibility bonus (same ABI = higher confidence)
  • Return confidence based on how well the binary matches this ABI
  • No need for artificial score limitations - let each ABI decide its own confidence
  • 0-30: Basic compatibility (correct magic bytes, architecture)
  • 31-60: Good match (+ file extension, path hints, valid entry point)
  • 61-80: Strong match (+ ABI-specific headers, symbols, sections)
  • 81-100: Perfect match (+ same ABI inheritance, full validation)
§Example Scoring Strategy
let mut confidence = 0;
 
// Basic format check
if self.is_valid_format(file_object) { confidence += 30; }
 
// Entry point validation
if self.is_valid_entry_point(file_object) { confidence += 15; }
 
// File path hints
if file_path.contains(self.get_name()) { confidence += 15; }
 
// ABI inheritance bonus
if let Some(abi) = current_abi {
    if abi.get_name() == self.get_name() { confidence += 40; }
}
 
Some(confidence.min(100))
Source

fn initialize_from_existing_handles( &self, _task: &mut Task, ) -> Result<(), &'static str>

Handle conversion when switching ABIs

Source

fn normalize_env_to_scarlet(&self, _envp: &mut Vec<String>)

Convert environment variables from this ABI to Scarlet canonical format (in-place)

This method is called when switching from this ABI to another ABI. It should convert ABI-specific environment variables to a canonical Scarlet format that can then be converted to the target ABI.

Uses in-place modification to avoid expensive allocations.

§Arguments
  • envp - Mutable reference to environment variables in “KEY=VALUE” format, will be modified to contain Scarlet canonical format
§Implementation Guidelines
  • Convert paths to absolute Scarlet namespace paths
  • Normalize variable names to Scarlet conventions
  • Remove ABI-specific variables that don’t translate
  • Ensure all paths are absolute and start with /
  • Modify the vector in-place for efficiency
Source

fn denormalize_env_from_scarlet(&self, _envp: &mut Vec<String>)

Convert environment variables from Scarlet canonical format to this ABI’s format (in-place)

This method is called when switching to this ABI from another ABI. It should convert canonical Scarlet environment variables to this ABI’s specific format and namespace.

Uses in-place modification to avoid expensive allocations.

§Arguments
  • envp - Mutable reference to environment variables in Scarlet canonical format, will be modified to contain this ABI’s format
Source

fn get_default_cwd(&self) -> &str

Get default working directory for this ABI

Source

fn setup_overlay_environment( &self, target_vfs: &Arc<VfsManager>, base_vfs: &Arc<VfsManager>, system_path: &str, config_path: &str, ) -> Result<(), &'static str>

Setup overlay environment for this ABI (read-only base + writable layer)

Creates overlay filesystem with provided base VFS and paths. The TransparentExecutor is responsible for providing base_vfs, paths, and verifying that directories exist. This method assumes that required directories (/system/{abi}, /data/config/{abi}) have been prepared by the user/administrator as part of system setup.

§Arguments
  • target_vfs - VfsManager to configure with overlay filesystem
  • base_vfs - Base VFS containing system and config directories
  • system_path - Path to read-only base layer (e.g., “/system/scarlet”)
  • config_path - Path to writable persistence layer (e.g., “/data/config/scarlet”)
Source

fn setup_shared_resources( &self, _target_vfs: &Arc<VfsManager>, _base_vfs: &Arc<VfsManager>, ) -> Result<(), &'static str>

Setup shared resources accessible across all ABIs

Bind mounts common directories that should be shared from base VFS. The TransparentExecutor is responsible for providing base_vfs.

§Arguments
  • target_vfs - VfsManager to configure
  • base_vfs - Base VFS containing shared directories

Implementors§