mirror of
https://github.com/opnsense/src.git
synced 2026-06-09 08:43:19 -04:00
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:
parent
c20264770f
commit
1328e1c4be
13 changed files with 52 additions and 52 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Reference in a new issue