1 #include "l.h" 2 3 #define Dbufslop 100 4 5 long 6 entryvalue(void) 7 { 8 char *a; 9 Sym *s; 10 11 a = INITENTRY; 12 if(*a >= '0' && *a <= '9') 13 return atolwhex(a); 14 s = lookup(a, 0); 15 if(s->type == 0) 16 return INITTEXT; 17 if(s->type != STEXT) 18 diag("entry not text: %s", s->name); 19 return s->value; 20 } 21 22 void 23 wput(ushort w) 24 { 25 CPUT(w); 26 CPUT(w>>8); 27 } 28 29 void 30 asmb(void) 31 { 32 Prog *p; 33 long v; 34 int a; 35 uchar *op1; 36 37 if(debug['v']) 38 Bprint(&bso, "%5.2f asmb\n", cputime()); 39 Bflush(&bso); 40 41 seek(cout, HEADR, 0); 42 pc = INITTEXT; 43 curp = firstp; 44 for(p = firstp; p != P; p = p->link) { 45 if(p->as == ATEXT) 46 curtext = p; 47 if(p->pc != pc) { 48 if(!debug['a']) 49 print("%P\n", curp); 50 diag("phase error %lux sb %lux in %s\n", p->pc, pc, TNAME); 51 pc = p->pc; 52 } 53 curp = p; 54 asmins(p); 55 if(cbc < sizeof(and)) 56 cflush(); 57 a = (andptr - and); 58 if(debug['a']) { 59 Bprint(&bso, pcstr, pc); 60 for(op1 = and; op1 < andptr; op1++) 61 Bprint(&bso, "%.2ux", *op1 & 0xff); 62 Bprint(&bso, "%.*s", (24+7-printcol)/8, "\t\t\t"); 63 Bprint(&bso, "%P\n", curp); 64 } 65 memmove(cbp, and, a); 66 cbp += a; 67 pc += a; 68 cbc -= a; 69 } 70 cflush(); 71 switch(HEADTYPE) { 72 default: 73 diag("unknown header type %d\n", HEADTYPE); 74 case 0: 75 seek(cout, rnd(HEADR+textsize, 8192), 0); 76 break; 77 case 1: 78 textsize = rnd(HEADR+textsize, 4096)-HEADR; 79 seek(cout, textsize+HEADR, 0); 80 break; 81 case 2: 82 seek(cout, HEADR+textsize, 0); 83 break; 84 case 3: 85 case 4: 86 seek(cout, HEADR+rnd(textsize, INITRND), 0); 87 break; 88 } 89 90 if(debug['v']) 91 Bprint(&bso, "%5.2f datblk\n", cputime()); 92 Bflush(&bso); 93 for(v = 0; v < datsize; v += sizeof(buf)-Dbufslop) { 94 if(datsize-v > sizeof(buf)-Dbufslop) 95 datblk(v, sizeof(buf)-Dbufslop); 96 else 97 datblk(v, datsize-v); 98 } 99 100 symsize = 0; 101 spsize = 0; 102 lcsize = 0; 103 if(!debug['s']) { 104 if(debug['v']) 105 Bprint(&bso, "%5.2f sym\n", cputime()); 106 Bflush(&bso); 107 switch(HEADTYPE) { 108 default: 109 case 0: 110 seek(cout, rnd(HEADR+textsize, 8192)+datsize, 0); 111 break; 112 case 1: 113 seek(cout, rnd(HEADR+textsize, INITRND)+datsize, 0); 114 break; 115 case 2: 116 seek(cout, HEADR+textsize+datsize, 0); 117 break; 118 case 3: 119 case 4: 120 debug['s'] = 1; 121 break; 122 } 123 if(!debug['s']) 124 asmsym(); 125 if(debug['v']) 126 Bprint(&bso, "%5.2f sp\n", cputime()); 127 Bflush(&bso); 128 if(debug['v']) 129 Bprint(&bso, "%5.2f pc\n", cputime()); 130 Bflush(&bso); 131 if(!debug['s']) 132 asmlc(); 133 cflush(); 134 } 135 if(debug['v']) 136 Bprint(&bso, "%5.2f headr\n", cputime()); 137 Bflush(&bso); 138 seek(cout, 0L, 0); 139 switch(HEADTYPE) { 140 default: 141 case 0: /* garbage */ 142 lput(0x160L<<16); /* magic and sections */ 143 lput(0L); /* time and date */ 144 lput(rnd(HEADR+textsize, 4096)+datsize); 145 lput(symsize); /* nsyms */ 146 lput((0x38L<<16)|7L); /* size of optional hdr and flags */ 147 lput((0413<<16)|0437L); /* magic and version */ 148 lput(rnd(HEADR+textsize, 4096)); /* sizes */ 149 lput(datsize); 150 lput(bsssize); 151 lput(entryvalue()); /* va of entry */ 152 lput(INITTEXT-HEADR); /* va of base of text */ 153 lput(INITDAT); /* va of base of data */ 154 lput(INITDAT+datsize); /* va of base of bss */ 155 lput(~0L); /* gp reg mask */ 156 lput(0L); 157 lput(0L); 158 lput(0L); 159 lput(0L); 160 lput(~0L); /* gp value ?? */ 161 break; 162 lputl(0); /* x */ 163 case 1: /* unix coff */ 164 /* 165 * file header 166 */ 167 lputl(0x0004014c); /* 4 sections, magic */ 168 lputl(0); /* unix time stamp */ 169 lputl(0); /* symbol table */ 170 lputl(0); /* nsyms */ 171 lputl(0x0003001c); /* flags, sizeof a.out header */ 172 /* 173 * a.out header 174 */ 175 lputl(0x10b); /* magic, version stamp */ 176 lputl(rnd(textsize, INITRND)); /* text sizes */ 177 lputl(datsize); /* data sizes */ 178 lputl(bsssize); /* bss sizes */ 179 lput(entryvalue()); /* va of entry */ 180 lputl(INITTEXT); /* text start */ 181 lputl(INITDAT); /* data start */ 182 /* 183 * text section header 184 */ 185 s8put(".text"); 186 lputl(HEADR); /* pa */ 187 lputl(HEADR); /* va */ 188 lputl(textsize); /* text size */ 189 lputl(HEADR); /* file offset */ 190 lputl(0); /* relocation */ 191 lputl(0); /* line numbers */ 192 lputl(0); /* relocation, line numbers */ 193 lputl(0x20); /* flags text only */ 194 /* 195 * data section header 196 */ 197 s8put(".data"); 198 lputl(INITDAT); /* pa */ 199 lputl(INITDAT); /* va */ 200 lputl(datsize); /* data size */ 201 lputl(HEADR+textsize); /* file offset */ 202 lputl(0); /* relocation */ 203 lputl(0); /* line numbers */ 204 lputl(0); /* relocation, line numbers */ 205 lputl(0x40); /* flags data only */ 206 /* 207 * bss section header 208 */ 209 s8put(".bss"); 210 lputl(INITDAT+datsize); /* pa */ 211 lputl(INITDAT+datsize); /* va */ 212 lputl(bsssize); /* bss size */ 213 lputl(0); /* file offset */ 214 lputl(0); /* relocation */ 215 lputl(0); /* line numbers */ 216 lputl(0); /* relocation, line numbers */ 217 lputl(0x80); /* flags bss only */ 218 /* 219 * comment section header 220 */ 221 s8put(".comment"); 222 lputl(0); /* pa */ 223 lputl(0); /* va */ 224 lputl(symsize+lcsize); /* comment size */ 225 lputl(HEADR+textsize+datsize); /* file offset */ 226 lputl(HEADR+textsize+datsize); /* offset of syms */ 227 lputl(HEADR+textsize+datsize+symsize);/* offset of line numbers */ 228 lputl(0); /* relocation, line numbers */ 229 lputl(0x200); /* flags comment only */ 230 break; 231 case 2: /* plan9 */ 232 lput(4*11*11+7); /* magic */ 233 lput(textsize); /* sizes */ 234 lput(datsize); 235 lput(bsssize); 236 lput(symsize); /* nsyms */ 237 lput(entryvalue()); /* va of entry */ 238 lput(spsize); /* sp offsets */ 239 lput(lcsize); /* line offsets */ 240 break; 241 case 3: 242 /* MS-DOS .COM */ 243 break; 244 case 4: 245 /* fake MS-DOS .EXE */ 246 v = rnd(HEADR+textsize, INITRND)+datsize; 247 wput(0x5A4D); /* 'MZ' */ 248 wput(v % 512); /* bytes in last page */ 249 wput(rnd(v, 512)/512); /* total number of pages */ 250 wput(0x0000); /* number of reloc items */ 251 v = rnd(HEADR-(INITTEXT & 0xFFFF), 16); 252 wput(v/16); /* size of header */ 253 wput(0x0000); /* minimum allocation */ 254 wput(0xFFFF); /* maximum allocation */ 255 wput(0x0000); /* initial ss value */ 256 wput(0x0100); /* initial sp value */ 257 wput(0x0000); /* complemented checksum */ 258 v = entryvalue(); 259 wput(v); /* initial ip value (!) */ 260 wput(0x0000); /* initial cs value */ 261 wput(0x0000); 262 wput(0x0000); 263 wput(0x003E); /* reloc table offset */ 264 wput(0x0000); /* overlay number */ 265 break; 266 } 267 cflush(); 268 } 269 270 void 271 lput(long l) 272 { 273 274 CPUT(l>>24) 275 CPUT(l>>16) 276 CPUT(l>>8) 277 CPUT(l) 278 } 279 280 void 281 lputl(long l) 282 { 283 284 CPUT(l) 285 CPUT(l>>8) 286 CPUT(l>>16) 287 CPUT(l>>24) 288 } 289 290 void 291 s8put(char *n) 292 { 293 char name[8]; 294 int i; 295 296 strncpy(name, n, sizeof(name)); 297 for(i=0; i<sizeof(name); i++) 298 CPUT(name[i]) 299 } 300 301 void 302 cflush(void) 303 { 304 int n; 305 306 n = sizeof(buf.cbuf) - cbc; 307 if(n) 308 write(cout, buf.cbuf, n); 309 cbp = buf.cbuf; 310 cbc = sizeof(buf.cbuf); 311 } 312 313 void 314 datblk(long s, long n) 315 { 316 Prog *p; 317 char *cast; 318 long l, fl, j; 319 int i, c; 320 321 memset(buf.dbuf, 0, n+Dbufslop); 322 for(p = datap; p != P; p = p->link) { 323 curp = p; 324 l = p->from.sym->value + p->from.offset - s; 325 c = p->from.scale; 326 i = 0; 327 if(l < 0) { 328 if(l+c <= 0) 329 continue; 330 while(l < 0) { 331 l++; 332 i++; 333 } 334 } 335 if(l >= n) 336 continue; 337 if(p->as != AINIT && p->as != ADYNT) { 338 for(j=l+(c-i)-1; j>=l; j--) 339 if(buf.dbuf[j]) { 340 print("%P\n", p); 341 diag("multiple initialization\n"); 342 break; 343 } 344 } 345 switch(p->to.type) { 346 case D_FCONST: 347 switch(c) { 348 default: 349 case 4: 350 fl = ieeedtof(&p->to.ieee); 351 cast = (char*)&fl; 352 if(debug['a'] && i == 0) { 353 Bprint(&bso, pcstr, l+s+INITDAT); 354 for(j=0; j<c; j++) 355 Bprint(&bso, "%.2ux", cast[fnuxi4[j]] & 0xff); 356 Bprint(&bso, "%.*s", (24+7-printcol)/8, "\t\t\t"); 357 Bprint(&bso, "%P\n", curp); 358 } 359 for(; i<c; i++) { 360 buf.dbuf[l] = cast[fnuxi4[i]]; 361 l++; 362 } 363 break; 364 case 8: 365 cast = (char*)&p->to.ieee; 366 if(debug['a'] && i == 0) { 367 Bprint(&bso, pcstr, l+s+INITDAT); 368 for(j=0; j<c; j++) 369 Bprint(&bso, "%.2ux", cast[fnuxi8[j]] & 0xff); 370 Bprint(&bso, "%.*s", (24+7-printcol)/8, "\t\t\t"); 371 Bprint(&bso, "%P\n", curp); 372 } 373 for(; i<c; i++) { 374 buf.dbuf[l] = cast[fnuxi8[i]]; 375 l++; 376 } 377 break; 378 } 379 break; 380 381 case D_SCONST: 382 if(debug['a'] && i == 0) { 383 Bprint(&bso, pcstr, l+s+INITDAT); 384 for(j=0; j<c; j++) 385 Bprint(&bso, "%.2ux", p->to.scon[j] & 0xff); 386 Bprint(&bso, "%.*s", (24+7-printcol)/8, "\t\t\t"); 387 Bprint(&bso, "%P\n", curp); 388 } 389 for(; i<c; i++) { 390 buf.dbuf[l] = p->to.scon[i]; 391 l++; 392 } 393 break; 394 default: 395 fl = p->to.offset; 396 if(p->to.type == D_ADDR) { 397 if(p->to.index != D_STATIC && p->to.index != D_EXTERN) 398 diag("DADDR type%P\n", p); 399 if(p->to.sym) { 400 fl += p->to.sym->value; 401 if(p->to.sym->type != STEXT) 402 fl += INITDAT; 403 } 404 } 405 cast = (char*)&fl; 406 switch(c) { 407 default: 408 diag("bad nuxi %d %d\n%P\n", c, i, curp); 409 break; 410 case 1: 411 if(debug['a'] && i == 0) { 412 Bprint(&bso, pcstr, l+s+INITDAT); 413 for(j=0; j<c; j++) 414 Bprint(&bso, "%.2ux", cast[inuxi1[j]] & 0xff); 415 Bprint(&bso, "%.*s", (24+7-printcol)/8, "\t\t\t"); 416 Bprint(&bso, "%P\n", curp); 417 } 418 for(; i<c; i++) { 419 buf.dbuf[l] = cast[inuxi1[i]]; 420 l++; 421 } 422 break; 423 case 2: 424 if(debug['a'] && i == 0) { 425 Bprint(&bso, pcstr, l+s+INITDAT); 426 for(j=0; j<c; j++) 427 Bprint(&bso, "%.2ux", cast[inuxi2[j]] & 0xff); 428 Bprint(&bso, "%.*s", (24+7-printcol)/8, "\t\t\t"); 429 Bprint(&bso, "%P\n", curp); 430 } 431 for(; i<c; i++) { 432 buf.dbuf[l] = cast[inuxi2[i]]; 433 l++; 434 } 435 break; 436 case 4: 437 if(debug['a'] && i == 0) { 438 Bprint(&bso, pcstr, l+s+INITDAT); 439 for(j=0; j<c; j++) 440 Bprint(&bso, "%.2ux", cast[inuxi4[j]] & 0xff); 441 Bprint(&bso, "%.*s", (24+7-printcol)/8, "\t\t\t"); 442 Bprint(&bso, "%P\n", curp); 443 } 444 for(; i<c; i++) { 445 buf.dbuf[l] = cast[inuxi4[i]]; 446 l++; 447 } 448 break; 449 } 450 break; 451 } 452 } 453 write(cout, buf.dbuf, n); 454 } 455 456 long 457 rnd(long v, long r) 458 { 459 long c; 460 461 if(r <= 0) 462 return v; 463 v += r - 1; 464 c = v % r; 465 if(c < 0) 466 c += r; 467 v -= c; 468 return v; 469 } 470