xref: /inferno-os/appl/cmd/mdb.b (revision 3f1f06c5d12b24c4061e5123acabf72348ff45a2)
137da2899SCharles.Forsythimplement Mdb;
237da2899SCharles.Forsyth
337da2899SCharles.Forsythinclude "sys.m";
437da2899SCharles.Forsyth	sys: Sys;
537da2899SCharles.Forsyth	stderr: ref Sys->FD;
637da2899SCharles.Forsyth	print, sprint: import sys;
737da2899SCharles.Forsyth
837da2899SCharles.Forsythinclude "draw.m";
937da2899SCharles.Forsythinclude "string.m";
1037da2899SCharles.Forsyth	str: String;
1137da2899SCharles.Forsythinclude "bufio.m";
1237da2899SCharles.Forsyth	bufio: Bufio;
1337da2899SCharles.Forsyth	Iobuf: import bufio;
14*3f1f06c5SCharles.Forsythinclude "dis.m";
15*3f1f06c5SCharles.Forsyth	dis: Dis;
16*3f1f06c5SCharles.Forsyth	Inst, Type, Data, Link, Mod: import dis;
17*3f1f06c5SCharles.Forsyth	XMAGIC: import Dis;
18*3f1f06c5SCharles.Forsyth	MUSTCOMPILE, DONTCOMPILE: import Dis;
19*3f1f06c5SCharles.Forsyth	AMP, AFP, AIMM, AXXX, AIND, AMASK: import Dis;
20*3f1f06c5SCharles.Forsyth	ARM, AXNON, AXIMM, AXINF, AXINM: import Dis;
21*3f1f06c5SCharles.Forsyth	DEFB, DEFW, DEFS, DEFF, DEFA, DIND, DAPOP, DEFL: import Dis;
22*3f1f06c5SCharles.Forsythdisfile: string;
23*3f1f06c5SCharles.Forsythm: ref Mod;
2437da2899SCharles.Forsyth
2537da2899SCharles.ForsythMdb: module
2637da2899SCharles.Forsyth{
2737da2899SCharles.Forsyth	init: fn(nil: ref Draw->Context, argv: list of string);
2837da2899SCharles.Forsyth};
2937da2899SCharles.Forsyth
3037da2899SCharles.Forsythmfd: ref Sys->FD;
3137da2899SCharles.Forsythdot := 0;
3237da2899SCharles.Forsythlastaddr := 0;
3337da2899SCharles.Forsythcount := 1;
3437da2899SCharles.Forsyth
3537da2899SCharles.Forsythatoi(s: string): int
3637da2899SCharles.Forsyth{
3737da2899SCharles.Forsyth        b := 10;
3837da2899SCharles.Forsyth        if(s == nil)
3937da2899SCharles.Forsyth                return 0;
4037da2899SCharles.Forsyth        if(s[0] == '0') {
4137da2899SCharles.Forsyth                b = 8;
4237da2899SCharles.Forsyth                s = s[1:];
4337da2899SCharles.Forsyth                if(s == nil)
4437da2899SCharles.Forsyth                        return 0;
4537da2899SCharles.Forsyth                if(s[0] == 'x' || s[0] == 'X') {
4637da2899SCharles.Forsyth                        b = 16;
4737da2899SCharles.Forsyth                        s = s[1:];
4837da2899SCharles.Forsyth                }
4937da2899SCharles.Forsyth        }
5037da2899SCharles.Forsyth        n: int;
5137da2899SCharles.Forsyth        (n, nil) = str->toint(s, b);
5237da2899SCharles.Forsyth        return n;
5337da2899SCharles.Forsyth}
5437da2899SCharles.Forsyth
5537da2899SCharles.Forsytheatws(s: string): string
5637da2899SCharles.Forsyth{
5737da2899SCharles.Forsyth	for (i := 0; i < len s; i++)
5837da2899SCharles.Forsyth		if (s[i] != ' ' && s[i] != '\t')
5937da2899SCharles.Forsyth			return s[i:];
6037da2899SCharles.Forsyth	return nil;
6137da2899SCharles.Forsyth}
6237da2899SCharles.Forsyth
6337da2899SCharles.Forsytheatnum(s: string): string
6437da2899SCharles.Forsyth{
6537da2899SCharles.Forsyth	if(len s == 0)
6637da2899SCharles.Forsyth		return s;
6737da2899SCharles.Forsyth	while(gotnum(s) || gotalpha(s))
6837da2899SCharles.Forsyth		s = s[1:];
6937da2899SCharles.Forsyth	return s;
7037da2899SCharles.Forsyth}
7137da2899SCharles.Forsyth
7237da2899SCharles.Forsythgotnum(s: string): int
7337da2899SCharles.Forsyth{
7437da2899SCharles.Forsyth	if(len s == 0)
7537da2899SCharles.Forsyth		return 0;
7637da2899SCharles.Forsyth	if(s[0] >= '0' && s[0] <= '9')
7737da2899SCharles.Forsyth		return 1;
7837da2899SCharles.Forsyth	else
7937da2899SCharles.Forsyth		return 0;
8037da2899SCharles.Forsyth}
8137da2899SCharles.Forsyth
8237da2899SCharles.Forsythgotalpha(s: string): int
8337da2899SCharles.Forsyth{
8437da2899SCharles.Forsyth	if(len s == 0)
8537da2899SCharles.Forsyth		return 0;
8637da2899SCharles.Forsyth	if((s[0] >= 'a' && s[0] <= 'z') || (s[0] >= 'A' && s[0] <= 'Z'))
8737da2899SCharles.Forsyth		return 1;
8837da2899SCharles.Forsyth	else
8937da2899SCharles.Forsyth		return 0;
9037da2899SCharles.Forsyth}
9137da2899SCharles.Forsyth
9237da2899SCharles.Forsythgetexpr(s: string): (string, int, int)
9337da2899SCharles.Forsyth{
9437da2899SCharles.Forsyth	ov: int;
9537da2899SCharles.Forsyth	v := 0;
9637da2899SCharles.Forsyth	op := '+';
9737da2899SCharles.Forsyth	for(;;) {
9837da2899SCharles.Forsyth		ov = v;
9937da2899SCharles.Forsyth		s = eatws(s);
10037da2899SCharles.Forsyth		if(s == nil)
10137da2899SCharles.Forsyth			return (nil, 0, 0);
10237da2899SCharles.Forsyth		if(s[0] == '.' || s[0] == '+' || s[0] == '^') {
10337da2899SCharles.Forsyth			v = dot;
10437da2899SCharles.Forsyth			s = s[1:];
10537da2899SCharles.Forsyth		} else if(s[0] == '"') {
10637da2899SCharles.Forsyth			v = lastaddr;
10737da2899SCharles.Forsyth			s = s[1:];
10837da2899SCharles.Forsyth		} else if(s[0] == '(') {
10937da2899SCharles.Forsyth			(s, v, nil) = getexpr(s[1:]);
11037da2899SCharles.Forsyth			s = s[1:];
11137da2899SCharles.Forsyth		} else if(gotnum(s)) {
11237da2899SCharles.Forsyth			v = atoi(s);
11337da2899SCharles.Forsyth			s = eatnum(s);
11437da2899SCharles.Forsyth		} else
11537da2899SCharles.Forsyth			return (s, 0, 0);
11637da2899SCharles.Forsyth		case op {
11737da2899SCharles.Forsyth		'+' => v = ov+v;
11837da2899SCharles.Forsyth		'-' => v = ov-v;
11937da2899SCharles.Forsyth		'*' => v = ov*v;
12037da2899SCharles.Forsyth		'%' => v = ov/v;
12137da2899SCharles.Forsyth		'&' => v = ov&v;
12237da2899SCharles.Forsyth		'|' => v = ov|v;
12337da2899SCharles.Forsyth		}
12437da2899SCharles.Forsyth		if(s == nil)
12537da2899SCharles.Forsyth			return (nil, v, 1);
12637da2899SCharles.Forsyth		case s[0] {
12737da2899SCharles.Forsyth		'+' or '-' or '*' or '%' or '&' or '|' =>
12837da2899SCharles.Forsyth			op = s[0]; s = s[1:];
12937da2899SCharles.Forsyth		* =>
13037da2899SCharles.Forsyth			return (eatws(s), v, 1);
13137da2899SCharles.Forsyth		}
13237da2899SCharles.Forsyth	}
13337da2899SCharles.Forsyth}
13437da2899SCharles.Forsyth
13537da2899SCharles.Forsythlastcmd := "";
13637da2899SCharles.Forsyth
13737da2899SCharles.Forsythdocmd(s: string)
13837da2899SCharles.Forsyth{
13937da2899SCharles.Forsyth	ok: int;
14037da2899SCharles.Forsyth	n: int;
14137da2899SCharles.Forsyth	s = eatws(s);
14237da2899SCharles.Forsyth	(s, n, ok) = getexpr(s);
14337da2899SCharles.Forsyth	if(ok) {
14437da2899SCharles.Forsyth		dot = n;
14537da2899SCharles.Forsyth		lastaddr = n;
14637da2899SCharles.Forsyth	}
14737da2899SCharles.Forsyth	count = 1;
14837da2899SCharles.Forsyth	if(s != nil && s[0] == ',') {
14937da2899SCharles.Forsyth		(s, n, ok) = getexpr(s[1:]);
15037da2899SCharles.Forsyth		if(ok)
15137da2899SCharles.Forsyth			count = n;
15237da2899SCharles.Forsyth	}
15337da2899SCharles.Forsyth	if(s == nil && (s = lastcmd) == nil)
15437da2899SCharles.Forsyth		return;
15537da2899SCharles.Forsyth	lastcmd = s;
15637da2899SCharles.Forsyth	cmd := s[0];
15737da2899SCharles.Forsyth	case cmd {
15837da2899SCharles.Forsyth	'?' or '/' =>
15937da2899SCharles.Forsyth		case s[1] {
16037da2899SCharles.Forsyth		'w' =>
16137da2899SCharles.Forsyth			writemem(2, s[2:]);
16237da2899SCharles.Forsyth		'W' =>
16337da2899SCharles.Forsyth			writemem(4, s[2:]);
164*3f1f06c5SCharles.Forsyth		'i' =>
165*3f1f06c5SCharles.Forsyth			das();
16637da2899SCharles.Forsyth		* =>
16737da2899SCharles.Forsyth			dumpmem(s[1:], cmd);
16837da2899SCharles.Forsyth		}
169*3f1f06c5SCharles.Forsyth	'$' =>
170*3f1f06c5SCharles.Forsyth		case s[1] {
171*3f1f06c5SCharles.Forsyth		'D' =>
172*3f1f06c5SCharles.Forsyth			desc();
173*3f1f06c5SCharles.Forsyth		'h' =>
174*3f1f06c5SCharles.Forsyth			hdr();
175*3f1f06c5SCharles.Forsyth		'l' =>
176*3f1f06c5SCharles.Forsyth			link();
177*3f1f06c5SCharles.Forsyth		'i' =>
178*3f1f06c5SCharles.Forsyth			imports();
179*3f1f06c5SCharles.Forsyth		'd' =>
180*3f1f06c5SCharles.Forsyth			dat();
181*3f1f06c5SCharles.Forsyth		'H' =>
182*3f1f06c5SCharles.Forsyth			handlers();
183*3f1f06c5SCharles.Forsyth		's' =>
184*3f1f06c5SCharles.Forsyth			if(m != nil)
185*3f1f06c5SCharles.Forsyth				print("%s\n", m.srcpath);
186*3f1f06c5SCharles.Forsyth		}
18737da2899SCharles.Forsyth	'=' =>
18837da2899SCharles.Forsyth		dumpmem(s[1:], cmd);
18937da2899SCharles.Forsyth	* =>
19037da2899SCharles.Forsyth		sys->fprint(stderr, "invalid cmd: %c\n", cmd);
19137da2899SCharles.Forsyth	}
19237da2899SCharles.Forsyth}
19337da2899SCharles.Forsyth
19437da2899SCharles.Forsythoctal(n: int, d: int): string
19537da2899SCharles.Forsyth{
19637da2899SCharles.Forsyth	s: string;
19737da2899SCharles.Forsyth	do {
19837da2899SCharles.Forsyth		s = string (n%8) + s;
19937da2899SCharles.Forsyth		n /= 8;
20037da2899SCharles.Forsyth	} while(d-- > 1);
20137da2899SCharles.Forsyth	return "0" + s;
20237da2899SCharles.Forsyth}
20337da2899SCharles.Forsyth
20437da2899SCharles.Forsythprintable(c: int): string
20537da2899SCharles.Forsyth{
20637da2899SCharles.Forsyth	case c {
20737da2899SCharles.Forsyth	32 to 126 =>
20837da2899SCharles.Forsyth		return sprint("%c", c);
20937da2899SCharles.Forsyth	'\n' =>
21037da2899SCharles.Forsyth		return "\\n";
21137da2899SCharles.Forsyth	'\r' =>
21237da2899SCharles.Forsyth		return "\\r";
21337da2899SCharles.Forsyth	'\b' =>
21437da2899SCharles.Forsyth		return "\\b";
21537da2899SCharles.Forsyth	'\a' =>
21637da2899SCharles.Forsyth		return "\\a";
21737da2899SCharles.Forsyth	'\v' =>
21837da2899SCharles.Forsyth		return "\\v";
21937da2899SCharles.Forsyth	* =>
22037da2899SCharles.Forsyth		return sprint("\\x%2.2x", c);
22137da2899SCharles.Forsyth	}
22237da2899SCharles.Forsyth
22337da2899SCharles.Forsyth}
22437da2899SCharles.Forsyth
22537da2899SCharles.Forsythdumpmem(s: string, t: int)
22637da2899SCharles.Forsyth{
22737da2899SCharles.Forsyth	n := 0;
22837da2899SCharles.Forsyth	c := count;
22937da2899SCharles.Forsyth	while(c-- > 0) for(p:=0; p<len s; p++) {
23037da2899SCharles.Forsyth		fmt := s[p];
23137da2899SCharles.Forsyth		case fmt {
23237da2899SCharles.Forsyth		'b' or 'c' or 'C' =>
23337da2899SCharles.Forsyth			n = 1;
23437da2899SCharles.Forsyth		'x' or 'd' or 'u' or 'o' =>
23537da2899SCharles.Forsyth			n = 2;
23637da2899SCharles.Forsyth		'X' or 'D' or 'U' or 'O' =>
23737da2899SCharles.Forsyth			n = 4;
23837da2899SCharles.Forsyth		's' or 'S' or 'r' or 'R' =>
23937da2899SCharles.Forsyth			print("'%c' format not yet supported\n", fmt);
24037da2899SCharles.Forsyth			continue;
24137da2899SCharles.Forsyth		'n' =>
24237da2899SCharles.Forsyth			print("\n");
24337da2899SCharles.Forsyth			continue;
24437da2899SCharles.Forsyth		'+' =>
24537da2899SCharles.Forsyth			dot++;
24637da2899SCharles.Forsyth			continue;
24737da2899SCharles.Forsyth		'-' =>
24837da2899SCharles.Forsyth			dot--;
24937da2899SCharles.Forsyth			continue;
25037da2899SCharles.Forsyth		'^' =>
25137da2899SCharles.Forsyth			dot -= n;
25237da2899SCharles.Forsyth			continue;
25337da2899SCharles.Forsyth		* =>
25437da2899SCharles.Forsyth			print("unknown format '%c'\n", fmt);
25537da2899SCharles.Forsyth			continue;
25637da2899SCharles.Forsyth		}
25737da2899SCharles.Forsyth		b := array[n] of byte;
25837da2899SCharles.Forsyth		v: int;
25937da2899SCharles.Forsyth		if(t == '=')
26037da2899SCharles.Forsyth			v = dot;
26137da2899SCharles.Forsyth		else {
26237da2899SCharles.Forsyth			sys->seek(mfd, big dot, Sys->SEEKSTART);
26337da2899SCharles.Forsyth			sys->read(mfd, b, len b);
26437da2899SCharles.Forsyth			v = 0;
26537da2899SCharles.Forsyth			for(i := 0; i < n; i++)
26637da2899SCharles.Forsyth				v |= int b[i] << (8*i);
26737da2899SCharles.Forsyth		}
26837da2899SCharles.Forsyth		case fmt {
26937da2899SCharles.Forsyth		'c' => print("%c", v);
27037da2899SCharles.Forsyth		'C' => print("%s", printable(v));
27137da2899SCharles.Forsyth		'b' => print("%#2.2ux ", v);
27237da2899SCharles.Forsyth		'x' => print("%#4.4ux ", v);
27337da2899SCharles.Forsyth		'X' => print("%#8.8ux ", v);
27437da2899SCharles.Forsyth		'd' => print("%-4d ", v);
27537da2899SCharles.Forsyth		'D' => print("%-8d ", v);
27637da2899SCharles.Forsyth		'u' => print("%-4ud ", v);
27737da2899SCharles.Forsyth		'U' => print("%-8ud ", v);
27837da2899SCharles.Forsyth		'o' => print("%s ", octal(v, 6));
27937da2899SCharles.Forsyth		'O' => print("%s ", octal(v, 11));
28037da2899SCharles.Forsyth		}
28137da2899SCharles.Forsyth		if(t != '=')
28237da2899SCharles.Forsyth			dot += n;
28337da2899SCharles.Forsyth	}
28437da2899SCharles.Forsyth	print("\n");
28537da2899SCharles.Forsyth}
28637da2899SCharles.Forsyth
28737da2899SCharles.Forsythwritemem(n: int, s: string)
28837da2899SCharles.Forsyth{
28937da2899SCharles.Forsyth	v: int;
29037da2899SCharles.Forsyth	ok: int;
29137da2899SCharles.Forsyth	s = eatws(s);
29237da2899SCharles.Forsyth	sys->seek(mfd, big dot, Sys->SEEKSTART);
29337da2899SCharles.Forsyth	for(;;) {
29437da2899SCharles.Forsyth		(s, v, ok) = getexpr(s);
29537da2899SCharles.Forsyth		if(!ok)
29637da2899SCharles.Forsyth			return;
29737da2899SCharles.Forsyth		b := array[n] of byte;
29837da2899SCharles.Forsyth		for(i := 0; i < n; i++)
29937da2899SCharles.Forsyth			b[i] = byte (v >> (8*i));
30037da2899SCharles.Forsyth		if (sys->write(mfd, b, len b) != len b)
30137da2899SCharles.Forsyth			sys->fprint(stderr, "mdb: write error: %r\n");
30237da2899SCharles.Forsyth	}
30337da2899SCharles.Forsyth}
30437da2899SCharles.Forsyth
30537da2899SCharles.Forsythusage()
30637da2899SCharles.Forsyth{
30737da2899SCharles.Forsyth	sys->fprint(stderr, "usage: mdb [-w] file [command]\n");
30837da2899SCharles.Forsyth	raise "fail:usage";
30937da2899SCharles.Forsyth}
31037da2899SCharles.Forsyth
31137da2899SCharles.Forsythwriteable := 0;
31237da2899SCharles.Forsyth
31337da2899SCharles.Forsythinit(nil: ref Draw->Context, argv: list of string)
31437da2899SCharles.Forsyth{
31537da2899SCharles.Forsyth	sys = load Sys Sys->PATH;
31637da2899SCharles.Forsyth	stderr = sys->fildes(2);
31737da2899SCharles.Forsyth	str = load String String->PATH;
31837da2899SCharles.Forsyth	if (str == nil) {
31937da2899SCharles.Forsyth		sys->fprint(stderr, "mdb: cannot load %s: %r\n", String->PATH);
32037da2899SCharles.Forsyth		raise "fail:bad module";
32137da2899SCharles.Forsyth	}
32237da2899SCharles.Forsyth	bufio = load Bufio Bufio->PATH;
32337da2899SCharles.Forsyth	if (bufio == nil) {
32437da2899SCharles.Forsyth		sys->fprint(stderr, "mdb: cannot load %s: %r\n", Bufio->PATH);
32537da2899SCharles.Forsyth		raise "fail:bad module";
32637da2899SCharles.Forsyth	}
327*3f1f06c5SCharles.Forsyth	dis = load Dis Dis->PATH;
328*3f1f06c5SCharles.Forsyth	dis->init();
32937da2899SCharles.Forsyth
33037da2899SCharles.Forsyth	if (len argv < 2)
33137da2899SCharles.Forsyth		usage();
33237da2899SCharles.Forsyth	if (argv != nil)
33337da2899SCharles.Forsyth		argv = tl argv;
33437da2899SCharles.Forsyth	if (argv != nil && len hd argv && (hd argv)[0] == '-') {
33537da2899SCharles.Forsyth		if (hd argv != "-w")
33637da2899SCharles.Forsyth			usage();
33737da2899SCharles.Forsyth		writeable = 1;
33837da2899SCharles.Forsyth		argv = tl argv;
33937da2899SCharles.Forsyth	}
34037da2899SCharles.Forsyth	if (argv == nil)
34137da2899SCharles.Forsyth		usage();
34237da2899SCharles.Forsyth	fname := hd argv;
34337da2899SCharles.Forsyth	argv = tl argv;
34437da2899SCharles.Forsyth	cmd := "";
34537da2899SCharles.Forsyth	if(argv != nil)
34637da2899SCharles.Forsyth		cmd = hd argv;
34737da2899SCharles.Forsyth
34837da2899SCharles.Forsyth	oflags := Sys->OREAD;
34937da2899SCharles.Forsyth	if (writeable)
35037da2899SCharles.Forsyth		oflags = Sys->ORDWR;
35137da2899SCharles.Forsyth	mfd = sys->open(fname, oflags);
35237da2899SCharles.Forsyth	if(mfd == nil) {
35337da2899SCharles.Forsyth		sys->fprint(stderr, "mdb: cannot open %s: %r\n", fname);
35437da2899SCharles.Forsyth		raise "fail:cannot open";
35537da2899SCharles.Forsyth	}
356*3f1f06c5SCharles.Forsyth	(m, nil) = dis->loadobj(fname);
35737da2899SCharles.Forsyth
35837da2899SCharles.Forsyth	if(cmd != nil)
35937da2899SCharles.Forsyth		docmd(cmd);
36037da2899SCharles.Forsyth	else {
36137da2899SCharles.Forsyth		stdin := bufio->fopen(sys->fildes(0), Sys->OREAD);
36237da2899SCharles.Forsyth		while ((s := stdin.gets('\n')) != nil) {
36337da2899SCharles.Forsyth			if (s[len s -1] == '\n')
36437da2899SCharles.Forsyth				s = s[0:len s - 1];
36537da2899SCharles.Forsyth			docmd(s);
36637da2899SCharles.Forsyth		}
36737da2899SCharles.Forsyth	}
36837da2899SCharles.Forsyth}
369*3f1f06c5SCharles.Forsyth
370*3f1f06c5SCharles.Forsythlink()
371*3f1f06c5SCharles.Forsyth{
372*3f1f06c5SCharles.Forsyth	if(m == nil || m.magic == 0)
373*3f1f06c5SCharles.Forsyth		return;
374*3f1f06c5SCharles.Forsyth
375*3f1f06c5SCharles.Forsyth	for(i := 0; i < m.lsize; i++) {
376*3f1f06c5SCharles.Forsyth		l := m.links[i];
377*3f1f06c5SCharles.Forsyth		print("	link %d,%d, 0x%ux, \"%s\"\n",
378*3f1f06c5SCharles.Forsyth					l.desc, l.pc, l.sig, l.name);
379*3f1f06c5SCharles.Forsyth	}
380*3f1f06c5SCharles.Forsyth}
381*3f1f06c5SCharles.Forsyth
382*3f1f06c5SCharles.Forsythimports()
383*3f1f06c5SCharles.Forsyth{
384*3f1f06c5SCharles.Forsyth	if(m == nil || m.magic == 0)
385*3f1f06c5SCharles.Forsyth		return;
386*3f1f06c5SCharles.Forsyth
387*3f1f06c5SCharles.Forsyth	mi := m.imports;
388*3f1f06c5SCharles.Forsyth	for(i := 0; i < len mi; i++) {
389*3f1f06c5SCharles.Forsyth		a := mi[i];
390*3f1f06c5SCharles.Forsyth		for(j := 0; j < len a; j++) {
391*3f1f06c5SCharles.Forsyth			ai := a[j];
392*3f1f06c5SCharles.Forsyth			print("	import 0x%ux, \"%s\"\n", ai.sig, ai.name);
393*3f1f06c5SCharles.Forsyth		}
394*3f1f06c5SCharles.Forsyth	}
395*3f1f06c5SCharles.Forsyth}
396*3f1f06c5SCharles.Forsyth
397*3f1f06c5SCharles.Forsythhandlers()
398*3f1f06c5SCharles.Forsyth{
399*3f1f06c5SCharles.Forsyth	if(m == nil || m.magic == 0)
400*3f1f06c5SCharles.Forsyth		return;
401*3f1f06c5SCharles.Forsyth
402*3f1f06c5SCharles.Forsyth	hs := m.handlers;
403*3f1f06c5SCharles.Forsyth	for(i := 0; i < len hs; i++) {
404*3f1f06c5SCharles.Forsyth		h := hs[i];
405*3f1f06c5SCharles.Forsyth		tt := -1;
406*3f1f06c5SCharles.Forsyth		for(j := 0; j < len m.types; j++) {
407*3f1f06c5SCharles.Forsyth			if(h.t == m.types[j]) {
408*3f1f06c5SCharles.Forsyth				tt = j;
409*3f1f06c5SCharles.Forsyth				break;
410*3f1f06c5SCharles.Forsyth			}
411*3f1f06c5SCharles.Forsyth		}
412*3f1f06c5SCharles.Forsyth		print("	%d-%d, o=%d, e=%d t=%d\n", h.pc1, h.pc2, h.eoff, h.ne, tt);
413*3f1f06c5SCharles.Forsyth		et := h.etab;
414*3f1f06c5SCharles.Forsyth		for(j = 0; j < len et; j++) {
415*3f1f06c5SCharles.Forsyth			e := et[j];
416*3f1f06c5SCharles.Forsyth			if(e.s == nil)
417*3f1f06c5SCharles.Forsyth				print("		%d	*\n", e.pc);
418*3f1f06c5SCharles.Forsyth			else
419*3f1f06c5SCharles.Forsyth				print("		%d	\"%s\"\n", e.pc, e.s);
420*3f1f06c5SCharles.Forsyth		}
421*3f1f06c5SCharles.Forsyth	}
422*3f1f06c5SCharles.Forsyth}
423*3f1f06c5SCharles.Forsyth
424*3f1f06c5SCharles.Forsythdesc()
425*3f1f06c5SCharles.Forsyth{
426*3f1f06c5SCharles.Forsyth	if(m == nil || m.magic == 0)
427*3f1f06c5SCharles.Forsyth		return;
428*3f1f06c5SCharles.Forsyth
429*3f1f06c5SCharles.Forsyth	for(i := 0; i < m.tsize; i++) {
430*3f1f06c5SCharles.Forsyth		h := m.types[i];
431*3f1f06c5SCharles.Forsyth		s := sprint("	desc $%d, %d, \"", i, h.size);
432*3f1f06c5SCharles.Forsyth		for(j := 0; j < h.np; j++)
433*3f1f06c5SCharles.Forsyth			s += sprint("%.2ux", int h.map[j]);
434*3f1f06c5SCharles.Forsyth		s += "\"\n";
435*3f1f06c5SCharles.Forsyth		print("%s", s);
436*3f1f06c5SCharles.Forsyth	}
437*3f1f06c5SCharles.Forsyth}
438*3f1f06c5SCharles.Forsyth
439*3f1f06c5SCharles.Forsythhdr()
440*3f1f06c5SCharles.Forsyth{
441*3f1f06c5SCharles.Forsyth	if(m == nil || m.magic == 0)
442*3f1f06c5SCharles.Forsyth		return;
443*3f1f06c5SCharles.Forsyth	s := sprint("%.8ux Version %d Dis VM\n", m.magic, m.magic - XMAGIC + 1);
444*3f1f06c5SCharles.Forsyth	s += sprint("%.8ux Runtime flags %s\n", m.rt, rtflag(m.rt));
445*3f1f06c5SCharles.Forsyth	s += sprint("%8d bytes per stack extent\n\n", m.ssize);
446*3f1f06c5SCharles.Forsyth
447*3f1f06c5SCharles.Forsyth
448*3f1f06c5SCharles.Forsyth	s += sprint("%8d instructions\n", m.isize);
449*3f1f06c5SCharles.Forsyth	s += sprint("%8d data size\n", m.dsize);
450*3f1f06c5SCharles.Forsyth	s += sprint("%8d heap type descriptors\n", m.tsize);
451*3f1f06c5SCharles.Forsyth	s += sprint("%8d link directives\n", m.lsize);
452*3f1f06c5SCharles.Forsyth	s += sprint("%8d entry pc\n", m.entry);
453*3f1f06c5SCharles.Forsyth	s += sprint("%8d entry type descriptor\n\n", m.entryt);
454*3f1f06c5SCharles.Forsyth
455*3f1f06c5SCharles.Forsyth	if(m.sign == nil)
456*3f1f06c5SCharles.Forsyth		s += "Module is Insecure\n";
457*3f1f06c5SCharles.Forsyth	print("%s", s);
458*3f1f06c5SCharles.Forsyth}
459*3f1f06c5SCharles.Forsyth
460*3f1f06c5SCharles.Forsythrtflag(flag: int): string
461*3f1f06c5SCharles.Forsyth{
462*3f1f06c5SCharles.Forsyth	if(flag == 0)
463*3f1f06c5SCharles.Forsyth		return "";
464*3f1f06c5SCharles.Forsyth
465*3f1f06c5SCharles.Forsyth	s := "[";
466*3f1f06c5SCharles.Forsyth
467*3f1f06c5SCharles.Forsyth	if(flag & MUSTCOMPILE)
468*3f1f06c5SCharles.Forsyth		s += "MustCompile";
469*3f1f06c5SCharles.Forsyth	if(flag & DONTCOMPILE) {
470*3f1f06c5SCharles.Forsyth		if(flag & MUSTCOMPILE)
471*3f1f06c5SCharles.Forsyth			s += "|";
472*3f1f06c5SCharles.Forsyth		s += "DontCompile";
473*3f1f06c5SCharles.Forsyth	}
474*3f1f06c5SCharles.Forsyth	s[len s] = ']';
475*3f1f06c5SCharles.Forsyth
476*3f1f06c5SCharles.Forsyth	return s;
477*3f1f06c5SCharles.Forsyth}
478*3f1f06c5SCharles.Forsyth
479*3f1f06c5SCharles.Forsythdas()
480*3f1f06c5SCharles.Forsyth{
481*3f1f06c5SCharles.Forsyth	if(m == nil || m.magic == 0)
482*3f1f06c5SCharles.Forsyth		return;
483*3f1f06c5SCharles.Forsyth
484*3f1f06c5SCharles.Forsyth	for(i := dot;  count-- > 0 && i < m.isize; i++) {
485*3f1f06c5SCharles.Forsyth		if(i % 10 == 0)
486*3f1f06c5SCharles.Forsyth			print("#%d\n", i);
487*3f1f06c5SCharles.Forsyth		print("\t%s\n", dis->inst2s(m.inst[i]));
488*3f1f06c5SCharles.Forsyth	}
489*3f1f06c5SCharles.Forsyth}
490*3f1f06c5SCharles.Forsyth
491*3f1f06c5SCharles.Forsythdat()
492*3f1f06c5SCharles.Forsyth{
493*3f1f06c5SCharles.Forsyth	if(m == nil || m.magic == 0)
494*3f1f06c5SCharles.Forsyth		return;
495*3f1f06c5SCharles.Forsyth	print("	var @mp, %d\n", m.types[0].size);
496*3f1f06c5SCharles.Forsyth
497*3f1f06c5SCharles.Forsyth	s := "";
498*3f1f06c5SCharles.Forsyth	for(d := m.data; d != nil; d = tl d) {
499*3f1f06c5SCharles.Forsyth		pick dat := hd d {
500*3f1f06c5SCharles.Forsyth		Bytes =>
501*3f1f06c5SCharles.Forsyth			s = sprint("\tbyte @mp+%d", dat.off);
502*3f1f06c5SCharles.Forsyth			for(n := 0; n < dat.n; n++)
503*3f1f06c5SCharles.Forsyth				s += sprint(",%d", int dat.bytes[n]);
504*3f1f06c5SCharles.Forsyth		Words =>
505*3f1f06c5SCharles.Forsyth			s = sprint("\tword @mp+%d", dat.off);
506*3f1f06c5SCharles.Forsyth			for(n := 0; n < dat.n; n++)
507*3f1f06c5SCharles.Forsyth				s += sprint(",%d", dat.words[n]);
508*3f1f06c5SCharles.Forsyth		String =>
509*3f1f06c5SCharles.Forsyth			s = sprint("\tstring @mp+%d, \"%s\"", dat.off, mapstr(dat.str));
510*3f1f06c5SCharles.Forsyth		Reals =>
511*3f1f06c5SCharles.Forsyth			s = sprint("\treal @mp+%d", dat.off);
512*3f1f06c5SCharles.Forsyth			for(n := 0; n < dat.n; n++)
513*3f1f06c5SCharles.Forsyth				s += sprint(", %g", dat.reals[n]);
514*3f1f06c5SCharles.Forsyth			break;
515*3f1f06c5SCharles.Forsyth		Array =>
516*3f1f06c5SCharles.Forsyth			s = sprint("\tarray @mp+%d,$%d,%d", dat.off, dat.typex, dat.length);
517*3f1f06c5SCharles.Forsyth		Aindex =>
518*3f1f06c5SCharles.Forsyth			s = sprint("\tindir @mp+%d,%d", dat.off, dat.index);
519*3f1f06c5SCharles.Forsyth		Arestore =>
520*3f1f06c5SCharles.Forsyth			s = "\tapop";
521*3f1f06c5SCharles.Forsyth			break;
522*3f1f06c5SCharles.Forsyth		Bigs =>
523*3f1f06c5SCharles.Forsyth			s = sprint("\tlong @mp+%d", dat.off);
524*3f1f06c5SCharles.Forsyth			for(n := 0; n < dat.n; n++)
525*3f1f06c5SCharles.Forsyth				s += sprint(", %bd", dat.bigs[n]);
526*3f1f06c5SCharles.Forsyth		}
527*3f1f06c5SCharles.Forsyth		print("%s\n", s);
528*3f1f06c5SCharles.Forsyth	}
529*3f1f06c5SCharles.Forsyth}
530*3f1f06c5SCharles.Forsyth
531*3f1f06c5SCharles.Forsythmapstr(s: string): string
532*3f1f06c5SCharles.Forsyth{
533*3f1f06c5SCharles.Forsyth	for(i := 0; i < len s; i++)
534*3f1f06c5SCharles.Forsyth		if(s[i] == '\n')
535*3f1f06c5SCharles.Forsyth			s = s[0:i] + "\\n" + s[i+1:];
536*3f1f06c5SCharles.Forsyth	return s;
537*3f1f06c5SCharles.Forsyth}
538