summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordeischen <deischen@FreeBSD.org>2003-04-25 01:50:30 +0000
committerdeischen <deischen@FreeBSD.org>2003-04-25 01:50:30 +0000
commit3d51b3a2809784a3fd4e35c34422c2f82d8fd818 (patch)
treebb8eb253f377c8996df874bb13ce8f388ab880c7
parentaf0b381b9f2eb4edc2bbd4c4d7b902ed42d913d7 (diff)
downloadFreeBSD-src-3d51b3a2809784a3fd4e35c34422c2f82d8fd818.zip
FreeBSD-src-3d51b3a2809784a3fd4e35c34422c2f82d8fd818.tar.gz
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)
-rw-r--r--sys/alpha/alpha/machdep.c10
-rw-r--r--sys/amd64/amd64/machdep.c11
-rw-r--r--sys/i386/i386/machdep.c11
-rw-r--r--sys/ia64/ia64/machdep.c2
-rw-r--r--sys/kern/kern_context.c4
-rw-r--r--sys/kern/kern_kse.c16
-rw-r--r--sys/kern/kern_thread.c16
-rw-r--r--sys/pc98/i386/machdep.c11
-rw-r--r--sys/pc98/pc98/machdep.c11
-rw-r--r--sys/powerpc/aim/machdep.c2
-rw-r--r--sys/powerpc/powerpc/machdep.c2
-rw-r--r--sys/sparc64/sparc64/machdep.c6
-rw-r--r--sys/sys/ucontext.h2
13 files changed, 52 insertions, 52 deletions
diff --git a/sys/alpha/alpha/machdep.c b/sys/alpha/alpha/machdep.c
index c7e8c8c..1efc6b9 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 d2dba4f..e5377d4 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 d2dba4f..e5377d4 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 fb16a72..cff38fe 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 653475d..ed30a8b 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 48f5ac0..ac7daa4 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 48f5ac0..ac7daa4 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 707b8fc..b9013a2 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 707b8fc..b9013a2 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 39fcc49..81fb604 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 39fcc49..81fb604 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 47d9093..6cf0f6a 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 1ea01d5..70402ff 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 */
OpenPOWER on IntegriCloud