1: /*
2: * Copyright (c) 1986 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: *
6: * @(#)sys_process.c 1.2 (2.11BSD) 1999/9/5
7: */
8:
9: #include "param.h"
10: #include "../machine/psl.h"
11: #include "../machine/reg.h"
12: #include "../machine/seg.h"
13:
14: #include "systm.h"
15: #include "user.h"
16: #include "proc.h"
17: #include "inode.h"
18: #include "text.h"
19: #include "vm.h"
20: #include "ptrace.h"
21:
22: /*
23: * Tracing variables.
24: * Used to pass trace command from
25: * parent to child being traced.
26: * This data base cannot be
27: * shared and is locked
28: * per user.
29: */
30: struct
31: {
32: int ip_lock;
33: int ip_req;
34: int *ip_addr;
35: int ip_data;
36: } ipc;
37:
38: /*
39: * sys-trace system call.
40: */
41: ptrace()
42: {
43: register struct proc *p;
44: register struct a {
45: int req;
46: int pid;
47: int *addr;
48: int data;
49: } *uap;
50:
51: uap = (struct a *)u.u_ap;
52: if (uap->req <= 0) {
53: u.u_procp->p_flag |= P_TRACED;
54: return;
55: }
56: p = pfind(uap->pid);
57: if (p == 0 || p->p_stat != SSTOP || p->p_ppid != u.u_procp->p_pid ||
58: !(p->p_flag & P_TRACED)) {
59: u.u_error = ESRCH;
60: return;
61: }
62: while (ipc.ip_lock)
63: sleep((caddr_t)&ipc, PZERO);
64: ipc.ip_lock = p->p_pid;
65: ipc.ip_data = uap->data;
66: ipc.ip_addr = uap->addr;
67: ipc.ip_req = uap->req;
68: p->p_flag &= ~P_WAITED;
69: setrun(p);
70: while (ipc.ip_req > 0)
71: sleep((caddr_t)&ipc, PZERO);
72: u.u_r.r_val1 = (short)ipc.ip_data;
73: if (ipc.ip_req < 0)
74: u.u_error = EIO;
75: ipc.ip_lock = 0;
76: wakeup((caddr_t)&ipc);
77: }
78:
79: /*
80: * Code that the child process
81: * executes to implement the command
82: * of the parent process in tracing.
83: */
84: procxmt()
85: {
86: register int i;
87: register *p;
88: register struct text *xp;
89:
90: if (ipc.ip_lock != u.u_procp->p_pid)
91: return(0);
92: u.u_procp->p_slptime = 0;
93: i = ipc.ip_req;
94: ipc.ip_req = 0;
95: wakeup((caddr_t)&ipc);
96: switch (i) {
97:
98: /* read user I */
99: case PT_READ_I:
100: #ifndef NONSEPARATE
101: if (fuibyte((caddr_t)ipc.ip_addr) == -1)
102: goto error;
103: ipc.ip_data = fuiword((caddr_t)ipc.ip_addr);
104: break;
105: #endif /* !NONSEPARATE */
106:
107: /* read user D */
108: case PT_READ_D:
109: if (fubyte((caddr_t)ipc.ip_addr) == -1)
110: goto error;
111: ipc.ip_data = fuword((caddr_t)ipc.ip_addr);
112: break;
113:
114: /* read u */
115: case PT_READ_U:
116: i = (int)ipc.ip_addr;
117: if (i<0 || i >= ctob(USIZE))
118: goto error;
119: ipc.ip_data = ((physadr)&u)->r[i/sizeof(int)];
120: break;
121:
122: /* write user I */
123: /* Must set up to allow writing */
124: case PT_WRITE_I:
125: /*
126: * If text, must assure exclusive use
127: */
128: if (xp = u.u_procp->p_textp) {
129: if (xp->x_count!=1 || xp->x_iptr->i_mode&ISVTX)
130: goto error;
131: xp->x_flag |= XTRC;
132: }
133: estabur(u.u_tsize, u.u_dsize, u.u_ssize, u.u_sep, RW);
134: i = suiword((caddr_t)ipc.ip_addr, 0);
135: suiword((caddr_t)ipc.ip_addr, ipc.ip_data);
136: estabur(u.u_tsize, u.u_dsize, u.u_ssize, u.u_sep, RO);
137: if (i<0)
138: goto error;
139: if (xp)
140: xp->x_flag |= XWRIT;
141: break;
142:
143: /* write user D */
144: case PT_WRITE_D:
145: if (suword((caddr_t)ipc.ip_addr, 0) < 0)
146: goto error;
147: suword((caddr_t)ipc.ip_addr, ipc.ip_data);
148: break;
149:
150: /* write u */
151: case PT_WRITE_U:
152: i = (int)ipc.ip_addr;
153: p = (int *)&((physadr)&u)->r[i/sizeof(int)];
154: if (p >= (int *)&u.u_fps && p < (int *)&u.u_fps.u_fpregs[6])
155: goto ok;
156: for (i=0; i<8; i++)
157: if (p == &u.u_ar0[regloc[i]])
158: goto ok;
159: if (p == &u.u_ar0[RPS]) {
160: ipc.ip_data |= PSL_USERSET; /* user space */
161: ipc.ip_data &= ~PSL_USERCLR; /* priority 0 */
162: goto ok;
163: }
164: if ((p == (int *)&u.u_ovdata.uo_curov) && ((ipc.ip_data >= 0) &&
165: (ipc.ip_data <= NOVL) && u.u_ovdata.uo_ovbase)) {
166: u.u_ovdata.uo_curov = ipc.ip_data;
167: choverlay(RW);
168: break;
169: }
170: goto error;
171:
172: ok:
173: *p = ipc.ip_data;
174: break;
175:
176: /* set signal and continue */
177: /* one version causes a trace-trap */
178: case PT_STEP:
179: u.u_ar0[RPS] |= PSL_T;
180: /* FALL THROUGH TO ... */
181: case PT_CONTINUE:
182: if ((int)ipc.ip_addr != 1)
183: u.u_ar0[PC] = (int)ipc.ip_addr;
184: if (ipc.ip_data > NSIG)
185: goto error;
186: u.u_procp->p_ptracesig = ipc.ip_data;
187: return(1);
188:
189: /* force exit */
190: case PT_KILL:
191: exit(u.u_procp->p_ptracesig);
192: /*NOTREACHED*/
193:
194: default:
195: error:
196: ipc.ip_req = -1;
197: }
198: return(0);
199: }
Defined functions
Defined struct's
a
defined in line
44; used 2 times