projects
/
unix-history
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
tags
|
clone url
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
notify clock routines when a process requests profiling
[unix-history]
/
usr
/
src
/
sys
/
kern
/
sys_process.c
diff --git
a/usr/src/sys/kern/sys_process.c
b/usr/src/sys/kern/sys_process.c
index
ff849cf
..
ab623e6
100644
(file)
--- a/
usr/src/sys/kern/sys_process.c
+++ b/
usr/src/sys/kern/sys_process.c
@@
-1,19
+1,25
@@
-/* sys_process.c 5.6 82/10/31 */
-
-#include "../h/param.h"
-#include "../h/systm.h"
-#include "../h/dir.h"
-#include "../h/user.h"
-#include "../h/proc.h"
-#include "../h/inode.h"
-#include "../h/reg.h"
-#include "../h/text.h"
-#include "../h/seg.h"
-#include "../h/pte.h"
-#include "../h/psl.h"
-#include "../h/vm.h"
-#include "../h/buf.h"
-#include "../h/acct.h"
+/*-
+ * Copyright (c) 1982, 1986, 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * %sccs.include.proprietary.c%
+ *
+ * @(#)sys_process.c 7.26 (Berkeley) %G%
+ */
+
+#define IPCREG
+#include "param.h"
+#include "proc.h"
+#include "vnode.h"
+#include "buf.h"
+#include "ptrace.h"
+
+#include "machine/reg.h"
+#include "machine/psl.h"
+#include "vm/vm.h"
+#include "vm/vm_page.h"
+
+#include "user.h"
/*
* Priority for tracing
/*
* Priority for tracing
@@
-36,28
+42,28
@@
struct {
} ipc;
/*
} ipc;
/*
- *
sys-trace
system call.
+ *
Process debugging
system call.
*/
*/
-ptrace()
-{
- register struct proc *p;
- register struct a {
+ptrace(curp, uap, retval)
+ struct proc *curp;
+ register struct args {
int req;
int pid;
int *addr;
int data;
} *uap;
int req;
int pid;
int *addr;
int data;
} *uap;
+ int *retval;
+{
+ register struct proc *p;
- uap = (struct a *)u.u_ap;
if (uap->req <= 0) {
if (uap->req <= 0) {
-
u.u_proc
p->p_flag |= STRC;
- return;
+
cur
p->p_flag |= STRC;
+ return
(0)
;
}
p = pfind(uap->pid);
}
p = pfind(uap->pid);
- if (p == 0 || p->p_stat != SSTOP || p->p_ppid != u.u_procp->p_pid) {
- u.u_error = ESRCH;
- return;
- }
+ if (p == 0 || p->p_stat != SSTOP || p->p_pptr != curp ||
+ !(p->p_flag & STRC))
+ return (ESRCH);
while (ipc.ip_lock)
sleep((caddr_t)&ipc, IPCPRI);
ipc.ip_lock = p->p_pid;
while (ipc.ip_lock)
sleep((caddr_t)&ipc, IPCPRI);
ipc.ip_lock = p->p_pid;
@@
-70,138
+76,154
@@
ptrace()
setrun(p);
sleep((caddr_t)&ipc, IPCPRI);
}
setrun(p);
sleep((caddr_t)&ipc, IPCPRI);
}
- u.u_r.r_val1 = ipc.ip_data;
- if (ipc.ip_req < 0)
- u.u_error = EIO;
+ *retval = ipc.ip_data;
ipc.ip_lock = 0;
wakeup((caddr_t)&ipc);
ipc.ip_lock = 0;
wakeup((caddr_t)&ipc);
+ if (ipc.ip_req < 0)
+ return (EIO);
+ return (0);
}
}
-#if vax
-#define NIPCREG 16
-#endif
-#if sun
-#define NIPCREG 17
-#endif
-int ipcreg[NIPCREG] =
-#if vax
- {R0,R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,AP,FP,SP,PC};
-#endif
-#if sun
- {R0,R1,R2,R3,R4,R5,R6,R7,AR0,AR1,AR2,AR3,AR4,AR5,AR6,AR7,PC};
-#endif
+#define PHYSOFF(p, o) ((caddr_t)(p) + (o))
-#define PHYSOFF(p, o) \
- ((physadr)(p)+((o)/sizeof(((physadr)0)->r[0])))
+#if defined(i386)
+#undef PC
+#undef SP
+#undef PS
+#undef R0
+#undef R1
+
+#define PC tEIP
+#define SP tESP
+#define PS tEFLAGS
+#define R0 tEDX
+#define R1 tECX
+#endif
/*
/*
- *
Code that
the child process
- *
executes to implement the command
- *
of the parent process in tracing
.
+ *
Transmit a tracing request from the parent to
the child process
+ *
being debugged. This code runs in the context of the child process
+ *
to fulfill the command requested by the parent
.
*/
*/
-procxmt()
+procxmt(p)
+ register struct proc *p;
{
{
- register int i;
- register *p;
- register struct text *xp;
+ register int i, *poff;
+ extern char kstack[];
- if (ipc.ip_lock !=
u.u_proc
p->p_pid)
+ if (ipc.ip_lock != p->p_pid)
return (0);
return (0);
- u.u_procp->p_slptime = 0;
+ p->p_slptime = 0;
+ p->p_addr->u_kproc.kp_proc.p_md.md_regs = p->p_md.md_regs; /* u.u_ar0 */
i = ipc.ip_req;
ipc.ip_req = 0;
switch (i) {
i = ipc.ip_req;
ipc.ip_req = 0;
switch (i) {
- /* read user I */
- case 1:
+ case PT_READ_I: /* read the child's text space */
if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ))
goto error;
ipc.ip_data = fuiword((caddr_t)ipc.ip_addr);
break;
if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ))
goto error;
ipc.ip_data = fuiword((caddr_t)ipc.ip_addr);
break;
- /* read user D */
- case 2:
+ case PT_READ_D: /* read the child's data space */
if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ))
goto error;
ipc.ip_data = fuword((caddr_t)ipc.ip_addr);
break;
if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ))
goto error;
ipc.ip_data = fuword((caddr_t)ipc.ip_addr);
break;
- /* read u */
- case 3:
+ case PT_READ_U: /* read the child's u. */
+#ifdef HPUXCOMPAT
+ if (p->p_addr->u_pcb.pcb_flags & PCB_HPUXTRACE)
+ i = hpuxtobsduoff(ipc.ip_addr);
+ else
+#endif
i = (int)ipc.ip_addr;
i = (int)ipc.ip_addr;
- if (
i<0 || i >= ctob(UPAGES)
)
+ if (
(u_int) i > ctob(UPAGES)-sizeof(int) || (i & 1) != 0
)
goto error;
goto error;
- ipc.ip_data = *(int *)PHYSOFF(
&u
, i);
+ ipc.ip_data = *(int *)PHYSOFF(
p->p_addr
, i);
break;
break;
- /* write user I */
- /* Must set up to allow writing */
- case 4:
- /*
- * If text, must assure exclusive use
- */
- if (xp = u.u_procp->p_textp) {
- if (xp->x_count!=1 || xp->x_iptr->i_mode&ISVTX)
- goto error;
- xp->x_iptr->i_flag &= ~ITEXT;
- }
- i = -1;
+ case PT_WRITE_I: /* write the child's text space */
if ((i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data)) < 0) {
if ((i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data)) < 0) {
- if (chgprot((caddr_t)ipc.ip_addr, RW) &&
- chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RW))
+ vm_offset_t sa, ea;
+ int rv;
+
+ sa = trunc_page((vm_offset_t)ipc.ip_addr);
+ ea = round_page((vm_offset_t)ipc.ip_addr+sizeof(int)-1);
+ rv = vm_map_protect(&p->p_vmspace->vm_map, sa, ea,
+ VM_PROT_DEFAULT, FALSE);
+ if (rv == KERN_SUCCESS) {
i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data);
i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data);
- (void) chgprot((caddr_t)ipc.ip_addr, RO);
- (void) chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RO);
+ (void) vm_map_protect(&p->p_vmspace->vm_map,
+ sa, ea, VM_PROT_READ|VM_PROT_EXECUTE,
+ FALSE);
+ }
}
if (i < 0)
goto error;
}
if (i < 0)
goto error;
- if (xp)
- xp->x_flag |= XWRIT;
break;
break;
- /* write user D */
- case 5:
+ case PT_WRITE_D: /* write the child's data space */
if (suword((caddr_t)ipc.ip_addr, 0) < 0)
goto error;
(void) suword((caddr_t)ipc.ip_addr, ipc.ip_data);
break;
if (suword((caddr_t)ipc.ip_addr, 0) < 0)
goto error;
(void) suword((caddr_t)ipc.ip_addr, ipc.ip_data);
break;
- /* write u */
- case 6:
+ case PT_WRITE_U: /* write the child's u. */
+#ifdef HPUXCOMPAT
+ if (p->p_addr->u_pcb.pcb_flags & PCB_HPUXTRACE)
+ i = hpuxtobsduoff(ipc.ip_addr);
+ else
+#endif
i = (int)ipc.ip_addr;
i = (int)ipc.ip_addr;
- p = (int *)PHYSOFF(&u, i);
+#ifdef mips
+ poff = (int *)PHYSOFF(curproc->p_addr, i);
+#else
+ poff = (int *)PHYSOFF(kstack, i);
+#endif
for (i=0; i<NIPCREG; i++)
for (i=0; i<NIPCREG; i++)
- if (p
== &u.u_ar0
[ipcreg[i]])
+ if (p
off == &p->p_md.md_regs
[ipcreg[i]])
goto ok;
goto ok;
- if (p
== &u.u_ar0
[PS]) {
+ if (p
off == &p->p_md.md_regs
[PS]) {
ipc.ip_data |= PSL_USERSET;
ipc.ip_data |= PSL_USERSET;
- ipc.ip_data &= ~PSL_USERCLR;
+ ipc.ip_data &= ~PSL_USERCLR;
+#ifdef PSL_CM_CLR
+ if (ipc.ip_data & PSL_CM)
+ ipc.ip_data &= ~PSL_CM_CLR;
+#endif
goto ok;
}
goto ok;
}
+#if defined(hp300) || defined(luna68k)
+#ifdef FPCOPROC
+ if (poff >= (int *)&((struct user *)kstack)->u_pcb.pcb_fpregs.fpf_regs &&
+ poff <= (int *)&((struct user *)kstack)->u_pcb.pcb_fpregs.fpf_fpiar)
+ goto ok;
+#endif
+#endif
goto error;
ok:
goto error;
ok:
- *p = ipc.ip_data;
+ *p
off
= ipc.ip_data;
break;
break;
- /* set signal and continue */
- /* one version causes a trace-trap */
- case 9:
- case 7:
+ case PT_STEP: /* single step the child */
+ case PT_CONTINUE: /* continue the child */
if ((int)ipc.ip_addr != 1)
if ((int)ipc.ip_addr != 1)
-
u.u_ar0
[PC] = (int)ipc.ip_addr;
+
p->p_md.md_regs
[PC] = (int)ipc.ip_addr;
if ((unsigned)ipc.ip_data > NSIG)
goto error;
if ((unsigned)ipc.ip_data > NSIG)
goto error;
- u.u_procp->p_cursig = ipc.ip_data; /* see issig */
- if (i == 9)
- u.u_ar0[PS] |= PSL_T;
+ p->p_xstat = ipc.ip_data; /* see issig */
+#ifdef PSL_T
+ /* need something more machine independent here... */
+ if (i == PT_STEP)
+ p->p_md.md_regs[PS] |= PSL_T;
+#endif
wakeup((caddr_t)&ipc);
return (1);
wakeup((caddr_t)&ipc);
return (1);
- /* force exit */
- case 8:
+ case PT_KILL: /* kill the child process */
wakeup((caddr_t)&ipc);
wakeup((caddr_t)&ipc);
- exit(
u.u_procp->p_cursig
);
+ exit(
p, (int)p->p_xstat
);
default:
error:
default:
error:
@@
-210,3
+232,28
@@
procxmt()
wakeup((caddr_t)&ipc);
return (0);
}
wakeup((caddr_t)&ipc);
return (0);
}
+
+/*
+ * Process debugging system call.
+ */
+/* ARGSUSED */
+profil(p, uap, retval)
+ struct proc *p;
+ register struct args {
+ short *bufbase;
+ unsigned bufsize;
+ unsigned pcoffset;
+ unsigned pcscale;
+ } *uap;
+ int *retval;
+{
+ register struct uprof *upp = &p->p_stats->p_prof;
+
+ upp->pr_base = uap->bufbase;
+ upp->pr_size = uap->bufsize;
+ upp->pr_off = uap->pcoffset;
+ upp->pr_scale = uap->pcscale;
+ if (uap->pcscale)
+ startprofclock(p);
+ return (0);
+}