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