more-or-less working with new proc & user structs
[unix-history] / usr / src / sys / kern / sys_process.c
CommitLineData
da7c5cc6 1/*
c4ec2128 2 * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
da7c5cc6
KM
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
d7db4999 6 * @(#)sys_process.c 7.16 (Berkeley) %G%
da7c5cc6 7 */
961945a8 8
ff32eb64 9#define IPCREG
94368568 10#include "param.h"
d9c2f47f 11#include "user.h"
94368568 12#include "proc.h"
c4ec2128 13#include "vnode.h"
94368568 14#include "seg.h"
94368568 15#include "buf.h"
01b0e233 16#include "ptrace.h"
9ce4de2d 17
d301d150
KM
18#include "machine/reg.h"
19#include "machine/psl.h"
d7db4999
MK
20#include "vm/vm_page.h"
21#include "vm/vm_prot.h"
d301d150 22
4147b3f6
BJ
23/*
24 * Priority for tracing
25 */
26#define IPCPRI PZERO
27
28/*
29 * Tracing variables.
30 * Used to pass trace command from
31 * parent to child being traced.
32 * This data base cannot be
33 * shared and is locked
34 * per user.
35 */
36struct {
37 int ip_lock;
38 int ip_req;
39 int *ip_addr;
40 int ip_data;
41} ipc;
42
43/*
44 * sys-trace system call.
45 */
8c7d0e2a
KM
46ptrace(curp, uap, retval)
47 struct proc *curp;
48 register struct args {
4147b3f6
BJ
49 int req;
50 int pid;
51 int *addr;
52 int data;
53 } *uap;
8c7d0e2a
KM
54 int *retval;
55{
56 register struct proc *p;
4147b3f6 57
4147b3f6 58 if (uap->req <= 0) {
8c7d0e2a 59 curp->p_flag |= STRC;
d9c2f47f 60 return (0);
4147b3f6
BJ
61 }
62 p = pfind(uap->pid);
d7db4999 63 if (p == 0 || p->p_stat != SSTOP || p->p_pptr != curp ||
8c7d0e2a 64 !(p->p_flag & STRC))
d9c2f47f 65 return (ESRCH);
4147b3f6
BJ
66 while (ipc.ip_lock)
67 sleep((caddr_t)&ipc, IPCPRI);
68 ipc.ip_lock = p->p_pid;
69 ipc.ip_data = uap->data;
70 ipc.ip_addr = uap->addr;
71 ipc.ip_req = uap->req;
72 p->p_flag &= ~SWTED;
73 while (ipc.ip_req > 0) {
74 if (p->p_stat==SSTOP)
75 setrun(p);
76 sleep((caddr_t)&ipc, IPCPRI);
77 }
8c7d0e2a 78 *retval = ipc.ip_data;
4147b3f6
BJ
79 ipc.ip_lock = 0;
80 wakeup((caddr_t)&ipc);
8c7d0e2a 81 if (ipc.ip_req < 0)
d9c2f47f
MK
82 return (EIO);
83 return (0);
4147b3f6
BJ
84}
85
fc0890b1 86#define PHYSOFF(p, o) \
883d0f83 87 ((physadr)(p)+((o)/sizeof(((physadr)0)->r[0])))
6ce8aff2
WN
88#if defined(i386)
89#undef PC
90#undef SP
91#undef PS
92#undef R0
93#undef R1
94
95#define PC tEIP
96#define SP tESP
97#define PS tEFLAGS
98#define R0 tEDX
99#define R1 tECX
100#endif
883d0f83 101
4147b3f6
BJ
102/*
103 * Code that the child process
104 * executes to implement the command
105 * of the parent process in tracing.
106 */
82655668
KM
107procxmt(p)
108 register struct proc *p;
4147b3f6 109{
82655668 110 register int i, *poff;
4147b3f6 111
82655668 112 if (ipc.ip_lock != p->p_pid)
4147b3f6 113 return (0);
82655668 114 p->p_slptime = 0;
4147b3f6
BJ
115 i = ipc.ip_req;
116 ipc.ip_req = 0;
117 switch (i) {
118
01b0e233 119 case PT_READ_I: /* read the child's text space */
4147b3f6
BJ
120 if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ))
121 goto error;
122 ipc.ip_data = fuiword((caddr_t)ipc.ip_addr);
123 break;
124
01b0e233 125 case PT_READ_D: /* read the child's data space */
4147b3f6
BJ
126 if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ))
127 goto error;
128 ipc.ip_data = fuword((caddr_t)ipc.ip_addr);
129 break;
130
01b0e233 131 case PT_READ_U: /* read the child's u. */
dc57440c
KM
132#ifdef HPUXCOMPAT
133 if (u.u_pcb.pcb_flags & PCB_HPUXTRACE)
134 i = hpuxtobsduoff(ipc.ip_addr);
135 else
136#endif
4147b3f6 137 i = (int)ipc.ip_addr;
dc57440c 138 if (i<0 || i > ctob(UPAGES)-sizeof(int))
4147b3f6 139 goto error;
883d0f83 140 ipc.ip_data = *(int *)PHYSOFF(&u, i);
4147b3f6
BJ
141 break;
142
01b0e233 143 case PT_WRITE_I: /* write the child's text space */
883d0f83 144 if ((i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data)) < 0) {
9db58063
KM
145 vm_offset_t sa, ea;
146 int rv;
147
148 sa = trunc_page((vm_offset_t)ipc.ip_addr);
149 ea = round_page((vm_offset_t)ipc.ip_addr+sizeof(int)-1);
d7db4999 150 rv = vm_map_protect(&p->p_vmspace->vm_map, sa, ea,
9db58063
KM
151 VM_PROT_DEFAULT, FALSE);
152 if (rv == KERN_SUCCESS) {
883d0f83 153 i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data);
d7db4999
MK
154 (void) vm_map_protect(&p->p_vmspace->vm_map,
155 sa, ea, VM_PROT_READ|VM_PROT_EXECUTE,
156 FALSE);
9db58063 157 }
883d0f83 158 }
4147b3f6
BJ
159 if (i < 0)
160 goto error;
4147b3f6
BJ
161 break;
162
01b0e233 163 case PT_WRITE_D: /* write the child's data space */
4147b3f6
BJ
164 if (suword((caddr_t)ipc.ip_addr, 0) < 0)
165 goto error;
166 (void) suword((caddr_t)ipc.ip_addr, ipc.ip_data);
167 break;
168
01b0e233 169 case PT_WRITE_U: /* write the child's u. */
dc57440c
KM
170#ifdef HPUXCOMPAT
171 if (u.u_pcb.pcb_flags & PCB_HPUXTRACE)
172 i = hpuxtobsduoff(ipc.ip_addr);
173 else
174#endif
4147b3f6 175 i = (int)ipc.ip_addr;
82655668 176 poff = (int *)PHYSOFF(&u, i);
883d0f83 177 for (i=0; i<NIPCREG; i++)
d7db4999 178 if (poff == &p->p_regs[ipcreg[i]])
4147b3f6 179 goto ok;
d7db4999 180 if (poff == &p->p_regs[PS]) {
883d0f83 181 ipc.ip_data |= PSL_USERSET;
dc57440c 182 ipc.ip_data &= ~PSL_USERCLR;
bf47fbca
MK
183#ifdef PSL_CM_CLR
184 if (ipc.ip_data & PSL_CM)
185 ipc.ip_data &= ~PSL_CM_CLR;
186#endif
4147b3f6
BJ
187 goto ok;
188 }
dc57440c
KM
189#if defined(hp300)
190#ifdef FPCOPROC
82655668
KM
191 if (poff >= (int *)u.u_pcb.pcb_fpregs.fpf_regs &&
192 poff <= (int *)&u.u_pcb.pcb_fpregs.fpf_fpiar)
dc57440c
KM
193 goto ok;
194#endif
195#endif
4147b3f6
BJ
196 goto error;
197
198 ok:
82655668 199 *poff = ipc.ip_data;
4147b3f6
BJ
200 break;
201
01b0e233
MK
202 case PT_STEP: /* single step the child */
203 case PT_CONTINUE: /* continue the child */
4147b3f6 204 if ((int)ipc.ip_addr != 1)
d7db4999 205 p->p_regs[PC] = (int)ipc.ip_addr;
4147b3f6
BJ
206 if ((unsigned)ipc.ip_data > NSIG)
207 goto error;
19dec745 208 p->p_xstat = ipc.ip_data; /* see issig */
01b0e233 209 if (i == PT_STEP)
d7db4999 210 p->p_regs[PS] |= PSL_T;
4147b3f6
BJ
211 wakeup((caddr_t)&ipc);
212 return (1);
213
01b0e233 214 case PT_KILL: /* kill the child process */
4147b3f6 215 wakeup((caddr_t)&ipc);
21d115dd 216 exit(p, (int)p->p_xstat);
4147b3f6
BJ
217
218 default:
219 error:
220 ipc.ip_req = -1;
221 }
222 wakeup((caddr_t)&ipc);
223 return (0);
224}