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)
This commit is contained in:
Daniel Eischen 2003-04-25 01:50:30 +00:00
parent c20264770f
commit 1328e1c4be
13 changed files with 52 additions and 52 deletions

View file

@ -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);
}

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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) {

View file

@ -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 */