diff --git a/sys/amd64/amd64/elf_machdep.c b/sys/amd64/amd64/elf_machdep.c --- a/sys/amd64/amd64/elf_machdep.c +++ b/sys/amd64/amd64/elf_machdep.c @@ -85,6 +85,8 @@ .sv_thread_detach = NULL, .sv_trap = NULL, .sv_stackgap = elf64_stackgap, + .sv_onexec_old = exec_onexec_old, + .sv_onexit = exit_onexit, }; struct sysentvec elf64_freebsd_sysvec_la57 = { @@ -123,6 +125,8 @@ .sv_thread_detach = NULL, .sv_trap = NULL, .sv_stackgap = elf64_stackgap, + .sv_onexec_old = exec_onexec_old, + .sv_onexit = exit_onexit, }; static void diff --git a/sys/compat/ia32/ia32_sysvec.c b/sys/compat/ia32/ia32_sysvec.c --- a/sys/compat/ia32/ia32_sysvec.c +++ b/sys/compat/ia32/ia32_sysvec.c @@ -131,6 +131,8 @@ .sv_thread_detach = NULL, .sv_trap = NULL, .sv_stackgap = elf32_stackgap, + .sv_onexec_old = exec_onexec_old, + .sv_onexit = exit_onexit, }; INIT_SYSENTVEC(elf_ia32_sysvec, &ia32_freebsd_sysvec); diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -1040,6 +1040,13 @@ } } +void +exec_onexec_old(struct thread *td) +{ + sigfastblock_clear(td); + umtx_exec(td->td_proc); +} + /* * Destroy old address space, and allocate a new stack. * The new stack is only sgrowsiz large because it is grown @@ -1062,8 +1069,8 @@ imgp->vmspace_destroyed = 1; imgp->sysent = sv; - sigfastblock_clear(td); - umtx_exec(p); + if (p->p_sysent->sv_onexec_old != NULL) + p->p_sysent->sv_onexec_old(td); itimers_exec(p); if (sv->sv_onexec != NULL) sv->sv_onexec(p, imgp); diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -195,6 +195,13 @@ p->p_treeflag &= ~P_TREE_ORPHANED; } +void +exit_onexit(struct proc *p) +{ + MPASS(p->p_numthreads == 1); + umtx_thread_exit(FIRST_THREAD_IN_PROC(p)); +} + /* * exit -- death of process. */ @@ -340,9 +347,6 @@ itimers_exit(p); - if (p->p_sysent->sv_onexit != NULL) - p->p_sysent->sv_onexit(p); - /* * Check if any loadable modules need anything done at process exit. * E.g. SYSV IPC stuff. @@ -373,7 +377,8 @@ PROC_UNLOCK(p); - umtx_thread_exit(td); + if (p->p_sysent->sv_onexit != NULL) + p->p_sysent->sv_onexit(p); seltdfini(td); /* diff --git a/sys/sys/sysent.h b/sys/sys/sysent.h --- a/sys/sys/sysent.h +++ b/sys/sys/sysent.h @@ -150,6 +150,7 @@ u_long *sv_hwcap2; /* Value passed in AT_HWCAP2. */ const char *(*sv_machine_arch)(struct proc *); vm_offset_t sv_fxrng_gen_base; + void (*sv_onexec_old)(struct thread *td); void (*sv_onexec)(struct proc *, struct image_params *); void (*sv_onexit)(struct proc *); void (*sv_ontdexit)(struct thread *td); @@ -321,6 +322,9 @@ void exec_sysvec_init_secondary(struct sysentvec *sv, struct sysentvec *sv2); void exec_inittk(void); +void exit_onexit(struct proc *p); +void exec_onexec_old(struct thread *td); + #define INIT_SYSENTVEC(name, sv) \ SYSINIT(name, SI_SUB_EXEC, SI_ORDER_ANY, \ (sysinit_cfunc_t)exec_sysvec_init, sv);