Index: sys/compat/netbsd32/netbsd32_compat_16.c =================================================================== RCS file: /cvsroot/src/sys/compat/netbsd32/netbsd32_compat_16.c,v retrieving revision 1.4 diff -p -u -r1.4 netbsd32_compat_16.c --- sys/compat/netbsd32/netbsd32_compat_16.c 26 Nov 2021 08:06:11 -0000 1.4 +++ sys/compat/netbsd32/netbsd32_compat_16.c 1 May 2024 08:08:14 -0000 @@ -36,6 +36,7 @@ __KERNEL_RCSID(0, "$NetBSD: netbsd32_com #include #include #include +#include #include #include #include @@ -47,40 +48,87 @@ __KERNEL_RCSID(0, "$NetBSD: netbsd32_com struct uvm_object *emul_netbsd32_object; -MODULE(MODULE_CLASS_EXEC, compat_netbsd32_16, "compat_netbsd32_20,compat_16"); +static const struct syscall_package netbsd32_kern_sig_16_syscalls[] = { + /* compat_16_netbs32___sigreturn14 is in MD code! */ + { NETBSD32_SYS_compat_16_netbsd32___sigreturn14, 0, + (sy_call_t *)compat_16_netbsd32___sigreturn14 }, + { 0, 0, NULL } +}; static int -compat_netbsd32_16_modcmd(modcmd_t cmd, void *arg) +compat_netbsd32_16_init(void) +{ + int error; + + error = syscall_establish(&emul_netbsd32, netbsd32_kern_sig_16_syscalls); + if (error) + return error; + + rw_enter(&exec_lock, RW_WRITER); + emul_netbsd32.e_sigcode = netbsd32_sigcode; + emul_netbsd32.e_esigcode = netbsd32_esigcode; + emul_netbsd32.e_sigobject = &emul_netbsd32_object; + error = exec_sigcode_alloc(&emul_netbsd); + if (error) { + emul_netbsd32.e_sigcode = NULL; + emul_netbsd32.e_esigcode = NULL; + emul_netbsd32.e_sigobject = NULL; + } + rw_exit(&exec_lock); + if (error) + return error; + netbsd32_machdep_md_16_init(); + return 0; +} + +static int +compat_netbsd32_16_fini(void) { + proc_t *p; int error; + error = syscall_disestablish(&emul_netbsd32, netbsd32_kern_sig_16_syscalls); + if (error) + return error; + /* + * Ensure sendsig_sigcontext() is not being used. + * module_lock prevents the flag being set on any + * further processes while we are here. See + * sigaction1() for the opposing half. + */ + mutex_enter(&proc_lock); + PROCLIST_FOREACH(p, &allproc) { + if ((p->p_lflag & PL_SIGCOMPAT) != 0) { + break; + } + } + mutex_exit(&proc_lock); + if (p != NULL) { + syscall_establish(&emul_netbsd32, netbsd32_kern_sig_16_syscalls); + return EBUSY; + } + + rw_enter(&exec_lock, RW_WRITER); + exec_sigcode_free(&emul_netbsd); + emul_netbsd32.e_sigcode = NULL; + emul_netbsd32.e_esigcode = NULL; + emul_netbsd32.e_sigobject = NULL; + rw_exit(&exec_lock); + netbsd32_machdep_md_16_fini(); + return 0; +} + +MODULE(MODULE_CLASS_EXEC, compat_netbsd32_16, "compat_netbsd32_20,compat_16"); + +static int +compat_netbsd32_16_modcmd(modcmd_t cmd, void *arg) +{ switch (cmd) { case MODULE_CMD_INIT: - rw_enter(&exec_lock, RW_WRITER); - emul_netbsd32.e_sigcode = netbsd32_sigcode; - emul_netbsd32.e_esigcode = netbsd32_esigcode; - emul_netbsd32.e_sigobject = &emul_netbsd32_object; - error = exec_sigcode_alloc(&emul_netbsd); - if (error) { - emul_netbsd32.e_sigcode = NULL; - emul_netbsd32.e_esigcode = NULL; - emul_netbsd32.e_sigobject = NULL; - } - rw_exit(&exec_lock); - if (error) - return error; - netbsd32_machdep_md_16_init(); - return 0; + return compat_netbsd32_16_init(); case MODULE_CMD_FINI: - rw_enter(&exec_lock, RW_WRITER); - exec_sigcode_free(&emul_netbsd); - emul_netbsd32.e_sigcode = NULL; - emul_netbsd32.e_esigcode = NULL; - emul_netbsd32.e_sigobject = NULL; - rw_exit(&exec_lock); - netbsd32_machdep_md_16_fini(); - return 0; + return compat_netbsd32_16_fini(); default: return ENOTTY;