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