13e12c5d1SDavid du Colombier #include "l.h" 23e12c5d1SDavid du Colombier #include <ar.h> 33e12c5d1SDavid du Colombier 43e12c5d1SDavid du Colombier #ifndef DEFAULT 53e12c5d1SDavid du Colombier #define DEFAULT '9' 63e12c5d1SDavid du Colombier #endif 73e12c5d1SDavid du Colombier 83e12c5d1SDavid du Colombier char *noname = "<none>"; 93e12c5d1SDavid du Colombier char symname[] = SYMDEF; 10*219b2ee8SDavid du Colombier char thechar = '8'; 11*219b2ee8SDavid du Colombier char *thestring = "386"; 123e12c5d1SDavid du Colombier 133e12c5d1SDavid du Colombier /* 143e12c5d1SDavid du Colombier * -H0 -T0x40004C -D0x10000000 is garbage unix 153e12c5d1SDavid du Colombier * -H1 -T0xd0 -R4 is unix coff 163e12c5d1SDavid du Colombier * -H2 -T4128 -R4096 is plan9 format 17*219b2ee8SDavid du Colombier * -H3 -Tx -Rx is MS-DOS .COM 18*219b2ee8SDavid du Colombier * -H4 -Tx -Rx is fake MS-DOS .EXE 193e12c5d1SDavid du Colombier */ 203e12c5d1SDavid du Colombier 213e12c5d1SDavid du Colombier void 223e12c5d1SDavid du Colombier main(int argc, char *argv[]) 233e12c5d1SDavid du Colombier { 243e12c5d1SDavid du Colombier int i, c; 253e12c5d1SDavid du Colombier char *a; 263e12c5d1SDavid du Colombier 273e12c5d1SDavid du Colombier Binit(&bso, 1, OWRITE); 283e12c5d1SDavid du Colombier cout = -1; 293e12c5d1SDavid du Colombier listinit(); 303e12c5d1SDavid du Colombier memset(debug, 0, sizeof(debug)); 313e12c5d1SDavid du Colombier nerrors = 0; 323e12c5d1SDavid du Colombier outfile = "8.out"; 333e12c5d1SDavid du Colombier HEADTYPE = -1; 343e12c5d1SDavid du Colombier INITTEXT = -1; 353e12c5d1SDavid du Colombier INITDAT = -1; 363e12c5d1SDavid du Colombier INITRND = -1; 373e12c5d1SDavid du Colombier INITENTRY = 0; 383e12c5d1SDavid du Colombier ARGBEGIN { 393e12c5d1SDavid du Colombier default: 403e12c5d1SDavid du Colombier c = ARGC(); 413e12c5d1SDavid du Colombier if(c >= 0 && c < sizeof(debug)) 423e12c5d1SDavid du Colombier debug[c]++; 433e12c5d1SDavid du Colombier break; 443e12c5d1SDavid du Colombier case 'o': /* output to (next arg) */ 453e12c5d1SDavid du Colombier outfile = ARGF(); 463e12c5d1SDavid du Colombier break; 473e12c5d1SDavid du Colombier case 'E': 483e12c5d1SDavid du Colombier a = ARGF(); 493e12c5d1SDavid du Colombier if(a) 503e12c5d1SDavid du Colombier INITENTRY = a; 513e12c5d1SDavid du Colombier break; 523e12c5d1SDavid du Colombier case 'H': 533e12c5d1SDavid du Colombier a = ARGF(); 543e12c5d1SDavid du Colombier if(a) 553e12c5d1SDavid du Colombier HEADTYPE = atolwhex(a); 563e12c5d1SDavid du Colombier break; 573e12c5d1SDavid du Colombier case 'T': 583e12c5d1SDavid du Colombier a = ARGF(); 593e12c5d1SDavid du Colombier if(a) 603e12c5d1SDavid du Colombier INITTEXT = atolwhex(a); 613e12c5d1SDavid du Colombier break; 623e12c5d1SDavid du Colombier case 'D': 633e12c5d1SDavid du Colombier a = ARGF(); 643e12c5d1SDavid du Colombier if(a) 653e12c5d1SDavid du Colombier INITDAT = atolwhex(a); 663e12c5d1SDavid du Colombier break; 673e12c5d1SDavid du Colombier case 'R': 683e12c5d1SDavid du Colombier a = ARGF(); 693e12c5d1SDavid du Colombier if(a) 703e12c5d1SDavid du Colombier INITRND = atolwhex(a); 713e12c5d1SDavid du Colombier break; 723e12c5d1SDavid du Colombier } ARGEND 733e12c5d1SDavid du Colombier USED(argc); 743e12c5d1SDavid du Colombier if(*argv == 0) { 753e12c5d1SDavid du Colombier diag("usage: 8l [-options] objects\n"); 763e12c5d1SDavid du Colombier errorexit(); 773e12c5d1SDavid du Colombier } 783e12c5d1SDavid du Colombier if(!debug['9'] && !debug['U'] && !debug['B']) 793e12c5d1SDavid du Colombier debug[DEFAULT] = 1; 803e12c5d1SDavid du Colombier if(HEADTYPE == -1) { 813e12c5d1SDavid du Colombier if(debug['U']) 823e12c5d1SDavid du Colombier HEADTYPE = 1; 833e12c5d1SDavid du Colombier if(debug['B']) 843e12c5d1SDavid du Colombier HEADTYPE = 2; 853e12c5d1SDavid du Colombier if(debug['9']) 863e12c5d1SDavid du Colombier HEADTYPE = 2; 873e12c5d1SDavid du Colombier } 883e12c5d1SDavid du Colombier switch(HEADTYPE) { 893e12c5d1SDavid du Colombier default: 903e12c5d1SDavid du Colombier diag("unknown -H option"); 913e12c5d1SDavid du Colombier errorexit(); 923e12c5d1SDavid du Colombier 933e12c5d1SDavid du Colombier case 0: /* this is garbage */ 943e12c5d1SDavid du Colombier HEADR = 20L+56L; 953e12c5d1SDavid du Colombier if(INITTEXT == -1) 963e12c5d1SDavid du Colombier INITTEXT = 0x40004CL; 973e12c5d1SDavid du Colombier if(INITDAT == -1) 983e12c5d1SDavid du Colombier INITDAT = 0x10000000L; 993e12c5d1SDavid du Colombier if(INITRND == -1) 1003e12c5d1SDavid du Colombier INITRND = 0; 1013e12c5d1SDavid du Colombier break; 1023e12c5d1SDavid du Colombier case 1: /* is unix coff */ 1033e12c5d1SDavid du Colombier HEADR = 0xd0L; 1043e12c5d1SDavid du Colombier if(INITTEXT == -1) 1053e12c5d1SDavid du Colombier INITTEXT = 0xd0; 1063e12c5d1SDavid du Colombier if(INITDAT == -1) 1073e12c5d1SDavid du Colombier INITDAT = 0x400000; 1083e12c5d1SDavid du Colombier if(INITRND == -1) 1093e12c5d1SDavid du Colombier INITRND = 0; 1103e12c5d1SDavid du Colombier break; 1113e12c5d1SDavid du Colombier case 2: /* plan 9 */ 1123e12c5d1SDavid du Colombier HEADR = 32L; 1133e12c5d1SDavid du Colombier if(INITTEXT == -1) 1143e12c5d1SDavid du Colombier INITTEXT = 4096+32; 1153e12c5d1SDavid du Colombier if(INITDAT == -1) 1163e12c5d1SDavid du Colombier INITDAT = 0; 1173e12c5d1SDavid du Colombier if(INITRND == -1) 1183e12c5d1SDavid du Colombier INITRND = 4096; 1193e12c5d1SDavid du Colombier break; 120*219b2ee8SDavid du Colombier case 3: /* MS-DOS .COM */ 1213e12c5d1SDavid du Colombier HEADR = 0; 1223e12c5d1SDavid du Colombier if(INITTEXT == -1) 1233e12c5d1SDavid du Colombier INITTEXT = 0x0100; 1243e12c5d1SDavid du Colombier if(INITDAT == -1) 1253e12c5d1SDavid du Colombier INITDAT = 0; 1263e12c5d1SDavid du Colombier if(INITRND == -1) 1273e12c5d1SDavid du Colombier INITRND = 4; 1283e12c5d1SDavid du Colombier break; 129*219b2ee8SDavid du Colombier case 4: /* fake MS-DOS .EXE */ 130*219b2ee8SDavid du Colombier HEADR = 0x200; 131*219b2ee8SDavid du Colombier if(INITTEXT == -1) 132*219b2ee8SDavid du Colombier INITTEXT = 0x0100; 133*219b2ee8SDavid du Colombier if(INITDAT == -1) 134*219b2ee8SDavid du Colombier INITDAT = 0; 135*219b2ee8SDavid du Colombier if(INITRND == -1) 136*219b2ee8SDavid du Colombier INITRND = 4; 137*219b2ee8SDavid du Colombier HEADR += (INITTEXT & 0xFFFF); 138*219b2ee8SDavid du Colombier if(debug['v']) 139*219b2ee8SDavid du Colombier Bprint(&bso, "HEADR = 0x%ld\n", HEADR); 140*219b2ee8SDavid du Colombier break; 1413e12c5d1SDavid du Colombier } 1423e12c5d1SDavid du Colombier if(INITDAT != 0 && INITRND != 0) 1433e12c5d1SDavid du Colombier print("warning: -D0x%lux is ignored because of -R0x%lux\n", 1443e12c5d1SDavid du Colombier INITDAT, INITRND); 1453e12c5d1SDavid du Colombier if(debug['v']) 1463e12c5d1SDavid du Colombier Bprint(&bso, "HEADER = -H0x%ld -T0x%lux -D0x%lux -R0x%lux\n", 1473e12c5d1SDavid du Colombier HEADTYPE, INITTEXT, INITDAT, INITRND); 1483e12c5d1SDavid du Colombier Bflush(&bso); 1493e12c5d1SDavid du Colombier for(i=1; optab[i].as; i++) 1503e12c5d1SDavid du Colombier if(i != optab[i].as) { 1513e12c5d1SDavid du Colombier diag("phase error in optab: %d\n", i); 1523e12c5d1SDavid du Colombier errorexit(); 1533e12c5d1SDavid du Colombier } 1543e12c5d1SDavid du Colombier maxop = i; 1553e12c5d1SDavid du Colombier 1563e12c5d1SDavid du Colombier for(i=0; i<Ymax; i++) 1573e12c5d1SDavid du Colombier ycover[i*Ymax + i] = 1; 1583e12c5d1SDavid du Colombier 1593e12c5d1SDavid du Colombier ycover[Yi0*Ymax + Yi8] = 1; 1603e12c5d1SDavid du Colombier ycover[Yi1*Ymax + Yi8] = 1; 1613e12c5d1SDavid du Colombier 1623e12c5d1SDavid du Colombier ycover[Yi0*Ymax + Yi32] = 1; 1633e12c5d1SDavid du Colombier ycover[Yi1*Ymax + Yi32] = 1; 1643e12c5d1SDavid du Colombier ycover[Yi8*Ymax + Yi32] = 1; 1653e12c5d1SDavid du Colombier 1663e12c5d1SDavid du Colombier ycover[Yal*Ymax + Yrb] = 1; 1673e12c5d1SDavid du Colombier ycover[Ycl*Ymax + Yrb] = 1; 1683e12c5d1SDavid du Colombier ycover[Yax*Ymax + Yrb] = 1; 1693e12c5d1SDavid du Colombier ycover[Ycx*Ymax + Yrb] = 1; 1703e12c5d1SDavid du Colombier ycover[Yrx*Ymax + Yrb] = 1; 1713e12c5d1SDavid du Colombier 1723e12c5d1SDavid du Colombier ycover[Yax*Ymax + Yrx] = 1; 1733e12c5d1SDavid du Colombier ycover[Ycx*Ymax + Yrx] = 1; 1743e12c5d1SDavid du Colombier 1753e12c5d1SDavid du Colombier ycover[Yax*Ymax + Yrl] = 1; 1763e12c5d1SDavid du Colombier ycover[Ycx*Ymax + Yrl] = 1; 1773e12c5d1SDavid du Colombier ycover[Yrx*Ymax + Yrl] = 1; 1783e12c5d1SDavid du Colombier 1793e12c5d1SDavid du Colombier ycover[Yf0*Ymax + Yrf] = 1; 1803e12c5d1SDavid du Colombier 1813e12c5d1SDavid du Colombier ycover[Yal*Ymax + Ymb] = 1; 1823e12c5d1SDavid du Colombier ycover[Ycl*Ymax + Ymb] = 1; 1833e12c5d1SDavid du Colombier ycover[Yax*Ymax + Ymb] = 1; 1843e12c5d1SDavid du Colombier ycover[Ycx*Ymax + Ymb] = 1; 1853e12c5d1SDavid du Colombier ycover[Yrx*Ymax + Ymb] = 1; 1863e12c5d1SDavid du Colombier ycover[Yrb*Ymax + Ymb] = 1; 1873e12c5d1SDavid du Colombier ycover[Ym*Ymax + Ymb] = 1; 1883e12c5d1SDavid du Colombier 1893e12c5d1SDavid du Colombier ycover[Yax*Ymax + Yml] = 1; 1903e12c5d1SDavid du Colombier ycover[Ycx*Ymax + Yml] = 1; 1913e12c5d1SDavid du Colombier ycover[Yrx*Ymax + Yml] = 1; 1923e12c5d1SDavid du Colombier ycover[Yrl*Ymax + Yml] = 1; 1933e12c5d1SDavid du Colombier ycover[Ym*Ymax + Yml] = 1; 1943e12c5d1SDavid du Colombier 1953e12c5d1SDavid du Colombier for(i=0; i<D_NONE; i++) { 1963e12c5d1SDavid du Colombier reg[i] = -1; 1973e12c5d1SDavid du Colombier if(i >= D_AL && i <= D_BH) 1983e12c5d1SDavid du Colombier reg[i] = (i-D_AL) & 7; 1993e12c5d1SDavid du Colombier if(i >= D_AX && i <= D_DI) 2003e12c5d1SDavid du Colombier reg[i] = (i-D_AX) & 7; 2013e12c5d1SDavid du Colombier if(i >= D_F0 && i <= D_F0+7) 2023e12c5d1SDavid du Colombier reg[i] = (i-D_F0) & 7; 2033e12c5d1SDavid du Colombier } 2043e12c5d1SDavid du Colombier 2053e12c5d1SDavid du Colombier zprg.link = P; 2063e12c5d1SDavid du Colombier zprg.cond = P; 2073e12c5d1SDavid du Colombier zprg.back = 2; 2083e12c5d1SDavid du Colombier zprg.as = AGOK; 2093e12c5d1SDavid du Colombier zprg.from.type = D_NONE; 2103e12c5d1SDavid du Colombier zprg.from.index = D_NONE; 2113e12c5d1SDavid du Colombier zprg.from.scale = 1; 2123e12c5d1SDavid du Colombier zprg.to = zprg.from; 2133e12c5d1SDavid du Colombier 2143e12c5d1SDavid du Colombier pcstr = "%.6lux "; 2153e12c5d1SDavid du Colombier nuxiinit(); 2163e12c5d1SDavid du Colombier histgen = 0; 2173e12c5d1SDavid du Colombier textp = P; 2183e12c5d1SDavid du Colombier datap = P; 2193e12c5d1SDavid du Colombier edatap = P; 2203e12c5d1SDavid du Colombier pc = 0; 221*219b2ee8SDavid du Colombier dtype = 4; 2223e12c5d1SDavid du Colombier cout = create(outfile, 1, 0775); 2233e12c5d1SDavid du Colombier if(cout < 0) { 2243e12c5d1SDavid du Colombier diag("cannot create %s\n", outfile); 2253e12c5d1SDavid du Colombier errorexit(); 2263e12c5d1SDavid du Colombier } 2273e12c5d1SDavid du Colombier version = 0; 2283e12c5d1SDavid du Colombier cbp = buf.cbuf; 2293e12c5d1SDavid du Colombier cbc = sizeof(buf.cbuf); 2303e12c5d1SDavid du Colombier firstp = prg(); 2313e12c5d1SDavid du Colombier lastp = firstp; 2323e12c5d1SDavid du Colombier 2333e12c5d1SDavid du Colombier if(INITENTRY == 0) { 2343e12c5d1SDavid du Colombier INITENTRY = "_main"; 2353e12c5d1SDavid du Colombier if(debug['p']) 2363e12c5d1SDavid du Colombier INITENTRY = "_mainp"; 2373e12c5d1SDavid du Colombier if(!debug['l']) 2383e12c5d1SDavid du Colombier lookup(INITENTRY, 0)->type = SXREF; 239*219b2ee8SDavid du Colombier } else 240*219b2ee8SDavid du Colombier lookup(INITENTRY, 0)->type = SXREF; 2413e12c5d1SDavid du Colombier 2423e12c5d1SDavid du Colombier while(*argv) 2433e12c5d1SDavid du Colombier objfile(*argv++); 2443e12c5d1SDavid du Colombier if(!debug['l']) 2453e12c5d1SDavid du Colombier loadlib(0, libraryp); 2463e12c5d1SDavid du Colombier firstp = firstp->link; 2473e12c5d1SDavid du Colombier if(firstp == P) 2483e12c5d1SDavid du Colombier errorexit(); 2493e12c5d1SDavid du Colombier patch(); 2503e12c5d1SDavid du Colombier if(debug['p']) 2513e12c5d1SDavid du Colombier if(debug['1']) 2523e12c5d1SDavid du Colombier doprof1(); 2533e12c5d1SDavid du Colombier else 2543e12c5d1SDavid du Colombier doprof2(); 2553e12c5d1SDavid du Colombier follow(); 2563e12c5d1SDavid du Colombier dodata(); 2573e12c5d1SDavid du Colombier dostkoff(); 2583e12c5d1SDavid du Colombier span(); 2593e12c5d1SDavid du Colombier doinit(); 2603e12c5d1SDavid du Colombier asmb(); 2613e12c5d1SDavid du Colombier undef(); 2623e12c5d1SDavid du Colombier if(debug['v']) { 2633e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f cpu time\n", cputime()); 2643e12c5d1SDavid du Colombier Bprint(&bso, "%ld symbols\n", nsymbol); 2653e12c5d1SDavid du Colombier Bprint(&bso, "%ld memory used\n", thunk); 2663e12c5d1SDavid du Colombier Bprint(&bso, "%d sizeof adr\n", sizeof(Adr)); 2673e12c5d1SDavid du Colombier Bprint(&bso, "%d sizeof prog\n", sizeof(Prog)); 2683e12c5d1SDavid du Colombier } 2693e12c5d1SDavid du Colombier Bflush(&bso); 2703e12c5d1SDavid du Colombier 2713e12c5d1SDavid du Colombier errorexit(); 2723e12c5d1SDavid du Colombier } 2733e12c5d1SDavid du Colombier 2743e12c5d1SDavid du Colombier void 2753e12c5d1SDavid du Colombier loadlib(int beg, int end) 2763e12c5d1SDavid du Colombier { 2773e12c5d1SDavid du Colombier int i, t; 2783e12c5d1SDavid du Colombier 2793e12c5d1SDavid du Colombier for(i=end-1; i>=beg; i--) { 2803e12c5d1SDavid du Colombier t = libraryp; 2813e12c5d1SDavid du Colombier if(debug['v']) 2823e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f autolib: %s\n", cputime(), library[i]); 2833e12c5d1SDavid du Colombier objfile(library[i]); 2843e12c5d1SDavid du Colombier if(t != libraryp) 2853e12c5d1SDavid du Colombier loadlib(t, libraryp); 2863e12c5d1SDavid du Colombier } 2873e12c5d1SDavid du Colombier } 2883e12c5d1SDavid du Colombier 2893e12c5d1SDavid du Colombier void 2903e12c5d1SDavid du Colombier errorexit(void) 2913e12c5d1SDavid du Colombier { 2923e12c5d1SDavid du Colombier 2933e12c5d1SDavid du Colombier if(nerrors) { 2943e12c5d1SDavid du Colombier if(cout >= 0) 2953e12c5d1SDavid du Colombier remove(outfile); 2963e12c5d1SDavid du Colombier exits("error"); 2973e12c5d1SDavid du Colombier } 2983e12c5d1SDavid du Colombier exits(0); 2993e12c5d1SDavid du Colombier } 3003e12c5d1SDavid du Colombier 3013e12c5d1SDavid du Colombier void 3023e12c5d1SDavid du Colombier objfile(char *file) 3033e12c5d1SDavid du Colombier { 304*219b2ee8SDavid du Colombier long off, esym, cnt, l; 3053e12c5d1SDavid du Colombier int f, work; 3063e12c5d1SDavid du Colombier Sym *s; 3073e12c5d1SDavid du Colombier char magbuf[SARMAG]; 3083e12c5d1SDavid du Colombier char name[100], pname[150]; 3093e12c5d1SDavid du Colombier struct ar_hdr arhdr; 310*219b2ee8SDavid du Colombier char *e, *start, *stop; 3113e12c5d1SDavid du Colombier 3123e12c5d1SDavid du Colombier if(file[0] == '-' && file[1] == 'l') { 3133e12c5d1SDavid du Colombier if(debug['9']) 314*219b2ee8SDavid du Colombier sprint(name, "/%s/lib/lib", thestring); 3153e12c5d1SDavid du Colombier else 316*219b2ee8SDavid du Colombier sprint(name, "/usr/%clib/lib", thechar); 3173e12c5d1SDavid du Colombier strcat(name, file+2); 3183e12c5d1SDavid du Colombier strcat(name, ".a"); 3193e12c5d1SDavid du Colombier file = name; 3203e12c5d1SDavid du Colombier } 3213e12c5d1SDavid du Colombier if(debug['v']) 3223e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f ldobj: %s\n", cputime(), file); 3233e12c5d1SDavid du Colombier Bflush(&bso); 3243e12c5d1SDavid du Colombier f = open(file, 0); 3253e12c5d1SDavid du Colombier if(f < 0) { 3263e12c5d1SDavid du Colombier diag("cannot open file: %s\n", file); 3273e12c5d1SDavid du Colombier errorexit(); 3283e12c5d1SDavid du Colombier } 3293e12c5d1SDavid du Colombier l = read(f, magbuf, SARMAG); 330*219b2ee8SDavid du Colombier if(l != SARMAG || strncmp(magbuf, ARMAG, SARMAG)){ 331*219b2ee8SDavid du Colombier /* load it as a regular file */ 332*219b2ee8SDavid du Colombier l = seek(f, 0L, 2); 333*219b2ee8SDavid du Colombier seek(f, 0L, 0); 334*219b2ee8SDavid du Colombier ldobj(f, l, file); 335*219b2ee8SDavid du Colombier close(f); 336*219b2ee8SDavid du Colombier return; 337*219b2ee8SDavid du Colombier } 3383e12c5d1SDavid du Colombier 3393e12c5d1SDavid du Colombier l = read(f, &arhdr, sizeof(struct ar_hdr)); 3403e12c5d1SDavid du Colombier if(l != sizeof(struct ar_hdr)) { 3413e12c5d1SDavid du Colombier diag("%s: short read on archive file symbol header\n", file); 3423e12c5d1SDavid du Colombier goto out; 3433e12c5d1SDavid du Colombier } 3443e12c5d1SDavid du Colombier if(strncmp(arhdr.name, symname, strlen(symname))) { 3453e12c5d1SDavid du Colombier diag("%s: first entry not symbol header\n", file); 3463e12c5d1SDavid du Colombier goto out; 3473e12c5d1SDavid du Colombier } 3483e12c5d1SDavid du Colombier 349*219b2ee8SDavid du Colombier esym = SARMAG + sizeof(struct ar_hdr) + atolwhex(arhdr.size); 3503e12c5d1SDavid du Colombier off = SARMAG + sizeof(struct ar_hdr); 3513e12c5d1SDavid du Colombier 352*219b2ee8SDavid du Colombier /* 353*219b2ee8SDavid du Colombier * just bang the whole symbol file into memory 354*219b2ee8SDavid du Colombier */ 3553e12c5d1SDavid du Colombier seek(f, off, 0); 3563e12c5d1SDavid du Colombier cnt = esym - off; 357*219b2ee8SDavid du Colombier start = malloc(cnt + 10); 358*219b2ee8SDavid du Colombier cnt = read(f, start, cnt); 3593e12c5d1SDavid du Colombier if(cnt <= 0){ 3603e12c5d1SDavid du Colombier close(f); 3613e12c5d1SDavid du Colombier return; 3623e12c5d1SDavid du Colombier } 363*219b2ee8SDavid du Colombier stop = &start[cnt]; 364*219b2ee8SDavid du Colombier memset(stop, 0, 10); 365*219b2ee8SDavid du Colombier 366*219b2ee8SDavid du Colombier work = 1; 367*219b2ee8SDavid du Colombier while(work){ 368*219b2ee8SDavid du Colombier if(debug['v']) 369*219b2ee8SDavid du Colombier Bprint(&bso, "%5.2f library pass: %s\n", cputime(), file); 370*219b2ee8SDavid du Colombier Bflush(&bso); 371*219b2ee8SDavid du Colombier work = 0; 372*219b2ee8SDavid du Colombier for(e = start; e < stop; e = strchr(e+5, 0) + 1) { 373*219b2ee8SDavid du Colombier s = lookup(e+5, 0); 3743e12c5d1SDavid du Colombier if(s->type != SXREF) 3753e12c5d1SDavid du Colombier continue; 376*219b2ee8SDavid du Colombier sprint(pname, "%s(%s)", file, s->name); 3773e12c5d1SDavid du Colombier if(debug['v']) 3783e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f library: %s\n", cputime(), pname); 3793e12c5d1SDavid du Colombier Bflush(&bso); 380*219b2ee8SDavid du Colombier l = e[1] & 0xff; 381*219b2ee8SDavid du Colombier l |= (e[2] & 0xff) << 8; 382*219b2ee8SDavid du Colombier l |= (e[3] & 0xff) << 16; 383*219b2ee8SDavid du Colombier l |= (e[4] & 0xff) << 24; 3843e12c5d1SDavid du Colombier seek(f, l, 0); 3853e12c5d1SDavid du Colombier l = read(f, &arhdr, sizeof(struct ar_hdr)); 3863e12c5d1SDavid du Colombier if(l != sizeof(struct ar_hdr)) 3873e12c5d1SDavid du Colombier goto bad; 3883e12c5d1SDavid du Colombier if(strncmp(arhdr.fmag, ARFMAG, sizeof(arhdr.fmag))) 3893e12c5d1SDavid du Colombier goto bad; 3903e12c5d1SDavid du Colombier l = atolwhex(arhdr.size); 3913e12c5d1SDavid du Colombier ldobj(f, l, pname); 3923e12c5d1SDavid du Colombier if(s->type == SXREF) { 3933e12c5d1SDavid du Colombier diag("%s: failed to load: %s\n", file, s->name); 3943e12c5d1SDavid du Colombier errorexit(); 3953e12c5d1SDavid du Colombier } 3963e12c5d1SDavid du Colombier work = 1; 3973e12c5d1SDavid du Colombier } 398*219b2ee8SDavid du Colombier } 3993e12c5d1SDavid du Colombier return; 4003e12c5d1SDavid du Colombier 4013e12c5d1SDavid du Colombier bad: 4023e12c5d1SDavid du Colombier diag("%s: bad or out of date archive\n", file); 4033e12c5d1SDavid du Colombier out: 4043e12c5d1SDavid du Colombier close(f); 4053e12c5d1SDavid du Colombier } 4063e12c5d1SDavid du Colombier 4073e12c5d1SDavid du Colombier int 4083e12c5d1SDavid du Colombier zaddr(uchar *p, Adr *a, Sym *h[]) 4093e12c5d1SDavid du Colombier { 4103e12c5d1SDavid du Colombier int c, t, i; 4113e12c5d1SDavid du Colombier long l; 4123e12c5d1SDavid du Colombier Sym *s; 4133e12c5d1SDavid du Colombier Auto *u; 4143e12c5d1SDavid du Colombier 4153e12c5d1SDavid du Colombier t = p[0]; 4163e12c5d1SDavid du Colombier 4173e12c5d1SDavid du Colombier c = 1; 4183e12c5d1SDavid du Colombier if(t & T_INDEX) { 4193e12c5d1SDavid du Colombier a->index = p[c]; 4203e12c5d1SDavid du Colombier a->scale = p[c+1]; 4213e12c5d1SDavid du Colombier c += 2; 4223e12c5d1SDavid du Colombier } else { 4233e12c5d1SDavid du Colombier a->index = D_NONE; 4243e12c5d1SDavid du Colombier a->scale = 0; 4253e12c5d1SDavid du Colombier } 4263e12c5d1SDavid du Colombier a->offset = 0; 4273e12c5d1SDavid du Colombier if(t & T_OFFSET) { 4283e12c5d1SDavid du Colombier a->offset = p[c] | (p[c+1]<<8) | (p[c+2]<<16) | (p[c+3]<<24); 4293e12c5d1SDavid du Colombier c += 4; 4303e12c5d1SDavid du Colombier } 4313e12c5d1SDavid du Colombier a->sym = S; 4323e12c5d1SDavid du Colombier if(t & T_SYM) { 4333e12c5d1SDavid du Colombier a->sym = h[p[c]]; 4343e12c5d1SDavid du Colombier c++; 4353e12c5d1SDavid du Colombier } 4363e12c5d1SDavid du Colombier a->type = D_NONE; 4373e12c5d1SDavid du Colombier if(t & T_FCONST) { 4383e12c5d1SDavid du Colombier a->ieee.l = p[c] | (p[c+1]<<8) | (p[c+2]<<16) | (p[c+3]<<24); 4393e12c5d1SDavid du Colombier a->ieee.h = p[c+4] | (p[c+5]<<8) | (p[c+6]<<16) | (p[c+7]<<24); 4403e12c5d1SDavid du Colombier c += 8; 4413e12c5d1SDavid du Colombier a->type = D_FCONST; 4423e12c5d1SDavid du Colombier } else 4433e12c5d1SDavid du Colombier if(t & T_SCONST) { 4443e12c5d1SDavid du Colombier for(i=0; i<NSNAME; i++) 4453e12c5d1SDavid du Colombier a->scon[i] = p[c+i]; 4463e12c5d1SDavid du Colombier c += NSNAME; 4473e12c5d1SDavid du Colombier a->type = D_SCONST; 4483e12c5d1SDavid du Colombier } 4493e12c5d1SDavid du Colombier if(t & T_TYPE) { 4503e12c5d1SDavid du Colombier a->type = p[c]; 4513e12c5d1SDavid du Colombier c++; 4523e12c5d1SDavid du Colombier } 4533e12c5d1SDavid du Colombier s = a->sym; 4543e12c5d1SDavid du Colombier if(s == S) 4553e12c5d1SDavid du Colombier return c; 4563e12c5d1SDavid du Colombier 4573e12c5d1SDavid du Colombier t = a->type; 4583e12c5d1SDavid du Colombier if(t != D_AUTO && t != D_PARAM) 4593e12c5d1SDavid du Colombier return c; 4603e12c5d1SDavid du Colombier l = a->offset; 4613e12c5d1SDavid du Colombier for(u=curauto; u; u=u->link) { 4623e12c5d1SDavid du Colombier if(u->sym == s) 4633e12c5d1SDavid du Colombier if(u->type == t) { 4643e12c5d1SDavid du Colombier if(u->offset > l) 4653e12c5d1SDavid du Colombier u->offset = l; 4663e12c5d1SDavid du Colombier return c; 4673e12c5d1SDavid du Colombier } 4683e12c5d1SDavid du Colombier } 4693e12c5d1SDavid du Colombier 4703e12c5d1SDavid du Colombier while(nhunk < sizeof(Auto)) 4713e12c5d1SDavid du Colombier gethunk(); 4723e12c5d1SDavid du Colombier u = (Auto*)hunk; 4733e12c5d1SDavid du Colombier nhunk -= sizeof(Auto); 4743e12c5d1SDavid du Colombier hunk += sizeof(Auto); 4753e12c5d1SDavid du Colombier 4763e12c5d1SDavid du Colombier u->link = curauto; 4773e12c5d1SDavid du Colombier curauto = u; 4783e12c5d1SDavid du Colombier u->sym = s; 4793e12c5d1SDavid du Colombier u->offset = l; 4803e12c5d1SDavid du Colombier u->type = t; 4813e12c5d1SDavid du Colombier return c; 4823e12c5d1SDavid du Colombier } 4833e12c5d1SDavid du Colombier 4843e12c5d1SDavid du Colombier void 4853e12c5d1SDavid du Colombier addlib(long line) 4863e12c5d1SDavid du Colombier { 487*219b2ee8SDavid du Colombier char name[MAXHIST*NAMELEN], comp[4*NAMELEN], *p; 4883e12c5d1SDavid du Colombier int i; 4893e12c5d1SDavid du Colombier 4903e12c5d1SDavid du Colombier USED(line); 4913e12c5d1SDavid du Colombier if(histfrogp <= 0) 4923e12c5d1SDavid du Colombier return; 4933e12c5d1SDavid du Colombier 4943e12c5d1SDavid du Colombier if(histfrog[0]->name[1] == '/') { 4953e12c5d1SDavid du Colombier sprint(name, ""); 4963e12c5d1SDavid du Colombier i = 1; 4973e12c5d1SDavid du Colombier } else 4983e12c5d1SDavid du Colombier if(histfrog[0]->name[1] == '.') { 4993e12c5d1SDavid du Colombier sprint(name, "."); 5003e12c5d1SDavid du Colombier i = 0; 5013e12c5d1SDavid du Colombier } else { 5023e12c5d1SDavid du Colombier if(debug['9']) 503*219b2ee8SDavid du Colombier sprint(name, "/%s/lib", thestring); 5043e12c5d1SDavid du Colombier else 505*219b2ee8SDavid du Colombier sprint(name, "/usr/%clib", thechar); 5063e12c5d1SDavid du Colombier i = 0; 5073e12c5d1SDavid du Colombier } 5083e12c5d1SDavid du Colombier 5093e12c5d1SDavid du Colombier for(; i<histfrogp; i++) { 510*219b2ee8SDavid du Colombier snprint(comp, 2*NAMELEN, histfrog[i]->name+1); 5113e12c5d1SDavid du Colombier for(;;) { 5123e12c5d1SDavid du Colombier p = strstr(comp, "$O"); 5133e12c5d1SDavid du Colombier if(p == 0) 5143e12c5d1SDavid du Colombier break; 5153e12c5d1SDavid du Colombier memmove(p+1, p+2, strlen(p+2)+1); 516*219b2ee8SDavid du Colombier p[0] = thechar; 5173e12c5d1SDavid du Colombier } 5183e12c5d1SDavid du Colombier for(;;) { 5193e12c5d1SDavid du Colombier p = strstr(comp, "$M"); 5203e12c5d1SDavid du Colombier if(p == 0) 5213e12c5d1SDavid du Colombier break; 522*219b2ee8SDavid du Colombier memmove(p+strlen(thestring), p+2, strlen(p+2)+1); 523*219b2ee8SDavid du Colombier memmove(p, thestring, strlen(thestring)); 524*219b2ee8SDavid du Colombier if(strlen(comp) > NAMELEN) { 525*219b2ee8SDavid du Colombier diag("library component too long"); 526*219b2ee8SDavid du Colombier return; 5273e12c5d1SDavid du Colombier } 528*219b2ee8SDavid du Colombier } 529*219b2ee8SDavid du Colombier if(strlen(comp) > NAMELEN || strlen(name) + strlen(comp) + 3 >= sizeof(name)) { 5303e12c5d1SDavid du Colombier diag("library component too long"); 5313e12c5d1SDavid du Colombier return; 5323e12c5d1SDavid du Colombier } 5333e12c5d1SDavid du Colombier strcat(name, "/"); 5343e12c5d1SDavid du Colombier strcat(name, comp); 5353e12c5d1SDavid du Colombier } 5363e12c5d1SDavid du Colombier for(i=0; i<libraryp; i++) 5373e12c5d1SDavid du Colombier if(strcmp(name, library[i]) == 0) 5383e12c5d1SDavid du Colombier return; 5393e12c5d1SDavid du Colombier 540*219b2ee8SDavid du Colombier p = malloc(strlen(name) + 1); 5413e12c5d1SDavid du Colombier strcpy(p, name); 5423e12c5d1SDavid du Colombier library[libraryp] = p; 5433e12c5d1SDavid du Colombier libraryp++; 5443e12c5d1SDavid du Colombier } 545*219b2ee8SDavid du Colombier 5463e12c5d1SDavid du Colombier void 5473e12c5d1SDavid du Colombier addhist(long line, int type) 5483e12c5d1SDavid du Colombier { 5493e12c5d1SDavid du Colombier Auto *u; 5503e12c5d1SDavid du Colombier Sym *s; 5513e12c5d1SDavid du Colombier int i, j, k; 5523e12c5d1SDavid du Colombier 553*219b2ee8SDavid du Colombier u = malloc(sizeof(Auto)); 554*219b2ee8SDavid du Colombier s = malloc(sizeof(Sym)); 555*219b2ee8SDavid du Colombier s->name = malloc(2*(histfrogp+1) + 1); 5563e12c5d1SDavid du Colombier 5573e12c5d1SDavid du Colombier u->sym = s; 5583e12c5d1SDavid du Colombier u->type = type; 5593e12c5d1SDavid du Colombier u->offset = line; 5603e12c5d1SDavid du Colombier u->link = curhist; 5613e12c5d1SDavid du Colombier curhist = u; 5623e12c5d1SDavid du Colombier 5633e12c5d1SDavid du Colombier j = 1; 5643e12c5d1SDavid du Colombier for(i=0; i<histfrogp; i++) { 5653e12c5d1SDavid du Colombier k = histfrog[i]->value; 5663e12c5d1SDavid du Colombier s->name[j+0] = k>>8; 5673e12c5d1SDavid du Colombier s->name[j+1] = k; 5683e12c5d1SDavid du Colombier j += 2; 5693e12c5d1SDavid du Colombier } 5703e12c5d1SDavid du Colombier } 5713e12c5d1SDavid du Colombier 5723e12c5d1SDavid du Colombier void 5733e12c5d1SDavid du Colombier histtoauto(void) 5743e12c5d1SDavid du Colombier { 5753e12c5d1SDavid du Colombier Auto *l; 5763e12c5d1SDavid du Colombier 5773e12c5d1SDavid du Colombier while(l = curhist) { 5783e12c5d1SDavid du Colombier curhist = l->link; 5793e12c5d1SDavid du Colombier l->link = curauto; 5803e12c5d1SDavid du Colombier curauto = l; 5813e12c5d1SDavid du Colombier } 5823e12c5d1SDavid du Colombier } 5833e12c5d1SDavid du Colombier 5843e12c5d1SDavid du Colombier void 585*219b2ee8SDavid du Colombier collapsefrog(Sym *s) 586*219b2ee8SDavid du Colombier { 587*219b2ee8SDavid du Colombier int i; 588*219b2ee8SDavid du Colombier 589*219b2ee8SDavid du Colombier /* 590*219b2ee8SDavid du Colombier * bad encoding of path components only allows 591*219b2ee8SDavid du Colombier * MAXHIST components. if there is an overflow, 592*219b2ee8SDavid du Colombier * first try to collapse xxx/.. 593*219b2ee8SDavid du Colombier */ 594*219b2ee8SDavid du Colombier for(i=1; i<histfrogp; i++) 595*219b2ee8SDavid du Colombier if(strcmp(histfrog[i]->name+1, "..") == 0) { 596*219b2ee8SDavid du Colombier memmove(histfrog+i-1, histfrog+i+1, 597*219b2ee8SDavid du Colombier (histfrogp-i-1)*sizeof(histfrog[0])); 598*219b2ee8SDavid du Colombier histfrogp--; 599*219b2ee8SDavid du Colombier goto out; 600*219b2ee8SDavid du Colombier } 601*219b2ee8SDavid du Colombier 602*219b2ee8SDavid du Colombier /* 603*219b2ee8SDavid du Colombier * next try to collapse . 604*219b2ee8SDavid du Colombier */ 605*219b2ee8SDavid du Colombier for(i=0; i<histfrogp; i++) 606*219b2ee8SDavid du Colombier if(strcmp(histfrog[i]->name+1, ".") == 0) { 607*219b2ee8SDavid du Colombier memmove(histfrog+i, histfrog+i+1, 608*219b2ee8SDavid du Colombier (histfrogp-i-1)*sizeof(histfrog[0])); 609*219b2ee8SDavid du Colombier goto out; 610*219b2ee8SDavid du Colombier } 611*219b2ee8SDavid du Colombier 612*219b2ee8SDavid du Colombier /* 613*219b2ee8SDavid du Colombier * last chance, just truncate from front 614*219b2ee8SDavid du Colombier */ 615*219b2ee8SDavid du Colombier memmove(histfrog+0, histfrog+1, 616*219b2ee8SDavid du Colombier (histfrogp-1)*sizeof(histfrog[0])); 617*219b2ee8SDavid du Colombier 618*219b2ee8SDavid du Colombier out: 619*219b2ee8SDavid du Colombier histfrog[histfrogp-1] = s; 620*219b2ee8SDavid du Colombier } 621*219b2ee8SDavid du Colombier 622*219b2ee8SDavid du Colombier void 623*219b2ee8SDavid du Colombier nopout(Prog *p) 624*219b2ee8SDavid du Colombier { 625*219b2ee8SDavid du Colombier p->as = ANOP; 626*219b2ee8SDavid du Colombier p->from.type = D_NONE; 627*219b2ee8SDavid du Colombier p->to.type = D_NONE; 628*219b2ee8SDavid du Colombier } 629*219b2ee8SDavid du Colombier 630*219b2ee8SDavid du Colombier uchar* 631*219b2ee8SDavid du Colombier readsome(int f, uchar *buf, uchar *good, uchar *stop, int max) 632*219b2ee8SDavid du Colombier { 633*219b2ee8SDavid du Colombier int n; 634*219b2ee8SDavid du Colombier 635*219b2ee8SDavid du Colombier n = stop - good; 636*219b2ee8SDavid du Colombier memmove(buf, good, stop - good); 637*219b2ee8SDavid du Colombier stop = buf + n; 638*219b2ee8SDavid du Colombier n = MAXIO - n; 639*219b2ee8SDavid du Colombier if(n > max) 640*219b2ee8SDavid du Colombier n = max; 641*219b2ee8SDavid du Colombier n = read(f, stop, n); 642*219b2ee8SDavid du Colombier if(n <= 0) 643*219b2ee8SDavid du Colombier return 0; 644*219b2ee8SDavid du Colombier return stop + n; 645*219b2ee8SDavid du Colombier } 646*219b2ee8SDavid du Colombier 647*219b2ee8SDavid du Colombier void 6483e12c5d1SDavid du Colombier ldobj(int f, long c, char *pn) 6493e12c5d1SDavid du Colombier { 6503e12c5d1SDavid du Colombier long ipc; 651*219b2ee8SDavid du Colombier Prog *p, *t; 652*219b2ee8SDavid du Colombier uchar *bloc, *bsize, *stop; 653*219b2ee8SDavid du Colombier int v, o, r, skip; 654*219b2ee8SDavid du Colombier Sym *h[NSYM], *s, *di; 6553e12c5d1SDavid du Colombier 6563e12c5d1SDavid du Colombier bsize = buf.xbuf; 6573e12c5d1SDavid du Colombier bloc = buf.xbuf; 658*219b2ee8SDavid du Colombier di = S; 6593e12c5d1SDavid du Colombier 6603e12c5d1SDavid du Colombier newloop: 6613e12c5d1SDavid du Colombier memset(h, 0, sizeof(h)); 6623e12c5d1SDavid du Colombier version++; 6633e12c5d1SDavid du Colombier histfrogp = 0; 6643e12c5d1SDavid du Colombier ipc = pc; 665*219b2ee8SDavid du Colombier skip = 0; 6663e12c5d1SDavid du Colombier 6673e12c5d1SDavid du Colombier loop: 6683e12c5d1SDavid du Colombier if(c <= 0) 6693e12c5d1SDavid du Colombier goto eof; 6703e12c5d1SDavid du Colombier r = bsize - bloc; 6713e12c5d1SDavid du Colombier if(r < 100 && r < c) { /* enough for largest prog */ 672*219b2ee8SDavid du Colombier bsize = readsome(f, buf.xbuf, bloc, bsize, c); 673*219b2ee8SDavid du Colombier if(bsize == 0) 6743e12c5d1SDavid du Colombier goto eof; 675*219b2ee8SDavid du Colombier bloc = buf.xbuf; 6763e12c5d1SDavid du Colombier goto loop; 6773e12c5d1SDavid du Colombier } 6783e12c5d1SDavid du Colombier o = bloc[0] | (bloc[1] << 8); 679*219b2ee8SDavid du Colombier if(o <= AXXX || o >= ALAST) { 6803e12c5d1SDavid du Colombier if(o < 0) 6813e12c5d1SDavid du Colombier goto eof; 6823e12c5d1SDavid du Colombier diag("%s: opcode out of range %d\n", pn, o); 6833e12c5d1SDavid du Colombier print(" probably not a .8 file\n"); 6843e12c5d1SDavid du Colombier errorexit(); 6853e12c5d1SDavid du Colombier } 6863e12c5d1SDavid du Colombier 6873e12c5d1SDavid du Colombier if(o == ANAME) { 688*219b2ee8SDavid du Colombier stop = memchr(&bloc[4], 0, bsize-&bloc[4]); 689*219b2ee8SDavid du Colombier if(stop == 0){ 690*219b2ee8SDavid du Colombier bsize = readsome(f, buf.xbuf, bloc, bsize, c); 691*219b2ee8SDavid du Colombier if(bsize == 0) 692*219b2ee8SDavid du Colombier goto eof; 693*219b2ee8SDavid du Colombier bloc = buf.xbuf; 694*219b2ee8SDavid du Colombier stop = memchr(&bloc[4], 0, bsize-&bloc[4]); 695*219b2ee8SDavid du Colombier if(stop == 0){ 696*219b2ee8SDavid du Colombier fprint(2, "%s: name too long\n", pn); 697*219b2ee8SDavid du Colombier errorexit(); 698*219b2ee8SDavid du Colombier } 699*219b2ee8SDavid du Colombier } 7003e12c5d1SDavid du Colombier v = bloc[2]; /* type */ 7013e12c5d1SDavid du Colombier o = bloc[3]; /* sym */ 7023e12c5d1SDavid du Colombier bloc += 4; 7033e12c5d1SDavid du Colombier c -= 4; 704*219b2ee8SDavid du Colombier 7053e12c5d1SDavid du Colombier r = 0; 7063e12c5d1SDavid du Colombier if(v == D_STATIC) 7073e12c5d1SDavid du Colombier r = version; 708*219b2ee8SDavid du Colombier s = lookup((char*)bloc, r); 709*219b2ee8SDavid du Colombier c -= &stop[1] - bloc; 710*219b2ee8SDavid du Colombier bloc = stop + 1; 711*219b2ee8SDavid du Colombier 7123e12c5d1SDavid du Colombier if(debug['W']) 7133e12c5d1SDavid du Colombier print(" ANAME %s\n", s->name); 7143e12c5d1SDavid du Colombier h[o] = s; 715*219b2ee8SDavid du Colombier if((v == D_EXTERN || v == D_STATIC) && s->type == 0) 7163e12c5d1SDavid du Colombier s->type = SXREF; 7173e12c5d1SDavid du Colombier if(v == D_FILE) { 7183e12c5d1SDavid du Colombier if(s->type != SFILE) { 7193e12c5d1SDavid du Colombier histgen++; 7203e12c5d1SDavid du Colombier s->type = SFILE; 7213e12c5d1SDavid du Colombier s->value = histgen; 7223e12c5d1SDavid du Colombier } 723*219b2ee8SDavid du Colombier if(histfrogp < MAXHIST) { 7243e12c5d1SDavid du Colombier histfrog[histfrogp] = s; 7253e12c5d1SDavid du Colombier histfrogp++; 726*219b2ee8SDavid du Colombier } else 727*219b2ee8SDavid du Colombier collapsefrog(s); 7283e12c5d1SDavid du Colombier } 7293e12c5d1SDavid du Colombier goto loop; 7303e12c5d1SDavid du Colombier } 7313e12c5d1SDavid du Colombier 7323e12c5d1SDavid du Colombier while(nhunk < sizeof(Prog)) 7333e12c5d1SDavid du Colombier gethunk(); 7343e12c5d1SDavid du Colombier p = (Prog*)hunk; 7353e12c5d1SDavid du Colombier nhunk -= sizeof(Prog); 7363e12c5d1SDavid du Colombier hunk += sizeof(Prog); 7373e12c5d1SDavid du Colombier 7383e12c5d1SDavid du Colombier p->as = o; 7393e12c5d1SDavid du Colombier p->line = bloc[2] | (bloc[3] << 8) | (bloc[4] << 16) | (bloc[5] << 24); 7403e12c5d1SDavid du Colombier p->back = 2; 7413e12c5d1SDavid du Colombier r = zaddr(bloc+6, &p->from, h) + 6; 7423e12c5d1SDavid du Colombier r += zaddr(bloc+r, &p->to, h); 7433e12c5d1SDavid du Colombier bloc += r; 7443e12c5d1SDavid du Colombier c -= r; 7453e12c5d1SDavid du Colombier 7463e12c5d1SDavid du Colombier if(debug['W']) 7473e12c5d1SDavid du Colombier print("%P\n", p); 7483e12c5d1SDavid du Colombier 7493e12c5d1SDavid du Colombier switch(p->as) { 7503e12c5d1SDavid du Colombier case AHISTORY: 7513e12c5d1SDavid du Colombier if(p->to.offset == -1) { 7523e12c5d1SDavid du Colombier addlib(p->line); 7533e12c5d1SDavid du Colombier histfrogp = 0; 7543e12c5d1SDavid du Colombier goto loop; 7553e12c5d1SDavid du Colombier } 756*219b2ee8SDavid du Colombier addhist(p->line, D_FILE); /* 'z' */ 7573e12c5d1SDavid du Colombier if(p->to.offset) 758*219b2ee8SDavid du Colombier addhist(p->to.offset, D_FILE1); /* 'Z' */ 7593e12c5d1SDavid du Colombier histfrogp = 0; 7603e12c5d1SDavid du Colombier goto loop; 7613e12c5d1SDavid du Colombier 7623e12c5d1SDavid du Colombier case AEND: 7633e12c5d1SDavid du Colombier histtoauto(); 7643e12c5d1SDavid du Colombier if(curtext != P) 7653e12c5d1SDavid du Colombier curtext->to.autom = curauto; 7663e12c5d1SDavid du Colombier curauto = 0; 7673e12c5d1SDavid du Colombier curtext = P; 7683e12c5d1SDavid du Colombier if(c) 7693e12c5d1SDavid du Colombier goto newloop; 7703e12c5d1SDavid du Colombier return; 7713e12c5d1SDavid du Colombier 7723e12c5d1SDavid du Colombier case AGLOBL: 7733e12c5d1SDavid du Colombier s = p->from.sym; 7743e12c5d1SDavid du Colombier if(s->type == 0 || s->type == SXREF) { 7753e12c5d1SDavid du Colombier s->type = SBSS; 7763e12c5d1SDavid du Colombier s->value = 0; 7773e12c5d1SDavid du Colombier } 7783e12c5d1SDavid du Colombier if(s->type != SBSS) { 7793e12c5d1SDavid du Colombier diag("%s: redefinition: %s in %s\n", 7803e12c5d1SDavid du Colombier pn, s->name, TNAME); 7813e12c5d1SDavid du Colombier s->type = SBSS; 7823e12c5d1SDavid du Colombier s->value = 0; 7833e12c5d1SDavid du Colombier } 7843e12c5d1SDavid du Colombier if(p->to.offset > s->value) 7853e12c5d1SDavid du Colombier s->value = p->to.offset; 7863e12c5d1SDavid du Colombier goto loop; 7873e12c5d1SDavid du Colombier 788*219b2ee8SDavid du Colombier case ADYNT: 789*219b2ee8SDavid du Colombier if(p->to.sym == S) { 790*219b2ee8SDavid du Colombier diag("DYNT without a sym\n%P\n", p); 791*219b2ee8SDavid du Colombier break; 792*219b2ee8SDavid du Colombier } 793*219b2ee8SDavid du Colombier di = p->to.sym; 794*219b2ee8SDavid du Colombier p->from.scale = 4; 795*219b2ee8SDavid du Colombier if(di->type == SXREF) { 796*219b2ee8SDavid du Colombier if(debug['z']) 797*219b2ee8SDavid du Colombier Bprint(&bso, "%P set to %d\n", p, dtype); 798*219b2ee8SDavid du Colombier di->type = SCONST; 799*219b2ee8SDavid du Colombier di->value = dtype; 800*219b2ee8SDavid du Colombier dtype += 4; 801*219b2ee8SDavid du Colombier } 802*219b2ee8SDavid du Colombier if(p->from.sym == S) 803*219b2ee8SDavid du Colombier break; 804*219b2ee8SDavid du Colombier 805*219b2ee8SDavid du Colombier p->from.offset = di->value; 806*219b2ee8SDavid du Colombier p->from.sym->type = SDATA; 807*219b2ee8SDavid du Colombier if(curtext == P) { 808*219b2ee8SDavid du Colombier diag("DYNT not in text: %P\n", p); 809*219b2ee8SDavid du Colombier break; 810*219b2ee8SDavid du Colombier } 811*219b2ee8SDavid du Colombier p->to.sym = curtext->from.sym; 812*219b2ee8SDavid du Colombier p->to.type = D_ADDR; 813*219b2ee8SDavid du Colombier p->to.index = D_EXTERN; 814*219b2ee8SDavid du Colombier goto data; 815*219b2ee8SDavid du Colombier 816*219b2ee8SDavid du Colombier case AINIT: 817*219b2ee8SDavid du Colombier if(p->from.sym == S) { 818*219b2ee8SDavid du Colombier diag("INIT without a sym\n%P\n", p); 819*219b2ee8SDavid du Colombier break; 820*219b2ee8SDavid du Colombier } 821*219b2ee8SDavid du Colombier if(di == S) { 822*219b2ee8SDavid du Colombier diag("INIT without previous DYNT\n%P\n", p); 823*219b2ee8SDavid du Colombier break; 824*219b2ee8SDavid du Colombier } 825*219b2ee8SDavid du Colombier p->from.offset = di->value; 826*219b2ee8SDavid du Colombier p->from.sym->type = SDATA; 827*219b2ee8SDavid du Colombier goto data; 828*219b2ee8SDavid du Colombier 8293e12c5d1SDavid du Colombier case ADATA: 830*219b2ee8SDavid du Colombier data: 8313e12c5d1SDavid du Colombier if(edatap == P) 8323e12c5d1SDavid du Colombier datap = p; 8333e12c5d1SDavid du Colombier else 8343e12c5d1SDavid du Colombier edatap->link = p; 8353e12c5d1SDavid du Colombier edatap = p; 8363e12c5d1SDavid du Colombier p->link = P; 8373e12c5d1SDavid du Colombier goto loop; 8383e12c5d1SDavid du Colombier 8393e12c5d1SDavid du Colombier case AGOK: 8403e12c5d1SDavid du Colombier diag("%s: GOK opcode in %s\n", pn, TNAME); 8413e12c5d1SDavid du Colombier pc++; 8423e12c5d1SDavid du Colombier goto loop; 8433e12c5d1SDavid du Colombier 8443e12c5d1SDavid du Colombier case ATEXT: 8453e12c5d1SDavid du Colombier if(curtext != P) { 8463e12c5d1SDavid du Colombier histtoauto(); 8473e12c5d1SDavid du Colombier curtext->to.autom = curauto; 8483e12c5d1SDavid du Colombier curauto = 0; 8493e12c5d1SDavid du Colombier } 850*219b2ee8SDavid du Colombier skip = 0; 8513e12c5d1SDavid du Colombier curtext = p; 8523e12c5d1SDavid du Colombier s = p->from.sym; 8533e12c5d1SDavid du Colombier if(s == S) { 8543e12c5d1SDavid du Colombier diag("%s: no TEXT symbol: %P\n", pn, p); 8553e12c5d1SDavid du Colombier errorexit(); 8563e12c5d1SDavid du Colombier } 857*219b2ee8SDavid du Colombier if(s->type != 0 && s->type != SXREF) { 858*219b2ee8SDavid du Colombier if(p->from.scale & DUPOK) { 859*219b2ee8SDavid du Colombier skip = 1; 860*219b2ee8SDavid du Colombier goto casdef; 861*219b2ee8SDavid du Colombier } 862*219b2ee8SDavid du Colombier diag("redefinition: %s\n%P\n", s->name, p); 863*219b2ee8SDavid du Colombier } 8643e12c5d1SDavid du Colombier s->type = STEXT; 865*219b2ee8SDavid du Colombier s->value = pc; 866*219b2ee8SDavid du Colombier lastp->link = p; 867*219b2ee8SDavid du Colombier lastp = p; 868*219b2ee8SDavid du Colombier p->pc = pc; 8693e12c5d1SDavid du Colombier pc++; 8703e12c5d1SDavid du Colombier if(textp == P) { 8713e12c5d1SDavid du Colombier textp = p; 8723e12c5d1SDavid du Colombier etextp = p; 8733e12c5d1SDavid du Colombier goto loop; 8743e12c5d1SDavid du Colombier } 8753e12c5d1SDavid du Colombier etextp->cond = p; 8763e12c5d1SDavid du Colombier etextp = p; 8773e12c5d1SDavid du Colombier goto loop; 8783e12c5d1SDavid du Colombier 8793e12c5d1SDavid du Colombier case AFMOVF: 8803e12c5d1SDavid du Colombier case AFADDF: 8813e12c5d1SDavid du Colombier case AFSUBF: 8823e12c5d1SDavid du Colombier case AFSUBRF: 8833e12c5d1SDavid du Colombier case AFMULF: 8843e12c5d1SDavid du Colombier case AFDIVF: 8853e12c5d1SDavid du Colombier case AFDIVRF: 8863e12c5d1SDavid du Colombier case AFCOMF: 8873e12c5d1SDavid du Colombier case AFCOMFP: 888*219b2ee8SDavid du Colombier if(skip) 889*219b2ee8SDavid du Colombier goto casdef; 8903e12c5d1SDavid du Colombier if(p->from.type == D_FCONST) { 8913e12c5d1SDavid du Colombier /* size sb 9 max */ 8923e12c5d1SDavid du Colombier sprint(literal, "$%lux", ieeedtof(&p->from.ieee)); 8933e12c5d1SDavid du Colombier s = lookup(literal, 0); 8943e12c5d1SDavid du Colombier if(s->type == 0) { 8953e12c5d1SDavid du Colombier s->type = SBSS; 8963e12c5d1SDavid du Colombier s->value = 4; 8973e12c5d1SDavid du Colombier t = prg(); 8983e12c5d1SDavid du Colombier t->as = ADATA; 8993e12c5d1SDavid du Colombier t->line = p->line; 9003e12c5d1SDavid du Colombier t->from.type = D_EXTERN; 9013e12c5d1SDavid du Colombier t->from.sym = s; 9023e12c5d1SDavid du Colombier t->from.scale = 4; 9033e12c5d1SDavid du Colombier t->to = p->from; 9043e12c5d1SDavid du Colombier if(edatap == P) 9053e12c5d1SDavid du Colombier datap = t; 9063e12c5d1SDavid du Colombier else 9073e12c5d1SDavid du Colombier edatap->link = t; 9083e12c5d1SDavid du Colombier edatap = t; 9093e12c5d1SDavid du Colombier t->link = P; 9103e12c5d1SDavid du Colombier } 9113e12c5d1SDavid du Colombier p->from.type = D_EXTERN; 9123e12c5d1SDavid du Colombier p->from.sym = s; 9133e12c5d1SDavid du Colombier p->from.offset = 0; 9143e12c5d1SDavid du Colombier } 9153e12c5d1SDavid du Colombier goto casdef; 9163e12c5d1SDavid du Colombier 9173e12c5d1SDavid du Colombier case AFMOVD: 9183e12c5d1SDavid du Colombier case AFADDD: 9193e12c5d1SDavid du Colombier case AFSUBD: 9203e12c5d1SDavid du Colombier case AFSUBRD: 9213e12c5d1SDavid du Colombier case AFMULD: 9223e12c5d1SDavid du Colombier case AFDIVD: 9233e12c5d1SDavid du Colombier case AFDIVRD: 9243e12c5d1SDavid du Colombier case AFCOMD: 9253e12c5d1SDavid du Colombier case AFCOMDP: 926*219b2ee8SDavid du Colombier if(skip) 927*219b2ee8SDavid du Colombier goto casdef; 9283e12c5d1SDavid du Colombier if(p->from.type == D_FCONST) { 9293e12c5d1SDavid du Colombier /* size sb 18 max */ 9303e12c5d1SDavid du Colombier sprint(literal, "$%lux.%lux", 9313e12c5d1SDavid du Colombier p->from.ieee.l, p->from.ieee.h); 9323e12c5d1SDavid du Colombier s = lookup(literal, 0); 9333e12c5d1SDavid du Colombier if(s->type == 0) { 9343e12c5d1SDavid du Colombier s->type = SBSS; 9353e12c5d1SDavid du Colombier s->value = 8; 9363e12c5d1SDavid du Colombier t = prg(); 9373e12c5d1SDavid du Colombier t->as = ADATA; 9383e12c5d1SDavid du Colombier t->line = p->line; 9393e12c5d1SDavid du Colombier t->from.type = D_EXTERN; 9403e12c5d1SDavid du Colombier t->from.sym = s; 9413e12c5d1SDavid du Colombier t->from.scale = 8; 9423e12c5d1SDavid du Colombier t->to = p->from; 9433e12c5d1SDavid du Colombier if(edatap == P) 9443e12c5d1SDavid du Colombier datap = t; 9453e12c5d1SDavid du Colombier else 9463e12c5d1SDavid du Colombier edatap->link = t; 9473e12c5d1SDavid du Colombier edatap = t; 9483e12c5d1SDavid du Colombier t->link = P; 9493e12c5d1SDavid du Colombier } 9503e12c5d1SDavid du Colombier p->from.type = D_EXTERN; 9513e12c5d1SDavid du Colombier p->from.sym = s; 9523e12c5d1SDavid du Colombier p->from.offset = 0; 9533e12c5d1SDavid du Colombier } 9543e12c5d1SDavid du Colombier goto casdef; 9553e12c5d1SDavid du Colombier 9563e12c5d1SDavid du Colombier case AADDL: 9573e12c5d1SDavid du Colombier if(p->from.type == D_CONST) 9583e12c5d1SDavid du Colombier if(p->from.offset < 0) { 9593e12c5d1SDavid du Colombier p->as = ASUBL; 9603e12c5d1SDavid du Colombier p->from.offset = -p->from.offset; 9613e12c5d1SDavid du Colombier } 9623e12c5d1SDavid du Colombier goto casdef; 9633e12c5d1SDavid du Colombier 9643e12c5d1SDavid du Colombier case ASUBL: 9653e12c5d1SDavid du Colombier if(p->from.type == D_CONST) 9663e12c5d1SDavid du Colombier if(p->from.offset < 0) { 9673e12c5d1SDavid du Colombier p->as = AADDL; 9683e12c5d1SDavid du Colombier p->from.offset = -p->from.offset; 9693e12c5d1SDavid du Colombier } 9703e12c5d1SDavid du Colombier goto casdef; 9713e12c5d1SDavid du Colombier 9723e12c5d1SDavid du Colombier casdef: 9733e12c5d1SDavid du Colombier default: 974*219b2ee8SDavid du Colombier if(skip) 975*219b2ee8SDavid du Colombier nopout(p); 976*219b2ee8SDavid du Colombier 9773e12c5d1SDavid du Colombier if(p->to.type == D_BRANCH) 9783e12c5d1SDavid du Colombier p->to.offset += ipc; 9793e12c5d1SDavid du Colombier lastp->link = p; 9803e12c5d1SDavid du Colombier lastp = p; 9813e12c5d1SDavid du Colombier p->pc = pc; 9823e12c5d1SDavid du Colombier pc++; 9833e12c5d1SDavid du Colombier goto loop; 9843e12c5d1SDavid du Colombier } 9853e12c5d1SDavid du Colombier goto loop; 9863e12c5d1SDavid du Colombier 9873e12c5d1SDavid du Colombier eof: 9883e12c5d1SDavid du Colombier diag("truncated object file: %s\n", pn); 9893e12c5d1SDavid du Colombier } 9903e12c5d1SDavid du Colombier 9913e12c5d1SDavid du Colombier Sym* 9923e12c5d1SDavid du Colombier lookup(char *symb, int v) 9933e12c5d1SDavid du Colombier { 9943e12c5d1SDavid du Colombier Sym *s; 9953e12c5d1SDavid du Colombier char *p; 9963e12c5d1SDavid du Colombier long h; 997*219b2ee8SDavid du Colombier int l, c; 9983e12c5d1SDavid du Colombier 9993e12c5d1SDavid du Colombier h = v; 1000*219b2ee8SDavid du Colombier for(p=symb; c = *p; p++) 10013e12c5d1SDavid du Colombier h = h+h+h + c; 1002*219b2ee8SDavid du Colombier l = (p - symb) + 1; 10033e12c5d1SDavid du Colombier if(h < 0) 10043e12c5d1SDavid du Colombier h = ~h; 10053e12c5d1SDavid du Colombier h %= NHASH; 1006*219b2ee8SDavid du Colombier for(s = hash[h]; s != S; s = s->link) 10073e12c5d1SDavid du Colombier if(s->version == v) 1008*219b2ee8SDavid du Colombier if(memcmp(s->name, symb, l) == 0) 10093e12c5d1SDavid du Colombier return s; 10103e12c5d1SDavid du Colombier 10113e12c5d1SDavid du Colombier while(nhunk < sizeof(Sym)) 10123e12c5d1SDavid du Colombier gethunk(); 10133e12c5d1SDavid du Colombier s = (Sym*)hunk; 10143e12c5d1SDavid du Colombier nhunk -= sizeof(Sym); 10153e12c5d1SDavid du Colombier hunk += sizeof(Sym); 10163e12c5d1SDavid du Colombier 1017*219b2ee8SDavid du Colombier s->name = malloc(l + 1); 1018*219b2ee8SDavid du Colombier memmove(s->name, symb, l); 1019*219b2ee8SDavid du Colombier 10203e12c5d1SDavid du Colombier s->link = hash[h]; 10213e12c5d1SDavid du Colombier s->type = 0; 10223e12c5d1SDavid du Colombier s->version = v; 10233e12c5d1SDavid du Colombier s->value = 0; 10243e12c5d1SDavid du Colombier hash[h] = s; 10253e12c5d1SDavid du Colombier nsymbol++; 10263e12c5d1SDavid du Colombier return s; 10273e12c5d1SDavid du Colombier } 10283e12c5d1SDavid du Colombier 10293e12c5d1SDavid du Colombier Prog* 10303e12c5d1SDavid du Colombier prg(void) 10313e12c5d1SDavid du Colombier { 10323e12c5d1SDavid du Colombier Prog *p; 10333e12c5d1SDavid du Colombier 10343e12c5d1SDavid du Colombier while(nhunk < sizeof(Prog)) 10353e12c5d1SDavid du Colombier gethunk(); 10363e12c5d1SDavid du Colombier p = (Prog*)hunk; 10373e12c5d1SDavid du Colombier nhunk -= sizeof(Prog); 10383e12c5d1SDavid du Colombier hunk += sizeof(Prog); 10393e12c5d1SDavid du Colombier 10403e12c5d1SDavid du Colombier *p = zprg; 10413e12c5d1SDavid du Colombier return p; 10423e12c5d1SDavid du Colombier } 10433e12c5d1SDavid du Colombier 10443e12c5d1SDavid du Colombier Prog* 10453e12c5d1SDavid du Colombier copyp(Prog *q) 10463e12c5d1SDavid du Colombier { 10473e12c5d1SDavid du Colombier Prog *p; 10483e12c5d1SDavid du Colombier 10493e12c5d1SDavid du Colombier p = prg(); 10503e12c5d1SDavid du Colombier *p = *q; 10513e12c5d1SDavid du Colombier return p; 10523e12c5d1SDavid du Colombier } 10533e12c5d1SDavid du Colombier 10543e12c5d1SDavid du Colombier Prog* 10553e12c5d1SDavid du Colombier appendp(Prog *q) 10563e12c5d1SDavid du Colombier { 10573e12c5d1SDavid du Colombier Prog *p; 10583e12c5d1SDavid du Colombier 10593e12c5d1SDavid du Colombier p = prg(); 10603e12c5d1SDavid du Colombier p->link = q->link; 10613e12c5d1SDavid du Colombier q->link = p; 10623e12c5d1SDavid du Colombier p->line = q->line; 10633e12c5d1SDavid du Colombier return p; 10643e12c5d1SDavid du Colombier } 10653e12c5d1SDavid du Colombier 10663e12c5d1SDavid du Colombier void 10673e12c5d1SDavid du Colombier gethunk(void) 10683e12c5d1SDavid du Colombier { 10693e12c5d1SDavid du Colombier char *h; 10703e12c5d1SDavid du Colombier long nh; 10713e12c5d1SDavid du Colombier 10723e12c5d1SDavid du Colombier nh = NHUNK; 10733e12c5d1SDavid du Colombier if(thunk >= 5L*NHUNK) { 10743e12c5d1SDavid du Colombier nh = 5L*NHUNK; 10753e12c5d1SDavid du Colombier if(thunk >= 25L*NHUNK) 10763e12c5d1SDavid du Colombier nh = 25L*NHUNK; 10773e12c5d1SDavid du Colombier } 10783e12c5d1SDavid du Colombier h = sbrk(nh); 10793e12c5d1SDavid du Colombier if(h == (char*)-1) { 10803e12c5d1SDavid du Colombier diag("out of memory\n"); 10813e12c5d1SDavid du Colombier errorexit(); 10823e12c5d1SDavid du Colombier } 10833e12c5d1SDavid du Colombier hunk = h; 10843e12c5d1SDavid du Colombier nhunk = nh; 10853e12c5d1SDavid du Colombier thunk += nh; 10863e12c5d1SDavid du Colombier } 10873e12c5d1SDavid du Colombier 10883e12c5d1SDavid du Colombier void 10893e12c5d1SDavid du Colombier doprof1(void) 10903e12c5d1SDavid du Colombier { 10913e12c5d1SDavid du Colombier Sym *s; 10923e12c5d1SDavid du Colombier long n; 10933e12c5d1SDavid du Colombier Prog *p, *q; 10943e12c5d1SDavid du Colombier 10953e12c5d1SDavid du Colombier if(debug['v']) 10963e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f profile 1\n", cputime()); 10973e12c5d1SDavid du Colombier Bflush(&bso); 10983e12c5d1SDavid du Colombier s = lookup("__mcount", 0); 10993e12c5d1SDavid du Colombier n = 1; 11003e12c5d1SDavid du Colombier for(p = firstp->link; p != P; p = p->link) { 11013e12c5d1SDavid du Colombier if(p->as == ATEXT) { 11023e12c5d1SDavid du Colombier q = prg(); 11033e12c5d1SDavid du Colombier q->line = p->line; 11043e12c5d1SDavid du Colombier q->link = datap; 11053e12c5d1SDavid du Colombier datap = q; 11063e12c5d1SDavid du Colombier q->as = ADATA; 11073e12c5d1SDavid du Colombier q->from.type = D_EXTERN; 11083e12c5d1SDavid du Colombier q->from.offset = n*4; 11093e12c5d1SDavid du Colombier q->from.sym = s; 11103e12c5d1SDavid du Colombier q->from.scale = 4; 11113e12c5d1SDavid du Colombier q->to = p->from; 11123e12c5d1SDavid du Colombier q->to.type = D_CONST; 11133e12c5d1SDavid du Colombier 11143e12c5d1SDavid du Colombier q = prg(); 11153e12c5d1SDavid du Colombier q->line = p->line; 11163e12c5d1SDavid du Colombier q->pc = p->pc; 11173e12c5d1SDavid du Colombier q->link = p->link; 11183e12c5d1SDavid du Colombier p->link = q; 11193e12c5d1SDavid du Colombier p = q; 11203e12c5d1SDavid du Colombier p->as = AADDL; 11213e12c5d1SDavid du Colombier p->from.type = D_CONST; 11223e12c5d1SDavid du Colombier p->from.offset = 1; 11233e12c5d1SDavid du Colombier p->to.type = D_EXTERN; 11243e12c5d1SDavid du Colombier p->to.sym = s; 11253e12c5d1SDavid du Colombier p->to.offset = n*4 + 4; 11263e12c5d1SDavid du Colombier 11273e12c5d1SDavid du Colombier n += 2; 11283e12c5d1SDavid du Colombier continue; 11293e12c5d1SDavid du Colombier } 11303e12c5d1SDavid du Colombier } 11313e12c5d1SDavid du Colombier q = prg(); 11323e12c5d1SDavid du Colombier q->line = 0; 11333e12c5d1SDavid du Colombier q->link = datap; 11343e12c5d1SDavid du Colombier datap = q; 11353e12c5d1SDavid du Colombier 11363e12c5d1SDavid du Colombier q->as = ADATA; 11373e12c5d1SDavid du Colombier q->from.type = D_EXTERN; 11383e12c5d1SDavid du Colombier q->from.sym = s; 11393e12c5d1SDavid du Colombier q->from.scale = 4; 11403e12c5d1SDavid du Colombier q->to.type = D_CONST; 11413e12c5d1SDavid du Colombier q->to.offset = n; 11423e12c5d1SDavid du Colombier 11433e12c5d1SDavid du Colombier s->type = SBSS; 11443e12c5d1SDavid du Colombier s->value = n*4; 11453e12c5d1SDavid du Colombier } 11463e12c5d1SDavid du Colombier 11473e12c5d1SDavid du Colombier void 11483e12c5d1SDavid du Colombier doprof2(void) 11493e12c5d1SDavid du Colombier { 11503e12c5d1SDavid du Colombier Sym *s2, *s4; 11513e12c5d1SDavid du Colombier Prog *p, *q, *ps2, *ps4; 11523e12c5d1SDavid du Colombier 11533e12c5d1SDavid du Colombier if(debug['v']) 11543e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f profile 2\n", cputime()); 11553e12c5d1SDavid du Colombier Bflush(&bso); 11563e12c5d1SDavid du Colombier 11573e12c5d1SDavid du Colombier s2 = lookup("_profin", 0); 11583e12c5d1SDavid du Colombier s4 = lookup("_profout", 0); 11593e12c5d1SDavid du Colombier 11603e12c5d1SDavid du Colombier ps2 = P; 11613e12c5d1SDavid du Colombier ps4 = P; 11623e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) { 11633e12c5d1SDavid du Colombier if(p->as == ATEXT) { 11643e12c5d1SDavid du Colombier if(p->from.sym == s2) { 11653e12c5d1SDavid du Colombier p->from.scale = 1; 11663e12c5d1SDavid du Colombier ps2 = p; 11673e12c5d1SDavid du Colombier } 11683e12c5d1SDavid du Colombier if(p->from.sym == s4) { 11693e12c5d1SDavid du Colombier p->from.scale = 1; 11703e12c5d1SDavid du Colombier ps4 = p; 11713e12c5d1SDavid du Colombier } 11723e12c5d1SDavid du Colombier } 11733e12c5d1SDavid du Colombier } 11743e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) { 11753e12c5d1SDavid du Colombier if(p->as == ATEXT) { 11763e12c5d1SDavid du Colombier curtext = p; 11773e12c5d1SDavid du Colombier 1178*219b2ee8SDavid du Colombier if(p->from.scale & NOPROF) { /* dont profile */ 11793e12c5d1SDavid du Colombier for(;;) { 11803e12c5d1SDavid du Colombier q = p->link; 11813e12c5d1SDavid du Colombier if(q == P) 11823e12c5d1SDavid du Colombier break; 11833e12c5d1SDavid du Colombier if(q->as == ATEXT) 11843e12c5d1SDavid du Colombier break; 11853e12c5d1SDavid du Colombier p = q; 11863e12c5d1SDavid du Colombier } 11873e12c5d1SDavid du Colombier continue; 11883e12c5d1SDavid du Colombier } 11893e12c5d1SDavid du Colombier 11903e12c5d1SDavid du Colombier /* 11913e12c5d1SDavid du Colombier * JMPL profin 11923e12c5d1SDavid du Colombier */ 11933e12c5d1SDavid du Colombier q = prg(); 11943e12c5d1SDavid du Colombier q->line = p->line; 11953e12c5d1SDavid du Colombier q->pc = p->pc; 11963e12c5d1SDavid du Colombier q->link = p->link; 11973e12c5d1SDavid du Colombier p->link = q; 11983e12c5d1SDavid du Colombier p = q; 11993e12c5d1SDavid du Colombier p->as = ACALL; 12003e12c5d1SDavid du Colombier p->to.type = D_BRANCH; 12013e12c5d1SDavid du Colombier p->cond = ps2; 12023e12c5d1SDavid du Colombier p->to.sym = s2; 12033e12c5d1SDavid du Colombier 12043e12c5d1SDavid du Colombier continue; 12053e12c5d1SDavid du Colombier } 12063e12c5d1SDavid du Colombier if(p->as == ARET) { 1207*219b2ee8SDavid du Colombier /* 1208*219b2ee8SDavid du Colombier * RET 1209*219b2ee8SDavid du Colombier */ 1210*219b2ee8SDavid du Colombier q = prg(); 1211*219b2ee8SDavid du Colombier q->as = ARET; 1212*219b2ee8SDavid du Colombier q->from = p->from; 1213*219b2ee8SDavid du Colombier q->to = p->to; 1214*219b2ee8SDavid du Colombier q->link = p->link; 1215*219b2ee8SDavid du Colombier p->link = q; 12163e12c5d1SDavid du Colombier 12173e12c5d1SDavid du Colombier /* 1218*219b2ee8SDavid du Colombier * JAL profout 12193e12c5d1SDavid du Colombier */ 12203e12c5d1SDavid du Colombier p->as = ACALL; 12213e12c5d1SDavid du Colombier p->from = zprg.from; 12223e12c5d1SDavid du Colombier p->to = zprg.to; 12233e12c5d1SDavid du Colombier p->to.type = D_BRANCH; 12243e12c5d1SDavid du Colombier p->cond = ps4; 12253e12c5d1SDavid du Colombier p->to.sym = s4; 12263e12c5d1SDavid du Colombier 12273e12c5d1SDavid du Colombier p = q; 12283e12c5d1SDavid du Colombier 12293e12c5d1SDavid du Colombier continue; 12303e12c5d1SDavid du Colombier } 12313e12c5d1SDavid du Colombier } 12323e12c5d1SDavid du Colombier } 12333e12c5d1SDavid du Colombier 12343e12c5d1SDavid du Colombier void 12353e12c5d1SDavid du Colombier nuxiinit(void) 12363e12c5d1SDavid du Colombier { 12373e12c5d1SDavid du Colombier int i, c; 12383e12c5d1SDavid du Colombier 12393e12c5d1SDavid du Colombier for(i=0; i<4; i++) { 12403e12c5d1SDavid du Colombier c = find1(0x04030201L, i+1); 12413e12c5d1SDavid du Colombier if(i < 2) 12423e12c5d1SDavid du Colombier inuxi2[i] = c; 12433e12c5d1SDavid du Colombier if(i < 1) 12443e12c5d1SDavid du Colombier inuxi1[i] = c; 12453e12c5d1SDavid du Colombier inuxi4[i] = c; 12463e12c5d1SDavid du Colombier fnuxi4[i] = c; 12473e12c5d1SDavid du Colombier fnuxi8[i] = c; 12483e12c5d1SDavid du Colombier fnuxi8[i+4] = c+4; 12493e12c5d1SDavid du Colombier } 12503e12c5d1SDavid du Colombier if(debug['v']) { 12513e12c5d1SDavid du Colombier Bprint(&bso, "inuxi = "); 12523e12c5d1SDavid du Colombier for(i=0; i<1; i++) 12533e12c5d1SDavid du Colombier Bprint(&bso, "%d", inuxi1[i]); 12543e12c5d1SDavid du Colombier Bprint(&bso, " "); 12553e12c5d1SDavid du Colombier for(i=0; i<2; i++) 12563e12c5d1SDavid du Colombier Bprint(&bso, "%d", inuxi2[i]); 12573e12c5d1SDavid du Colombier Bprint(&bso, " "); 12583e12c5d1SDavid du Colombier for(i=0; i<4; i++) 12593e12c5d1SDavid du Colombier Bprint(&bso, "%d", inuxi4[i]); 12603e12c5d1SDavid du Colombier Bprint(&bso, "\nfnuxi = "); 12613e12c5d1SDavid du Colombier for(i=0; i<4; i++) 12623e12c5d1SDavid du Colombier Bprint(&bso, "%d", fnuxi4[i]); 12633e12c5d1SDavid du Colombier Bprint(&bso, " "); 12643e12c5d1SDavid du Colombier for(i=0; i<8; i++) 12653e12c5d1SDavid du Colombier Bprint(&bso, "%d", fnuxi8[i]); 12663e12c5d1SDavid du Colombier Bprint(&bso, "\n"); 12673e12c5d1SDavid du Colombier } 12683e12c5d1SDavid du Colombier Bflush(&bso); 12693e12c5d1SDavid du Colombier } 12703e12c5d1SDavid du Colombier 12713e12c5d1SDavid du Colombier int 12723e12c5d1SDavid du Colombier find1(long l, int c) 12733e12c5d1SDavid du Colombier { 12743e12c5d1SDavid du Colombier char *p; 12753e12c5d1SDavid du Colombier int i; 12763e12c5d1SDavid du Colombier 12773e12c5d1SDavid du Colombier p = (char*)&l; 12783e12c5d1SDavid du Colombier for(i=0; i<4; i++) 12793e12c5d1SDavid du Colombier if(*p++ == c) 12803e12c5d1SDavid du Colombier return i; 12813e12c5d1SDavid du Colombier return 0; 12823e12c5d1SDavid du Colombier } 12833e12c5d1SDavid du Colombier 12843e12c5d1SDavid du Colombier int 12853e12c5d1SDavid du Colombier find2(long l, int c) 12863e12c5d1SDavid du Colombier { 12873e12c5d1SDavid du Colombier short *p; 12883e12c5d1SDavid du Colombier int i; 12893e12c5d1SDavid du Colombier 12903e12c5d1SDavid du Colombier p = (short*)&l; 12913e12c5d1SDavid du Colombier for(i=0; i<4; i+=2) { 12923e12c5d1SDavid du Colombier if(((*p >> 8) & 0xff) == c) 12933e12c5d1SDavid du Colombier return i; 12943e12c5d1SDavid du Colombier if((*p++ & 0xff) == c) 12953e12c5d1SDavid du Colombier return i+1; 12963e12c5d1SDavid du Colombier } 12973e12c5d1SDavid du Colombier return 0; 12983e12c5d1SDavid du Colombier } 12993e12c5d1SDavid du Colombier 13003e12c5d1SDavid du Colombier long 13013e12c5d1SDavid du Colombier ieeedtof(Ieee *e) 13023e12c5d1SDavid du Colombier { 13033e12c5d1SDavid du Colombier int exp; 13043e12c5d1SDavid du Colombier long v; 13053e12c5d1SDavid du Colombier 13063e12c5d1SDavid du Colombier if(e->h == 0) 13073e12c5d1SDavid du Colombier return 0; 13083e12c5d1SDavid du Colombier exp = (e->h>>20) & ((1L<<11)-1L); 13093e12c5d1SDavid du Colombier exp -= (1L<<10) - 2L; 13103e12c5d1SDavid du Colombier v = (e->h & 0xfffffL) << 3; 13113e12c5d1SDavid du Colombier v |= (e->l >> 29) & 0x7L; 13123e12c5d1SDavid du Colombier if((e->l >> 28) & 1) { 13133e12c5d1SDavid du Colombier v++; 13143e12c5d1SDavid du Colombier if(v & 0x800000L) { 13153e12c5d1SDavid du Colombier v = (v & 0x7fffffL) >> 1; 13163e12c5d1SDavid du Colombier exp++; 13173e12c5d1SDavid du Colombier } 13183e12c5d1SDavid du Colombier } 13193e12c5d1SDavid du Colombier if(exp <= -126 || exp >= 130) 13203e12c5d1SDavid du Colombier diag("double fp to single fp overflow\n"); 13213e12c5d1SDavid du Colombier v |= ((exp + 126) & 0xffL) << 23; 13223e12c5d1SDavid du Colombier v |= e->h & 0x80000000L; 13233e12c5d1SDavid du Colombier return v; 13243e12c5d1SDavid du Colombier } 13253e12c5d1SDavid du Colombier 13263e12c5d1SDavid du Colombier double 13273e12c5d1SDavid du Colombier ieeedtod(Ieee *ieee) 13283e12c5d1SDavid du Colombier { 13293e12c5d1SDavid du Colombier Ieee e; 13303e12c5d1SDavid du Colombier double fr; 13313e12c5d1SDavid du Colombier int exp; 13323e12c5d1SDavid du Colombier 13333e12c5d1SDavid du Colombier if(ieee->h & (1L<<31)) { 13343e12c5d1SDavid du Colombier e.h = ieee->h & ~(1L<<31); 13353e12c5d1SDavid du Colombier e.l = ieee->l; 13363e12c5d1SDavid du Colombier return -ieeedtod(&e); 13373e12c5d1SDavid du Colombier } 13383e12c5d1SDavid du Colombier if(ieee->l == 0 && ieee->h == 0) 13393e12c5d1SDavid du Colombier return 0; 13403e12c5d1SDavid du Colombier fr = ieee->l & ((1L<<16)-1L); 13413e12c5d1SDavid du Colombier fr /= 1L<<16; 13423e12c5d1SDavid du Colombier fr += (ieee->l>>16) & ((1L<<16)-1L); 13433e12c5d1SDavid du Colombier fr /= 1L<<16; 13443e12c5d1SDavid du Colombier fr += (ieee->h & (1L<<20)-1L) | (1L<<20); 13453e12c5d1SDavid du Colombier fr /= 1L<<21; 13463e12c5d1SDavid du Colombier exp = (ieee->h>>20) & ((1L<<11)-1L); 13473e12c5d1SDavid du Colombier exp -= (1L<<10) - 2L; 13483e12c5d1SDavid du Colombier return ldexp(fr, exp); 13493e12c5d1SDavid du Colombier } 13503e12c5d1SDavid du Colombier 13513e12c5d1SDavid du Colombier /* 13523e12c5d1SDavid du Colombier * fake malloc 13533e12c5d1SDavid du Colombier */ 13543e12c5d1SDavid du Colombier void* 13553e12c5d1SDavid du Colombier malloc(long n) 13563e12c5d1SDavid du Colombier { 13573e12c5d1SDavid du Colombier void *p; 13583e12c5d1SDavid du Colombier 1359*219b2ee8SDavid du Colombier while(n & 7) 13603e12c5d1SDavid du Colombier n++; 13613e12c5d1SDavid du Colombier while(nhunk < n) 13623e12c5d1SDavid du Colombier gethunk(); 13633e12c5d1SDavid du Colombier p = hunk; 13643e12c5d1SDavid du Colombier nhunk -= n; 13653e12c5d1SDavid du Colombier hunk += n; 13663e12c5d1SDavid du Colombier return p; 13673e12c5d1SDavid du Colombier } 13683e12c5d1SDavid du Colombier 13693e12c5d1SDavid du Colombier void 13703e12c5d1SDavid du Colombier free(void *p) 13713e12c5d1SDavid du Colombier { 13723e12c5d1SDavid du Colombier USED(p); 13733e12c5d1SDavid du Colombier } 13743e12c5d1SDavid du Colombier 13753e12c5d1SDavid du Colombier void* 13763e12c5d1SDavid du Colombier calloc(long m, long n) 13773e12c5d1SDavid du Colombier { 13783e12c5d1SDavid du Colombier void *p; 13793e12c5d1SDavid du Colombier 13803e12c5d1SDavid du Colombier n *= m; 13813e12c5d1SDavid du Colombier p = malloc(n); 13823e12c5d1SDavid du Colombier memset(p, 0, n); 13833e12c5d1SDavid du Colombier return p; 13843e12c5d1SDavid du Colombier } 13853e12c5d1SDavid du Colombier 13863e12c5d1SDavid du Colombier void* 13873e12c5d1SDavid du Colombier realloc(void *p, long n) 13883e12c5d1SDavid du Colombier { 13893e12c5d1SDavid du Colombier fprint(2, "realloc called\n", p, n); 13903e12c5d1SDavid du Colombier abort(); 13913e12c5d1SDavid du Colombier return 0; 13923e12c5d1SDavid du Colombier } 1393