Merge from sys/i386/i386/machdep.c 1.480 (Julian's KSE changes)
Reviewed by: julian, bde, jhb
This commit is contained in:
parent
2af8d76dad
commit
2fb670e0b5
@ -302,14 +302,16 @@ osendsig(catcher, sig, mask, code)
|
|||||||
struct osigframe sf;
|
struct osigframe sf;
|
||||||
struct osigframe *fp;
|
struct osigframe *fp;
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
|
struct thread *td;
|
||||||
struct sigacts *psp;
|
struct sigacts *psp;
|
||||||
struct trapframe *regs;
|
struct trapframe *regs;
|
||||||
int oonstack;
|
int oonstack;
|
||||||
|
|
||||||
p = curproc;
|
td = curthread;
|
||||||
|
p = td->td_proc;
|
||||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||||
psp = p->p_sigacts;
|
psp = p->p_sigacts;
|
||||||
regs = p->p_frame;
|
regs = td->td_frame;
|
||||||
oonstack = sigonstack(regs->tf_esp);
|
oonstack = sigonstack(regs->tf_esp);
|
||||||
|
|
||||||
/* Allocate and validate space for the signal handler context. */
|
/* Allocate and validate space for the signal handler context. */
|
||||||
@ -399,7 +401,7 @@ osendsig(catcher, sig, mask, code)
|
|||||||
if (regs->tf_eflags & PSL_VM) {
|
if (regs->tf_eflags & PSL_VM) {
|
||||||
/* XXX confusing names: `tf' isn't a trapframe; `regs' is. */
|
/* XXX confusing names: `tf' isn't a trapframe; `regs' is. */
|
||||||
struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
|
struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
|
||||||
struct vm86_kernel *vm86 = &p->p_addr->u_pcb.pcb_ext->ext_vm86;
|
struct vm86_kernel *vm86 = &td->td_pcb->pcb_ext->ext_vm86;
|
||||||
|
|
||||||
sf.sf_siginfo.si_sc.sc_gs = tf->tf_vm86_gs;
|
sf.sf_siginfo.si_sc.sc_gs = tf->tf_vm86_gs;
|
||||||
sf.sf_siginfo.si_sc.sc_fs = tf->tf_vm86_fs;
|
sf.sf_siginfo.si_sc.sc_fs = tf->tf_vm86_fs;
|
||||||
@ -422,7 +424,7 @@ osendsig(catcher, sig, mask, code)
|
|||||||
* ...Kill the process.
|
* ...Kill the process.
|
||||||
*/
|
*/
|
||||||
PROC_LOCK(p);
|
PROC_LOCK(p);
|
||||||
sigexit(p, SIGILL);
|
sigexit(td, SIGILL);
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,12 +449,14 @@ sendsig(catcher, sig, mask, code)
|
|||||||
{
|
{
|
||||||
struct sigframe sf;
|
struct sigframe sf;
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
|
struct thread *td;
|
||||||
struct sigacts *psp;
|
struct sigacts *psp;
|
||||||
struct trapframe *regs;
|
struct trapframe *regs;
|
||||||
struct sigframe *sfp;
|
struct sigframe *sfp;
|
||||||
int oonstack;
|
int oonstack;
|
||||||
|
|
||||||
p = curproc;
|
td = curthread;
|
||||||
|
p = td->td_proc;
|
||||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||||
psp = p->p_sigacts;
|
psp = p->p_sigacts;
|
||||||
#ifdef COMPAT_43
|
#ifdef COMPAT_43
|
||||||
@ -461,7 +465,7 @@ sendsig(catcher, sig, mask, code)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
regs = p->p_frame;
|
regs = td->td_frame;
|
||||||
oonstack = sigonstack(regs->tf_esp);
|
oonstack = sigonstack(regs->tf_esp);
|
||||||
|
|
||||||
/* Save user context. */
|
/* Save user context. */
|
||||||
@ -541,7 +545,7 @@ sendsig(catcher, sig, mask, code)
|
|||||||
*/
|
*/
|
||||||
if (regs->tf_eflags & PSL_VM) {
|
if (regs->tf_eflags & PSL_VM) {
|
||||||
struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
|
struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
|
||||||
struct vm86_kernel *vm86 = &p->p_addr->u_pcb.pcb_ext->ext_vm86;
|
struct vm86_kernel *vm86 = &td->td_pcb->pcb_ext->ext_vm86;
|
||||||
|
|
||||||
sf.sf_uc.uc_mcontext.mc_gs = tf->tf_vm86_gs;
|
sf.sf_uc.uc_mcontext.mc_gs = tf->tf_vm86_gs;
|
||||||
sf.sf_uc.uc_mcontext.mc_fs = tf->tf_vm86_fs;
|
sf.sf_uc.uc_mcontext.mc_fs = tf->tf_vm86_fs;
|
||||||
@ -574,7 +578,7 @@ sendsig(catcher, sig, mask, code)
|
|||||||
* ...Kill the process.
|
* ...Kill the process.
|
||||||
*/
|
*/
|
||||||
PROC_LOCK(p);
|
PROC_LOCK(p);
|
||||||
sigexit(p, SIGILL);
|
sigexit(td, SIGILL);
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -599,17 +603,18 @@ sendsig(catcher, sig, mask, code)
|
|||||||
*/
|
*/
|
||||||
#ifdef COMPAT_43
|
#ifdef COMPAT_43
|
||||||
int
|
int
|
||||||
osigreturn(p, uap)
|
osigreturn(td, uap)
|
||||||
struct proc *p;
|
struct thread *td;
|
||||||
struct osigreturn_args /* {
|
struct osigreturn_args /* {
|
||||||
struct osigcontext *sigcntxp;
|
struct osigcontext *sigcntxp;
|
||||||
} */ *uap;
|
} */ *uap;
|
||||||
{
|
{
|
||||||
struct trapframe *regs;
|
struct trapframe *regs;
|
||||||
struct osigcontext *scp;
|
struct osigcontext *scp;
|
||||||
|
struct proc *p = td->td_proc;
|
||||||
int eflags;
|
int eflags;
|
||||||
|
|
||||||
regs = p->p_frame;
|
regs = td->td_frame;
|
||||||
scp = uap->sigcntxp;
|
scp = uap->sigcntxp;
|
||||||
if (!useracc((caddr_t)scp, sizeof(*scp), VM_PROT_READ))
|
if (!useracc((caddr_t)scp, sizeof(*scp), VM_PROT_READ))
|
||||||
return (EFAULT);
|
return (EFAULT);
|
||||||
@ -622,9 +627,9 @@ osigreturn(p, uap)
|
|||||||
* if pcb_ext == 0 or vm86_inited == 0, the user hasn't
|
* if pcb_ext == 0 or vm86_inited == 0, the user hasn't
|
||||||
* set up the vm86 area, and we can't enter vm86 mode.
|
* set up the vm86 area, and we can't enter vm86 mode.
|
||||||
*/
|
*/
|
||||||
if (p->p_addr->u_pcb.pcb_ext == 0)
|
if (td->td_pcb->pcb_ext == 0)
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
vm86 = &p->p_addr->u_pcb.pcb_ext->ext_vm86;
|
vm86 = &td->td_pcb->pcb_ext->ext_vm86;
|
||||||
if (vm86->vm86_inited == 0)
|
if (vm86->vm86_inited == 0)
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
|
|
||||||
@ -710,12 +715,13 @@ osigreturn(p, uap)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
sigreturn(p, uap)
|
sigreturn(td, uap)
|
||||||
struct proc *p;
|
struct thread *td;
|
||||||
struct sigreturn_args /* {
|
struct sigreturn_args /* {
|
||||||
ucontext_t *sigcntxp;
|
ucontext_t *sigcntxp;
|
||||||
} */ *uap;
|
} */ *uap;
|
||||||
{
|
{
|
||||||
|
struct proc *p = td->td_proc;
|
||||||
struct trapframe *regs;
|
struct trapframe *regs;
|
||||||
ucontext_t *ucp;
|
ucontext_t *ucp;
|
||||||
int cs, eflags;
|
int cs, eflags;
|
||||||
@ -725,7 +731,7 @@ sigreturn(p, uap)
|
|||||||
if (!useracc((caddr_t)ucp, sizeof(struct osigcontext), VM_PROT_READ))
|
if (!useracc((caddr_t)ucp, sizeof(struct osigcontext), VM_PROT_READ))
|
||||||
return (EFAULT);
|
return (EFAULT);
|
||||||
if (((struct osigcontext *)ucp)->sc_trapno == 0x01d516)
|
if (((struct osigcontext *)ucp)->sc_trapno == 0x01d516)
|
||||||
return (osigreturn(p, (struct osigreturn_args *)uap));
|
return (osigreturn(td, (struct osigreturn_args *)uap));
|
||||||
/*
|
/*
|
||||||
* Since ucp is not an osigcontext but a ucontext_t, we have to
|
* Since ucp is not an osigcontext but a ucontext_t, we have to
|
||||||
* check again if all of it is accessible. A ucontext_t is
|
* check again if all of it is accessible. A ucontext_t is
|
||||||
@ -737,7 +743,7 @@ sigreturn(p, uap)
|
|||||||
if (!useracc((caddr_t)ucp, sizeof(*ucp), VM_PROT_READ))
|
if (!useracc((caddr_t)ucp, sizeof(*ucp), VM_PROT_READ))
|
||||||
return (EFAULT);
|
return (EFAULT);
|
||||||
|
|
||||||
regs = p->p_frame;
|
regs = td->td_frame;
|
||||||
eflags = ucp->uc_mcontext.mc_eflags;
|
eflags = ucp->uc_mcontext.mc_eflags;
|
||||||
if (eflags & PSL_VM) {
|
if (eflags & PSL_VM) {
|
||||||
struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
|
struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
|
||||||
@ -747,9 +753,9 @@ sigreturn(p, uap)
|
|||||||
* if pcb_ext == 0 or vm86_inited == 0, the user hasn't
|
* if pcb_ext == 0 or vm86_inited == 0, the user hasn't
|
||||||
* set up the vm86 area, and we can't enter vm86 mode.
|
* set up the vm86 area, and we can't enter vm86 mode.
|
||||||
*/
|
*/
|
||||||
if (p->p_addr->u_pcb.pcb_ext == 0)
|
if (td->td_pcb->pcb_ext == 0)
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
vm86 = &p->p_addr->u_pcb.pcb_ext->ext_vm86;
|
vm86 = &td->td_pcb->pcb_ext->ext_vm86;
|
||||||
if (vm86->vm86_inited == 0)
|
if (vm86->vm86_inited == 0)
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
|
|
||||||
@ -878,14 +884,14 @@ cpu_idle(void)
|
|||||||
* Clear registers on exec
|
* Clear registers on exec
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
setregs(p, entry, stack, ps_strings)
|
setregs(td, entry, stack, ps_strings)
|
||||||
struct proc *p;
|
struct thread *td;
|
||||||
u_long entry;
|
u_long entry;
|
||||||
u_long stack;
|
u_long stack;
|
||||||
u_long ps_strings;
|
u_long ps_strings;
|
||||||
{
|
{
|
||||||
struct trapframe *regs = p->p_frame;
|
struct trapframe *regs = td->td_frame;
|
||||||
struct pcb *pcb = &p->p_addr->u_pcb;
|
struct pcb *pcb = td->td_pcb;
|
||||||
|
|
||||||
if (pcb->pcb_ldt)
|
if (pcb->pcb_ldt)
|
||||||
user_ldt_free(pcb);
|
user_ldt_free(pcb);
|
||||||
@ -938,7 +944,7 @@ setregs(p, entry, stack, ps_strings)
|
|||||||
* traps to the emulator (if it is done at all) mainly because
|
* traps to the emulator (if it is done at all) mainly because
|
||||||
* emulators don't provide an entry point for initialization.
|
* emulators don't provide an entry point for initialization.
|
||||||
*/
|
*/
|
||||||
p->p_addr->u_pcb.pcb_flags &= ~FP_SOFTFP;
|
td->td_pcb->pcb_flags &= ~FP_SOFTFP;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Arrange to trap the next npx or `fwait' instruction (see npx.c
|
* Arrange to trap the next npx or `fwait' instruction (see npx.c
|
||||||
@ -961,7 +967,7 @@ setregs(p, entry, stack, ps_strings)
|
|||||||
* Make sure sure edx is 0x0 on entry. Linux binaries depend
|
* Make sure sure edx is 0x0 on entry. Linux binaries depend
|
||||||
* on it.
|
* on it.
|
||||||
*/
|
*/
|
||||||
p->p_retval[1] = 0;
|
td->td_retval[1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1029,7 +1035,8 @@ extern int has_f00f_bug;
|
|||||||
static struct i386tss dblfault_tss;
|
static struct i386tss dblfault_tss;
|
||||||
static char dblfault_stack[PAGE_SIZE];
|
static char dblfault_stack[PAGE_SIZE];
|
||||||
|
|
||||||
extern struct user *proc0paddr;
|
extern struct user *proc0uarea;
|
||||||
|
extern vm_offset_t proc0kstack;
|
||||||
|
|
||||||
|
|
||||||
/* software prototypes -- in more palatable form */
|
/* software prototypes -- in more palatable form */
|
||||||
@ -1718,8 +1725,12 @@ init386(first)
|
|||||||
struct region_descriptor r_gdt, r_idt;
|
struct region_descriptor r_gdt, r_idt;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
proc0.p_addr = proc0paddr;
|
proc_linkup(&proc0);
|
||||||
|
proc0.p_uarea = proc0uarea;
|
||||||
|
thread0 = &proc0.p_thread;
|
||||||
|
thread0->td_kstack = proc0kstack;
|
||||||
|
thread0->td_pcb = (struct pcb *)
|
||||||
|
(thread0->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||||
atdevbase = ISA_HOLE_START + KERNBASE;
|
atdevbase = ISA_HOLE_START + KERNBASE;
|
||||||
|
|
||||||
#ifdef PC98
|
#ifdef PC98
|
||||||
@ -1785,10 +1796,11 @@ init386(first)
|
|||||||
lgdt(&r_gdt);
|
lgdt(&r_gdt);
|
||||||
|
|
||||||
/* setup curproc so that mutexes work */
|
/* setup curproc so that mutexes work */
|
||||||
PCPU_SET(curproc, &proc0);
|
|
||||||
|
PCPU_SET(curthread, thread0);
|
||||||
PCPU_SET(spinlocks, NULL);
|
PCPU_SET(spinlocks, NULL);
|
||||||
|
|
||||||
LIST_INIT(&proc0.p_contested);
|
LIST_INIT(&thread0->td_contested);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize mutexes.
|
* Initialize mutexes.
|
||||||
@ -1892,8 +1904,9 @@ init386(first)
|
|||||||
initializecpu(); /* Initialize CPU registers */
|
initializecpu(); /* Initialize CPU registers */
|
||||||
|
|
||||||
/* make an initial tss so cpu can get interrupt stack on syscall! */
|
/* make an initial tss so cpu can get interrupt stack on syscall! */
|
||||||
PCPU_SET(common_tss.tss_esp0,
|
/* Note: -16 is so we can grow the trapframe if we came from vm86 */
|
||||||
(int) proc0.p_addr + UPAGES*PAGE_SIZE - 16);
|
PCPU_SET(common_tss.tss_esp0, thread0->td_kstack +
|
||||||
|
KSTACK_PAGES * PAGE_SIZE - sizeof(struct pcb) - 16);
|
||||||
PCPU_SET(common_tss.tss_ss0, GSEL(GDATA_SEL, SEL_KPL));
|
PCPU_SET(common_tss.tss_ss0, GSEL(GDATA_SEL, SEL_KPL));
|
||||||
gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
|
gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
|
||||||
private_tss = 0;
|
private_tss = 0;
|
||||||
@ -1948,10 +1961,10 @@ init386(first)
|
|||||||
_udatasel = LSEL(LUDATA_SEL, SEL_UPL);
|
_udatasel = LSEL(LUDATA_SEL, SEL_UPL);
|
||||||
|
|
||||||
/* setup proc 0's pcb */
|
/* setup proc 0's pcb */
|
||||||
proc0.p_addr->u_pcb.pcb_flags = 0;
|
thread0->td_pcb->pcb_flags = 0; /* XXXKSE */
|
||||||
proc0.p_addr->u_pcb.pcb_cr3 = (int)IdlePTD;
|
thread0->td_pcb->pcb_cr3 = (int)IdlePTD;
|
||||||
proc0.p_addr->u_pcb.pcb_ext = 0;
|
thread0->td_pcb->pcb_ext = 0;
|
||||||
proc0.p_frame = &proc0_tf;
|
thread0->td_frame = &proc0_tf;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(I586_CPU) && !defined(NO_F00F_HACK)
|
#if defined(I586_CPU) && !defined(NO_F00F_HACK)
|
||||||
@ -1994,31 +2007,26 @@ f00f_hack(void *unused) {
|
|||||||
#endif /* defined(I586_CPU) && !NO_F00F_HACK */
|
#endif /* defined(I586_CPU) && !NO_F00F_HACK */
|
||||||
|
|
||||||
int
|
int
|
||||||
ptrace_set_pc(p, addr)
|
ptrace_set_pc(struct thread *td, unsigned long addr)
|
||||||
struct proc *p;
|
|
||||||
unsigned long addr;
|
|
||||||
{
|
{
|
||||||
p->p_frame->tf_eip = addr;
|
td->td_frame->tf_eip = addr;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ptrace_single_step(p)
|
ptrace_single_step(struct thread *td)
|
||||||
struct proc *p;
|
|
||||||
{
|
{
|
||||||
p->p_frame->tf_eflags |= PSL_T;
|
td->td_frame->tf_eflags |= PSL_T;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fill_regs(p, regs)
|
fill_regs(struct thread *td, struct reg *regs)
|
||||||
struct proc *p;
|
|
||||||
struct reg *regs;
|
|
||||||
{
|
{
|
||||||
struct pcb *pcb;
|
struct pcb *pcb;
|
||||||
struct trapframe *tp;
|
struct trapframe *tp;
|
||||||
|
|
||||||
tp = p->p_frame;
|
tp = td->td_frame;
|
||||||
regs->r_fs = tp->tf_fs;
|
regs->r_fs = tp->tf_fs;
|
||||||
regs->r_es = tp->tf_es;
|
regs->r_es = tp->tf_es;
|
||||||
regs->r_ds = tp->tf_ds;
|
regs->r_ds = tp->tf_ds;
|
||||||
@ -2034,20 +2042,18 @@ fill_regs(p, regs)
|
|||||||
regs->r_eflags = tp->tf_eflags;
|
regs->r_eflags = tp->tf_eflags;
|
||||||
regs->r_esp = tp->tf_esp;
|
regs->r_esp = tp->tf_esp;
|
||||||
regs->r_ss = tp->tf_ss;
|
regs->r_ss = tp->tf_ss;
|
||||||
pcb = &p->p_addr->u_pcb;
|
pcb = td->td_pcb;
|
||||||
regs->r_gs = pcb->pcb_gs;
|
regs->r_gs = pcb->pcb_gs;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
set_regs(p, regs)
|
set_regs(struct thread *td, struct reg *regs)
|
||||||
struct proc *p;
|
|
||||||
struct reg *regs;
|
|
||||||
{
|
{
|
||||||
struct pcb *pcb;
|
struct pcb *pcb;
|
||||||
struct trapframe *tp;
|
struct trapframe *tp;
|
||||||
|
|
||||||
tp = p->p_frame;
|
tp = td->td_frame;
|
||||||
if (!EFL_SECURE(regs->r_eflags, tp->tf_eflags) ||
|
if (!EFL_SECURE(regs->r_eflags, tp->tf_eflags) ||
|
||||||
!CS_SECURE(regs->r_cs))
|
!CS_SECURE(regs->r_cs))
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
@ -2066,7 +2072,7 @@ set_regs(p, regs)
|
|||||||
tp->tf_eflags = regs->r_eflags;
|
tp->tf_eflags = regs->r_eflags;
|
||||||
tp->tf_esp = regs->r_esp;
|
tp->tf_esp = regs->r_esp;
|
||||||
tp->tf_ss = regs->r_ss;
|
tp->tf_ss = regs->r_ss;
|
||||||
pcb = &p->p_addr->u_pcb;
|
pcb = td->td_pcb;
|
||||||
pcb->pcb_gs = regs->r_gs;
|
pcb->pcb_gs = regs->r_gs;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -2126,45 +2132,39 @@ set_fpregs_xmm(sv_87, sv_xmm)
|
|||||||
#endif /* CPU_ENABLE_SSE */
|
#endif /* CPU_ENABLE_SSE */
|
||||||
|
|
||||||
int
|
int
|
||||||
fill_fpregs(p, fpregs)
|
fill_fpregs(struct thread *td, struct fpreg *fpregs)
|
||||||
struct proc *p;
|
|
||||||
struct fpreg *fpregs;
|
|
||||||
{
|
{
|
||||||
#ifdef CPU_ENABLE_SSE
|
#ifdef CPU_ENABLE_SSE
|
||||||
if (cpu_fxsr) {
|
if (cpu_fxsr) {
|
||||||
fill_fpregs_xmm(&p->p_addr->u_pcb.pcb_save.sv_xmm,
|
fill_fpregs_xmm(&td->td_pcb->pcb_save.sv_xmm,
|
||||||
(struct save87 *)fpregs);
|
(struct save87 *)fpregs);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
#endif /* CPU_ENABLE_SSE */
|
#endif /* CPU_ENABLE_SSE */
|
||||||
bcopy(&p->p_addr->u_pcb.pcb_save.sv_87, fpregs, sizeof *fpregs);
|
bcopy(&td->td_pcb->pcb_save.sv_87, fpregs, sizeof *fpregs);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
set_fpregs(p, fpregs)
|
set_fpregs(struct thread *td, struct fpreg *fpregs)
|
||||||
struct proc *p;
|
|
||||||
struct fpreg *fpregs;
|
|
||||||
{
|
{
|
||||||
#ifdef CPU_ENABLE_SSE
|
#ifdef CPU_ENABLE_SSE
|
||||||
if (cpu_fxsr) {
|
if (cpu_fxsr) {
|
||||||
set_fpregs_xmm((struct save87 *)fpregs,
|
set_fpregs_xmm((struct save87 *)fpregs,
|
||||||
&p->p_addr->u_pcb.pcb_save.sv_xmm);
|
&td->td_pcb->pcb_save.sv_xmm);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
#endif /* CPU_ENABLE_SSE */
|
#endif /* CPU_ENABLE_SSE */
|
||||||
bcopy(fpregs, &p->p_addr->u_pcb.pcb_save.sv_87, sizeof *fpregs);
|
bcopy(fpregs, &td->td_pcb->pcb_save.sv_87, sizeof *fpregs);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fill_dbregs(p, dbregs)
|
fill_dbregs(struct thread *td, struct dbreg *dbregs)
|
||||||
struct proc *p;
|
|
||||||
struct dbreg *dbregs;
|
|
||||||
{
|
{
|
||||||
struct pcb *pcb;
|
struct pcb *pcb;
|
||||||
|
|
||||||
if (p == NULL) {
|
if (td == NULL) {
|
||||||
dbregs->dr0 = rdr0();
|
dbregs->dr0 = rdr0();
|
||||||
dbregs->dr1 = rdr1();
|
dbregs->dr1 = rdr1();
|
||||||
dbregs->dr2 = rdr2();
|
dbregs->dr2 = rdr2();
|
||||||
@ -2173,9 +2173,8 @@ fill_dbregs(p, dbregs)
|
|||||||
dbregs->dr5 = rdr5();
|
dbregs->dr5 = rdr5();
|
||||||
dbregs->dr6 = rdr6();
|
dbregs->dr6 = rdr6();
|
||||||
dbregs->dr7 = rdr7();
|
dbregs->dr7 = rdr7();
|
||||||
}
|
} else {
|
||||||
else {
|
pcb = td->td_pcb;
|
||||||
pcb = &p->p_addr->u_pcb;
|
|
||||||
dbregs->dr0 = pcb->pcb_dr0;
|
dbregs->dr0 = pcb->pcb_dr0;
|
||||||
dbregs->dr1 = pcb->pcb_dr1;
|
dbregs->dr1 = pcb->pcb_dr1;
|
||||||
dbregs->dr2 = pcb->pcb_dr2;
|
dbregs->dr2 = pcb->pcb_dr2;
|
||||||
@ -2189,15 +2188,13 @@ fill_dbregs(p, dbregs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
set_dbregs(p, dbregs)
|
set_dbregs(struct thread *td, struct dbreg *dbregs)
|
||||||
struct proc *p;
|
|
||||||
struct dbreg *dbregs;
|
|
||||||
{
|
{
|
||||||
struct pcb *pcb;
|
struct pcb *pcb;
|
||||||
int i;
|
int i;
|
||||||
u_int32_t mask1, mask2;
|
u_int32_t mask1, mask2;
|
||||||
|
|
||||||
if (p == NULL) {
|
if (td == NULL) {
|
||||||
load_dr0(dbregs->dr0);
|
load_dr0(dbregs->dr0);
|
||||||
load_dr1(dbregs->dr1);
|
load_dr1(dbregs->dr1);
|
||||||
load_dr2(dbregs->dr2);
|
load_dr2(dbregs->dr2);
|
||||||
@ -2206,8 +2203,7 @@ set_dbregs(p, dbregs)
|
|||||||
load_dr5(dbregs->dr5);
|
load_dr5(dbregs->dr5);
|
||||||
load_dr6(dbregs->dr6);
|
load_dr6(dbregs->dr6);
|
||||||
load_dr7(dbregs->dr7);
|
load_dr7(dbregs->dr7);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
/*
|
/*
|
||||||
* Don't let an illegal value for dr7 get set. Specifically,
|
* Don't let an illegal value for dr7 get set. Specifically,
|
||||||
* check for undefined settings. Setting these bit patterns
|
* check for undefined settings. Setting these bit patterns
|
||||||
@ -2219,7 +2215,7 @@ set_dbregs(p, dbregs)
|
|||||||
if ((dbregs->dr7 & mask1) == mask2)
|
if ((dbregs->dr7 & mask1) == mask2)
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
|
|
||||||
pcb = &p->p_addr->u_pcb;
|
pcb = td->td_pcb;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Don't let a process set a breakpoint that is not within the
|
* Don't let a process set a breakpoint that is not within the
|
||||||
@ -2236,7 +2232,7 @@ set_dbregs(p, dbregs)
|
|||||||
* from within kernel mode?
|
* from within kernel mode?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (suser(p) != 0) {
|
if (suser_td(td) != 0) {
|
||||||
if (dbregs->dr7 & 0x3) {
|
if (dbregs->dr7 & 0x3) {
|
||||||
/* dr0 is enabled */
|
/* dr0 is enabled */
|
||||||
if (dbregs->dr0 >= VM_MAXUSER_ADDRESS)
|
if (dbregs->dr0 >= VM_MAXUSER_ADDRESS)
|
||||||
|
@ -302,14 +302,16 @@ osendsig(catcher, sig, mask, code)
|
|||||||
struct osigframe sf;
|
struct osigframe sf;
|
||||||
struct osigframe *fp;
|
struct osigframe *fp;
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
|
struct thread *td;
|
||||||
struct sigacts *psp;
|
struct sigacts *psp;
|
||||||
struct trapframe *regs;
|
struct trapframe *regs;
|
||||||
int oonstack;
|
int oonstack;
|
||||||
|
|
||||||
p = curproc;
|
td = curthread;
|
||||||
|
p = td->td_proc;
|
||||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||||
psp = p->p_sigacts;
|
psp = p->p_sigacts;
|
||||||
regs = p->p_frame;
|
regs = td->td_frame;
|
||||||
oonstack = sigonstack(regs->tf_esp);
|
oonstack = sigonstack(regs->tf_esp);
|
||||||
|
|
||||||
/* Allocate and validate space for the signal handler context. */
|
/* Allocate and validate space for the signal handler context. */
|
||||||
@ -399,7 +401,7 @@ osendsig(catcher, sig, mask, code)
|
|||||||
if (regs->tf_eflags & PSL_VM) {
|
if (regs->tf_eflags & PSL_VM) {
|
||||||
/* XXX confusing names: `tf' isn't a trapframe; `regs' is. */
|
/* XXX confusing names: `tf' isn't a trapframe; `regs' is. */
|
||||||
struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
|
struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
|
||||||
struct vm86_kernel *vm86 = &p->p_addr->u_pcb.pcb_ext->ext_vm86;
|
struct vm86_kernel *vm86 = &td->td_pcb->pcb_ext->ext_vm86;
|
||||||
|
|
||||||
sf.sf_siginfo.si_sc.sc_gs = tf->tf_vm86_gs;
|
sf.sf_siginfo.si_sc.sc_gs = tf->tf_vm86_gs;
|
||||||
sf.sf_siginfo.si_sc.sc_fs = tf->tf_vm86_fs;
|
sf.sf_siginfo.si_sc.sc_fs = tf->tf_vm86_fs;
|
||||||
@ -422,7 +424,7 @@ osendsig(catcher, sig, mask, code)
|
|||||||
* ...Kill the process.
|
* ...Kill the process.
|
||||||
*/
|
*/
|
||||||
PROC_LOCK(p);
|
PROC_LOCK(p);
|
||||||
sigexit(p, SIGILL);
|
sigexit(td, SIGILL);
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,12 +449,14 @@ sendsig(catcher, sig, mask, code)
|
|||||||
{
|
{
|
||||||
struct sigframe sf;
|
struct sigframe sf;
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
|
struct thread *td;
|
||||||
struct sigacts *psp;
|
struct sigacts *psp;
|
||||||
struct trapframe *regs;
|
struct trapframe *regs;
|
||||||
struct sigframe *sfp;
|
struct sigframe *sfp;
|
||||||
int oonstack;
|
int oonstack;
|
||||||
|
|
||||||
p = curproc;
|
td = curthread;
|
||||||
|
p = td->td_proc;
|
||||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||||
psp = p->p_sigacts;
|
psp = p->p_sigacts;
|
||||||
#ifdef COMPAT_43
|
#ifdef COMPAT_43
|
||||||
@ -461,7 +465,7 @@ sendsig(catcher, sig, mask, code)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
regs = p->p_frame;
|
regs = td->td_frame;
|
||||||
oonstack = sigonstack(regs->tf_esp);
|
oonstack = sigonstack(regs->tf_esp);
|
||||||
|
|
||||||
/* Save user context. */
|
/* Save user context. */
|
||||||
@ -541,7 +545,7 @@ sendsig(catcher, sig, mask, code)
|
|||||||
*/
|
*/
|
||||||
if (regs->tf_eflags & PSL_VM) {
|
if (regs->tf_eflags & PSL_VM) {
|
||||||
struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
|
struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
|
||||||
struct vm86_kernel *vm86 = &p->p_addr->u_pcb.pcb_ext->ext_vm86;
|
struct vm86_kernel *vm86 = &td->td_pcb->pcb_ext->ext_vm86;
|
||||||
|
|
||||||
sf.sf_uc.uc_mcontext.mc_gs = tf->tf_vm86_gs;
|
sf.sf_uc.uc_mcontext.mc_gs = tf->tf_vm86_gs;
|
||||||
sf.sf_uc.uc_mcontext.mc_fs = tf->tf_vm86_fs;
|
sf.sf_uc.uc_mcontext.mc_fs = tf->tf_vm86_fs;
|
||||||
@ -574,7 +578,7 @@ sendsig(catcher, sig, mask, code)
|
|||||||
* ...Kill the process.
|
* ...Kill the process.
|
||||||
*/
|
*/
|
||||||
PROC_LOCK(p);
|
PROC_LOCK(p);
|
||||||
sigexit(p, SIGILL);
|
sigexit(td, SIGILL);
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -599,17 +603,18 @@ sendsig(catcher, sig, mask, code)
|
|||||||
*/
|
*/
|
||||||
#ifdef COMPAT_43
|
#ifdef COMPAT_43
|
||||||
int
|
int
|
||||||
osigreturn(p, uap)
|
osigreturn(td, uap)
|
||||||
struct proc *p;
|
struct thread *td;
|
||||||
struct osigreturn_args /* {
|
struct osigreturn_args /* {
|
||||||
struct osigcontext *sigcntxp;
|
struct osigcontext *sigcntxp;
|
||||||
} */ *uap;
|
} */ *uap;
|
||||||
{
|
{
|
||||||
struct trapframe *regs;
|
struct trapframe *regs;
|
||||||
struct osigcontext *scp;
|
struct osigcontext *scp;
|
||||||
|
struct proc *p = td->td_proc;
|
||||||
int eflags;
|
int eflags;
|
||||||
|
|
||||||
regs = p->p_frame;
|
regs = td->td_frame;
|
||||||
scp = uap->sigcntxp;
|
scp = uap->sigcntxp;
|
||||||
if (!useracc((caddr_t)scp, sizeof(*scp), VM_PROT_READ))
|
if (!useracc((caddr_t)scp, sizeof(*scp), VM_PROT_READ))
|
||||||
return (EFAULT);
|
return (EFAULT);
|
||||||
@ -622,9 +627,9 @@ osigreturn(p, uap)
|
|||||||
* if pcb_ext == 0 or vm86_inited == 0, the user hasn't
|
* if pcb_ext == 0 or vm86_inited == 0, the user hasn't
|
||||||
* set up the vm86 area, and we can't enter vm86 mode.
|
* set up the vm86 area, and we can't enter vm86 mode.
|
||||||
*/
|
*/
|
||||||
if (p->p_addr->u_pcb.pcb_ext == 0)
|
if (td->td_pcb->pcb_ext == 0)
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
vm86 = &p->p_addr->u_pcb.pcb_ext->ext_vm86;
|
vm86 = &td->td_pcb->pcb_ext->ext_vm86;
|
||||||
if (vm86->vm86_inited == 0)
|
if (vm86->vm86_inited == 0)
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
|
|
||||||
@ -710,12 +715,13 @@ osigreturn(p, uap)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
sigreturn(p, uap)
|
sigreturn(td, uap)
|
||||||
struct proc *p;
|
struct thread *td;
|
||||||
struct sigreturn_args /* {
|
struct sigreturn_args /* {
|
||||||
ucontext_t *sigcntxp;
|
ucontext_t *sigcntxp;
|
||||||
} */ *uap;
|
} */ *uap;
|
||||||
{
|
{
|
||||||
|
struct proc *p = td->td_proc;
|
||||||
struct trapframe *regs;
|
struct trapframe *regs;
|
||||||
ucontext_t *ucp;
|
ucontext_t *ucp;
|
||||||
int cs, eflags;
|
int cs, eflags;
|
||||||
@ -725,7 +731,7 @@ sigreturn(p, uap)
|
|||||||
if (!useracc((caddr_t)ucp, sizeof(struct osigcontext), VM_PROT_READ))
|
if (!useracc((caddr_t)ucp, sizeof(struct osigcontext), VM_PROT_READ))
|
||||||
return (EFAULT);
|
return (EFAULT);
|
||||||
if (((struct osigcontext *)ucp)->sc_trapno == 0x01d516)
|
if (((struct osigcontext *)ucp)->sc_trapno == 0x01d516)
|
||||||
return (osigreturn(p, (struct osigreturn_args *)uap));
|
return (osigreturn(td, (struct osigreturn_args *)uap));
|
||||||
/*
|
/*
|
||||||
* Since ucp is not an osigcontext but a ucontext_t, we have to
|
* Since ucp is not an osigcontext but a ucontext_t, we have to
|
||||||
* check again if all of it is accessible. A ucontext_t is
|
* check again if all of it is accessible. A ucontext_t is
|
||||||
@ -737,7 +743,7 @@ sigreturn(p, uap)
|
|||||||
if (!useracc((caddr_t)ucp, sizeof(*ucp), VM_PROT_READ))
|
if (!useracc((caddr_t)ucp, sizeof(*ucp), VM_PROT_READ))
|
||||||
return (EFAULT);
|
return (EFAULT);
|
||||||
|
|
||||||
regs = p->p_frame;
|
regs = td->td_frame;
|
||||||
eflags = ucp->uc_mcontext.mc_eflags;
|
eflags = ucp->uc_mcontext.mc_eflags;
|
||||||
if (eflags & PSL_VM) {
|
if (eflags & PSL_VM) {
|
||||||
struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
|
struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
|
||||||
@ -747,9 +753,9 @@ sigreturn(p, uap)
|
|||||||
* if pcb_ext == 0 or vm86_inited == 0, the user hasn't
|
* if pcb_ext == 0 or vm86_inited == 0, the user hasn't
|
||||||
* set up the vm86 area, and we can't enter vm86 mode.
|
* set up the vm86 area, and we can't enter vm86 mode.
|
||||||
*/
|
*/
|
||||||
if (p->p_addr->u_pcb.pcb_ext == 0)
|
if (td->td_pcb->pcb_ext == 0)
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
vm86 = &p->p_addr->u_pcb.pcb_ext->ext_vm86;
|
vm86 = &td->td_pcb->pcb_ext->ext_vm86;
|
||||||
if (vm86->vm86_inited == 0)
|
if (vm86->vm86_inited == 0)
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
|
|
||||||
@ -878,14 +884,14 @@ cpu_idle(void)
|
|||||||
* Clear registers on exec
|
* Clear registers on exec
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
setregs(p, entry, stack, ps_strings)
|
setregs(td, entry, stack, ps_strings)
|
||||||
struct proc *p;
|
struct thread *td;
|
||||||
u_long entry;
|
u_long entry;
|
||||||
u_long stack;
|
u_long stack;
|
||||||
u_long ps_strings;
|
u_long ps_strings;
|
||||||
{
|
{
|
||||||
struct trapframe *regs = p->p_frame;
|
struct trapframe *regs = td->td_frame;
|
||||||
struct pcb *pcb = &p->p_addr->u_pcb;
|
struct pcb *pcb = td->td_pcb;
|
||||||
|
|
||||||
if (pcb->pcb_ldt)
|
if (pcb->pcb_ldt)
|
||||||
user_ldt_free(pcb);
|
user_ldt_free(pcb);
|
||||||
@ -938,7 +944,7 @@ setregs(p, entry, stack, ps_strings)
|
|||||||
* traps to the emulator (if it is done at all) mainly because
|
* traps to the emulator (if it is done at all) mainly because
|
||||||
* emulators don't provide an entry point for initialization.
|
* emulators don't provide an entry point for initialization.
|
||||||
*/
|
*/
|
||||||
p->p_addr->u_pcb.pcb_flags &= ~FP_SOFTFP;
|
td->td_pcb->pcb_flags &= ~FP_SOFTFP;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Arrange to trap the next npx or `fwait' instruction (see npx.c
|
* Arrange to trap the next npx or `fwait' instruction (see npx.c
|
||||||
@ -961,7 +967,7 @@ setregs(p, entry, stack, ps_strings)
|
|||||||
* Make sure sure edx is 0x0 on entry. Linux binaries depend
|
* Make sure sure edx is 0x0 on entry. Linux binaries depend
|
||||||
* on it.
|
* on it.
|
||||||
*/
|
*/
|
||||||
p->p_retval[1] = 0;
|
td->td_retval[1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1029,7 +1035,8 @@ extern int has_f00f_bug;
|
|||||||
static struct i386tss dblfault_tss;
|
static struct i386tss dblfault_tss;
|
||||||
static char dblfault_stack[PAGE_SIZE];
|
static char dblfault_stack[PAGE_SIZE];
|
||||||
|
|
||||||
extern struct user *proc0paddr;
|
extern struct user *proc0uarea;
|
||||||
|
extern vm_offset_t proc0kstack;
|
||||||
|
|
||||||
|
|
||||||
/* software prototypes -- in more palatable form */
|
/* software prototypes -- in more palatable form */
|
||||||
@ -1718,8 +1725,12 @@ init386(first)
|
|||||||
struct region_descriptor r_gdt, r_idt;
|
struct region_descriptor r_gdt, r_idt;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
proc0.p_addr = proc0paddr;
|
proc_linkup(&proc0);
|
||||||
|
proc0.p_uarea = proc0uarea;
|
||||||
|
thread0 = &proc0.p_thread;
|
||||||
|
thread0->td_kstack = proc0kstack;
|
||||||
|
thread0->td_pcb = (struct pcb *)
|
||||||
|
(thread0->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||||
atdevbase = ISA_HOLE_START + KERNBASE;
|
atdevbase = ISA_HOLE_START + KERNBASE;
|
||||||
|
|
||||||
#ifdef PC98
|
#ifdef PC98
|
||||||
@ -1785,10 +1796,11 @@ init386(first)
|
|||||||
lgdt(&r_gdt);
|
lgdt(&r_gdt);
|
||||||
|
|
||||||
/* setup curproc so that mutexes work */
|
/* setup curproc so that mutexes work */
|
||||||
PCPU_SET(curproc, &proc0);
|
|
||||||
|
PCPU_SET(curthread, thread0);
|
||||||
PCPU_SET(spinlocks, NULL);
|
PCPU_SET(spinlocks, NULL);
|
||||||
|
|
||||||
LIST_INIT(&proc0.p_contested);
|
LIST_INIT(&thread0->td_contested);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize mutexes.
|
* Initialize mutexes.
|
||||||
@ -1892,8 +1904,9 @@ init386(first)
|
|||||||
initializecpu(); /* Initialize CPU registers */
|
initializecpu(); /* Initialize CPU registers */
|
||||||
|
|
||||||
/* make an initial tss so cpu can get interrupt stack on syscall! */
|
/* make an initial tss so cpu can get interrupt stack on syscall! */
|
||||||
PCPU_SET(common_tss.tss_esp0,
|
/* Note: -16 is so we can grow the trapframe if we came from vm86 */
|
||||||
(int) proc0.p_addr + UPAGES*PAGE_SIZE - 16);
|
PCPU_SET(common_tss.tss_esp0, thread0->td_kstack +
|
||||||
|
KSTACK_PAGES * PAGE_SIZE - sizeof(struct pcb) - 16);
|
||||||
PCPU_SET(common_tss.tss_ss0, GSEL(GDATA_SEL, SEL_KPL));
|
PCPU_SET(common_tss.tss_ss0, GSEL(GDATA_SEL, SEL_KPL));
|
||||||
gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
|
gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
|
||||||
private_tss = 0;
|
private_tss = 0;
|
||||||
@ -1948,10 +1961,10 @@ init386(first)
|
|||||||
_udatasel = LSEL(LUDATA_SEL, SEL_UPL);
|
_udatasel = LSEL(LUDATA_SEL, SEL_UPL);
|
||||||
|
|
||||||
/* setup proc 0's pcb */
|
/* setup proc 0's pcb */
|
||||||
proc0.p_addr->u_pcb.pcb_flags = 0;
|
thread0->td_pcb->pcb_flags = 0; /* XXXKSE */
|
||||||
proc0.p_addr->u_pcb.pcb_cr3 = (int)IdlePTD;
|
thread0->td_pcb->pcb_cr3 = (int)IdlePTD;
|
||||||
proc0.p_addr->u_pcb.pcb_ext = 0;
|
thread0->td_pcb->pcb_ext = 0;
|
||||||
proc0.p_frame = &proc0_tf;
|
thread0->td_frame = &proc0_tf;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(I586_CPU) && !defined(NO_F00F_HACK)
|
#if defined(I586_CPU) && !defined(NO_F00F_HACK)
|
||||||
@ -1994,31 +2007,26 @@ f00f_hack(void *unused) {
|
|||||||
#endif /* defined(I586_CPU) && !NO_F00F_HACK */
|
#endif /* defined(I586_CPU) && !NO_F00F_HACK */
|
||||||
|
|
||||||
int
|
int
|
||||||
ptrace_set_pc(p, addr)
|
ptrace_set_pc(struct thread *td, unsigned long addr)
|
||||||
struct proc *p;
|
|
||||||
unsigned long addr;
|
|
||||||
{
|
{
|
||||||
p->p_frame->tf_eip = addr;
|
td->td_frame->tf_eip = addr;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ptrace_single_step(p)
|
ptrace_single_step(struct thread *td)
|
||||||
struct proc *p;
|
|
||||||
{
|
{
|
||||||
p->p_frame->tf_eflags |= PSL_T;
|
td->td_frame->tf_eflags |= PSL_T;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fill_regs(p, regs)
|
fill_regs(struct thread *td, struct reg *regs)
|
||||||
struct proc *p;
|
|
||||||
struct reg *regs;
|
|
||||||
{
|
{
|
||||||
struct pcb *pcb;
|
struct pcb *pcb;
|
||||||
struct trapframe *tp;
|
struct trapframe *tp;
|
||||||
|
|
||||||
tp = p->p_frame;
|
tp = td->td_frame;
|
||||||
regs->r_fs = tp->tf_fs;
|
regs->r_fs = tp->tf_fs;
|
||||||
regs->r_es = tp->tf_es;
|
regs->r_es = tp->tf_es;
|
||||||
regs->r_ds = tp->tf_ds;
|
regs->r_ds = tp->tf_ds;
|
||||||
@ -2034,20 +2042,18 @@ fill_regs(p, regs)
|
|||||||
regs->r_eflags = tp->tf_eflags;
|
regs->r_eflags = tp->tf_eflags;
|
||||||
regs->r_esp = tp->tf_esp;
|
regs->r_esp = tp->tf_esp;
|
||||||
regs->r_ss = tp->tf_ss;
|
regs->r_ss = tp->tf_ss;
|
||||||
pcb = &p->p_addr->u_pcb;
|
pcb = td->td_pcb;
|
||||||
regs->r_gs = pcb->pcb_gs;
|
regs->r_gs = pcb->pcb_gs;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
set_regs(p, regs)
|
set_regs(struct thread *td, struct reg *regs)
|
||||||
struct proc *p;
|
|
||||||
struct reg *regs;
|
|
||||||
{
|
{
|
||||||
struct pcb *pcb;
|
struct pcb *pcb;
|
||||||
struct trapframe *tp;
|
struct trapframe *tp;
|
||||||
|
|
||||||
tp = p->p_frame;
|
tp = td->td_frame;
|
||||||
if (!EFL_SECURE(regs->r_eflags, tp->tf_eflags) ||
|
if (!EFL_SECURE(regs->r_eflags, tp->tf_eflags) ||
|
||||||
!CS_SECURE(regs->r_cs))
|
!CS_SECURE(regs->r_cs))
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
@ -2066,7 +2072,7 @@ set_regs(p, regs)
|
|||||||
tp->tf_eflags = regs->r_eflags;
|
tp->tf_eflags = regs->r_eflags;
|
||||||
tp->tf_esp = regs->r_esp;
|
tp->tf_esp = regs->r_esp;
|
||||||
tp->tf_ss = regs->r_ss;
|
tp->tf_ss = regs->r_ss;
|
||||||
pcb = &p->p_addr->u_pcb;
|
pcb = td->td_pcb;
|
||||||
pcb->pcb_gs = regs->r_gs;
|
pcb->pcb_gs = regs->r_gs;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -2126,45 +2132,39 @@ set_fpregs_xmm(sv_87, sv_xmm)
|
|||||||
#endif /* CPU_ENABLE_SSE */
|
#endif /* CPU_ENABLE_SSE */
|
||||||
|
|
||||||
int
|
int
|
||||||
fill_fpregs(p, fpregs)
|
fill_fpregs(struct thread *td, struct fpreg *fpregs)
|
||||||
struct proc *p;
|
|
||||||
struct fpreg *fpregs;
|
|
||||||
{
|
{
|
||||||
#ifdef CPU_ENABLE_SSE
|
#ifdef CPU_ENABLE_SSE
|
||||||
if (cpu_fxsr) {
|
if (cpu_fxsr) {
|
||||||
fill_fpregs_xmm(&p->p_addr->u_pcb.pcb_save.sv_xmm,
|
fill_fpregs_xmm(&td->td_pcb->pcb_save.sv_xmm,
|
||||||
(struct save87 *)fpregs);
|
(struct save87 *)fpregs);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
#endif /* CPU_ENABLE_SSE */
|
#endif /* CPU_ENABLE_SSE */
|
||||||
bcopy(&p->p_addr->u_pcb.pcb_save.sv_87, fpregs, sizeof *fpregs);
|
bcopy(&td->td_pcb->pcb_save.sv_87, fpregs, sizeof *fpregs);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
set_fpregs(p, fpregs)
|
set_fpregs(struct thread *td, struct fpreg *fpregs)
|
||||||
struct proc *p;
|
|
||||||
struct fpreg *fpregs;
|
|
||||||
{
|
{
|
||||||
#ifdef CPU_ENABLE_SSE
|
#ifdef CPU_ENABLE_SSE
|
||||||
if (cpu_fxsr) {
|
if (cpu_fxsr) {
|
||||||
set_fpregs_xmm((struct save87 *)fpregs,
|
set_fpregs_xmm((struct save87 *)fpregs,
|
||||||
&p->p_addr->u_pcb.pcb_save.sv_xmm);
|
&td->td_pcb->pcb_save.sv_xmm);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
#endif /* CPU_ENABLE_SSE */
|
#endif /* CPU_ENABLE_SSE */
|
||||||
bcopy(fpregs, &p->p_addr->u_pcb.pcb_save.sv_87, sizeof *fpregs);
|
bcopy(fpregs, &td->td_pcb->pcb_save.sv_87, sizeof *fpregs);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fill_dbregs(p, dbregs)
|
fill_dbregs(struct thread *td, struct dbreg *dbregs)
|
||||||
struct proc *p;
|
|
||||||
struct dbreg *dbregs;
|
|
||||||
{
|
{
|
||||||
struct pcb *pcb;
|
struct pcb *pcb;
|
||||||
|
|
||||||
if (p == NULL) {
|
if (td == NULL) {
|
||||||
dbregs->dr0 = rdr0();
|
dbregs->dr0 = rdr0();
|
||||||
dbregs->dr1 = rdr1();
|
dbregs->dr1 = rdr1();
|
||||||
dbregs->dr2 = rdr2();
|
dbregs->dr2 = rdr2();
|
||||||
@ -2173,9 +2173,8 @@ fill_dbregs(p, dbregs)
|
|||||||
dbregs->dr5 = rdr5();
|
dbregs->dr5 = rdr5();
|
||||||
dbregs->dr6 = rdr6();
|
dbregs->dr6 = rdr6();
|
||||||
dbregs->dr7 = rdr7();
|
dbregs->dr7 = rdr7();
|
||||||
}
|
} else {
|
||||||
else {
|
pcb = td->td_pcb;
|
||||||
pcb = &p->p_addr->u_pcb;
|
|
||||||
dbregs->dr0 = pcb->pcb_dr0;
|
dbregs->dr0 = pcb->pcb_dr0;
|
||||||
dbregs->dr1 = pcb->pcb_dr1;
|
dbregs->dr1 = pcb->pcb_dr1;
|
||||||
dbregs->dr2 = pcb->pcb_dr2;
|
dbregs->dr2 = pcb->pcb_dr2;
|
||||||
@ -2189,15 +2188,13 @@ fill_dbregs(p, dbregs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
set_dbregs(p, dbregs)
|
set_dbregs(struct thread *td, struct dbreg *dbregs)
|
||||||
struct proc *p;
|
|
||||||
struct dbreg *dbregs;
|
|
||||||
{
|
{
|
||||||
struct pcb *pcb;
|
struct pcb *pcb;
|
||||||
int i;
|
int i;
|
||||||
u_int32_t mask1, mask2;
|
u_int32_t mask1, mask2;
|
||||||
|
|
||||||
if (p == NULL) {
|
if (td == NULL) {
|
||||||
load_dr0(dbregs->dr0);
|
load_dr0(dbregs->dr0);
|
||||||
load_dr1(dbregs->dr1);
|
load_dr1(dbregs->dr1);
|
||||||
load_dr2(dbregs->dr2);
|
load_dr2(dbregs->dr2);
|
||||||
@ -2206,8 +2203,7 @@ set_dbregs(p, dbregs)
|
|||||||
load_dr5(dbregs->dr5);
|
load_dr5(dbregs->dr5);
|
||||||
load_dr6(dbregs->dr6);
|
load_dr6(dbregs->dr6);
|
||||||
load_dr7(dbregs->dr7);
|
load_dr7(dbregs->dr7);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
/*
|
/*
|
||||||
* Don't let an illegal value for dr7 get set. Specifically,
|
* Don't let an illegal value for dr7 get set. Specifically,
|
||||||
* check for undefined settings. Setting these bit patterns
|
* check for undefined settings. Setting these bit patterns
|
||||||
@ -2219,7 +2215,7 @@ set_dbregs(p, dbregs)
|
|||||||
if ((dbregs->dr7 & mask1) == mask2)
|
if ((dbregs->dr7 & mask1) == mask2)
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
|
|
||||||
pcb = &p->p_addr->u_pcb;
|
pcb = td->td_pcb;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Don't let a process set a breakpoint that is not within the
|
* Don't let a process set a breakpoint that is not within the
|
||||||
@ -2236,7 +2232,7 @@ set_dbregs(p, dbregs)
|
|||||||
* from within kernel mode?
|
* from within kernel mode?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (suser(p) != 0) {
|
if (suser_td(td) != 0) {
|
||||||
if (dbregs->dr7 & 0x3) {
|
if (dbregs->dr7 & 0x3) {
|
||||||
/* dr0 is enabled */
|
/* dr0 is enabled */
|
||||||
if (dbregs->dr0 >= VM_MAXUSER_ADDRESS)
|
if (dbregs->dr0 >= VM_MAXUSER_ADDRESS)
|
||||||
|
Loading…
Reference in New Issue
Block a user