statfs.f_bsize => statfs.f_iosize; statfs.f_fsize => statfs.f_bsize (for SunOS)
[unix-history] / usr / src / sys / kern / sys_process.c
CommitLineData
5dc2581e
KB
1/*-
2 * Copyright (c) 1982, 1986, 1989 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * %sccs.include.proprietary.c%
da7c5cc6 6 *
4fa687fa 7 * @(#)sys_process.c 7.23 (Berkeley) %G%
da7c5cc6 8 */
961945a8 9
ff32eb64 10#define IPCREG
94368568 11#include "param.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"
de5931fb 20#include "vm/vm.h"
d7db4999 21#include "vm/vm_page.h"
de5931fb
MK
22
23#include "user.h"
d301d150 24
4147b3f6
BJ
25/*
26 * Priority for tracing
27 */
28#define IPCPRI PZERO
29
30/*
31 * Tracing variables.
32 * Used to pass trace command from
33 * parent to child being traced.
34 * This data base cannot be
35 * shared and is locked
36 * per user.
37 */
38struct {
39 int ip_lock;
40 int ip_req;
41 int *ip_addr;
42 int ip_data;
43} ipc;
44
45/*
3f75397a 46 * Process debugging system call.
4147b3f6 47 */
8c7d0e2a
KM
48ptrace(curp, uap, retval)
49 struct proc *curp;
50 register struct args {
4147b3f6
BJ
51 int req;
52 int pid;
53 int *addr;
54 int data;
55 } *uap;
8c7d0e2a
KM
56 int *retval;
57{
58 register struct proc *p;
4147b3f6 59
4147b3f6 60 if (uap->req <= 0) {
8c7d0e2a 61 curp->p_flag |= STRC;
d9c2f47f 62 return (0);
4147b3f6
BJ
63 }
64 p = pfind(uap->pid);
d7db4999 65 if (p == 0 || p->p_stat != SSTOP || p->p_pptr != curp ||
8c7d0e2a 66 !(p->p_flag & STRC))
d9c2f47f 67 return (ESRCH);
4147b3f6
BJ
68 while (ipc.ip_lock)
69 sleep((caddr_t)&ipc, IPCPRI);
70 ipc.ip_lock = p->p_pid;
71 ipc.ip_data = uap->data;
72 ipc.ip_addr = uap->addr;
73 ipc.ip_req = uap->req;
74 p->p_flag &= ~SWTED;
75 while (ipc.ip_req > 0) {
76 if (p->p_stat==SSTOP)
77 setrun(p);
78 sleep((caddr_t)&ipc, IPCPRI);
79 }
8c7d0e2a 80 *retval = ipc.ip_data;
4147b3f6
BJ
81 ipc.ip_lock = 0;
82 wakeup((caddr_t)&ipc);
8c7d0e2a 83 if (ipc.ip_req < 0)
d9c2f47f
MK
84 return (EIO);
85 return (0);
4147b3f6
BJ
86}
87
e128a701
MK
88#define PHYSOFF(p, o) ((caddr_t)(p) + (o))
89
6ce8aff2
WN
90#if defined(i386)
91#undef PC
92#undef SP
93#undef PS
94#undef R0
95#undef R1
96
97#define PC tEIP
98#define SP tESP
99#define PS tEFLAGS
100#define R0 tEDX
101#define R1 tECX
102#endif
883d0f83 103
4147b3f6 104/*
3f75397a
KM
105 * Transmit a tracing request from the parent to the child process
106 * being debugged. This code runs in the context of the child process
107 * to fulfill the command requested by the parent.
4147b3f6 108 */
82655668
KM
109procxmt(p)
110 register struct proc *p;
4147b3f6 111{
82655668 112 register int i, *poff;
e128a701 113 extern char kstack[];
4147b3f6 114
82655668 115 if (ipc.ip_lock != p->p_pid)
4147b3f6 116 return (0);
82655668 117 p->p_slptime = 0;
eadb8ef2 118 p->p_addr->u_kproc.kp_proc.p_regs = p->p_regs; /* u.u_ar0 */
4147b3f6
BJ
119 i = ipc.ip_req;
120 ipc.ip_req = 0;
121 switch (i) {
122
01b0e233 123 case PT_READ_I: /* read the child's text space */
4147b3f6
BJ
124 if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ))
125 goto error;
126 ipc.ip_data = fuiword((caddr_t)ipc.ip_addr);
127 break;
128
01b0e233 129 case PT_READ_D: /* read the child's data space */
4147b3f6
BJ
130 if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ))
131 goto error;
132 ipc.ip_data = fuword((caddr_t)ipc.ip_addr);
133 break;
134
01b0e233 135 case PT_READ_U: /* read the child's u. */
dc57440c 136#ifdef HPUXCOMPAT
eadb8ef2 137 if (p->p_addr->u_pcb.pcb_flags & PCB_HPUXTRACE)
dc57440c
KM
138 i = hpuxtobsduoff(ipc.ip_addr);
139 else
140#endif
4147b3f6 141 i = (int)ipc.ip_addr;
e128a701 142 if ((u_int) i > ctob(UPAGES)-sizeof(int) || (i & 1) != 0)
4147b3f6 143 goto error;
eadb8ef2 144 ipc.ip_data = *(int *)PHYSOFF(p->p_addr, i);
4147b3f6
BJ
145 break;
146
01b0e233 147 case PT_WRITE_I: /* write the child's text space */
883d0f83 148 if ((i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data)) < 0) {
9db58063
KM
149 vm_offset_t sa, ea;
150 int rv;
151
152 sa = trunc_page((vm_offset_t)ipc.ip_addr);
153 ea = round_page((vm_offset_t)ipc.ip_addr+sizeof(int)-1);
d7db4999 154 rv = vm_map_protect(&p->p_vmspace->vm_map, sa, ea,
9db58063
KM
155 VM_PROT_DEFAULT, FALSE);
156 if (rv == KERN_SUCCESS) {
883d0f83 157 i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data);
d7db4999
MK
158 (void) vm_map_protect(&p->p_vmspace->vm_map,
159 sa, ea, VM_PROT_READ|VM_PROT_EXECUTE,
160 FALSE);
9db58063 161 }
883d0f83 162 }
4147b3f6
BJ
163 if (i < 0)
164 goto error;
4147b3f6
BJ
165 break;
166
01b0e233 167 case PT_WRITE_D: /* write the child's data space */
4147b3f6
BJ
168 if (suword((caddr_t)ipc.ip_addr, 0) < 0)
169 goto error;
170 (void) suword((caddr_t)ipc.ip_addr, ipc.ip_data);
171 break;
172
01b0e233 173 case PT_WRITE_U: /* write the child's u. */
dc57440c 174#ifdef HPUXCOMPAT
eadb8ef2 175 if (p->p_addr->u_pcb.pcb_flags & PCB_HPUXTRACE)
dc57440c
KM
176 i = hpuxtobsduoff(ipc.ip_addr);
177 else
178#endif
4147b3f6 179 i = (int)ipc.ip_addr;
e128a701 180 poff = (int *)PHYSOFF(kstack, i);
883d0f83 181 for (i=0; i<NIPCREG; i++)
d7db4999 182 if (poff == &p->p_regs[ipcreg[i]])
4147b3f6 183 goto ok;
d7db4999 184 if (poff == &p->p_regs[PS]) {
883d0f83 185 ipc.ip_data |= PSL_USERSET;
dc57440c 186 ipc.ip_data &= ~PSL_USERCLR;
bf47fbca
MK
187#ifdef PSL_CM_CLR
188 if (ipc.ip_data & PSL_CM)
189 ipc.ip_data &= ~PSL_CM_CLR;
190#endif
4147b3f6
BJ
191 goto ok;
192 }
dc57440c
KM
193#if defined(hp300)
194#ifdef FPCOPROC
e128a701
MK
195 if (poff >= (int *)&((struct user *)kstack)->u_pcb.pcb_fpregs.fpf_regs &&
196 poff <= (int *)&((struct user *)kstack)->u_pcb.pcb_fpregs.fpf_fpiar)
dc57440c
KM
197 goto ok;
198#endif
199#endif
4147b3f6
BJ
200 goto error;
201
202 ok:
82655668 203 *poff = ipc.ip_data;
4147b3f6
BJ
204 break;
205
01b0e233
MK
206 case PT_STEP: /* single step the child */
207 case PT_CONTINUE: /* continue the child */
4147b3f6 208 if ((int)ipc.ip_addr != 1)
d7db4999 209 p->p_regs[PC] = (int)ipc.ip_addr;
4147b3f6
BJ
210 if ((unsigned)ipc.ip_data > NSIG)
211 goto error;
19dec745 212 p->p_xstat = ipc.ip_data; /* see issig */
01b0e233 213 if (i == PT_STEP)
d7db4999 214 p->p_regs[PS] |= PSL_T;
4147b3f6
BJ
215 wakeup((caddr_t)&ipc);
216 return (1);
217
01b0e233 218 case PT_KILL: /* kill the child process */
4147b3f6 219 wakeup((caddr_t)&ipc);
21d115dd 220 exit(p, (int)p->p_xstat);
4147b3f6
BJ
221
222 default:
223 error:
224 ipc.ip_req = -1;
225 }
226 wakeup((caddr_t)&ipc);
227 return (0);
228}
f7fd221a 229
3f75397a
KM
230/*
231 * Process debugging system call.
232 */
f7fd221a
KM
233/* ARGSUSED */
234profil(p, uap, retval)
235 struct proc *p;
236 register struct args {
237 short *bufbase;
238 unsigned bufsize;
239 unsigned pcoffset;
240 unsigned pcscale;
241 } *uap;
242 int *retval;
243{
244 register struct uprof *upp = &p->p_stats->p_prof;
245
246 upp->pr_base = uap->bufbase;
247 upp->pr_size = uap->bufsize;
248 upp->pr_off = uap->pcoffset;
249 upp->pr_scale = uap->pcscale;
250#ifdef PROFTIMER
251 initprofclock();
252#endif
253 return (0);
254}