From 1328e1c4beb0c88b4291ca7849ce66cc2078ee8d Mon Sep 17 00:00:00 2001 From: Daniel Eischen Date: Fri, 25 Apr 2003 01:50:30 +0000 Subject: [PATCH] Add an argument to get_mcontext() which specified whether the syscall return values should be cleared. The system calls getcontext() and swapcontext() want to return 0 on success but these contexts can be switched to at a later time so the return values need to be cleared in the saved register sets. Other callers of get_mcontext() would normally want the context without clearing the return values. Remove the i386-specific context saving from the KSE code. get_mcontext() is not i386-specific any more. Fix a bad pointer in the alpha get_mcontext() code. The context was being bcopy()'d from &td->tf_frame, but tf_frame is itself a pointer, so the thread was being copied instead. Spotted by jake. Glanced at by: jake Reviewed by: bde (months ago) --- sys/alpha/alpha/machdep.c | 10 +++++++--- sys/amd64/amd64/machdep.c | 11 ++++++++--- sys/i386/i386/machdep.c | 11 ++++++++--- sys/ia64/ia64/machdep.c | 2 +- sys/kern/kern_context.c | 4 ++-- sys/kern/kern_kse.c | 16 +--------------- sys/kern/kern_thread.c | 16 +--------------- sys/pc98/i386/machdep.c | 11 ++++++++--- sys/pc98/pc98/machdep.c | 11 ++++++++--- sys/powerpc/aim/machdep.c | 2 +- sys/powerpc/powerpc/machdep.c | 2 +- sys/sparc64/sparc64/machdep.c | 6 +++++- sys/sys/ucontext.h | 2 +- 13 files changed, 52 insertions(+), 52 deletions(-) diff --git a/sys/alpha/alpha/machdep.c b/sys/alpha/alpha/machdep.c index c7e8c8c6112..1efc6b9eedb 100644 --- a/sys/alpha/alpha/machdep.c +++ b/sys/alpha/alpha/machdep.c @@ -1977,13 +1977,17 @@ set_regs(td, regs) } int -get_mcontext(struct thread *td, mcontext_t *mcp) +get_mcontext(struct thread *td, mcontext_t *mcp, int clear_ret) { /* * Use a trapframe for getsetcontext, so just copy the * threads trapframe. */ - bcopy(&td->td_frame, &mcp->mc_regs, sizeof(td->td_frame)); + bcopy(td->td_frame, &mcp->mc_regs, sizeof(struct trapframe)); + if (clear_ret != 0) { + mcp->mc_regs[FRAME_V0] = 0; + mcp->mc_regs[FRAME_A4] = 0; + } /* * When the thread is the current thread, the user stack pointer @@ -2029,7 +2033,7 @@ set_mcontext(struct thread *td, const mcontext_t *mcp) * The context is a trapframe, so just copy it over the * threads frame. */ - bcopy(&mcp->mc_regs, &td->td_frame, sizeof(td->td_frame)); + bcopy(&mcp->mc_regs, td->td_frame, sizeof(struct trapframe)); } return (0); } diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index d2dba4ff1ed..e5377d4477e 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -2359,7 +2359,7 @@ set_fpregs(struct thread *td, struct fpreg *fpregs) * Get machine context. */ int -get_mcontext(struct thread *td, mcontext_t *mcp) +get_mcontext(struct thread *td, mcontext_t *mcp, int clear_ret) { struct trapframe *tp; @@ -2376,10 +2376,15 @@ get_mcontext(struct thread *td, mcontext_t *mcp) mcp->mc_esi = tp->tf_esi; mcp->mc_ebp = tp->tf_ebp; mcp->mc_isp = tp->tf_isp; + if (clear_ret != 0) { + mcp->mc_eax = 0; + mcp->mc_edx = 0; + } else { + mcp->mc_eax = tp->tf_eax; + mcp->mc_edx = tp->tf_edx; + } mcp->mc_ebx = tp->tf_ebx; - mcp->mc_edx = tp->tf_edx; mcp->mc_ecx = tp->tf_ecx; - mcp->mc_eax = tp->tf_eax; mcp->mc_eip = tp->tf_eip; mcp->mc_cs = tp->tf_cs; mcp->mc_eflags = tp->tf_eflags; diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index d2dba4ff1ed..e5377d4477e 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -2359,7 +2359,7 @@ set_fpregs(struct thread *td, struct fpreg *fpregs) * Get machine context. */ int -get_mcontext(struct thread *td, mcontext_t *mcp) +get_mcontext(struct thread *td, mcontext_t *mcp, int clear_ret) { struct trapframe *tp; @@ -2376,10 +2376,15 @@ get_mcontext(struct thread *td, mcontext_t *mcp) mcp->mc_esi = tp->tf_esi; mcp->mc_ebp = tp->tf_ebp; mcp->mc_isp = tp->tf_isp; + if (clear_ret != 0) { + mcp->mc_eax = 0; + mcp->mc_edx = 0; + } else { + mcp->mc_eax = tp->tf_eax; + mcp->mc_edx = tp->tf_edx; + } mcp->mc_ebx = tp->tf_ebx; - mcp->mc_edx = tp->tf_edx; mcp->mc_ecx = tp->tf_ecx; - mcp->mc_eax = tp->tf_eax; mcp->mc_eip = tp->tf_eip; mcp->mc_cs = tp->tf_cs; mcp->mc_eflags = tp->tf_eflags; diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c index fb16a72d8e0..cff38fed3b6 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -1018,7 +1018,7 @@ freebsd4_sigreturn(struct thread *td, struct freebsd4_sigreturn_args *uap) #endif int -get_mcontext(struct thread *td, mcontext_t *mcp) +get_mcontext(struct thread *td, mcontext_t *mcp, int clear_ret) { return (ENOSYS); diff --git a/sys/kern/kern_context.c b/sys/kern/kern_context.c index 653475d2df2..ed30a8b3e18 100644 --- a/sys/kern/kern_context.c +++ b/sys/kern/kern_context.c @@ -71,7 +71,7 @@ getcontext(struct thread *td, struct getcontext_args *uap) if (uap->ucp == NULL) ret = EINVAL; else { - get_mcontext(td, &uc.uc_mcontext); + get_mcontext(td, &uc.uc_mcontext, 1); PROC_LOCK(td->td_proc); uc.uc_sigmask = td->td_sigmask; PROC_UNLOCK(td->td_proc); @@ -115,7 +115,7 @@ swapcontext(struct thread *td, struct swapcontext_args *uap) if (uap->oucp == NULL || uap->ucp == NULL) ret = EINVAL; else { - get_mcontext(td, &uc.uc_mcontext); + get_mcontext(td, &uc.uc_mcontext, 1); PROC_LOCK(td->td_proc); uc.uc_sigmask = td->td_sigmask; PROC_UNLOCK(td->td_proc); diff --git a/sys/kern/kern_kse.c b/sys/kern/kern_kse.c index 48f5ac0fa12..ac7daa455bd 100644 --- a/sys/kern/kern_kse.c +++ b/sys/kern/kern_kse.c @@ -729,13 +729,7 @@ void thread_getcontext(struct thread *td, ucontext_t *uc) { -/* - * XXX this is declared in a MD include file, i386/include/ucontext.h but - * is used in MI code. - */ -#ifdef __i386__ - get_mcontext(td, &uc->uc_mcontext); -#endif + get_mcontext(td, &uc->uc_mcontext, 0); PROC_LOCK(td->td_proc); uc->uc_sigmask = td->td_sigmask; PROC_UNLOCK(td->td_proc); @@ -751,15 +745,7 @@ thread_setcontext(struct thread *td, ucontext_t *uc) { int ret; -/* - * XXX this is declared in a MD include file, i386/include/ucontext.h but - * is used in MI code. - */ -#ifdef __i386__ ret = set_mcontext(td, &uc->uc_mcontext); -#else - ret = ENOSYS; -#endif if (ret == 0) { SIG_CANTMASK(uc->uc_sigmask); PROC_LOCK(td->td_proc); diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c index 48f5ac0fa12..ac7daa455bd 100644 --- a/sys/kern/kern_thread.c +++ b/sys/kern/kern_thread.c @@ -729,13 +729,7 @@ void thread_getcontext(struct thread *td, ucontext_t *uc) { -/* - * XXX this is declared in a MD include file, i386/include/ucontext.h but - * is used in MI code. - */ -#ifdef __i386__ - get_mcontext(td, &uc->uc_mcontext); -#endif + get_mcontext(td, &uc->uc_mcontext, 0); PROC_LOCK(td->td_proc); uc->uc_sigmask = td->td_sigmask; PROC_UNLOCK(td->td_proc); @@ -751,15 +745,7 @@ thread_setcontext(struct thread *td, ucontext_t *uc) { int ret; -/* - * XXX this is declared in a MD include file, i386/include/ucontext.h but - * is used in MI code. - */ -#ifdef __i386__ ret = set_mcontext(td, &uc->uc_mcontext); -#else - ret = ENOSYS; -#endif if (ret == 0) { SIG_CANTMASK(uc->uc_sigmask); PROC_LOCK(td->td_proc); diff --git a/sys/pc98/i386/machdep.c b/sys/pc98/i386/machdep.c index 707b8fc7d3a..b9013a22da3 100644 --- a/sys/pc98/i386/machdep.c +++ b/sys/pc98/i386/machdep.c @@ -2428,7 +2428,7 @@ set_fpregs(struct thread *td, struct fpreg *fpregs) * Get machine context. */ int -get_mcontext(struct thread *td, mcontext_t *mcp) +get_mcontext(struct thread *td, mcontext_t *mcp, int clear_ret) { struct trapframe *tp; @@ -2446,9 +2446,14 @@ get_mcontext(struct thread *td, mcontext_t *mcp) mcp->mc_ebp = tp->tf_ebp; mcp->mc_isp = tp->tf_isp; mcp->mc_ebx = tp->tf_ebx; - mcp->mc_edx = tp->tf_edx; + if (clear_ret != 0) { + mcp->mc_eax = 0; + mcp->mc_edx = 0; + } else { + mcp->mc_eax = tp->tf_eax; + mcp->mc_edx = tp->tf_edx; + } mcp->mc_ecx = tp->tf_ecx; - mcp->mc_eax = tp->tf_eax; mcp->mc_eip = tp->tf_eip; mcp->mc_cs = tp->tf_cs; mcp->mc_eflags = tp->tf_eflags; diff --git a/sys/pc98/pc98/machdep.c b/sys/pc98/pc98/machdep.c index 707b8fc7d3a..b9013a22da3 100644 --- a/sys/pc98/pc98/machdep.c +++ b/sys/pc98/pc98/machdep.c @@ -2428,7 +2428,7 @@ set_fpregs(struct thread *td, struct fpreg *fpregs) * Get machine context. */ int -get_mcontext(struct thread *td, mcontext_t *mcp) +get_mcontext(struct thread *td, mcontext_t *mcp, int clear_ret) { struct trapframe *tp; @@ -2446,9 +2446,14 @@ get_mcontext(struct thread *td, mcontext_t *mcp) mcp->mc_ebp = tp->tf_ebp; mcp->mc_isp = tp->tf_isp; mcp->mc_ebx = tp->tf_ebx; - mcp->mc_edx = tp->tf_edx; + if (clear_ret != 0) { + mcp->mc_eax = 0; + mcp->mc_edx = 0; + } else { + mcp->mc_eax = tp->tf_eax; + mcp->mc_edx = tp->tf_edx; + } mcp->mc_ecx = tp->tf_ecx; - mcp->mc_eax = tp->tf_eax; mcp->mc_eip = tp->tf_eip; mcp->mc_cs = tp->tf_cs; mcp->mc_eflags = tp->tf_eflags; diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/machdep.c index 39fcc4945cc..81fb604a8b2 100644 --- a/sys/powerpc/aim/machdep.c +++ b/sys/powerpc/aim/machdep.c @@ -562,7 +562,7 @@ freebsd4_sigreturn(struct thread *td, struct freebsd4_sigreturn_args *uap) #endif int -get_mcontext(struct thread *td, mcontext_t *mcp) +get_mcontext(struct thread *td, mcontext_t *mcp, int clear_ret) { return (ENOSYS); diff --git a/sys/powerpc/powerpc/machdep.c b/sys/powerpc/powerpc/machdep.c index 39fcc4945cc..81fb604a8b2 100644 --- a/sys/powerpc/powerpc/machdep.c +++ b/sys/powerpc/powerpc/machdep.c @@ -562,7 +562,7 @@ freebsd4_sigreturn(struct thread *td, struct freebsd4_sigreturn_args *uap) #endif int -get_mcontext(struct thread *td, mcontext_t *mcp) +get_mcontext(struct thread *td, mcontext_t *mcp, int clear_ret) { return (ENOSYS); diff --git a/sys/sparc64/sparc64/machdep.c b/sys/sparc64/sparc64/machdep.c index 47d909394ce..6cf0f6af2df 100644 --- a/sys/sparc64/sparc64/machdep.c +++ b/sys/sparc64/sparc64/machdep.c @@ -535,7 +535,7 @@ freebsd4_sigreturn(struct thread *td, struct freebsd4_sigreturn_args *uap) #endif int -get_mcontext(struct thread *td, mcontext_t *mc) +get_mcontext(struct thread *td, mcontext_t *mc, int clear_ret) { struct trapframe *tf; struct pcb *pcb; @@ -543,6 +543,10 @@ get_mcontext(struct thread *td, mcontext_t *mc) tf = td->td_frame; pcb = td->td_pcb; bcopy(tf, mc, sizeof(*tf)); + if (clear_ret != 0) { + mc->mc_out[0] = 0; + mc->mc_out[1] = 0; + } mc->mc_flags = _MC_VERSION; critical_enter(); if ((tf->tf_fprs & FPRS_FEF) != 0) { diff --git a/sys/sys/ucontext.h b/sys/sys/ucontext.h index 1ea01d577ac..70402ffc394 100644 --- a/sys/sys/ucontext.h +++ b/sys/sys/ucontext.h @@ -84,7 +84,7 @@ __END_DECLS struct thread; /* Machine-dependent functions: */ -int get_mcontext(struct thread *td, mcontext_t *mcp); +int get_mcontext(struct thread *td, mcontext_t *mcp, int clear_ret); int set_mcontext(struct thread *td, const mcontext_t *mcp); #endif /* !_KERNEL */