]> 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..edcb6cf
--- /dev/null
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2018, Tulio A M Mendes <[email protected]>
+ * All rights reserved.
+ * See LICENSE for details.
+ *
+ * Source: https://github.com/tadryanom/AdrOS
+ */
+
+#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 a8f6560bc4e06b8246ff22d47503f914857b99f5..884a786a4e3e2bb23e926e99dfa1258e4695a4f3 100644 (file)
@@ -11,7 +11,6 @@
 #define ARCH_PROCESS_H
 
 #include <stdint.h>
-#include "interrupts.h"
 
 /*
  * arch_kstack_init — Prepare a kernel stack for a brand-new process/thread
@@ -32,13 +31,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 436fc573aa76595a77eefb78bdb1b93369c5f0a2..6d4d7eef3496c785971503a99cb9fa276a535651 100644 (file)
 #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..065d67f
--- /dev/null
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2018, Tulio A M Mendes <[email protected]>
+ * All rights reserved.
+ * See LICENSE for details.
+ *
+ * Source: https://github.com/tadryanom/AdrOS
+ */
+
+#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 acba1737f51843882d98c42056f5a1f132ddafc0..9c5d8aeee57778cbc4cb62839a95d86e792a4e05 100644 (file)
 #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 223bf1af9ff28359b56bdebd9953f87ada8f4046..ca06b090f3e538954c32b5744596225ae8a77d3f 100644 (file)
@@ -11,7 +11,7 @@
 #define PROCESS_H
 
 #include <stdint.h>
-#include "interrupts.h" // For struct registers
+#include "arch_types.h"
 #include "fs.h"
 #include "signal.h"
 
@@ -74,7 +74,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
@@ -162,12 +162,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 3e88b07ea4b03fef2c59ca868764b0aa31dcfad4..80f92fe615f80190f98b90f115a3fda1e933cba8 100644 (file)
@@ -48,13 +48,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 89705e1b5c840f3313c6b5a0afb3d4d0b7240fe0..85ebb7b3ecc4ef2ce9075fa8bfe119260f89c2c1 100644 (file)
@@ -15,8 +15,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 4ebc4e46eb39e8b28e68e6793320b137035dbffc..579f30a04bb88ddde040b8fd5886576600a56d57 100644 (file)
@@ -23,9 +23,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 eab3bde530418ebc0752f38fd0cf7071607d6d2f..b5328c2262f4c2d32206bbae830c9928cf58a3e0 100644 (file)
@@ -424,10 +424,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);
@@ -466,7 +466,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;
@@ -520,12 +520,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;
 
@@ -610,12 +610,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 */