git: 361971fbca5f - main - Rework how shared page related data is stored

From: Kornel Dulęba <kd_at_FreeBSD.org>
Date: Mon, 18 Jul 2022 14:29:46 UTC
The branch main has been updated by kd:

URL: https://cgit.FreeBSD.org/src/commit/?id=361971fbca5fdb8121dd4d05119d81269af78ea7

commit 361971fbca5fdb8121dd4d05119d81269af78ea7
Author:     Kornel Dulęba <kd@FreeBSD.org>
AuthorDate: 2022-06-02 07:58:12 +0000
Commit:     Kornel Dulęba <kd@FreeBSD.org>
CommitDate: 2022-07-18 14:27:32 +0000

    Rework how shared page related data is stored
    
    Store the shared page address in struct vmspace.
    Also instead of storing absolute addresses of various shared page
    segments save their offsets with respect to the shared page address.
    This will be more useful when the shared page address is randomized.
    
    Approved by:    mw(mentor)
    Sponsored by:   Stormshield
    Obtained from:  Semihalf
    Reviewed by:    kib
    Differential Revision: https://reviews.freebsd.org/D35393
---
 sys/amd64/amd64/exec_machdep.c        |  1 +
 sys/amd64/linux/linux_sysvec.c        |  2 +-
 sys/amd64/linux32/linux32_sysvec.c    |  2 +-
 sys/arm/arm/exec_machdep.c            |  2 +-
 sys/arm64/arm64/exec_machdep.c        |  2 ++
 sys/arm64/arm64/freebsd32_machdep.c   |  2 +-
 sys/arm64/linux/linux_sysvec.c        |  2 +-
 sys/compat/freebsd32/freebsd32_misc.c |  2 +-
 sys/i386/i386/exec_machdep.c          |  2 +-
 sys/i386/linux/linux_sysvec.c         |  2 +-
 sys/kern/imgact_elf.c                 | 21 ++++++++++-----
 sys/kern/kern_exec.c                  | 11 ++++----
 sys/kern/kern_proc.c                  |  4 +--
 sys/kern/kern_sharedpage.c            | 49 ++++++++++++-----------------------
 sys/powerpc/powerpc/elf32_machdep.c   |  2 ++
 sys/powerpc/powerpc/elf64_machdep.c   |  6 +++--
 sys/powerpc/powerpc/elf_common.c      |  7 +++--
 sys/powerpc/powerpc/exec_machdep.c    |  3 +++
 sys/riscv/riscv/exec_machdep.c        |  2 +-
 sys/sys/exec.h                        |  8 +++---
 sys/sys/sysent.h                      |  8 +++---
 sys/vm/vm_map.c                       |  1 +
 sys/vm/vm_map.h                       |  1 +
 23 files changed, 75 insertions(+), 67 deletions(-)

diff --git a/sys/amd64/amd64/exec_machdep.c b/sys/amd64/amd64/exec_machdep.c
index 1e537cad43f4..50de0421922a 100644
--- a/sys/amd64/amd64/exec_machdep.c
+++ b/sys/amd64/amd64/exec_machdep.c
@@ -77,6 +77,7 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm_param.h>
 #include <vm/vm_extern.h>
 #include <vm/pmap.h>
+#include <vm/vm_map.h>
 
 #ifdef DDB
 #ifndef KDB
diff --git a/sys/amd64/linux/linux_sysvec.c b/sys/amd64/linux/linux_sysvec.c
index 25fc8b10e903..abb498370f79 100644
--- a/sys/amd64/linux/linux_sysvec.c
+++ b/sys/amd64/linux/linux_sysvec.c
@@ -772,7 +772,7 @@ linux_exec_sysvec_init(void *param)
 
 	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
index e9162f04d3f7..bd10d659979c 100644
--- a/sys/amd64/linux32/linux32_sysvec.c
+++ b/sys/amd64/linux32/linux32_sysvec.c
@@ -924,7 +924,7 @@ linux_exec_sysvec_init(void *param)
 
 	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
index 56e6006c0767..2bf3efff7fe4 100644
--- a/sys/arm/arm/exec_machdep.c
+++ b/sys/arm/arm/exec_machdep.c
@@ -346,7 +346,7 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
 	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
index 49765e73f390..6109a866a2d0 100644
--- a/sys/arm64/arm64/exec_machdep.c
+++ b/sys/arm64/arm64/exec_machdep.c
@@ -50,6 +50,8 @@ __FBSDID("$FreeBSD$");
 
 #include <vm/vm.h>
 #include <vm/vm_param.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
 
 #include <machine/armreg.h>
 #include <machine/kdb.h>
diff --git a/sys/arm64/arm64/freebsd32_machdep.c b/sys/arm64/arm64/freebsd32_machdep.c
index 85ed3b923bc0..9b62802efbc5 100644
--- a/sys/arm64/arm64/freebsd32_machdep.c
+++ b/sys/arm64/arm64/freebsd32_machdep.c
@@ -418,7 +418,7 @@ freebsd32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
 	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
index 732eddf0c308..362917c3de31 100644
--- a/sys/arm64/linux/linux_sysvec.c
+++ b/sys/arm64/linux/linux_sysvec.c
@@ -619,7 +619,7 @@ linux_exec_sysvec_init(void *param)
 
 	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
index 67dcaa35cae5..d1c44a4f9952 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -3525,7 +3525,7 @@ freebsd32_copyout_strings(struct image_params *imgp, uintptr_t *stack_base)
 	/*
 	 * 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
index ba85cf9756a9..29c06ff86ca8 100644
--- a/sys/i386/i386/exec_machdep.c
+++ b/sys/i386/i386/exec_machdep.c
@@ -237,7 +237,7 @@ osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
 	}
 
 	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
index 269ab3b7ab75..e964f475a393 100644
--- a/sys/i386/linux/linux_sysvec.c
+++ b/sys/i386/linux/linux_sysvec.c
@@ -866,7 +866,7 @@ linux_exec_sysvec_init(void *param)
 
 	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
index 964e9c999d60..c71b00337027 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -1433,11 +1433,14 @@ __elfN(freebsd_copyout_auxargs)(struct image_params *imgp, uintptr_t base)
 {
 	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 @@ __elfN(freebsd_copyout_auxargs)(struct image_params *imgp, uintptr_t base)
 		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 @@ __elfN(freebsd_copyout_auxargs)(struct image_params *imgp, uintptr_t base)
 	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
index 5951883cdc62..2d46bc018173 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -1106,18 +1106,16 @@ void
 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 @@ exec_new_vmspace(struct image_params *imgp, struct sysentvec *sv)
 			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 @@ exec_copyout_strings(struct image_params *imgp, uintptr_t *stack_base)
 	/*
 	 * 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
index 3938bfe611b9..56bdb6aa3837 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -3096,7 +3096,7 @@ sysctl_kern_proc_sigtramp(SYSCTL_HANDLER_ARGS)
 	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 @@ sysctl_kern_proc_sigtramp(SYSCTL_HANDLER_ARGS)
 	}
 #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
index 3aa5501eafdc..f90e90b0feaf 100644
--- a/sys/kern/kern_sharedpage.c
+++ b/sys/kern/kern_sharedpage.c
@@ -305,10 +305,6 @@ void
 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 @@ exec_sysvec_init(void *param)
 	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 @@ exec_sysvec_init(void *param)
 				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 @@ exec_sysvec_init(void *param)
 				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 @@ exec_sysvec_init(void *param)
 		 */
 		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 @@ exec_sysvec_init_secondary(struct sysentvec *sv, struct sysentvec *sv2)
 	    (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
index 2efe9a5fdca8..c518080ebad3 100644
--- a/sys/powerpc/powerpc/elf32_machdep.c
+++ b/sys/powerpc/powerpc/elf32_machdep.c
@@ -52,6 +52,8 @@
 
 #include <vm/vm.h>
 #include <vm/vm_param.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
 
 #include <machine/altivec.h>
 #include <machine/cpu.h>
diff --git a/sys/powerpc/powerpc/elf64_machdep.c b/sys/powerpc/powerpc/elf64_machdep.c
index 93b66461308d..a247a2c51ad6 100644
--- a/sys/powerpc/powerpc/elf64_machdep.c
+++ b/sys/powerpc/powerpc/elf64_machdep.c
@@ -49,6 +49,8 @@
 
 #include <vm/vm.h>
 #include <vm/vm_param.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
 
 #include <machine/altivec.h>
 #include <machine/cpu.h>
@@ -216,10 +218,10 @@ ppc64_init_sysvecs(void *arg)
 	 * 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
index c7460848b89a..2ee7fd96b94d 100644
--- a/sys/powerpc/powerpc/elf_common.c
+++ b/sys/powerpc/powerpc/elf_common.c
@@ -34,6 +34,7 @@ __elfN(powerpc_copyout_auxargs)(struct image_params *imgp, uintptr_t base)
 {
 	Elf_Auxargs *args;
 	Elf_Auxinfo *argarray, *pos;
+	struct vmspace *vmspace;
 	int error;
 
 	/*
@@ -58,6 +59,8 @@ __elfN(powerpc_copyout_auxargs)(struct image_params *imgp, uintptr_t base)
 	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 @@ __elfN(powerpc_copyout_auxargs)(struct image_params *imgp, uintptr_t base)
 		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
index 000892bdf295..c06c13a86368 100644
--- a/sys/powerpc/powerpc/exec_machdep.c
+++ b/sys/powerpc/powerpc/exec_machdep.c
@@ -94,7 +94,10 @@ __FBSDID("$FreeBSD$");
 #include <machine/trap.h>
 #include <machine/vmparam.h>
 
+#include <vm/vm.h>
+#include <vm/vm_param.h>
 #include <vm/pmap.h>
+#include <vm/vm_map.h>
 
 #ifdef FPU_EMU
 #include <powerpc/fpu/fpu_extern.h>
diff --git a/sys/riscv/riscv/exec_machdep.c b/sys/riscv/riscv/exec_machdep.c
index d45e8b808f74..ab79c0384eb3 100644
--- a/sys/riscv/riscv/exec_machdep.c
+++ b/sys/riscv/riscv/exec_machdep.c
@@ -415,7 +415,7 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
 	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
index 8e62876deb81..dd7a99475cbd 100644
--- a/sys/sys/exec.h
+++ b/sys/sys/exec.h
@@ -92,11 +92,13 @@ struct execsw {
 
 /*
  * 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
index f677050db769..a77feb5bcbf7 100644
--- a/sys/sys/sysent.h
+++ b/sys/sys/sysent.h
@@ -137,19 +137,19 @@ struct sysentvec {
 	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.c b/sys/vm/vm_map.c
index 04310e42218f..a7efa00da1e2 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -4259,6 +4259,7 @@ vmspace_fork(struct vmspace *vm1, vm_ooffset_t *fork_charge)
 	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);
diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h
index 8f318b34e601..2ac54a39a57b 100644
--- a/sys/vm/vm_map.h
+++ b/sys/vm/vm_map.h
@@ -295,6 +295,7 @@ struct vmspace {
 	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