sys_execve() to return EJUSTRETURN.
setregs() is the MD routine used by sys_execve() to set up the
thread's trapframe and PCB such that, on 'return' to userspace, it
has the register values defined by the ABI and otherwise zero. It
had to set the syscall retval[] values previously because the normal
syscall return path overwrites a couple registers with the retval[]
values. By instead returning EJUSTRETURN that and some complexity
with program-counter handling on m88k and sparc64 goes away.
Also, give setregs() add a 'struct ps_strings *arginfo' argument
so powerpc, powerpc64, and sh can directly get argc/argv/envp
values for registers instead of copyin()ing the one in userspace.
Improvements from miod@ and millert@
Testing assistance miod@, kettenis@, and aoyama@
ok miod@ kettenis@
-/* $OpenBSD: machdep.c,v 1.198 2022/08/10 10:41:35 miod Exp $ */
+/* $OpenBSD: machdep.c,v 1.199 2022/10/30 17:43:39 guenther Exp $ */
/* $NetBSD: machdep.c,v 1.210 2000/06/01 17:12:38 thorpej Exp $ */
/*-
* Set registers on exec.
*/
void
-setregs(p, pack, stack, retval)
- register struct proc *p;
- struct exec_package *pack;
- u_long stack;
- register_t *retval;
+setregs(struct proc *p, struct exec_package *pack, u_long stack,
+ struct ps_strings *arginfo)
{
struct trapframe *tfp = p->p_md.md_tf;
#ifdef DEBUG
tfp->tf_regs[i] = 0xbabefacedeadbeef;
tfp->tf_regs[FRAME_A1] = 0;
#else
- bzero(tfp->tf_regs, FRAME_SIZE * sizeof tfp->tf_regs[0]);
+ memset(tfp->tf_regs, 0, FRAME_SIZE * sizeof tfp->tf_regs[0]);
#endif
- bzero(&p->p_addr->u_pcb.pcb_fp, sizeof p->p_addr->u_pcb.pcb_fp);
+ memset(&p->p_addr->u_pcb.pcb_fp, 0, sizeof p->p_addr->u_pcb.pcb_fp);
alpha_pal_wrusp(stack);
tfp->tf_regs[FRAME_PS] = ALPHA_PSL_USERSET;
tfp->tf_regs[FRAME_PC] = pack->ep_entry & ~3;
#endif
if (p->p_addr->u_pcb.pcb_fpcpu != NULL)
fpusave_proc(p, 0);
-
- retval[1] = 0;
}
/*
-/* $OpenBSD: machdep.c,v 1.281 2022/10/16 15:03:39 kettenis Exp $ */
+/* $OpenBSD: machdep.c,v 1.282 2022/10/30 17:43:39 guenther Exp $ */
/* $NetBSD: machdep.c,v 1.3 2003/05/07 22:58:18 fvdl Exp $ */
/*-
*/
void
setregs(struct proc *p, struct exec_package *pack, u_long stack,
- register_t *retval)
+ struct ps_strings *arginfo)
{
struct trapframe *tf;
p->p_addr->u_pcb.pcb_fsbase = 0;
tf = p->p_md.md_regs;
- tf->tf_rdi = 0;
- tf->tf_rsi = 0;
- tf->tf_rbp = 0;
- tf->tf_rbx = 0;
- tf->tf_rdx = 0;
- tf->tf_rcx = 0;
- tf->tf_rax = 0;
- tf->tf_r8 = 0;
- tf->tf_r9 = 0;
- tf->tf_r10 = 0;
- tf->tf_r11 = 0;
- tf->tf_r12 = 0;
- tf->tf_r13 = 0;
- tf->tf_r14 = 0;
- tf->tf_r15 = 0;
+ memset(tf, 0, sizeof *tf);
tf->tf_rip = pack->ep_entry;
tf->tf_cs = GSEL(GUCODE_SEL, SEL_UPL);
tf->tf_rflags = PSL_USERSET;
tf->tf_rsp = stack;
tf->tf_ss = GSEL(GUDATA_SEL, SEL_UPL);
-
- retval[1] = 0;
}
/*
-/* $OpenBSD: arm_machdep.c,v 1.6 2021/03/25 04:12:00 jsg Exp $ */
+/* $OpenBSD: arm_machdep.c,v 1.7 2022/10/30 17:43:39 guenther Exp $ */
/* $NetBSD: arm_machdep.c,v 1.7 2003/10/25 19:44:42 scw Exp $ */
/*
void
setregs(struct proc *p, struct exec_package *pack, u_long stack,
- register_t *retval)
+ struct ps_strings *arginfo)
{
struct trapframe *tf;
tf = p->p_addr->u_pcb.pcb_tf;
- memset(tf, 0, sizeof(*tf));
+ memset(tf, 0, sizeof *tf);
/* tf->tf_r0 = (u_int)p->p_proc->p_psstr; */
tf->tf_usr_sp = stack;
tf->tf_usr_lr = pack->ep_entry;
tf->tf_svc_lr = 0x77777777; /* Something we can see */
tf->tf_pc = pack->ep_entry;
tf->tf_spsr = PSR_USR32_MODE;
-
- retval[1] = 0;
}
-/* $OpenBSD: machdep.c,v 1.74 2022/10/04 19:41:21 kettenis Exp $ */
+/* $OpenBSD: machdep.c,v 1.75 2022/10/30 17:43:39 guenther Exp $ */
/*
* Copyright (c) 2014 Patrick Wildt <patrick@blueri.se>
* Copyright (c) 2021 Mark Kettenis <kettenis@openbsd.org>
void
setregs(struct proc *p, struct exec_package *pack, u_long stack,
- register_t *retval)
+ struct ps_strings *arginfo)
{
struct pcb *pcb = &p->p_addr->u_pcb;
struct trapframe *tf = pcb->pcb_tf;
pcb->pcb_flags &= ~PCB_FPU;
fpu_drop();
- memset (tf,0, sizeof(*tf));
+ memset(tf, 0, sizeof *tf);
tf->tf_sp = stack;
tf->tf_lr = pack->ep_entry;
tf->tf_elr = pack->ep_entry; /* ??? */
tf->tf_spsr = PSR_M_EL0t | PSR_DIT;
-
- retval[1] = 0;
}
void
-/* $OpenBSD: machdep.c,v 1.266 2022/08/10 03:18:19 jsg Exp $ */
+/* $OpenBSD: machdep.c,v 1.267 2022/10/30 17:43:39 guenther Exp $ */
/*
* Copyright (c) 1999-2003 Michael Shalayeff
*/
void
setregs(struct proc *p, struct exec_package *pack, u_long stack,
- register_t *retval)
+ struct ps_strings *arginfo)
{
struct trapframe *tf = p->p_md.md_regs;
struct pcb *pcb = &p->p_addr->u_pcb;
+ struct fpreg *fpreg = &pcb->pcb_fpstate->hfp_regs;
- bzero(tf, sizeof(*tf));
+ memset(tf, 0, sizeof *tf);
tf->tf_flags = TFF_SYS|TFF_LAST;
tf->tf_iioq_head = pack->ep_entry | HPPA_PC_PRIV_USER;
tf->tf_iioq_tail = tf->tf_iioq_head + 4;
/* clear the FPU */
fpu_proc_flush(p);
- bzero(&pcb->pcb_fpstate->hfp_regs, sizeof(pcb->pcb_fpstate->hfp_regs));
- pcb->pcb_fpstate->hfp_regs.fpr_regs[0] =
- ((u_int64_t)HPPA_FPU_INIT) << 32;
- pcb->pcb_fpstate->hfp_regs.fpr_regs[1] = 0;
- pcb->pcb_fpstate->hfp_regs.fpr_regs[2] = 0;
- pcb->pcb_fpstate->hfp_regs.fpr_regs[3] = 0;
+ memset(fpreg, 0, sizeof *fpreg);
+ fpreg->fpr_regs[0] = ((u_int64_t)HPPA_FPU_INIT) << 32;
p->p_md.md_bpva = 0;
-
- retval[1] = 0;
}
/*
-/* $OpenBSD: machdep.c,v 1.656 2022/08/25 17:25:25 cheloha Exp $ */
+/* $OpenBSD: machdep.c,v 1.657 2022/10/30 17:43:39 guenther Exp $ */
/* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */
/*-
*/
void
setregs(struct proc *p, struct exec_package *pack, u_long stack,
- register_t *retval)
+ struct ps_strings *arginfo)
{
struct pcb *pcb = &p->p_addr->u_pcb;
struct pmap *pmap = vm_map_pmap(&p->p_vmspace->vm_map);
tf->tf_eflags = PSL_USERSET;
tf->tf_esp = stack;
tf->tf_ss = GSEL(GUDATA_SEL, SEL_UPL);
-
- retval[1] = 0;
}
/*
-/* $OpenBSD: m88k_machdep.c,v 1.70 2019/10/15 10:05:43 mpi Exp $ */
+/* $OpenBSD: m88k_machdep.c,v 1.71 2022/10/30 17:43:39 guenther Exp $ */
/*
* Copyright (c) 1998, 1999, 2000, 2001 Steve Murphree, Jr.
* Copyright (c) 1996 Nivas Madhur
* Clear all except sp and pc.
*/
void
-setregs(p, pack, stack, retval)
- struct proc *p;
- struct exec_package *pack;
- u_long stack;
- register_t retval[2];
+setregs(struct proc *p, struct exec_package *pack, u_long stack,
+ struct ps_strings *arginfo)
{
struct trapframe *tf = (struct trapframe *)USER_REGS(p);
__asm__ volatile ("fstcr %r0, %fcr62");
__asm__ volatile ("fstcr %r0, %fcr63");
- bzero((caddr_t)tf, sizeof *tf);
+ memset(tf, 0, sizeof *tf);
#ifdef M88110
if (CPU_IS88110) {
*/
#ifdef M88110
if (CPU_IS88110) {
- /*
- * m88110_syscall() will resume at exip + 8... which
- * really is the first instruction we want to run.
- */
- tf->tf_exip = pack->ep_entry & XIP_ADDR;
+ /*
+ * The first instruction we want to run is at
+ * ep_entry + 8. m88110_syscall() returning EJUSTRETURN
+ * will resume at exip + 4, so make it point to
+ * ep_entry + 4.
+ */
+ tf->tf_exip = (pack->ep_entry & XIP_ADDR) + 4;
}
#endif
#ifdef M88100
if (CPU_IS88100) {
- /*
- * m88100_syscall() will resume at sfip / sfip + 4...
- */
- tf->tf_sfip = ((pack->ep_entry + 8) & FIP_ADDR) | FIP_V;
-
- /*
- * ... unless we are starting init, in which case we
- * won't be returning through the regular path, and
- * need to explicitly set up nip and fip (note that
- * 88110 do not need such a test).
- * Note that this isn't 100% correct, as it mishandles
- * a real execve() from userspace by process 1. However
- * our init will never do that, so it's okay.
- */
- if (p->p_p->ps_pid == 1) {
- tf->tf_snip = tf->tf_sfip;
- tf->tf_sfip += 4;
- }
+ /*
+ * The first instruction we want to run is at
+ * ep_entry + 8. m88100_syscall() returning EJUSTRETURN
+ * will resume at snip, so make it point to
+ * ep_entry + 8.
+ */
+ tf->tf_snip = ((pack->ep_entry + 8) & FIP_ADDR) | FIP_V;
+ tf->tf_sfip = tf->tf_snip + 4;
}
#endif
- tf->tf_r[2] = retval[0] = stack;
+ tf->tf_r[2] = stack;
tf->tf_r[31] = stack;
- retval[1] = 0;
}
int
-/* $OpenBSD: machdep.c,v 1.198 2022/10/21 22:42:36 gkoehler Exp $ */
+/* $OpenBSD: machdep.c,v 1.199 2022/10/30 17:43:39 guenther Exp $ */
/* $NetBSD: machdep.c,v 1.4 1996/10/16 19:33:11 ws Exp $ */
/*
*/
void
setregs(struct proc *p, struct exec_package *pack, u_long stack,
- register_t *retval)
+ struct ps_strings *arginfo)
{
u_int32_t newstack;
u_int32_t pargs;
- u_int32_t args[4];
-
struct trapframe *tf = trapframe(p);
+
pargs = -roundup(-stack + 8, 16);
newstack = (u_int32_t)(pargs - 32);
- copyin ((void *)p->p_p->ps_strings, &args, 0x10);
-
- bzero(tf, sizeof *tf);
+ memset(tf, 0, sizeof *tf);
tf->fixreg[1] = newstack;
- tf->fixreg[3] = retval[0] = args[1]; /* XXX */
- tf->fixreg[4] = retval[1] = args[0]; /* XXX */
- tf->fixreg[5] = args[2]; /* XXX */
- tf->fixreg[6] = args[3]; /* XXX */
+ tf->fixreg[3] = arginfo->ps_nargvstr;
+ tf->fixreg[4] = (register_t)arginfo->ps_argvstr;
+ tf->fixreg[5] = (register_t)arginfo->ps_envstr;
+ tf->fixreg[6] = arginfo->ps_nenvstr;
tf->srr0 = pack->ep_entry;
tf->srr1 = PSL_MBO | PSL_USERSET | PSL_FE_DFLT;
p->p_addr->u_pcb.pcb_flags = 0;
-/* $OpenBSD: mips64_machdep.c,v 1.38 2022/08/22 00:35:06 cheloha Exp $ */
+/* $OpenBSD: mips64_machdep.c,v 1.39 2022/10/30 17:43:39 guenther Exp $ */
/*
* Copyright (c) 2009, 2010, 2012 Miodrag Vallat.
*/
void
setregs(struct proc *p, struct exec_package *pack, u_long stack,
- register_t *retval)
+ struct ps_strings *arginfo)
{
struct cpu_info *ci = curcpu();
+ struct trapframe *tf = p->p_md.md_regs;
+
+ memset(tf, 0, sizeof *tf);
+ tf->sp = stack;
+ tf->pc = pack->ep_entry & ~3;
+ tf->t9 = pack->ep_entry & ~3; /* abicall req */
+ tf->sr = protosr | (idle_mask & SR_INT_MASK);
- bzero((caddr_t)p->p_md.md_regs, sizeof(struct trapframe));
- p->p_md.md_regs->sp = stack;
- p->p_md.md_regs->pc = pack->ep_entry & ~3;
- p->p_md.md_regs->t9 = pack->ep_entry & ~3; /* abicall req */
- p->p_md.md_regs->sr = protosr | (idle_mask & SR_INT_MASK);
if (CPU_HAS_FPU(ci))
p->p_md.md_flags &= ~MDP_FPUSED;
if (ci->ci_fpuproc == p)
ci->ci_fpuproc = NULL;
-
- retval[1] = 0;
}
int
-/* $OpenBSD: machdep.c,v 1.72 2022/05/19 05:43:48 miod Exp $ */
+/* $OpenBSD: machdep.c,v 1.73 2022/10/30 17:43:39 guenther Exp $ */
/*
* Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org>
void
setregs(struct proc *p, struct exec_package *pack, u_long stack,
- register_t *retval)
+ struct ps_strings *arginfo)
{
struct trapframe *frame = p->p_md.md_regs;
struct pcb *pcb = &p->p_addr->u_pcb;
- struct ps_strings arginfo;
-
- copyin((void *)p->p_p->ps_strings, &arginfo, sizeof(arginfo));
memset(frame, 0, sizeof(*frame));
frame->fixreg[1] = stack;
- frame->fixreg[3] = retval[0] = arginfo.ps_nargvstr;
- frame->fixreg[4] = retval[1] = (register_t)arginfo.ps_argvstr;
- frame->fixreg[5] = (register_t)arginfo.ps_envstr;
+ frame->fixreg[3] = arginfo->ps_nargvstr;
+ frame->fixreg[4] = (register_t)arginfo->ps_argvstr;
+ frame->fixreg[5] = (register_t)arginfo->ps_envstr;
frame->fixreg[6] = (register_t)pack->ep_auxinfo;
frame->fixreg[12] = pack->ep_entry;
frame->srr0 = pack->ep_entry;
-/* $OpenBSD: machdep.c,v 1.28 2022/10/03 19:32:22 kettenis Exp $ */
+/* $OpenBSD: machdep.c,v 1.29 2022/10/30 17:43:40 guenther Exp $ */
/*
* Copyright (c) 2014 Patrick Wildt <patrick@blueri.se>
void
setregs(struct proc *p, struct exec_package *pack, u_long stack,
- register_t *retval)
+ struct ps_strings *arginfo)
{
struct trapframe *tf = p->p_addr->u_pcb.pcb_tf;
struct pcb *pcb = &p->p_addr->u_pcb;
tf->tf_sstatus &= ~SSTATUS_FS_MASK;
tf->tf_sstatus |= SSTATUS_FS_OFF;
- memset(tf, 0, sizeof(*tf));
+ memset(tf, 0, sizeof *tf);
tf->tf_sp = STACKALIGN(stack);
tf->tf_ra = pack->ep_entry;
tf->tf_sepc = pack->ep_entry;
-
- retval[1] = 0;
}
void
-/* $OpenBSD: sh_machdep.c,v 1.54 2022/02/21 10:51:36 jsg Exp $ */
+/* $OpenBSD: sh_machdep.c,v 1.55 2022/10/30 17:43:40 guenther Exp $ */
/* $NetBSD: sh3_machdep.c,v 1.59 2006/03/04 01:13:36 uwe Exp $ */
/*
*/
void
setregs(struct proc *p, struct exec_package *pack, u_long stack,
- register_t rval[2])
+ struct ps_strings *arginfo)
{
struct trapframe *tf;
struct pcb *pcb = p->p_md.md_pcb;
tf->tf_r1 = 0;
tf->tf_r2 = 0;
tf->tf_r3 = 0;
- copyin((caddr_t)stack, &tf->tf_r4, sizeof(register_t)); /* argc */
- tf->tf_r5 = stack + 4; /* argv */
- tf->tf_r6 = stack + 4 * tf->tf_r4 + 8; /* envp */
+ tf->tf_r4 = arginfo->ps_nargvstr;
+ tf->tf_r5 = (register_t)arginfo->ps_argvstr;
+ tf->tf_r6 = (register_t)arginfo->ps_envstr;
tf->tf_r7 = 0;
tf->tf_r8 = 0;
tf->tf_r9 = (int)p->p_p->ps_strings;
fpu_restore(&pcb->pcb_fp);
}
#endif
-
- rval[1] = 0;
}
/*
-/* $OpenBSD: machdep.c,v 1.204 2022/10/25 06:05:57 guenther Exp $ */
+/* $OpenBSD: machdep.c,v 1.205 2022/10/30 17:43:40 guenther Exp $ */
/* $NetBSD: machdep.c,v 1.108 2001/07/24 19:30:14 eeh Exp $ */
/*-
#define CPOUTREG(l,v) copyout(&(v), (l), sizeof(v))
-/* ARGSUSED */
void
-setregs(struct proc *p, struct exec_package *pack, vaddr_t stack,
- register_t *retval)
+setregs(struct proc *p, struct exec_package *pack, u_long stack,
+ struct ps_strings *arginfo)
{
struct trapframe *tf = p->p_md.md_tf;
int64_t tstate;
free(p->p_md.md_fpstate, M_SUBPROC, sizeof(struct fpstate));
p->p_md.md_fpstate = NULL;
}
- bzero((caddr_t)tf, sizeof *tf);
+ memset(tf, 0, sizeof *tf);
tf->tf_tstate = tstate;
tf->tf_pc = pack->ep_entry & ~3;
tf->tf_npc = tf->tf_pc + 4;
- tf->tf_global[2] = tf->tf_pc;
stack -= sizeof(struct rwindow);
tf->tf_out[6] = stack - BIAS;
#ifdef NOTDEF_DEBUG
printf("setregs: setting tf %p sp %p pc %p\n", (long)tf,
(long)tf->tf_out[6], (long)tf->tf_pc);
#endif
- retval[1] = 0;
}
struct sigframe {
-/* $OpenBSD: init_main.c,v 1.317 2022/08/14 01:58:27 jsg Exp $ */
+/* $OpenBSD: init_main.c,v 1.318 2022/10/30 17:43:40 guenther Exp $ */
/* $NetBSD: init_main.c,v 1.84.4.1 1996/06/02 09:08:06 mrg Exp $ */
/*
* Now try to exec the program. If can't for any reason
* other than it doesn't exist, complain.
*/
- if ((error = sys_execve(p, &args, retval)) == 0) {
+ if ((error = sys_execve(p, &args, retval)) == EJUSTRETURN) {
KERNEL_UNLOCK();
return;
}
-/* $OpenBSD: kern_exec.c,v 1.237 2022/10/21 19:13:31 deraadt Exp $ */
+/* $OpenBSD: kern_exec.c,v 1.238 2022/10/30 17:43:40 guenther Exp $ */
/* $NetBSD: kern_exec.c,v 1.75 1996/02/09 18:59:28 christos Exp $ */
/*-
if (exec_elf_fixup(p, &pack) != 0)
goto free_pack_abort;
#ifdef MACHINE_STACK_GROWS_UP
- setregs(p, &pack, (u_long)stack + slen, retval);
+ setregs(p, &pack, (u_long)stack + slen, &arginfo);
#else
- setregs(p, &pack, (u_long)stack, retval);
+ setregs(p, &pack, (u_long)stack, &arginfo);
#endif
/* map the process's signal trampoline code */
atomic_clearbits_int(&pr->ps_flags, PS_INEXEC);
single_thread_clear(p, P_SUSPSIG);
- return (0);
+ /* setregs() sets up all the registers, so just 'return' */
+ return EJUSTRETURN;
bad:
/* free the vmspace-creation commands, and release their references */
-/* $OpenBSD: exec.h,v 1.50 2022/10/27 22:48:17 deraadt Exp $ */
+/* $OpenBSD: exec.h,v 1.51 2022/10/30 17:43:40 guenther Exp $ */
/* $NetBSD: exec.h,v 1.59 1996/02/09 18:25:09 christos Exp $ */
/*-
int vmcmd_mutable(struct proc *, struct exec_vmcmd *);
int vmcmd_randomize(struct proc *, struct exec_vmcmd *);
int copyargs(struct exec_package *, struct ps_strings *, void *, void *);
-void setregs(struct proc *, struct exec_package *, u_long, register_t *);
+void setregs(struct proc *, struct exec_package *, u_long,
+ struct ps_strings *);
int check_exec(struct proc *, struct exec_package *);
int exec_setup_stack(struct proc *, struct exec_package *);
int exec_process_vmcmds(struct proc *, struct exec_package *);