- 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
--- /dev/null
+#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 */
#define ARCH_PROCESS_H
#include <stdint.h>
-#include "interrupts.h"
/*
* arch_kstack_init — Prepare a kernel stack for a brand-new process/thread
/*
* 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 */
#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 */
--- /dev/null
+#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 */
#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
#define PROCESS_H
#include <stdint.h>
-#include "interrupts.h" // For struct registers
+#include "arch_types.h"
#include "fs.h"
#include "signal.h"
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
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).
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;
}
#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;
#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
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);
}
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;
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;
}
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 */