1 #include "l.h" 2 #include <ar.h> 3 4 #ifndef DEFAULT 5 #define DEFAULT '9' 6 #endif 7 8 char *noname = "<none>"; 9 char symname[] = SYMDEF; 10 char thechar = '6'; 11 char *thestring = "960"; 12 13 /* 14 * -H0 -T0x40004C -D0x10000000 is garbage unix 15 * -H1 -T0xd0 -R4 is unix coff 16 * -H2 -T4128 -R4096 is plan9 format 17 * -H3 -Tx -Rx is msdos boot 18 * -H4 -T0x8000 -R4 is Intel 960 coff 19 */ 20 21 void 22 main(int argc, char *argv[]) 23 { 24 int i, c; 25 char *a; 26 27 Binit(&bso, 1, OWRITE); 28 cout = -1; 29 listinit(); 30 memset(debug, 0, sizeof(debug)); 31 nerrors = 0; 32 outfile = "6.out"; 33 HEADTYPE = -1; 34 INITTEXT = -1; 35 INITDAT = -1; 36 INITRND = -1; 37 INITENTRY = 0; 38 ARGBEGIN { 39 default: 40 c = ARGC(); 41 if(c >= 0 && c < sizeof(debug)) 42 debug[c]++; 43 break; 44 case 'o': /* output to (next arg) */ 45 outfile = ARGF(); 46 break; 47 case 'E': 48 a = ARGF(); 49 if(a) 50 INITENTRY = a; 51 break; 52 case 'H': 53 a = ARGF(); 54 if(a) 55 HEADTYPE = atolwhex(a); 56 break; 57 case 'T': 58 a = ARGF(); 59 if(a) 60 INITTEXT = atolwhex(a); 61 break; 62 case 'D': 63 a = ARGF(); 64 if(a) 65 INITDAT = atolwhex(a); 66 break; 67 case 'R': 68 a = ARGF(); 69 if(a) 70 INITRND = atolwhex(a); 71 break; 72 } ARGEND 73 USED(argc); 74 if(*argv == 0) { 75 diag("usage: 6l [-options] objects\n"); 76 errorexit(); 77 } 78 if(!debug['9'] && !debug['U'] && !debug['B']) 79 debug[DEFAULT] = 1; 80 if(HEADTYPE == -1) { 81 if(debug['U']) 82 HEADTYPE = 1; 83 if(debug['B']) 84 HEADTYPE = 2; 85 if(debug['9']) 86 HEADTYPE = 2; 87 } 88 switch(HEADTYPE) { 89 default: 90 diag("unknown -H option"); 91 errorexit(); 92 93 case 0: /* this is garbage */ 94 HEADR = 20L+56L; 95 if(INITTEXT == -1) 96 INITTEXT = 0x40004CL; 97 if(INITDAT == -1) 98 INITDAT = 0x10000000L; 99 if(INITRND == -1) 100 INITRND = 0; 101 break; 102 case 1: /* is unix coff */ 103 HEADR = 0xd0L; 104 if(INITTEXT == -1) 105 INITTEXT = 0xd0; 106 if(INITDAT == -1) 107 INITDAT = 0x400000; 108 if(INITRND == -1) 109 INITRND = 0; 110 break; 111 case 2: /* plan 9 */ 112 HEADR = 32L; 113 if(INITTEXT == -1) 114 INITTEXT = 4096+32; 115 if(INITDAT == -1) 116 INITDAT = 0; 117 if(INITRND == -1) 118 INITRND = 4096; 119 break; 120 case 3: /* msdos boot */ 121 HEADR = 0; 122 if(INITTEXT == -1) 123 INITTEXT = 0x0100; 124 if(INITDAT == -1) 125 INITDAT = 0; 126 if(INITRND == -1) 127 INITRND = 4; 128 break; 129 case 4: /* is 960 coff */ 130 HEADR = 0x8CL; 131 if(INITTEXT == -1) 132 INITTEXT = 0x8000; 133 if(INITDAT == -1) 134 INITDAT = 0; 135 if(INITRND == -1) 136 INITRND = 4; 137 break; 138 } 139 if(INITDAT != 0 && INITRND != 0) 140 print("warning: -D0x%lux is ignored because of -R0x%lux\n", 141 INITDAT, INITRND); 142 if(debug['v']) 143 Bprint(&bso, "HEADER = -H0x%ld -T0x%lux -D0x%lux -R0x%lux\n", 144 HEADTYPE, INITTEXT, INITDAT, INITRND); 145 Bflush(&bso); 146 for(i=1; optab[i].as; i++) 147 if(i != optab[i].as) { 148 diag("phase error in optab: %d\n", i); 149 errorexit(); 150 } 151 maxop = i; 152 153 for(i=0; i<Ymax; i++) 154 ycover[i*Ymax + i] = 1; 155 156 ycover[Yi5*Ymax + Yri5] = 1; 157 ycover[Yr*Ymax + Yri5] = 1; 158 159 ycover[Yi5*Ymax + Ynri5] = 1; 160 ycover[Yr*Ymax + Ynri5] = 1; 161 ycover[Ynone*Ymax + Ynri5] = 1; 162 163 ycover[Yi5*Ymax + Yi32] = 1; 164 165 zprg.link = P; 166 zprg.cond = P; 167 zprg.back = 2; 168 zprg.as = AGOK; 169 zprg.type = D_NONE; 170 zprg.offset = 0; 171 zprg.from.type = D_NONE; 172 zprg.from.index = D_NONE; 173 zprg.from.scale = 1; 174 zprg.to = zprg.from; 175 176 pcstr = "%.6lux "; 177 nuxiinit(); 178 histgen = 0; 179 textp = P; 180 datap = P; 181 edatap = P; 182 pc = 0; 183 cout = create(outfile, 1, 0775); 184 if(cout < 0) { 185 diag("cannot create %s\n", outfile); 186 errorexit(); 187 } 188 version = 0; 189 cbp = buf.cbuf; 190 cbc = sizeof(buf.cbuf); 191 firstp = prg(); 192 lastp = firstp; 193 194 if(INITENTRY == 0) { 195 INITENTRY = "_main"; 196 if(debug['p']) 197 INITENTRY = "_mainp"; 198 if(!debug['l']) 199 lookup(INITENTRY, 0)->type = SXREF; 200 } else 201 lookup(INITENTRY, 0)->type = SXREF; 202 203 while(*argv) 204 objfile(*argv++); 205 if(!debug['l']) 206 loadlib(0, libraryp); 207 firstp = firstp->link; 208 if(firstp == P) 209 errorexit(); 210 patch(); 211 if(debug['p']) 212 doprof2(); 213 dodata(); 214 follow(); 215 noops(); 216 span(); 217 doinit(); 218 asmb(); 219 undef(); 220 if(debug['v']) { 221 Bprint(&bso, "%5.2f cpu time\n", cputime()); 222 Bprint(&bso, "%ld symbols\n", nsymbol); 223 Bprint(&bso, "%ld memory used\n", thunk); 224 Bprint(&bso, "%d sizeof adr\n", sizeof(Adr)); 225 Bprint(&bso, "%d sizeof prog\n", sizeof(Prog)); 226 } 227 Bflush(&bso); 228 229 errorexit(); 230 } 231 232 void 233 loadlib(int beg, int end) 234 { 235 int i, t; 236 237 for(i=end-1; i>=beg; i--) { 238 t = libraryp; 239 if(debug['v']) 240 Bprint(&bso, "%5.2f autolib: %s\n", cputime(), library[i]); 241 objfile(library[i]); 242 if(t != libraryp) 243 loadlib(t, libraryp); 244 } 245 } 246 247 void 248 errorexit(void) 249 { 250 251 if(nerrors) { 252 if(cout >= 0) 253 remove(outfile); 254 exits("error"); 255 } 256 exits(0); 257 } 258 259 void 260 objfile(char *file) 261 { 262 long off, esym, cnt, l; 263 int f, work; 264 Sym *s; 265 char magbuf[SARMAG]; 266 char name[100], pname[150]; 267 struct ar_hdr arhdr; 268 char *e, *start, *stop; 269 270 if(file[0] == '-' && file[1] == 'l') { 271 if(debug['9']) 272 sprint(name, "/%s/lib/lib", thestring); 273 else 274 sprint(name, "/usr/%clib/lib", thechar); 275 strcat(name, file+2); 276 strcat(name, ".a"); 277 file = name; 278 } 279 if(debug['v']) 280 Bprint(&bso, "%5.2f ldobj: %s\n", cputime(), file); 281 Bflush(&bso); 282 f = open(file, 0); 283 if(f < 0) { 284 diag("cannot open file: %s\n", file); 285 errorexit(); 286 } 287 l = read(f, magbuf, SARMAG); 288 if(l != SARMAG || strncmp(magbuf, ARMAG, SARMAG)){ 289 /* load it as a regular file */ 290 l = seek(f, 0L, 2); 291 seek(f, 0L, 0); 292 ldobj(f, l, file); 293 close(f); 294 return; 295 } 296 297 if(debug['v']) 298 Bprint(&bso, "%5.2f ldlib: %s\n", cputime(), file); 299 l = read(f, &arhdr, sizeof(struct ar_hdr)); 300 if(l != sizeof(struct ar_hdr)) { 301 diag("%s: short read on archive file symbol header\n", file); 302 goto out; 303 } 304 if(strncmp(arhdr.name, symname, strlen(symname))) { 305 diag("%s: first entry not symbol header\n", file); 306 goto out; 307 } 308 309 esym = SARMAG + sizeof(struct ar_hdr) + atolwhex(arhdr.size); 310 off = SARMAG + sizeof(struct ar_hdr); 311 312 /* 313 * just bang the whole symbol file into memory 314 */ 315 seek(f, off, 0); 316 cnt = esym - off; 317 start = malloc(cnt + 10); 318 cnt = read(f, start, cnt); 319 if(cnt <= 0){ 320 close(f); 321 return; 322 } 323 stop = &start[cnt]; 324 memset(stop, 0, 10); 325 326 work = 1; 327 while(work){ 328 if(debug['v']) 329 Bprint(&bso, "%5.2f library pass: %s\n", cputime(), file); 330 Bflush(&bso); 331 work = 0; 332 for(e = start; e < stop; e = strchr(e+5, 0) + 1) { 333 s = lookup(e+5, 0); 334 if(s->type != SXREF) 335 continue; 336 sprint(pname, "%s(%s)", file, s->name); 337 if(debug['v']) 338 Bprint(&bso, "%5.2f library: %s\n", cputime(), pname); 339 Bflush(&bso); 340 l = e[1] & 0xff; 341 l |= (e[2] & 0xff) << 8; 342 l |= (e[3] & 0xff) << 16; 343 l |= (e[4] & 0xff) << 24; 344 seek(f, l, 0); 345 l = read(f, &arhdr, sizeof(struct ar_hdr)); 346 if(l != sizeof(struct ar_hdr)) 347 goto bad; 348 if(strncmp(arhdr.fmag, ARFMAG, sizeof(arhdr.fmag))) 349 goto bad; 350 l = atolwhex(arhdr.size); 351 ldobj(f, l, pname); 352 if(s->type == SXREF) { 353 diag("%s: failed to load: %s\n", file, s->name); 354 errorexit(); 355 } 356 work = 1; 357 } 358 } 359 return; 360 361 bad: 362 diag("%s: bad or out of date archive\n", file); 363 out: 364 close(f); 365 } 366 367 int 368 zaddr(uchar *p, Adr *a, Sym *h[]) 369 { 370 int c, t, i; 371 long l; 372 Sym *s; 373 Auto *u; 374 375 t = p[0]; 376 377 c = 1; 378 if(t & T_INDEX) { 379 a->index = p[c]; 380 a->scale = p[c+1]; 381 c += 2; 382 } else { 383 a->index = D_NONE; 384 a->scale = 0; 385 } 386 a->offset = 0; 387 if(t & T_OFFSET) { 388 a->offset = p[c] | (p[c+1]<<8) | (p[c+2]<<16) | (p[c+3]<<24); 389 c += 4; 390 } 391 a->sym = S; 392 if(t & T_SYM) { 393 a->sym = h[p[c]]; 394 c++; 395 } 396 a->type = D_NONE; 397 if(t & T_FCONST) { 398 a->ieee.l = p[c] | (p[c+1]<<8) | (p[c+2]<<16) | (p[c+3]<<24); 399 a->ieee.h = p[c+4] | (p[c+5]<<8) | (p[c+6]<<16) | (p[c+7]<<24); 400 c += 8; 401 a->type = D_FCONST; 402 } else 403 if(t & T_SCONST) { 404 for(i=0; i<NSNAME; i++) 405 a->scon[i] = p[c+i]; 406 c += NSNAME; 407 a->type = D_SCONST; 408 } 409 if(t & T_TYPE) { 410 a->type = p[c]; 411 c++; 412 } 413 s = a->sym; 414 if(s == S) 415 return c; 416 417 dosym: 418 t = a->type; 419 if(t != D_AUTO && t != D_PARAM) 420 return c; 421 l = a->offset; 422 for(u=curauto; u; u=u->link) { 423 if(u->sym == s) 424 if(u->type == t) { 425 if(u->offset > l) 426 u->offset = l; 427 return c; 428 } 429 } 430 431 while(nhunk < sizeof(Auto)) 432 gethunk(); 433 u = (Auto*)hunk; 434 nhunk -= sizeof(Auto); 435 hunk += sizeof(Auto); 436 437 u->link = curauto; 438 curauto = u; 439 u->sym = s; 440 u->offset = l; 441 u->type = t; 442 return c; 443 } 444 445 void 446 addlib(long line) 447 { 448 char name[MAXHIST*NAMELEN], comp[4*NAMELEN], *p; 449 int i; 450 451 USED(line); 452 if(histfrogp <= 0) 453 return; 454 455 if(histfrog[0]->name[1] == '/') { 456 sprint(name, ""); 457 i = 1; 458 } else 459 if(histfrog[0]->name[1] == '.') { 460 sprint(name, "."); 461 i = 0; 462 } else { 463 if(debug['9']) 464 sprint(name, "/%s/lib", thestring); 465 else 466 sprint(name, "/usr/%clib", thechar); 467 i = 0; 468 } 469 470 for(; i<histfrogp; i++) { 471 snprint(comp, 2*NAMELEN, histfrog[i]->name+1); 472 for(;;) { 473 p = strstr(comp, "$O"); 474 if(p == 0) 475 break; 476 memmove(p+1, p+2, strlen(p+2)+1); 477 p[0] = thechar; 478 } 479 for(;;) { 480 p = strstr(comp, "$M"); 481 if(p == 0) 482 break; 483 memmove(p+strlen(thestring), p+2, strlen(p+2)+1); 484 memmove(p, thestring, strlen(thestring)); 485 if(strlen(comp) > NAMELEN) { 486 diag("library component too long"); 487 return; 488 } 489 } 490 if(strlen(comp) > NAMELEN || strlen(name) + strlen(comp) + 3 >= sizeof(name)) { 491 diag("library component too long"); 492 return; 493 } 494 strcat(name, "/"); 495 strcat(name, comp); 496 } 497 for(i=0; i<libraryp; i++) 498 if(strcmp(name, library[i]) == 0) 499 return; 500 501 p = malloc(strlen(name) + 1); 502 strcpy(p, name); 503 library[libraryp] = p; 504 libraryp++; 505 } 506 507 void 508 addhist(long line, int type) 509 { 510 Auto *u; 511 Sym *s; 512 int i, j, k; 513 514 u = malloc(sizeof(Auto)); 515 s = malloc(sizeof(Sym)); 516 s->name = malloc(2*(histfrogp+1) + 1); 517 518 u->sym = s; 519 u->type = type; 520 u->offset = line; 521 u->link = curhist; 522 curhist = u; 523 524 j = 1; 525 for(i=0; i<histfrogp; i++) { 526 k = histfrog[i]->value; 527 s->name[j+0] = k>>8; 528 s->name[j+1] = k; 529 j += 2; 530 } 531 } 532 533 void 534 histtoauto(void) 535 { 536 Auto *l; 537 538 while(l = curhist) { 539 curhist = l->link; 540 l->link = curauto; 541 curauto = l; 542 } 543 } 544 545 void 546 collapsefrog(Sym *s) 547 { 548 int i; 549 550 /* 551 * bad encoding of path components only allows 552 * MAXHIST components. if there is an overflow, 553 * first try to collapse xxx/.. 554 */ 555 for(i=1; i<histfrogp; i++) 556 if(strcmp(histfrog[i]->name+1, "..") == 0) { 557 memmove(histfrog+i-1, histfrog+i+1, 558 (histfrogp-i-1)*sizeof(histfrog[0])); 559 histfrogp--; 560 goto out; 561 } 562 563 /* 564 * next try to collapse . 565 */ 566 for(i=0; i<histfrogp; i++) 567 if(strcmp(histfrog[i]->name+1, ".") == 0) { 568 memmove(histfrog+i, histfrog+i+1, 569 (histfrogp-i-1)*sizeof(histfrog[0])); 570 goto out; 571 } 572 573 /* 574 * last chance, just truncate from front 575 */ 576 memmove(histfrog+0, histfrog+1, 577 (histfrogp-1)*sizeof(histfrog[0])); 578 579 out: 580 histfrog[histfrogp-1] = s; 581 } 582 583 uchar* 584 readsome(int f, uchar *buf, uchar *good, uchar *stop, int max) 585 { 586 int n; 587 588 n = stop - good; 589 memmove(buf, good, stop - good); 590 stop = buf + n; 591 n = MAXIO - n; 592 if(n > max) 593 n = max; 594 n = read(f, stop, n); 595 if(n <= 0) 596 return 0; 597 return stop + n; 598 } 599 600 void 601 ldobj(int f, long c, char *pn) 602 { 603 Prog *p; 604 Sym *h[NSYM], *s; 605 int v, o, r; 606 long ipc; 607 uchar *bloc, *bsize, *stop; 608 609 bsize = buf.xbuf; 610 bloc = buf.xbuf; 611 612 newloop: 613 memset(h, 0, sizeof(h)); 614 version++; 615 histfrogp = 0; 616 ipc = pc; 617 618 loop: 619 if(c <= 0) 620 goto eof; 621 r = bsize - bloc; 622 if(r < 100 && r < c) { /* enough for largest prog */ 623 bsize = readsome(f, buf.xbuf, bloc, bsize, c); 624 if(bsize == 0) 625 goto eof; 626 bloc = buf.xbuf; 627 goto loop; 628 } 629 o = bloc[0]; 630 if(o <= 0 || o >= maxop) { 631 if(o < 0) 632 goto eof; 633 diag("%s: opcode out of range %d\n", pn, o); 634 print(" probably not a .8 file\n"); 635 errorexit(); 636 } 637 638 if(o == ANAME) { 639 stop = memchr(&bloc[3], 0, bsize-&bloc[3]); 640 if(stop == 0){ 641 bsize = readsome(f, buf.xbuf, bloc, bsize, c); 642 if(bsize == 0) 643 goto eof; 644 bloc = buf.xbuf; 645 stop = memchr(&bloc[3], 0, bsize-&bloc[3]); 646 if(stop == 0){ 647 fprint(2, "%s: name too long\n", pn); 648 errorexit(); 649 } 650 } 651 v = bloc[1]; /* type */ 652 o = bloc[2]; /* sym */ 653 bloc += 3; 654 c -= 3; 655 656 r = 0; 657 if(v == D_STATIC) 658 r = version; 659 s = lookup((char*)bloc, r); 660 c -= &stop[1] - bloc; 661 bloc = stop + 1; 662 663 if(debug['W']) 664 print(" ANAME %s\n", s->name); 665 h[o] = s; 666 if((v == D_EXTERN || v == D_STATIC) && s->type == 0) 667 s->type = SXREF; 668 if(v == D_FILE) { 669 if(s->type != SFILE) { 670 histgen++; 671 s->type = SFILE; 672 s->value = histgen; 673 } 674 if(histfrogp < MAXHIST) { 675 histfrog[histfrogp] = s; 676 histfrogp++; 677 } else 678 collapsefrog(s); 679 } 680 goto loop; 681 } 682 683 while(nhunk < sizeof(Prog)) 684 gethunk(); 685 p = (Prog*)hunk; 686 nhunk -= sizeof(Prog); 687 hunk += sizeof(Prog); 688 689 p->as = o; 690 p->line = bloc[1] | (bloc[2] << 8) | (bloc[3] << 16) | (bloc[4] << 24); 691 p->back = 2; 692 r = bloc[5]; 693 p->type = D_NONE; 694 p->offset = 0; 695 if(r > 0) { 696 if(r >= 33) { 697 p->type = D_CONST; 698 p->offset = r - 33; 699 } else 700 p->type = D_R0 + (r - 1); 701 } 702 r = zaddr(bloc+6, &p->from, h) + 6; 703 r += zaddr(bloc+r, &p->to, h); 704 bloc += r; 705 c -= r; 706 707 if(debug['W']) 708 print("%P\n", p); 709 710 switch(p->as) { 711 case AHISTORY: 712 if(p->to.offset == -1) { 713 addlib(p->line); 714 histfrogp = 0; 715 goto loop; 716 } 717 addhist(p->line, D_FILE); 718 if(p->to.offset) 719 addhist(p->to.offset, D_FILE1); 720 histfrogp = 0; 721 goto loop; 722 723 case AEND: 724 histtoauto(); 725 if(curtext != P) 726 curtext->to.autom = curauto; 727 curauto = 0; 728 curtext = P; 729 if(c) 730 goto newloop; 731 return; 732 733 case AGLOBL: 734 s = p->from.sym; 735 if(s->type == 0 || s->type == SXREF) { 736 s->type = SBSS; 737 s->value = 0; 738 } 739 if(s->type != SBSS) { 740 diag("%s: redefinition: %s in %s\n", 741 pn, s->name, TNAME); 742 s->type = SBSS; 743 s->value = 0; 744 } 745 if(p->to.offset > s->value) 746 s->value = p->to.offset; 747 goto loop; 748 749 case ADATA: 750 if(edatap == P) 751 datap = p; 752 else 753 edatap->link = p; 754 edatap = p; 755 p->link = P; 756 goto loop; 757 758 case AGOK: 759 diag("%s: GOK opcode in %s\n", pn, TNAME); 760 pc++; 761 goto loop; 762 763 case ATEXT: 764 if(curtext != P) { 765 histtoauto(); 766 curtext->to.autom = curauto; 767 curauto = 0; 768 } 769 curtext = p; 770 lastp->link = p; 771 lastp = p; 772 p->pc = pc; 773 s = p->from.sym; 774 if(s == S) { 775 diag("%s: no TEXT symbol: %P\n", pn, p); 776 errorexit(); 777 } 778 if(s->type != 0 && s->type != SXREF) 779 diag("%s: redefinition: %s\n", pn, s->name); 780 s->type = STEXT; 781 s->value = p->pc; 782 pc++; 783 p->cond = P; 784 if(textp == P) { 785 textp = p; 786 etextp = p; 787 goto loop; 788 } 789 etextp->cond = p; 790 etextp = p; 791 goto loop; 792 793 case AADDO: 794 if(p->from.type == D_CONST) 795 if(p->from.offset < 0) { 796 p->as = ASUBO; 797 p->from.offset = -p->from.offset; 798 } 799 goto casdef; 800 801 case AADDI: 802 if(p->from.type == D_CONST) 803 if(p->from.offset < 0) { 804 p->as = ASUBI; 805 p->from.offset = -p->from.offset; 806 } 807 goto casdef; 808 809 case ASUBO: 810 if(p->from.type == D_CONST) 811 if(p->from.offset < 0) { 812 p->as = AADDO; 813 p->from.offset = -p->from.offset; 814 } 815 goto casdef; 816 817 case ASUBI: 818 if(p->from.type == D_CONST) 819 if(p->from.offset < 0) { 820 p->as = AADDI; 821 p->from.offset = -p->from.offset; 822 } 823 goto casdef; 824 825 casdef: 826 default: 827 if(p->to.type == D_BRANCH) 828 p->to.offset += ipc; 829 lastp->link = p; 830 lastp = p; 831 p->pc = pc; 832 pc++; 833 goto loop; 834 } 835 goto loop; 836 837 eof: 838 diag("truncated object file: %s\n", pn); 839 } 840 841 Sym* 842 lookup(char *symb, int v) 843 { 844 Sym *s; 845 char *p; 846 long h; 847 int c, l; 848 849 h = v; 850 for(p=symb; c = *p; p++) 851 h = h+h+h + c; 852 l = (p - symb) + 1; 853 if(h < 0) 854 h = ~h; 855 h %= NHASH; 856 for(s = hash[h]; s != S; s = s->link) 857 if(s->version == v) 858 if(memcmp(s->name, symb, l) == 0) 859 return s; 860 861 while(nhunk < sizeof(Sym)) 862 gethunk(); 863 s = (Sym*)hunk; 864 nhunk -= sizeof(Sym); 865 hunk += sizeof(Sym); 866 867 s->name = malloc(l); 868 memmove(s->name, symb, l); 869 870 s->link = hash[h]; 871 s->type = 0; 872 s->version = v; 873 s->value = 0; 874 hash[h] = s; 875 nsymbol++; 876 return s; 877 } 878 879 Prog* 880 prg(void) 881 { 882 Prog *p; 883 884 while(nhunk < sizeof(Prog)) 885 gethunk(); 886 p = (Prog*)hunk; 887 nhunk -= sizeof(Prog); 888 hunk += sizeof(Prog); 889 890 *p = zprg; 891 return p; 892 } 893 894 Prog* 895 copyp(Prog *q) 896 { 897 Prog *p; 898 899 p = prg(); 900 *p = *q; 901 return p; 902 } 903 904 Prog* 905 appendp(Prog *q) 906 { 907 Prog *p; 908 909 p = prg(); 910 p->link = q->link; 911 q->link = p; 912 p->line = q->line; 913 return p; 914 } 915 916 void 917 gethunk(void) 918 { 919 char *h; 920 long nh; 921 922 nh = NHUNK; 923 if(thunk >= 5L*NHUNK) { 924 nh = 5L*NHUNK; 925 if(thunk >= 25L*NHUNK) 926 nh = 25L*NHUNK; 927 } 928 h = sbrk(nh); 929 if(h == (char*)-1) { 930 diag("out of memory\n"); 931 errorexit(); 932 } 933 hunk = h; 934 nhunk = nh; 935 thunk += nh; 936 } 937 938 void 939 doprof1(void) 940 {} 941 942 void 943 doprof2(void) 944 {} 945 946 void 947 nuxiinit(void) 948 { 949 int i, c; 950 951 for(i=0; i<4; i++) { 952 c = find1(0x04030201L, i+1); 953 if(i < 2) 954 inuxi2[i] = c; 955 if(i < 1) 956 inuxi1[i] = c; 957 inuxi4[i] = c; 958 fnuxi4[i] = c; 959 fnuxi8[i] = c; 960 fnuxi8[i+4] = c+4; 961 } 962 if(debug['v']) { 963 Bprint(&bso, "inuxi = "); 964 for(i=0; i<1; i++) 965 Bprint(&bso, "%d", inuxi1[i]); 966 Bprint(&bso, " "); 967 for(i=0; i<2; i++) 968 Bprint(&bso, "%d", inuxi2[i]); 969 Bprint(&bso, " "); 970 for(i=0; i<4; i++) 971 Bprint(&bso, "%d", inuxi4[i]); 972 Bprint(&bso, "\nfnuxi = "); 973 for(i=0; i<4; i++) 974 Bprint(&bso, "%d", fnuxi4[i]); 975 Bprint(&bso, " "); 976 for(i=0; i<8; i++) 977 Bprint(&bso, "%d", fnuxi8[i]); 978 Bprint(&bso, "\n"); 979 } 980 Bflush(&bso); 981 } 982 983 int 984 find1(long l, int c) 985 { 986 char *p; 987 int i; 988 989 p = (char*)&l; 990 for(i=0; i<4; i++) 991 if(*p++ == c) 992 return i; 993 return 0; 994 } 995 996 int 997 find2(long l, int c) 998 { 999 short *p; 1000 int i; 1001 1002 p = (short*)&l; 1003 for(i=0; i<4; i+=2) { 1004 if(((*p >> 8) & 0xff) == c) 1005 return i; 1006 if((*p++ & 0xff) == c) 1007 return i+1; 1008 } 1009 return 0; 1010 } 1011 1012 long 1013 ieeedtof(Ieee *e) 1014 { 1015 int exp; 1016 long v; 1017 1018 if(e->h == 0) 1019 return 0; 1020 exp = (e->h>>20) & ((1L<<11)-1L); 1021 exp -= (1L<<10) - 2L; 1022 v = (e->h & 0xfffffL) << 3; 1023 v |= (e->l >> 29) & 0x7L; 1024 if((e->l >> 28) & 1) { 1025 v++; 1026 if(v & 0x800000L) { 1027 v = (v & 0x7fffffL) >> 1; 1028 exp++; 1029 } 1030 } 1031 if(exp <= -126 || exp >= 130) 1032 diag("double fp to single fp overflow\n"); 1033 v |= ((exp + 126) & 0xffL) << 23; 1034 v |= e->h & 0x80000000L; 1035 return v; 1036 } 1037 1038 double 1039 ieeedtod(Ieee *ieee) 1040 { 1041 Ieee e; 1042 double fr; 1043 int exp; 1044 1045 if(ieee->h & (1L<<31)) { 1046 e.h = ieee->h & ~(1L<<31); 1047 e.l = ieee->l; 1048 return -ieeedtod(&e); 1049 } 1050 if(ieee->l == 0 && ieee->h == 0) 1051 return 0; 1052 fr = ieee->l & ((1L<<16)-1L); 1053 fr /= 1L<<16; 1054 fr += (ieee->l>>16) & ((1L<<16)-1L); 1055 fr /= 1L<<16; 1056 fr += (ieee->h & (1L<<20)-1L) | (1L<<20); 1057 fr /= 1L<<21; 1058 exp = (ieee->h>>20) & ((1L<<11)-1L); 1059 exp -= (1L<<10) - 2L; 1060 return ldexp(fr, exp); 1061 } 1062 1063 /* 1064 * fake malloc 1065 */ 1066 void* 1067 malloc(long n) 1068 { 1069 void *p; 1070 1071 while(n & 7) 1072 n++; 1073 while(nhunk < n) 1074 gethunk(); 1075 p = hunk; 1076 nhunk -= n; 1077 hunk += n; 1078 return p; 1079 } 1080 1081 void 1082 free(void *p) 1083 { 1084 USED(p); 1085 } 1086 1087 void* 1088 calloc(long m, long n) 1089 { 1090 void *p; 1091 1092 n *= m; 1093 p = malloc(n); 1094 memset(p, 0, n); 1095 return p; 1096 } 1097 1098 void* 1099 realloc(void *p, long n) 1100 { 1101 1102 fprint(2, "realloc called\n", p, n); 1103 abort(); 1104 return 0; 1105 } 1106