1*74a4d8c2SCharles.Forsyth #include <u.h>
2*74a4d8c2SCharles.Forsyth #include <libc.h>
3*74a4d8c2SCharles.Forsyth #include <bio.h>
4*74a4d8c2SCharles.Forsyth #include <mach.h>
5*74a4d8c2SCharles.Forsyth
6*74a4d8c2SCharles.Forsyth void record(uchar*, int);
7*74a4d8c2SCharles.Forsyth void usage(void);
8*74a4d8c2SCharles.Forsyth void dosegment(long, int);
9*74a4d8c2SCharles.Forsyth void trailer(ulong);
10*74a4d8c2SCharles.Forsyth
11*74a4d8c2SCharles.Forsyth enum
12*74a4d8c2SCharles.Forsyth {
13*74a4d8c2SCharles.Forsyth Recordsize = 32,
14*74a4d8c2SCharles.Forsyth };
15*74a4d8c2SCharles.Forsyth
16*74a4d8c2SCharles.Forsyth int dsegonly;
17*74a4d8c2SCharles.Forsyth int supressend;
18*74a4d8c2SCharles.Forsyth int binary;
19*74a4d8c2SCharles.Forsyth int addr4;
20*74a4d8c2SCharles.Forsyth ulong addr;
21*74a4d8c2SCharles.Forsyth ulong psize = 4096;
22*74a4d8c2SCharles.Forsyth ulong startaddr = 0x030000;
23*74a4d8c2SCharles.Forsyth Biobuf stdout;
24*74a4d8c2SCharles.Forsyth Biobuf bio;
25*74a4d8c2SCharles.Forsyth
26*74a4d8c2SCharles.Forsyth void
main(int argc,char ** argv)27*74a4d8c2SCharles.Forsyth main(int argc, char **argv)
28*74a4d8c2SCharles.Forsyth {
29*74a4d8c2SCharles.Forsyth Dir dir;
30*74a4d8c2SCharles.Forsyth Fhdr f;
31*74a4d8c2SCharles.Forsyth int fd;
32*74a4d8c2SCharles.Forsyth
33*74a4d8c2SCharles.Forsyth ARGBEGIN{
34*74a4d8c2SCharles.Forsyth case 'd':
35*74a4d8c2SCharles.Forsyth dsegonly++;
36*74a4d8c2SCharles.Forsyth break;
37*74a4d8c2SCharles.Forsyth case 's':
38*74a4d8c2SCharles.Forsyth supressend++;
39*74a4d8c2SCharles.Forsyth break;
40*74a4d8c2SCharles.Forsyth case 'a':
41*74a4d8c2SCharles.Forsyth addr = strtoul(ARGF(), 0, 0);
42*74a4d8c2SCharles.Forsyth break;
43*74a4d8c2SCharles.Forsyth case 'p':
44*74a4d8c2SCharles.Forsyth psize = strtoul(ARGF(), 0, 0);
45*74a4d8c2SCharles.Forsyth break;
46*74a4d8c2SCharles.Forsyth case 'b':
47*74a4d8c2SCharles.Forsyth binary++;
48*74a4d8c2SCharles.Forsyth break;
49*74a4d8c2SCharles.Forsyth case 'S':
50*74a4d8c2SCharles.Forsyth startaddr = strtoul(ARGF(), 0, 0);
51*74a4d8c2SCharles.Forsyth break;
52*74a4d8c2SCharles.Forsyth case '4':
53*74a4d8c2SCharles.Forsyth addr4++;
54*74a4d8c2SCharles.Forsyth break;
55*74a4d8c2SCharles.Forsyth default:
56*74a4d8c2SCharles.Forsyth usage();
57*74a4d8c2SCharles.Forsyth }ARGEND
58*74a4d8c2SCharles.Forsyth
59*74a4d8c2SCharles.Forsyth if(argc != 1)
60*74a4d8c2SCharles.Forsyth usage();
61*74a4d8c2SCharles.Forsyth
62*74a4d8c2SCharles.Forsyth Binit(&stdout, 1, OWRITE);
63*74a4d8c2SCharles.Forsyth
64*74a4d8c2SCharles.Forsyth fd = open(argv[0], OREAD);
65*74a4d8c2SCharles.Forsyth if(fd < 0) {
66*74a4d8c2SCharles.Forsyth fprint(2, "ms2: open %s: %r\n", argv[0]);
67*74a4d8c2SCharles.Forsyth exits("open");
68*74a4d8c2SCharles.Forsyth }
69*74a4d8c2SCharles.Forsyth
70*74a4d8c2SCharles.Forsyth if(binary) {
71*74a4d8c2SCharles.Forsyth if(dirfstat(fd, &dir) < 0) {
72*74a4d8c2SCharles.Forsyth fprint(2, "ms2: stat failed %r");
73*74a4d8c2SCharles.Forsyth exits("dirfstat");
74*74a4d8c2SCharles.Forsyth }
75*74a4d8c2SCharles.Forsyth Binit(&bio, fd, OREAD);
76*74a4d8c2SCharles.Forsyth dosegment(0, dir.length);
77*74a4d8c2SCharles.Forsyth if(supressend == 0)
78*74a4d8c2SCharles.Forsyth trailer(startaddr);
79*74a4d8c2SCharles.Forsyth Bterm(&stdout);
80*74a4d8c2SCharles.Forsyth Bterm(&bio);
81*74a4d8c2SCharles.Forsyth exits(0);
82*74a4d8c2SCharles.Forsyth }
83*74a4d8c2SCharles.Forsyth
84*74a4d8c2SCharles.Forsyth if(crackhdr(fd, &f) == 0){
85*74a4d8c2SCharles.Forsyth fprint(2, "ms2: bad magic: %r\n");
86*74a4d8c2SCharles.Forsyth exits("magic");
87*74a4d8c2SCharles.Forsyth }
88*74a4d8c2SCharles.Forsyth seek(fd, 0, 0);
89*74a4d8c2SCharles.Forsyth
90*74a4d8c2SCharles.Forsyth Binit(&bio, fd, OREAD);
91*74a4d8c2SCharles.Forsyth
92*74a4d8c2SCharles.Forsyth if(dsegonly)
93*74a4d8c2SCharles.Forsyth dosegment(f.datoff, f.datsz);
94*74a4d8c2SCharles.Forsyth else {
95*74a4d8c2SCharles.Forsyth dosegment(f.txtoff, f.txtsz);
96*74a4d8c2SCharles.Forsyth addr = (addr+(psize-1))&~(psize-1);
97*74a4d8c2SCharles.Forsyth dosegment(f.datoff, f.datsz);
98*74a4d8c2SCharles.Forsyth }
99*74a4d8c2SCharles.Forsyth
100*74a4d8c2SCharles.Forsyth if(supressend == 0)
101*74a4d8c2SCharles.Forsyth trailer(startaddr);
102*74a4d8c2SCharles.Forsyth
103*74a4d8c2SCharles.Forsyth Bterm(&stdout);
104*74a4d8c2SCharles.Forsyth Bterm(&bio);
105*74a4d8c2SCharles.Forsyth exits(0);
106*74a4d8c2SCharles.Forsyth }
107*74a4d8c2SCharles.Forsyth
108*74a4d8c2SCharles.Forsyth void
dosegment(long foff,int len)109*74a4d8c2SCharles.Forsyth dosegment(long foff, int len)
110*74a4d8c2SCharles.Forsyth {
111*74a4d8c2SCharles.Forsyth int l, n;
112*74a4d8c2SCharles.Forsyth uchar buf[2*Recordsize];
113*74a4d8c2SCharles.Forsyth
114*74a4d8c2SCharles.Forsyth Bseek(&bio, foff, 0);
115*74a4d8c2SCharles.Forsyth for(;;) {
116*74a4d8c2SCharles.Forsyth l = len;
117*74a4d8c2SCharles.Forsyth if(l > Recordsize)
118*74a4d8c2SCharles.Forsyth l = Recordsize;
119*74a4d8c2SCharles.Forsyth n = Bread(&bio, buf, l);
120*74a4d8c2SCharles.Forsyth if(n == 0)
121*74a4d8c2SCharles.Forsyth break;
122*74a4d8c2SCharles.Forsyth if(n < 0) {
123*74a4d8c2SCharles.Forsyth fprint(2, "ms2: read error: %r\n");
124*74a4d8c2SCharles.Forsyth exits("read");
125*74a4d8c2SCharles.Forsyth }
126*74a4d8c2SCharles.Forsyth record(buf, l);
127*74a4d8c2SCharles.Forsyth len -= l;
128*74a4d8c2SCharles.Forsyth }
129*74a4d8c2SCharles.Forsyth }
130*74a4d8c2SCharles.Forsyth
131*74a4d8c2SCharles.Forsyth void
record(uchar * s,int l)132*74a4d8c2SCharles.Forsyth record(uchar *s, int l)
133*74a4d8c2SCharles.Forsyth {
134*74a4d8c2SCharles.Forsyth int i;
135*74a4d8c2SCharles.Forsyth ulong cksum;
136*74a4d8c2SCharles.Forsyth
137*74a4d8c2SCharles.Forsyth if(addr4 || addr & (0xFF<<24)){
138*74a4d8c2SCharles.Forsyth Bprint(&stdout, "S3%.2X%.8luX", l+5, addr);
139*74a4d8c2SCharles.Forsyth cksum = l+5;
140*74a4d8c2SCharles.Forsyth cksum += (addr>>24)&0xff;
141*74a4d8c2SCharles.Forsyth }else{
142*74a4d8c2SCharles.Forsyth Bprint(&stdout, "S2%.2X%.6X", l+4, addr);
143*74a4d8c2SCharles.Forsyth cksum = l+4;
144*74a4d8c2SCharles.Forsyth }
145*74a4d8c2SCharles.Forsyth cksum += addr&0xff;
146*74a4d8c2SCharles.Forsyth cksum += (addr>>8)&0xff;
147*74a4d8c2SCharles.Forsyth cksum += (addr>>16)&0xff;
148*74a4d8c2SCharles.Forsyth
149*74a4d8c2SCharles.Forsyth for(i = 0; i < l; i++) {
150*74a4d8c2SCharles.Forsyth cksum += *s;
151*74a4d8c2SCharles.Forsyth Bprint(&stdout, "%.2X", *s++);
152*74a4d8c2SCharles.Forsyth }
153*74a4d8c2SCharles.Forsyth Bprint(&stdout, "%.2X\n", (~cksum)&0xff);
154*74a4d8c2SCharles.Forsyth addr += l;
155*74a4d8c2SCharles.Forsyth }
156*74a4d8c2SCharles.Forsyth
157*74a4d8c2SCharles.Forsyth void
trailer(ulong a)158*74a4d8c2SCharles.Forsyth trailer(ulong a)
159*74a4d8c2SCharles.Forsyth {
160*74a4d8c2SCharles.Forsyth ulong cksum;
161*74a4d8c2SCharles.Forsyth
162*74a4d8c2SCharles.Forsyth cksum = 0;
163*74a4d8c2SCharles.Forsyth if(addr4 || a & (0xFF<<24)){
164*74a4d8c2SCharles.Forsyth Bprint(&stdout, "S7%.8luX", a);
165*74a4d8c2SCharles.Forsyth cksum += (a>>24)&0xff;
166*74a4d8c2SCharles.Forsyth }else
167*74a4d8c2SCharles.Forsyth Bprint(&stdout, "S9%.6X", a);
168*74a4d8c2SCharles.Forsyth cksum += a&0xff;
169*74a4d8c2SCharles.Forsyth cksum += (a>>8)&0xff;
170*74a4d8c2SCharles.Forsyth cksum += (a>>16)&0xff;
171*74a4d8c2SCharles.Forsyth Bprint(&stdout, "%.2X\n", (~cksum)&0xff);
172*74a4d8c2SCharles.Forsyth }
173*74a4d8c2SCharles.Forsyth
174*74a4d8c2SCharles.Forsyth void
usage(void)175*74a4d8c2SCharles.Forsyth usage(void)
176*74a4d8c2SCharles.Forsyth {
177*74a4d8c2SCharles.Forsyth fprint(2, "usage: ms2 [-ds] [-a address] [-p pagesize] ?.out\n");
178*74a4d8c2SCharles.Forsyth exits("usage");
179*74a4d8c2SCharles.Forsyth }
180