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 14b87cd620SDavid du Colombier char** libdir; 15b87cd620SDavid du Colombier int nlibdir = 0; 16b87cd620SDavid du Colombier static int maxlibdir = 0; 17b87cd620SDavid du Colombier 183e12c5d1SDavid du Colombier /* 193e12c5d1SDavid du Colombier * -H0 -T0x40004C -D0x10000000 is garbage unix 203e12c5d1SDavid du Colombier * -H1 -T0xd0 -R4 is unix coff 213e12c5d1SDavid du Colombier * -H2 -T4128 -R4096 is plan9 format 22219b2ee8SDavid du Colombier * -H3 -Tx -Rx is MS-DOS .COM 23219b2ee8SDavid du Colombier * -H4 -Tx -Rx is fake MS-DOS .EXE 24260f7b65SDavid du Colombier * -H5 -T0x80100020 -R4096 is ELF 253e12c5d1SDavid du Colombier */ 263e12c5d1SDavid du Colombier 27b87cd620SDavid du Colombier void 28b87cd620SDavid du Colombier usage(void) 29b87cd620SDavid du Colombier { 30*6af32fc1SDavid du Colombier diag("usage: %s [-options] objects", argv0); 31b87cd620SDavid du Colombier errorexit(); 32b87cd620SDavid du Colombier } 33b87cd620SDavid du Colombier 34375daca8SDavid du Colombier static int 35375daca8SDavid du Colombier isobjfile(char *f) 36375daca8SDavid du Colombier { 37375daca8SDavid du Colombier int n, v; 38375daca8SDavid du Colombier Biobuf *b; 39375daca8SDavid du Colombier char buf1[5], buf2[SARMAG]; 40375daca8SDavid du Colombier 41375daca8SDavid du Colombier b = Bopen(f, OREAD); 42375daca8SDavid du Colombier if(b == nil) 43375daca8SDavid du Colombier return 0; 44375daca8SDavid du Colombier n = Bread(b, buf1, 5); 45375daca8SDavid du Colombier if(n == 5 && (buf1[2] == 1 && buf1[3] == '<' || buf1[3] == 1 && buf1[4] == '<')) 46375daca8SDavid du Colombier v = 1; /* good enough for our purposes */ 47375daca8SDavid du Colombier else{ 48375daca8SDavid du Colombier Bseek(b, 0, 0); 49375daca8SDavid du Colombier n = Bread(b, buf2, SARMAG); 50375daca8SDavid du Colombier v = n == SARMAG && strncmp(buf2, ARMAG, SARMAG) == 0; 51375daca8SDavid du Colombier } 52375daca8SDavid du Colombier Bterm(b); 53375daca8SDavid du Colombier return v; 54375daca8SDavid du Colombier } 55375daca8SDavid du Colombier 563e12c5d1SDavid du Colombier void 573e12c5d1SDavid du Colombier main(int argc, char *argv[]) 583e12c5d1SDavid du Colombier { 593e12c5d1SDavid du Colombier int i, c; 603e12c5d1SDavid du Colombier char *a; 61b87cd620SDavid du Colombier char name[LIBNAMELEN]; 623e12c5d1SDavid du Colombier 633e12c5d1SDavid du Colombier Binit(&bso, 1, OWRITE); 643e12c5d1SDavid du Colombier cout = -1; 653e12c5d1SDavid du Colombier listinit(); 663e12c5d1SDavid du Colombier memset(debug, 0, sizeof(debug)); 673e12c5d1SDavid du Colombier nerrors = 0; 683e12c5d1SDavid du Colombier outfile = "8.out"; 693e12c5d1SDavid du Colombier HEADTYPE = -1; 703e12c5d1SDavid du Colombier INITTEXT = -1; 713e12c5d1SDavid du Colombier INITDAT = -1; 723e12c5d1SDavid du Colombier INITRND = -1; 733e12c5d1SDavid du Colombier INITENTRY = 0; 743e12c5d1SDavid du Colombier ARGBEGIN { 753e12c5d1SDavid du Colombier default: 763e12c5d1SDavid du Colombier c = ARGC(); 773e12c5d1SDavid du Colombier if(c >= 0 && c < sizeof(debug)) 783e12c5d1SDavid du Colombier debug[c]++; 793e12c5d1SDavid du Colombier break; 803e12c5d1SDavid du Colombier case 'o': /* output to (next arg) */ 813e12c5d1SDavid du Colombier outfile = ARGF(); 823e12c5d1SDavid du Colombier break; 833e12c5d1SDavid du Colombier case 'E': 843e12c5d1SDavid du Colombier a = ARGF(); 853e12c5d1SDavid du Colombier if(a) 863e12c5d1SDavid du Colombier INITENTRY = a; 873e12c5d1SDavid du Colombier break; 883e12c5d1SDavid du Colombier case 'H': 893e12c5d1SDavid du Colombier a = ARGF(); 903e12c5d1SDavid du Colombier if(a) 913e12c5d1SDavid du Colombier HEADTYPE = atolwhex(a); 923e12c5d1SDavid du Colombier break; 93b87cd620SDavid du Colombier case 'L': 94b87cd620SDavid du Colombier addlibpath(EARGF(usage())); 95b87cd620SDavid du Colombier break; 963e12c5d1SDavid du Colombier case 'T': 973e12c5d1SDavid du Colombier a = ARGF(); 983e12c5d1SDavid du Colombier if(a) 993e12c5d1SDavid du Colombier INITTEXT = atolwhex(a); 1003e12c5d1SDavid du Colombier break; 1013e12c5d1SDavid du Colombier case 'D': 1023e12c5d1SDavid du Colombier a = ARGF(); 1033e12c5d1SDavid du Colombier if(a) 1043e12c5d1SDavid du Colombier INITDAT = atolwhex(a); 1053e12c5d1SDavid du Colombier break; 1063e12c5d1SDavid du Colombier case 'R': 1073e12c5d1SDavid du Colombier a = ARGF(); 1083e12c5d1SDavid du Colombier if(a) 1093e12c5d1SDavid du Colombier INITRND = atolwhex(a); 1103e12c5d1SDavid du Colombier break; 111375daca8SDavid du Colombier case 'x': /* produce export table */ 112375daca8SDavid du Colombier doexp = 1; 1136520663fSDavid du Colombier if(argv[1] != nil && argv[1][0] != '-' && !isobjfile(argv[1])){ 1146520663fSDavid du Colombier a = ARGF(); 1156520663fSDavid du Colombier if(strcmp(a, "*") == 0) 1166520663fSDavid du Colombier allexport = 1; 1176520663fSDavid du Colombier else 1186520663fSDavid du Colombier readundefs(a, SEXPORT); 1196520663fSDavid du Colombier } 120375daca8SDavid du Colombier break; 121375daca8SDavid du Colombier case 'u': /* produce dynamically loadable module */ 122375daca8SDavid du Colombier dlm = 1; 123375daca8SDavid du Colombier debug['l']++; 124375daca8SDavid du Colombier if(argv[1] != nil && argv[1][0] != '-' && !isobjfile(argv[1])) 125375daca8SDavid du Colombier readundefs(ARGF(), SIMPORT); 126375daca8SDavid du Colombier break; 1273e12c5d1SDavid du Colombier } ARGEND 1283e12c5d1SDavid du Colombier USED(argc); 129b87cd620SDavid du Colombier if(*argv == 0) 130b87cd620SDavid du Colombier usage(); 1313e12c5d1SDavid du Colombier if(!debug['9'] && !debug['U'] && !debug['B']) 1323e12c5d1SDavid du Colombier debug[DEFAULT] = 1; 133b87cd620SDavid du Colombier a = getenv("ccroot"); 134b87cd620SDavid du Colombier if(a != nil && *a != '\0') { 135b87cd620SDavid du Colombier if(!fileexists(a)) { 136b87cd620SDavid du Colombier diag("nonexistent $ccroot: %s", a); 137b87cd620SDavid du Colombier errorexit(); 138b87cd620SDavid du Colombier } 139b87cd620SDavid du Colombier }else 140b87cd620SDavid du Colombier a = ""; 141b87cd620SDavid du Colombier snprint(name, sizeof(name), "%s/%s/lib", a, thestring); 142b87cd620SDavid du Colombier addlibpath(name); 1433e12c5d1SDavid du Colombier if(HEADTYPE == -1) { 1443e12c5d1SDavid du Colombier if(debug['U']) 1453e12c5d1SDavid du Colombier HEADTYPE = 1; 1463e12c5d1SDavid du Colombier if(debug['B']) 1473e12c5d1SDavid du Colombier HEADTYPE = 2; 1483e12c5d1SDavid du Colombier if(debug['9']) 1493e12c5d1SDavid du Colombier HEADTYPE = 2; 1503e12c5d1SDavid du Colombier } 1513e12c5d1SDavid du Colombier switch(HEADTYPE) { 1523e12c5d1SDavid du Colombier default: 1533e12c5d1SDavid du Colombier diag("unknown -H option"); 1543e12c5d1SDavid du Colombier errorexit(); 1553e12c5d1SDavid du Colombier 1563e12c5d1SDavid du Colombier case 0: /* this is garbage */ 1573e12c5d1SDavid du Colombier HEADR = 20L+56L; 1583e12c5d1SDavid du Colombier if(INITTEXT == -1) 1593e12c5d1SDavid du Colombier INITTEXT = 0x40004CL; 1603e12c5d1SDavid du Colombier if(INITDAT == -1) 1613e12c5d1SDavid du Colombier INITDAT = 0x10000000L; 1623e12c5d1SDavid du Colombier if(INITRND == -1) 1633e12c5d1SDavid du Colombier INITRND = 0; 1643e12c5d1SDavid du Colombier break; 1653e12c5d1SDavid du Colombier case 1: /* is unix coff */ 1663e12c5d1SDavid du Colombier HEADR = 0xd0L; 1673e12c5d1SDavid du Colombier if(INITTEXT == -1) 1683e12c5d1SDavid du Colombier INITTEXT = 0xd0; 1693e12c5d1SDavid du Colombier if(INITDAT == -1) 1703e12c5d1SDavid du Colombier INITDAT = 0x400000; 1713e12c5d1SDavid du Colombier if(INITRND == -1) 1723e12c5d1SDavid du Colombier INITRND = 0; 1733e12c5d1SDavid du Colombier break; 1743e12c5d1SDavid du Colombier case 2: /* plan 9 */ 1753e12c5d1SDavid du Colombier HEADR = 32L; 1763e12c5d1SDavid du Colombier if(INITTEXT == -1) 1773e12c5d1SDavid du Colombier INITTEXT = 4096+32; 1783e12c5d1SDavid du Colombier if(INITDAT == -1) 1793e12c5d1SDavid du Colombier INITDAT = 0; 1803e12c5d1SDavid du Colombier if(INITRND == -1) 1813e12c5d1SDavid du Colombier INITRND = 4096; 1823e12c5d1SDavid du Colombier break; 183219b2ee8SDavid du Colombier case 3: /* MS-DOS .COM */ 1843e12c5d1SDavid du Colombier HEADR = 0; 1853e12c5d1SDavid du Colombier if(INITTEXT == -1) 1863e12c5d1SDavid du Colombier INITTEXT = 0x0100; 1873e12c5d1SDavid du Colombier if(INITDAT == -1) 1883e12c5d1SDavid du Colombier INITDAT = 0; 1893e12c5d1SDavid du Colombier if(INITRND == -1) 1903e12c5d1SDavid du Colombier INITRND = 4; 1913e12c5d1SDavid du Colombier break; 192219b2ee8SDavid du Colombier case 4: /* fake MS-DOS .EXE */ 193219b2ee8SDavid du Colombier HEADR = 0x200; 194219b2ee8SDavid du Colombier if(INITTEXT == -1) 195219b2ee8SDavid du Colombier INITTEXT = 0x0100; 196219b2ee8SDavid du Colombier if(INITDAT == -1) 197219b2ee8SDavid du Colombier INITDAT = 0; 198219b2ee8SDavid du Colombier if(INITRND == -1) 199219b2ee8SDavid du Colombier INITRND = 4; 200219b2ee8SDavid du Colombier HEADR += (INITTEXT & 0xFFFF); 201219b2ee8SDavid du Colombier if(debug['v']) 202219b2ee8SDavid du Colombier Bprint(&bso, "HEADR = 0x%ld\n", HEADR); 203219b2ee8SDavid du Colombier break; 204260f7b65SDavid du Colombier case 5: /* elf executable */ 205260f7b65SDavid du Colombier HEADR = rnd(52L+3*32L, 16); 206260f7b65SDavid du Colombier if(INITTEXT == -1) 2076b8bc682SDavid du Colombier INITTEXT = 0x80100020L; 208260f7b65SDavid du Colombier if(INITDAT == -1) 209260f7b65SDavid du Colombier INITDAT = 0; 210260f7b65SDavid du Colombier if(INITRND == -1) 211260f7b65SDavid du Colombier INITRND = 4096; 212260f7b65SDavid du Colombier break; 2133e12c5d1SDavid du Colombier } 2143e12c5d1SDavid du Colombier if(INITDAT != 0 && INITRND != 0) 2153e12c5d1SDavid du Colombier print("warning: -D0x%lux is ignored because of -R0x%lux\n", 2163e12c5d1SDavid du Colombier INITDAT, INITRND); 2173e12c5d1SDavid du Colombier if(debug['v']) 2183e12c5d1SDavid du Colombier Bprint(&bso, "HEADER = -H0x%ld -T0x%lux -D0x%lux -R0x%lux\n", 2193e12c5d1SDavid du Colombier HEADTYPE, INITTEXT, INITDAT, INITRND); 2203e12c5d1SDavid du Colombier Bflush(&bso); 2213e12c5d1SDavid du Colombier for(i=1; optab[i].as; i++) 2223e12c5d1SDavid du Colombier if(i != optab[i].as) { 2236b6b9ac8SDavid du Colombier diag("phase error in optab: %d", i); 2243e12c5d1SDavid du Colombier errorexit(); 2253e12c5d1SDavid du Colombier } 2263e12c5d1SDavid du Colombier 2273e12c5d1SDavid du Colombier for(i=0; i<Ymax; i++) 2283e12c5d1SDavid du Colombier ycover[i*Ymax + i] = 1; 2293e12c5d1SDavid du Colombier 2303e12c5d1SDavid du Colombier ycover[Yi0*Ymax + Yi8] = 1; 2313e12c5d1SDavid du Colombier ycover[Yi1*Ymax + Yi8] = 1; 2323e12c5d1SDavid du Colombier 2333e12c5d1SDavid du Colombier ycover[Yi0*Ymax + Yi32] = 1; 2343e12c5d1SDavid du Colombier ycover[Yi1*Ymax + Yi32] = 1; 2353e12c5d1SDavid du Colombier ycover[Yi8*Ymax + Yi32] = 1; 2363e12c5d1SDavid du Colombier 2373e12c5d1SDavid du Colombier ycover[Yal*Ymax + Yrb] = 1; 2383e12c5d1SDavid du Colombier ycover[Ycl*Ymax + Yrb] = 1; 2393e12c5d1SDavid du Colombier ycover[Yax*Ymax + Yrb] = 1; 2403e12c5d1SDavid du Colombier ycover[Ycx*Ymax + Yrb] = 1; 2413e12c5d1SDavid du Colombier ycover[Yrx*Ymax + Yrb] = 1; 2423e12c5d1SDavid du Colombier 2433e12c5d1SDavid du Colombier ycover[Yax*Ymax + Yrx] = 1; 2443e12c5d1SDavid du Colombier ycover[Ycx*Ymax + Yrx] = 1; 2453e12c5d1SDavid du Colombier 2463e12c5d1SDavid du Colombier ycover[Yax*Ymax + Yrl] = 1; 2473e12c5d1SDavid du Colombier ycover[Ycx*Ymax + Yrl] = 1; 2483e12c5d1SDavid du Colombier ycover[Yrx*Ymax + Yrl] = 1; 2493e12c5d1SDavid du Colombier 2503e12c5d1SDavid du Colombier ycover[Yf0*Ymax + Yrf] = 1; 2513e12c5d1SDavid du Colombier 2523e12c5d1SDavid du Colombier ycover[Yal*Ymax + Ymb] = 1; 2533e12c5d1SDavid du Colombier ycover[Ycl*Ymax + Ymb] = 1; 2543e12c5d1SDavid du Colombier ycover[Yax*Ymax + Ymb] = 1; 2553e12c5d1SDavid du Colombier ycover[Ycx*Ymax + Ymb] = 1; 2563e12c5d1SDavid du Colombier ycover[Yrx*Ymax + Ymb] = 1; 2573e12c5d1SDavid du Colombier ycover[Yrb*Ymax + Ymb] = 1; 2583e12c5d1SDavid du Colombier ycover[Ym*Ymax + Ymb] = 1; 2593e12c5d1SDavid du Colombier 2603e12c5d1SDavid du Colombier ycover[Yax*Ymax + Yml] = 1; 2613e12c5d1SDavid du Colombier ycover[Ycx*Ymax + Yml] = 1; 2623e12c5d1SDavid du Colombier ycover[Yrx*Ymax + Yml] = 1; 2633e12c5d1SDavid du Colombier ycover[Yrl*Ymax + Yml] = 1; 2643e12c5d1SDavid du Colombier ycover[Ym*Ymax + Yml] = 1; 2653e12c5d1SDavid du Colombier 2663e12c5d1SDavid du Colombier for(i=0; i<D_NONE; i++) { 2673e12c5d1SDavid du Colombier reg[i] = -1; 2683e12c5d1SDavid du Colombier if(i >= D_AL && i <= D_BH) 2693e12c5d1SDavid du Colombier reg[i] = (i-D_AL) & 7; 2703e12c5d1SDavid du Colombier if(i >= D_AX && i <= D_DI) 2713e12c5d1SDavid du Colombier reg[i] = (i-D_AX) & 7; 2723e12c5d1SDavid du Colombier if(i >= D_F0 && i <= D_F0+7) 2733e12c5d1SDavid du Colombier reg[i] = (i-D_F0) & 7; 2743e12c5d1SDavid du Colombier } 2753e12c5d1SDavid du Colombier 2763e12c5d1SDavid du Colombier zprg.link = P; 2777dd7cddfSDavid du Colombier zprg.pcond = P; 2783e12c5d1SDavid du Colombier zprg.back = 2; 2793e12c5d1SDavid du Colombier zprg.as = AGOK; 2803e12c5d1SDavid du Colombier zprg.from.type = D_NONE; 2813e12c5d1SDavid du Colombier zprg.from.index = D_NONE; 2823e12c5d1SDavid du Colombier zprg.from.scale = 1; 2833e12c5d1SDavid du Colombier zprg.to = zprg.from; 2843e12c5d1SDavid du Colombier 2853e12c5d1SDavid du Colombier pcstr = "%.6lux "; 2863e12c5d1SDavid du Colombier nuxiinit(); 2873e12c5d1SDavid du Colombier histgen = 0; 2883e12c5d1SDavid du Colombier textp = P; 2893e12c5d1SDavid du Colombier datap = P; 2903e12c5d1SDavid du Colombier edatap = P; 2913e12c5d1SDavid du Colombier pc = 0; 292219b2ee8SDavid du Colombier dtype = 4; 2933e12c5d1SDavid du Colombier cout = create(outfile, 1, 0775); 2943e12c5d1SDavid du Colombier if(cout < 0) { 295b87cd620SDavid du Colombier diag("cannot create %s: %r", outfile); 2963e12c5d1SDavid du Colombier errorexit(); 2973e12c5d1SDavid du Colombier } 2983e12c5d1SDavid du Colombier version = 0; 2993e12c5d1SDavid du Colombier cbp = buf.cbuf; 3003e12c5d1SDavid du Colombier cbc = sizeof(buf.cbuf); 3013e12c5d1SDavid du Colombier firstp = prg(); 3023e12c5d1SDavid du Colombier lastp = firstp; 3033e12c5d1SDavid du Colombier 3043e12c5d1SDavid du Colombier if(INITENTRY == 0) { 3053e12c5d1SDavid du Colombier INITENTRY = "_main"; 306375daca8SDavid du Colombier if(debug['p']) 3073e12c5d1SDavid du Colombier INITENTRY = "_mainp"; 3083e12c5d1SDavid du Colombier if(!debug['l']) 3093e12c5d1SDavid du Colombier lookup(INITENTRY, 0)->type = SXREF; 310b87cd620SDavid du Colombier } else if(!(*INITENTRY >= '0' && *INITENTRY <= '9')) 311219b2ee8SDavid du Colombier lookup(INITENTRY, 0)->type = SXREF; 3123e12c5d1SDavid du Colombier 3133e12c5d1SDavid du Colombier while(*argv) 3143e12c5d1SDavid du Colombier objfile(*argv++); 3153e12c5d1SDavid du Colombier if(!debug['l']) 3167dd7cddfSDavid du Colombier loadlib(); 3173e12c5d1SDavid du Colombier firstp = firstp->link; 3183e12c5d1SDavid du Colombier if(firstp == P) 3193e12c5d1SDavid du Colombier errorexit(); 320375daca8SDavid du Colombier if(doexp || dlm){ 321375daca8SDavid du Colombier EXPTAB = "_exporttab"; 322375daca8SDavid du Colombier zerosig(EXPTAB); 323375daca8SDavid du Colombier zerosig("etext"); 324375daca8SDavid du Colombier zerosig("edata"); 325375daca8SDavid du Colombier zerosig("end"); 326375daca8SDavid du Colombier if(dlm){ 327375daca8SDavid du Colombier import(); 328375daca8SDavid du Colombier HEADTYPE = 2; 329375daca8SDavid du Colombier INITTEXT = INITDAT = 0; 330375daca8SDavid du Colombier INITRND = 8; 331375daca8SDavid du Colombier INITENTRY = EXPTAB; 332375daca8SDavid du Colombier } 333375daca8SDavid du Colombier export(); 334375daca8SDavid du Colombier } 3353e12c5d1SDavid du Colombier patch(); 3367dd7cddfSDavid du Colombier follow(); 3377dd7cddfSDavid du Colombier dodata(); 3387dd7cddfSDavid du Colombier dostkoff(); 3393e12c5d1SDavid du Colombier if(debug['p']) 3403e12c5d1SDavid du Colombier if(debug['1']) 3413e12c5d1SDavid du Colombier doprof1(); 3423e12c5d1SDavid du Colombier else 3433e12c5d1SDavid du Colombier doprof2(); 3443e12c5d1SDavid du Colombier span(); 3453e12c5d1SDavid du Colombier doinit(); 3463e12c5d1SDavid du Colombier asmb(); 3473e12c5d1SDavid du Colombier undef(); 3483e12c5d1SDavid du Colombier if(debug['v']) { 3493e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f cpu time\n", cputime()); 3503e12c5d1SDavid du Colombier Bprint(&bso, "%ld symbols\n", nsymbol); 3513e12c5d1SDavid du Colombier Bprint(&bso, "%ld memory used\n", thunk); 3523e12c5d1SDavid du Colombier Bprint(&bso, "%d sizeof adr\n", sizeof(Adr)); 3533e12c5d1SDavid du Colombier Bprint(&bso, "%d sizeof prog\n", sizeof(Prog)); 3543e12c5d1SDavid du Colombier } 3553e12c5d1SDavid du Colombier Bflush(&bso); 3563e12c5d1SDavid du Colombier 3573e12c5d1SDavid du Colombier errorexit(); 3583e12c5d1SDavid du Colombier } 3593e12c5d1SDavid du Colombier 3603e12c5d1SDavid du Colombier void 361b87cd620SDavid du Colombier addlibpath(char *arg) 362b87cd620SDavid du Colombier { 363b87cd620SDavid du Colombier char **p; 364b87cd620SDavid du Colombier 365b87cd620SDavid du Colombier if(nlibdir >= maxlibdir) { 366b87cd620SDavid du Colombier if(maxlibdir == 0) 367b87cd620SDavid du Colombier maxlibdir = 8; 368b87cd620SDavid du Colombier else 369b87cd620SDavid du Colombier maxlibdir *= 2; 370b87cd620SDavid du Colombier p = malloc(maxlibdir*sizeof(*p)); 371b87cd620SDavid du Colombier if(p == nil) { 372b87cd620SDavid du Colombier diag("out of memory"); 373b87cd620SDavid du Colombier errorexit(); 374b87cd620SDavid du Colombier } 375b87cd620SDavid du Colombier memmove(p, libdir, nlibdir*sizeof(*p)); 376b87cd620SDavid du Colombier free(libdir); 377b87cd620SDavid du Colombier libdir = p; 378b87cd620SDavid du Colombier } 379b87cd620SDavid du Colombier libdir[nlibdir++] = strdup(arg); 380b87cd620SDavid du Colombier } 381b87cd620SDavid du Colombier 382b87cd620SDavid du Colombier char* 383b87cd620SDavid du Colombier findlib(char *file) 384b87cd620SDavid du Colombier { 385b87cd620SDavid du Colombier int i; 386b87cd620SDavid du Colombier char name[LIBNAMELEN]; 387b87cd620SDavid du Colombier 388b87cd620SDavid du Colombier for(i = 0; i < nlibdir; i++) { 389b87cd620SDavid du Colombier snprint(name, sizeof(name), "%s/%s", libdir[i], file); 390b87cd620SDavid du Colombier if(fileexists(name)) 391b87cd620SDavid du Colombier return libdir[i]; 392b87cd620SDavid du Colombier } 393b87cd620SDavid du Colombier return nil; 394b87cd620SDavid du Colombier } 395b87cd620SDavid du Colombier 396b87cd620SDavid du Colombier void 3977dd7cddfSDavid du Colombier loadlib(void) 3983e12c5d1SDavid du Colombier { 3997dd7cddfSDavid du Colombier int i; 4007dd7cddfSDavid du Colombier long h; 4017dd7cddfSDavid du Colombier Sym *s; 4023e12c5d1SDavid du Colombier 4037dd7cddfSDavid du Colombier loop: 4047dd7cddfSDavid du Colombier xrefresolv = 0; 4057dd7cddfSDavid du Colombier for(i=0; i<libraryp; i++) { 4063e12c5d1SDavid du Colombier if(debug['v']) 407375daca8SDavid du Colombier Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(), library[i], libraryobj[i]); 4083e12c5d1SDavid du Colombier objfile(library[i]); 4093e12c5d1SDavid du Colombier } 4107dd7cddfSDavid du Colombier if(xrefresolv) 4117dd7cddfSDavid du Colombier for(h=0; h<nelem(hash); h++) 4127dd7cddfSDavid du Colombier for(s = hash[h]; s != S; s = s->link) 4137dd7cddfSDavid du Colombier if(s->type == SXREF) 4147dd7cddfSDavid du Colombier goto loop; 4153e12c5d1SDavid du Colombier } 4163e12c5d1SDavid du Colombier 4173e12c5d1SDavid du Colombier void 4183e12c5d1SDavid du Colombier errorexit(void) 4193e12c5d1SDavid du Colombier { 4203e12c5d1SDavid du Colombier 4213e12c5d1SDavid du Colombier if(nerrors) { 4223e12c5d1SDavid du Colombier if(cout >= 0) 4233e12c5d1SDavid du Colombier remove(outfile); 4243e12c5d1SDavid du Colombier exits("error"); 4253e12c5d1SDavid du Colombier } 4263e12c5d1SDavid du Colombier exits(0); 4273e12c5d1SDavid du Colombier } 4283e12c5d1SDavid du Colombier 4293e12c5d1SDavid du Colombier void 4303e12c5d1SDavid du Colombier objfile(char *file) 4313e12c5d1SDavid du Colombier { 432219b2ee8SDavid du Colombier long off, esym, cnt, l; 4333e12c5d1SDavid du Colombier int f, work; 4343e12c5d1SDavid du Colombier Sym *s; 4353e12c5d1SDavid du Colombier char magbuf[SARMAG]; 436b87cd620SDavid du Colombier char name[LIBNAMELEN], pname[LIBNAMELEN]; 4373e12c5d1SDavid du Colombier struct ar_hdr arhdr; 438219b2ee8SDavid du Colombier char *e, *start, *stop; 4393e12c5d1SDavid du Colombier 4403e12c5d1SDavid du Colombier if(debug['v']) 4413e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f ldobj: %s\n", cputime(), file); 4423e12c5d1SDavid du Colombier Bflush(&bso); 443b87cd620SDavid du Colombier if(file[0] == '-' && file[1] == 'l') { 444b87cd620SDavid du Colombier snprint(pname, sizeof(pname), "lib%s.a", file+2); 445b87cd620SDavid du Colombier e = findlib(pname); 446b87cd620SDavid du Colombier if(e == nil) { 447b87cd620SDavid du Colombier diag("cannot find library: %s", file); 448b87cd620SDavid du Colombier errorexit(); 449b87cd620SDavid du Colombier } 450b87cd620SDavid du Colombier snprint(name, sizeof(name), "%s/%s", e, pname); 451b87cd620SDavid du Colombier file = name; 452b87cd620SDavid du Colombier } 4533e12c5d1SDavid du Colombier f = open(file, 0); 4543e12c5d1SDavid du Colombier if(f < 0) { 455b87cd620SDavid du Colombier diag("cannot open %s: %r", file); 4563e12c5d1SDavid du Colombier errorexit(); 4573e12c5d1SDavid du Colombier } 4583e12c5d1SDavid du Colombier l = read(f, magbuf, SARMAG); 459219b2ee8SDavid du Colombier if(l != SARMAG || strncmp(magbuf, ARMAG, SARMAG)){ 460219b2ee8SDavid du Colombier /* load it as a regular file */ 461219b2ee8SDavid du Colombier l = seek(f, 0L, 2); 462219b2ee8SDavid du Colombier seek(f, 0L, 0); 463219b2ee8SDavid du Colombier ldobj(f, l, file); 464219b2ee8SDavid du Colombier close(f); 465219b2ee8SDavid du Colombier return; 466219b2ee8SDavid du Colombier } 4673e12c5d1SDavid du Colombier 4687dd7cddfSDavid du Colombier l = read(f, &arhdr, SAR_HDR); 4697dd7cddfSDavid du Colombier if(l != SAR_HDR) { 4706b6b9ac8SDavid du Colombier diag("%s: short read on archive file symbol header", file); 4713e12c5d1SDavid du Colombier goto out; 4723e12c5d1SDavid du Colombier } 4733e12c5d1SDavid du Colombier if(strncmp(arhdr.name, symname, strlen(symname))) { 4746b6b9ac8SDavid du Colombier diag("%s: first entry not symbol header", file); 4753e12c5d1SDavid du Colombier goto out; 4763e12c5d1SDavid du Colombier } 4773e12c5d1SDavid du Colombier 4787dd7cddfSDavid du Colombier esym = SARMAG + SAR_HDR + atolwhex(arhdr.size); 4797dd7cddfSDavid du Colombier off = SARMAG + SAR_HDR; 4803e12c5d1SDavid du Colombier 481219b2ee8SDavid du Colombier /* 482219b2ee8SDavid du Colombier * just bang the whole symbol file into memory 483219b2ee8SDavid du Colombier */ 4843e12c5d1SDavid du Colombier seek(f, off, 0); 4853e12c5d1SDavid du Colombier cnt = esym - off; 486219b2ee8SDavid du Colombier start = malloc(cnt + 10); 487219b2ee8SDavid du Colombier cnt = read(f, start, cnt); 4883e12c5d1SDavid du Colombier if(cnt <= 0){ 4893e12c5d1SDavid du Colombier close(f); 4903e12c5d1SDavid du Colombier return; 4913e12c5d1SDavid du Colombier } 492219b2ee8SDavid du Colombier stop = &start[cnt]; 493219b2ee8SDavid du Colombier memset(stop, 0, 10); 494219b2ee8SDavid du Colombier 495219b2ee8SDavid du Colombier work = 1; 496219b2ee8SDavid du Colombier while(work) { 497219b2ee8SDavid du Colombier if(debug['v']) 498219b2ee8SDavid du Colombier Bprint(&bso, "%5.2f library pass: %s\n", cputime(), file); 499219b2ee8SDavid du Colombier Bflush(&bso); 500219b2ee8SDavid du Colombier work = 0; 501219b2ee8SDavid du Colombier for(e = start; e < stop; e = strchr(e+5, 0) + 1) { 502219b2ee8SDavid du Colombier s = lookup(e+5, 0); 5033e12c5d1SDavid du Colombier if(s->type != SXREF) 5043e12c5d1SDavid du Colombier continue; 505219b2ee8SDavid du Colombier sprint(pname, "%s(%s)", file, s->name); 5063e12c5d1SDavid du Colombier if(debug['v']) 5073e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f library: %s\n", cputime(), pname); 5083e12c5d1SDavid du Colombier Bflush(&bso); 509219b2ee8SDavid du Colombier l = e[1] & 0xff; 510219b2ee8SDavid du Colombier l |= (e[2] & 0xff) << 8; 511219b2ee8SDavid du Colombier l |= (e[3] & 0xff) << 16; 512219b2ee8SDavid du Colombier l |= (e[4] & 0xff) << 24; 5133e12c5d1SDavid du Colombier seek(f, l, 0); 5147dd7cddfSDavid du Colombier l = read(f, &arhdr, SAR_HDR); 5157dd7cddfSDavid du Colombier if(l != SAR_HDR) 5163e12c5d1SDavid du Colombier goto bad; 5173e12c5d1SDavid du Colombier if(strncmp(arhdr.fmag, ARFMAG, sizeof(arhdr.fmag))) 5183e12c5d1SDavid du Colombier goto bad; 5193e12c5d1SDavid du Colombier l = atolwhex(arhdr.size); 5203e12c5d1SDavid du Colombier ldobj(f, l, pname); 5213e12c5d1SDavid du Colombier if(s->type == SXREF) { 5226b6b9ac8SDavid du Colombier diag("%s: failed to load: %s", file, s->name); 5233e12c5d1SDavid du Colombier errorexit(); 5243e12c5d1SDavid du Colombier } 5253e12c5d1SDavid du Colombier work = 1; 5267dd7cddfSDavid du Colombier xrefresolv = 1; 5273e12c5d1SDavid du Colombier } 528219b2ee8SDavid du Colombier } 5293e12c5d1SDavid du Colombier return; 5303e12c5d1SDavid du Colombier 5313e12c5d1SDavid du Colombier bad: 5326b6b9ac8SDavid du Colombier diag("%s: bad or out of date archive", file); 5333e12c5d1SDavid du Colombier out: 5343e12c5d1SDavid du Colombier close(f); 5353e12c5d1SDavid du Colombier } 5363e12c5d1SDavid du Colombier 5373e12c5d1SDavid du Colombier int 5383e12c5d1SDavid du Colombier zaddr(uchar *p, Adr *a, Sym *h[]) 5393e12c5d1SDavid du Colombier { 5403e12c5d1SDavid du Colombier int c, t, i; 541b87cd620SDavid du Colombier int l; 5423e12c5d1SDavid du Colombier Sym *s; 5433e12c5d1SDavid du Colombier Auto *u; 5443e12c5d1SDavid du Colombier 5453e12c5d1SDavid du Colombier t = p[0]; 5463e12c5d1SDavid du Colombier 5473e12c5d1SDavid du Colombier c = 1; 5483e12c5d1SDavid du Colombier if(t & T_INDEX) { 5493e12c5d1SDavid du Colombier a->index = p[c]; 5503e12c5d1SDavid du Colombier a->scale = p[c+1]; 5513e12c5d1SDavid du Colombier c += 2; 5523e12c5d1SDavid du Colombier } else { 5533e12c5d1SDavid du Colombier a->index = D_NONE; 5543e12c5d1SDavid du Colombier a->scale = 0; 5553e12c5d1SDavid du Colombier } 5563e12c5d1SDavid du Colombier a->offset = 0; 5573e12c5d1SDavid du Colombier if(t & T_OFFSET) { 5583e12c5d1SDavid du Colombier a->offset = p[c] | (p[c+1]<<8) | (p[c+2]<<16) | (p[c+3]<<24); 5593e12c5d1SDavid du Colombier c += 4; 5603e12c5d1SDavid du Colombier } 5613e12c5d1SDavid du Colombier a->sym = S; 5623e12c5d1SDavid du Colombier if(t & T_SYM) { 5633e12c5d1SDavid du Colombier a->sym = h[p[c]]; 5643e12c5d1SDavid du Colombier c++; 5653e12c5d1SDavid du Colombier } 5663e12c5d1SDavid du Colombier a->type = D_NONE; 5673e12c5d1SDavid du Colombier if(t & T_FCONST) { 5683e12c5d1SDavid du Colombier a->ieee.l = p[c] | (p[c+1]<<8) | (p[c+2]<<16) | (p[c+3]<<24); 5693e12c5d1SDavid du Colombier a->ieee.h = p[c+4] | (p[c+5]<<8) | (p[c+6]<<16) | (p[c+7]<<24); 5703e12c5d1SDavid du Colombier c += 8; 5713e12c5d1SDavid du Colombier a->type = D_FCONST; 5723e12c5d1SDavid du Colombier } else 5733e12c5d1SDavid du Colombier if(t & T_SCONST) { 5743e12c5d1SDavid du Colombier for(i=0; i<NSNAME; i++) 5753e12c5d1SDavid du Colombier a->scon[i] = p[c+i]; 5763e12c5d1SDavid du Colombier c += NSNAME; 5773e12c5d1SDavid du Colombier a->type = D_SCONST; 5783e12c5d1SDavid du Colombier } 5793e12c5d1SDavid du Colombier if(t & T_TYPE) { 5803e12c5d1SDavid du Colombier a->type = p[c]; 5813e12c5d1SDavid du Colombier c++; 5823e12c5d1SDavid du Colombier } 5833e12c5d1SDavid du Colombier s = a->sym; 5843e12c5d1SDavid du Colombier if(s == S) 5853e12c5d1SDavid du Colombier return c; 5863e12c5d1SDavid du Colombier 5873e12c5d1SDavid du Colombier t = a->type; 5883e12c5d1SDavid du Colombier if(t != D_AUTO && t != D_PARAM) 5893e12c5d1SDavid du Colombier return c; 5903e12c5d1SDavid du Colombier l = a->offset; 5913e12c5d1SDavid du Colombier for(u=curauto; u; u=u->link) { 5927dd7cddfSDavid du Colombier if(u->asym == s) 5933e12c5d1SDavid du Colombier if(u->type == t) { 5947dd7cddfSDavid du Colombier if(u->aoffset > l) 5957dd7cddfSDavid du Colombier u->aoffset = l; 5963e12c5d1SDavid du Colombier return c; 5973e12c5d1SDavid du Colombier } 5983e12c5d1SDavid du Colombier } 5993e12c5d1SDavid du Colombier 6003e12c5d1SDavid du Colombier while(nhunk < sizeof(Auto)) 6013e12c5d1SDavid du Colombier gethunk(); 6023e12c5d1SDavid du Colombier u = (Auto*)hunk; 6033e12c5d1SDavid du Colombier nhunk -= sizeof(Auto); 6043e12c5d1SDavid du Colombier hunk += sizeof(Auto); 6053e12c5d1SDavid du Colombier 6063e12c5d1SDavid du Colombier u->link = curauto; 6073e12c5d1SDavid du Colombier curauto = u; 6087dd7cddfSDavid du Colombier u->asym = s; 6097dd7cddfSDavid du Colombier u->aoffset = l; 6103e12c5d1SDavid du Colombier u->type = t; 6113e12c5d1SDavid du Colombier return c; 6123e12c5d1SDavid du Colombier } 6133e12c5d1SDavid du Colombier 6143e12c5d1SDavid du Colombier void 61580ee5cbfSDavid du Colombier addlib(char *obj) 6163e12c5d1SDavid du Colombier { 617b87cd620SDavid du Colombier char fn1[LIBNAMELEN], fn2[LIBNAMELEN], comp[LIBNAMELEN], *p, *name; 618b87cd620SDavid du Colombier int i, search; 6193e12c5d1SDavid du Colombier 6203e12c5d1SDavid du Colombier if(histfrogp <= 0) 6213e12c5d1SDavid du Colombier return; 6223e12c5d1SDavid du Colombier 623b87cd620SDavid du Colombier name = fn1; 624b87cd620SDavid du Colombier search = 0; 6253e12c5d1SDavid du Colombier if(histfrog[0]->name[1] == '/') { 6263e12c5d1SDavid du Colombier sprint(name, ""); 6273e12c5d1SDavid du Colombier i = 1; 628b87cd620SDavid du Colombier } else if(histfrog[0]->name[1] == '.') { 6293e12c5d1SDavid du Colombier sprint(name, "."); 6303e12c5d1SDavid du Colombier i = 0; 6313e12c5d1SDavid du Colombier } else { 632b87cd620SDavid du Colombier sprint(name, ""); 6333e12c5d1SDavid du Colombier i = 0; 634b87cd620SDavid du Colombier search = 1; 6353e12c5d1SDavid du Colombier } 6363e12c5d1SDavid du Colombier 6373e12c5d1SDavid du Colombier for(; i<histfrogp; i++) { 6389a747e4fSDavid du Colombier snprint(comp, sizeof comp, histfrog[i]->name+1); 6393e12c5d1SDavid du Colombier for(;;) { 6403e12c5d1SDavid du Colombier p = strstr(comp, "$O"); 6413e12c5d1SDavid du Colombier if(p == 0) 6423e12c5d1SDavid du Colombier break; 6433e12c5d1SDavid du Colombier memmove(p+1, p+2, strlen(p+2)+1); 644219b2ee8SDavid du Colombier p[0] = thechar; 6453e12c5d1SDavid du Colombier } 6463e12c5d1SDavid du Colombier for(;;) { 6473e12c5d1SDavid du Colombier p = strstr(comp, "$M"); 6483e12c5d1SDavid du Colombier if(p == 0) 6493e12c5d1SDavid du Colombier break; 6509a747e4fSDavid du Colombier if(strlen(comp)+strlen(thestring)-2+1 >= sizeof comp) { 651219b2ee8SDavid du Colombier diag("library component too long"); 652219b2ee8SDavid du Colombier return; 6533e12c5d1SDavid du Colombier } 6549a747e4fSDavid du Colombier memmove(p+strlen(thestring), p+2, strlen(p+2)+1); 6559a747e4fSDavid du Colombier memmove(p, thestring, strlen(thestring)); 656219b2ee8SDavid du Colombier } 657b87cd620SDavid du Colombier if(strlen(fn1) + strlen(comp) + 3 >= sizeof(fn1)) { 6583e12c5d1SDavid du Colombier diag("library component too long"); 6593e12c5d1SDavid du Colombier return; 6603e12c5d1SDavid du Colombier } 661b87cd620SDavid du Colombier if(i > 0 || !search) 662b87cd620SDavid du Colombier strcat(fn1, "/"); 663b87cd620SDavid du Colombier strcat(fn1, comp); 6643e12c5d1SDavid du Colombier } 665b87cd620SDavid du Colombier 666b87cd620SDavid du Colombier cleanname(name); 667b87cd620SDavid du Colombier 668b87cd620SDavid du Colombier if(search){ 669b87cd620SDavid du Colombier p = findlib(name); 670b87cd620SDavid du Colombier if(p != nil){ 671b87cd620SDavid du Colombier snprint(fn2, sizeof(fn2), "%s/%s", p, name); 672b87cd620SDavid du Colombier name = fn2; 673b87cd620SDavid du Colombier } 674b87cd620SDavid du Colombier } 675b87cd620SDavid du Colombier 6763e12c5d1SDavid du Colombier for(i=0; i<libraryp; i++) 6773e12c5d1SDavid du Colombier if(strcmp(name, library[i]) == 0) 6783e12c5d1SDavid du Colombier return; 67980ee5cbfSDavid du Colombier if(libraryp == nelem(library)){ 68080ee5cbfSDavid du Colombier diag("too many autolibs; skipping %s", name); 68180ee5cbfSDavid du Colombier return; 68280ee5cbfSDavid du Colombier } 6833e12c5d1SDavid du Colombier 684219b2ee8SDavid du Colombier p = malloc(strlen(name) + 1); 6853e12c5d1SDavid du Colombier strcpy(p, name); 6863e12c5d1SDavid du Colombier library[libraryp] = p; 68780ee5cbfSDavid du Colombier p = malloc(strlen(obj) + 1); 68880ee5cbfSDavid du Colombier strcpy(p, obj); 68980ee5cbfSDavid du Colombier libraryobj[libraryp] = p; 6903e12c5d1SDavid du Colombier libraryp++; 6913e12c5d1SDavid du Colombier } 692219b2ee8SDavid du Colombier 6933e12c5d1SDavid du Colombier void 6943e12c5d1SDavid du Colombier addhist(long line, int type) 6953e12c5d1SDavid du Colombier { 6963e12c5d1SDavid du Colombier Auto *u; 6973e12c5d1SDavid du Colombier Sym *s; 6983e12c5d1SDavid du Colombier int i, j, k; 6993e12c5d1SDavid du Colombier 700219b2ee8SDavid du Colombier u = malloc(sizeof(Auto)); 701219b2ee8SDavid du Colombier s = malloc(sizeof(Sym)); 702219b2ee8SDavid du Colombier s->name = malloc(2*(histfrogp+1) + 1); 7033e12c5d1SDavid du Colombier 7047dd7cddfSDavid du Colombier u->asym = s; 7053e12c5d1SDavid du Colombier u->type = type; 7067dd7cddfSDavid du Colombier u->aoffset = line; 7073e12c5d1SDavid du Colombier u->link = curhist; 7083e12c5d1SDavid du Colombier curhist = u; 7093e12c5d1SDavid du Colombier 7103e12c5d1SDavid du Colombier j = 1; 7113e12c5d1SDavid du Colombier for(i=0; i<histfrogp; i++) { 7123e12c5d1SDavid du Colombier k = histfrog[i]->value; 7133e12c5d1SDavid du Colombier s->name[j+0] = k>>8; 7143e12c5d1SDavid du Colombier s->name[j+1] = k; 7153e12c5d1SDavid du Colombier j += 2; 7163e12c5d1SDavid du Colombier } 7173e12c5d1SDavid du Colombier } 7183e12c5d1SDavid du Colombier 7193e12c5d1SDavid du Colombier void 7203e12c5d1SDavid du Colombier histtoauto(void) 7213e12c5d1SDavid du Colombier { 7223e12c5d1SDavid du Colombier Auto *l; 7233e12c5d1SDavid du Colombier 7243e12c5d1SDavid du Colombier while(l = curhist) { 7253e12c5d1SDavid du Colombier curhist = l->link; 7263e12c5d1SDavid du Colombier l->link = curauto; 7273e12c5d1SDavid du Colombier curauto = l; 7283e12c5d1SDavid du Colombier } 7293e12c5d1SDavid du Colombier } 7303e12c5d1SDavid du Colombier 7313e12c5d1SDavid du Colombier void 732219b2ee8SDavid du Colombier collapsefrog(Sym *s) 733219b2ee8SDavid du Colombier { 734219b2ee8SDavid du Colombier int i; 735219b2ee8SDavid du Colombier 736219b2ee8SDavid du Colombier /* 737219b2ee8SDavid du Colombier * bad encoding of path components only allows 738219b2ee8SDavid du Colombier * MAXHIST components. if there is an overflow, 739219b2ee8SDavid du Colombier * first try to collapse xxx/.. 740219b2ee8SDavid du Colombier */ 741219b2ee8SDavid du Colombier for(i=1; i<histfrogp; i++) 742219b2ee8SDavid du Colombier if(strcmp(histfrog[i]->name+1, "..") == 0) { 743219b2ee8SDavid du Colombier memmove(histfrog+i-1, histfrog+i+1, 744219b2ee8SDavid du Colombier (histfrogp-i-1)*sizeof(histfrog[0])); 745219b2ee8SDavid du Colombier histfrogp--; 746219b2ee8SDavid du Colombier goto out; 747219b2ee8SDavid du Colombier } 748219b2ee8SDavid du Colombier 749219b2ee8SDavid du Colombier /* 750219b2ee8SDavid du Colombier * next try to collapse . 751219b2ee8SDavid du Colombier */ 752219b2ee8SDavid du Colombier for(i=0; i<histfrogp; i++) 753219b2ee8SDavid du Colombier if(strcmp(histfrog[i]->name+1, ".") == 0) { 754219b2ee8SDavid du Colombier memmove(histfrog+i, histfrog+i+1, 755219b2ee8SDavid du Colombier (histfrogp-i-1)*sizeof(histfrog[0])); 756219b2ee8SDavid du Colombier goto out; 757219b2ee8SDavid du Colombier } 758219b2ee8SDavid du Colombier 759219b2ee8SDavid du Colombier /* 760219b2ee8SDavid du Colombier * last chance, just truncate from front 761219b2ee8SDavid du Colombier */ 762219b2ee8SDavid du Colombier memmove(histfrog+0, histfrog+1, 763219b2ee8SDavid du Colombier (histfrogp-1)*sizeof(histfrog[0])); 764219b2ee8SDavid du Colombier 765219b2ee8SDavid du Colombier out: 766219b2ee8SDavid du Colombier histfrog[histfrogp-1] = s; 767219b2ee8SDavid du Colombier } 768219b2ee8SDavid du Colombier 769219b2ee8SDavid du Colombier void 770219b2ee8SDavid du Colombier nopout(Prog *p) 771219b2ee8SDavid du Colombier { 772219b2ee8SDavid du Colombier p->as = ANOP; 773219b2ee8SDavid du Colombier p->from.type = D_NONE; 774219b2ee8SDavid du Colombier p->to.type = D_NONE; 775219b2ee8SDavid du Colombier } 776219b2ee8SDavid du Colombier 777219b2ee8SDavid du Colombier uchar* 778219b2ee8SDavid du Colombier readsome(int f, uchar *buf, uchar *good, uchar *stop, int max) 779219b2ee8SDavid du Colombier { 780219b2ee8SDavid du Colombier int n; 781219b2ee8SDavid du Colombier 782219b2ee8SDavid du Colombier n = stop - good; 783219b2ee8SDavid du Colombier memmove(buf, good, stop - good); 784219b2ee8SDavid du Colombier stop = buf + n; 785219b2ee8SDavid du Colombier n = MAXIO - n; 786219b2ee8SDavid du Colombier if(n > max) 787219b2ee8SDavid du Colombier n = max; 788219b2ee8SDavid du Colombier n = read(f, stop, n); 789219b2ee8SDavid du Colombier if(n <= 0) 790219b2ee8SDavid du Colombier return 0; 791219b2ee8SDavid du Colombier return stop + n; 792219b2ee8SDavid du Colombier } 793219b2ee8SDavid du Colombier 794219b2ee8SDavid du Colombier void 7953e12c5d1SDavid du Colombier ldobj(int f, long c, char *pn) 7963e12c5d1SDavid du Colombier { 7973e12c5d1SDavid du Colombier long ipc; 798219b2ee8SDavid du Colombier Prog *p, *t; 799219b2ee8SDavid du Colombier uchar *bloc, *bsize, *stop; 800219b2ee8SDavid du Colombier int v, o, r, skip; 801219b2ee8SDavid du Colombier Sym *h[NSYM], *s, *di; 802375daca8SDavid du Colombier ulong sig; 803375daca8SDavid du Colombier static int files; 804375daca8SDavid du Colombier static char **filen; 805375daca8SDavid du Colombier char **nfilen; 806375daca8SDavid du Colombier 807375daca8SDavid du Colombier if((files&15) == 0){ 808375daca8SDavid du Colombier nfilen = malloc((files+16)*sizeof(char*)); 809375daca8SDavid du Colombier memmove(nfilen, filen, files*sizeof(char*)); 810375daca8SDavid du Colombier free(filen); 811375daca8SDavid du Colombier filen = nfilen; 812375daca8SDavid du Colombier } 813375daca8SDavid du Colombier filen[files++] = strdup(pn); 8143e12c5d1SDavid du Colombier 8153e12c5d1SDavid du Colombier bsize = buf.xbuf; 8163e12c5d1SDavid du Colombier bloc = buf.xbuf; 817219b2ee8SDavid du Colombier di = S; 8183e12c5d1SDavid du Colombier 8193e12c5d1SDavid du Colombier newloop: 8203e12c5d1SDavid du Colombier memset(h, 0, sizeof(h)); 8213e12c5d1SDavid du Colombier version++; 8223e12c5d1SDavid du Colombier histfrogp = 0; 8233e12c5d1SDavid du Colombier ipc = pc; 824219b2ee8SDavid du Colombier skip = 0; 8253e12c5d1SDavid du Colombier 8263e12c5d1SDavid du Colombier loop: 8273e12c5d1SDavid du Colombier if(c <= 0) 8283e12c5d1SDavid du Colombier goto eof; 8293e12c5d1SDavid du Colombier r = bsize - bloc; 8303e12c5d1SDavid du Colombier if(r < 100 && r < c) { /* enough for largest prog */ 831219b2ee8SDavid du Colombier bsize = readsome(f, buf.xbuf, bloc, bsize, c); 832219b2ee8SDavid du Colombier if(bsize == 0) 8333e12c5d1SDavid du Colombier goto eof; 834219b2ee8SDavid du Colombier bloc = buf.xbuf; 8353e12c5d1SDavid du Colombier goto loop; 8363e12c5d1SDavid du Colombier } 8373e12c5d1SDavid du Colombier o = bloc[0] | (bloc[1] << 8); 838219b2ee8SDavid du Colombier if(o <= AXXX || o >= ALAST) { 8393e12c5d1SDavid du Colombier if(o < 0) 8403e12c5d1SDavid du Colombier goto eof; 8416b6b9ac8SDavid du Colombier diag("%s: opcode out of range %d", pn, o); 8423e12c5d1SDavid du Colombier print(" probably not a .8 file\n"); 8433e12c5d1SDavid du Colombier errorexit(); 8443e12c5d1SDavid du Colombier } 8453e12c5d1SDavid du Colombier 846375daca8SDavid du Colombier if(o == ANAME || o == ASIGNAME) { 847375daca8SDavid du Colombier sig = 0; 848375daca8SDavid du Colombier if(o == ASIGNAME) { 849375daca8SDavid du Colombier sig = bloc[2] | (bloc[3]<<8) | (bloc[4]<<16) | (bloc[5]<<24); 850375daca8SDavid du Colombier bloc += 4; 851375daca8SDavid du Colombier c -= 4; 852375daca8SDavid du Colombier } 853219b2ee8SDavid du Colombier stop = memchr(&bloc[4], 0, bsize-&bloc[4]); 854219b2ee8SDavid du Colombier if(stop == 0){ 855219b2ee8SDavid du Colombier bsize = readsome(f, buf.xbuf, bloc, bsize, c); 856219b2ee8SDavid du Colombier if(bsize == 0) 857219b2ee8SDavid du Colombier goto eof; 858219b2ee8SDavid du Colombier bloc = buf.xbuf; 859219b2ee8SDavid du Colombier stop = memchr(&bloc[4], 0, bsize-&bloc[4]); 860219b2ee8SDavid du Colombier if(stop == 0){ 861219b2ee8SDavid du Colombier fprint(2, "%s: name too long\n", pn); 862219b2ee8SDavid du Colombier errorexit(); 863219b2ee8SDavid du Colombier } 864219b2ee8SDavid du Colombier } 8653e12c5d1SDavid du Colombier v = bloc[2]; /* type */ 8663e12c5d1SDavid du Colombier o = bloc[3]; /* sym */ 8673e12c5d1SDavid du Colombier bloc += 4; 8683e12c5d1SDavid du Colombier c -= 4; 869219b2ee8SDavid du Colombier 8703e12c5d1SDavid du Colombier r = 0; 8713e12c5d1SDavid du Colombier if(v == D_STATIC) 8723e12c5d1SDavid du Colombier r = version; 873219b2ee8SDavid du Colombier s = lookup((char*)bloc, r); 874219b2ee8SDavid du Colombier c -= &stop[1] - bloc; 875219b2ee8SDavid du Colombier bloc = stop + 1; 876219b2ee8SDavid du Colombier 877375daca8SDavid du Colombier if(debug['S'] && r == 0) 878375daca8SDavid du Colombier sig = 1729; 879375daca8SDavid du Colombier if(sig != 0){ 880375daca8SDavid du Colombier if(s->sig != 0 && s->sig != sig) 881375daca8SDavid du Colombier diag("incompatible type signatures %lux(%s) and %lux(%s) for %s", s->sig, filen[s->file], sig, pn, s->name); 882375daca8SDavid du Colombier s->sig = sig; 883375daca8SDavid du Colombier s->file = files-1; 884375daca8SDavid du Colombier } 885375daca8SDavid du Colombier 8863e12c5d1SDavid du Colombier if(debug['W']) 8873e12c5d1SDavid du Colombier print(" ANAME %s\n", s->name); 8883e12c5d1SDavid du Colombier h[o] = s; 889219b2ee8SDavid du Colombier if((v == D_EXTERN || v == D_STATIC) && s->type == 0) 8903e12c5d1SDavid du Colombier s->type = SXREF; 8913e12c5d1SDavid du Colombier if(v == D_FILE) { 8923e12c5d1SDavid du Colombier if(s->type != SFILE) { 8933e12c5d1SDavid du Colombier histgen++; 8943e12c5d1SDavid du Colombier s->type = SFILE; 8953e12c5d1SDavid du Colombier s->value = histgen; 8963e12c5d1SDavid du Colombier } 897219b2ee8SDavid du Colombier if(histfrogp < MAXHIST) { 8983e12c5d1SDavid du Colombier histfrog[histfrogp] = s; 8993e12c5d1SDavid du Colombier histfrogp++; 900219b2ee8SDavid du Colombier } else 901219b2ee8SDavid du Colombier collapsefrog(s); 9023e12c5d1SDavid du Colombier } 9033e12c5d1SDavid du Colombier goto loop; 9043e12c5d1SDavid du Colombier } 9053e12c5d1SDavid du Colombier 9063e12c5d1SDavid du Colombier while(nhunk < sizeof(Prog)) 9073e12c5d1SDavid du Colombier gethunk(); 9083e12c5d1SDavid du Colombier p = (Prog*)hunk; 9093e12c5d1SDavid du Colombier nhunk -= sizeof(Prog); 9103e12c5d1SDavid du Colombier hunk += sizeof(Prog); 9113e12c5d1SDavid du Colombier 9123e12c5d1SDavid du Colombier p->as = o; 9133e12c5d1SDavid du Colombier p->line = bloc[2] | (bloc[3] << 8) | (bloc[4] << 16) | (bloc[5] << 24); 9143e12c5d1SDavid du Colombier p->back = 2; 9153e12c5d1SDavid du Colombier r = zaddr(bloc+6, &p->from, h) + 6; 9163e12c5d1SDavid du Colombier r += zaddr(bloc+r, &p->to, h); 9173e12c5d1SDavid du Colombier bloc += r; 9183e12c5d1SDavid du Colombier c -= r; 9193e12c5d1SDavid du Colombier 9203e12c5d1SDavid du Colombier if(debug['W']) 9213e12c5d1SDavid du Colombier print("%P\n", p); 9223e12c5d1SDavid du Colombier 9233e12c5d1SDavid du Colombier switch(p->as) { 9243e12c5d1SDavid du Colombier case AHISTORY: 9253e12c5d1SDavid du Colombier if(p->to.offset == -1) { 92680ee5cbfSDavid du Colombier addlib(pn); 9273e12c5d1SDavid du Colombier histfrogp = 0; 9283e12c5d1SDavid du Colombier goto loop; 9293e12c5d1SDavid du Colombier } 930219b2ee8SDavid du Colombier addhist(p->line, D_FILE); /* 'z' */ 9313e12c5d1SDavid du Colombier if(p->to.offset) 932219b2ee8SDavid du Colombier addhist(p->to.offset, D_FILE1); /* 'Z' */ 9333e12c5d1SDavid du Colombier histfrogp = 0; 9343e12c5d1SDavid du Colombier goto loop; 9353e12c5d1SDavid du Colombier 9363e12c5d1SDavid du Colombier case AEND: 9373e12c5d1SDavid du Colombier histtoauto(); 9383e12c5d1SDavid du Colombier if(curtext != P) 9393e12c5d1SDavid du Colombier curtext->to.autom = curauto; 9403e12c5d1SDavid du Colombier curauto = 0; 9413e12c5d1SDavid du Colombier curtext = P; 9423e12c5d1SDavid du Colombier if(c) 9433e12c5d1SDavid du Colombier goto newloop; 9443e12c5d1SDavid du Colombier return; 9453e12c5d1SDavid du Colombier 9463e12c5d1SDavid du Colombier case AGLOBL: 9473e12c5d1SDavid du Colombier s = p->from.sym; 9483e12c5d1SDavid du Colombier if(s->type == 0 || s->type == SXREF) { 9493e12c5d1SDavid du Colombier s->type = SBSS; 9503e12c5d1SDavid du Colombier s->value = 0; 9513e12c5d1SDavid du Colombier } 9523e12c5d1SDavid du Colombier if(s->type != SBSS) { 9536b6b9ac8SDavid du Colombier diag("%s: redefinition: %s in %s", 9543e12c5d1SDavid du Colombier pn, s->name, TNAME); 9553e12c5d1SDavid du Colombier s->type = SBSS; 9563e12c5d1SDavid du Colombier s->value = 0; 9573e12c5d1SDavid du Colombier } 9583e12c5d1SDavid du Colombier if(p->to.offset > s->value) 9593e12c5d1SDavid du Colombier s->value = p->to.offset; 9603e12c5d1SDavid du Colombier goto loop; 9613e12c5d1SDavid du Colombier 962219b2ee8SDavid du Colombier case ADYNT: 963219b2ee8SDavid du Colombier if(p->to.sym == S) { 9646b6b9ac8SDavid du Colombier diag("DYNT without a sym\n%P", p); 965219b2ee8SDavid du Colombier break; 966219b2ee8SDavid du Colombier } 967219b2ee8SDavid du Colombier di = p->to.sym; 968219b2ee8SDavid du Colombier p->from.scale = 4; 969219b2ee8SDavid du Colombier if(di->type == SXREF) { 970219b2ee8SDavid du Colombier if(debug['z']) 971219b2ee8SDavid du Colombier Bprint(&bso, "%P set to %d\n", p, dtype); 972219b2ee8SDavid du Colombier di->type = SCONST; 973219b2ee8SDavid du Colombier di->value = dtype; 974219b2ee8SDavid du Colombier dtype += 4; 975219b2ee8SDavid du Colombier } 976219b2ee8SDavid du Colombier if(p->from.sym == S) 977219b2ee8SDavid du Colombier break; 978219b2ee8SDavid du Colombier 979219b2ee8SDavid du Colombier p->from.offset = di->value; 980219b2ee8SDavid du Colombier p->from.sym->type = SDATA; 981219b2ee8SDavid du Colombier if(curtext == P) { 9826b6b9ac8SDavid du Colombier diag("DYNT not in text: %P", p); 983219b2ee8SDavid du Colombier break; 984219b2ee8SDavid du Colombier } 985219b2ee8SDavid du Colombier p->to.sym = curtext->from.sym; 986219b2ee8SDavid du Colombier p->to.type = D_ADDR; 987219b2ee8SDavid du Colombier p->to.index = D_EXTERN; 988219b2ee8SDavid du Colombier goto data; 989219b2ee8SDavid du Colombier 990219b2ee8SDavid du Colombier case AINIT: 991219b2ee8SDavid du Colombier if(p->from.sym == S) { 9926b6b9ac8SDavid du Colombier diag("INIT without a sym\n%P", p); 993219b2ee8SDavid du Colombier break; 994219b2ee8SDavid du Colombier } 995219b2ee8SDavid du Colombier if(di == S) { 9966b6b9ac8SDavid du Colombier diag("INIT without previous DYNT\n%P", p); 997219b2ee8SDavid du Colombier break; 998219b2ee8SDavid du Colombier } 999219b2ee8SDavid du Colombier p->from.offset = di->value; 1000219b2ee8SDavid du Colombier p->from.sym->type = SDATA; 1001219b2ee8SDavid du Colombier goto data; 1002219b2ee8SDavid du Colombier 10033e12c5d1SDavid du Colombier case ADATA: 1004219b2ee8SDavid du Colombier data: 10053e12c5d1SDavid du Colombier if(edatap == P) 10063e12c5d1SDavid du Colombier datap = p; 10073e12c5d1SDavid du Colombier else 10083e12c5d1SDavid du Colombier edatap->link = p; 10093e12c5d1SDavid du Colombier edatap = p; 10103e12c5d1SDavid du Colombier p->link = P; 10113e12c5d1SDavid du Colombier goto loop; 10123e12c5d1SDavid du Colombier 10133e12c5d1SDavid du Colombier case AGOK: 10146b6b9ac8SDavid du Colombier diag("%s: GOK opcode in %s", pn, TNAME); 10153e12c5d1SDavid du Colombier pc++; 10163e12c5d1SDavid du Colombier goto loop; 10173e12c5d1SDavid du Colombier 10183e12c5d1SDavid du Colombier case ATEXT: 10193e12c5d1SDavid du Colombier if(curtext != P) { 10203e12c5d1SDavid du Colombier histtoauto(); 10213e12c5d1SDavid du Colombier curtext->to.autom = curauto; 10223e12c5d1SDavid du Colombier curauto = 0; 10233e12c5d1SDavid du Colombier } 1024219b2ee8SDavid du Colombier skip = 0; 10253e12c5d1SDavid du Colombier curtext = p; 10263e12c5d1SDavid du Colombier s = p->from.sym; 10273e12c5d1SDavid du Colombier if(s == S) { 10286b6b9ac8SDavid du Colombier diag("%s: no TEXT symbol: %P", pn, p); 10293e12c5d1SDavid du Colombier errorexit(); 10303e12c5d1SDavid du Colombier } 1031219b2ee8SDavid du Colombier if(s->type != 0 && s->type != SXREF) { 1032219b2ee8SDavid du Colombier if(p->from.scale & DUPOK) { 1033219b2ee8SDavid du Colombier skip = 1; 1034219b2ee8SDavid du Colombier goto casdef; 1035219b2ee8SDavid du Colombier } 10366b6b9ac8SDavid du Colombier diag("%s: redefinition: %s\n%P", pn, s->name, p); 1037219b2ee8SDavid du Colombier } 10383e12c5d1SDavid du Colombier s->type = STEXT; 1039219b2ee8SDavid du Colombier s->value = pc; 1040219b2ee8SDavid du Colombier lastp->link = p; 1041219b2ee8SDavid du Colombier lastp = p; 1042219b2ee8SDavid du Colombier p->pc = pc; 10433e12c5d1SDavid du Colombier pc++; 10443e12c5d1SDavid du Colombier if(textp == P) { 10453e12c5d1SDavid du Colombier textp = p; 10463e12c5d1SDavid du Colombier etextp = p; 10473e12c5d1SDavid du Colombier goto loop; 10483e12c5d1SDavid du Colombier } 10497dd7cddfSDavid du Colombier etextp->pcond = p; 10503e12c5d1SDavid du Colombier etextp = p; 10513e12c5d1SDavid du Colombier goto loop; 10523e12c5d1SDavid du Colombier 10533e12c5d1SDavid du Colombier case AFMOVF: 10543e12c5d1SDavid du Colombier case AFADDF: 10553e12c5d1SDavid du Colombier case AFSUBF: 10563e12c5d1SDavid du Colombier case AFSUBRF: 10573e12c5d1SDavid du Colombier case AFMULF: 10583e12c5d1SDavid du Colombier case AFDIVF: 10593e12c5d1SDavid du Colombier case AFDIVRF: 10603e12c5d1SDavid du Colombier case AFCOMF: 10613e12c5d1SDavid du Colombier case AFCOMFP: 1062219b2ee8SDavid du Colombier if(skip) 1063219b2ee8SDavid du Colombier goto casdef; 10643e12c5d1SDavid du Colombier if(p->from.type == D_FCONST) { 10653e12c5d1SDavid du Colombier /* size sb 9 max */ 10663e12c5d1SDavid du Colombier sprint(literal, "$%lux", ieeedtof(&p->from.ieee)); 10673e12c5d1SDavid du Colombier s = lookup(literal, 0); 10683e12c5d1SDavid du Colombier if(s->type == 0) { 10693e12c5d1SDavid du Colombier s->type = SBSS; 10703e12c5d1SDavid du Colombier s->value = 4; 10713e12c5d1SDavid du Colombier t = prg(); 10723e12c5d1SDavid du Colombier t->as = ADATA; 10733e12c5d1SDavid du Colombier t->line = p->line; 10743e12c5d1SDavid du Colombier t->from.type = D_EXTERN; 10753e12c5d1SDavid du Colombier t->from.sym = s; 10763e12c5d1SDavid du Colombier t->from.scale = 4; 10773e12c5d1SDavid du Colombier t->to = p->from; 10783e12c5d1SDavid du Colombier if(edatap == P) 10793e12c5d1SDavid du Colombier datap = t; 10803e12c5d1SDavid du Colombier else 10813e12c5d1SDavid du Colombier edatap->link = t; 10823e12c5d1SDavid du Colombier edatap = t; 10833e12c5d1SDavid du Colombier t->link = P; 10843e12c5d1SDavid du Colombier } 10853e12c5d1SDavid du Colombier p->from.type = D_EXTERN; 10863e12c5d1SDavid du Colombier p->from.sym = s; 10873e12c5d1SDavid du Colombier p->from.offset = 0; 10883e12c5d1SDavid du Colombier } 10893e12c5d1SDavid du Colombier goto casdef; 10903e12c5d1SDavid du Colombier 10913e12c5d1SDavid du Colombier case AFMOVD: 10923e12c5d1SDavid du Colombier case AFADDD: 10933e12c5d1SDavid du Colombier case AFSUBD: 10943e12c5d1SDavid du Colombier case AFSUBRD: 10953e12c5d1SDavid du Colombier case AFMULD: 10963e12c5d1SDavid du Colombier case AFDIVD: 10973e12c5d1SDavid du Colombier case AFDIVRD: 10983e12c5d1SDavid du Colombier case AFCOMD: 10993e12c5d1SDavid du Colombier case AFCOMDP: 1100219b2ee8SDavid du Colombier if(skip) 1101219b2ee8SDavid du Colombier goto casdef; 11023e12c5d1SDavid du Colombier if(p->from.type == D_FCONST) { 11033e12c5d1SDavid du Colombier /* size sb 18 max */ 11043e12c5d1SDavid du Colombier sprint(literal, "$%lux.%lux", 11053e12c5d1SDavid du Colombier p->from.ieee.l, p->from.ieee.h); 11063e12c5d1SDavid du Colombier s = lookup(literal, 0); 11073e12c5d1SDavid du Colombier if(s->type == 0) { 11083e12c5d1SDavid du Colombier s->type = SBSS; 11093e12c5d1SDavid du Colombier s->value = 8; 11103e12c5d1SDavid du Colombier t = prg(); 11113e12c5d1SDavid du Colombier t->as = ADATA; 11123e12c5d1SDavid du Colombier t->line = p->line; 11133e12c5d1SDavid du Colombier t->from.type = D_EXTERN; 11143e12c5d1SDavid du Colombier t->from.sym = s; 11153e12c5d1SDavid du Colombier t->from.scale = 8; 11163e12c5d1SDavid du Colombier t->to = p->from; 11173e12c5d1SDavid du Colombier if(edatap == P) 11183e12c5d1SDavid du Colombier datap = t; 11193e12c5d1SDavid du Colombier else 11203e12c5d1SDavid du Colombier edatap->link = t; 11213e12c5d1SDavid du Colombier edatap = t; 11223e12c5d1SDavid du Colombier t->link = P; 11233e12c5d1SDavid du Colombier } 11243e12c5d1SDavid du Colombier p->from.type = D_EXTERN; 11253e12c5d1SDavid du Colombier p->from.sym = s; 11263e12c5d1SDavid du Colombier p->from.offset = 0; 11273e12c5d1SDavid du Colombier } 11283e12c5d1SDavid du Colombier goto casdef; 11293e12c5d1SDavid du Colombier 11303e12c5d1SDavid du Colombier casdef: 11313e12c5d1SDavid du Colombier default: 1132219b2ee8SDavid du Colombier if(skip) 1133219b2ee8SDavid du Colombier nopout(p); 1134219b2ee8SDavid du Colombier 11353e12c5d1SDavid du Colombier if(p->to.type == D_BRANCH) 11363e12c5d1SDavid du Colombier p->to.offset += ipc; 11373e12c5d1SDavid du Colombier lastp->link = p; 11383e12c5d1SDavid du Colombier lastp = p; 11393e12c5d1SDavid du Colombier p->pc = pc; 11403e12c5d1SDavid du Colombier pc++; 11413e12c5d1SDavid du Colombier goto loop; 11423e12c5d1SDavid du Colombier } 11433e12c5d1SDavid du Colombier goto loop; 11443e12c5d1SDavid du Colombier 11453e12c5d1SDavid du Colombier eof: 11466b6b9ac8SDavid du Colombier diag("truncated object file: %s", pn); 11473e12c5d1SDavid du Colombier } 11483e12c5d1SDavid du Colombier 11493e12c5d1SDavid du Colombier Sym* 11503e12c5d1SDavid du Colombier lookup(char *symb, int v) 11513e12c5d1SDavid du Colombier { 11523e12c5d1SDavid du Colombier Sym *s; 11533e12c5d1SDavid du Colombier char *p; 11543e12c5d1SDavid du Colombier long h; 1155219b2ee8SDavid du Colombier int l, c; 11563e12c5d1SDavid du Colombier 11573e12c5d1SDavid du Colombier h = v; 1158219b2ee8SDavid du Colombier for(p=symb; c = *p; p++) 11593e12c5d1SDavid du Colombier h = h+h+h + c; 1160219b2ee8SDavid du Colombier l = (p - symb) + 1; 1161b87cd620SDavid du Colombier h &= 0xffffff; 11623e12c5d1SDavid du Colombier h %= NHASH; 1163219b2ee8SDavid du Colombier for(s = hash[h]; s != S; s = s->link) 11643e12c5d1SDavid du Colombier if(s->version == v) 1165219b2ee8SDavid du Colombier if(memcmp(s->name, symb, l) == 0) 11663e12c5d1SDavid du Colombier return s; 11673e12c5d1SDavid du Colombier 11683e12c5d1SDavid du Colombier while(nhunk < sizeof(Sym)) 11693e12c5d1SDavid du Colombier gethunk(); 11703e12c5d1SDavid du Colombier s = (Sym*)hunk; 11713e12c5d1SDavid du Colombier nhunk -= sizeof(Sym); 11723e12c5d1SDavid du Colombier hunk += sizeof(Sym); 11733e12c5d1SDavid du Colombier 1174219b2ee8SDavid du Colombier s->name = malloc(l + 1); 1175219b2ee8SDavid du Colombier memmove(s->name, symb, l); 1176219b2ee8SDavid du Colombier 11773e12c5d1SDavid du Colombier s->link = hash[h]; 11783e12c5d1SDavid du Colombier s->type = 0; 11793e12c5d1SDavid du Colombier s->version = v; 11803e12c5d1SDavid du Colombier s->value = 0; 1181375daca8SDavid du Colombier s->sig = 0; 11823e12c5d1SDavid du Colombier hash[h] = s; 11833e12c5d1SDavid du Colombier nsymbol++; 11843e12c5d1SDavid du Colombier return s; 11853e12c5d1SDavid du Colombier } 11863e12c5d1SDavid du Colombier 11873e12c5d1SDavid du Colombier Prog* 11883e12c5d1SDavid du Colombier prg(void) 11893e12c5d1SDavid du Colombier { 11903e12c5d1SDavid du Colombier Prog *p; 11913e12c5d1SDavid du Colombier 11923e12c5d1SDavid du Colombier while(nhunk < sizeof(Prog)) 11933e12c5d1SDavid du Colombier gethunk(); 11943e12c5d1SDavid du Colombier p = (Prog*)hunk; 11953e12c5d1SDavid du Colombier nhunk -= sizeof(Prog); 11963e12c5d1SDavid du Colombier hunk += sizeof(Prog); 11973e12c5d1SDavid du Colombier 11983e12c5d1SDavid du Colombier *p = zprg; 11993e12c5d1SDavid du Colombier return p; 12003e12c5d1SDavid du Colombier } 12013e12c5d1SDavid du Colombier 12023e12c5d1SDavid du Colombier Prog* 12033e12c5d1SDavid du Colombier copyp(Prog *q) 12043e12c5d1SDavid du Colombier { 12053e12c5d1SDavid du Colombier Prog *p; 12063e12c5d1SDavid du Colombier 12073e12c5d1SDavid du Colombier p = prg(); 12083e12c5d1SDavid du Colombier *p = *q; 12093e12c5d1SDavid du Colombier return p; 12103e12c5d1SDavid du Colombier } 12113e12c5d1SDavid du Colombier 12123e12c5d1SDavid du Colombier Prog* 12133e12c5d1SDavid du Colombier appendp(Prog *q) 12143e12c5d1SDavid du Colombier { 12153e12c5d1SDavid du Colombier Prog *p; 12163e12c5d1SDavid du Colombier 12173e12c5d1SDavid du Colombier p = prg(); 12183e12c5d1SDavid du Colombier p->link = q->link; 12193e12c5d1SDavid du Colombier q->link = p; 12203e12c5d1SDavid du Colombier p->line = q->line; 12213e12c5d1SDavid du Colombier return p; 12223e12c5d1SDavid du Colombier } 12233e12c5d1SDavid du Colombier 12243e12c5d1SDavid du Colombier void 12253e12c5d1SDavid du Colombier gethunk(void) 12263e12c5d1SDavid du Colombier { 12273e12c5d1SDavid du Colombier char *h; 12283e12c5d1SDavid du Colombier long nh; 12293e12c5d1SDavid du Colombier 12303e12c5d1SDavid du Colombier nh = NHUNK; 12313e12c5d1SDavid du Colombier if(thunk >= 5L*NHUNK) { 12323e12c5d1SDavid du Colombier nh = 5L*NHUNK; 12333e12c5d1SDavid du Colombier if(thunk >= 25L*NHUNK) 12343e12c5d1SDavid du Colombier nh = 25L*NHUNK; 12353e12c5d1SDavid du Colombier } 12367dd7cddfSDavid du Colombier h = mysbrk(nh); 12373e12c5d1SDavid du Colombier if(h == (char*)-1) { 12386b6b9ac8SDavid du Colombier diag("out of memory"); 12393e12c5d1SDavid du Colombier errorexit(); 12403e12c5d1SDavid du Colombier } 12413e12c5d1SDavid du Colombier hunk = h; 12423e12c5d1SDavid du Colombier nhunk = nh; 12433e12c5d1SDavid du Colombier thunk += nh; 12443e12c5d1SDavid du Colombier } 12453e12c5d1SDavid du Colombier 12463e12c5d1SDavid du Colombier void 12473e12c5d1SDavid du Colombier doprof1(void) 12483e12c5d1SDavid du Colombier { 12493e12c5d1SDavid du Colombier Sym *s; 12503e12c5d1SDavid du Colombier long n; 12513e12c5d1SDavid du Colombier Prog *p, *q; 12523e12c5d1SDavid du Colombier 12533e12c5d1SDavid du Colombier if(debug['v']) 12543e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f profile 1\n", cputime()); 12553e12c5d1SDavid du Colombier Bflush(&bso); 12563e12c5d1SDavid du Colombier s = lookup("__mcount", 0); 12573e12c5d1SDavid du Colombier n = 1; 12583e12c5d1SDavid du Colombier for(p = firstp->link; p != P; p = p->link) { 12593e12c5d1SDavid du Colombier if(p->as == ATEXT) { 12603e12c5d1SDavid du Colombier q = prg(); 12613e12c5d1SDavid du Colombier q->line = p->line; 12623e12c5d1SDavid du Colombier q->link = datap; 12633e12c5d1SDavid du Colombier datap = q; 12643e12c5d1SDavid du Colombier q->as = ADATA; 12653e12c5d1SDavid du Colombier q->from.type = D_EXTERN; 12663e12c5d1SDavid du Colombier q->from.offset = n*4; 12673e12c5d1SDavid du Colombier q->from.sym = s; 12683e12c5d1SDavid du Colombier q->from.scale = 4; 12693e12c5d1SDavid du Colombier q->to = p->from; 12703e12c5d1SDavid du Colombier q->to.type = D_CONST; 12713e12c5d1SDavid du Colombier 12723e12c5d1SDavid du Colombier q = prg(); 12733e12c5d1SDavid du Colombier q->line = p->line; 12743e12c5d1SDavid du Colombier q->pc = p->pc; 12753e12c5d1SDavid du Colombier q->link = p->link; 12763e12c5d1SDavid du Colombier p->link = q; 12773e12c5d1SDavid du Colombier p = q; 12783e12c5d1SDavid du Colombier p->as = AADDL; 12793e12c5d1SDavid du Colombier p->from.type = D_CONST; 12803e12c5d1SDavid du Colombier p->from.offset = 1; 12813e12c5d1SDavid du Colombier p->to.type = D_EXTERN; 12823e12c5d1SDavid du Colombier p->to.sym = s; 12833e12c5d1SDavid du Colombier p->to.offset = n*4 + 4; 12843e12c5d1SDavid du Colombier 12853e12c5d1SDavid du Colombier n += 2; 12863e12c5d1SDavid du Colombier continue; 12873e12c5d1SDavid du Colombier } 12883e12c5d1SDavid du Colombier } 12893e12c5d1SDavid du Colombier q = prg(); 12903e12c5d1SDavid du Colombier q->line = 0; 12913e12c5d1SDavid du Colombier q->link = datap; 12923e12c5d1SDavid du Colombier datap = q; 12933e12c5d1SDavid du Colombier 12943e12c5d1SDavid du Colombier q->as = ADATA; 12953e12c5d1SDavid du Colombier q->from.type = D_EXTERN; 12963e12c5d1SDavid du Colombier q->from.sym = s; 12973e12c5d1SDavid du Colombier q->from.scale = 4; 12983e12c5d1SDavid du Colombier q->to.type = D_CONST; 12993e12c5d1SDavid du Colombier q->to.offset = n; 13003e12c5d1SDavid du Colombier 13013e12c5d1SDavid du Colombier s->type = SBSS; 13023e12c5d1SDavid du Colombier s->value = n*4; 13033e12c5d1SDavid du Colombier } 13043e12c5d1SDavid du Colombier 13053e12c5d1SDavid du Colombier void 13063e12c5d1SDavid du Colombier doprof2(void) 13073e12c5d1SDavid du Colombier { 13083e12c5d1SDavid du Colombier Sym *s2, *s4; 130925fc6993SDavid du Colombier Prog *p, *q, *q2, *ps2, *ps4; 13103e12c5d1SDavid du Colombier 13113e12c5d1SDavid du Colombier if(debug['v']) 13123e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f profile 2\n", cputime()); 13133e12c5d1SDavid du Colombier Bflush(&bso); 13143e12c5d1SDavid du Colombier 131525fc6993SDavid du Colombier if(debug['e']){ 131625fc6993SDavid du Colombier s2 = lookup("_tracein", 0); 131725fc6993SDavid du Colombier s4 = lookup("_traceout", 0); 131825fc6993SDavid du Colombier }else{ 13193e12c5d1SDavid du Colombier s2 = lookup("_profin", 0); 13203e12c5d1SDavid du Colombier s4 = lookup("_profout", 0); 132125fc6993SDavid du Colombier } 132259cc4ca5SDavid du Colombier if(s2->type != STEXT || s4->type != STEXT) { 132325fc6993SDavid du Colombier if(debug['e']) 132425fc6993SDavid du Colombier diag("_tracein/_traceout not defined %d %d", s2->type, s4->type); 132525fc6993SDavid du Colombier else 13266b6b9ac8SDavid du Colombier diag("_profin/_profout not defined"); 132759cc4ca5SDavid du Colombier return; 132859cc4ca5SDavid du Colombier } 13293e12c5d1SDavid du Colombier 13303e12c5d1SDavid du Colombier ps2 = P; 13313e12c5d1SDavid du Colombier ps4 = P; 13323e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) { 13333e12c5d1SDavid du Colombier if(p->as == ATEXT) { 13343e12c5d1SDavid du Colombier if(p->from.sym == s2) { 13353e12c5d1SDavid du Colombier p->from.scale = 1; 13363e12c5d1SDavid du Colombier ps2 = p; 13373e12c5d1SDavid du Colombier } 13383e12c5d1SDavid du Colombier if(p->from.sym == s4) { 13393e12c5d1SDavid du Colombier p->from.scale = 1; 13403e12c5d1SDavid du Colombier ps4 = p; 13413e12c5d1SDavid du Colombier } 13423e12c5d1SDavid du Colombier } 13433e12c5d1SDavid du Colombier } 13443e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) { 13453e12c5d1SDavid du Colombier if(p->as == ATEXT) { 13463e12c5d1SDavid du Colombier curtext = p; 13473e12c5d1SDavid du Colombier 1348219b2ee8SDavid du Colombier if(p->from.scale & NOPROF) { /* dont profile */ 13493e12c5d1SDavid du Colombier for(;;) { 13503e12c5d1SDavid du Colombier q = p->link; 13513e12c5d1SDavid du Colombier if(q == P) 13523e12c5d1SDavid du Colombier break; 13533e12c5d1SDavid du Colombier if(q->as == ATEXT) 13543e12c5d1SDavid du Colombier break; 13553e12c5d1SDavid du Colombier p = q; 13563e12c5d1SDavid du Colombier } 13573e12c5d1SDavid du Colombier continue; 13583e12c5d1SDavid du Colombier } 13593e12c5d1SDavid du Colombier 13603e12c5d1SDavid du Colombier /* 13613e12c5d1SDavid du Colombier * JMPL profin 13623e12c5d1SDavid du Colombier */ 13633e12c5d1SDavid du Colombier q = prg(); 13643e12c5d1SDavid du Colombier q->line = p->line; 13653e12c5d1SDavid du Colombier q->pc = p->pc; 13663e12c5d1SDavid du Colombier q->link = p->link; 136725fc6993SDavid du Colombier if(debug['e']){ /* embedded tracing */ 136825fc6993SDavid du Colombier q2 = prg(); 136925fc6993SDavid du Colombier p->link = q2; 137025fc6993SDavid du Colombier q2->link = q; 137125fc6993SDavid du Colombier 137225fc6993SDavid du Colombier q2->line = p->line; 137325fc6993SDavid du Colombier q2->pc = p->pc; 137425fc6993SDavid du Colombier 137525fc6993SDavid du Colombier q2->as = AJMP; 137625fc6993SDavid du Colombier q2->to.type = D_BRANCH; 137725fc6993SDavid du Colombier q2->to.sym = p->to.sym; 137825fc6993SDavid du Colombier q2->pcond = q->link; 137925fc6993SDavid du Colombier }else 13803e12c5d1SDavid du Colombier p->link = q; 13813e12c5d1SDavid du Colombier p = q; 13823e12c5d1SDavid du Colombier p->as = ACALL; 13833e12c5d1SDavid du Colombier p->to.type = D_BRANCH; 13847dd7cddfSDavid du Colombier p->pcond = ps2; 13853e12c5d1SDavid du Colombier p->to.sym = s2; 13863e12c5d1SDavid du Colombier 13873e12c5d1SDavid du Colombier continue; 13883e12c5d1SDavid du Colombier } 13893e12c5d1SDavid du Colombier if(p->as == ARET) { 1390219b2ee8SDavid du Colombier /* 139125fc6993SDavid du Colombier * RET (default) 139225fc6993SDavid du Colombier */ 139325fc6993SDavid du Colombier if(debug['e']){ /* embedded tracing */ 139425fc6993SDavid du Colombier q = prg(); 139525fc6993SDavid du Colombier q->line = p->line; 139625fc6993SDavid du Colombier q->pc = p->pc; 139725fc6993SDavid du Colombier q->link = p->link; 139825fc6993SDavid du Colombier p->link = q; 139925fc6993SDavid du Colombier p = q; 140025fc6993SDavid du Colombier } 140125fc6993SDavid du Colombier /* 1402219b2ee8SDavid du Colombier * RET 1403219b2ee8SDavid du Colombier */ 1404219b2ee8SDavid du Colombier q = prg(); 1405219b2ee8SDavid du Colombier q->as = ARET; 1406219b2ee8SDavid du Colombier q->from = p->from; 1407219b2ee8SDavid du Colombier q->to = p->to; 1408219b2ee8SDavid du Colombier q->link = p->link; 1409219b2ee8SDavid du Colombier p->link = q; 14103e12c5d1SDavid du Colombier 14113e12c5d1SDavid du Colombier /* 1412219b2ee8SDavid du Colombier * JAL profout 14133e12c5d1SDavid du Colombier */ 14143e12c5d1SDavid du Colombier p->as = ACALL; 14153e12c5d1SDavid du Colombier p->from = zprg.from; 14163e12c5d1SDavid du Colombier p->to = zprg.to; 14173e12c5d1SDavid du Colombier p->to.type = D_BRANCH; 14187dd7cddfSDavid du Colombier p->pcond = ps4; 14193e12c5d1SDavid du Colombier p->to.sym = s4; 14203e12c5d1SDavid du Colombier 14213e12c5d1SDavid du Colombier p = q; 14223e12c5d1SDavid du Colombier 14233e12c5d1SDavid du Colombier continue; 14243e12c5d1SDavid du Colombier } 14253e12c5d1SDavid du Colombier } 14263e12c5d1SDavid du Colombier } 14273e12c5d1SDavid du Colombier 14283e12c5d1SDavid du Colombier void 14293e12c5d1SDavid du Colombier nuxiinit(void) 14303e12c5d1SDavid du Colombier { 14313e12c5d1SDavid du Colombier int i, c; 14323e12c5d1SDavid du Colombier 14333e12c5d1SDavid du Colombier for(i=0; i<4; i++) { 14343e12c5d1SDavid du Colombier c = find1(0x04030201L, i+1); 14353e12c5d1SDavid du Colombier if(i < 2) 14363e12c5d1SDavid du Colombier inuxi2[i] = c; 14373e12c5d1SDavid du Colombier if(i < 1) 14383e12c5d1SDavid du Colombier inuxi1[i] = c; 14393e12c5d1SDavid du Colombier inuxi4[i] = c; 14403e12c5d1SDavid du Colombier fnuxi4[i] = c; 14413e12c5d1SDavid du Colombier fnuxi8[i] = c; 14423e12c5d1SDavid du Colombier fnuxi8[i+4] = c+4; 14433e12c5d1SDavid du Colombier } 14443e12c5d1SDavid du Colombier if(debug['v']) { 14453e12c5d1SDavid du Colombier Bprint(&bso, "inuxi = "); 14463e12c5d1SDavid du Colombier for(i=0; i<1; i++) 14473e12c5d1SDavid du Colombier Bprint(&bso, "%d", inuxi1[i]); 14483e12c5d1SDavid du Colombier Bprint(&bso, " "); 14493e12c5d1SDavid du Colombier for(i=0; i<2; i++) 14503e12c5d1SDavid du Colombier Bprint(&bso, "%d", inuxi2[i]); 14513e12c5d1SDavid du Colombier Bprint(&bso, " "); 14523e12c5d1SDavid du Colombier for(i=0; i<4; i++) 14533e12c5d1SDavid du Colombier Bprint(&bso, "%d", inuxi4[i]); 14543e12c5d1SDavid du Colombier Bprint(&bso, "\nfnuxi = "); 14553e12c5d1SDavid du Colombier for(i=0; i<4; i++) 14563e12c5d1SDavid du Colombier Bprint(&bso, "%d", fnuxi4[i]); 14573e12c5d1SDavid du Colombier Bprint(&bso, " "); 14583e12c5d1SDavid du Colombier for(i=0; i<8; i++) 14593e12c5d1SDavid du Colombier Bprint(&bso, "%d", fnuxi8[i]); 14603e12c5d1SDavid du Colombier Bprint(&bso, "\n"); 14613e12c5d1SDavid du Colombier } 14623e12c5d1SDavid du Colombier Bflush(&bso); 14633e12c5d1SDavid du Colombier } 14643e12c5d1SDavid du Colombier 14653e12c5d1SDavid du Colombier int 14663e12c5d1SDavid du Colombier find1(long l, int c) 14673e12c5d1SDavid du Colombier { 14683e12c5d1SDavid du Colombier char *p; 14693e12c5d1SDavid du Colombier int i; 14703e12c5d1SDavid du Colombier 14713e12c5d1SDavid du Colombier p = (char*)&l; 14723e12c5d1SDavid du Colombier for(i=0; i<4; i++) 14733e12c5d1SDavid du Colombier if(*p++ == c) 14743e12c5d1SDavid du Colombier return i; 14753e12c5d1SDavid du Colombier return 0; 14763e12c5d1SDavid du Colombier } 14773e12c5d1SDavid du Colombier 14783e12c5d1SDavid du Colombier int 14793e12c5d1SDavid du Colombier find2(long l, int c) 14803e12c5d1SDavid du Colombier { 14813e12c5d1SDavid du Colombier short *p; 14823e12c5d1SDavid du Colombier int i; 14833e12c5d1SDavid du Colombier 14843e12c5d1SDavid du Colombier p = (short*)&l; 14853e12c5d1SDavid du Colombier for(i=0; i<4; i+=2) { 14863e12c5d1SDavid du Colombier if(((*p >> 8) & 0xff) == c) 14873e12c5d1SDavid du Colombier return i; 14883e12c5d1SDavid du Colombier if((*p++ & 0xff) == c) 14893e12c5d1SDavid du Colombier return i+1; 14903e12c5d1SDavid du Colombier } 14913e12c5d1SDavid du Colombier return 0; 14923e12c5d1SDavid du Colombier } 14933e12c5d1SDavid du Colombier 14943e12c5d1SDavid du Colombier long 14953e12c5d1SDavid du Colombier ieeedtof(Ieee *e) 14963e12c5d1SDavid du Colombier { 14973e12c5d1SDavid du Colombier int exp; 14983e12c5d1SDavid du Colombier long v; 14993e12c5d1SDavid du Colombier 15003e12c5d1SDavid du Colombier if(e->h == 0) 15013e12c5d1SDavid du Colombier return 0; 15023e12c5d1SDavid du Colombier exp = (e->h>>20) & ((1L<<11)-1L); 15033e12c5d1SDavid du Colombier exp -= (1L<<10) - 2L; 15043e12c5d1SDavid du Colombier v = (e->h & 0xfffffL) << 3; 15053e12c5d1SDavid du Colombier v |= (e->l >> 29) & 0x7L; 15063e12c5d1SDavid du Colombier if((e->l >> 28) & 1) { 15073e12c5d1SDavid du Colombier v++; 15083e12c5d1SDavid du Colombier if(v & 0x800000L) { 15093e12c5d1SDavid du Colombier v = (v & 0x7fffffL) >> 1; 15103e12c5d1SDavid du Colombier exp++; 15113e12c5d1SDavid du Colombier } 15123e12c5d1SDavid du Colombier } 15133e12c5d1SDavid du Colombier if(exp <= -126 || exp >= 130) 15146b6b9ac8SDavid du Colombier diag("double fp to single fp overflow"); 15153e12c5d1SDavid du Colombier v |= ((exp + 126) & 0xffL) << 23; 15163e12c5d1SDavid du Colombier v |= e->h & 0x80000000L; 15173e12c5d1SDavid du Colombier return v; 15183e12c5d1SDavid du Colombier } 15193e12c5d1SDavid du Colombier 15203e12c5d1SDavid du Colombier double 15217dd7cddfSDavid du Colombier ieeedtod(Ieee *ieeep) 15223e12c5d1SDavid du Colombier { 15233e12c5d1SDavid du Colombier Ieee e; 15243e12c5d1SDavid du Colombier double fr; 15253e12c5d1SDavid du Colombier int exp; 15263e12c5d1SDavid du Colombier 15277dd7cddfSDavid du Colombier if(ieeep->h & (1L<<31)) { 15287dd7cddfSDavid du Colombier e.h = ieeep->h & ~(1L<<31); 15297dd7cddfSDavid du Colombier e.l = ieeep->l; 15303e12c5d1SDavid du Colombier return -ieeedtod(&e); 15313e12c5d1SDavid du Colombier } 15327dd7cddfSDavid du Colombier if(ieeep->l == 0 && ieeep->h == 0) 15333e12c5d1SDavid du Colombier return 0; 15347dd7cddfSDavid du Colombier fr = ieeep->l & ((1L<<16)-1L); 15353e12c5d1SDavid du Colombier fr /= 1L<<16; 15367dd7cddfSDavid du Colombier fr += (ieeep->l>>16) & ((1L<<16)-1L); 15373e12c5d1SDavid du Colombier fr /= 1L<<16; 15387dd7cddfSDavid du Colombier fr += (ieeep->h & (1L<<20)-1L) | (1L<<20); 15393e12c5d1SDavid du Colombier fr /= 1L<<21; 15407dd7cddfSDavid du Colombier exp = (ieeep->h>>20) & ((1L<<11)-1L); 15413e12c5d1SDavid du Colombier exp -= (1L<<10) - 2L; 15423e12c5d1SDavid du Colombier return ldexp(fr, exp); 15433e12c5d1SDavid du Colombier } 15449a747e4fSDavid du Colombier 15459a747e4fSDavid du Colombier void 1546375daca8SDavid du Colombier undefsym(Sym *s) 1547375daca8SDavid du Colombier { 1548375daca8SDavid du Colombier int n; 1549375daca8SDavid du Colombier 1550375daca8SDavid du Colombier n = imports; 1551375daca8SDavid du Colombier if(s->value != 0) 1552375daca8SDavid du Colombier diag("value != 0 on SXREF"); 1553375daca8SDavid du Colombier if(n >= 1<<Rindex) 1554375daca8SDavid du Colombier diag("import index %d out of range", n); 1555375daca8SDavid du Colombier s->value = n<<Roffset; 1556375daca8SDavid du Colombier s->type = SUNDEF; 1557375daca8SDavid du Colombier imports++; 1558375daca8SDavid du Colombier } 1559375daca8SDavid du Colombier 1560375daca8SDavid du Colombier void 1561375daca8SDavid du Colombier zerosig(char *sp) 1562375daca8SDavid du Colombier { 1563375daca8SDavid du Colombier Sym *s; 1564375daca8SDavid du Colombier 1565375daca8SDavid du Colombier s = lookup(sp, 0); 1566375daca8SDavid du Colombier s->sig = 0; 1567375daca8SDavid du Colombier } 1568375daca8SDavid du Colombier 1569375daca8SDavid du Colombier void 1570375daca8SDavid du Colombier readundefs(char *f, int t) 15719a747e4fSDavid du Colombier { 15729a747e4fSDavid du Colombier int i, n; 15739a747e4fSDavid du Colombier Sym *s; 15749a747e4fSDavid du Colombier Biobuf *b; 1575375daca8SDavid du Colombier char *l, buf[256], *fields[64]; 15769a747e4fSDavid du Colombier 1577375daca8SDavid du Colombier if(f == nil) 1578375daca8SDavid du Colombier return; 1579375daca8SDavid du Colombier b = Bopen(f, OREAD); 15809a747e4fSDavid du Colombier if(b == nil){ 1581375daca8SDavid du Colombier diag("could not open %s: %r", f); 15829a747e4fSDavid du Colombier errorexit(); 15839a747e4fSDavid du Colombier } 15849a747e4fSDavid du Colombier while((l = Brdline(b, '\n')) != nil){ 15859a747e4fSDavid du Colombier n = Blinelen(b); 15869a747e4fSDavid du Colombier if(n >= sizeof(buf)){ 1587375daca8SDavid du Colombier diag("%s: line too long", f); 15889a747e4fSDavid du Colombier errorexit(); 15899a747e4fSDavid du Colombier } 1590375daca8SDavid du Colombier memmove(buf, l, n); 1591375daca8SDavid du Colombier buf[n-1] = '\0'; 15929a747e4fSDavid du Colombier n = getfields(buf, fields, nelem(fields), 1, " \t\r\n"); 15939a747e4fSDavid du Colombier if(n == nelem(fields)){ 1594375daca8SDavid du Colombier diag("%s: bad format", f); 15959a747e4fSDavid du Colombier errorexit(); 15969a747e4fSDavid du Colombier } 1597375daca8SDavid du Colombier for(i = 0; i < n; i++){ 1598375daca8SDavid du Colombier s = lookup(fields[i], 0); 1599375daca8SDavid du Colombier s->type = SXREF; 1600375daca8SDavid du Colombier s->subtype = t; 1601375daca8SDavid du Colombier if(t == SIMPORT) 1602375daca8SDavid du Colombier nimports++; 1603375daca8SDavid du Colombier else 1604375daca8SDavid du Colombier nexports++; 1605375daca8SDavid du Colombier } 16069a747e4fSDavid du Colombier } 16079a747e4fSDavid du Colombier Bterm(b); 16089a747e4fSDavid du Colombier } 1609