ARM64 Implementation
Relevant source files
This document describes the ARM64 (AArch64) architecture-specific implementation of the signal handling system in ArceOS. It details how signal context management, trampolines, and architecture-specific data structures are implemented for ARM64 processors. For information about other architecture implementations, see x86_64 Implementation, RISC-V Implementation, or LoongArch64 Implementation.
Overview
The ARM64 implementation provides the architecture-specific components needed for signal handling, including:
- A signal trampoline for transferring control to user signal handlers
- Context management structures for saving and restoring CPU state
- Context conversion utilities between trap frames and signal contexts
flowchart TD subgraph subGraph1["Key Functions"] save["Context Saving"] restore["Context Restoration"] syscall["rt_sigreturn Syscall"] end subgraph subGraph0["ARM64 Signal Implementation"] trampoline["signal_trampoline()"] mcontext["MContext"] ucontext["UContext"] end mcontext --> restore mcontext --> save restore --> mcontext save --> ucontext trampoline --> syscall ucontext --> mcontext
Sources: src/arch/aarch64.rs src/arch/mod.rs
Signal Trampoline
The signal trampoline is a small piece of assembly code that serves as the return path from signal handlers. When a signal handler completes execution, the trampoline is called to restore the original execution context and return to the interrupted code.
The ARM64 signal trampoline is implemented as:
- A page-aligned assembly function that makes syscall 139 (typically
rt_sigreturn
in Unix-like systems) - The function is padded to fill an entire 4096-byte page
The implementation in assembly is:
signal_trampoline:
mov x8, #139 ; Load syscall number 139 into x8 register
svc #0 ; Trigger supervisor call (system call)
This trampoline is accessed via the signal_trampoline_address()
function, which returns its memory address for use during signal handler setup.
Sources: src/arch/aarch64.rs(L5 - L16) src/arch/mod.rs(L19 - L25)
Machine Context (MContext)
The MContext
structure is responsible for storing the complete CPU state necessary to restore execution after signal handling. It captures all registers and processor state flags.
classDiagram class MContext { +u64 fault_address +u64[31] regs +u64 sp +u64 pc +u64 pstate +MContextPadding __reserved +new(TrapFrame) MContext +restore(TrapFrame) } class MContextPadding { +u8[4096] 0 } MContext --> MContextPadding
The MContext
structure:
- Is 16-byte aligned for optimal performance on ARM64
- Contains all 31 general-purpose registers (x0-x30)
- Stores critical CPU state including stack pointer, program counter, and processor state
- Includes a large reserved padding area
- Provides methods to create from and restore to a trap frame
This structure effectively captures the entire execution state that must be preserved during signal handling.
Sources: src/arch/aarch64.rs(L18 - L51)
User Context (UContext)
The UContext
structure provides a higher-level abstraction that combines the machine context with additional signal-related information. This matches the structure expected by user-level signal handlers.
classDiagram class UContext { +usize flags +usize link +SignalStack stack +SignalSet sigmask +u8[] __unused +MContext mcontext +new(TrapFrame, SignalSet) UContext } class MContext { +u64 fault_address +u64[31] regs +u64 sp +u64 pc +u64 pstate +padding } class SignalStack { +stack attributes } class SignalSet { +signal mask bits } UContext --> MContext UContext --> SignalStack UContext --> SignalSet
The UContext
structure includes:
- Flags for context management
- A link field that can point to another context
- A
SignalStack
for defining the stack used during signal handling - A
SignalSet
representing the signal mask during handler execution - Reserved space to ensure proper sizing and alignment
- The
MContext
containing all CPU registers and state
During signal handling, this structure is used to:
- Save the current execution context before calling the handler
- Configure the signal environment for the handler execution
- Restore the original context when the handler completes
Sources: src/arch/aarch64.rs(L53 - L75)
Context Management Flow
The following diagram illustrates how the ARM64 implementation manages context during signal handling:
sequenceDiagram participant UserProcess as "User Process" participant KernelArceOS as "Kernel/ArceOS" participant SignalHandler as "Signal Handler" participant signal_trampoline as "signal_trampoline" UserProcess ->> KernelArceOS: Normal Execution KernelArceOS ->> KernelArceOS: Signal Received KernelArceOS ->> KernelArceOS: Create MContext from TrapFrame KernelArceOS ->> KernelArceOS: Create UContext with MContext KernelArceOS ->> SignalHandler: Set up and jump to handler with UContext SignalHandler ->> SignalHandler: Handle signal SignalHandler ->> signal_trampoline: Return via trampoline signal_trampoline ->> KernelArceOS: syscall rt_sigreturn (139) KernelArceOS ->> KernelArceOS: Extract MContext from UContext KernelArceOS ->> KernelArceOS: Restore TrapFrame from MContext KernelArceOS ->> UserProcess: Resume original execution
When a signal is delivered:
- The current CPU state is captured in a
TrapFrame
- This state is converted to an
MContext
- An
UContext
is built including theMContext
and signal information - The signal handler is called with this context
- When the handler returns, the signal trampoline is executed
- The syscall in the trampoline triggers the kernel to restore the original context
- Regular execution continues from where it was interrupted
Sources: src/arch/aarch64.rs(L34 - L45) src/arch/aarch64.rs(L45 - L50) src/arch/aarch64.rs(L65 - L74)
Context Conversion Process
The ARM64 implementation provides efficient methods for converting between trap frames and contexts:
Creation Process
When creating an MContext
from a TrapFrame
, the following fields are mapped:
- General registers (r0-r30) are copied directly
- The user stack pointer (usp) becomes the stack pointer (sp)
- The exception link register (elr) becomes the program counter (pc)
- The saved program status register (spsr) becomes the processor state (pstate)
Restoration Process
When restoring a TrapFrame
from an MContext
, the reverse mappings occur:
- General registers are copied back
- The stack pointer is restored to usp
- The program counter is restored to elr
- The processor state is restored to spsr
This bidirectional conversion ensures that execution context is properly preserved during signal handling.
Sources: src/arch/aarch64.rs(L34 - L45) src/arch/aarch64.rs(L45 - L50)
Integration with Signal Handling System
The ARM64 implementation integrates with the overall signal handling system through the architecture abstraction layer defined in arch/mod.rs
. This layer provides a unified interface for all supported architectures while allowing architecture-specific implementations of critical components.
flowchart TD subgraph subGraph2["Signal Handling System"] thread_manager["ThreadSignalManager"] process_manager["ProcessSignalManager"] end subgraph subGraph1["ARM64 Implementation"] aarch64["aarch64.rs"] mcontext["MContext"] ucontext["UContext"] trampoline["signal_trampoline"] end subgraph subGraph0["Architecture Module"] arch_mod["arch/mod.rs"] trampoline_addr["signal_trampoline_address()"] end aarch64 --> mcontext aarch64 --> trampoline aarch64 --> ucontext arch_mod --> aarch64 process_manager --> arch_mod thread_manager --> arch_mod trampoline_addr --> trampoline
The key integration points are:
- The architecture module exposes the
signal_trampoline_address()
function - The signal handling system uses this function to set up signal handlers
- The
MContext
andUContext
structures are used to manage execution state - The architecture-specific context conversion methods are used during signal delivery and return
This abstraction allows the core signal handling logic to remain architecture-agnostic while leveraging the ARM64-specific implementation for context management.
Sources: src/arch/mod.rs(L1 - L17) src/arch/mod.rs(L19 - L25)
Summary
The ARM64 implementation provides the architecture-specific components required for signal handling on AArch64 processors:
- Signal Trampoline: A carefully positioned assembly function that makes the
rt_sigreturn
syscall - Machine Context (MContext): A structure capturing all ARM64 CPU registers and state
- User Context (UContext): A higher-level structure combining machine context with signal information
- Context Management Methods: Functions to convert between trap frames and contexts
These components work together to ensure that signal handling can properly save and restore execution state on ARM64 platforms.
Sources: src/arch/aarch64.rs src/arch/mod.rs