xref: /plan9/sys/src/cmd/aux/ms2.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
33e12c5d1SDavid du Colombier #include <a.out.h>
43e12c5d1SDavid du Colombier #include <bio.h>
53e12c5d1SDavid du Colombier 
63e12c5d1SDavid du Colombier void	record(uchar*, int);
73e12c5d1SDavid du Colombier void	usage(void);
83e12c5d1SDavid du Colombier void	segment(long, int);
93e12c5d1SDavid du Colombier 
103e12c5d1SDavid du Colombier enum
113e12c5d1SDavid du Colombier {
123e12c5d1SDavid du Colombier 	Recordsize = 32,
133e12c5d1SDavid du Colombier };
143e12c5d1SDavid du Colombier 
153e12c5d1SDavid du Colombier int	dsegonly;
163e12c5d1SDavid du Colombier int	supressend;
17*219b2ee8SDavid du Colombier int	binary;
183e12c5d1SDavid du Colombier ulong	addr;
193e12c5d1SDavid du Colombier ulong 	psize = 4096;
203e12c5d1SDavid du Colombier Biobuf 	stdout;
213e12c5d1SDavid du Colombier Exec	exech;
223e12c5d1SDavid du Colombier Biobuf *bio;
233e12c5d1SDavid du Colombier 
243e12c5d1SDavid du Colombier void
253e12c5d1SDavid du Colombier main(int argc, char **argv)
263e12c5d1SDavid du Colombier {
273e12c5d1SDavid du Colombier 	int n;
28*219b2ee8SDavid du Colombier 	Dir dir;
293e12c5d1SDavid du Colombier 
303e12c5d1SDavid du Colombier 	ARGBEGIN{
313e12c5d1SDavid du Colombier 	case 'd':
323e12c5d1SDavid du Colombier 		dsegonly++;
333e12c5d1SDavid du Colombier 		break;
343e12c5d1SDavid du Colombier 	case 's':
353e12c5d1SDavid du Colombier 		supressend++;
363e12c5d1SDavid du Colombier 		break;
373e12c5d1SDavid du Colombier 	case 'a':
383e12c5d1SDavid du Colombier 		addr = strtoul(ARGF(), 0, 0);
393e12c5d1SDavid du Colombier 		break;
403e12c5d1SDavid du Colombier 	case 'p':
413e12c5d1SDavid du Colombier 		psize = strtoul(ARGF(), 0, 0);
423e12c5d1SDavid du Colombier 		break;
43*219b2ee8SDavid du Colombier 	case 'b':
44*219b2ee8SDavid du Colombier 		binary++;
45*219b2ee8SDavid du Colombier 		break;
463e12c5d1SDavid du Colombier 	default:
473e12c5d1SDavid du Colombier 		usage();
483e12c5d1SDavid du Colombier 	}ARGEND
493e12c5d1SDavid du Colombier 
503e12c5d1SDavid du Colombier 	if(argc != 1)
513e12c5d1SDavid du Colombier 		usage();
523e12c5d1SDavid du Colombier 
533e12c5d1SDavid du Colombier 	Binit(&stdout, 1, OWRITE);
543e12c5d1SDavid du Colombier 
553e12c5d1SDavid du Colombier 	bio = Bopen(argv[0], OREAD);
563e12c5d1SDavid du Colombier 	if(bio == 0) {
573e12c5d1SDavid du Colombier 		fprint(2, "ms2: open %s: %r\n", argv[0]);
583e12c5d1SDavid du Colombier 		exits("open");
593e12c5d1SDavid du Colombier 	}
603e12c5d1SDavid du Colombier 
61*219b2ee8SDavid du Colombier 	if(binary) {
62*219b2ee8SDavid du Colombier 		if(dirfstat(Bfildes(bio), &dir) < 0) {
63*219b2ee8SDavid du Colombier 			fprint(2, "ms2: stat failed %r");
64*219b2ee8SDavid du Colombier 			exits("dirfstat");
65*219b2ee8SDavid du Colombier 		}
66*219b2ee8SDavid du Colombier 		segment(0, dir.length);
67*219b2ee8SDavid du Colombier 		Bprint(&stdout, "S9030000FC\n");
68*219b2ee8SDavid du Colombier 		Bterm(&stdout);
69*219b2ee8SDavid du Colombier 		Bterm(bio);
70*219b2ee8SDavid du Colombier 		exits(0);
71*219b2ee8SDavid du Colombier 	}
72*219b2ee8SDavid du Colombier 
733e12c5d1SDavid du Colombier 	n = Bread(bio, &exech, sizeof(Exec));
743e12c5d1SDavid du Colombier 	if(n != sizeof(Exec)) {
753e12c5d1SDavid du Colombier 		fprint(2, "ms2: read failed: %r\n");
763e12c5d1SDavid du Colombier 		exits("read");
773e12c5d1SDavid du Colombier 	}
783e12c5d1SDavid du Colombier 
793e12c5d1SDavid du Colombier 	switch(exech.magic) {
803e12c5d1SDavid du Colombier 	default:
813e12c5d1SDavid du Colombier 		fprint(2, "ms2: bad magic\n");
823e12c5d1SDavid du Colombier 		exits("magic");
833e12c5d1SDavid du Colombier 	case A_MAGIC:
843e12c5d1SDavid du Colombier 	case I_MAGIC:
853e12c5d1SDavid du Colombier 	case J_MAGIC:
863e12c5d1SDavid du Colombier 	case K_MAGIC:
873e12c5d1SDavid du Colombier 	case V_MAGIC:
883e12c5d1SDavid du Colombier 		break;
893e12c5d1SDavid du Colombier 	}
903e12c5d1SDavid du Colombier 
913e12c5d1SDavid du Colombier 	if(dsegonly)
923e12c5d1SDavid du Colombier 		segment(exech.text+sizeof(exech), exech.data);
933e12c5d1SDavid du Colombier 	else {
943e12c5d1SDavid du Colombier 		segment(sizeof(exech), exech.text);
953e12c5d1SDavid du Colombier 		addr = (addr+(psize-1))&~(psize-1);
963e12c5d1SDavid du Colombier 		segment(exech.text+sizeof(exech), exech.data);
973e12c5d1SDavid du Colombier 	}
983e12c5d1SDavid du Colombier 
993e12c5d1SDavid du Colombier 	if(supressend == 0)
1003e12c5d1SDavid du Colombier 		Bprint(&stdout, "S9030000FC\n");
1013e12c5d1SDavid du Colombier 
102*219b2ee8SDavid du Colombier 	Bterm(&stdout);
103*219b2ee8SDavid du Colombier 	Bterm(bio);
1043e12c5d1SDavid du Colombier 	exits(0);
1053e12c5d1SDavid du Colombier }
1063e12c5d1SDavid du Colombier 
1073e12c5d1SDavid du Colombier void
1083e12c5d1SDavid du Colombier segment(long foff, int len)
1093e12c5d1SDavid du Colombier {
1103e12c5d1SDavid du Colombier 	int l, n;
1113e12c5d1SDavid du Colombier 	uchar buf[2*Recordsize];
1123e12c5d1SDavid du Colombier 
1133e12c5d1SDavid du Colombier 	Bseek(bio, foff, 0);
1143e12c5d1SDavid du Colombier 	for(;;) {
1153e12c5d1SDavid du Colombier 		l = len;
1163e12c5d1SDavid du Colombier 		if(l > Recordsize)
1173e12c5d1SDavid du Colombier 			l = Recordsize;
1183e12c5d1SDavid du Colombier 		n = Bread(bio, buf, l);
1193e12c5d1SDavid du Colombier 		if(n == 0)
1203e12c5d1SDavid du Colombier 			break;
1213e12c5d1SDavid du Colombier 		if(n < 0) {
1223e12c5d1SDavid du Colombier 			fprint(2, "ms2: read error: %r\n");
1233e12c5d1SDavid du Colombier 			exits("read");
1243e12c5d1SDavid du Colombier 		}
1253e12c5d1SDavid du Colombier 		record(buf, l);
1263e12c5d1SDavid du Colombier 		len -= l;
1273e12c5d1SDavid du Colombier 	}
1283e12c5d1SDavid du Colombier }
1293e12c5d1SDavid du Colombier 
1303e12c5d1SDavid du Colombier void
1313e12c5d1SDavid du Colombier record(uchar *s, int l)
1323e12c5d1SDavid du Colombier {
1333e12c5d1SDavid du Colombier 	int i;
1343e12c5d1SDavid du Colombier 	ulong cksum;
1353e12c5d1SDavid du Colombier 
1363e12c5d1SDavid du Colombier 	cksum = l+4;
1373e12c5d1SDavid du Colombier 	Bprint(&stdout, "S2%.2X%.6X", l+4, addr);
1383e12c5d1SDavid du Colombier 	cksum += addr&0xff;
1393e12c5d1SDavid du Colombier 	cksum += (addr>>8)&0xff;
1403e12c5d1SDavid du Colombier 	cksum += (addr>>16)&0xff;
1413e12c5d1SDavid du Colombier 
1423e12c5d1SDavid du Colombier 	for(i = 0; i < l; i++) {
1433e12c5d1SDavid du Colombier 		cksum += *s;
1443e12c5d1SDavid du Colombier 		Bprint(&stdout, "%.2X", *s++);
1453e12c5d1SDavid du Colombier 	}
1463e12c5d1SDavid du Colombier 	Bprint(&stdout, "%.2X\n", (~cksum)&0xff);
1473e12c5d1SDavid du Colombier 	addr += l;
1483e12c5d1SDavid du Colombier }
1493e12c5d1SDavid du Colombier 
1503e12c5d1SDavid du Colombier void
1513e12c5d1SDavid du Colombier usage(void)
1523e12c5d1SDavid du Colombier {
1533e12c5d1SDavid du Colombier 	fprint(2, "usage: ms2 [-ds] [-a address] [-p pagesize] ?.out\n");
1543e12c5d1SDavid du Colombier 	exits("usage");
1553e12c5d1SDavid du Colombier }
156