]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
refactor: decouple struct process from arch-specific struct registers
authorTulio A M Mendes <[email protected]>
Fri, 13 Feb 2026 19:42:45 +0000 (16:42 -0300)
committerTulio A M Mendes <[email protected]>
Fri, 13 Feb 2026 19:42:45 +0000 (16:42 -0300)
- 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

include/arch/x86/arch_types.h [new file with mode: 0644]
include/arch_process.h
include/arch_signal.h
include/arch_types.h [new file with mode: 0644]
include/hal/usermode.h
include/process.h
src/arch/x86/arch_process.c
src/arch/x86/signal.c
src/hal/x86/usermode.c
src/kernel/scheduler.c

diff --git a/include/arch/x86/arch_types.h b/include/arch/x86/arch_types.h
new file mode 100644 (file)
index 0000000..8296c37
--- /dev/null
@@ -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 */
index 424ece9004bfedf40a9efb2e410c9a507dda011a..203ebabc02ca9c1e97a491401317cda81e7d1810 100644 (file)
@@ -2,7 +2,6 @@
 #define ARCH_PROCESS_H
 
 #include <stdint.h>
-#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 */
index d68daddccc7c89340c9dc7e3cb57489f212a00be..79fd60e6a81a442971cf5c91e5f75316c1784407 100644 (file)
@@ -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 (file)
index 0000000..2ac0402
--- /dev/null
@@ -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 */
index a8785ccad5d1a8ca7073fd2897b1cc521759a870..27248ecf179b72067f0a1067b86fac8c230eca4d 100644 (file)
@@ -2,10 +2,9 @@
 #define HAL_USERMODE_H
 
 #include <stdint.h>
-#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
index aaf1ace89268dc74560b5c0aed0c20e83e1eea91..33c271352fbb3ea92bdfd14a4c8024e4be3ad780 100644 (file)
@@ -2,7 +2,7 @@
 #define PROCESS_H
 
 #include <stdint.h>
-#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).
index 25dc9270acfdfee701379fac40c0e458f86482a2..c4d6e5db861f1ffc43364b3a21976242e9828d7d 100644 (file)
@@ -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;
 }
 
index b70badb8d29031090db9966f1354442980b1441e..27a87a364ffb71dec4a7134ff061493324be849c 100644 (file)
@@ -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;
index 85989834ae70e6944585bcddf399b5973c5bb0d2..fdef058dda1f5cc1f09668cae525749b101d565c 100644 (file)
@@ -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
index a36d07a50ea03576ecebbc9a6c86fa9dd6616dce..5931baff717b8c058688f126033f9e148235972a 100644 (file)
@@ -415,10 +415,10 @@ static void fork_child_trampoline(void) {
         vmm_as_activate(current_process->addr_space);
     }
 
-    hal_usermode_enter_regs(&current_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(&current_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 */