|
|
1.1 root 1: /*
2: * Copyright (c) 1982, 1986, 1989 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 7.12 (Berkeley) 6/28/90
7: */
8:
9: #define IPCREG
10: #include "param.h"
11: #include "user.h"
12: #include "proc.h"
13: #include "vnode.h"
14: #include "text.h"
15: #include "seg.h"
16: #include "buf.h"
17: #include "ptrace.h"
18:
19: #include "machine/reg.h"
20: #include "machine/psl.h"
21: #include "machine/pte.h"
22:
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: */
36: struct {
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: */
46: ptrace(curp, uap, retval)
47: struct proc *curp;
48: register struct args {
49: int req;
50: int pid;
51: int *addr;
52: int data;
53: } *uap;
54: int *retval;
55: {
56: register struct proc *p;
57:
58: if (uap->req <= 0) {
59: curp->p_flag |= STRC;
60: return (0);
61: }
62: p = pfind(uap->pid);
63: if (p == 0 || p->p_stat != SSTOP || p->p_ppid != curp->p_pid ||
64: !(p->p_flag & STRC))
65: return (ESRCH);
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: }
78: *retval = ipc.ip_data;
79: ipc.ip_lock = 0;
80: wakeup((caddr_t)&ipc);
81: if (ipc.ip_req < 0)
82: return (EIO);
83: return (0);
84: }
85:
86: #define PHYSOFF(p, o) \
87: ((physadr)(p)+((o)/sizeof(((physadr)0)->r[0])))
88:
89: /*
90: * Code that the child process
91: * executes to implement the command
92: * of the parent process in tracing.
93: */
94: procxmt(p)
95: register struct proc *p;
96: {
97: register int i, *poff;
98: register struct text *xp;
99: struct vattr vattr;
100: struct vnode *vp;
101:
102: if (ipc.ip_lock != p->p_pid)
103: return (0);
104: p->p_slptime = 0;
105: i = ipc.ip_req;
106: ipc.ip_req = 0;
107: switch (i) {
108:
109: case PT_READ_I: /* read the child's text space */
110: if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ))
111: goto error;
112: ipc.ip_data = fuiword((caddr_t)ipc.ip_addr);
113: break;
114:
115: case PT_READ_D: /* read the child's data space */
116: if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ))
117: goto error;
118: ipc.ip_data = fuword((caddr_t)ipc.ip_addr);
119: break;
120:
121: case PT_READ_U: /* read the child's u. */
122: #ifdef HPUXCOMPAT
123: if (u.u_pcb.pcb_flags & PCB_HPUXTRACE)
124: i = hpuxtobsduoff(ipc.ip_addr);
125: else
126: #endif
127: i = (int)ipc.ip_addr;
128: if (i<0 || i > ctob(UPAGES)-sizeof(int))
129: goto error;
130: ipc.ip_data = *(int *)PHYSOFF(&u, i);
131: break;
132:
133: case PT_WRITE_I: /* write the child's text space */
134: /*
135: * If text, must assure exclusive use
136: */
137: if (xp = p->p_textp) {
138: vp = xp->x_vptr;
139: VOP_GETATTR(vp, &vattr, u.u_cred);
140: if (xp->x_count!=1 || (vattr.va_mode & VSVTX))
141: goto error;
142: xp->x_flag |= XTRC;
143: }
144: i = -1;
145: if ((i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data)) < 0) {
146: if (!chgprot((caddr_t)ipc.ip_addr, RW) &&
147: !chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RW))
148: i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data);
149: (void) chgprot((caddr_t)ipc.ip_addr, RO);
150: (void) chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RO);
151: }
152: if (i < 0)
153: goto error;
154: #if defined(tahoe)
155: /* make sure the old value is not in cache */
156: ckeyrelease(p->p_ckey);
157: p->p_ckey = getcodekey();
158: #endif
159: if (xp) {
160: xp->x_flag |= XWRIT;
161: #if defined(tahoe)
162: xp->x_ckey = p->p_ckey;
163: #endif
164: }
165: break;
166:
167: case PT_WRITE_D: /* write the child's data space */
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:
173: case PT_WRITE_U: /* write the child's u. */
174: #ifdef HPUXCOMPAT
175: if (u.u_pcb.pcb_flags & PCB_HPUXTRACE)
176: i = hpuxtobsduoff(ipc.ip_addr);
177: else
178: #endif
179: i = (int)ipc.ip_addr;
180: poff = (int *)PHYSOFF(&u, i);
181: for (i=0; i<NIPCREG; i++)
182: if (poff == &u.u_ar0[ipcreg[i]])
183: goto ok;
184: if (poff == &u.u_ar0[PS]) {
185: ipc.ip_data |= PSL_USERSET;
186: ipc.ip_data &= ~PSL_USERCLR;
187: #ifdef PSL_CM_CLR
188: if (ipc.ip_data & PSL_CM)
189: ipc.ip_data &= ~PSL_CM_CLR;
190: #endif
191: goto ok;
192: }
193: #if defined(hp300)
194: #ifdef FPCOPROC
195: if (poff >= (int *)u.u_pcb.pcb_fpregs.fpf_regs &&
196: poff <= (int *)&u.u_pcb.pcb_fpregs.fpf_fpiar)
197: goto ok;
198: #endif
199: #endif
200: goto error;
201:
202: ok:
203: *poff = ipc.ip_data;
204: break;
205:
206: case PT_STEP: /* single step the child */
207: case PT_CONTINUE: /* continue the child */
208: if ((int)ipc.ip_addr != 1)
209: u.u_ar0[PC] = (int)ipc.ip_addr;
210: if ((unsigned)ipc.ip_data > NSIG)
211: goto error;
212: p->p_xstat = ipc.ip_data; /* see issig */
213: if (i == PT_STEP)
214: u.u_ar0[PS] |= PSL_T;
215: wakeup((caddr_t)&ipc);
216: return (1);
217:
218: case PT_KILL: /* kill the child process */
219: wakeup((caddr_t)&ipc);
220: exit(p, p->p_xstat);
221:
222: default:
223: error:
224: ipc.ip_req = -1;
225: }
226: wakeup((caddr_t)&ipc);
227: return (0);
228: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.