diff --git a/sys/amd64/amd64/exec_machdep.c b/sys/amd64/amd64/exec_machdep.c --- a/sys/amd64/amd64/exec_machdep.c +++ b/sys/amd64/amd64/exec_machdep.c @@ -77,6 +77,7 @@ #include #include #include +#include #ifdef DDB #ifndef KDB diff --git a/sys/amd64/linux/linux_sysvec.c b/sys/amd64/linux/linux_sysvec.c --- a/sys/amd64/linux/linux_sysvec.c +++ b/sys/amd64/linux/linux_sysvec.c @@ -772,7 +772,7 @@ tkoff = kern_timekeep_base - linux_vdso_base; ktimekeep_base = (l_uintptr_t *)(linux_vdso_mapping + tkoff); - *ktimekeep_base = sv->sv_timekeep_base; + *ktimekeep_base = sv->sv_shared_page_base + sv->sv_timekeep_offset; tkoff = kern_tsc_selector - linux_vdso_base; ktsc_selector = (l_uintptr_t *)(linux_vdso_mapping + tkoff); diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c --- a/sys/amd64/linux32/linux32_sysvec.c +++ b/sys/amd64/linux32/linux32_sysvec.c @@ -924,7 +924,7 @@ tkoff = kern_timekeep_base - linux_vdso_base; ktimekeep_base = (l_uintptr_t *)(linux_vdso_mapping + tkoff); - *ktimekeep_base = sv->sv_timekeep_base; + *ktimekeep_base = sv->sv_shared_page_base + sv->sv_timekeep_offset; tkoff = kern_tsc_selector - linux_vdso_base; ktsc_selector = (l_uintptr_t *)(linux_vdso_mapping + tkoff); diff --git a/sys/arm/arm/exec_machdep.c b/sys/arm/arm/exec_machdep.c --- a/sys/arm/arm/exec_machdep.c +++ b/sys/arm/arm/exec_machdep.c @@ -346,7 +346,7 @@ tf->tf_pc = (register_t)catcher; tf->tf_usr_sp = (register_t)fp; sysent = p->p_sysent; - if (sysent->sv_sigcode_base != 0) + if (PROC_HAS_SHP(p)) tf->tf_usr_lr = (register_t)PROC_SIGCODE(p); else tf->tf_usr_lr = (register_t)(PROC_PS_STRINGS(p) - diff --git a/sys/arm64/arm64/exec_machdep.c b/sys/arm64/arm64/exec_machdep.c --- a/sys/arm64/arm64/exec_machdep.c +++ b/sys/arm64/arm64/exec_machdep.c @@ -50,6 +50,8 @@ #include #include +#include +#include #include #include diff --git a/sys/arm64/arm64/freebsd32_machdep.c b/sys/arm64/arm64/freebsd32_machdep.c --- a/sys/arm64/arm64/freebsd32_machdep.c +++ b/sys/arm64/arm64/freebsd32_machdep.c @@ -418,7 +418,7 @@ tf->tf_elr = (register_t)catcher; tf->tf_x[13] = (register_t)fp; sysent = p->p_sysent; - if (sysent->sv_sigcode_base != 0) + if (PROC_HAS_SHP(p)) tf->tf_x[14] = (register_t)PROC_SIGCODE(p); else tf->tf_x[14] = (register_t)(PROC_PS_STRINGS(p) - diff --git a/sys/arm64/linux/linux_sysvec.c b/sys/arm64/linux/linux_sysvec.c --- a/sys/arm64/linux/linux_sysvec.c +++ b/sys/arm64/linux/linux_sysvec.c @@ -619,7 +619,7 @@ tkoff = kern_timekeep_base - linux_vdso_base; ktimekeep_base = (l_uintptr_t *)(linux_vdso_mapping + tkoff); - *ktimekeep_base = sv->sv_timekeep_base; + *ktimekeep_base = sv->sv_shared_page_base + sv->sv_timekeep_offset; } SYSINIT(elf_linux_exec_sysvec_init, SI_SUB_EXEC + 1, SI_ORDER_ANY, linux_exec_sysvec_init, &elf_linux_sysvec); diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -3525,7 +3525,7 @@ /* * Install sigcode. */ - if (sysent->sv_sigcode_base == 0) { + if (!PROC_HAS_SHP(imgp->proc)) { szsigcode = *sysent->sv_szsigcode; destp -= szsigcode; destp = rounddown2(destp, sizeof(uint32_t)); diff --git a/sys/i386/i386/exec_machdep.c b/sys/i386/i386/exec_machdep.c --- a/sys/i386/i386/exec_machdep.c +++ b/sys/i386/i386/exec_machdep.c @@ -237,7 +237,7 @@ } regs->tf_esp = (int)fp; - if (p->p_sysent->sv_sigcode_base != 0) { + if (PROC_HAS_SHP(p)) { regs->tf_eip = PROC_SIGCODE(p) + szsigcode - szosigcode; } else { diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c --- a/sys/i386/linux/linux_sysvec.c +++ b/sys/i386/linux/linux_sysvec.c @@ -866,7 +866,7 @@ tkoff = kern_timekeep_base - linux_vdso_base; ktimekeep_base = (l_uintptr_t *)(linux_vdso_mapping + tkoff); - *ktimekeep_base = sv->sv_timekeep_base; + *ktimekeep_base = sv->sv_shared_page_base + sv->sv_timekeep_offset; tkoff = kern_tsc_selector - linux_vdso_base; ktsc_selector = (l_uintptr_t *)(linux_vdso_mapping + tkoff); diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -1433,11 +1433,14 @@ { Elf_Auxargs *args = (Elf_Auxargs *)imgp->auxargs; Elf_Auxinfo *argarray, *pos; + struct vmspace *vmspace; int error; argarray = pos = malloc(AT_COUNT * sizeof(*pos), M_TEMP, M_WAITOK | M_ZERO); + vmspace = imgp->proc->p_vmspace; + if (args->execfd != -1) AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd); AUXARGS_ENTRY(pos, AT_PHDR, args->phdr); @@ -1461,9 +1464,9 @@ AUXARGS_ENTRY_PTR(pos, AT_PAGESIZES, imgp->pagesizes); AUXARGS_ENTRY(pos, AT_PAGESIZESLEN, imgp->pagesizeslen); } - if (imgp->sysent->sv_timekeep_base != 0) { + if ((imgp->sysent->sv_flags & SV_TIMEKEEP) != 0) { AUXARGS_ENTRY(pos, AT_TIMEKEEP, - imgp->sysent->sv_timekeep_base); + vmspace->vm_shp_base + imgp->sysent->sv_timekeep_offset); } AUXARGS_ENTRY(pos, AT_STACKPROT, imgp->sysent->sv_shared_page_obj != NULL && imgp->stack_prot != 0 ? imgp->stack_prot : @@ -1479,10 +1482,16 @@ AUXARGS_ENTRY(pos, AT_ENVC, imgp->args->envc); AUXARGS_ENTRY_PTR(pos, AT_ENVV, imgp->envv); AUXARGS_ENTRY_PTR(pos, AT_PS_STRINGS, imgp->ps_strings); - if (imgp->sysent->sv_fxrng_gen_base != 0) - AUXARGS_ENTRY(pos, AT_FXRNG, imgp->sysent->sv_fxrng_gen_base); - if (imgp->sysent->sv_vdso_base != 0 && __elfN(vdso) != 0) - AUXARGS_ENTRY(pos, AT_KPRELOAD, imgp->sysent->sv_vdso_base); +#ifdef RANDOM_FENESTRASX + if ((imgp->sysent->sv_flags & SV_RNG_SEED_VER) != 0) { + AUXARGS_ENTRY(pos, AT_FXRNG, + vmspace->vm_shp_base + imgp->sysent->sv_fxrng_gen_offset); + } +#endif + if ((imgp->sysent->sv_flags & SV_DSO_SIG) != 0 && __elfN(vdso) != 0) { + AUXARGS_ENTRY(pos, AT_KPRELOAD, + vmspace->vm_shp_base + imgp->sysent->sv_vdso_offset); + } AUXARGS_ENTRY(pos, AT_NULL, 0); free(imgp->auxargs, M_TEMP); 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 @@ -1106,18 +1106,16 @@ exec_free_abi_mappings(struct proc *p) { struct vmspace *vmspace; - struct sysentvec *sv; vmspace = p->p_vmspace; if (refcount_load(&vmspace->vm_refcnt) != 1) return; - sv = p->p_sysent; - if (sv->sv_shared_page_obj == NULL) + if (!PROC_HAS_SHP(p)) return; - pmap_remove(vmspace_pmap(vmspace), sv->sv_shared_page_base, - sv->sv_shared_page_base + sv->sv_shared_page_len); + pmap_remove(vmspace_pmap(vmspace), vmspace->vm_shp_base, + vmspace->vm_shp_base + p->p_sysent->sv_shared_page_len); } /* @@ -1192,6 +1190,7 @@ vm_object_deallocate(obj); return (vm_mmap_to_errno(error)); } + vmspace->vm_shp_base = sv->sv_shared_page_base; } return (sv->sv_onexec != NULL ? sv->sv_onexec(p, imgp) : 0); @@ -1633,7 +1632,7 @@ /* * Install sigcode. */ - if (sysent->sv_sigcode_base == 0 && sysent->sv_szsigcode != NULL) { + if (sysent->sv_shared_page_base == 0 && sysent->sv_szsigcode != NULL) { szsigcode = *(sysent->sv_szsigcode); destp -= szsigcode; destp = rounddown2(destp, sizeof(void *)); diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -3096,7 +3096,7 @@ if ((req->flags & SCTL_MASK32) != 0) { bzero(&kst32, sizeof(kst32)); if (SV_PROC_FLAG(p, SV_ILP32)) { - if (sv->sv_sigcode_base != 0) { + if (PROC_HAS_SHP(p)) { kst32.ksigtramp_start = PROC_SIGCODE(p); kst32.ksigtramp_end = kst32.ksigtramp_start + ((sv->sv_flags & SV_DSO_SIG) == 0 ? @@ -3114,7 +3114,7 @@ } #endif bzero(&kst, sizeof(kst)); - if (sv->sv_sigcode_base != 0) { + if (PROC_HAS_SHP(p)) { kst.ksigtramp_start = (char *)PROC_SIGCODE(p); kst.ksigtramp_end = (char *)kst.ksigtramp_start + ((sv->sv_flags & SV_DSO_SIG) == 0 ? *sv->sv_szsigcode : diff --git a/sys/kern/kern_sharedpage.c b/sys/kern/kern_sharedpage.c --- a/sys/kern/kern_sharedpage.c +++ b/sys/kern/kern_sharedpage.c @@ -305,10 +305,6 @@ exec_sysvec_init(void *param) { struct sysentvec *sv; - vm_offset_t sb; -#ifdef RANDOM_FENESTRASX - ptrdiff_t base; -#endif u_int flags; int res; @@ -322,19 +318,18 @@ sv->sv_shared_page_obj = shared_page_obj; if ((flags & SV_ABI_MASK) == SV_ABI_FREEBSD) { if ((flags & SV_DSO_SIG) != 0) { - sb = sv->sv_shared_page_base; res = shared_page_fill((uintptr_t)sv->sv_szsigcode, 16, sv->sv_sigcode); if (res == -1) - panic("copying sigtramp to shared page"); - sb += res; - sv->sv_vdso_base = sb; - sb += sv->sv_sigcodeoff; - sv->sv_sigcode_base = sb; + panic("copying vdso to shared page"); + sv->sv_vdso_offset = res; + sv->sv_sigcode_offset = res + sv->sv_sigcodeoff; } else { - sv->sv_sigcode_base = sv->sv_shared_page_base + - shared_page_fill(*(sv->sv_szsigcode), 16, - sv->sv_sigcode); + res = shared_page_fill(*(sv->sv_szsigcode), + 16, sv->sv_sigcode); + if (res == -1) + panic("copying sigtramp to shared page"); + sv->sv_sigcode_offset = res; } } if ((flags & SV_TIMEKEEP) != 0) { @@ -348,8 +343,7 @@ KASSERT(compat32_svtk != NULL, ("Compat32 not registered")); } - sv->sv_timekeep_base = sv->sv_shared_page_base + - compat32_svtk->sv_timekeep_off; + sv->sv_timekeep_offset = compat32_svtk->sv_timekeep_off; } else { #endif if ((flags & SV_ABI_MASK) == SV_ABI_FREEBSD) { @@ -360,8 +354,7 @@ KASSERT(host_svtk != NULL, ("Host not registered")); } - sv->sv_timekeep_base = sv->sv_shared_page_base + - host_svtk->sv_timekeep_off; + sv->sv_timekeep_offset = host_svtk->sv_timekeep_off; #ifdef COMPAT_FREEBSD32 } #endif @@ -375,8 +368,8 @@ */ if (fxrng_shpage_mapping == NULL) alloc_sv_fxrng_generation(); - base = (char *)fxrng_shpage_mapping - shared_page_mapping; - sv->sv_fxrng_gen_base = sv->sv_shared_page_base + base; + sv->sv_fxrng_gen_offset = + (char *)fxrng_shpage_mapping - shared_page_mapping; } #endif } @@ -392,20 +385,10 @@ (sv->sv_flags & SV_RNG_SEED_VER)); sv2->sv_shared_page_obj = sv->sv_shared_page_obj; - sv2->sv_sigcode_base = sv2->sv_shared_page_base + - (sv->sv_sigcode_base - sv->sv_shared_page_base); - if ((sv2->sv_flags & SV_DSO_SIG) != 0) { - sv2->sv_vdso_base = sv2->sv_shared_page_base + - (sv->sv_vdso_base - sv->sv_shared_page_base); - } + sv2->sv_sigcode_offset = sv->sv_sigcode_offset; + sv2->sv_vdso_offset = sv->sv_vdso_offset; if ((sv2->sv_flags & SV_ABI_MASK) != SV_ABI_FREEBSD) return; - if ((sv2->sv_flags & SV_TIMEKEEP) != 0) { - sv2->sv_timekeep_base = sv2->sv_shared_page_base + - (sv->sv_timekeep_base - sv->sv_shared_page_base); - } - if ((sv2->sv_flags & SV_RNG_SEED_VER) != 0) { - sv2->sv_fxrng_gen_base = sv2->sv_shared_page_base + - (sv->sv_fxrng_gen_base - sv->sv_shared_page_base); - } + sv2->sv_timekeep_offset = sv->sv_timekeep_offset; + sv2->sv_fxrng_gen_offset = sv->sv_fxrng_gen_offset; } diff --git a/sys/powerpc/powerpc/elf32_machdep.c b/sys/powerpc/powerpc/elf32_machdep.c --- a/sys/powerpc/powerpc/elf32_machdep.c +++ b/sys/powerpc/powerpc/elf32_machdep.c @@ -52,6 +52,8 @@ #include #include +#include +#include #include #include diff --git a/sys/powerpc/powerpc/elf64_machdep.c b/sys/powerpc/powerpc/elf64_machdep.c --- a/sys/powerpc/powerpc/elf64_machdep.c +++ b/sys/powerpc/powerpc/elf64_machdep.c @@ -49,6 +49,8 @@ #include #include +#include +#include #include #include @@ -216,10 +218,10 @@ * exec_sysvec_init_secondary() assumes secondary sysvecs use * identical signal code, and skips allocating a second copy. * Since the ELFv2 trampoline is a strict subset of the ELFv1 code, - * we can work around this by adjusting the base address. This also + * we can work around this by adjusting the offset. This also * avoids two copies of the trampoline code being allocated! */ - elf64_freebsd_sysvec_v2.sv_sigcode_base += + elf64_freebsd_sysvec_v2.sv_sigcode_offset += (uintptr_t)sigcode64_elfv2 - (uintptr_t)&sigcode64; elf64_freebsd_sysvec_v2.sv_szsigcode = &szsigcode64_elfv2; } diff --git a/sys/powerpc/powerpc/elf_common.c b/sys/powerpc/powerpc/elf_common.c --- a/sys/powerpc/powerpc/elf_common.c +++ b/sys/powerpc/powerpc/elf_common.c @@ -34,6 +34,7 @@ { Elf_Auxargs *args; Elf_Auxinfo *argarray, *pos; + struct vmspace *vmspace; int error; /* @@ -58,6 +59,8 @@ argarray = pos = malloc(AT_OLD_COUNT * sizeof(*pos), M_TEMP, M_WAITOK | M_ZERO); + vmspace = imgp->proc->p_vmspace; + if (args->execfd != -1) AUXARGS_ENTRY(pos, AT_OLD_EXECFD, args->execfd); AUXARGS_ENTRY(pos, AT_OLD_PHDR, args->phdr); @@ -81,9 +84,9 @@ AUXARGS_ENTRY_PTR(pos, AT_OLD_PAGESIZES, imgp->pagesizes); AUXARGS_ENTRY(pos, AT_OLD_PAGESIZESLEN, imgp->pagesizeslen); } - if (imgp->sysent->sv_timekeep_base != 0) { + if ((imgp->sysent->sv_flags & SV_TIMEKEEP) != 0) { AUXARGS_ENTRY(pos, AT_OLD_TIMEKEEP, - imgp->sysent->sv_timekeep_base); + vmspace->vm_shp_base + imgp->sysent->sv_timekeep_offset); } AUXARGS_ENTRY(pos, AT_OLD_STACKPROT, imgp->sysent->sv_shared_page_obj != NULL && imgp->stack_prot != 0 ? imgp->stack_prot : diff --git a/sys/powerpc/powerpc/exec_machdep.c b/sys/powerpc/powerpc/exec_machdep.c --- a/sys/powerpc/powerpc/exec_machdep.c +++ b/sys/powerpc/powerpc/exec_machdep.c @@ -94,7 +94,10 @@ #include #include +#include +#include #include +#include #ifdef FPU_EMU #include diff --git a/sys/riscv/riscv/exec_machdep.c b/sys/riscv/riscv/exec_machdep.c --- a/sys/riscv/riscv/exec_machdep.c +++ b/sys/riscv/riscv/exec_machdep.c @@ -415,7 +415,7 @@ tf->tf_sp = (register_t)fp; sysent = p->p_sysent; - if (sysent->sv_sigcode_base != 0) + if (PROC_HAS_SHP(p)) tf->tf_ra = (register_t)PROC_SIGCODE(p); else tf->tf_ra = (register_t)(PROC_PS_STRINGS(p) - diff --git a/sys/sys/exec.h b/sys/sys/exec.h --- a/sys/sys/exec.h +++ b/sys/sys/exec.h @@ -92,11 +92,13 @@ /* * Address of signal trampoline (in user space). - * This assumes that the sigcode resides in the shared page, which is true - * in all cases, except for a.out binaries. + * This assumes that the sigcode resides in the shared page. */ #define PROC_SIGCODE(p) \ - ((p)->p_sysent->sv_sigcode_base) + ((p)->p_vmspace->vm_shp_base + (p)->p_sysent->sv_sigcode_offset) + +#define PROC_HAS_SHP(p) \ + ((p)->p_sysent->sv_shared_page_obj != NULL) int exec_map_first_page(struct image_params *); void exec_unmap_first_page(struct image_params *); diff --git a/sys/sys/sysent.h b/sys/sys/sysent.h --- a/sys/sys/sysent.h +++ b/sys/sys/sysent.h @@ -137,19 +137,19 @@ void (*sv_set_syscall_retval)(struct thread *, int); int (*sv_fetch_syscall_args)(struct thread *); const char **sv_syscallnames; - vm_offset_t sv_timekeep_base; + vm_offset_t sv_timekeep_offset; vm_offset_t sv_shared_page_base; vm_offset_t sv_shared_page_len; - vm_offset_t sv_sigcode_base; + vm_offset_t sv_sigcode_offset; void *sv_shared_page_obj; - vm_offset_t sv_vdso_base; + vm_offset_t sv_vdso_offset; void (*sv_schedtail)(struct thread *); void (*sv_thread_detach)(struct thread *); int (*sv_trap)(struct thread *); u_long *sv_hwcap; /* Value passed in AT_HWCAP. */ u_long *sv_hwcap2; /* Value passed in AT_HWCAP2. */ const char *(*sv_machine_arch)(struct proc *); - vm_offset_t sv_fxrng_gen_base; + vm_offset_t sv_fxrng_gen_offset; void (*sv_onexec_old)(struct thread *td); int (*sv_onexec)(struct proc *, struct image_params *); void (*sv_onexit)(struct proc *); diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h --- a/sys/vm/vm_map.h +++ b/sys/vm/vm_map.h @@ -295,6 +295,7 @@ caddr_t vm_daddr; /* (c) user virtual address of data */ caddr_t vm_maxsaddr; /* user VA at max stack growth */ vm_offset_t vm_stacktop; /* top of the stack, may not be page-aligned */ + vm_offset_t vm_shp_base; /* shared page address */ u_int vm_refcnt; /* number of references */ /* * Keep the PMAP last, so that CPU-specific variations of that diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -4259,6 +4259,7 @@ vm2->vm_daddr = vm1->vm_daddr; vm2->vm_maxsaddr = vm1->vm_maxsaddr; vm2->vm_stacktop = vm1->vm_stacktop; + vm2->vm_shp_base = vm1->vm_shp_base; vm_map_lock(old_map); if (old_map->busy) vm_map_wait_busy(old_map);