17dd7cddfSDavid du Colombier #define EXTERN 23e12c5d1SDavid du Colombier #include "l.h" 33e12c5d1SDavid du Colombier #include <ar.h> 43e12c5d1SDavid du Colombier 53e12c5d1SDavid du Colombier #ifndef DEFAULT 63e12c5d1SDavid du Colombier #define DEFAULT '9' 73e12c5d1SDavid du Colombier #endif 83e12c5d1SDavid du Colombier 93e12c5d1SDavid du Colombier char *noname = "<none>"; 103e12c5d1SDavid du Colombier char symname[] = SYMDEF; 11219b2ee8SDavid du Colombier char thechar = '8'; 12219b2ee8SDavid du Colombier char *thestring = "386"; 133e12c5d1SDavid du Colombier 143e12c5d1SDavid du Colombier /* 153e12c5d1SDavid du Colombier * -H0 -T0x40004C -D0x10000000 is garbage unix 163e12c5d1SDavid du Colombier * -H1 -T0xd0 -R4 is unix coff 173e12c5d1SDavid du Colombier * -H2 -T4128 -R4096 is plan9 format 18219b2ee8SDavid du Colombier * -H3 -Tx -Rx is MS-DOS .COM 19219b2ee8SDavid du Colombier * -H4 -Tx -Rx is fake MS-DOS .EXE 203e12c5d1SDavid du Colombier */ 213e12c5d1SDavid du Colombier 22*375daca8SDavid du Colombier static int 23*375daca8SDavid du Colombier isobjfile(char *f) 24*375daca8SDavid du Colombier { 25*375daca8SDavid du Colombier int n, v; 26*375daca8SDavid du Colombier Biobuf *b; 27*375daca8SDavid du Colombier char buf1[5], buf2[SARMAG]; 28*375daca8SDavid du Colombier 29*375daca8SDavid du Colombier b = Bopen(f, OREAD); 30*375daca8SDavid du Colombier if(b == nil) 31*375daca8SDavid du Colombier return 0; 32*375daca8SDavid du Colombier n = Bread(b, buf1, 5); 33*375daca8SDavid du Colombier if(n == 5 && (buf1[2] == 1 && buf1[3] == '<' || buf1[3] == 1 && buf1[4] == '<')) 34*375daca8SDavid du Colombier v = 1; /* good enough for our purposes */ 35*375daca8SDavid du Colombier else{ 36*375daca8SDavid du Colombier Bseek(b, 0, 0); 37*375daca8SDavid du Colombier n = Bread(b, buf2, SARMAG); 38*375daca8SDavid du Colombier v = n == SARMAG && strncmp(buf2, ARMAG, SARMAG) == 0; 39*375daca8SDavid du Colombier } 40*375daca8SDavid du Colombier Bterm(b); 41*375daca8SDavid du Colombier return v; 42*375daca8SDavid du Colombier } 43*375daca8SDavid du Colombier 443e12c5d1SDavid du Colombier void 453e12c5d1SDavid du Colombier main(int argc, char *argv[]) 463e12c5d1SDavid du Colombier { 473e12c5d1SDavid du Colombier int i, c; 483e12c5d1SDavid du Colombier char *a; 493e12c5d1SDavid du Colombier 503e12c5d1SDavid du Colombier Binit(&bso, 1, OWRITE); 513e12c5d1SDavid du Colombier cout = -1; 523e12c5d1SDavid du Colombier listinit(); 533e12c5d1SDavid du Colombier memset(debug, 0, sizeof(debug)); 543e12c5d1SDavid du Colombier nerrors = 0; 553e12c5d1SDavid du Colombier outfile = "8.out"; 563e12c5d1SDavid du Colombier HEADTYPE = -1; 573e12c5d1SDavid du Colombier INITTEXT = -1; 583e12c5d1SDavid du Colombier INITDAT = -1; 593e12c5d1SDavid du Colombier INITRND = -1; 603e12c5d1SDavid du Colombier INITENTRY = 0; 613e12c5d1SDavid du Colombier ARGBEGIN { 623e12c5d1SDavid du Colombier default: 633e12c5d1SDavid du Colombier c = ARGC(); 643e12c5d1SDavid du Colombier if(c >= 0 && c < sizeof(debug)) 653e12c5d1SDavid du Colombier debug[c]++; 663e12c5d1SDavid du Colombier break; 673e12c5d1SDavid du Colombier case 'o': /* output to (next arg) */ 683e12c5d1SDavid du Colombier outfile = ARGF(); 693e12c5d1SDavid du Colombier break; 703e12c5d1SDavid du Colombier case 'E': 713e12c5d1SDavid du Colombier a = ARGF(); 723e12c5d1SDavid du Colombier if(a) 733e12c5d1SDavid du Colombier INITENTRY = a; 743e12c5d1SDavid du Colombier break; 753e12c5d1SDavid du Colombier case 'H': 763e12c5d1SDavid du Colombier a = ARGF(); 773e12c5d1SDavid du Colombier if(a) 783e12c5d1SDavid du Colombier HEADTYPE = atolwhex(a); 793e12c5d1SDavid du Colombier break; 803e12c5d1SDavid du Colombier case 'T': 813e12c5d1SDavid du Colombier a = ARGF(); 823e12c5d1SDavid du Colombier if(a) 833e12c5d1SDavid du Colombier INITTEXT = atolwhex(a); 843e12c5d1SDavid du Colombier break; 853e12c5d1SDavid du Colombier case 'D': 863e12c5d1SDavid du Colombier a = ARGF(); 873e12c5d1SDavid du Colombier if(a) 883e12c5d1SDavid du Colombier INITDAT = atolwhex(a); 893e12c5d1SDavid du Colombier break; 903e12c5d1SDavid du Colombier case 'R': 913e12c5d1SDavid du Colombier a = ARGF(); 923e12c5d1SDavid du Colombier if(a) 933e12c5d1SDavid du Colombier INITRND = atolwhex(a); 943e12c5d1SDavid du Colombier break; 95*375daca8SDavid du Colombier case 'x': /* produce export table */ 96*375daca8SDavid du Colombier doexp = 1; 97*375daca8SDavid du Colombier if(argv[1] != nil && argv[1][0] != '-' && !isobjfile(argv[1])) 98*375daca8SDavid du Colombier readundefs(ARGF(), SEXPORT); 99*375daca8SDavid du Colombier break; 100*375daca8SDavid du Colombier case 'u': /* produce dynamically loadable module */ 101*375daca8SDavid du Colombier dlm = 1; 102*375daca8SDavid du Colombier debug['l']++; 103*375daca8SDavid du Colombier if(argv[1] != nil && argv[1][0] != '-' && !isobjfile(argv[1])) 104*375daca8SDavid du Colombier readundefs(ARGF(), SIMPORT); 105*375daca8SDavid du Colombier break; 1063e12c5d1SDavid du Colombier } ARGEND 1073e12c5d1SDavid du Colombier USED(argc); 1083e12c5d1SDavid du Colombier if(*argv == 0) { 1096b6b9ac8SDavid du Colombier diag("usage: 8l [-options] objects"); 1103e12c5d1SDavid du Colombier errorexit(); 1113e12c5d1SDavid du Colombier } 1123e12c5d1SDavid du Colombier if(!debug['9'] && !debug['U'] && !debug['B']) 1133e12c5d1SDavid du Colombier debug[DEFAULT] = 1; 1143e12c5d1SDavid du Colombier if(HEADTYPE == -1) { 1153e12c5d1SDavid du Colombier if(debug['U']) 1163e12c5d1SDavid du Colombier HEADTYPE = 1; 1173e12c5d1SDavid du Colombier if(debug['B']) 1183e12c5d1SDavid du Colombier HEADTYPE = 2; 1193e12c5d1SDavid du Colombier if(debug['9']) 1203e12c5d1SDavid du Colombier HEADTYPE = 2; 1213e12c5d1SDavid du Colombier } 1223e12c5d1SDavid du Colombier switch(HEADTYPE) { 1233e12c5d1SDavid du Colombier default: 1243e12c5d1SDavid du Colombier diag("unknown -H option"); 1253e12c5d1SDavid du Colombier errorexit(); 1263e12c5d1SDavid du Colombier 1273e12c5d1SDavid du Colombier case 0: /* this is garbage */ 1283e12c5d1SDavid du Colombier HEADR = 20L+56L; 1293e12c5d1SDavid du Colombier if(INITTEXT == -1) 1303e12c5d1SDavid du Colombier INITTEXT = 0x40004CL; 1313e12c5d1SDavid du Colombier if(INITDAT == -1) 1323e12c5d1SDavid du Colombier INITDAT = 0x10000000L; 1333e12c5d1SDavid du Colombier if(INITRND == -1) 1343e12c5d1SDavid du Colombier INITRND = 0; 1353e12c5d1SDavid du Colombier break; 1363e12c5d1SDavid du Colombier case 1: /* is unix coff */ 1373e12c5d1SDavid du Colombier HEADR = 0xd0L; 1383e12c5d1SDavid du Colombier if(INITTEXT == -1) 1393e12c5d1SDavid du Colombier INITTEXT = 0xd0; 1403e12c5d1SDavid du Colombier if(INITDAT == -1) 1413e12c5d1SDavid du Colombier INITDAT = 0x400000; 1423e12c5d1SDavid du Colombier if(INITRND == -1) 1433e12c5d1SDavid du Colombier INITRND = 0; 1443e12c5d1SDavid du Colombier break; 1453e12c5d1SDavid du Colombier case 2: /* plan 9 */ 1463e12c5d1SDavid du Colombier HEADR = 32L; 1473e12c5d1SDavid du Colombier if(INITTEXT == -1) 1483e12c5d1SDavid du Colombier INITTEXT = 4096+32; 1493e12c5d1SDavid du Colombier if(INITDAT == -1) 1503e12c5d1SDavid du Colombier INITDAT = 0; 1513e12c5d1SDavid du Colombier if(INITRND == -1) 1523e12c5d1SDavid du Colombier INITRND = 4096; 1533e12c5d1SDavid du Colombier break; 154219b2ee8SDavid du Colombier case 3: /* MS-DOS .COM */ 1553e12c5d1SDavid du Colombier HEADR = 0; 1563e12c5d1SDavid du Colombier if(INITTEXT == -1) 1573e12c5d1SDavid du Colombier INITTEXT = 0x0100; 1583e12c5d1SDavid du Colombier if(INITDAT == -1) 1593e12c5d1SDavid du Colombier INITDAT = 0; 1603e12c5d1SDavid du Colombier if(INITRND == -1) 1613e12c5d1SDavid du Colombier INITRND = 4; 1623e12c5d1SDavid du Colombier break; 163219b2ee8SDavid du Colombier case 4: /* fake MS-DOS .EXE */ 164219b2ee8SDavid du Colombier HEADR = 0x200; 165219b2ee8SDavid du Colombier if(INITTEXT == -1) 166219b2ee8SDavid du Colombier INITTEXT = 0x0100; 167219b2ee8SDavid du Colombier if(INITDAT == -1) 168219b2ee8SDavid du Colombier INITDAT = 0; 169219b2ee8SDavid du Colombier if(INITRND == -1) 170219b2ee8SDavid du Colombier INITRND = 4; 171219b2ee8SDavid du Colombier HEADR += (INITTEXT & 0xFFFF); 172219b2ee8SDavid du Colombier if(debug['v']) 173219b2ee8SDavid du Colombier Bprint(&bso, "HEADR = 0x%ld\n", HEADR); 174219b2ee8SDavid du Colombier break; 1753e12c5d1SDavid du Colombier } 1763e12c5d1SDavid du Colombier if(INITDAT != 0 && INITRND != 0) 1773e12c5d1SDavid du Colombier print("warning: -D0x%lux is ignored because of -R0x%lux\n", 1783e12c5d1SDavid du Colombier INITDAT, INITRND); 1793e12c5d1SDavid du Colombier if(debug['v']) 1803e12c5d1SDavid du Colombier Bprint(&bso, "HEADER = -H0x%ld -T0x%lux -D0x%lux -R0x%lux\n", 1813e12c5d1SDavid du Colombier HEADTYPE, INITTEXT, INITDAT, INITRND); 1823e12c5d1SDavid du Colombier Bflush(&bso); 1833e12c5d1SDavid du Colombier for(i=1; optab[i].as; i++) 1843e12c5d1SDavid du Colombier if(i != optab[i].as) { 1856b6b9ac8SDavid du Colombier diag("phase error in optab: %d", i); 1863e12c5d1SDavid du Colombier errorexit(); 1873e12c5d1SDavid du Colombier } 1883e12c5d1SDavid du Colombier maxop = i; 1893e12c5d1SDavid du Colombier 1903e12c5d1SDavid du Colombier for(i=0; i<Ymax; i++) 1913e12c5d1SDavid du Colombier ycover[i*Ymax + i] = 1; 1923e12c5d1SDavid du Colombier 1933e12c5d1SDavid du Colombier ycover[Yi0*Ymax + Yi8] = 1; 1943e12c5d1SDavid du Colombier ycover[Yi1*Ymax + Yi8] = 1; 1953e12c5d1SDavid du Colombier 1963e12c5d1SDavid du Colombier ycover[Yi0*Ymax + Yi32] = 1; 1973e12c5d1SDavid du Colombier ycover[Yi1*Ymax + Yi32] = 1; 1983e12c5d1SDavid du Colombier ycover[Yi8*Ymax + Yi32] = 1; 1993e12c5d1SDavid du Colombier 2003e12c5d1SDavid du Colombier ycover[Yal*Ymax + Yrb] = 1; 2013e12c5d1SDavid du Colombier ycover[Ycl*Ymax + Yrb] = 1; 2023e12c5d1SDavid du Colombier ycover[Yax*Ymax + Yrb] = 1; 2033e12c5d1SDavid du Colombier ycover[Ycx*Ymax + Yrb] = 1; 2043e12c5d1SDavid du Colombier ycover[Yrx*Ymax + Yrb] = 1; 2053e12c5d1SDavid du Colombier 2063e12c5d1SDavid du Colombier ycover[Yax*Ymax + Yrx] = 1; 2073e12c5d1SDavid du Colombier ycover[Ycx*Ymax + Yrx] = 1; 2083e12c5d1SDavid du Colombier 2093e12c5d1SDavid du Colombier ycover[Yax*Ymax + Yrl] = 1; 2103e12c5d1SDavid du Colombier ycover[Ycx*Ymax + Yrl] = 1; 2113e12c5d1SDavid du Colombier ycover[Yrx*Ymax + Yrl] = 1; 2123e12c5d1SDavid du Colombier 2133e12c5d1SDavid du Colombier ycover[Yf0*Ymax + Yrf] = 1; 2143e12c5d1SDavid du Colombier 2153e12c5d1SDavid du Colombier ycover[Yal*Ymax + Ymb] = 1; 2163e12c5d1SDavid du Colombier ycover[Ycl*Ymax + Ymb] = 1; 2173e12c5d1SDavid du Colombier ycover[Yax*Ymax + Ymb] = 1; 2183e12c5d1SDavid du Colombier ycover[Ycx*Ymax + Ymb] = 1; 2193e12c5d1SDavid du Colombier ycover[Yrx*Ymax + Ymb] = 1; 2203e12c5d1SDavid du Colombier ycover[Yrb*Ymax + Ymb] = 1; 2213e12c5d1SDavid du Colombier ycover[Ym*Ymax + Ymb] = 1; 2223e12c5d1SDavid du Colombier 2233e12c5d1SDavid du Colombier ycover[Yax*Ymax + Yml] = 1; 2243e12c5d1SDavid du Colombier ycover[Ycx*Ymax + Yml] = 1; 2253e12c5d1SDavid du Colombier ycover[Yrx*Ymax + Yml] = 1; 2263e12c5d1SDavid du Colombier ycover[Yrl*Ymax + Yml] = 1; 2273e12c5d1SDavid du Colombier ycover[Ym*Ymax + Yml] = 1; 2283e12c5d1SDavid du Colombier 2293e12c5d1SDavid du Colombier for(i=0; i<D_NONE; i++) { 2303e12c5d1SDavid du Colombier reg[i] = -1; 2313e12c5d1SDavid du Colombier if(i >= D_AL && i <= D_BH) 2323e12c5d1SDavid du Colombier reg[i] = (i-D_AL) & 7; 2333e12c5d1SDavid du Colombier if(i >= D_AX && i <= D_DI) 2343e12c5d1SDavid du Colombier reg[i] = (i-D_AX) & 7; 2353e12c5d1SDavid du Colombier if(i >= D_F0 && i <= D_F0+7) 2363e12c5d1SDavid du Colombier reg[i] = (i-D_F0) & 7; 2373e12c5d1SDavid du Colombier } 2383e12c5d1SDavid du Colombier 2393e12c5d1SDavid du Colombier zprg.link = P; 2407dd7cddfSDavid du Colombier zprg.pcond = P; 2413e12c5d1SDavid du Colombier zprg.back = 2; 2423e12c5d1SDavid du Colombier zprg.as = AGOK; 2433e12c5d1SDavid du Colombier zprg.from.type = D_NONE; 2443e12c5d1SDavid du Colombier zprg.from.index = D_NONE; 2453e12c5d1SDavid du Colombier zprg.from.scale = 1; 2463e12c5d1SDavid du Colombier zprg.to = zprg.from; 2473e12c5d1SDavid du Colombier 2483e12c5d1SDavid du Colombier pcstr = "%.6lux "; 2493e12c5d1SDavid du Colombier nuxiinit(); 2503e12c5d1SDavid du Colombier histgen = 0; 2513e12c5d1SDavid du Colombier textp = P; 2523e12c5d1SDavid du Colombier datap = P; 2533e12c5d1SDavid du Colombier edatap = P; 2543e12c5d1SDavid du Colombier pc = 0; 255219b2ee8SDavid du Colombier dtype = 4; 2563e12c5d1SDavid du Colombier cout = create(outfile, 1, 0775); 2573e12c5d1SDavid du Colombier if(cout < 0) { 2586b6b9ac8SDavid du Colombier diag("cannot create %s", outfile); 2593e12c5d1SDavid du Colombier errorexit(); 2603e12c5d1SDavid du Colombier } 2613e12c5d1SDavid du Colombier version = 0; 2623e12c5d1SDavid du Colombier cbp = buf.cbuf; 2633e12c5d1SDavid du Colombier cbc = sizeof(buf.cbuf); 2643e12c5d1SDavid du Colombier firstp = prg(); 2653e12c5d1SDavid du Colombier lastp = firstp; 2663e12c5d1SDavid du Colombier 2673e12c5d1SDavid du Colombier if(INITENTRY == 0) { 2683e12c5d1SDavid du Colombier INITENTRY = "_main"; 269*375daca8SDavid du Colombier if(debug['p']) 2703e12c5d1SDavid du Colombier INITENTRY = "_mainp"; 2713e12c5d1SDavid du Colombier if(!debug['l']) 2723e12c5d1SDavid du Colombier lookup(INITENTRY, 0)->type = SXREF; 273219b2ee8SDavid du Colombier } else 274219b2ee8SDavid du Colombier lookup(INITENTRY, 0)->type = SXREF; 2753e12c5d1SDavid du Colombier 2763e12c5d1SDavid du Colombier while(*argv) 2773e12c5d1SDavid du Colombier objfile(*argv++); 2783e12c5d1SDavid du Colombier if(!debug['l']) 2797dd7cddfSDavid du Colombier loadlib(); 2803e12c5d1SDavid du Colombier firstp = firstp->link; 2813e12c5d1SDavid du Colombier if(firstp == P) 2823e12c5d1SDavid du Colombier errorexit(); 283*375daca8SDavid du Colombier if(doexp || dlm){ 284*375daca8SDavid du Colombier EXPTAB = "_exporttab"; 285*375daca8SDavid du Colombier zerosig(EXPTAB); 286*375daca8SDavid du Colombier zerosig("etext"); 287*375daca8SDavid du Colombier zerosig("edata"); 288*375daca8SDavid du Colombier zerosig("end"); 289*375daca8SDavid du Colombier if(dlm){ 290*375daca8SDavid du Colombier import(); 291*375daca8SDavid du Colombier HEADTYPE = 2; 292*375daca8SDavid du Colombier INITTEXT = INITDAT = 0; 293*375daca8SDavid du Colombier INITRND = 8; 294*375daca8SDavid du Colombier INITENTRY = EXPTAB; 295*375daca8SDavid du Colombier } 296*375daca8SDavid du Colombier export(); 297*375daca8SDavid du Colombier } 2983e12c5d1SDavid du Colombier patch(); 2997dd7cddfSDavid du Colombier follow(); 3007dd7cddfSDavid du Colombier dodata(); 3017dd7cddfSDavid du Colombier dostkoff(); 3023e12c5d1SDavid du Colombier if(debug['p']) 3033e12c5d1SDavid du Colombier if(debug['1']) 3043e12c5d1SDavid du Colombier doprof1(); 3053e12c5d1SDavid du Colombier else 3063e12c5d1SDavid du Colombier doprof2(); 3073e12c5d1SDavid du Colombier span(); 3083e12c5d1SDavid du Colombier doinit(); 3093e12c5d1SDavid du Colombier asmb(); 3103e12c5d1SDavid du Colombier undef(); 3113e12c5d1SDavid du Colombier if(debug['v']) { 3123e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f cpu time\n", cputime()); 3133e12c5d1SDavid du Colombier Bprint(&bso, "%ld symbols\n", nsymbol); 3143e12c5d1SDavid du Colombier Bprint(&bso, "%ld memory used\n", thunk); 3153e12c5d1SDavid du Colombier Bprint(&bso, "%d sizeof adr\n", sizeof(Adr)); 3163e12c5d1SDavid du Colombier Bprint(&bso, "%d sizeof prog\n", sizeof(Prog)); 3173e12c5d1SDavid du Colombier } 3183e12c5d1SDavid du Colombier Bflush(&bso); 3193e12c5d1SDavid du Colombier 3203e12c5d1SDavid du Colombier errorexit(); 3213e12c5d1SDavid du Colombier } 3223e12c5d1SDavid du Colombier 3233e12c5d1SDavid du Colombier void 3247dd7cddfSDavid du Colombier loadlib(void) 3253e12c5d1SDavid du Colombier { 3267dd7cddfSDavid du Colombier int i; 3277dd7cddfSDavid du Colombier long h; 3287dd7cddfSDavid du Colombier Sym *s; 3293e12c5d1SDavid du Colombier 3307dd7cddfSDavid du Colombier loop: 3317dd7cddfSDavid du Colombier xrefresolv = 0; 3327dd7cddfSDavid du Colombier for(i=0; i<libraryp; i++) { 3333e12c5d1SDavid du Colombier if(debug['v']) 334*375daca8SDavid du Colombier Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(), library[i], libraryobj[i]); 3353e12c5d1SDavid du Colombier objfile(library[i]); 3363e12c5d1SDavid du Colombier } 3377dd7cddfSDavid du Colombier if(xrefresolv) 3387dd7cddfSDavid du Colombier for(h=0; h<nelem(hash); h++) 3397dd7cddfSDavid du Colombier for(s = hash[h]; s != S; s = s->link) 3407dd7cddfSDavid du Colombier if(s->type == SXREF) 3417dd7cddfSDavid du Colombier goto loop; 3423e12c5d1SDavid du Colombier } 3433e12c5d1SDavid du Colombier 3443e12c5d1SDavid du Colombier void 3453e12c5d1SDavid du Colombier errorexit(void) 3463e12c5d1SDavid du Colombier { 3473e12c5d1SDavid du Colombier 3483e12c5d1SDavid du Colombier if(nerrors) { 3493e12c5d1SDavid du Colombier if(cout >= 0) 3503e12c5d1SDavid du Colombier remove(outfile); 3513e12c5d1SDavid du Colombier exits("error"); 3523e12c5d1SDavid du Colombier } 3533e12c5d1SDavid du Colombier exits(0); 3543e12c5d1SDavid du Colombier } 3553e12c5d1SDavid du Colombier 3563e12c5d1SDavid du Colombier void 3573e12c5d1SDavid du Colombier objfile(char *file) 3583e12c5d1SDavid du Colombier { 359219b2ee8SDavid du Colombier long off, esym, cnt, l; 3603e12c5d1SDavid du Colombier int f, work; 3613e12c5d1SDavid du Colombier Sym *s; 3623e12c5d1SDavid du Colombier char magbuf[SARMAG]; 3633e12c5d1SDavid du Colombier char name[100], pname[150]; 3643e12c5d1SDavid du Colombier struct ar_hdr arhdr; 365219b2ee8SDavid du Colombier char *e, *start, *stop; 3663e12c5d1SDavid du Colombier 3673e12c5d1SDavid du Colombier if(file[0] == '-' && file[1] == 'l') { 3683e12c5d1SDavid du Colombier if(debug['9']) 369219b2ee8SDavid du Colombier sprint(name, "/%s/lib/lib", thestring); 3703e12c5d1SDavid du Colombier else 371219b2ee8SDavid du Colombier sprint(name, "/usr/%clib/lib", thechar); 3723e12c5d1SDavid du Colombier strcat(name, file+2); 3733e12c5d1SDavid du Colombier strcat(name, ".a"); 3743e12c5d1SDavid du Colombier file = name; 3753e12c5d1SDavid du Colombier } 3763e12c5d1SDavid du Colombier if(debug['v']) 3773e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f ldobj: %s\n", cputime(), file); 3783e12c5d1SDavid du Colombier Bflush(&bso); 3793e12c5d1SDavid du Colombier f = open(file, 0); 3803e12c5d1SDavid du Colombier if(f < 0) { 3816b6b9ac8SDavid du Colombier diag("cannot open file: %s", file); 3823e12c5d1SDavid du Colombier errorexit(); 3833e12c5d1SDavid du Colombier } 3843e12c5d1SDavid du Colombier l = read(f, magbuf, SARMAG); 385219b2ee8SDavid du Colombier if(l != SARMAG || strncmp(magbuf, ARMAG, SARMAG)){ 386219b2ee8SDavid du Colombier /* load it as a regular file */ 387219b2ee8SDavid du Colombier l = seek(f, 0L, 2); 388219b2ee8SDavid du Colombier seek(f, 0L, 0); 389219b2ee8SDavid du Colombier ldobj(f, l, file); 390219b2ee8SDavid du Colombier close(f); 391219b2ee8SDavid du Colombier return; 392219b2ee8SDavid du Colombier } 3933e12c5d1SDavid du Colombier 3947dd7cddfSDavid du Colombier l = read(f, &arhdr, SAR_HDR); 3957dd7cddfSDavid du Colombier if(l != SAR_HDR) { 3966b6b9ac8SDavid du Colombier diag("%s: short read on archive file symbol header", file); 3973e12c5d1SDavid du Colombier goto out; 3983e12c5d1SDavid du Colombier } 3993e12c5d1SDavid du Colombier if(strncmp(arhdr.name, symname, strlen(symname))) { 4006b6b9ac8SDavid du Colombier diag("%s: first entry not symbol header", file); 4013e12c5d1SDavid du Colombier goto out; 4023e12c5d1SDavid du Colombier } 4033e12c5d1SDavid du Colombier 4047dd7cddfSDavid du Colombier esym = SARMAG + SAR_HDR + atolwhex(arhdr.size); 4057dd7cddfSDavid du Colombier off = SARMAG + SAR_HDR; 4063e12c5d1SDavid du Colombier 407219b2ee8SDavid du Colombier /* 408219b2ee8SDavid du Colombier * just bang the whole symbol file into memory 409219b2ee8SDavid du Colombier */ 4103e12c5d1SDavid du Colombier seek(f, off, 0); 4113e12c5d1SDavid du Colombier cnt = esym - off; 412219b2ee8SDavid du Colombier start = malloc(cnt + 10); 413219b2ee8SDavid du Colombier cnt = read(f, start, cnt); 4143e12c5d1SDavid du Colombier if(cnt <= 0){ 4153e12c5d1SDavid du Colombier close(f); 4163e12c5d1SDavid du Colombier return; 4173e12c5d1SDavid du Colombier } 418219b2ee8SDavid du Colombier stop = &start[cnt]; 419219b2ee8SDavid du Colombier memset(stop, 0, 10); 420219b2ee8SDavid du Colombier 421219b2ee8SDavid du Colombier work = 1; 422219b2ee8SDavid du Colombier while(work) { 423219b2ee8SDavid du Colombier if(debug['v']) 424219b2ee8SDavid du Colombier Bprint(&bso, "%5.2f library pass: %s\n", cputime(), file); 425219b2ee8SDavid du Colombier Bflush(&bso); 426219b2ee8SDavid du Colombier work = 0; 427219b2ee8SDavid du Colombier for(e = start; e < stop; e = strchr(e+5, 0) + 1) { 428219b2ee8SDavid du Colombier s = lookup(e+5, 0); 4293e12c5d1SDavid du Colombier if(s->type != SXREF) 4303e12c5d1SDavid du Colombier continue; 431219b2ee8SDavid du Colombier sprint(pname, "%s(%s)", file, s->name); 4323e12c5d1SDavid du Colombier if(debug['v']) 4333e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f library: %s\n", cputime(), pname); 4343e12c5d1SDavid du Colombier Bflush(&bso); 435219b2ee8SDavid du Colombier l = e[1] & 0xff; 436219b2ee8SDavid du Colombier l |= (e[2] & 0xff) << 8; 437219b2ee8SDavid du Colombier l |= (e[3] & 0xff) << 16; 438219b2ee8SDavid du Colombier l |= (e[4] & 0xff) << 24; 4393e12c5d1SDavid du Colombier seek(f, l, 0); 4407dd7cddfSDavid du Colombier l = read(f, &arhdr, SAR_HDR); 4417dd7cddfSDavid du Colombier if(l != SAR_HDR) 4423e12c5d1SDavid du Colombier goto bad; 4433e12c5d1SDavid du Colombier if(strncmp(arhdr.fmag, ARFMAG, sizeof(arhdr.fmag))) 4443e12c5d1SDavid du Colombier goto bad; 4453e12c5d1SDavid du Colombier l = atolwhex(arhdr.size); 4463e12c5d1SDavid du Colombier ldobj(f, l, pname); 4473e12c5d1SDavid du Colombier if(s->type == SXREF) { 4486b6b9ac8SDavid du Colombier diag("%s: failed to load: %s", file, s->name); 4493e12c5d1SDavid du Colombier errorexit(); 4503e12c5d1SDavid du Colombier } 4513e12c5d1SDavid du Colombier work = 1; 4527dd7cddfSDavid du Colombier xrefresolv = 1; 4533e12c5d1SDavid du Colombier } 454219b2ee8SDavid du Colombier } 4553e12c5d1SDavid du Colombier return; 4563e12c5d1SDavid du Colombier 4573e12c5d1SDavid du Colombier bad: 4586b6b9ac8SDavid du Colombier diag("%s: bad or out of date archive", file); 4593e12c5d1SDavid du Colombier out: 4603e12c5d1SDavid du Colombier close(f); 4613e12c5d1SDavid du Colombier } 4623e12c5d1SDavid du Colombier 4633e12c5d1SDavid du Colombier int 4643e12c5d1SDavid du Colombier zaddr(uchar *p, Adr *a, Sym *h[]) 4653e12c5d1SDavid du Colombier { 4663e12c5d1SDavid du Colombier int c, t, i; 4673e12c5d1SDavid du Colombier long l; 4683e12c5d1SDavid du Colombier Sym *s; 4693e12c5d1SDavid du Colombier Auto *u; 4703e12c5d1SDavid du Colombier 4713e12c5d1SDavid du Colombier t = p[0]; 4723e12c5d1SDavid du Colombier 4733e12c5d1SDavid du Colombier c = 1; 4743e12c5d1SDavid du Colombier if(t & T_INDEX) { 4753e12c5d1SDavid du Colombier a->index = p[c]; 4763e12c5d1SDavid du Colombier a->scale = p[c+1]; 4773e12c5d1SDavid du Colombier c += 2; 4783e12c5d1SDavid du Colombier } else { 4793e12c5d1SDavid du Colombier a->index = D_NONE; 4803e12c5d1SDavid du Colombier a->scale = 0; 4813e12c5d1SDavid du Colombier } 4823e12c5d1SDavid du Colombier a->offset = 0; 4833e12c5d1SDavid du Colombier if(t & T_OFFSET) { 4843e12c5d1SDavid du Colombier a->offset = p[c] | (p[c+1]<<8) | (p[c+2]<<16) | (p[c+3]<<24); 4853e12c5d1SDavid du Colombier c += 4; 4863e12c5d1SDavid du Colombier } 4873e12c5d1SDavid du Colombier a->sym = S; 4883e12c5d1SDavid du Colombier if(t & T_SYM) { 4893e12c5d1SDavid du Colombier a->sym = h[p[c]]; 4903e12c5d1SDavid du Colombier c++; 4913e12c5d1SDavid du Colombier } 4923e12c5d1SDavid du Colombier a->type = D_NONE; 4933e12c5d1SDavid du Colombier if(t & T_FCONST) { 4943e12c5d1SDavid du Colombier a->ieee.l = p[c] | (p[c+1]<<8) | (p[c+2]<<16) | (p[c+3]<<24); 4953e12c5d1SDavid du Colombier a->ieee.h = p[c+4] | (p[c+5]<<8) | (p[c+6]<<16) | (p[c+7]<<24); 4963e12c5d1SDavid du Colombier c += 8; 4973e12c5d1SDavid du Colombier a->type = D_FCONST; 4983e12c5d1SDavid du Colombier } else 4993e12c5d1SDavid du Colombier if(t & T_SCONST) { 5003e12c5d1SDavid du Colombier for(i=0; i<NSNAME; i++) 5013e12c5d1SDavid du Colombier a->scon[i] = p[c+i]; 5023e12c5d1SDavid du Colombier c += NSNAME; 5033e12c5d1SDavid du Colombier a->type = D_SCONST; 5043e12c5d1SDavid du Colombier } 5053e12c5d1SDavid du Colombier if(t & T_TYPE) { 5063e12c5d1SDavid du Colombier a->type = p[c]; 5073e12c5d1SDavid du Colombier c++; 5083e12c5d1SDavid du Colombier } 5093e12c5d1SDavid du Colombier s = a->sym; 5103e12c5d1SDavid du Colombier if(s == S) 5113e12c5d1SDavid du Colombier return c; 5123e12c5d1SDavid du Colombier 5133e12c5d1SDavid du Colombier t = a->type; 5143e12c5d1SDavid du Colombier if(t != D_AUTO && t != D_PARAM) 5153e12c5d1SDavid du Colombier return c; 5163e12c5d1SDavid du Colombier l = a->offset; 5173e12c5d1SDavid du Colombier for(u=curauto; u; u=u->link) { 5187dd7cddfSDavid du Colombier if(u->asym == s) 5193e12c5d1SDavid du Colombier if(u->type == t) { 5207dd7cddfSDavid du Colombier if(u->aoffset > l) 5217dd7cddfSDavid du Colombier u->aoffset = l; 5223e12c5d1SDavid du Colombier return c; 5233e12c5d1SDavid du Colombier } 5243e12c5d1SDavid du Colombier } 5253e12c5d1SDavid du Colombier 5263e12c5d1SDavid du Colombier while(nhunk < sizeof(Auto)) 5273e12c5d1SDavid du Colombier gethunk(); 5283e12c5d1SDavid du Colombier u = (Auto*)hunk; 5293e12c5d1SDavid du Colombier nhunk -= sizeof(Auto); 5303e12c5d1SDavid du Colombier hunk += sizeof(Auto); 5313e12c5d1SDavid du Colombier 5323e12c5d1SDavid du Colombier u->link = curauto; 5333e12c5d1SDavid du Colombier curauto = u; 5347dd7cddfSDavid du Colombier u->asym = s; 5357dd7cddfSDavid du Colombier u->aoffset = l; 5363e12c5d1SDavid du Colombier u->type = t; 5373e12c5d1SDavid du Colombier return c; 5383e12c5d1SDavid du Colombier } 5393e12c5d1SDavid du Colombier 5403e12c5d1SDavid du Colombier void 54180ee5cbfSDavid du Colombier addlib(char *obj) 5423e12c5d1SDavid du Colombier { 5439a747e4fSDavid du Colombier char name[1024], comp[256], *p; 5443e12c5d1SDavid du Colombier int i; 5453e12c5d1SDavid du Colombier 5463e12c5d1SDavid du Colombier if(histfrogp <= 0) 5473e12c5d1SDavid du Colombier return; 5483e12c5d1SDavid du Colombier 5493e12c5d1SDavid du Colombier if(histfrog[0]->name[1] == '/') { 5503e12c5d1SDavid du Colombier sprint(name, ""); 5513e12c5d1SDavid du Colombier i = 1; 5523e12c5d1SDavid du Colombier } else 5533e12c5d1SDavid du Colombier if(histfrog[0]->name[1] == '.') { 5543e12c5d1SDavid du Colombier sprint(name, "."); 5553e12c5d1SDavid du Colombier i = 0; 5563e12c5d1SDavid du Colombier } else { 5573e12c5d1SDavid du Colombier if(debug['9']) 558219b2ee8SDavid du Colombier sprint(name, "/%s/lib", thestring); 5593e12c5d1SDavid du Colombier else 560219b2ee8SDavid du Colombier sprint(name, "/usr/%clib", thechar); 5613e12c5d1SDavid du Colombier i = 0; 5623e12c5d1SDavid du Colombier } 5633e12c5d1SDavid du Colombier 5643e12c5d1SDavid du Colombier for(; i<histfrogp; i++) { 5659a747e4fSDavid du Colombier snprint(comp, sizeof comp, histfrog[i]->name+1); 5663e12c5d1SDavid du Colombier for(;;) { 5673e12c5d1SDavid du Colombier p = strstr(comp, "$O"); 5683e12c5d1SDavid du Colombier if(p == 0) 5693e12c5d1SDavid du Colombier break; 5703e12c5d1SDavid du Colombier memmove(p+1, p+2, strlen(p+2)+1); 571219b2ee8SDavid du Colombier p[0] = thechar; 5723e12c5d1SDavid du Colombier } 5733e12c5d1SDavid du Colombier for(;;) { 5743e12c5d1SDavid du Colombier p = strstr(comp, "$M"); 5753e12c5d1SDavid du Colombier if(p == 0) 5763e12c5d1SDavid du Colombier break; 5779a747e4fSDavid du Colombier if(strlen(comp)+strlen(thestring)-2+1 >= sizeof comp) { 578219b2ee8SDavid du Colombier diag("library component too long"); 579219b2ee8SDavid du Colombier return; 5803e12c5d1SDavid du Colombier } 5819a747e4fSDavid du Colombier memmove(p+strlen(thestring), p+2, strlen(p+2)+1); 5829a747e4fSDavid du Colombier memmove(p, thestring, strlen(thestring)); 583219b2ee8SDavid du Colombier } 5849a747e4fSDavid du Colombier if(strlen(name) + strlen(comp) + 3 >= sizeof(name)) { 5853e12c5d1SDavid du Colombier diag("library component too long"); 5863e12c5d1SDavid du Colombier return; 5873e12c5d1SDavid du Colombier } 5883e12c5d1SDavid du Colombier strcat(name, "/"); 5893e12c5d1SDavid du Colombier strcat(name, comp); 5903e12c5d1SDavid du Colombier } 5913e12c5d1SDavid du Colombier for(i=0; i<libraryp; i++) 5923e12c5d1SDavid du Colombier if(strcmp(name, library[i]) == 0) 5933e12c5d1SDavid du Colombier return; 59480ee5cbfSDavid du Colombier if(libraryp == nelem(library)){ 59580ee5cbfSDavid du Colombier diag("too many autolibs; skipping %s", name); 59680ee5cbfSDavid du Colombier return; 59780ee5cbfSDavid du Colombier } 5983e12c5d1SDavid du Colombier 599219b2ee8SDavid du Colombier p = malloc(strlen(name) + 1); 6003e12c5d1SDavid du Colombier strcpy(p, name); 6013e12c5d1SDavid du Colombier library[libraryp] = p; 60280ee5cbfSDavid du Colombier p = malloc(strlen(obj) + 1); 60380ee5cbfSDavid du Colombier strcpy(p, obj); 60480ee5cbfSDavid du Colombier libraryobj[libraryp] = p; 6053e12c5d1SDavid du Colombier libraryp++; 6063e12c5d1SDavid du Colombier } 607219b2ee8SDavid du Colombier 6083e12c5d1SDavid du Colombier void 6093e12c5d1SDavid du Colombier addhist(long line, int type) 6103e12c5d1SDavid du Colombier { 6113e12c5d1SDavid du Colombier Auto *u; 6123e12c5d1SDavid du Colombier Sym *s; 6133e12c5d1SDavid du Colombier int i, j, k; 6143e12c5d1SDavid du Colombier 615219b2ee8SDavid du Colombier u = malloc(sizeof(Auto)); 616219b2ee8SDavid du Colombier s = malloc(sizeof(Sym)); 617219b2ee8SDavid du Colombier s->name = malloc(2*(histfrogp+1) + 1); 6183e12c5d1SDavid du Colombier 6197dd7cddfSDavid du Colombier u->asym = s; 6203e12c5d1SDavid du Colombier u->type = type; 6217dd7cddfSDavid du Colombier u->aoffset = line; 6223e12c5d1SDavid du Colombier u->link = curhist; 6233e12c5d1SDavid du Colombier curhist = u; 6243e12c5d1SDavid du Colombier 6253e12c5d1SDavid du Colombier j = 1; 6263e12c5d1SDavid du Colombier for(i=0; i<histfrogp; i++) { 6273e12c5d1SDavid du Colombier k = histfrog[i]->value; 6283e12c5d1SDavid du Colombier s->name[j+0] = k>>8; 6293e12c5d1SDavid du Colombier s->name[j+1] = k; 6303e12c5d1SDavid du Colombier j += 2; 6313e12c5d1SDavid du Colombier } 6323e12c5d1SDavid du Colombier } 6333e12c5d1SDavid du Colombier 6343e12c5d1SDavid du Colombier void 6353e12c5d1SDavid du Colombier histtoauto(void) 6363e12c5d1SDavid du Colombier { 6373e12c5d1SDavid du Colombier Auto *l; 6383e12c5d1SDavid du Colombier 6393e12c5d1SDavid du Colombier while(l = curhist) { 6403e12c5d1SDavid du Colombier curhist = l->link; 6413e12c5d1SDavid du Colombier l->link = curauto; 6423e12c5d1SDavid du Colombier curauto = l; 6433e12c5d1SDavid du Colombier } 6443e12c5d1SDavid du Colombier } 6453e12c5d1SDavid du Colombier 6463e12c5d1SDavid du Colombier void 647219b2ee8SDavid du Colombier collapsefrog(Sym *s) 648219b2ee8SDavid du Colombier { 649219b2ee8SDavid du Colombier int i; 650219b2ee8SDavid du Colombier 651219b2ee8SDavid du Colombier /* 652219b2ee8SDavid du Colombier * bad encoding of path components only allows 653219b2ee8SDavid du Colombier * MAXHIST components. if there is an overflow, 654219b2ee8SDavid du Colombier * first try to collapse xxx/.. 655219b2ee8SDavid du Colombier */ 656219b2ee8SDavid du Colombier for(i=1; i<histfrogp; i++) 657219b2ee8SDavid du Colombier if(strcmp(histfrog[i]->name+1, "..") == 0) { 658219b2ee8SDavid du Colombier memmove(histfrog+i-1, histfrog+i+1, 659219b2ee8SDavid du Colombier (histfrogp-i-1)*sizeof(histfrog[0])); 660219b2ee8SDavid du Colombier histfrogp--; 661219b2ee8SDavid du Colombier goto out; 662219b2ee8SDavid du Colombier } 663219b2ee8SDavid du Colombier 664219b2ee8SDavid du Colombier /* 665219b2ee8SDavid du Colombier * next try to collapse . 666219b2ee8SDavid du Colombier */ 667219b2ee8SDavid du Colombier for(i=0; i<histfrogp; i++) 668219b2ee8SDavid du Colombier if(strcmp(histfrog[i]->name+1, ".") == 0) { 669219b2ee8SDavid du Colombier memmove(histfrog+i, histfrog+i+1, 670219b2ee8SDavid du Colombier (histfrogp-i-1)*sizeof(histfrog[0])); 671219b2ee8SDavid du Colombier goto out; 672219b2ee8SDavid du Colombier } 673219b2ee8SDavid du Colombier 674219b2ee8SDavid du Colombier /* 675219b2ee8SDavid du Colombier * last chance, just truncate from front 676219b2ee8SDavid du Colombier */ 677219b2ee8SDavid du Colombier memmove(histfrog+0, histfrog+1, 678219b2ee8SDavid du Colombier (histfrogp-1)*sizeof(histfrog[0])); 679219b2ee8SDavid du Colombier 680219b2ee8SDavid du Colombier out: 681219b2ee8SDavid du Colombier histfrog[histfrogp-1] = s; 682219b2ee8SDavid du Colombier } 683219b2ee8SDavid du Colombier 684219b2ee8SDavid du Colombier void 685219b2ee8SDavid du Colombier nopout(Prog *p) 686219b2ee8SDavid du Colombier { 687219b2ee8SDavid du Colombier p->as = ANOP; 688219b2ee8SDavid du Colombier p->from.type = D_NONE; 689219b2ee8SDavid du Colombier p->to.type = D_NONE; 690219b2ee8SDavid du Colombier } 691219b2ee8SDavid du Colombier 692219b2ee8SDavid du Colombier uchar* 693219b2ee8SDavid du Colombier readsome(int f, uchar *buf, uchar *good, uchar *stop, int max) 694219b2ee8SDavid du Colombier { 695219b2ee8SDavid du Colombier int n; 696219b2ee8SDavid du Colombier 697219b2ee8SDavid du Colombier n = stop - good; 698219b2ee8SDavid du Colombier memmove(buf, good, stop - good); 699219b2ee8SDavid du Colombier stop = buf + n; 700219b2ee8SDavid du Colombier n = MAXIO - n; 701219b2ee8SDavid du Colombier if(n > max) 702219b2ee8SDavid du Colombier n = max; 703219b2ee8SDavid du Colombier n = read(f, stop, n); 704219b2ee8SDavid du Colombier if(n <= 0) 705219b2ee8SDavid du Colombier return 0; 706219b2ee8SDavid du Colombier return stop + n; 707219b2ee8SDavid du Colombier } 708219b2ee8SDavid du Colombier 709219b2ee8SDavid du Colombier void 7103e12c5d1SDavid du Colombier ldobj(int f, long c, char *pn) 7113e12c5d1SDavid du Colombier { 7123e12c5d1SDavid du Colombier long ipc; 713219b2ee8SDavid du Colombier Prog *p, *t; 714219b2ee8SDavid du Colombier uchar *bloc, *bsize, *stop; 715219b2ee8SDavid du Colombier int v, o, r, skip; 716219b2ee8SDavid du Colombier Sym *h[NSYM], *s, *di; 717*375daca8SDavid du Colombier ulong sig; 718*375daca8SDavid du Colombier static int files; 719*375daca8SDavid du Colombier static char **filen; 720*375daca8SDavid du Colombier char **nfilen; 721*375daca8SDavid du Colombier 722*375daca8SDavid du Colombier if((files&15) == 0){ 723*375daca8SDavid du Colombier nfilen = malloc((files+16)*sizeof(char*)); 724*375daca8SDavid du Colombier memmove(nfilen, filen, files*sizeof(char*)); 725*375daca8SDavid du Colombier free(filen); 726*375daca8SDavid du Colombier filen = nfilen; 727*375daca8SDavid du Colombier } 728*375daca8SDavid du Colombier filen[files++] = strdup(pn); 7293e12c5d1SDavid du Colombier 7303e12c5d1SDavid du Colombier bsize = buf.xbuf; 7313e12c5d1SDavid du Colombier bloc = buf.xbuf; 732219b2ee8SDavid du Colombier di = S; 7333e12c5d1SDavid du Colombier 7343e12c5d1SDavid du Colombier newloop: 7353e12c5d1SDavid du Colombier memset(h, 0, sizeof(h)); 7363e12c5d1SDavid du Colombier version++; 7373e12c5d1SDavid du Colombier histfrogp = 0; 7383e12c5d1SDavid du Colombier ipc = pc; 739219b2ee8SDavid du Colombier skip = 0; 7403e12c5d1SDavid du Colombier 7413e12c5d1SDavid du Colombier loop: 7423e12c5d1SDavid du Colombier if(c <= 0) 7433e12c5d1SDavid du Colombier goto eof; 7443e12c5d1SDavid du Colombier r = bsize - bloc; 7453e12c5d1SDavid du Colombier if(r < 100 && r < c) { /* enough for largest prog */ 746219b2ee8SDavid du Colombier bsize = readsome(f, buf.xbuf, bloc, bsize, c); 747219b2ee8SDavid du Colombier if(bsize == 0) 7483e12c5d1SDavid du Colombier goto eof; 749219b2ee8SDavid du Colombier bloc = buf.xbuf; 7503e12c5d1SDavid du Colombier goto loop; 7513e12c5d1SDavid du Colombier } 7523e12c5d1SDavid du Colombier o = bloc[0] | (bloc[1] << 8); 753219b2ee8SDavid du Colombier if(o <= AXXX || o >= ALAST) { 7543e12c5d1SDavid du Colombier if(o < 0) 7553e12c5d1SDavid du Colombier goto eof; 7566b6b9ac8SDavid du Colombier diag("%s: opcode out of range %d", pn, o); 7573e12c5d1SDavid du Colombier print(" probably not a .8 file\n"); 7583e12c5d1SDavid du Colombier errorexit(); 7593e12c5d1SDavid du Colombier } 7603e12c5d1SDavid du Colombier 761*375daca8SDavid du Colombier if(o == ANAME || o == ASIGNAME) { 762*375daca8SDavid du Colombier sig = 0; 763*375daca8SDavid du Colombier if(o == ASIGNAME) { 764*375daca8SDavid du Colombier sig = bloc[2] | (bloc[3]<<8) | (bloc[4]<<16) | (bloc[5]<<24); 765*375daca8SDavid du Colombier bloc += 4; 766*375daca8SDavid du Colombier c -= 4; 767*375daca8SDavid du Colombier } 768219b2ee8SDavid du Colombier stop = memchr(&bloc[4], 0, bsize-&bloc[4]); 769219b2ee8SDavid du Colombier if(stop == 0){ 770219b2ee8SDavid du Colombier bsize = readsome(f, buf.xbuf, bloc, bsize, c); 771219b2ee8SDavid du Colombier if(bsize == 0) 772219b2ee8SDavid du Colombier goto eof; 773219b2ee8SDavid du Colombier bloc = buf.xbuf; 774219b2ee8SDavid du Colombier stop = memchr(&bloc[4], 0, bsize-&bloc[4]); 775219b2ee8SDavid du Colombier if(stop == 0){ 776219b2ee8SDavid du Colombier fprint(2, "%s: name too long\n", pn); 777219b2ee8SDavid du Colombier errorexit(); 778219b2ee8SDavid du Colombier } 779219b2ee8SDavid du Colombier } 7803e12c5d1SDavid du Colombier v = bloc[2]; /* type */ 7813e12c5d1SDavid du Colombier o = bloc[3]; /* sym */ 7823e12c5d1SDavid du Colombier bloc += 4; 7833e12c5d1SDavid du Colombier c -= 4; 784219b2ee8SDavid du Colombier 7853e12c5d1SDavid du Colombier r = 0; 7863e12c5d1SDavid du Colombier if(v == D_STATIC) 7873e12c5d1SDavid du Colombier r = version; 788219b2ee8SDavid du Colombier s = lookup((char*)bloc, r); 789219b2ee8SDavid du Colombier c -= &stop[1] - bloc; 790219b2ee8SDavid du Colombier bloc = stop + 1; 791219b2ee8SDavid du Colombier 792*375daca8SDavid du Colombier if(debug['S'] && r == 0) 793*375daca8SDavid du Colombier sig = 1729; 794*375daca8SDavid du Colombier if(sig != 0){ 795*375daca8SDavid du Colombier if(s->sig != 0 && s->sig != sig) 796*375daca8SDavid du Colombier diag("incompatible type signatures %lux(%s) and %lux(%s) for %s", s->sig, filen[s->file], sig, pn, s->name); 797*375daca8SDavid du Colombier s->sig = sig; 798*375daca8SDavid du Colombier s->file = files-1; 799*375daca8SDavid du Colombier } 800*375daca8SDavid du Colombier 8013e12c5d1SDavid du Colombier if(debug['W']) 8023e12c5d1SDavid du Colombier print(" ANAME %s\n", s->name); 8033e12c5d1SDavid du Colombier h[o] = s; 804219b2ee8SDavid du Colombier if((v == D_EXTERN || v == D_STATIC) && s->type == 0) 8053e12c5d1SDavid du Colombier s->type = SXREF; 8063e12c5d1SDavid du Colombier if(v == D_FILE) { 8073e12c5d1SDavid du Colombier if(s->type != SFILE) { 8083e12c5d1SDavid du Colombier histgen++; 8093e12c5d1SDavid du Colombier s->type = SFILE; 8103e12c5d1SDavid du Colombier s->value = histgen; 8113e12c5d1SDavid du Colombier } 812219b2ee8SDavid du Colombier if(histfrogp < MAXHIST) { 8133e12c5d1SDavid du Colombier histfrog[histfrogp] = s; 8143e12c5d1SDavid du Colombier histfrogp++; 815219b2ee8SDavid du Colombier } else 816219b2ee8SDavid du Colombier collapsefrog(s); 8173e12c5d1SDavid du Colombier } 8183e12c5d1SDavid du Colombier goto loop; 8193e12c5d1SDavid du Colombier } 8203e12c5d1SDavid du Colombier 8213e12c5d1SDavid du Colombier while(nhunk < sizeof(Prog)) 8223e12c5d1SDavid du Colombier gethunk(); 8233e12c5d1SDavid du Colombier p = (Prog*)hunk; 8243e12c5d1SDavid du Colombier nhunk -= sizeof(Prog); 8253e12c5d1SDavid du Colombier hunk += sizeof(Prog); 8263e12c5d1SDavid du Colombier 8273e12c5d1SDavid du Colombier p->as = o; 8283e12c5d1SDavid du Colombier p->line = bloc[2] | (bloc[3] << 8) | (bloc[4] << 16) | (bloc[5] << 24); 8293e12c5d1SDavid du Colombier p->back = 2; 8303e12c5d1SDavid du Colombier r = zaddr(bloc+6, &p->from, h) + 6; 8313e12c5d1SDavid du Colombier r += zaddr(bloc+r, &p->to, h); 8323e12c5d1SDavid du Colombier bloc += r; 8333e12c5d1SDavid du Colombier c -= r; 8343e12c5d1SDavid du Colombier 8353e12c5d1SDavid du Colombier if(debug['W']) 8363e12c5d1SDavid du Colombier print("%P\n", p); 8373e12c5d1SDavid du Colombier 8383e12c5d1SDavid du Colombier switch(p->as) { 8393e12c5d1SDavid du Colombier case AHISTORY: 8403e12c5d1SDavid du Colombier if(p->to.offset == -1) { 84180ee5cbfSDavid du Colombier addlib(pn); 8423e12c5d1SDavid du Colombier histfrogp = 0; 8433e12c5d1SDavid du Colombier goto loop; 8443e12c5d1SDavid du Colombier } 845219b2ee8SDavid du Colombier addhist(p->line, D_FILE); /* 'z' */ 8463e12c5d1SDavid du Colombier if(p->to.offset) 847219b2ee8SDavid du Colombier addhist(p->to.offset, D_FILE1); /* 'Z' */ 8483e12c5d1SDavid du Colombier histfrogp = 0; 8493e12c5d1SDavid du Colombier goto loop; 8503e12c5d1SDavid du Colombier 8513e12c5d1SDavid du Colombier case AEND: 8523e12c5d1SDavid du Colombier histtoauto(); 8533e12c5d1SDavid du Colombier if(curtext != P) 8543e12c5d1SDavid du Colombier curtext->to.autom = curauto; 8553e12c5d1SDavid du Colombier curauto = 0; 8563e12c5d1SDavid du Colombier curtext = P; 8573e12c5d1SDavid du Colombier if(c) 8583e12c5d1SDavid du Colombier goto newloop; 8593e12c5d1SDavid du Colombier return; 8603e12c5d1SDavid du Colombier 8613e12c5d1SDavid du Colombier case AGLOBL: 8623e12c5d1SDavid du Colombier s = p->from.sym; 8633e12c5d1SDavid du Colombier if(s->type == 0 || s->type == SXREF) { 8643e12c5d1SDavid du Colombier s->type = SBSS; 8653e12c5d1SDavid du Colombier s->value = 0; 8663e12c5d1SDavid du Colombier } 8673e12c5d1SDavid du Colombier if(s->type != SBSS) { 8686b6b9ac8SDavid du Colombier diag("%s: redefinition: %s in %s", 8693e12c5d1SDavid du Colombier pn, s->name, TNAME); 8703e12c5d1SDavid du Colombier s->type = SBSS; 8713e12c5d1SDavid du Colombier s->value = 0; 8723e12c5d1SDavid du Colombier } 8733e12c5d1SDavid du Colombier if(p->to.offset > s->value) 8743e12c5d1SDavid du Colombier s->value = p->to.offset; 8753e12c5d1SDavid du Colombier goto loop; 8763e12c5d1SDavid du Colombier 877219b2ee8SDavid du Colombier case ADYNT: 878219b2ee8SDavid du Colombier if(p->to.sym == S) { 8796b6b9ac8SDavid du Colombier diag("DYNT without a sym\n%P", p); 880219b2ee8SDavid du Colombier break; 881219b2ee8SDavid du Colombier } 882219b2ee8SDavid du Colombier di = p->to.sym; 883219b2ee8SDavid du Colombier p->from.scale = 4; 884219b2ee8SDavid du Colombier if(di->type == SXREF) { 885219b2ee8SDavid du Colombier if(debug['z']) 886219b2ee8SDavid du Colombier Bprint(&bso, "%P set to %d\n", p, dtype); 887219b2ee8SDavid du Colombier di->type = SCONST; 888219b2ee8SDavid du Colombier di->value = dtype; 889219b2ee8SDavid du Colombier dtype += 4; 890219b2ee8SDavid du Colombier } 891219b2ee8SDavid du Colombier if(p->from.sym == S) 892219b2ee8SDavid du Colombier break; 893219b2ee8SDavid du Colombier 894219b2ee8SDavid du Colombier p->from.offset = di->value; 895219b2ee8SDavid du Colombier p->from.sym->type = SDATA; 896219b2ee8SDavid du Colombier if(curtext == P) { 8976b6b9ac8SDavid du Colombier diag("DYNT not in text: %P", p); 898219b2ee8SDavid du Colombier break; 899219b2ee8SDavid du Colombier } 900219b2ee8SDavid du Colombier p->to.sym = curtext->from.sym; 901219b2ee8SDavid du Colombier p->to.type = D_ADDR; 902219b2ee8SDavid du Colombier p->to.index = D_EXTERN; 903219b2ee8SDavid du Colombier goto data; 904219b2ee8SDavid du Colombier 905219b2ee8SDavid du Colombier case AINIT: 906219b2ee8SDavid du Colombier if(p->from.sym == S) { 9076b6b9ac8SDavid du Colombier diag("INIT without a sym\n%P", p); 908219b2ee8SDavid du Colombier break; 909219b2ee8SDavid du Colombier } 910219b2ee8SDavid du Colombier if(di == S) { 9116b6b9ac8SDavid du Colombier diag("INIT without previous DYNT\n%P", p); 912219b2ee8SDavid du Colombier break; 913219b2ee8SDavid du Colombier } 914219b2ee8SDavid du Colombier p->from.offset = di->value; 915219b2ee8SDavid du Colombier p->from.sym->type = SDATA; 916219b2ee8SDavid du Colombier goto data; 917219b2ee8SDavid du Colombier 9183e12c5d1SDavid du Colombier case ADATA: 919219b2ee8SDavid du Colombier data: 9203e12c5d1SDavid du Colombier if(edatap == P) 9213e12c5d1SDavid du Colombier datap = p; 9223e12c5d1SDavid du Colombier else 9233e12c5d1SDavid du Colombier edatap->link = p; 9243e12c5d1SDavid du Colombier edatap = p; 9253e12c5d1SDavid du Colombier p->link = P; 9263e12c5d1SDavid du Colombier goto loop; 9273e12c5d1SDavid du Colombier 9283e12c5d1SDavid du Colombier case AGOK: 9296b6b9ac8SDavid du Colombier diag("%s: GOK opcode in %s", pn, TNAME); 9303e12c5d1SDavid du Colombier pc++; 9313e12c5d1SDavid du Colombier goto loop; 9323e12c5d1SDavid du Colombier 9333e12c5d1SDavid du Colombier case ATEXT: 9343e12c5d1SDavid du Colombier if(curtext != P) { 9353e12c5d1SDavid du Colombier histtoauto(); 9363e12c5d1SDavid du Colombier curtext->to.autom = curauto; 9373e12c5d1SDavid du Colombier curauto = 0; 9383e12c5d1SDavid du Colombier } 939219b2ee8SDavid du Colombier skip = 0; 9403e12c5d1SDavid du Colombier curtext = p; 9413e12c5d1SDavid du Colombier s = p->from.sym; 9423e12c5d1SDavid du Colombier if(s == S) { 9436b6b9ac8SDavid du Colombier diag("%s: no TEXT symbol: %P", pn, p); 9443e12c5d1SDavid du Colombier errorexit(); 9453e12c5d1SDavid du Colombier } 946219b2ee8SDavid du Colombier if(s->type != 0 && s->type != SXREF) { 947219b2ee8SDavid du Colombier if(p->from.scale & DUPOK) { 948219b2ee8SDavid du Colombier skip = 1; 949219b2ee8SDavid du Colombier goto casdef; 950219b2ee8SDavid du Colombier } 9516b6b9ac8SDavid du Colombier diag("%s: redefinition: %s\n%P", pn, s->name, p); 952219b2ee8SDavid du Colombier } 9533e12c5d1SDavid du Colombier s->type = STEXT; 954219b2ee8SDavid du Colombier s->value = pc; 955219b2ee8SDavid du Colombier lastp->link = p; 956219b2ee8SDavid du Colombier lastp = p; 957219b2ee8SDavid du Colombier p->pc = pc; 9583e12c5d1SDavid du Colombier pc++; 9593e12c5d1SDavid du Colombier if(textp == P) { 9603e12c5d1SDavid du Colombier textp = p; 9613e12c5d1SDavid du Colombier etextp = p; 9623e12c5d1SDavid du Colombier goto loop; 9633e12c5d1SDavid du Colombier } 9647dd7cddfSDavid du Colombier etextp->pcond = p; 9653e12c5d1SDavid du Colombier etextp = p; 9663e12c5d1SDavid du Colombier goto loop; 9673e12c5d1SDavid du Colombier 9683e12c5d1SDavid du Colombier case AFMOVF: 9693e12c5d1SDavid du Colombier case AFADDF: 9703e12c5d1SDavid du Colombier case AFSUBF: 9713e12c5d1SDavid du Colombier case AFSUBRF: 9723e12c5d1SDavid du Colombier case AFMULF: 9733e12c5d1SDavid du Colombier case AFDIVF: 9743e12c5d1SDavid du Colombier case AFDIVRF: 9753e12c5d1SDavid du Colombier case AFCOMF: 9763e12c5d1SDavid du Colombier case AFCOMFP: 977219b2ee8SDavid du Colombier if(skip) 978219b2ee8SDavid du Colombier goto casdef; 9793e12c5d1SDavid du Colombier if(p->from.type == D_FCONST) { 9803e12c5d1SDavid du Colombier /* size sb 9 max */ 9813e12c5d1SDavid du Colombier sprint(literal, "$%lux", ieeedtof(&p->from.ieee)); 9823e12c5d1SDavid du Colombier s = lookup(literal, 0); 9833e12c5d1SDavid du Colombier if(s->type == 0) { 9843e12c5d1SDavid du Colombier s->type = SBSS; 9853e12c5d1SDavid du Colombier s->value = 4; 9863e12c5d1SDavid du Colombier t = prg(); 9873e12c5d1SDavid du Colombier t->as = ADATA; 9883e12c5d1SDavid du Colombier t->line = p->line; 9893e12c5d1SDavid du Colombier t->from.type = D_EXTERN; 9903e12c5d1SDavid du Colombier t->from.sym = s; 9913e12c5d1SDavid du Colombier t->from.scale = 4; 9923e12c5d1SDavid du Colombier t->to = p->from; 9933e12c5d1SDavid du Colombier if(edatap == P) 9943e12c5d1SDavid du Colombier datap = t; 9953e12c5d1SDavid du Colombier else 9963e12c5d1SDavid du Colombier edatap->link = t; 9973e12c5d1SDavid du Colombier edatap = t; 9983e12c5d1SDavid du Colombier t->link = P; 9993e12c5d1SDavid du Colombier } 10003e12c5d1SDavid du Colombier p->from.type = D_EXTERN; 10013e12c5d1SDavid du Colombier p->from.sym = s; 10023e12c5d1SDavid du Colombier p->from.offset = 0; 10033e12c5d1SDavid du Colombier } 10043e12c5d1SDavid du Colombier goto casdef; 10053e12c5d1SDavid du Colombier 10063e12c5d1SDavid du Colombier case AFMOVD: 10073e12c5d1SDavid du Colombier case AFADDD: 10083e12c5d1SDavid du Colombier case AFSUBD: 10093e12c5d1SDavid du Colombier case AFSUBRD: 10103e12c5d1SDavid du Colombier case AFMULD: 10113e12c5d1SDavid du Colombier case AFDIVD: 10123e12c5d1SDavid du Colombier case AFDIVRD: 10133e12c5d1SDavid du Colombier case AFCOMD: 10143e12c5d1SDavid du Colombier case AFCOMDP: 1015219b2ee8SDavid du Colombier if(skip) 1016219b2ee8SDavid du Colombier goto casdef; 10173e12c5d1SDavid du Colombier if(p->from.type == D_FCONST) { 10183e12c5d1SDavid du Colombier /* size sb 18 max */ 10193e12c5d1SDavid du Colombier sprint(literal, "$%lux.%lux", 10203e12c5d1SDavid du Colombier p->from.ieee.l, p->from.ieee.h); 10213e12c5d1SDavid du Colombier s = lookup(literal, 0); 10223e12c5d1SDavid du Colombier if(s->type == 0) { 10233e12c5d1SDavid du Colombier s->type = SBSS; 10243e12c5d1SDavid du Colombier s->value = 8; 10253e12c5d1SDavid du Colombier t = prg(); 10263e12c5d1SDavid du Colombier t->as = ADATA; 10273e12c5d1SDavid du Colombier t->line = p->line; 10283e12c5d1SDavid du Colombier t->from.type = D_EXTERN; 10293e12c5d1SDavid du Colombier t->from.sym = s; 10303e12c5d1SDavid du Colombier t->from.scale = 8; 10313e12c5d1SDavid du Colombier t->to = p->from; 10323e12c5d1SDavid du Colombier if(edatap == P) 10333e12c5d1SDavid du Colombier datap = t; 10343e12c5d1SDavid du Colombier else 10353e12c5d1SDavid du Colombier edatap->link = t; 10363e12c5d1SDavid du Colombier edatap = t; 10373e12c5d1SDavid du Colombier t->link = P; 10383e12c5d1SDavid du Colombier } 10393e12c5d1SDavid du Colombier p->from.type = D_EXTERN; 10403e12c5d1SDavid du Colombier p->from.sym = s; 10413e12c5d1SDavid du Colombier p->from.offset = 0; 10423e12c5d1SDavid du Colombier } 10433e12c5d1SDavid du Colombier goto casdef; 10443e12c5d1SDavid du Colombier 10453e12c5d1SDavid du Colombier casdef: 10463e12c5d1SDavid du Colombier default: 1047219b2ee8SDavid du Colombier if(skip) 1048219b2ee8SDavid du Colombier nopout(p); 1049219b2ee8SDavid du Colombier 10503e12c5d1SDavid du Colombier if(p->to.type == D_BRANCH) 10513e12c5d1SDavid du Colombier p->to.offset += ipc; 10523e12c5d1SDavid du Colombier lastp->link = p; 10533e12c5d1SDavid du Colombier lastp = p; 10543e12c5d1SDavid du Colombier p->pc = pc; 10553e12c5d1SDavid du Colombier pc++; 10563e12c5d1SDavid du Colombier goto loop; 10573e12c5d1SDavid du Colombier } 10583e12c5d1SDavid du Colombier goto loop; 10593e12c5d1SDavid du Colombier 10603e12c5d1SDavid du Colombier eof: 10616b6b9ac8SDavid du Colombier diag("truncated object file: %s", pn); 10623e12c5d1SDavid du Colombier } 10633e12c5d1SDavid du Colombier 10643e12c5d1SDavid du Colombier Sym* 10653e12c5d1SDavid du Colombier lookup(char *symb, int v) 10663e12c5d1SDavid du Colombier { 10673e12c5d1SDavid du Colombier Sym *s; 10683e12c5d1SDavid du Colombier char *p; 10693e12c5d1SDavid du Colombier long h; 1070219b2ee8SDavid du Colombier int l, c; 10713e12c5d1SDavid du Colombier 10723e12c5d1SDavid du Colombier h = v; 1073219b2ee8SDavid du Colombier for(p=symb; c = *p; p++) 10743e12c5d1SDavid du Colombier h = h+h+h + c; 1075219b2ee8SDavid du Colombier l = (p - symb) + 1; 10763e12c5d1SDavid du Colombier if(h < 0) 10773e12c5d1SDavid du Colombier h = ~h; 10783e12c5d1SDavid du Colombier h %= NHASH; 1079219b2ee8SDavid du Colombier for(s = hash[h]; s != S; s = s->link) 10803e12c5d1SDavid du Colombier if(s->version == v) 1081219b2ee8SDavid du Colombier if(memcmp(s->name, symb, l) == 0) 10823e12c5d1SDavid du Colombier return s; 10833e12c5d1SDavid du Colombier 10843e12c5d1SDavid du Colombier while(nhunk < sizeof(Sym)) 10853e12c5d1SDavid du Colombier gethunk(); 10863e12c5d1SDavid du Colombier s = (Sym*)hunk; 10873e12c5d1SDavid du Colombier nhunk -= sizeof(Sym); 10883e12c5d1SDavid du Colombier hunk += sizeof(Sym); 10893e12c5d1SDavid du Colombier 1090219b2ee8SDavid du Colombier s->name = malloc(l + 1); 1091219b2ee8SDavid du Colombier memmove(s->name, symb, l); 1092219b2ee8SDavid du Colombier 10933e12c5d1SDavid du Colombier s->link = hash[h]; 10943e12c5d1SDavid du Colombier s->type = 0; 10953e12c5d1SDavid du Colombier s->version = v; 10963e12c5d1SDavid du Colombier s->value = 0; 1097*375daca8SDavid du Colombier s->sig = 0; 10983e12c5d1SDavid du Colombier hash[h] = s; 10993e12c5d1SDavid du Colombier nsymbol++; 11003e12c5d1SDavid du Colombier return s; 11013e12c5d1SDavid du Colombier } 11023e12c5d1SDavid du Colombier 11033e12c5d1SDavid du Colombier Prog* 11043e12c5d1SDavid du Colombier prg(void) 11053e12c5d1SDavid du Colombier { 11063e12c5d1SDavid du Colombier Prog *p; 11073e12c5d1SDavid du Colombier 11083e12c5d1SDavid du Colombier while(nhunk < sizeof(Prog)) 11093e12c5d1SDavid du Colombier gethunk(); 11103e12c5d1SDavid du Colombier p = (Prog*)hunk; 11113e12c5d1SDavid du Colombier nhunk -= sizeof(Prog); 11123e12c5d1SDavid du Colombier hunk += sizeof(Prog); 11133e12c5d1SDavid du Colombier 11143e12c5d1SDavid du Colombier *p = zprg; 11153e12c5d1SDavid du Colombier return p; 11163e12c5d1SDavid du Colombier } 11173e12c5d1SDavid du Colombier 11183e12c5d1SDavid du Colombier Prog* 11193e12c5d1SDavid du Colombier copyp(Prog *q) 11203e12c5d1SDavid du Colombier { 11213e12c5d1SDavid du Colombier Prog *p; 11223e12c5d1SDavid du Colombier 11233e12c5d1SDavid du Colombier p = prg(); 11243e12c5d1SDavid du Colombier *p = *q; 11253e12c5d1SDavid du Colombier return p; 11263e12c5d1SDavid du Colombier } 11273e12c5d1SDavid du Colombier 11283e12c5d1SDavid du Colombier Prog* 11293e12c5d1SDavid du Colombier appendp(Prog *q) 11303e12c5d1SDavid du Colombier { 11313e12c5d1SDavid du Colombier Prog *p; 11323e12c5d1SDavid du Colombier 11333e12c5d1SDavid du Colombier p = prg(); 11343e12c5d1SDavid du Colombier p->link = q->link; 11353e12c5d1SDavid du Colombier q->link = p; 11363e12c5d1SDavid du Colombier p->line = q->line; 11373e12c5d1SDavid du Colombier return p; 11383e12c5d1SDavid du Colombier } 11393e12c5d1SDavid du Colombier 11403e12c5d1SDavid du Colombier void 11413e12c5d1SDavid du Colombier gethunk(void) 11423e12c5d1SDavid du Colombier { 11433e12c5d1SDavid du Colombier char *h; 11443e12c5d1SDavid du Colombier long nh; 11453e12c5d1SDavid du Colombier 11463e12c5d1SDavid du Colombier nh = NHUNK; 11473e12c5d1SDavid du Colombier if(thunk >= 5L*NHUNK) { 11483e12c5d1SDavid du Colombier nh = 5L*NHUNK; 11493e12c5d1SDavid du Colombier if(thunk >= 25L*NHUNK) 11503e12c5d1SDavid du Colombier nh = 25L*NHUNK; 11513e12c5d1SDavid du Colombier } 11527dd7cddfSDavid du Colombier h = mysbrk(nh); 11533e12c5d1SDavid du Colombier if(h == (char*)-1) { 11546b6b9ac8SDavid du Colombier diag("out of memory"); 11553e12c5d1SDavid du Colombier errorexit(); 11563e12c5d1SDavid du Colombier } 11573e12c5d1SDavid du Colombier hunk = h; 11583e12c5d1SDavid du Colombier nhunk = nh; 11593e12c5d1SDavid du Colombier thunk += nh; 11603e12c5d1SDavid du Colombier } 11613e12c5d1SDavid du Colombier 11623e12c5d1SDavid du Colombier void 11633e12c5d1SDavid du Colombier doprof1(void) 11643e12c5d1SDavid du Colombier { 11653e12c5d1SDavid du Colombier Sym *s; 11663e12c5d1SDavid du Colombier long n; 11673e12c5d1SDavid du Colombier Prog *p, *q; 11683e12c5d1SDavid du Colombier 11693e12c5d1SDavid du Colombier if(debug['v']) 11703e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f profile 1\n", cputime()); 11713e12c5d1SDavid du Colombier Bflush(&bso); 11723e12c5d1SDavid du Colombier s = lookup("__mcount", 0); 11733e12c5d1SDavid du Colombier n = 1; 11743e12c5d1SDavid du Colombier for(p = firstp->link; p != P; p = p->link) { 11753e12c5d1SDavid du Colombier if(p->as == ATEXT) { 11763e12c5d1SDavid du Colombier q = prg(); 11773e12c5d1SDavid du Colombier q->line = p->line; 11783e12c5d1SDavid du Colombier q->link = datap; 11793e12c5d1SDavid du Colombier datap = q; 11803e12c5d1SDavid du Colombier q->as = ADATA; 11813e12c5d1SDavid du Colombier q->from.type = D_EXTERN; 11823e12c5d1SDavid du Colombier q->from.offset = n*4; 11833e12c5d1SDavid du Colombier q->from.sym = s; 11843e12c5d1SDavid du Colombier q->from.scale = 4; 11853e12c5d1SDavid du Colombier q->to = p->from; 11863e12c5d1SDavid du Colombier q->to.type = D_CONST; 11873e12c5d1SDavid du Colombier 11883e12c5d1SDavid du Colombier q = prg(); 11893e12c5d1SDavid du Colombier q->line = p->line; 11903e12c5d1SDavid du Colombier q->pc = p->pc; 11913e12c5d1SDavid du Colombier q->link = p->link; 11923e12c5d1SDavid du Colombier p->link = q; 11933e12c5d1SDavid du Colombier p = q; 11943e12c5d1SDavid du Colombier p->as = AADDL; 11953e12c5d1SDavid du Colombier p->from.type = D_CONST; 11963e12c5d1SDavid du Colombier p->from.offset = 1; 11973e12c5d1SDavid du Colombier p->to.type = D_EXTERN; 11983e12c5d1SDavid du Colombier p->to.sym = s; 11993e12c5d1SDavid du Colombier p->to.offset = n*4 + 4; 12003e12c5d1SDavid du Colombier 12013e12c5d1SDavid du Colombier n += 2; 12023e12c5d1SDavid du Colombier continue; 12033e12c5d1SDavid du Colombier } 12043e12c5d1SDavid du Colombier } 12053e12c5d1SDavid du Colombier q = prg(); 12063e12c5d1SDavid du Colombier q->line = 0; 12073e12c5d1SDavid du Colombier q->link = datap; 12083e12c5d1SDavid du Colombier datap = q; 12093e12c5d1SDavid du Colombier 12103e12c5d1SDavid du Colombier q->as = ADATA; 12113e12c5d1SDavid du Colombier q->from.type = D_EXTERN; 12123e12c5d1SDavid du Colombier q->from.sym = s; 12133e12c5d1SDavid du Colombier q->from.scale = 4; 12143e12c5d1SDavid du Colombier q->to.type = D_CONST; 12153e12c5d1SDavid du Colombier q->to.offset = n; 12163e12c5d1SDavid du Colombier 12173e12c5d1SDavid du Colombier s->type = SBSS; 12183e12c5d1SDavid du Colombier s->value = n*4; 12193e12c5d1SDavid du Colombier } 12203e12c5d1SDavid du Colombier 12213e12c5d1SDavid du Colombier void 12223e12c5d1SDavid du Colombier doprof2(void) 12233e12c5d1SDavid du Colombier { 12243e12c5d1SDavid du Colombier Sym *s2, *s4; 12253e12c5d1SDavid du Colombier Prog *p, *q, *ps2, *ps4; 12263e12c5d1SDavid du Colombier 12273e12c5d1SDavid du Colombier if(debug['v']) 12283e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f profile 2\n", cputime()); 12293e12c5d1SDavid du Colombier Bflush(&bso); 12303e12c5d1SDavid du Colombier 12313e12c5d1SDavid du Colombier s2 = lookup("_profin", 0); 12323e12c5d1SDavid du Colombier s4 = lookup("_profout", 0); 123359cc4ca5SDavid du Colombier if(s2->type != STEXT || s4->type != STEXT) { 12346b6b9ac8SDavid du Colombier diag("_profin/_profout not defined"); 123559cc4ca5SDavid du Colombier return; 123659cc4ca5SDavid du Colombier } 12373e12c5d1SDavid du Colombier 12383e12c5d1SDavid du Colombier ps2 = P; 12393e12c5d1SDavid du Colombier ps4 = P; 12403e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) { 12413e12c5d1SDavid du Colombier if(p->as == ATEXT) { 12423e12c5d1SDavid du Colombier if(p->from.sym == s2) { 12433e12c5d1SDavid du Colombier p->from.scale = 1; 12443e12c5d1SDavid du Colombier ps2 = p; 12453e12c5d1SDavid du Colombier } 12463e12c5d1SDavid du Colombier if(p->from.sym == s4) { 12473e12c5d1SDavid du Colombier p->from.scale = 1; 12483e12c5d1SDavid du Colombier ps4 = p; 12493e12c5d1SDavid du Colombier } 12503e12c5d1SDavid du Colombier } 12513e12c5d1SDavid du Colombier } 12523e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) { 12533e12c5d1SDavid du Colombier if(p->as == ATEXT) { 12543e12c5d1SDavid du Colombier curtext = p; 12553e12c5d1SDavid du Colombier 1256219b2ee8SDavid du Colombier if(p->from.scale & NOPROF) { /* dont profile */ 12573e12c5d1SDavid du Colombier for(;;) { 12583e12c5d1SDavid du Colombier q = p->link; 12593e12c5d1SDavid du Colombier if(q == P) 12603e12c5d1SDavid du Colombier break; 12613e12c5d1SDavid du Colombier if(q->as == ATEXT) 12623e12c5d1SDavid du Colombier break; 12633e12c5d1SDavid du Colombier p = q; 12643e12c5d1SDavid du Colombier } 12653e12c5d1SDavid du Colombier continue; 12663e12c5d1SDavid du Colombier } 12673e12c5d1SDavid du Colombier 12683e12c5d1SDavid du Colombier /* 12693e12c5d1SDavid du Colombier * JMPL profin 12703e12c5d1SDavid du Colombier */ 12713e12c5d1SDavid du Colombier q = prg(); 12723e12c5d1SDavid du Colombier q->line = p->line; 12733e12c5d1SDavid du Colombier q->pc = p->pc; 12743e12c5d1SDavid du Colombier q->link = p->link; 12753e12c5d1SDavid du Colombier p->link = q; 12763e12c5d1SDavid du Colombier p = q; 12773e12c5d1SDavid du Colombier p->as = ACALL; 12783e12c5d1SDavid du Colombier p->to.type = D_BRANCH; 12797dd7cddfSDavid du Colombier p->pcond = ps2; 12803e12c5d1SDavid du Colombier p->to.sym = s2; 12813e12c5d1SDavid du Colombier 12823e12c5d1SDavid du Colombier continue; 12833e12c5d1SDavid du Colombier } 12843e12c5d1SDavid du Colombier if(p->as == ARET) { 1285219b2ee8SDavid du Colombier /* 1286219b2ee8SDavid du Colombier * RET 1287219b2ee8SDavid du Colombier */ 1288219b2ee8SDavid du Colombier q = prg(); 1289219b2ee8SDavid du Colombier q->as = ARET; 1290219b2ee8SDavid du Colombier q->from = p->from; 1291219b2ee8SDavid du Colombier q->to = p->to; 1292219b2ee8SDavid du Colombier q->link = p->link; 1293219b2ee8SDavid du Colombier p->link = q; 12943e12c5d1SDavid du Colombier 12953e12c5d1SDavid du Colombier /* 1296219b2ee8SDavid du Colombier * JAL profout 12973e12c5d1SDavid du Colombier */ 12983e12c5d1SDavid du Colombier p->as = ACALL; 12993e12c5d1SDavid du Colombier p->from = zprg.from; 13003e12c5d1SDavid du Colombier p->to = zprg.to; 13013e12c5d1SDavid du Colombier p->to.type = D_BRANCH; 13027dd7cddfSDavid du Colombier p->pcond = ps4; 13033e12c5d1SDavid du Colombier p->to.sym = s4; 13043e12c5d1SDavid du Colombier 13053e12c5d1SDavid du Colombier p = q; 13063e12c5d1SDavid du Colombier 13073e12c5d1SDavid du Colombier continue; 13083e12c5d1SDavid du Colombier } 13093e12c5d1SDavid du Colombier } 13103e12c5d1SDavid du Colombier } 13113e12c5d1SDavid du Colombier 13123e12c5d1SDavid du Colombier void 13133e12c5d1SDavid du Colombier nuxiinit(void) 13143e12c5d1SDavid du Colombier { 13153e12c5d1SDavid du Colombier int i, c; 13163e12c5d1SDavid du Colombier 13173e12c5d1SDavid du Colombier for(i=0; i<4; i++) { 13183e12c5d1SDavid du Colombier c = find1(0x04030201L, i+1); 13193e12c5d1SDavid du Colombier if(i < 2) 13203e12c5d1SDavid du Colombier inuxi2[i] = c; 13213e12c5d1SDavid du Colombier if(i < 1) 13223e12c5d1SDavid du Colombier inuxi1[i] = c; 13233e12c5d1SDavid du Colombier inuxi4[i] = c; 13243e12c5d1SDavid du Colombier fnuxi4[i] = c; 13253e12c5d1SDavid du Colombier fnuxi8[i] = c; 13263e12c5d1SDavid du Colombier fnuxi8[i+4] = c+4; 13273e12c5d1SDavid du Colombier } 13283e12c5d1SDavid du Colombier if(debug['v']) { 13293e12c5d1SDavid du Colombier Bprint(&bso, "inuxi = "); 13303e12c5d1SDavid du Colombier for(i=0; i<1; i++) 13313e12c5d1SDavid du Colombier Bprint(&bso, "%d", inuxi1[i]); 13323e12c5d1SDavid du Colombier Bprint(&bso, " "); 13333e12c5d1SDavid du Colombier for(i=0; i<2; i++) 13343e12c5d1SDavid du Colombier Bprint(&bso, "%d", inuxi2[i]); 13353e12c5d1SDavid du Colombier Bprint(&bso, " "); 13363e12c5d1SDavid du Colombier for(i=0; i<4; i++) 13373e12c5d1SDavid du Colombier Bprint(&bso, "%d", inuxi4[i]); 13383e12c5d1SDavid du Colombier Bprint(&bso, "\nfnuxi = "); 13393e12c5d1SDavid du Colombier for(i=0; i<4; i++) 13403e12c5d1SDavid du Colombier Bprint(&bso, "%d", fnuxi4[i]); 13413e12c5d1SDavid du Colombier Bprint(&bso, " "); 13423e12c5d1SDavid du Colombier for(i=0; i<8; i++) 13433e12c5d1SDavid du Colombier Bprint(&bso, "%d", fnuxi8[i]); 13443e12c5d1SDavid du Colombier Bprint(&bso, "\n"); 13453e12c5d1SDavid du Colombier } 13463e12c5d1SDavid du Colombier Bflush(&bso); 13473e12c5d1SDavid du Colombier } 13483e12c5d1SDavid du Colombier 13493e12c5d1SDavid du Colombier int 13503e12c5d1SDavid du Colombier find1(long l, int c) 13513e12c5d1SDavid du Colombier { 13523e12c5d1SDavid du Colombier char *p; 13533e12c5d1SDavid du Colombier int i; 13543e12c5d1SDavid du Colombier 13553e12c5d1SDavid du Colombier p = (char*)&l; 13563e12c5d1SDavid du Colombier for(i=0; i<4; i++) 13573e12c5d1SDavid du Colombier if(*p++ == c) 13583e12c5d1SDavid du Colombier return i; 13593e12c5d1SDavid du Colombier return 0; 13603e12c5d1SDavid du Colombier } 13613e12c5d1SDavid du Colombier 13623e12c5d1SDavid du Colombier int 13633e12c5d1SDavid du Colombier find2(long l, int c) 13643e12c5d1SDavid du Colombier { 13653e12c5d1SDavid du Colombier short *p; 13663e12c5d1SDavid du Colombier int i; 13673e12c5d1SDavid du Colombier 13683e12c5d1SDavid du Colombier p = (short*)&l; 13693e12c5d1SDavid du Colombier for(i=0; i<4; i+=2) { 13703e12c5d1SDavid du Colombier if(((*p >> 8) & 0xff) == c) 13713e12c5d1SDavid du Colombier return i; 13723e12c5d1SDavid du Colombier if((*p++ & 0xff) == c) 13733e12c5d1SDavid du Colombier return i+1; 13743e12c5d1SDavid du Colombier } 13753e12c5d1SDavid du Colombier return 0; 13763e12c5d1SDavid du Colombier } 13773e12c5d1SDavid du Colombier 13783e12c5d1SDavid du Colombier long 13793e12c5d1SDavid du Colombier ieeedtof(Ieee *e) 13803e12c5d1SDavid du Colombier { 13813e12c5d1SDavid du Colombier int exp; 13823e12c5d1SDavid du Colombier long v; 13833e12c5d1SDavid du Colombier 13843e12c5d1SDavid du Colombier if(e->h == 0) 13853e12c5d1SDavid du Colombier return 0; 13863e12c5d1SDavid du Colombier exp = (e->h>>20) & ((1L<<11)-1L); 13873e12c5d1SDavid du Colombier exp -= (1L<<10) - 2L; 13883e12c5d1SDavid du Colombier v = (e->h & 0xfffffL) << 3; 13893e12c5d1SDavid du Colombier v |= (e->l >> 29) & 0x7L; 13903e12c5d1SDavid du Colombier if((e->l >> 28) & 1) { 13913e12c5d1SDavid du Colombier v++; 13923e12c5d1SDavid du Colombier if(v & 0x800000L) { 13933e12c5d1SDavid du Colombier v = (v & 0x7fffffL) >> 1; 13943e12c5d1SDavid du Colombier exp++; 13953e12c5d1SDavid du Colombier } 13963e12c5d1SDavid du Colombier } 13973e12c5d1SDavid du Colombier if(exp <= -126 || exp >= 130) 13986b6b9ac8SDavid du Colombier diag("double fp to single fp overflow"); 13993e12c5d1SDavid du Colombier v |= ((exp + 126) & 0xffL) << 23; 14003e12c5d1SDavid du Colombier v |= e->h & 0x80000000L; 14013e12c5d1SDavid du Colombier return v; 14023e12c5d1SDavid du Colombier } 14033e12c5d1SDavid du Colombier 14043e12c5d1SDavid du Colombier double 14057dd7cddfSDavid du Colombier ieeedtod(Ieee *ieeep) 14063e12c5d1SDavid du Colombier { 14073e12c5d1SDavid du Colombier Ieee e; 14083e12c5d1SDavid du Colombier double fr; 14093e12c5d1SDavid du Colombier int exp; 14103e12c5d1SDavid du Colombier 14117dd7cddfSDavid du Colombier if(ieeep->h & (1L<<31)) { 14127dd7cddfSDavid du Colombier e.h = ieeep->h & ~(1L<<31); 14137dd7cddfSDavid du Colombier e.l = ieeep->l; 14143e12c5d1SDavid du Colombier return -ieeedtod(&e); 14153e12c5d1SDavid du Colombier } 14167dd7cddfSDavid du Colombier if(ieeep->l == 0 && ieeep->h == 0) 14173e12c5d1SDavid du Colombier return 0; 14187dd7cddfSDavid du Colombier fr = ieeep->l & ((1L<<16)-1L); 14193e12c5d1SDavid du Colombier fr /= 1L<<16; 14207dd7cddfSDavid du Colombier fr += (ieeep->l>>16) & ((1L<<16)-1L); 14213e12c5d1SDavid du Colombier fr /= 1L<<16; 14227dd7cddfSDavid du Colombier fr += (ieeep->h & (1L<<20)-1L) | (1L<<20); 14233e12c5d1SDavid du Colombier fr /= 1L<<21; 14247dd7cddfSDavid du Colombier exp = (ieeep->h>>20) & ((1L<<11)-1L); 14253e12c5d1SDavid du Colombier exp -= (1L<<10) - 2L; 14263e12c5d1SDavid du Colombier return ldexp(fr, exp); 14273e12c5d1SDavid du Colombier } 14289a747e4fSDavid du Colombier 14299a747e4fSDavid du Colombier void 1430*375daca8SDavid du Colombier undefsym(Sym *s) 1431*375daca8SDavid du Colombier { 1432*375daca8SDavid du Colombier int n; 1433*375daca8SDavid du Colombier 1434*375daca8SDavid du Colombier n = imports; 1435*375daca8SDavid du Colombier if(s->value != 0) 1436*375daca8SDavid du Colombier diag("value != 0 on SXREF"); 1437*375daca8SDavid du Colombier if(n >= 1<<Rindex) 1438*375daca8SDavid du Colombier diag("import index %d out of range", n); 1439*375daca8SDavid du Colombier s->value = n<<Roffset; 1440*375daca8SDavid du Colombier s->type = SUNDEF; 1441*375daca8SDavid du Colombier imports++; 1442*375daca8SDavid du Colombier } 1443*375daca8SDavid du Colombier 1444*375daca8SDavid du Colombier void 1445*375daca8SDavid du Colombier zerosig(char *sp) 1446*375daca8SDavid du Colombier { 1447*375daca8SDavid du Colombier Sym *s; 1448*375daca8SDavid du Colombier 1449*375daca8SDavid du Colombier s = lookup(sp, 0); 1450*375daca8SDavid du Colombier s->sig = 0; 1451*375daca8SDavid du Colombier } 1452*375daca8SDavid du Colombier 1453*375daca8SDavid du Colombier void 1454*375daca8SDavid du Colombier readundefs(char *f, int t) 14559a747e4fSDavid du Colombier { 14569a747e4fSDavid du Colombier int i, n; 14579a747e4fSDavid du Colombier Sym *s; 14589a747e4fSDavid du Colombier Biobuf *b; 1459*375daca8SDavid du Colombier char *l, buf[256], *fields[64]; 14609a747e4fSDavid du Colombier 1461*375daca8SDavid du Colombier if(f == nil) 1462*375daca8SDavid du Colombier return; 1463*375daca8SDavid du Colombier b = Bopen(f, OREAD); 14649a747e4fSDavid du Colombier if(b == nil){ 1465*375daca8SDavid du Colombier diag("could not open %s: %r", f); 14669a747e4fSDavid du Colombier errorexit(); 14679a747e4fSDavid du Colombier } 14689a747e4fSDavid du Colombier while((l = Brdline(b, '\n')) != nil){ 14699a747e4fSDavid du Colombier n = Blinelen(b); 14709a747e4fSDavid du Colombier if(n >= sizeof(buf)){ 1471*375daca8SDavid du Colombier diag("%s: line too long", f); 14729a747e4fSDavid du Colombier errorexit(); 14739a747e4fSDavid du Colombier } 1474*375daca8SDavid du Colombier memmove(buf, l, n); 1475*375daca8SDavid du Colombier buf[n-1] = '\0'; 14769a747e4fSDavid du Colombier n = getfields(buf, fields, nelem(fields), 1, " \t\r\n"); 14779a747e4fSDavid du Colombier if(n == nelem(fields)){ 1478*375daca8SDavid du Colombier diag("%s: bad format", f); 14799a747e4fSDavid du Colombier errorexit(); 14809a747e4fSDavid du Colombier } 1481*375daca8SDavid du Colombier for(i = 0; i < n; i++){ 1482*375daca8SDavid du Colombier s = lookup(fields[i], 0); 1483*375daca8SDavid du Colombier s->type = SXREF; 1484*375daca8SDavid du Colombier s->subtype = t; 1485*375daca8SDavid du Colombier if(t == SIMPORT) 1486*375daca8SDavid du Colombier nimports++; 1487*375daca8SDavid du Colombier else 1488*375daca8SDavid du Colombier nexports++; 1489*375daca8SDavid du Colombier } 14909a747e4fSDavid du Colombier } 14919a747e4fSDavid du Colombier Bterm(b); 14929a747e4fSDavid du Colombier } 1493