From: Tulio A M Mendes Date: Thu, 12 Feb 2026 04:00:34 +0000 (-0300) Subject: feat: sigaltstack syscall (86) — alternate signal stack per-process (ss_sp/ss_size... X-Git-Url: https://projects.tadryanom.me/docs/static/git-logo.png?a=commitdiff_plain;h=f3b0e83a58f3f31be506abcb8f69d179da21ad27;p=AdrOS.git feat: sigaltstack syscall (86) — alternate signal stack per-process (ss_sp/ss_size/ss_flags) --- diff --git a/include/process.h b/include/process.h index 8c2ace6..fee54f5 100644 --- a/include/process.h +++ b/include/process.h @@ -72,6 +72,9 @@ struct process { struct sigaction sigactions[PROCESS_MAX_SIG]; uint32_t sig_blocked_mask; uint32_t sig_pending_mask; + uintptr_t ss_sp; /* alternate signal stack pointer */ + uint32_t ss_size; /* alternate signal stack size */ + uint32_t ss_flags; /* SS_DISABLE etc. */ // For SIGSEGV: last page fault address (CR2) captured in ring3. uintptr_t last_fault_addr; diff --git a/include/syscall.h b/include/syscall.h index f1b67dc..9f16ebc 100644 --- a/include/syscall.h +++ b/include/syscall.h @@ -109,6 +109,7 @@ enum { SYSCALL_ALARM = 83, SYSCALL_TIMES = 84, SYSCALL_FUTEX = 85, + SYSCALL_SIGALTSTACK = 86, }; #endif diff --git a/src/kernel/syscall.c b/src/kernel/syscall.c index d0821f2..c2940b7 100644 --- a/src/kernel/syscall.c +++ b/src/kernel/syscall.c @@ -2272,7 +2272,8 @@ void syscall_handler(struct registers* regs) { return; } - if (syscall_no == SYSCALL_TIMES || syscall_no == SYSCALL_FUTEX) { + if (syscall_no == SYSCALL_SIGALTSTACK || + syscall_no == SYSCALL_TIMES || syscall_no == SYSCALL_FUTEX) { posix_ext_syscall_dispatch(regs, syscall_no); return; } @@ -2453,6 +2454,41 @@ static void posix_ext_syscall_dispatch(struct registers* regs, uint32_t syscall_ return; } + if (syscall_no == SYSCALL_SIGALTSTACK) { + if (!current_process) { regs->eax = (uint32_t)-EINVAL; return; } + #ifndef SS_DISABLE + #define SS_DISABLE 2 + #endif + uint32_t* user_old = (uint32_t*)regs->ecx; + uint32_t* user_new = (uint32_t*)regs->ebx; + if (user_old) { + uint32_t old_ss[3]; + old_ss[0] = (uint32_t)current_process->ss_sp; + old_ss[1] = current_process->ss_flags; + old_ss[2] = current_process->ss_size; + if (copy_to_user(user_old, old_ss, 12) < 0) { + regs->eax = (uint32_t)-EFAULT; return; + } + } + if (user_new) { + uint32_t new_ss[3]; + if (copy_from_user(new_ss, user_new, 12) < 0) { + regs->eax = (uint32_t)-EFAULT; return; + } + if (new_ss[1] & SS_DISABLE) { + current_process->ss_sp = 0; + current_process->ss_size = 0; + current_process->ss_flags = SS_DISABLE; + } else { + current_process->ss_sp = (uintptr_t)new_ss[0]; + current_process->ss_flags = new_ss[1]; + current_process->ss_size = new_ss[2]; + } + } + regs->eax = 0; + return; + } + if (syscall_no == SYSCALL_FUTEX) { #define FUTEX_WAIT 0 #define FUTEX_WAKE 1 diff --git a/user/ulibc/include/signal.h b/user/ulibc/include/signal.h index f6816c6..68dc553 100644 --- a/user/ulibc/include/signal.h +++ b/user/ulibc/include/signal.h @@ -53,4 +53,13 @@ int sigprocmask(int how, const uint32_t* set, uint32_t* oldset); int sigpending(uint32_t* set); int sigsuspend(const uint32_t* mask); +#define SS_DISABLE 2 +typedef struct { + void* ss_sp; + int ss_flags; + unsigned ss_size; +} stack_t; + +int sigaltstack(const stack_t* ss, stack_t* old_ss); + #endif diff --git a/user/ulibc/include/syscall.h b/user/ulibc/include/syscall.h index ebc3bcc..568e79f 100644 --- a/user/ulibc/include/syscall.h +++ b/user/ulibc/include/syscall.h @@ -68,6 +68,7 @@ enum { SYS_ALARM = 83, SYS_TIMES = 84, SYS_FUTEX = 85, + SYS_SIGALTSTACK = 86, }; /* Raw syscall wrappers — up to 5 args via INT 0x80 */ diff --git a/user/ulibc/src/signal.c b/user/ulibc/src/signal.c index 2b20fa6..625c69d 100644 --- a/user/ulibc/src/signal.c +++ b/user/ulibc/src/signal.c @@ -21,3 +21,7 @@ int sigpending(uint32_t* set) { int sigsuspend(const uint32_t* mask) { return __syscall_ret(_syscall1(SYS_SIGSUSPEND, (int)mask)); } + +int sigaltstack(const stack_t* ss, stack_t* old_ss) { + return __syscall_ret(_syscall2(SYS_SIGALTSTACK, (int)ss, (int)old_ss)); +}