Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/*
2
 * functions for running the debugged process
3
 */
4
 
5
#include "defs.h"
6
#include "fns.h"
7
 
8
 
9
int child;
10
int msgfd = -1;
11
int notefd = -1;
12
int pcspid = -1;
13
int pcsactive = 0;
14
 
15
void
16
setpcs(void)
17
{
18
	char buf[128];
19
 
20
	if(pid && pid != pcspid){
21
		if(msgfd >= 0){
22
			close(msgfd);
23
			msgfd = -1;
24
		}
25
		if(notefd >= 0){
26
			close(notefd);
27
			notefd = -1;
28
		}
29
		pcspid = -1;
30
		sprint(buf, "/proc/%d/ctl", pid);
31
		msgfd = open(buf, OWRITE);
32
		if(msgfd < 0)
33
			error("can't open control file");
34
		sprint(buf, "/proc/%d/note", pid);
35
		notefd = open(buf, ORDWR);
36
		if(notefd < 0)
37
			error("can't open note file");
38
		pcspid = pid;
39
	}
40
}
41
 
42
void
43
msgpcs(char *msg)
44
{
45
	char err[ERRMAX];
46
 
47
	setpcs();
48
	if(write(msgfd, msg, strlen(msg)) < 0 && !ending){
49
		errstr(err, sizeof err);
50
		if(strcmp(err, "interrupted") != 0)
51
			endpcs();
52
		errors("can't write control file", err);
53
	}
54
}
55
 
56
/*
57
 * empty the note buffer and toss pending breakpoint notes
58
 */
59
void
60
unloadnote(void)
61
{
62
	char err[ERRMAX];
63
 
64
	setpcs();
65
	for(; nnote<NNOTE; nnote++){
66
		switch(read(notefd, note[nnote], sizeof note[nnote])){
67
		case -1:
68
			errstr(err, sizeof err);
69
			if(strcmp(err, "interrupted") != 0)
70
				endpcs();
71
			errors("can't read note file", err);
72
		case 0:
73
			return;
74
		}
75
		note[nnote][ERRMAX-1] = '\0';
76
		if(strncmp(note[nnote], "sys: breakpoint", 15) == 0)
77
			--nnote;
78
	}
79
}
80
 
81
/*
82
 * reload the note buffer
83
 */
84
void
85
loadnote(void)
86
{
87
	int i;
88
	char err[ERRMAX];
89
 
90
	setpcs();
91
	for(i=0; i<nnote; i++){
92
		if(write(notefd, note[i], strlen(note[i])) < 0){
93
			errstr(err, sizeof err);
94
			if(strcmp(err, "interrupted") != 0)
95
				endpcs();
96
			errors("can't write note file", err);
97
		}
98
	}
99
	nnote = 0;
100
}
101
 
102
void
103
notes(void)
104
{
105
	int n;
106
 
107
	if(nnote == 0)
108
		return;
109
	dprint("notes:\n");
110
	for(n=0; n<nnote; n++)
111
		dprint("%d:\t%s\n", n, note[n]);
112
}
113
 
114
void
115
killpcs(void)
116
{
117
	msgpcs("kill");
118
}
119
 
120
void
121
grab(void)
122
{
123
	flush();
124
	msgpcs("stop");
125
	bpwait();
126
}
127
 
128
void
129
ungrab(void)
130
{
131
	msgpcs("start");
132
}
133
 
134
void
135
doexec(void)
136
{
137
	char *argl[MAXARG];
138
	char args[LINSIZ];
139
	char *p;
140
	char **ap;
141
	char *thisarg;
142
 
143
	ap = argl;
144
	p = args;
145
	*ap++ = symfil;
146
	for (rdc(); lastc != EOR;) {
147
		thisarg = p;
148
		if (lastc == '<' || lastc == '>') {
149
			*p++ = lastc;
150
			rdc();
151
		}
152
		while (lastc != EOR && lastc != SPC && lastc != TB) {
153
			*p++ = lastc;
154
			readchar();
155
		}
156
		if (lastc == SPC || lastc == TB)
157
			rdc();
158
		*p++ = 0;
159
		if (*thisarg == '<') {
160
			close(0);
161
			if (open(&thisarg[1], OREAD) < 0) {
162
				print("%s: cannot open\n", &thisarg[1]);
163
				_exits(0);
164
			}
165
		}
166
		else if (*thisarg == '>') {
167
			close(1);
168
			if (create(&thisarg[1], OWRITE, 0666) < 0) {
169
				print("%s: cannot create\n", &thisarg[1]);
170
				_exits(0);
171
			}
172
		}
173
		else
174
			*ap++ = thisarg;
175
	}
176
	*ap = 0;
177
	exec(symfil, argl);
178
	perror(symfil);
179
}
180
 
181
char	procname[100];
182
 
183
void
184
startpcs(void)
185
{
186
	if ((pid = fork()) == 0) {
187
		pid = getpid();
188
		msgpcs("hang");
189
		doexec();
190
		exits(0);
191
	}
192
 
193
	if (pid == -1)
194
		error("can't fork");
195
	child++;
196
	sprint(procname, "/proc/%d/mem", pid);
197
	corfil = procname;
198
	msgpcs("waitstop");
199
	bpwait();
200
	if (adrflg)
201
		rput(cormap, mach->pc, adrval);
202
	while (rdc() != EOR)
203
		;
204
	reread();
205
}
206
 
207
void
208
runstep(uvlong loc, int keepnote)
209
{
210
	int nfoll;
211
	uvlong foll[3];
212
	BKPT bkpt[3];
213
	int i;
214
 
215
	if(machdata->foll == 0){
216
		dprint("stepping unimplemented; assuming not a branch\n");
217
		nfoll = 1;
218
		foll[0] = loc+mach->pcquant;
219
	}else {
220
		nfoll = machdata->foll(cormap, loc, rget, foll);
221
		if (nfoll < 0)
222
			error("%r");
223
	}
224
	memset(bkpt, 0, sizeof bkpt);
225
	for(i=0; i<nfoll; i++){
226
		if(foll[i] == loc)
227
			error("can't single step: next instruction is dot");
228
		bkpt[i].loc = foll[i];
229
		bkput(&bkpt[i], 1);
230
	}
231
	runrun(keepnote);
232
	for(i=0; i<nfoll; i++)
233
		bkput(&bkpt[i], 0);
234
}
235
 
236
void
237
bpwait(void)
238
{
239
	setcor();
240
	unloadnote();
241
}
242
 
243
void
244
runrun(int keepnote)
245
{
246
	int on;
247
 
248
	on = nnote;
249
	unloadnote();
250
	if(on != nnote){
251
		notes();
252
		error("not running: new notes pending");
253
	}
254
	if(keepnote)
255
		loadnote();
256
	else
257
		nnote = 0;
258
	flush();
259
	msgpcs("startstop");
260
	bpwait();
261
}
262
 
263
void
264
bkput(BKPT *bp, int install)
265
{
266
	char buf[256];
267
	ADDR loc;
268
	int ret;
269
 
270
	errstr(buf, sizeof buf);
271
	if(machdata->bpfix)
272
		loc = (*machdata->bpfix)(bp->loc);
273
	else
274
		loc = bp->loc;
275
	if(install){
276
		ret = get1(cormap, loc, bp->save, machdata->bpsize);
277
		if (ret > 0)
278
			ret = put1(cormap, loc, machdata->bpinst, machdata->bpsize);
279
	}else
280
		ret = put1(cormap, loc, bp->save, machdata->bpsize);
281
	if(ret < 0){
282
		sprint(buf, "can't set breakpoint at %#llux: %r", bp->loc);
283
		print(buf);
284
		read(0, buf, 100);
285
	}
286
}