pub trait AbiModule:
Send
+ Sync
+ 'static {
Show 22 methods
// Required methods
fn name() -> &'static str
where Self: Sized;
fn get_name(&self) -> String;
fn clone_boxed(&self) -> Box<dyn AbiModule + Send + Sync>;
fn handle_syscall(
&mut self,
trapframe: &mut Trapframe,
) -> Result<usize, &'static str>;
fn execute_binary(
&self,
file_object: &KernelObject,
argv: &[&str],
envp: &[&str],
task: &Task,
trapframe: &mut Trapframe,
) -> Result<(), &'static str>;
// Provided methods
fn on_task_cloned(
&mut self,
_parent_task: &Task,
_child_task: &Task,
_flags: CloneFlags,
) -> Result<(), &'static str> { ... }
fn on_task_exit(&mut self, _task: &Task) { ... }
fn get_task_namespace(&self) -> Arc<TaskNamespace> { ... }
fn can_execute_binary(
&self,
_file_object: &KernelObject,
_file_path: &str,
_current_abi: Option<&(dyn AbiModule + Send + Sync)>,
) -> Option<u8> { ... }
fn initialize_from_existing_handles(
&mut self,
_task: &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 choose_load_address(
&self,
_elf_type: u16,
_target: LoadTarget,
) -> Option<u64> { ... }
fn get_interpreter_path(&self, requested_interpreter: &str) -> String { ... }
fn get_runtime_config(
&self,
_file_object: &KernelObject,
_file_path: &str,
) -> Option<RuntimeConfig> { ... }
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> { ... }
fn handle_event(
&self,
_event: Event,
_target_task_id: u32,
) -> Result<(), &'static str> { ... }
fn set_tls_pointer(&mut self, _ptr: usize) { ... }
fn get_tls_pointer(&self) -> Option<usize> { ... }
fn set_clear_child_tid(&mut self, _ptr: usize) { ... }
}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§
fn name() -> &'static strwhere
Self: Sized,
fn get_name(&self) -> String
Sourcefn clone_boxed(&self) -> Box<dyn AbiModule + Send + Sync>
fn clone_boxed(&self) -> Box<dyn AbiModule + Send + Sync>
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.
fn handle_syscall( &mut self, trapframe: &mut Trapframe, ) -> Result<usize, &'static str>
Sourcefn execute_binary(
&self,
file_object: &KernelObject,
argv: &[&str],
envp: &[&str],
task: &Task,
trapframe: &mut Trapframe,
) -> Result<(), &'static str>
fn execute_binary( &self, file_object: &KernelObject, argv: &[&str], envp: &[&str], task: &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 argumentsenvp- Environment variables in “KEY=VALUE” formattask- 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:
- sys_execve() calls this method
- sys_execve() returns usize to syscall_handler()
- syscall_handler() returns Ok(usize) to syscall_dispatcher()
- syscall_dispatcher() returns Ok(usize) to trap handler
- Trap handler calls trapframe.set_return_value(usize) automatically
Provided Methods§
Sourcefn on_task_cloned(
&mut self,
_parent_task: &Task,
_child_task: &Task,
_flags: CloneFlags,
) -> Result<(), &'static str>
fn on_task_cloned( &mut self, _parent_task: &Task, _child_task: &Task, _flags: CloneFlags, ) -> Result<(), &'static str>
Hook invoked after Task::clone_task creates the child
Sourcefn on_task_exit(&mut self, _task: &Task)
fn on_task_exit(&mut self, _task: &Task)
Hook invoked as part of Task::exit cleanup for the current task
ABI modules can perform per-ABI teardown such as waking futex waiters, clearing TLS/robust-list pointers, or delivering exit-related signals.
Sourcefn get_task_namespace(&self) -> Arc<TaskNamespace>
fn get_task_namespace(&self) -> Arc<TaskNamespace>
Get the task namespace for this ABI.
This allows each ABI to have its own namespace for task IDs. By default, returns the root namespace.
§Returns
The task namespace for this ABI
Sourcefn can_execute_binary(
&self,
_file_object: &KernelObject,
_file_path: &str,
_current_abi: Option<&(dyn AbiModule + Send + Sync)>,
) -> Option<u8>
fn can_execute_binary( &self, _file_object: &KernelObject, _file_path: &str, _current_abi: Option<&(dyn AbiModule + Send + Sync)>, ) -> 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 ABINone- 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
§Recommended Scoring Guidelines
- 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))Sourcefn initialize_from_existing_handles(
&mut self,
_task: &Task,
) -> Result<(), &'static str>
fn initialize_from_existing_handles( &mut self, _task: &Task, ) -> Result<(), &'static str>
Handle conversion when switching ABIs
Sourcefn normalize_env_to_scarlet(&self, _envp: &mut Vec<String>)
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
Sourcefn denormalize_env_from_scarlet(&self, _envp: &mut Vec<String>)
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
Sourcefn choose_load_address(
&self,
_elf_type: u16,
_target: LoadTarget,
) -> Option<u64>
fn choose_load_address( &self, _elf_type: u16, _target: LoadTarget, ) -> Option<u64>
Choose base address for ELF loading (ABI-specific strategy)
This method allows each ABI to define its own memory layout preferences for different types of ELF objects. The ELF loader will use these addresses when loading binaries for this ABI.
§Arguments
elf_type- ELF file type (ET_EXEC, ET_DYN, etc.)target- Target component being loaded
§Returns
Base address where the component should be loaded, or None to use kernel default strategy
Sourcefn get_interpreter_path(&self, requested_interpreter: &str) -> String
fn get_interpreter_path(&self, requested_interpreter: &str) -> String
Override interpreter path (for ABI compatibility)
This method allows each ABI to specify which dynamic linker should be used when a binary requires dynamic linking (has PT_INTERP).
§Arguments
requested_interpreter- Interpreter path from PT_INTERP segment
§Returns
The interpreter path to actually use (may be different from requested)
Sourcefn get_runtime_config(
&self,
_file_object: &KernelObject,
_file_path: &str,
) -> Option<RuntimeConfig>
fn get_runtime_config( &self, _file_object: &KernelObject, _file_path: &str, ) -> Option<RuntimeConfig>
Get userland runtime configuration for executing binaries
This method allows ABI modules to delegate binary execution to userland runtimes. When a runtime is configured, the binary will be executed via the runtime instead of being loaded directly by the kernel.
§Arguments
file_object- Binary file to checkfile_path- File path for format detection
§Returns
Some(RuntimeConfig)- Runtime configuration if delegation is neededNone- No runtime delegation, execute directly
§Example Use Cases
- MS-DOS binaries via DOSBox (Linux ABI runtime)
- Wasm binaries via Scarlet-native Wasm runtime
- Java bytecode via JVM
- Cross-architecture binaries via QEMU user-mode
Sourcefn get_default_cwd(&self) -> &str
fn get_default_cwd(&self) -> &str
Get default working directory for this ABI
Sourcefn setup_overlay_environment(
&self,
_target_vfs: &Arc<VfsManager>,
_base_vfs: &Arc<VfsManager>,
_system_path: &str,
_config_path: &str,
) -> Result<(), &'static str>
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 filesystembase_vfs- Base VFS containing system and config directoriessystem_path- Path to read-only base layer (e.g., “/system/scarlet”)config_path- Path to writable persistence layer (e.g., “/data/config/scarlet”)
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 configurebase_vfs- Base VFS containing shared directories
Sourcefn handle_event(
&self,
_event: Event,
_target_task_id: u32,
) -> Result<(), &'static str>
fn handle_event( &self, _event: Event, _target_task_id: u32, ) -> Result<(), &'static str>
Handle incoming event from EventManager
This method is called when an event is delivered to a task using this ABI. Each ABI can implement its own event handling strategy:
- Scarlet ABI: Handle-based queuing with EventSubscription objects
- xv6 ABI: POSIX-like signals and pipe notifications
- Other ABIs: Custom event processing mechanisms
§Arguments
event- The event to be deliveredtarget_task_id- ID of the task that should receive the event
§Returns
Ok(())if the event was successfully handledErr(message)if event delivery failed
Sourcefn set_tls_pointer(&mut self, _ptr: usize)
fn set_tls_pointer(&mut self, _ptr: usize)
Set the TLS (Thread Local Storage) pointer for this task
Default implementation does nothing - ABIs that support TLS should override this method.
Sourcefn get_tls_pointer(&self) -> Option<usize>
fn get_tls_pointer(&self) -> Option<usize>
Get the TLS (Thread Local Storage) pointer for this task
Default implementation returns None - ABIs that support TLS should override this method.
Sourcefn set_clear_child_tid(&mut self, _ptr: usize)
fn set_clear_child_tid(&mut self, _ptr: usize)
Set the clear_child_tid pointer for thread exit notification
Default implementation does nothing - ABIs that support TLS should override this method.