1 #include "auxi.h" 2 3 #define RND(x, y) ((((x)+(y)-1)/(y))*(y)) 4 5 char *cmd; 6 int sflag, dflag; 7 8 int ifd, ofd; 9 Fhdr ihdr; 10 11 long HEADR, INITTEXT, INITDAT, INITRND, INITENTRY; 12 long textsize, datsize, bsssize; 13 14 int cout; 15 int thumb; 16 17 static void get_file(char *); 18 static void put_file(char *); 19 static void usage(char *); 20 static long strxtol(char *); 21 static void readsyms(void); 22 23 char *fail = "error"; 24 25 void 26 main(int argc, char *argv[]) 27 { 28 char *a, *ifile, *ofile; 29 30 cmd = argv[0]; 31 32 INITTEXT = -1; 33 INITDAT = -1; 34 INITRND = -1; 35 INITENTRY = -1; 36 37 ARGBEGIN { 38 /* 39 * Options without args 40 */ 41 case 's': 42 sflag = 1; 43 break; 44 /* 45 * Options with args 46 */ 47 case 'T': 48 a = ARGF(); 49 if(a) 50 INITTEXT = strxtol(a); 51 break; 52 case 'D': 53 a = ARGF(); 54 if(a) 55 INITDAT = strxtol(a); 56 break; 57 case 'R': 58 a = ARGF(); 59 if(a) 60 INITRND = strxtol(a); 61 break; 62 case 'E': 63 a = ARGF(); 64 if(a) 65 INITENTRY = strxtol(a); 66 break; 67 case 'd': 68 dflag |= strxtol(ARGF()); 69 break; 70 default: 71 usage("Invalid option"); 72 } ARGEND 73 74 if (argc != 2) 75 usage("Wrong number of arguments"); 76 77 ifile = argv[0]; 78 ofile = argv[1]; 79 80 get_file(ifile); 81 put_file(ofile); 82 exits(0); 83 } 84 85 char usagemsg[] = 86 "usage: %s options infile outfile\n\t options (for outfile): -H[1234] -s -T<text> -D<data> -R<rnd> -E<entry>\n"; 87 88 static void 89 usage(char *msg) 90 { 91 fprint(2, "***Error: %s\n", msg); 92 fprint(2, usagemsg, cmd); 93 exits("usage"); 94 } 95 96 static long 97 strxtol(char *s) 98 { 99 char *es; 100 int base = 0; 101 long r; 102 103 if (*s == '0') 104 if (*++s == 'x'){ 105 base = 16; 106 s++; 107 } 108 else 109 base = 8; 110 r = strtol(s, &es, base); 111 if (*es) 112 usage("bad number"); 113 return(r); 114 } 115 116 static void 117 get_file(char *ifile) 118 { 119 int h; 120 121 ifd = open(ifile, OREAD); 122 if (ifd < 0) { 123 fprint(2, "5coff: open %s: %r\n", ifile); 124 exits("open"); 125 } 126 h = crackhdr(ifd, &ihdr); 127 if (!h || dflag){ 128 fprint(2, "Crackhdr: %d, type: %d, name: %s\n", h, ihdr.type, ihdr.name); 129 fprint(2, "txt %llux, ent %llux, txtsz %lux, dataddr %llux\n", 130 ihdr.txtaddr, ihdr.entry, ihdr.txtsz, ihdr.dataddr); 131 } 132 if (!h) 133 usage("File type not recognized"); 134 machbytype(ihdr.type); 135 if (dflag) 136 fprint(2, "name: <%s> pgsize:%ux\n", mach->name, mach->pgsize); 137 138 HEADR = 22+28+3*48; 139 if(INITTEXT == -1) 140 INITTEXT = ihdr.txtaddr; 141 else 142 ihdr.txtaddr = INITTEXT; 143 if(INITDAT == -1) 144 INITDAT = ihdr.dataddr; 145 else 146 ihdr.dataddr = INITDAT; 147 if(INITENTRY == -1) 148 INITENTRY = ihdr.entry; 149 else 150 ihdr.entry = INITENTRY; 151 textsize = ihdr.txtsz; 152 datsize = ihdr.datsz; 153 bsssize = ihdr.bsssz; 154 if(INITRND > 0) 155 ihdr.dataddr = INITDAT = RND(INITTEXT+textsize, INITRND); 156 if(0){ 157 INITTEXT = INITENTRY; 158 INITDAT = RND(INITTEXT+textsize, 4); 159 } 160 if(0){ 161 print("H=%lux T=%lux D=%lux t=%lux d=%lux b=%lux e=%lux\n", HEADR, INITTEXT, INITDAT, textsize, datsize, bsssize, INITENTRY); 162 print("%llux %llux %llux %lux %lux %lux\n", ihdr.txtaddr, ihdr.dataddr, ihdr.entry, ihdr.txtsz, ihdr.datsz, ihdr.bsssz); 163 } 164 165 readsyms(); 166 } 167 168 #define WB 128 169 #define WSAFE (WB-4) 170 char Wbuf[WB]; 171 char *wp = Wbuf; 172 173 void 174 cflush(void) 175 { 176 if(wp > Wbuf) 177 write(ofd, Wbuf, wp-Wbuf); 178 wp = Wbuf; 179 } 180 181 void 182 lput(long l) 183 { 184 wp[0] = l>>24; 185 wp[1] = l>>16; 186 wp[2] = l>>8; 187 wp[3] = l; 188 wp += 4; 189 if(wp >= Wbuf+WSAFE) 190 cflush(); 191 } 192 193 void 194 cput(int l) 195 { 196 wp[0] = l; 197 wp += 1; 198 if(wp >= Wbuf+WSAFE) 199 cflush(); 200 } 201 202 void 203 hputl(int l) 204 { 205 wp[1] = l>>8; 206 wp[0] = l; 207 wp += 2; 208 if(wp >= Wbuf+WSAFE) 209 cflush(); 210 } 211 212 void 213 lputl(long l) 214 { 215 wp[3] = l>>24; 216 wp[2] = l>>16; 217 wp[1] = l>>8; 218 wp[0] = l; 219 wp += 4; 220 if(wp >= Wbuf+WSAFE) 221 cflush(); 222 } 223 224 static void 225 copyseg(long sz) 226 { 227 char buf[1024]; 228 229 cflush(); 230 while (sz > 0){ 231 long n; 232 long r; 233 234 n = sz; 235 if (n > sizeof buf) 236 n = sizeof buf; 237 sz -= n; 238 239 if ((r = read(ifd, buf, n)) != n){ 240 fprint(2, "%ld = read(...%ld) at %ld\n", r, n, (long)seek(ifd, 0, 1)); 241 perror("Premature eof"); 242 exits(fail); 243 } 244 if ((r = write(ofd, buf, n)) != n){ 245 fprint(2, "%ld = write(...%ld)\n", r, n); 246 perror("Write error!"); 247 exits(fail); 248 } 249 } 250 cflush(); 251 } 252 253 static void 254 put_file(char *ofile) 255 { 256 ofd = create(ofile, OWRITE, 0666); 257 if (ofd < 0) { 258 fprint(2, "5coff: create %s: %r\n", ofile); 259 exits("create"); 260 } 261 cout = ofd; 262 263 /* TBS lput for Plan9 header before ? */ 264 265 seek(ifd, ihdr.txtoff, 0); 266 seek(ofd, HEADR, 0); 267 copyseg(ihdr.txtsz); 268 269 seek(ifd, ihdr.datoff, 0); 270 seek(ofd, HEADR+textsize, 0); 271 copyseg(ihdr.datsz); 272 273 seek(ofd, HEADR+textsize+datsize, 0); 274 coffsym(); 275 cflush(); 276 cofflc(); 277 cflush(); 278 279 seek(ofd, 0, 0); 280 coffhdr(); 281 cflush(); 282 283 close(ifd); 284 close(ofd); 285 } 286 287 long 288 entryvalue(void) 289 { 290 return INITENTRY; 291 } 292 293 void 294 diag(char *s, ...) 295 { 296 fprint(2, "%s\n", s); 297 exits("error"); 298 } 299 300 static void 301 readsyms(void) 302 { 303 int i; 304 long n; 305 Sym *s; 306 307 if(sflag) 308 return; 309 n = syminit(ifd, &ihdr); 310 beginsym(); 311 for(i = 0; i < n; i++){ 312 s = getsym(i); 313 newsym(i, s->name, s->value, s->type); 314 } 315 endsym(); 316 } 317