From: Tulio A M Mendes Date: Fri, 13 Feb 2026 19:42:45 +0000 (-0300) Subject: refactor: decouple struct process from arch-specific struct registers X-Git-Url: https://projects.tadryanom.me/docs/static/git-logo.png?a=commitdiff_plain;h=2a96572498275dafa7e97bf678d521d843794da7;p=AdrOS.git refactor: decouple struct process from arch-specific struct registers - Replace embedded 'struct registers user_regs' with opaque uint8_t user_regs[ARCH_REGS_SIZE] - Add include/arch_types.h dispatcher and include/arch/x86/arch_types.h (ARCH_REGS_SIZE=64) - Change arch_regs_set_retval, arch_regs_set_ustack, hal_usermode_enter_regs, arch_sigreturn to accept void* instead of struct registers* — arch implementations cast internally - process_fork_create and process_clone_create now take const void* child_regs - Remove #include interrupts.h from process.h, arch_process.h, hal/usermode.h, arch_signal.h - process.h is now fully architecture-agnostic (no x86 register names visible) 20/20 smoke, cppcheck clean --- diff --git a/include/arch/x86/arch_types.h b/include/arch/x86/arch_types.h new file mode 100644 index 0000000..8296c37 --- /dev/null +++ b/include/arch/x86/arch_types.h @@ -0,0 +1,13 @@ +#ifndef ARCH_X86_TYPES_H +#define ARCH_X86_TYPES_H + +/* + * Size in bytes of the saved user-mode register frame (struct registers). + * x86: ds(4) + pusha(32) + int_no+err(8) + iret_frame(20) = 64 + * + * Used by struct process to hold an opaque register snapshot without + * pulling in the full x86 IDT / register definitions. + */ +#define ARCH_REGS_SIZE 64 + +#endif /* ARCH_X86_TYPES_H */ diff --git a/include/arch_process.h b/include/arch_process.h index 424ece9..203ebab 100644 --- a/include/arch_process.h +++ b/include/arch_process.h @@ -2,7 +2,6 @@ #define ARCH_PROCESS_H #include -#include "interrupts.h" /* * arch_kstack_init — Prepare a kernel stack for a brand-new process/thread @@ -23,13 +22,15 @@ uintptr_t arch_kstack_init(void* stack_top, /* * Set the "return value" register in a saved trapframe. * On x86 this is EAX; on ARM it would be R0, etc. + * regs points to the opaque user_regs[] buffer in struct process. */ -void arch_regs_set_retval(struct registers* regs, uint32_t val); +void arch_regs_set_retval(void* regs, uint32_t val); /* * Set the user-mode stack pointer in a saved trapframe. * On x86 this is useresp; on ARM it would be SP_usr, etc. + * regs points to the opaque user_regs[] buffer in struct process. */ -void arch_regs_set_ustack(struct registers* regs, uintptr_t sp); +void arch_regs_set_ustack(void* regs, uintptr_t sp); #endif /* ARCH_PROCESS_H */ diff --git a/include/arch_signal.h b/include/arch_signal.h index d68dadd..79fd60e 100644 --- a/include/arch_signal.h +++ b/include/arch_signal.h @@ -1,19 +1,18 @@ #ifndef ARCH_SIGNAL_H #define ARCH_SIGNAL_H -#include "interrupts.h" - /* * arch_sigreturn — Restore user registers from a signal frame on the * user stack. Architecture-specific because the frame * layout and register sanitisation depend on the ISA. * * regs : current trapframe (will be overwritten on success). + * Points to the arch-specific register struct (e.g. struct registers on x86). * user_frame : user-space pointer to the signal frame pushed by the * signal delivery trampoline. * * Returns 0 on success, negative errno on failure. */ -int arch_sigreturn(struct registers* regs, const void* user_frame); +int arch_sigreturn(void* regs, const void* user_frame); #endif /* ARCH_SIGNAL_H */ diff --git a/include/arch_types.h b/include/arch_types.h new file mode 100644 index 0000000..2ac0402 --- /dev/null +++ b/include/arch_types.h @@ -0,0 +1,18 @@ +#ifndef ARCH_TYPES_H +#define ARCH_TYPES_H + +/* + * Architecture-specific type constants. + * This header provides opaque sizing information so that generic kernel + * headers (e.g. process.h) can embed arch data without including the + * full arch register / interrupt definitions. + */ + +#if defined(__i386__) || defined(__x86_64__) +#include "arch/x86/arch_types.h" +#else +/* Fallback for non-x86: define a generous default */ +#define ARCH_REGS_SIZE 64 +#endif + +#endif /* ARCH_TYPES_H */ diff --git a/include/hal/usermode.h b/include/hal/usermode.h index a8785cc..27248ec 100644 --- a/include/hal/usermode.h +++ b/include/hal/usermode.h @@ -2,10 +2,9 @@ #define HAL_USERMODE_H #include -#include "interrupts.h" int hal_usermode_enter(uintptr_t user_eip, uintptr_t user_esp); -void hal_usermode_enter_regs(const struct registers* regs); +void hal_usermode_enter_regs(const void* regs); #endif diff --git a/include/process.h b/include/process.h index aaf1ace..33c2713 100644 --- a/include/process.h +++ b/include/process.h @@ -2,7 +2,7 @@ #define PROCESS_H #include -#include "interrupts.h" // For struct registers +#include "arch_types.h" #include "fs.h" #include "signal.h" @@ -65,7 +65,7 @@ struct process { int exit_status; int has_user_regs; - struct registers user_regs; + uint8_t user_regs[ARCH_REGS_SIZE]; /* opaque arch register snapshot */ // Minimal signals: per-signal action, blocked mask and pending mask. // sa_handler == 0 => default @@ -153,12 +153,14 @@ int process_kill(uint32_t pid, int sig); int process_kill_pgrp(uint32_t pgrp, int sig); // Create a child process that will resume in usermode from a saved register frame. -struct process* process_fork_create(uintptr_t child_as, const struct registers* child_regs); +// child_regs points to an opaque arch register snapshot (ARCH_REGS_SIZE bytes). +struct process* process_fork_create(uintptr_t child_as, const void* child_regs); // Create a thread (clone) sharing the parent's address space. +// child_regs points to an opaque arch register snapshot (ARCH_REGS_SIZE bytes). struct process* process_clone_create(uint32_t clone_flags, uintptr_t child_stack, - const struct registers* child_regs, + const void* child_regs, uintptr_t tls_base); // Look up a process by PID (scheduler lock must NOT be held). diff --git a/src/arch/x86/arch_process.c b/src/arch/x86/arch_process.c index 25dc927..c4d6e5d 100644 --- a/src/arch/x86/arch_process.c +++ b/src/arch/x86/arch_process.c @@ -39,13 +39,15 @@ uintptr_t arch_kstack_init(void* stack_top, return (uintptr_t)sp; } -void arch_regs_set_retval(struct registers* regs, uint32_t val) +void arch_regs_set_retval(void* opaque, uint32_t val) { + struct registers* regs = (struct registers*)opaque; if (regs) regs->eax = val; } -void arch_regs_set_ustack(struct registers* regs, uintptr_t sp) +void arch_regs_set_ustack(void* opaque, uintptr_t sp) { + struct registers* regs = (struct registers*)opaque; if (regs) regs->useresp = (uint32_t)sp; } diff --git a/src/arch/x86/signal.c b/src/arch/x86/signal.c index b70badb..27a87a3 100644 --- a/src/arch/x86/signal.c +++ b/src/arch/x86/signal.c @@ -6,8 +6,9 @@ #if defined(__i386__) -int arch_sigreturn(struct registers* regs, const void* user_frame) +int arch_sigreturn(void* opaque, const void* user_frame) { + struct registers* regs = (struct registers*)opaque; if (!regs) return -EINVAL; if (!current_process) return -EINVAL; if ((regs->cs & 3U) != 3U) return -EPERM; diff --git a/src/hal/x86/usermode.c b/src/hal/x86/usermode.c index 8598983..fdef058 100644 --- a/src/hal/x86/usermode.c +++ b/src/hal/x86/usermode.c @@ -14,9 +14,9 @@ int hal_usermode_enter(uintptr_t user_eip, uintptr_t user_esp) { #endif } -void hal_usermode_enter_regs(const struct registers* regs) { +void hal_usermode_enter_regs(const void* regs) { #if defined(__i386__) - x86_enter_usermode_regs(regs); + x86_enter_usermode_regs((const struct registers*)regs); #else (void)regs; #endif diff --git a/src/kernel/scheduler.c b/src/kernel/scheduler.c index a36d07a..5931baf 100644 --- a/src/kernel/scheduler.c +++ b/src/kernel/scheduler.c @@ -415,10 +415,10 @@ static void fork_child_trampoline(void) { vmm_as_activate(current_process->addr_space); } - hal_usermode_enter_regs(¤t_process->user_regs); + hal_usermode_enter_regs(current_process->user_regs); } -struct process* process_fork_create(uintptr_t child_as, const struct registers* child_regs) { +struct process* process_fork_create(uintptr_t child_as, const void* child_regs) { if (!child_as || !child_regs) return NULL; uintptr_t flags = spin_lock_irqsave(&sched_lock); @@ -457,7 +457,7 @@ struct process* process_fork_create(uintptr_t child_as, const struct registers* } proc->has_user_regs = 1; - proc->user_regs = *child_regs; + memcpy(proc->user_regs, child_regs, ARCH_REGS_SIZE); proc->tgid = proc->pid; proc->flags = 0; proc->tls_base = 0; @@ -511,12 +511,12 @@ static void clone_child_trampoline(void) { hal_cpu_set_tls(current_process->tls_base); } - hal_usermode_enter_regs(¤t_process->user_regs); + hal_usermode_enter_regs(current_process->user_regs); } struct process* process_clone_create(uint32_t clone_flags, uintptr_t child_stack, - const struct registers* child_regs, + const void* child_regs, uintptr_t tls_base) { if (!child_regs || !current_process) return NULL; @@ -601,12 +601,12 @@ struct process* process_clone_create(uint32_t clone_flags, } proc->has_user_regs = 1; - proc->user_regs = *child_regs; - arch_regs_set_retval(&proc->user_regs, 0); /* child returns 0 */ + memcpy(proc->user_regs, child_regs, ARCH_REGS_SIZE); + arch_regs_set_retval(proc->user_regs, 0); /* child returns 0 */ /* If child_stack specified, override user stack pointer */ if (child_stack) { - arch_regs_set_ustack(&proc->user_regs, child_stack); + arch_regs_set_ustack(proc->user_regs, child_stack); } /* Allocate kernel stack */