Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_tlsv12/sys/src/cmd/acid/main.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <bio.h>
4
#include <mach.h>
5
#define Extern
6
#include "acid.h"
7
#include "y.tab.h"
8
 
9
extern int _ifmt(Fmt*);
10
 
11
static Biobuf	bioout;
12
static char	prog[128];
13
static char*	lm[16];
14
static int	nlm;
15
static char*	mtype;
16
 
17
static	int attachfiles(char*, int);
18
int	xfmt(Fmt*);
19
int	isnumeric(char*);
20
void	die(void);
21
void	loadmoduleobjtype(void);
22
 
23
void
24
usage(void)
25
{
26
	fprint(2, "usage: acid [-kqw] [-l library] [-m machine] [pid] [file]\n");
27
	exits("usage");
28
}
29
 
30
void
31
main(int argc, char *argv[])
32
{
33
	Lsym *l;
34
	Node *n;
35
	char *s;
36
	int pid, i;
37
 
38
	argv0 = argv[0];
39
	pid = 0;
40
	aout = "8.out";
41
	quiet = 1;
42
 
43
	mtype = 0;
44
	ARGBEGIN{
45
	case 'm':
46
		mtype = ARGF();
47
		break;
48
	case 'w':
49
		wtflag = 1;
50
		break;
51
	case 'l':
52
		s = ARGF();
53
		if(s == 0)
54
			usage();
55
		lm[nlm++] = s;
56
		break;
57
	case 'k':
58
		kernel++;
59
		break;
60
	case 'q':
61
		quiet = 0;
62
		break;
63
	case 'r':
64
		pid = 1;
65
		remote++;
66
		kernel++;
67
		break;
68
	default:
69
		usage();
70
	}ARGEND
71
 
72
	if(argc > 0) {
73
		if(remote)
74
			aout = argv[0];
75
		else
76
		if(isnumeric(argv[0])) {
77
			pid = strtol(argv[0], 0, 0);
78
			snprint(prog, sizeof(prog), "/proc/%d/text", pid);
79
			aout = prog;
80
			if(argc > 1)
81
				aout = argv[1];
82
			else if(kernel)
83
				aout = system();
84
		}
85
		else {
86
			if(kernel) {
87
				fprint(2, "acid: -k requires a pid\n");
88
				usage();
89
			}
90
			aout = argv[0];
91
		}
92
	} else
93
	if(remote)
94
		aout = "/mips/9ch";
95
 
96
	fmtinstall('x', xfmt);
97
	fmtinstall('L', Lfmt);
98
	Binit(&bioout, 1, OWRITE);
99
	bout = &bioout;
100
 
101
	kinit();
102
	initialising = 1;
103
	pushfile(0);
104
	loadvars();
105
	installbuiltin();
106
 
107
	if(mtype && machbyname(mtype) == 0)
108
		print("unknown machine %s", mtype);
109
 
110
	if (attachfiles(aout, pid) < 0)
111
		varreg();		/* use default register set on error */
112
 
113
	loadmodule("/sys/lib/acid/port");
114
	loadmoduleobjtype();
115
 
116
	for(i = 0; i < nlm; i++) {
117
		if(access(lm[i], AREAD) >= 0)
118
			loadmodule(lm[i]);
119
		else {
120
			s = smprint("/sys/lib/acid/%s", lm[i]);
121
			loadmodule(s);
122
			free(s);
123
		}
124
	}
125
 
126
	userinit();
127
	varsym();
128
 
129
	l = look("acidmap");
130
	if(l && l->proc) {
131
		n = an(ONAME, ZN, ZN);
132
		n->sym = l;
133
		n = an(OCALL, n, ZN);
134
		execute(n);
135
	}
136
 
137
	interactive = 1;
138
	initialising = 0;
139
	line = 1;
140
 
141
	notify(catcher);
142
 
143
	for(;;) {
144
		if(setjmp(err)) {
145
			Binit(&bioout, 1, OWRITE);
146
			unwind();
147
		}
148
		stacked = 0;
149
 
150
		Bprint(bout, "acid: ");
151
 
152
		if(yyparse() != 1)
153
			die();
154
		restartio();
155
 
156
		unwind();
157
	}
158
	/* not reached */
159
}
160
 
161
static int
162
attachfiles(char *aout, int pid)
163
{
164
	interactive = 0;
165
	if(setjmp(err))
166
		return -1;
167
 
168
	if(aout) {				/* executable given */
169
		if(wtflag)
170
			text = open(aout, ORDWR);
171
		else
172
			text = open(aout, OREAD);
173
 
174
		if(text < 0)
175
			error("%s: can't open %s: %r\n", argv0, aout);
176
		readtext(aout);
177
	}
178
	if(pid)					/* pid given */
179
		sproc(pid);
180
	return 0;
181
}
182
 
183
void
184
die(void)
185
{
186
	Lsym *s;
187
	List *f;
188
 
189
	Bprint(bout, "\n");
190
 
191
	s = look("proclist");
192
	if(s && s->v->type == TLIST) {
193
		for(f = s->v->l; f; f = f->next)
194
			Bprint(bout, "echo kill > /proc/%d/ctl\n", (int)f->ival);
195
	}
196
	exits(0);
197
}
198
 
199
void
200
loadmoduleobjtype(void)
201
{
202
	char *buf;
203
 
204
	buf = smprint("/sys/lib/acid/%s", mach->name);
205
	loadmodule(buf);
206
	free(buf);
207
}
208
 
209
void
210
userinit(void)
211
{
212
	Lsym *l;
213
	Node *n;
214
	char *buf, *p;
215
 
216
	p = getenv("home");
217
	if(p != 0) {
218
		buf = smprint("%s/lib/acid", p);
219
		silent = 1;
220
		loadmodule(buf);
221
		free(buf);
222
	}
223
 
224
	interactive = 0;
225
	if(setjmp(err)) {
226
		unwind();
227
		return;
228
	}
229
	l = look("acidinit");
230
	if(l && l->proc) {
231
		n = an(ONAME, ZN, ZN);
232
		n->sym = l;
233
		n = an(OCALL, n, ZN);
234
		execute(n);
235
	}
236
}
237
 
238
void
239
loadmodule(char *s)
240
{
241
	interactive = 0;
242
	if(setjmp(err)) {
243
		unwind();
244
		return;
245
	}
246
	pushfile(s);
247
	silent = 0;
248
	yyparse();
249
	popio();
250
	return;
251
}
252
 
253
void
254
readtext(char *s)
255
{
256
	Dir *d;
257
	Lsym *l;
258
	Value *v;
259
	uvlong length;
260
	Symbol sym;
261
	extern Machdata mipsmach;
262
 
263
	if(mtype != 0){
264
		symmap = newmap(0, 1);
265
		if(symmap == 0)
266
			print("%s: (error) loadmap: cannot make symbol map\n", argv0);
267
		length = 1<<24;
268
		d = dirfstat(text);
269
		if(d != nil){
270
			length = d->length;
271
			free(d);
272
		}
273
		setmap(symmap, text, 0, length, 0, "binary");
274
		return;
275
	}
276
 
277
	machdata = &mipsmach;
278
 
279
	if(!crackhdr(text, &fhdr)) {
280
		print("can't decode file header\n");
281
		return;
282
	}
283
 
284
	symmap = loadmap(0, text, &fhdr);
285
	if(symmap == 0)
286
		print("%s: (error) loadmap: cannot make symbol map\n", argv0);
287
 
288
	if(syminit(text, &fhdr) < 0) {
289
		print("%s: (error) syminit: %r\n", argv0);
290
		return;
291
	}
292
	print("%s:%s\n", s, fhdr.name);
293
 
294
	if(mach->sbreg && lookup(0, mach->sbreg, &sym)) {
295
		mach->sb = sym.value;
296
		l = enter("SB", Tid);
297
		l->v->fmt = 'X';
298
		l->v->ival = mach->sb;
299
		l->v->type = TINT;
300
		l->v->set = 1;
301
	}
302
 
303
	l = mkvar("objtype");
304
	v = l->v;
305
	v->fmt = 's';
306
	v->set = 1;
307
	v->string = strnode(mach->name);
308
	v->type = TSTRING;
309
 
310
	l = mkvar("textfile");
311
	v = l->v;
312
	v->fmt = 's';
313
	v->set = 1;
314
	v->string = strnode(s);
315
	v->type = TSTRING;
316
 
317
	machbytype(fhdr.type);
318
	varreg();
319
}
320
 
321
Node*
322
an(int op, Node *l, Node *r)
323
{
324
	Node *n;
325
 
326
	n = gmalloc(sizeof(Node));
327
	memset(n, 0, sizeof(Node));
328
	n->gclink = gcl;
329
	gcl = n;
330
	n->op = op;
331
	n->left = l;
332
	n->right = r;
333
	return n;
334
}
335
 
336
List*
337
al(int t)
338
{
339
	List *l;
340
 
341
	l = gmalloc(sizeof(List));
342
	memset(l, 0, sizeof(List));
343
	l->type = t;
344
	l->gclink = gcl;
345
	gcl = l;
346
	return l;
347
}
348
 
349
Node*
350
con(vlong v)
351
{
352
	Node *n;
353
 
354
	n = an(OCONST, ZN, ZN);
355
	n->ival = v;
356
	n->fmt = 'W';
357
	n->type = TINT;
358
	return n;
359
}
360
 
361
void
362
fatal(char *fmt, ...)
363
{
364
	char buf[128];
365
	va_list arg;
366
 
367
	va_start(arg, fmt);
368
	vseprint(buf, buf+sizeof(buf), fmt, arg);
369
	va_end(arg);
370
	fprint(2, "%s: %L (fatal problem) %s\n", argv0, buf);
371
	exits(buf);
372
}
373
 
374
void
375
yyerror(char *fmt, ...)
376
{
377
	char buf[128];
378
	va_list arg;
379
 
380
	if(strcmp(fmt, "syntax error") == 0) {
381
		yyerror("syntax error, near symbol '%s'", symbol);
382
		return;
383
	}
384
	va_start(arg, fmt);
385
	vseprint(buf, buf+sizeof(buf), fmt, arg);
386
	va_end(arg);
387
	print("%L: %s\n", buf);
388
}
389
 
390
void
391
marktree(Node *n)
392
{
393
 
394
	if(n == 0)
395
		return;
396
 
397
	marktree(n->left);
398
	marktree(n->right);
399
 
400
	n->gcmark = 1;
401
	if(n->op != OCONST)
402
		return;
403
 
404
	switch(n->type) {
405
	case TSTRING:
406
		n->string->gcmark = 1;
407
		break;
408
	case TLIST:
409
		marklist(n->l);
410
		break;
411
	case TCODE:
412
		marktree(n->cc);
413
		break;
414
	}
415
}
416
 
417
void
418
marklist(List *l)
419
{
420
	while(l) {
421
		l->gcmark = 1;
422
		switch(l->type) {
423
		case TSTRING:
424
			l->string->gcmark = 1;
425
			break;
426
		case TLIST:
427
			marklist(l->l);
428
			break;
429
		case TCODE:
430
			marktree(l->cc);
431
			break;
432
		}
433
		l = l->next;
434
	}
435
}
436
 
437
void
438
gc(void)
439
{
440
	int i;
441
	Lsym *f;
442
	Value *v;
443
	Gc *m, **p, *next;
444
 
445
	if(dogc < Mempergc)
446
		return;
447
	dogc = 0;
448
 
449
	/* Mark */
450
	for(m = gcl; m; m = m->gclink)
451
		m->gcmark = 0;
452
 
453
	/* Scan */
454
	for(i = 0; i < Hashsize; i++) {
455
		for(f = hash[i]; f; f = f->hash) {
456
			marktree(f->proc);
457
			if(f->lexval != Tid)
458
				continue;
459
			for(v = f->v; v; v = v->pop) {
460
				switch(v->type) {
461
				case TSTRING:
462
					v->string->gcmark = 1;
463
					break;
464
				case TLIST:
465
					marklist(v->l);
466
					break;
467
				case TCODE:
468
					marktree(v->cc);
469
					break;
470
				}
471
			}
472
		}
473
	}
474
 
475
	/* Free */
476
	p = &gcl;
477
	for(m = gcl; m; m = next) {
478
		next = m->gclink;
479
		if(m->gcmark == 0) {
480
			*p = next;
481
			free(m);	/* Sleazy reliance on my malloc */
482
		}
483
		else
484
			p = &m->gclink;
485
	}
486
}
487
 
488
void*
489
gmalloc(long l)
490
{
491
	void *p;
492
 
493
	dogc += l;
494
	p = malloc(l);
495
	if(p == 0)
496
		fatal("out of memory");
497
	return p;
498
}
499
 
500
void
501
checkqid(int f1, int pid)
502
{
503
	int fd;
504
	Dir *d1, *d2;
505
	char buf[128];
506
 
507
	if(kernel)
508
		return;
509
 
510
	d1 = dirfstat(f1);
511
	if(d1 == nil){
512
		print("checkqid: (qid not checked) dirfstat: %r\n");
513
		return;
514
	}
515
 
516
	snprint(buf, sizeof(buf), "/proc/%d/text", pid);
517
	fd = open(buf, OREAD);
518
	if(fd < 0 || (d2 = dirfstat(fd)) == nil){
519
		print("checkqid: (qid not checked) dirstat %s: %r\n", buf);
520
		free(d1);
521
		if(fd >= 0)
522
			close(fd);
523
		return;
524
	}
525
 
526
	close(fd);
527
 
528
	if(d1->qid.path != d2->qid.path || d1->qid.vers != d2->qid.vers || d1->qid.type != d2->qid.type){
529
		print("path %llux %llux vers %lud %lud type %d %d\n",
530
			d1->qid.path, d2->qid.path, d1->qid.vers, d2->qid.vers, d1->qid.type, d2->qid.type);
531
		print("warning: image does not match text for pid %d\n", pid);
532
	}
533
	free(d1);
534
	free(d2);
535
}
536
 
537
void
538
catcher(void *junk, char *s)
539
{
540
	USED(junk);
541
 
542
	if(strstr(s, "interrupt")) {
543
		gotint = 1;
544
		noted(NCONT);
545
	}
546
	noted(NDFLT);
547
}
548
 
549
char*
550
system(void)
551
{
552
	char *cpu, *p, *q;
553
	static char *kernel;
554
 
555
	cpu = getenv("cputype");
556
	if(cpu == 0) {
557
		cpu = "mips";
558
		print("$cputype not set; assuming %s\n", cpu);
559
	}
560
	p = getenv("terminal");
561
	if(p == 0 || (p=strchr(p, ' ')) == 0 || p[1] == ' ' || p[1] == 0) {
562
		p = "ch";
563
		print("missing or bad $terminal; assuming %s\n", p);
564
	}
565
	else{
566
		p++;
567
		q = strchr(p, ' ');
568
		if(q)
569
			*q = 0;
570
	}
571
 
572
	if(kernel != nil)
573
		free(kernel);
574
	kernel = smprint("/%s/9%s", cpu, p);
575
 
576
	return kernel;
577
}
578
 
579
int
580
isnumeric(char *s)
581
{
582
	while(*s) {
583
		if(*s < '0' || *s > '9')
584
			return 0;
585
		s++;
586
	}
587
	return 1;
588
}
589
 
590
int
591
xfmt(Fmt *f)
592
{
593
	f->flags ^= FmtSharp;
594
	return _ifmt(f);
595
}