]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/aux/ms2.c
change icanhasvmx to report extra info only with -v
[plan9front.git] / sys / src / cmd / aux / ms2.c
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <mach.h>
5
6 void    record(uchar*, long);
7 void    usage(void);
8 void    segment(vlong, vlong);
9
10 enum
11 {
12         Recordsize = 32,
13 };
14
15 int     dsegonly;
16 int     supressend;
17 int     binary;
18 int     halfswap;
19 int     srec = 2;
20 uvlong  addr;
21 ulong   psize = 4096;
22 Biobuf  stdout;
23 Fhdr    exech;
24 Biobuf *bio;
25
26 void
27 main(int argc, char **argv)
28 {
29         Dir *dir;
30         uvlong totsz;
31
32         ARGBEGIN{
33         case 'd':
34                 dsegonly++;
35                 break;
36         case 's':
37                 supressend++;
38                 break;
39         case 'a':
40                 addr = strtoull(ARGF(), 0, 0);
41                 break;
42         case 'p':
43                 psize = strtoul(ARGF(), 0, 0);
44                 break;
45         case 'b':
46                 binary++;
47                 break;
48         case 'h':
49                 halfswap++;
50                 break;
51         case '1':
52                 srec = 1;
53                 break;
54         case '2':
55                 srec = 2;
56                 break;
57         case '3':
58                 srec = 3;
59                 break;
60         default:
61                 usage();
62         }ARGEND
63
64         if(argc != 1)
65                 usage();
66
67         Binit(&stdout, 1, OWRITE);
68
69         bio = Bopen(argv[0], OREAD);
70         if(bio == 0) {
71                 fprint(2, "ms2: open %s: %r\n", argv[0]);
72                 exits("open");
73         }
74
75         if(binary) {
76                 if((dir = dirfstat(Bfildes(bio))) == nil) {
77                         fprint(2, "ms2: stat failed %r");
78                         exits("dirfstat");
79                 }
80                 segment(0, dir->length);
81                 Bprint(&stdout, "S9030000FC\n");
82                 Bterm(&stdout);
83                 Bterm(bio);
84                 free(dir);
85                 exits(0);
86         }
87
88         if(!crackhdr(Bfildes(bio), &exech)) {
89                 fprint(2, "ms2: can't decode file header\n");
90                 return;
91         }
92
93         totsz = exech.txtsz + exech.datsz + exech.bsssz;
94         fprint(2, "%s: %lud+%lud+%lud=%llud\n",
95                 exech.name, exech.txtsz, exech.datsz, exech.bsssz, totsz);
96
97         if(dsegonly)
98                 segment(exech.datoff, exech.datsz);
99         else {
100                 segment(exech.txtoff, exech.txtsz);
101                 addr = (addr+(psize-1))&~(psize-1);
102                 segment(exech.datoff, exech.datsz);
103         }
104
105         if(supressend == 0) {
106                 switch(srec) {
107                 case 1:
108                 case 2:
109                         Bprint(&stdout, "S9030000FC\n");
110                         break;
111                 case 3:
112                         Bprint(&stdout, "S705000000FA\n");
113                         break;
114                 }
115         }
116
117         Bterm(&stdout);
118         Bterm(bio);
119         exits(0);
120 }
121
122 void
123 segment(vlong foff, vlong len)
124 {
125         int i;
126         long l, n;
127         uchar t, buf[2*Recordsize];
128
129         Bseek(bio, foff, 0);
130         for(;;) {
131                 l = len;
132                 if(l > Recordsize)
133                         l = Recordsize;
134                 n = Bread(bio, buf, l);
135                 if(n == 0)
136                         break;
137                 if(n < 0) {
138                         fprint(2, "ms2: read error: %r\n");
139                         exits("read");
140                 }
141                 if(halfswap) {
142                         if(n & 1) {
143                                 fprint(2, "ms2: data must be even length\n");
144                                 exits("even");
145                         }
146                         for(i = 0; i < n; i += 2) {
147                                 t = buf[i];
148                                 buf[i] = buf[i+1];
149                                 buf[i+1] = t;
150                         }
151                 }
152                 record(buf, l);
153                 len -= l;
154         }
155 }
156
157 void
158 record(uchar *s, long l)
159 {
160         int i;
161         ulong cksum = 0;
162
163         switch(srec) {
164         case 1:
165                 cksum = l+3;
166                 Bprint(&stdout, "S1%.2lX%.4lluX", l+3, addr);
167                 cksum += addr&0xff;
168                 cksum += (addr>>8)&0xff;
169                 break;
170         case 2:
171                 cksum = l+4;
172                 Bprint(&stdout, "S2%.2lX%.6lluX", l+4, addr);
173                 cksum += addr&0xff;
174                 cksum += (addr>>8)&0xff;
175                 cksum += (addr>>16)&0xff;
176                 break;
177         case 3:
178                 cksum = l+5;
179                 Bprint(&stdout, "S3%.2lX%.8lluX", l+5, addr);
180                 cksum += addr&0xff;
181                 cksum += (addr>>8)&0xff;
182                 cksum += (addr>>16)&0xff;
183                 cksum += (addr>>24)&0xff;
184                 break;
185         }
186
187         for(i = 0; i < l; i++) {
188                 cksum += *s;
189                 Bprint(&stdout, "%.2X", *s++);
190         }
191         Bprint(&stdout, "%.2luX\n", (~cksum)&0xff);
192         addr += l;
193 }
194
195 void
196 usage(void)
197 {
198         fprint(2, "usage: ms2 [-dsbh] [-a address] [-p pagesize] ?.out\n");
199         exits("usage");
200 }