LoongArch64 Implementation
Relevant source files
Purpose and Scope
This document describes the LoongArch64-specific implementation of signal handling in the axsignal
crate. It details the architecture-specific data structures, register context management, and signal trampoline mechanism that enable Unix-like signal handling on the LoongArch64 architecture. For a general overview of the architecture support system, see Architecture Support.
Signal Context Management
The LoongArch64 implementation provides specialized structures for managing CPU context during signal handling operations. These structures are critical for preserving and restoring the CPU state when a signal handler is invoked and when it returns.
Context Structures
classDiagram class TrapFrame { +regs: [u64; 32] +era: usize +Other architecture-specific registers } class MContext { +sc_pc: u64 +sc_regs: [u64; 32] +sc_flags: u32 +new(tf: &TrapFrame) +restore(&self, tf: &mut TrapFrame) } class UContext { +flags: usize +link: usize +stack: SignalStack +sigmask: SignalSet +__unused: [u8; ...] +mcontext: MContext +new(tf: &TrapFrame, sigmask: SignalSet) } class SignalSet { } class SignalStack { } TrapFrame --> MContext : converted to MContext --> UContext : contained in SignalSet --> UContext : contained in SignalStack --> UContext : contained in
The LoongArch64 implementation defines two main context structures:
- MContext (Machine Context): Stores the CPU register state for LoongArch64
sc_pc
: Program counter (instruction pointer)sc_regs
: Array of 32 general-purpose registerssc_flags
: Context flags
- UContext (User Context): Encapsulates the complete execution context
flags
: Context flagslink
: Pointer to linked contextstack
: Signal stack informationsigmask
: Signal mask in effectmcontext
: Machine context (CPU registers)
Sources: src/arch/loongarch64.rs(L20 - L67)
Signal Trampoline
The signal trampoline is a critical piece of assembly code that provides a reliable mechanism for returning from signal handlers. It executes a system call (rt_sigreturn) to restore the original execution context.
flowchart TD SignalDelivery["Signal Delivery"] SetupStack["Set up Handler Stack"] SaveContext["Save Current Context"] InvokeHandler["Invoke Signal Handler"] SignalTrampoline["Signal Trampoline"] SyscallRtSigreturn["Syscall rt_sigreturn (139)"] RestoreContext["Restore Original Context"] ResumeExecution["Resume Original Execution"] InvokeHandler --> SignalTrampoline RestoreContext --> ResumeExecution SaveContext --> InvokeHandler SetupStack --> SaveContext SignalDelivery --> SetupStack SignalTrampoline --> SyscallRtSigreturn SyscallRtSigreturn --> RestoreContext
The LoongArch64 signal trampoline is implemented in assembly:
signal_trampoline:
li.w $a7, 139 # Load syscall number 139 (rt_sigreturn)
syscall 0 # Make syscall
The trampoline is aligned on a 4096-byte boundary and padded to fill a full page, ensuring it has a predictable memory layout. When the signal handler completes, execution flows to this trampoline, which performs syscall 139 (rt_sigreturn) to restore the original execution context.
Sources: src/arch/loongarch64.rs(L7 - L18) src/arch/mod.rs(L19 - L25)
Context Conversion and Restoration
The LoongArch64 implementation provides methods to convert between the TrapFrame
structure (used by the kernel) and the MContext
structure (used for signal handling).
sequenceDiagram participant Kernel as "Kernel" participant SignalManager as "Signal Manager" participant SignalHandler as "Signal Handler" participant SignalTrampoline as SignalTrampoline Kernel ->> SignalManager: Deliver signal with TrapFrame SignalManager ->> SignalManager: Create MContext from TrapFrame SignalManager ->> SignalManager: Create UContext with MContext SignalManager ->> SignalHandler: Invoke with UContext pointer SignalHandler -->> SignalTrampoline: Return SignalTrampoline ->> Kernel: rt_sigreturn syscall Kernel ->> SignalManager: Restore TrapFrame from UContext SignalManager ->> SignalManager: MContext.restore(TrapFrame) SignalManager ->> Kernel: Resume execution
Context Creation
When a signal is delivered, the system creates an MContext
from the current TrapFrame
:
- The
MContext::new
method creates a new machine context from a trap frame - It copies the program counter (
era
) and all 32 general-purpose registers
Context Restoration
When a signal handler returns, the system restores the original TrapFrame
from the saved MContext
:
- The
MContext::restore
method updates the trap frame with saved values - It restores the program counter (
era
) and all 32 general-purpose registers
Sources: src/arch/loongarch64.rs(L28 - L43)
Memory Layout for Signal Handling
When a signal is delivered, the system sets up a specific memory layout on the user stack to facilitate signal handling.
flowchart TD subgraph subGraph0["Signal Handler Stack Layout"] signalHandler["Signal Handler Function"] signoArg["Signal Number (Argument 1)"] siginfoArg["SignalInfo Pointer (Argument 2)"] ucontextArg["UContext Pointer (Argument 3)"] returnAddress["Return Address (signal_trampoline)"] savedRegisters["Saved Registers (MContext)"] end stackGrowth["Stack Growth Direction ↓"] returnAddress --> savedRegisters siginfoArg --> ucontextArg signalHandler --> signoArg signoArg --> siginfoArg stackGrowth --> signalHandler ucontextArg --> returnAddress
The key components of this memory layout are:
- Signal Handler Function: The entry point for the signal handler
- Arguments: Three arguments are passed to the handler:
- Signal number
- Pointer to signal information
- Pointer to user context (UContext)
- Return Address: Set to the
signal_trampoline
function - Saved Context: The complete user context (UContext) including:
- Signal mask
- Signal stack information
- Machine context (registers)
This layout ensures that when the signal handler returns, it will jump to the signal trampoline, which will restore the original execution context through the rt_sigreturn syscall.
Sources: src/arch/loongarch64.rs(L7 - L18) src/arch/loongarch64.rs(L45 - L67)
Comparison with Other Architectures
The LoongArch64 implementation shares many similarities with other RISC architectures in the axsignal
crate, particularly with RISC-V. However, there are architecture-specific differences in register naming and context structure.
Feature | LoongArch64 | RISC-V | x86_64 | AArch64 |
---|---|---|---|---|
PC Register | era | sepc | rip | elr_el1 |
Register Count | 32 GP registers | 32 GP registers | 16 GP registers | 31 GP registers |
Context Flags | Simple 32-bit flags | Simple 32-bit flags | EFLAGS/XSAVE | PSTATE flags |
Signal Trampoline | Syscall 139 | Syscall 139 | Syscall 15 | Syscall 139 |
The main architecture-specific aspects of the LoongArch64 implementation include:
- Register Set: LoongArch64 has 32 general-purpose registers (like RISC-V)
- Program Counter: Called
era
(Exception Return Address) - Assembly Instructions: Uses LoongArch64-specific instructions like
li.w
andsyscall
Sources: src/arch/loongarch64.rs(L20 - L43)
Integration with Signal Handling System
The LoongArch64 implementation integrates with the broader signal handling system through the architecture abstraction layer in src/arch/mod.rs
.
The integration points include:
- Architecture Selection: Conditional compilation selects the LoongArch64 implementation based on the target architecture
- Signal Trampoline Address: Exposed through a common function to get the address of the architecture-specific signal trampoline
- Context Management: The architecture-specific UContext and MContext structures are used by the signal manager to save and restore execution context
Sources: src/arch/mod.rs(L1 - L25)
Summary
The LoongArch64 implementation in the axsignal
crate provides the architecture-specific components needed for Unix-like signal handling on LoongArch64 processors. It includes:
- A signal trampoline mechanism for returning from signal handlers
- Machine context (MContext) and user context (UContext) structures for saving and restoring CPU state
- Methods for converting between trap frames and machine contexts
- Integration with the architecture-independent signal handling system
These components enable the axsignal crate to provide a consistent signal handling API across different architectures, including LoongArch64.