xref: /plan9/sys/src/cmd/acid/main.c (revision 4af5a9a1337b2226c3ce480af26cabb9dde39fa9)
1bd389b36SDavid du Colombier #include <u.h>
2bd389b36SDavid du Colombier #include <libc.h>
3bd389b36SDavid du Colombier #include <bio.h>
4bd389b36SDavid du Colombier #include <mach.h>
5bd389b36SDavid du Colombier #define Extern
6bd389b36SDavid du Colombier #include "acid.h"
7bd389b36SDavid du Colombier #include "y.tab.h"
8bd389b36SDavid du Colombier 
99a747e4fSDavid du Colombier extern int _ifmt(Fmt*);
109a747e4fSDavid du Colombier 
11bd389b36SDavid du Colombier static Biobuf	bioout;
12bd389b36SDavid du Colombier static char	prog[128];
13bd389b36SDavid du Colombier static char*	lm[16];
14bd389b36SDavid du Colombier static int	nlm;
15219b2ee8SDavid du Colombier static char*	mtype;
16bd389b36SDavid du Colombier 
17219b2ee8SDavid du Colombier static	int attachfiles(char*, int);
189a747e4fSDavid du Colombier int	xfmt(Fmt*);
19bd389b36SDavid du Colombier int	isnumeric(char*);
20219b2ee8SDavid du Colombier void	die(void);
21*4af5a9a1SDavid du Colombier void	loadmoduleobjtype(void);
22219b2ee8SDavid du Colombier 
23219b2ee8SDavid du Colombier void
usage(void)24219b2ee8SDavid du Colombier usage(void)
25219b2ee8SDavid du Colombier {
264aeffbf5SDavid du Colombier 	fprint(2, "usage: acid [-kqw] [-l library] [-m machine] [pid] [file]\n");
27219b2ee8SDavid du Colombier 	exits("usage");
28219b2ee8SDavid du Colombier }
29bd389b36SDavid du Colombier 
30bd389b36SDavid du Colombier void
main(int argc,char * argv[])31bd389b36SDavid du Colombier main(int argc, char *argv[])
32bd389b36SDavid du Colombier {
337dd7cddfSDavid du Colombier 	Lsym *l;
347dd7cddfSDavid du Colombier 	Node *n;
354de34a7eSDavid du Colombier 	char *s;
36219b2ee8SDavid du Colombier 	int pid, i;
37bd389b36SDavid du Colombier 
38bd389b36SDavid du Colombier 	argv0 = argv[0];
39219b2ee8SDavid du Colombier 	pid = 0;
407dd7cddfSDavid du Colombier 	aout = "8.out";
417dd7cddfSDavid du Colombier 	quiet = 1;
42bd389b36SDavid du Colombier 
437dd7cddfSDavid du Colombier 	mtype = 0;
44bd389b36SDavid du Colombier 	ARGBEGIN{
45219b2ee8SDavid du Colombier 	case 'm':
46219b2ee8SDavid du Colombier 		mtype = ARGF();
47219b2ee8SDavid du Colombier 		break;
487dd7cddfSDavid du Colombier 	case 'w':
497dd7cddfSDavid du Colombier 		wtflag = 1;
507dd7cddfSDavid du Colombier 		break;
51bd389b36SDavid du Colombier 	case 'l':
52219b2ee8SDavid du Colombier 		s = ARGF();
53219b2ee8SDavid du Colombier 		if(s == 0)
54219b2ee8SDavid du Colombier 			usage();
55219b2ee8SDavid du Colombier 		lm[nlm++] = s;
56bd389b36SDavid du Colombier 		break;
577dd7cddfSDavid du Colombier 	case 'k':
587dd7cddfSDavid du Colombier 		kernel++;
597dd7cddfSDavid du Colombier 		break;
607dd7cddfSDavid du Colombier 	case 'q':
617dd7cddfSDavid du Colombier 		quiet = 0;
627dd7cddfSDavid du Colombier 		break;
637dd7cddfSDavid du Colombier 	case 'r':
647dd7cddfSDavid du Colombier 		pid = 1;
657dd7cddfSDavid du Colombier 		remote++;
667dd7cddfSDavid du Colombier 		kernel++;
677dd7cddfSDavid du Colombier 		break;
68bd389b36SDavid du Colombier 	default:
69219b2ee8SDavid du Colombier 		usage();
70bd389b36SDavid du Colombier 	}ARGEND
71bd389b36SDavid du Colombier 
72bd389b36SDavid du Colombier 	if(argc > 0) {
737dd7cddfSDavid du Colombier 		if(remote)
747dd7cddfSDavid du Colombier 			aout = argv[0];
757dd7cddfSDavid du Colombier 		else
76bd389b36SDavid du Colombier 		if(isnumeric(argv[0])) {
774de34a7eSDavid du Colombier 			pid = strtol(argv[0], 0, 0);
784de34a7eSDavid du Colombier 			snprint(prog, sizeof(prog), "/proc/%d/text", pid);
79bd389b36SDavid du Colombier 			aout = prog;
80219b2ee8SDavid du Colombier 			if(argc > 1)
81219b2ee8SDavid du Colombier 				aout = argv[1];
827dd7cddfSDavid du Colombier 			else if(kernel)
837dd7cddfSDavid du Colombier 				aout = system();
84bd389b36SDavid du Colombier 		}
857dd7cddfSDavid du Colombier 		else {
867dd7cddfSDavid du Colombier 			if(kernel) {
877dd7cddfSDavid du Colombier 				fprint(2, "acid: -k requires a pid\n");
887dd7cddfSDavid du Colombier 				usage();
897dd7cddfSDavid du Colombier 			}
90bd389b36SDavid du Colombier 			aout = argv[0];
91bd389b36SDavid du Colombier 		}
927dd7cddfSDavid du Colombier 	} else
937dd7cddfSDavid du Colombier 	if(remote)
944de34a7eSDavid du Colombier 		aout = "/mips/9ch";
95bd389b36SDavid du Colombier 
969a747e4fSDavid du Colombier 	fmtinstall('x', xfmt);
979a747e4fSDavid du Colombier 	fmtinstall('L', Lfmt);
98bd389b36SDavid du Colombier 	Binit(&bioout, 1, OWRITE);
99bd389b36SDavid du Colombier 	bout = &bioout;
100bd389b36SDavid du Colombier 
101bd389b36SDavid du Colombier 	kinit();
102219b2ee8SDavid du Colombier 	initialising = 1;
103219b2ee8SDavid du Colombier 	pushfile(0);
104219b2ee8SDavid du Colombier 	loadvars();
105bd389b36SDavid du Colombier 	installbuiltin();
106bd389b36SDavid du Colombier 
107219b2ee8SDavid du Colombier 	if(mtype && machbyname(mtype) == 0)
108219b2ee8SDavid du Colombier 		print("unknown machine %s", mtype);
109219b2ee8SDavid du Colombier 
110219b2ee8SDavid du Colombier 	if (attachfiles(aout, pid) < 0)
111219b2ee8SDavid du Colombier 		varreg();		/* use default register set on error */
112219b2ee8SDavid du Colombier 
113219b2ee8SDavid du Colombier 	loadmodule("/sys/lib/acid/port");
114*4af5a9a1SDavid du Colombier 	loadmoduleobjtype();
115*4af5a9a1SDavid du Colombier 
116219b2ee8SDavid du Colombier 	for(i = 0; i < nlm; i++) {
1179a747e4fSDavid du Colombier 		if(access(lm[i], AREAD) >= 0)
118219b2ee8SDavid du Colombier 			loadmodule(lm[i]);
119219b2ee8SDavid du Colombier 		else {
1204de34a7eSDavid du Colombier 			s = smprint("/sys/lib/acid/%s", lm[i]);
1214de34a7eSDavid du Colombier 			loadmodule(s);
1224de34a7eSDavid du Colombier 			free(s);
123219b2ee8SDavid du Colombier 		}
124219b2ee8SDavid du Colombier 	}
1257dd7cddfSDavid du Colombier 
126219b2ee8SDavid du Colombier 	userinit();
127bd389b36SDavid du Colombier 	varsym();
128bd389b36SDavid du Colombier 
1297dd7cddfSDavid du Colombier 	l = look("acidmap");
1307dd7cddfSDavid du Colombier 	if(l && l->proc) {
1317dd7cddfSDavid du Colombier 		n = an(ONAME, ZN, ZN);
1327dd7cddfSDavid du Colombier 		n->sym = l;
1337dd7cddfSDavid du Colombier 		n = an(OCALL, n, ZN);
1347dd7cddfSDavid du Colombier 		execute(n);
1357dd7cddfSDavid du Colombier 	}
1367dd7cddfSDavid du Colombier 
137bd389b36SDavid du Colombier 	interactive = 1;
138219b2ee8SDavid du Colombier 	initialising = 0;
139bd389b36SDavid du Colombier 	line = 1;
140bd389b36SDavid du Colombier 
141bd389b36SDavid du Colombier 	notify(catcher);
142bd389b36SDavid du Colombier 
143bd389b36SDavid du Colombier 	for(;;) {
144219b2ee8SDavid du Colombier 		if(setjmp(err)) {
145219b2ee8SDavid du Colombier 			Binit(&bioout, 1, OWRITE);
146bd389b36SDavid du Colombier 			unwind();
147bd389b36SDavid du Colombier 		}
148219b2ee8SDavid du Colombier 		stacked = 0;
149bd389b36SDavid du Colombier 
150bd389b36SDavid du Colombier 		Bprint(bout, "acid: ");
151bd389b36SDavid du Colombier 
152219b2ee8SDavid du Colombier 		if(yyparse() != 1)
153219b2ee8SDavid du Colombier 			die();
154219b2ee8SDavid du Colombier 		restartio();
155bd389b36SDavid du Colombier 
156bd389b36SDavid du Colombier 		unwind();
157bd389b36SDavid du Colombier 	}
158b85a8364SDavid du Colombier 	/* not reached */
159219b2ee8SDavid du Colombier }
160219b2ee8SDavid du Colombier 
161219b2ee8SDavid du Colombier static int
attachfiles(char * aout,int pid)162219b2ee8SDavid du Colombier attachfiles(char *aout, int pid)
163219b2ee8SDavid du Colombier {
164219b2ee8SDavid du Colombier 	interactive = 0;
165219b2ee8SDavid du Colombier 	if(setjmp(err))
166219b2ee8SDavid du Colombier 		return -1;
167219b2ee8SDavid du Colombier 
168219b2ee8SDavid du Colombier 	if(aout) {				/* executable given */
169219b2ee8SDavid du Colombier 		if(wtflag)
170219b2ee8SDavid du Colombier 			text = open(aout, ORDWR);
171219b2ee8SDavid du Colombier 		else
172219b2ee8SDavid du Colombier 			text = open(aout, OREAD);
1737dd7cddfSDavid du Colombier 
174219b2ee8SDavid du Colombier 		if(text < 0)
175219b2ee8SDavid du Colombier 			error("%s: can't open %s: %r\n", argv0, aout);
176219b2ee8SDavid du Colombier 		readtext(aout);
177219b2ee8SDavid du Colombier 	}
178219b2ee8SDavid du Colombier 	if(pid)					/* pid given */
179219b2ee8SDavid du Colombier 		sproc(pid);
180219b2ee8SDavid du Colombier 	return 0;
181bd389b36SDavid du Colombier }
182bd389b36SDavid du Colombier 
183bd389b36SDavid du Colombier void
die(void)184219b2ee8SDavid du Colombier die(void)
185219b2ee8SDavid du Colombier {
186219b2ee8SDavid du Colombier 	Lsym *s;
187219b2ee8SDavid du Colombier 	List *f;
188219b2ee8SDavid du Colombier 
189219b2ee8SDavid du Colombier 	Bprint(bout, "\n");
190219b2ee8SDavid du Colombier 
191219b2ee8SDavid du Colombier 	s = look("proclist");
192219b2ee8SDavid du Colombier 	if(s && s->v->type == TLIST) {
193219b2ee8SDavid du Colombier 		for(f = s->v->l; f; f = f->next)
1947dd7cddfSDavid du Colombier 			Bprint(bout, "echo kill > /proc/%d/ctl\n", (int)f->ival);
195219b2ee8SDavid du Colombier 	}
196219b2ee8SDavid du Colombier 	exits(0);
197219b2ee8SDavid du Colombier }
198219b2ee8SDavid du Colombier 
199219b2ee8SDavid du Colombier void
loadmoduleobjtype(void)200*4af5a9a1SDavid du Colombier loadmoduleobjtype(void)
201*4af5a9a1SDavid du Colombier {
202*4af5a9a1SDavid du Colombier 	char *buf;
203*4af5a9a1SDavid du Colombier 
204*4af5a9a1SDavid du Colombier 	buf = smprint("/sys/lib/acid/%s", mach->name);
205*4af5a9a1SDavid du Colombier 	loadmodule(buf);
206*4af5a9a1SDavid du Colombier 	free(buf);
207*4af5a9a1SDavid du Colombier }
208*4af5a9a1SDavid du Colombier 
209*4af5a9a1SDavid du Colombier void
userinit(void)210219b2ee8SDavid du Colombier userinit(void)
211bd389b36SDavid du Colombier {
212bd389b36SDavid du Colombier 	Lsym *l;
213bd389b36SDavid du Colombier 	Node *n;
2144de34a7eSDavid du Colombier 	char *buf, *p;
215bd389b36SDavid du Colombier 
216bd389b36SDavid du Colombier 	p = getenv("home");
217bd389b36SDavid du Colombier 	if(p != 0) {
2184de34a7eSDavid du Colombier 		buf = smprint("%s/lib/acid", p);
219219b2ee8SDavid du Colombier 		silent = 1;
220bd389b36SDavid du Colombier 		loadmodule(buf);
2214de34a7eSDavid du Colombier 		free(buf);
222bd389b36SDavid du Colombier 	}
223bd389b36SDavid du Colombier 
224219b2ee8SDavid du Colombier 	interactive = 0;
225219b2ee8SDavid du Colombier 	if(setjmp(err)) {
226219b2ee8SDavid du Colombier 		unwind();
227219b2ee8SDavid du Colombier 		return;
228219b2ee8SDavid du Colombier 	}
229bd389b36SDavid du Colombier 	l = look("acidinit");
230bd389b36SDavid du Colombier 	if(l && l->proc) {
231bd389b36SDavid du Colombier 		n = an(ONAME, ZN, ZN);
232bd389b36SDavid du Colombier 		n->sym = l;
233bd389b36SDavid du Colombier 		n = an(OCALL, n, ZN);
234bd389b36SDavid du Colombier 		execute(n);
235bd389b36SDavid du Colombier 	}
236bd389b36SDavid du Colombier }
237bd389b36SDavid du Colombier 
238219b2ee8SDavid du Colombier void
loadmodule(char * s)239bd389b36SDavid du Colombier loadmodule(char *s)
240bd389b36SDavid du Colombier {
241219b2ee8SDavid du Colombier 	interactive = 0;
242bd389b36SDavid du Colombier 	if(setjmp(err)) {
243bd389b36SDavid du Colombier 		unwind();
244219b2ee8SDavid du Colombier 		return;
245bd389b36SDavid du Colombier 	}
246219b2ee8SDavid du Colombier 	pushfile(s);
247219b2ee8SDavid du Colombier 	silent = 0;
248bd389b36SDavid du Colombier 	yyparse();
249219b2ee8SDavid du Colombier 	popio();
250219b2ee8SDavid du Colombier 	return;
251bd389b36SDavid du Colombier }
252bd389b36SDavid du Colombier 
253bd389b36SDavid du Colombier void
readtext(char * s)254bd389b36SDavid du Colombier readtext(char *s)
255bd389b36SDavid du Colombier {
2569a747e4fSDavid du Colombier 	Dir *d;
257bd389b36SDavid du Colombier 	Lsym *l;
258219b2ee8SDavid du Colombier 	Value *v;
2594de34a7eSDavid du Colombier 	uvlong length;
260bd389b36SDavid du Colombier 	Symbol sym;
261219b2ee8SDavid du Colombier 	extern Machdata mipsmach;
262bd389b36SDavid du Colombier 
263219b2ee8SDavid du Colombier 	if(mtype != 0){
2647dd7cddfSDavid du Colombier 		symmap = newmap(0, 1);
265219b2ee8SDavid du Colombier 		if(symmap == 0)
266219b2ee8SDavid du Colombier 			print("%s: (error) loadmap: cannot make symbol map\n", argv0);
2679a747e4fSDavid du Colombier 		length = 1<<24;
2689a747e4fSDavid du Colombier 		d = dirfstat(text);
2699a747e4fSDavid du Colombier 		if(d != nil){
2709a747e4fSDavid du Colombier 			length = d->length;
2719a747e4fSDavid du Colombier 			free(d);
2729a747e4fSDavid du Colombier 		}
2739a747e4fSDavid du Colombier 		setmap(symmap, text, 0, length, 0, "binary");
274bd389b36SDavid du Colombier 		return;
275bd389b36SDavid du Colombier 	}
276219b2ee8SDavid du Colombier 
277219b2ee8SDavid du Colombier 	machdata = &mipsmach;
278219b2ee8SDavid du Colombier 
279bd389b36SDavid du Colombier 	if(!crackhdr(text, &fhdr)) {
280219b2ee8SDavid du Colombier 		print("can't decode file header\n");
281bd389b36SDavid du Colombier 		return;
282bd389b36SDavid du Colombier 	}
283bd389b36SDavid du Colombier 
284bd389b36SDavid du Colombier 	symmap = loadmap(0, text, &fhdr);
285bd389b36SDavid du Colombier 	if(symmap == 0)
286219b2ee8SDavid du Colombier 		print("%s: (error) loadmap: cannot make symbol map\n", argv0);
287bd389b36SDavid du Colombier 
288bd389b36SDavid du Colombier 	if(syminit(text, &fhdr) < 0) {
289219b2ee8SDavid du Colombier 		print("%s: (error) syminit: %r\n", argv0);
290bd389b36SDavid du Colombier 		return;
291bd389b36SDavid du Colombier 	}
2926f222ee0SDavid du Colombier 	print("%s:%s\n", s, fhdr.name);
293bd389b36SDavid du Colombier 
294bd389b36SDavid du Colombier 	if(mach->sbreg && lookup(0, mach->sbreg, &sym)) {
295bd389b36SDavid du Colombier 		mach->sb = sym.value;
296bd389b36SDavid du Colombier 		l = enter("SB", Tid);
297bd389b36SDavid du Colombier 		l->v->fmt = 'X';
298bd389b36SDavid du Colombier 		l->v->ival = mach->sb;
299bd389b36SDavid du Colombier 		l->v->type = TINT;
300bd389b36SDavid du Colombier 		l->v->set = 1;
301bd389b36SDavid du Colombier 	}
302bd389b36SDavid du Colombier 
303219b2ee8SDavid du Colombier 	l = mkvar("objtype");
304219b2ee8SDavid du Colombier 	v = l->v;
305219b2ee8SDavid du Colombier 	v->fmt = 's';
306219b2ee8SDavid du Colombier 	v->set = 1;
307219b2ee8SDavid du Colombier 	v->string = strnode(mach->name);
308219b2ee8SDavid du Colombier 	v->type = TSTRING;
309219b2ee8SDavid du Colombier 
310219b2ee8SDavid du Colombier 	l = mkvar("textfile");
311219b2ee8SDavid du Colombier 	v = l->v;
312219b2ee8SDavid du Colombier 	v->fmt = 's';
313219b2ee8SDavid du Colombier 	v->set = 1;
314219b2ee8SDavid du Colombier 	v->string = strnode(s);
315219b2ee8SDavid du Colombier 	v->type = TSTRING;
316219b2ee8SDavid du Colombier 
317219b2ee8SDavid du Colombier 	machbytype(fhdr.type);
318219b2ee8SDavid du Colombier 	varreg();
319bd389b36SDavid du Colombier }
320bd389b36SDavid du Colombier 
321bd389b36SDavid du Colombier Node*
an(int op,Node * l,Node * r)322bd389b36SDavid du Colombier an(int op, Node *l, Node *r)
323bd389b36SDavid du Colombier {
324bd389b36SDavid du Colombier 	Node *n;
325bd389b36SDavid du Colombier 
326bd389b36SDavid du Colombier 	n = gmalloc(sizeof(Node));
327bd389b36SDavid du Colombier 	memset(n, 0, sizeof(Node));
328bd389b36SDavid du Colombier 	n->gclink = gcl;
329bd389b36SDavid du Colombier 	gcl = n;
330bd389b36SDavid du Colombier 	n->op = op;
331bd389b36SDavid du Colombier 	n->left = l;
332bd389b36SDavid du Colombier 	n->right = r;
333bd389b36SDavid du Colombier 	return n;
334bd389b36SDavid du Colombier }
335bd389b36SDavid du Colombier 
336bd389b36SDavid du Colombier List*
al(int t)337bd389b36SDavid du Colombier al(int t)
338bd389b36SDavid du Colombier {
339bd389b36SDavid du Colombier 	List *l;
340bd389b36SDavid du Colombier 
341bd389b36SDavid du Colombier 	l = gmalloc(sizeof(List));
342bd389b36SDavid du Colombier 	memset(l, 0, sizeof(List));
343bd389b36SDavid du Colombier 	l->type = t;
344bd389b36SDavid du Colombier 	l->gclink = gcl;
345bd389b36SDavid du Colombier 	gcl = l;
346bd389b36SDavid du Colombier 	return l;
347bd389b36SDavid du Colombier }
348bd389b36SDavid du Colombier 
349bd389b36SDavid du Colombier Node*
con(vlong v)3504de34a7eSDavid du Colombier con(vlong v)
351bd389b36SDavid du Colombier {
352bd389b36SDavid du Colombier 	Node *n;
353bd389b36SDavid du Colombier 
354bd389b36SDavid du Colombier 	n = an(OCONST, ZN, ZN);
355bd389b36SDavid du Colombier 	n->ival = v;
3564de34a7eSDavid du Colombier 	n->fmt = 'W';
357bd389b36SDavid du Colombier 	n->type = TINT;
358bd389b36SDavid du Colombier 	return n;
359bd389b36SDavid du Colombier }
360bd389b36SDavid du Colombier 
361bd389b36SDavid du Colombier void
fatal(char * fmt,...)362bd389b36SDavid du Colombier fatal(char *fmt, ...)
363bd389b36SDavid du Colombier {
364bd389b36SDavid du Colombier 	char buf[128];
3657dd7cddfSDavid du Colombier 	va_list arg;
366bd389b36SDavid du Colombier 
3677dd7cddfSDavid du Colombier 	va_start(arg, fmt);
3689a747e4fSDavid du Colombier 	vseprint(buf, buf+sizeof(buf), fmt, arg);
3697dd7cddfSDavid du Colombier 	va_end(arg);
370219b2ee8SDavid du Colombier 	fprint(2, "%s: %L (fatal problem) %s\n", argv0, buf);
371bd389b36SDavid du Colombier 	exits(buf);
372bd389b36SDavid du Colombier }
373bd389b36SDavid du Colombier 
374bd389b36SDavid du Colombier void
yyerror(char * fmt,...)3757dd7cddfSDavid du Colombier yyerror(char *fmt, ...)
376bd389b36SDavid du Colombier {
377bd389b36SDavid du Colombier 	char buf[128];
3787dd7cddfSDavid du Colombier 	va_list arg;
379bd389b36SDavid du Colombier 
3807dd7cddfSDavid du Colombier 	if(strcmp(fmt, "syntax error") == 0) {
381bd389b36SDavid du Colombier 		yyerror("syntax error, near symbol '%s'", symbol);
382bd389b36SDavid du Colombier 		return;
383bd389b36SDavid du Colombier 	}
3847dd7cddfSDavid du Colombier 	va_start(arg, fmt);
3859a747e4fSDavid du Colombier 	vseprint(buf, buf+sizeof(buf), fmt, arg);
3867dd7cddfSDavid du Colombier 	va_end(arg);
387219b2ee8SDavid du Colombier 	print("%L: %s\n", buf);
388bd389b36SDavid du Colombier }
389bd389b36SDavid du Colombier 
390bd389b36SDavid du Colombier void
marktree(Node * n)391bd389b36SDavid du Colombier marktree(Node *n)
392bd389b36SDavid du Colombier {
393bd389b36SDavid du Colombier 
394bd389b36SDavid du Colombier 	if(n == 0)
395bd389b36SDavid du Colombier 		return;
396bd389b36SDavid du Colombier 
397bd389b36SDavid du Colombier 	marktree(n->left);
398bd389b36SDavid du Colombier 	marktree(n->right);
399bd389b36SDavid du Colombier 
400bd389b36SDavid du Colombier 	n->gcmark = 1;
401bd389b36SDavid du Colombier 	if(n->op != OCONST)
402bd389b36SDavid du Colombier 		return;
403219b2ee8SDavid du Colombier 
404bd389b36SDavid du Colombier 	switch(n->type) {
405bd389b36SDavid du Colombier 	case TSTRING:
406bd389b36SDavid du Colombier 		n->string->gcmark = 1;
407bd389b36SDavid du Colombier 		break;
408bd389b36SDavid du Colombier 	case TLIST:
409bd389b36SDavid du Colombier 		marklist(n->l);
410bd389b36SDavid du Colombier 		break;
411219b2ee8SDavid du Colombier 	case TCODE:
412219b2ee8SDavid du Colombier 		marktree(n->cc);
413219b2ee8SDavid du Colombier 		break;
414219b2ee8SDavid du Colombier 	}
415219b2ee8SDavid du Colombier }
416219b2ee8SDavid du Colombier 
417219b2ee8SDavid du Colombier void
marklist(List * l)418219b2ee8SDavid du Colombier marklist(List *l)
419219b2ee8SDavid du Colombier {
420219b2ee8SDavid du Colombier 	while(l) {
421219b2ee8SDavid du Colombier 		l->gcmark = 1;
422219b2ee8SDavid du Colombier 		switch(l->type) {
423219b2ee8SDavid du Colombier 		case TSTRING:
424219b2ee8SDavid du Colombier 			l->string->gcmark = 1;
425219b2ee8SDavid du Colombier 			break;
426219b2ee8SDavid du Colombier 		case TLIST:
427219b2ee8SDavid du Colombier 			marklist(l->l);
428219b2ee8SDavid du Colombier 			break;
429219b2ee8SDavid du Colombier 		case TCODE:
430219b2ee8SDavid du Colombier 			marktree(l->cc);
431219b2ee8SDavid du Colombier 			break;
432219b2ee8SDavid du Colombier 		}
433219b2ee8SDavid du Colombier 		l = l->next;
434bd389b36SDavid du Colombier 	}
435bd389b36SDavid du Colombier }
436bd389b36SDavid du Colombier 
437bd389b36SDavid du Colombier void
gc(void)438bd389b36SDavid du Colombier gc(void)
439bd389b36SDavid du Colombier {
440bd389b36SDavid du Colombier 	int i;
441bd389b36SDavid du Colombier 	Lsym *f;
442bd389b36SDavid du Colombier 	Value *v;
443bd389b36SDavid du Colombier 	Gc *m, **p, *next;
444bd389b36SDavid du Colombier 
445219b2ee8SDavid du Colombier 	if(dogc < Mempergc)
446bd389b36SDavid du Colombier 		return;
447219b2ee8SDavid du Colombier 	dogc = 0;
448bd389b36SDavid du Colombier 
449bd389b36SDavid du Colombier 	/* Mark */
450bd389b36SDavid du Colombier 	for(m = gcl; m; m = m->gclink)
451bd389b36SDavid du Colombier 		m->gcmark = 0;
452bd389b36SDavid du Colombier 
453bd389b36SDavid du Colombier 	/* Scan */
454bd389b36SDavid du Colombier 	for(i = 0; i < Hashsize; i++) {
455bd389b36SDavid du Colombier 		for(f = hash[i]; f; f = f->hash) {
456219b2ee8SDavid du Colombier 			marktree(f->proc);
457219b2ee8SDavid du Colombier 			if(f->lexval != Tid)
458219b2ee8SDavid du Colombier 				continue;
459219b2ee8SDavid du Colombier 			for(v = f->v; v; v = v->pop) {
460bd389b36SDavid du Colombier 				switch(v->type) {
461bd389b36SDavid du Colombier 				case TSTRING:
462bd389b36SDavid du Colombier 					v->string->gcmark = 1;
463bd389b36SDavid du Colombier 					break;
464bd389b36SDavid du Colombier 				case TLIST:
465bd389b36SDavid du Colombier 					marklist(v->l);
466bd389b36SDavid du Colombier 					break;
467219b2ee8SDavid du Colombier 				case TCODE:
468219b2ee8SDavid du Colombier 					marktree(v->cc);
469219b2ee8SDavid du Colombier 					break;
470bd389b36SDavid du Colombier 				}
471bd389b36SDavid du Colombier 			}
472bd389b36SDavid du Colombier 		}
473bd389b36SDavid du Colombier 	}
474bd389b36SDavid du Colombier 
475bd389b36SDavid du Colombier 	/* Free */
476bd389b36SDavid du Colombier 	p = &gcl;
477bd389b36SDavid du Colombier 	for(m = gcl; m; m = next) {
478bd389b36SDavid du Colombier 		next = m->gclink;
479219b2ee8SDavid du Colombier 		if(m->gcmark == 0) {
480219b2ee8SDavid du Colombier 			*p = next;
481bd389b36SDavid du Colombier 			free(m);	/* Sleazy reliance on my malloc */
482bd389b36SDavid du Colombier 		}
483bd389b36SDavid du Colombier 		else
484bd389b36SDavid du Colombier 			p = &m->gclink;
485bd389b36SDavid du Colombier 	}
486bd389b36SDavid du Colombier }
487bd389b36SDavid du Colombier 
488bd389b36SDavid du Colombier void*
gmalloc(long l)489bd389b36SDavid du Colombier gmalloc(long l)
490bd389b36SDavid du Colombier {
491bd389b36SDavid du Colombier 	void *p;
492bd389b36SDavid du Colombier 
493bd389b36SDavid du Colombier 	dogc += l;
494bd389b36SDavid du Colombier 	p = malloc(l);
495bd389b36SDavid du Colombier 	if(p == 0)
496bd389b36SDavid du Colombier 		fatal("out of memory");
497bd389b36SDavid du Colombier 	return p;
498bd389b36SDavid du Colombier }
499bd389b36SDavid du Colombier 
500bd389b36SDavid du Colombier void
checkqid(int f1,int pid)501bd389b36SDavid du Colombier checkqid(int f1, int pid)
502bd389b36SDavid du Colombier {
503bd389b36SDavid du Colombier 	int fd;
5049a747e4fSDavid du Colombier 	Dir *d1, *d2;
505bd389b36SDavid du Colombier 	char buf[128];
506bd389b36SDavid du Colombier 
5077dd7cddfSDavid du Colombier 	if(kernel)
5087dd7cddfSDavid du Colombier 		return;
5097dd7cddfSDavid du Colombier 
5109a747e4fSDavid du Colombier 	d1 = dirfstat(f1);
5110b459c2cSDavid du Colombier 	if(d1 == nil){
5120b459c2cSDavid du Colombier 		print("checkqid: (qid not checked) dirfstat: %r\n");
5130b459c2cSDavid du Colombier 		return;
5140b459c2cSDavid du Colombier 	}
515bd389b36SDavid du Colombier 
5164de34a7eSDavid du Colombier 	snprint(buf, sizeof(buf), "/proc/%d/text", pid);
517bd389b36SDavid du Colombier 	fd = open(buf, OREAD);
5180b459c2cSDavid du Colombier 	if(fd < 0 || (d2 = dirfstat(fd)) == nil){
5190b459c2cSDavid du Colombier 		print("checkqid: (qid not checked) dirstat %s: %r\n", buf);
5200b459c2cSDavid du Colombier 		free(d1);
5210b459c2cSDavid du Colombier 		if(fd >= 0)
5220b459c2cSDavid du Colombier 			close(fd);
5230b459c2cSDavid du Colombier 		return;
5240b459c2cSDavid du Colombier 	}
525bd389b36SDavid du Colombier 
526bd389b36SDavid du Colombier 	close(fd);
527219b2ee8SDavid du Colombier 
5289a747e4fSDavid du Colombier 	if(d1->qid.path != d2->qid.path || d1->qid.vers != d2->qid.vers || d1->qid.type != d2->qid.type){
5299a747e4fSDavid du Colombier 		print("path %llux %llux vers %lud %lud type %d %d\n",
5309a747e4fSDavid du Colombier 			d1->qid.path, d2->qid.path, d1->qid.vers, d2->qid.vers, d1->qid.type, d2->qid.type);
5319a747e4fSDavid du Colombier 		print("warning: image does not match text for pid %d\n", pid);
5329a747e4fSDavid du Colombier 	}
5339a747e4fSDavid du Colombier 	free(d1);
5349a747e4fSDavid du Colombier 	free(d2);
535bd389b36SDavid du Colombier }
536bd389b36SDavid du Colombier 
537bd389b36SDavid du Colombier void
catcher(void * junk,char * s)538bd389b36SDavid du Colombier catcher(void *junk, char *s)
539bd389b36SDavid du Colombier {
540bd389b36SDavid du Colombier 	USED(junk);
541bd389b36SDavid du Colombier 
542bd389b36SDavid du Colombier 	if(strstr(s, "interrupt")) {
543bd389b36SDavid du Colombier 		gotint = 1;
544bd389b36SDavid du Colombier 		noted(NCONT);
545bd389b36SDavid du Colombier 	}
546bd389b36SDavid du Colombier 	noted(NDFLT);
547bd389b36SDavid du Colombier }
548bd389b36SDavid du Colombier 
5497dd7cddfSDavid du Colombier char*
system(void)5507dd7cddfSDavid du Colombier system(void)
5517dd7cddfSDavid du Colombier {
5527dd7cddfSDavid du Colombier 	char *cpu, *p, *q;
5534de34a7eSDavid du Colombier 	static char *kernel;
5547dd7cddfSDavid du Colombier 
5557dd7cddfSDavid du Colombier 	cpu = getenv("cputype");
5567dd7cddfSDavid du Colombier 	if(cpu == 0) {
5577dd7cddfSDavid du Colombier 		cpu = "mips";
5587dd7cddfSDavid du Colombier 		print("$cputype not set; assuming %s\n", cpu);
5597dd7cddfSDavid du Colombier 	}
5607dd7cddfSDavid du Colombier 	p = getenv("terminal");
5617dd7cddfSDavid du Colombier 	if(p == 0 || (p=strchr(p, ' ')) == 0 || p[1] == ' ' || p[1] == 0) {
5624de34a7eSDavid du Colombier 		p = "ch";
5637dd7cddfSDavid du Colombier 		print("missing or bad $terminal; assuming %s\n", p);
5647dd7cddfSDavid du Colombier 	}
5657dd7cddfSDavid du Colombier 	else{
5667dd7cddfSDavid du Colombier 		p++;
5677dd7cddfSDavid du Colombier 		q = strchr(p, ' ');
5687dd7cddfSDavid du Colombier 		if(q)
5697dd7cddfSDavid du Colombier 			*q = 0;
5707dd7cddfSDavid du Colombier 	}
5714de34a7eSDavid du Colombier 
5724de34a7eSDavid du Colombier 	if(kernel != nil)
5734de34a7eSDavid du Colombier 		free(kernel);
5744de34a7eSDavid du Colombier 	kernel = smprint("/%s/9%s", cpu, p);
5754de34a7eSDavid du Colombier 
5767dd7cddfSDavid du Colombier 	return kernel;
5777dd7cddfSDavid du Colombier }
5787dd7cddfSDavid du Colombier 
579bd389b36SDavid du Colombier int
isnumeric(char * s)580bd389b36SDavid du Colombier isnumeric(char *s)
581bd389b36SDavid du Colombier {
582bd389b36SDavid du Colombier 	while(*s) {
583bd389b36SDavid du Colombier 		if(*s < '0' || *s > '9')
584bd389b36SDavid du Colombier 			return 0;
585bd389b36SDavid du Colombier 		s++;
586bd389b36SDavid du Colombier 	}
587bd389b36SDavid du Colombier 	return 1;
588bd389b36SDavid du Colombier }
589219b2ee8SDavid du Colombier 
590219b2ee8SDavid du Colombier int
xfmt(Fmt * f)5919a747e4fSDavid du Colombier xfmt(Fmt *f)
592219b2ee8SDavid du Colombier {
5939a747e4fSDavid du Colombier 	f->flags ^= FmtSharp;
5949a747e4fSDavid du Colombier 	return _ifmt(f);
595219b2ee8SDavid du Colombier }
596