1375daca8SDavid du Colombier #define EXTERN 27dd7cddfSDavid du Colombier #include "l.h" 37dd7cddfSDavid du Colombier #include <ar.h> 47dd7cddfSDavid du Colombier 57dd7cddfSDavid du Colombier #ifndef DEFAULT 67dd7cddfSDavid du Colombier #define DEFAULT '9' 77dd7cddfSDavid du Colombier #endif 87dd7cddfSDavid du Colombier 97dd7cddfSDavid du Colombier char *noname = "<none>"; 107dd7cddfSDavid du Colombier char symname[] = SYMDEF; 117dd7cddfSDavid du Colombier char thechar = 'q'; 127dd7cddfSDavid du Colombier char *thestring = "power"; 137dd7cddfSDavid du Colombier 147dd7cddfSDavid du Colombier /* 157dd7cddfSDavid du Colombier * -H0 -T0x200000 -R0 is boot 167dd7cddfSDavid du Colombier * -H1 -T0x100000 -R4 is Be boot 177dd7cddfSDavid du Colombier * -H2 -T4128 -R4096 is plan9 format 187dd7cddfSDavid du Colombier * -H3 -T0x02010000 -D0x00001000 is raw 197dd7cddfSDavid du Colombier * -H4 -T0x1000200 -D0x20000e00 -R4 is aix xcoff executable 20dc5a79c1SDavid du Colombier * -H5 -T0x80010000 -t0x10000 ELF, phys = 10000, vaddr = 0x8001... 217dd7cddfSDavid du Colombier */ 227dd7cddfSDavid du Colombier 23375daca8SDavid du Colombier static int 24375daca8SDavid du Colombier isobjfile(char *f) 25375daca8SDavid du Colombier { 26375daca8SDavid du Colombier int n, v; 27375daca8SDavid du Colombier Biobuf *b; 28375daca8SDavid du Colombier char buf1[5], buf2[SARMAG]; 29375daca8SDavid du Colombier 30375daca8SDavid du Colombier b = Bopen(f, OREAD); 31375daca8SDavid du Colombier if(b == nil) 32375daca8SDavid du Colombier return 0; 33375daca8SDavid du Colombier n = Bread(b, buf1, 5); 34375daca8SDavid du Colombier if(n == 5 && (buf1[2] == 1 && buf1[3] == '<' || buf1[3] == 1 && buf1[4] == '<')) 35375daca8SDavid du Colombier v = 1; /* good enough for our purposes */ 36375daca8SDavid du Colombier else{ 37375daca8SDavid du Colombier Bseek(b, 0, 0); 38375daca8SDavid du Colombier n = Bread(b, buf2, SARMAG); 39375daca8SDavid du Colombier v = n == SARMAG && strncmp(buf2, ARMAG, SARMAG) == 0; 40375daca8SDavid du Colombier } 41375daca8SDavid du Colombier Bterm(b); 42375daca8SDavid du Colombier return v; 43375daca8SDavid du Colombier } 44375daca8SDavid du Colombier 457dd7cddfSDavid du Colombier void 467dd7cddfSDavid du Colombier main(int argc, char *argv[]) 477dd7cddfSDavid du Colombier { 487dd7cddfSDavid du Colombier int c; 497dd7cddfSDavid du Colombier char *a; 507dd7cddfSDavid du Colombier 517dd7cddfSDavid du Colombier Binit(&bso, 1, OWRITE); 527dd7cddfSDavid du Colombier cout = -1; 537dd7cddfSDavid du Colombier listinit(); 547dd7cddfSDavid du Colombier outfile = 0; 557dd7cddfSDavid du Colombier nerrors = 0; 567dd7cddfSDavid du Colombier curtext = P; 577dd7cddfSDavid du Colombier HEADTYPE = -1; 587dd7cddfSDavid du Colombier INITTEXT = -1; 597dd7cddfSDavid du Colombier INITDAT = -1; 607dd7cddfSDavid du Colombier INITRND = -1; 617dd7cddfSDavid du Colombier INITENTRY = 0; 627dd7cddfSDavid du Colombier 637dd7cddfSDavid du Colombier ARGBEGIN { 647dd7cddfSDavid du Colombier default: 657dd7cddfSDavid du Colombier c = ARGC(); 667dd7cddfSDavid du Colombier if(c >= 0 && c < sizeof(debug)) 677dd7cddfSDavid du Colombier debug[c]++; 687dd7cddfSDavid du Colombier break; 697dd7cddfSDavid du Colombier case 'o': 707dd7cddfSDavid du Colombier outfile = ARGF(); 717dd7cddfSDavid du Colombier break; 727dd7cddfSDavid du Colombier case 'E': 737dd7cddfSDavid du Colombier a = ARGF(); 747dd7cddfSDavid du Colombier if(a) 757dd7cddfSDavid du Colombier INITENTRY = a; 767dd7cddfSDavid du Colombier break; 777dd7cddfSDavid du Colombier case 'T': 787dd7cddfSDavid du Colombier a = ARGF(); 797dd7cddfSDavid du Colombier if(a) 807dd7cddfSDavid du Colombier INITTEXT = atolwhex(a); 817dd7cddfSDavid du Colombier break; 827dd7cddfSDavid du Colombier case 'D': 837dd7cddfSDavid du Colombier a = ARGF(); 847dd7cddfSDavid du Colombier if(a) 857dd7cddfSDavid du Colombier INITDAT = atolwhex(a); 867dd7cddfSDavid du Colombier break; 877dd7cddfSDavid du Colombier case 'R': 887dd7cddfSDavid du Colombier a = ARGF(); 897dd7cddfSDavid du Colombier if(a) 907dd7cddfSDavid du Colombier INITRND = atolwhex(a); 917dd7cddfSDavid du Colombier break; 927dd7cddfSDavid du Colombier case 'H': 937dd7cddfSDavid du Colombier a = ARGF(); 947dd7cddfSDavid du Colombier if(a) 957dd7cddfSDavid du Colombier HEADTYPE = atolwhex(a); 967dd7cddfSDavid du Colombier break; 97375daca8SDavid du Colombier case 'x': /* produce export table */ 98375daca8SDavid du Colombier doexp = 1; 99375daca8SDavid du Colombier if(argv[1] != nil && argv[1][0] != '-' && !isobjfile(argv[1])) 100375daca8SDavid du Colombier readundefs(ARGF(), SEXPORT); 101375daca8SDavid du Colombier break; 102375daca8SDavid du Colombier case 'u': /* produce dynamically loadable module */ 103375daca8SDavid du Colombier dlm = 1; 104375daca8SDavid du Colombier if(argv[1] != nil && argv[1][0] != '-' && !isobjfile(argv[1])) 105375daca8SDavid du Colombier readundefs(ARGF(), SIMPORT); 106375daca8SDavid du Colombier break; 1077dd7cddfSDavid du Colombier } ARGEND 1087dd7cddfSDavid du Colombier USED(argc); 1097dd7cddfSDavid du Colombier if(*argv == 0) { 110375daca8SDavid du Colombier diag("usage: ql [-options] objects"); 1117dd7cddfSDavid du Colombier errorexit(); 1127dd7cddfSDavid du Colombier } 1137dd7cddfSDavid du Colombier if(!debug['9'] && !debug['U'] && !debug['B']) 1147dd7cddfSDavid du Colombier debug[DEFAULT] = 1; 115375daca8SDavid du Colombier r0iszero = debug['0'] == 0; 1167dd7cddfSDavid du Colombier if(HEADTYPE == -1) { 1177dd7cddfSDavid du Colombier if(debug['U']) 1187dd7cddfSDavid du Colombier HEADTYPE = 0; 1197dd7cddfSDavid du Colombier if(debug['B']) 1207dd7cddfSDavid du Colombier HEADTYPE = 1; 1217dd7cddfSDavid du Colombier if(debug['9']) 1227dd7cddfSDavid du Colombier HEADTYPE = 2; 1237dd7cddfSDavid du Colombier } 1247dd7cddfSDavid du Colombier switch(HEADTYPE) { 1257dd7cddfSDavid du Colombier default: 1267dd7cddfSDavid du Colombier diag("unknown -H option"); 1277dd7cddfSDavid du Colombier errorexit(); 1287dd7cddfSDavid du Colombier 1297dd7cddfSDavid du Colombier case 0: /* boot */ 1307dd7cddfSDavid du Colombier HEADR = 32L; 1317dd7cddfSDavid du Colombier if(INITTEXT == -1) 1327dd7cddfSDavid du Colombier INITTEXT = 0x200000L; 1337dd7cddfSDavid du Colombier if(INITDAT == -1) 1347dd7cddfSDavid du Colombier INITDAT = 0; 1357dd7cddfSDavid du Colombier if(INITRND == -1) 1367dd7cddfSDavid du Colombier INITRND = 4096L; 1377dd7cddfSDavid du Colombier break; 1387dd7cddfSDavid du Colombier case 1: /* Be boot format (PEF) */ 1397dd7cddfSDavid du Colombier HEADR = 208L; 1407dd7cddfSDavid du Colombier if(INITTEXT == -1) 1417dd7cddfSDavid du Colombier INITTEXT = 0x100000; 1427dd7cddfSDavid du Colombier if(INITDAT == -1) 1437dd7cddfSDavid du Colombier INITDAT = 0; 1447dd7cddfSDavid du Colombier if(INITRND == -1) 1457dd7cddfSDavid du Colombier INITRND = 4; 1467dd7cddfSDavid du Colombier break; 1477dd7cddfSDavid du Colombier case 2: /* plan 9 */ 1487dd7cddfSDavid du Colombier HEADR = 32L; 1497dd7cddfSDavid du Colombier if(INITTEXT == -1) 1507dd7cddfSDavid du Colombier INITTEXT = 4128; 1517dd7cddfSDavid du Colombier if(INITDAT == -1) 1527dd7cddfSDavid du Colombier INITDAT = 0; 1537dd7cddfSDavid du Colombier if(INITRND == -1) 1547dd7cddfSDavid du Colombier INITRND = 4096; 1557dd7cddfSDavid du Colombier break; 1567dd7cddfSDavid du Colombier case 3: /* raw */ 1577dd7cddfSDavid du Colombier HEADR = 0; 1587dd7cddfSDavid du Colombier if(INITTEXT == -1) 1597dd7cddfSDavid du Colombier INITTEXT = 4128; 1607dd7cddfSDavid du Colombier if(INITDAT == -1) { 1617dd7cddfSDavid du Colombier INITDAT = 0; 1627dd7cddfSDavid du Colombier INITRND = 4; 1637dd7cddfSDavid du Colombier } 1647dd7cddfSDavid du Colombier if(INITRND == -1) 1657dd7cddfSDavid du Colombier INITRND = 0; 1667dd7cddfSDavid du Colombier break; 1677dd7cddfSDavid du Colombier case 4: /* aix unix xcoff executable */ 1687dd7cddfSDavid du Colombier HEADR = 20L+72L+3*40L; 1697dd7cddfSDavid du Colombier if(INITTEXT == -1) 1707dd7cddfSDavid du Colombier INITTEXT = 0x1000000L+HEADR; 1717dd7cddfSDavid du Colombier if(INITDAT == -1) 1727dd7cddfSDavid du Colombier INITDAT = 0x20000000; 1737dd7cddfSDavid du Colombier if(INITRND == -1) 1747dd7cddfSDavid du Colombier INITRND = 0; 1757dd7cddfSDavid du Colombier break; 176dc5a79c1SDavid du Colombier case 5: /* elf executable */ 177dc5a79c1SDavid du Colombier HEADR = rnd(52L+3*32L, 16); 178dc5a79c1SDavid du Colombier if(INITTEXT == -1) 179dc5a79c1SDavid du Colombier INITTEXT = 0x00400000L+HEADR; 180dc5a79c1SDavid du Colombier if(INITDAT == -1) 181dc5a79c1SDavid du Colombier INITDAT = 0x10000000; 182dc5a79c1SDavid du Colombier if(INITRND == -1) 183dc5a79c1SDavid du Colombier INITRND = 0; 184dc5a79c1SDavid du Colombier break; 1857dd7cddfSDavid du Colombier } 1867dd7cddfSDavid du Colombier if(INITDAT != 0 && INITRND != 0) 1877dd7cddfSDavid du Colombier print("warning: -D0x%lux is ignored because of -R0x%lux\n", 1887dd7cddfSDavid du Colombier INITDAT, INITRND); 1897dd7cddfSDavid du Colombier if(debug['v']) 190375daca8SDavid du Colombier Bprint(&bso, "HEADER = -H0x%x -T0x%lux -D0x%lux -R0x%lux\n", 1917dd7cddfSDavid du Colombier HEADTYPE, INITTEXT, INITDAT, INITRND); 1927dd7cddfSDavid du Colombier Bflush(&bso); 1937dd7cddfSDavid du Colombier zprg.as = AGOK; 1947dd7cddfSDavid du Colombier zprg.reg = NREG; 1957dd7cddfSDavid du Colombier zprg.from.name = D_NONE; 1967dd7cddfSDavid du Colombier zprg.from.type = D_NONE; 1977dd7cddfSDavid du Colombier zprg.from.reg = NREG; 1987dd7cddfSDavid du Colombier zprg.from3 = zprg.from; 1997dd7cddfSDavid du Colombier zprg.to = zprg.from; 2007dd7cddfSDavid du Colombier buildop(); 2017dd7cddfSDavid du Colombier histgen = 0; 2027dd7cddfSDavid du Colombier textp = P; 2037dd7cddfSDavid du Colombier datap = P; 2047dd7cddfSDavid du Colombier pc = 0; 2057dd7cddfSDavid du Colombier dtype = 4; 2067dd7cddfSDavid du Colombier if(outfile == 0) 2077dd7cddfSDavid du Colombier outfile = "q.out"; 2087dd7cddfSDavid du Colombier cout = create(outfile, 1, 0775); 2097dd7cddfSDavid du Colombier if(cout < 0) { 2106b6b9ac8SDavid du Colombier diag("%s: cannot create", outfile); 2117dd7cddfSDavid du Colombier errorexit(); 2127dd7cddfSDavid du Colombier } 2137dd7cddfSDavid du Colombier nuxiinit(); 2147dd7cddfSDavid du Colombier version = 0; 2157dd7cddfSDavid du Colombier cbp = buf.cbuf; 2167dd7cddfSDavid du Colombier cbc = sizeof(buf.cbuf); 2177dd7cddfSDavid du Colombier firstp = prg(); 2187dd7cddfSDavid du Colombier lastp = firstp; 2197dd7cddfSDavid du Colombier 2207dd7cddfSDavid du Colombier if(INITENTRY == 0) { 2217dd7cddfSDavid du Colombier INITENTRY = "_main"; 2227dd7cddfSDavid du Colombier if(debug['p']) 2237dd7cddfSDavid du Colombier INITENTRY = "_mainp"; 2247dd7cddfSDavid du Colombier if(!debug['l']) 2257dd7cddfSDavid du Colombier lookup(INITENTRY, 0)->type = SXREF; 2267dd7cddfSDavid du Colombier } else 2277dd7cddfSDavid du Colombier lookup(INITENTRY, 0)->type = SXREF; 2287dd7cddfSDavid du Colombier 2297dd7cddfSDavid du Colombier while(*argv) 2307dd7cddfSDavid du Colombier objfile(*argv++); 2317dd7cddfSDavid du Colombier if(!debug['l']) 2327dd7cddfSDavid du Colombier loadlib(); 2337dd7cddfSDavid du Colombier firstp = firstp->link; 2347dd7cddfSDavid du Colombier if(firstp == P) 2357dd7cddfSDavid du Colombier goto out; 236375daca8SDavid du Colombier if(doexp || dlm){ 237375daca8SDavid du Colombier EXPTAB = "_exporttab"; 238375daca8SDavid du Colombier zerosig(EXPTAB); 239375daca8SDavid du Colombier zerosig("etext"); 240375daca8SDavid du Colombier zerosig("edata"); 241375daca8SDavid du Colombier zerosig("end"); 242375daca8SDavid du Colombier if(dlm){ 243375daca8SDavid du Colombier import(); 244375daca8SDavid du Colombier HEADTYPE = 2; 245375daca8SDavid du Colombier INITTEXT = INITDAT = 0; 246375daca8SDavid du Colombier INITRND = 8; 247375daca8SDavid du Colombier INITENTRY = EXPTAB; 248375daca8SDavid du Colombier } 249375daca8SDavid du Colombier export(); 250375daca8SDavid du Colombier } 2517dd7cddfSDavid du Colombier patch(); 2527dd7cddfSDavid du Colombier if(debug['p']) 2537dd7cddfSDavid du Colombier if(debug['1']) 2547dd7cddfSDavid du Colombier doprof1(); 2557dd7cddfSDavid du Colombier else 2567dd7cddfSDavid du Colombier doprof2(); 2577dd7cddfSDavid du Colombier dodata(); 2587dd7cddfSDavid du Colombier follow(); 2597dd7cddfSDavid du Colombier if(firstp == P) 2607dd7cddfSDavid du Colombier goto out; 2617dd7cddfSDavid du Colombier noops(); 2627dd7cddfSDavid du Colombier span(); 2637dd7cddfSDavid du Colombier asmb(); 2647dd7cddfSDavid du Colombier undef(); 2657dd7cddfSDavid du Colombier 2667dd7cddfSDavid du Colombier out: 2677dd7cddfSDavid du Colombier if(debug['v']) { 2687dd7cddfSDavid du Colombier Bprint(&bso, "%5.2f cpu time\n", cputime()); 2697dd7cddfSDavid du Colombier Bprint(&bso, "%ld memory used\n", tothunk); 2707dd7cddfSDavid du Colombier Bprint(&bso, "%d sizeof adr\n", sizeof(Adr)); 2717dd7cddfSDavid du Colombier Bprint(&bso, "%d sizeof prog\n", sizeof(Prog)); 2727dd7cddfSDavid du Colombier } 2737dd7cddfSDavid du Colombier errorexit(); 2747dd7cddfSDavid du Colombier } 2757dd7cddfSDavid du Colombier 2767dd7cddfSDavid du Colombier void 2777dd7cddfSDavid du Colombier loadlib(void) 2787dd7cddfSDavid du Colombier { 2797dd7cddfSDavid du Colombier int i; 2807dd7cddfSDavid du Colombier long h; 2817dd7cddfSDavid du Colombier Sym *s; 2827dd7cddfSDavid du Colombier 2837dd7cddfSDavid du Colombier loop: 2847dd7cddfSDavid du Colombier xrefresolv = 0; 2857dd7cddfSDavid du Colombier for(i=0; i<libraryp; i++) { 2867dd7cddfSDavid du Colombier if(debug['v']) 287375daca8SDavid du Colombier Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(), library[i], libraryobj[i]); 2887dd7cddfSDavid du Colombier objfile(library[i]); 2897dd7cddfSDavid du Colombier } 2907dd7cddfSDavid du Colombier if(xrefresolv) 2917dd7cddfSDavid du Colombier for(h=0; h<nelem(hash); h++) 2927dd7cddfSDavid du Colombier for(s = hash[h]; s != S; s = s->link) 2937dd7cddfSDavid du Colombier if(s->type == SXREF) 2947dd7cddfSDavid du Colombier goto loop; 2957dd7cddfSDavid du Colombier } 2967dd7cddfSDavid du Colombier 2977dd7cddfSDavid du Colombier void 2987dd7cddfSDavid du Colombier errorexit(void) 2997dd7cddfSDavid du Colombier { 3007dd7cddfSDavid du Colombier 3017dd7cddfSDavid du Colombier Bflush(&bso); 3027dd7cddfSDavid du Colombier if(nerrors) { 3037dd7cddfSDavid du Colombier if(cout >= 0) 3047dd7cddfSDavid du Colombier remove(outfile); 3057dd7cddfSDavid du Colombier exits("error"); 3067dd7cddfSDavid du Colombier } 3077dd7cddfSDavid du Colombier exits(0); 3087dd7cddfSDavid du Colombier } 3097dd7cddfSDavid du Colombier 3107dd7cddfSDavid du Colombier void 3117dd7cddfSDavid du Colombier objfile(char *file) 3127dd7cddfSDavid du Colombier { 3137dd7cddfSDavid du Colombier long off, esym, cnt, l; 3147dd7cddfSDavid du Colombier int f, work; 3157dd7cddfSDavid du Colombier Sym *s; 3167dd7cddfSDavid du Colombier char magbuf[SARMAG]; 3177dd7cddfSDavid du Colombier char name[100], pname[150]; 3187dd7cddfSDavid du Colombier struct ar_hdr arhdr; 3197dd7cddfSDavid du Colombier char *e, *start, *stop; 3207dd7cddfSDavid du Colombier 3217dd7cddfSDavid du Colombier if(file[0] == '-' && file[1] == 'l') { 3227dd7cddfSDavid du Colombier if(debug['9']) 3237dd7cddfSDavid du Colombier sprint(name, "/%s/lib/lib", thestring); 3247dd7cddfSDavid du Colombier else 3257dd7cddfSDavid du Colombier sprint(name, "/usr/%clib/lib", thechar); 3267dd7cddfSDavid du Colombier strcat(name, file+2); 3277dd7cddfSDavid du Colombier strcat(name, ".a"); 3287dd7cddfSDavid du Colombier file = name; 3297dd7cddfSDavid du Colombier } 3307dd7cddfSDavid du Colombier if(debug['v']) 3317dd7cddfSDavid du Colombier Bprint(&bso, "%5.2f ldobj: %s\n", cputime(), file); 3327dd7cddfSDavid du Colombier Bflush(&bso); 3337dd7cddfSDavid du Colombier f = open(file, 0); 3347dd7cddfSDavid du Colombier if(f < 0) { 3356b6b9ac8SDavid du Colombier diag("cannot open file: %s", file); 3367dd7cddfSDavid du Colombier errorexit(); 3377dd7cddfSDavid du Colombier } 3387dd7cddfSDavid du Colombier l = read(f, magbuf, SARMAG); 3397dd7cddfSDavid du Colombier if(l != SARMAG || strncmp(magbuf, ARMAG, SARMAG)){ 3407dd7cddfSDavid du Colombier /* load it as a regular file */ 3417dd7cddfSDavid du Colombier l = seek(f, 0L, 2); 3427dd7cddfSDavid du Colombier seek(f, 0L, 0); 3437dd7cddfSDavid du Colombier ldobj(f, l, file); 3447dd7cddfSDavid du Colombier close(f); 3457dd7cddfSDavid du Colombier return; 3467dd7cddfSDavid du Colombier } 3477dd7cddfSDavid du Colombier 3487dd7cddfSDavid du Colombier l = read(f, &arhdr, SAR_HDR); 3497dd7cddfSDavid du Colombier if(l != SAR_HDR) { 3506b6b9ac8SDavid du Colombier diag("%s: short read on archive file symbol header", file); 3517dd7cddfSDavid du Colombier goto out; 3527dd7cddfSDavid du Colombier } 3537dd7cddfSDavid du Colombier if(strncmp(arhdr.name, symname, strlen(symname))) { 3546b6b9ac8SDavid du Colombier diag("%s: first entry not symbol header", file); 3557dd7cddfSDavid du Colombier goto out; 3567dd7cddfSDavid du Colombier } 3577dd7cddfSDavid du Colombier 3587dd7cddfSDavid du Colombier esym = SARMAG + SAR_HDR + atolwhex(arhdr.size); 3597dd7cddfSDavid du Colombier off = SARMAG + SAR_HDR; 3607dd7cddfSDavid du Colombier 3617dd7cddfSDavid du Colombier /* 3627dd7cddfSDavid du Colombier * just bang the whole symbol file into memory 3637dd7cddfSDavid du Colombier */ 3647dd7cddfSDavid du Colombier seek(f, off, 0); 3657dd7cddfSDavid du Colombier cnt = esym - off; 3667dd7cddfSDavid du Colombier start = malloc(cnt + 10); 3677dd7cddfSDavid du Colombier cnt = read(f, start, cnt); 3687dd7cddfSDavid du Colombier if(cnt <= 0){ 3697dd7cddfSDavid du Colombier close(f); 3707dd7cddfSDavid du Colombier return; 3717dd7cddfSDavid du Colombier } 3727dd7cddfSDavid du Colombier stop = &start[cnt]; 3737dd7cddfSDavid du Colombier memset(stop, 0, 10); 3747dd7cddfSDavid du Colombier 3757dd7cddfSDavid du Colombier work = 1; 3767dd7cddfSDavid du Colombier while(work){ 3777dd7cddfSDavid du Colombier if(debug['v']) 3787dd7cddfSDavid du Colombier Bprint(&bso, "%5.2f library pass: %s\n", cputime(), file); 3797dd7cddfSDavid du Colombier Bflush(&bso); 3807dd7cddfSDavid du Colombier work = 0; 3817dd7cddfSDavid du Colombier for(e = start; e < stop; e = strchr(e+5, 0) + 1) { 3827dd7cddfSDavid du Colombier s = lookup(e+5, 0); 3837dd7cddfSDavid du Colombier if(s->type != SXREF) 3847dd7cddfSDavid du Colombier continue; 3857dd7cddfSDavid du Colombier sprint(pname, "%s(%s)", file, s->name); 3867dd7cddfSDavid du Colombier if(debug['v']) 3877dd7cddfSDavid du Colombier Bprint(&bso, "%5.2f library: %s\n", cputime(), pname); 3887dd7cddfSDavid du Colombier Bflush(&bso); 3897dd7cddfSDavid du Colombier l = e[1] & 0xff; 3907dd7cddfSDavid du Colombier l |= (e[2] & 0xff) << 8; 3917dd7cddfSDavid du Colombier l |= (e[3] & 0xff) << 16; 3927dd7cddfSDavid du Colombier l |= (e[4] & 0xff) << 24; 3937dd7cddfSDavid du Colombier seek(f, l, 0); 3947dd7cddfSDavid du Colombier l = read(f, &arhdr, SAR_HDR); 3957dd7cddfSDavid du Colombier if(l != SAR_HDR) 3967dd7cddfSDavid du Colombier goto bad; 3977dd7cddfSDavid du Colombier if(strncmp(arhdr.fmag, ARFMAG, sizeof(arhdr.fmag))) 3987dd7cddfSDavid du Colombier goto bad; 3997dd7cddfSDavid du Colombier l = atolwhex(arhdr.size); 4007dd7cddfSDavid du Colombier ldobj(f, l, pname); 4017dd7cddfSDavid du Colombier if(s->type == SXREF) { 4026b6b9ac8SDavid du Colombier diag("%s: failed to load: %s", file, s->name); 4037dd7cddfSDavid du Colombier errorexit(); 4047dd7cddfSDavid du Colombier } 4057dd7cddfSDavid du Colombier work = 1; 4067dd7cddfSDavid du Colombier xrefresolv = 1; 4077dd7cddfSDavid du Colombier } 4087dd7cddfSDavid du Colombier } 4097dd7cddfSDavid du Colombier return; 4107dd7cddfSDavid du Colombier 4117dd7cddfSDavid du Colombier bad: 4126b6b9ac8SDavid du Colombier diag("%s: bad or out of date archive", file); 4137dd7cddfSDavid du Colombier out: 4147dd7cddfSDavid du Colombier close(f); 4157dd7cddfSDavid du Colombier } 4167dd7cddfSDavid du Colombier 4177dd7cddfSDavid du Colombier int 4187dd7cddfSDavid du Colombier zaddr(uchar *p, Adr *a, Sym *h[]) 4197dd7cddfSDavid du Colombier { 4207dd7cddfSDavid du Colombier int i, c; 4217dd7cddfSDavid du Colombier long l; 4227dd7cddfSDavid du Colombier Sym *s; 4237dd7cddfSDavid du Colombier Auto *u; 4247dd7cddfSDavid du Colombier 4257dd7cddfSDavid du Colombier c = p[2]; 4267dd7cddfSDavid du Colombier if(c < 0 || c > NSYM){ 4277dd7cddfSDavid du Colombier print("sym out of range: %d\n", c); 4287dd7cddfSDavid du Colombier p[0] = AEND+1; 4297dd7cddfSDavid du Colombier return 0; 4307dd7cddfSDavid du Colombier } 4317dd7cddfSDavid du Colombier a->type = p[0]; 4327dd7cddfSDavid du Colombier a->reg = p[1]; 4337dd7cddfSDavid du Colombier a->sym = h[c]; 4347dd7cddfSDavid du Colombier a->name = p[3]; 4357dd7cddfSDavid du Colombier c = 4; 4367dd7cddfSDavid du Colombier 43722a127bbSDavid du Colombier if(a->reg > NREG) { 4387dd7cddfSDavid du Colombier print("register out of range %d\n", a->reg); 4397dd7cddfSDavid du Colombier p[0] = AEND+1; 4407dd7cddfSDavid du Colombier return 0; /* force real diagnostic */ 4417dd7cddfSDavid du Colombier } 4427dd7cddfSDavid du Colombier 4437dd7cddfSDavid du Colombier switch(a->type) { 4447dd7cddfSDavid du Colombier default: 4457dd7cddfSDavid du Colombier print("unknown type %d\n", a->type); 4467dd7cddfSDavid du Colombier p[0] = AEND+1; 4477dd7cddfSDavid du Colombier return 0; /* force real diagnostic */ 4487dd7cddfSDavid du Colombier 4497dd7cddfSDavid du Colombier case D_NONE: 4507dd7cddfSDavid du Colombier case D_REG: 4517dd7cddfSDavid du Colombier case D_FREG: 4527dd7cddfSDavid du Colombier case D_CREG: 4537dd7cddfSDavid du Colombier case D_FPSCR: 4547dd7cddfSDavid du Colombier case D_MSR: 4557dd7cddfSDavid du Colombier case D_SREG: 4567dd7cddfSDavid du Colombier case D_OPT: 4577dd7cddfSDavid du Colombier break; 4587dd7cddfSDavid du Colombier 4597dd7cddfSDavid du Colombier case D_SPR: 460375daca8SDavid du Colombier case D_DCR: 4617dd7cddfSDavid du Colombier case D_BRANCH: 4627dd7cddfSDavid du Colombier case D_OREG: 4637dd7cddfSDavid du Colombier case D_CONST: 4647dd7cddfSDavid du Colombier a->offset = p[4] | (p[5]<<8) | 4657dd7cddfSDavid du Colombier (p[6]<<16) | (p[7]<<24); 4667dd7cddfSDavid du Colombier c += 4; 4677dd7cddfSDavid du Colombier break; 4687dd7cddfSDavid du Colombier 4697dd7cddfSDavid du Colombier case D_SCONST: 4707dd7cddfSDavid du Colombier memmove(a->sval, p+4, NSNAME); 4717dd7cddfSDavid du Colombier c += NSNAME; 4727dd7cddfSDavid du Colombier break; 4737dd7cddfSDavid du Colombier 4747dd7cddfSDavid du Colombier case D_FCONST: 4757dd7cddfSDavid du Colombier a->ieee.l = p[4] | (p[5]<<8) | 4767dd7cddfSDavid du Colombier (p[6]<<16) | (p[7]<<24); 4777dd7cddfSDavid du Colombier a->ieee.h = p[8] | (p[9]<<8) | 4787dd7cddfSDavid du Colombier (p[10]<<16) | (p[11]<<24); 4797dd7cddfSDavid du Colombier c += 8; 4807dd7cddfSDavid du Colombier break; 4817dd7cddfSDavid du Colombier } 4827dd7cddfSDavid du Colombier s = a->sym; 4837dd7cddfSDavid du Colombier if(s == S) 4847dd7cddfSDavid du Colombier goto out; 4857dd7cddfSDavid du Colombier i = a->name; 4867dd7cddfSDavid du Colombier if(i != D_AUTO && i != D_PARAM) 4877dd7cddfSDavid du Colombier goto out; 4887dd7cddfSDavid du Colombier 4897dd7cddfSDavid du Colombier l = a->offset; 4907dd7cddfSDavid du Colombier for(u=curauto; u; u=u->link) 4917dd7cddfSDavid du Colombier if(u->sym == s) 4927dd7cddfSDavid du Colombier if(u->type == i) { 493375daca8SDavid du Colombier if(u->aoffset > l) 494375daca8SDavid du Colombier u->aoffset = l; 4957dd7cddfSDavid du Colombier goto out; 4967dd7cddfSDavid du Colombier } 4977dd7cddfSDavid du Colombier 4987dd7cddfSDavid du Colombier u = malloc(sizeof(Auto)); 4997dd7cddfSDavid du Colombier 5007dd7cddfSDavid du Colombier u->link = curauto; 5017dd7cddfSDavid du Colombier curauto = u; 5027dd7cddfSDavid du Colombier u->sym = s; 503375daca8SDavid du Colombier u->aoffset = l; 5047dd7cddfSDavid du Colombier u->type = i; 5057dd7cddfSDavid du Colombier out: 5067dd7cddfSDavid du Colombier return c; 5077dd7cddfSDavid du Colombier } 5087dd7cddfSDavid du Colombier 5097dd7cddfSDavid du Colombier void 51080ee5cbfSDavid du Colombier addlib(char *obj) 5117dd7cddfSDavid du Colombier { 5129a747e4fSDavid du Colombier char name[1024], comp[256], *p; 5137dd7cddfSDavid du Colombier int i; 5147dd7cddfSDavid du Colombier 5157dd7cddfSDavid du Colombier if(histfrogp <= 0) 5167dd7cddfSDavid du Colombier return; 5177dd7cddfSDavid du Colombier 5187dd7cddfSDavid du Colombier if(histfrog[0]->name[1] == '/') { 5197dd7cddfSDavid du Colombier sprint(name, ""); 5207dd7cddfSDavid du Colombier i = 1; 5217dd7cddfSDavid du Colombier } else 5227dd7cddfSDavid du Colombier if(histfrog[0]->name[1] == '.') { 5237dd7cddfSDavid du Colombier sprint(name, "."); 5247dd7cddfSDavid du Colombier i = 0; 5257dd7cddfSDavid du Colombier } else { 5267dd7cddfSDavid du Colombier if(debug['9']) 5277dd7cddfSDavid du Colombier sprint(name, "/%s/lib", thestring); 5287dd7cddfSDavid du Colombier else 5297dd7cddfSDavid du Colombier sprint(name, "/usr/%clib", thechar); 5307dd7cddfSDavid du Colombier i = 0; 5317dd7cddfSDavid du Colombier } 5327dd7cddfSDavid du Colombier 5337dd7cddfSDavid du Colombier for(; i<histfrogp; i++) { 5349a747e4fSDavid du Colombier snprint(comp, sizeof comp, histfrog[i]->name+1); 5357dd7cddfSDavid du Colombier for(;;) { 5367dd7cddfSDavid du Colombier p = strstr(comp, "$O"); 5377dd7cddfSDavid du Colombier if(p == 0) 5387dd7cddfSDavid du Colombier break; 5397dd7cddfSDavid du Colombier memmove(p+1, p+2, strlen(p+2)+1); 5407dd7cddfSDavid du Colombier p[0] = thechar; 5417dd7cddfSDavid du Colombier } 5427dd7cddfSDavid du Colombier for(;;) { 5437dd7cddfSDavid du Colombier p = strstr(comp, "$M"); 5447dd7cddfSDavid du Colombier if(p == 0) 5457dd7cddfSDavid du Colombier break; 5469a747e4fSDavid du Colombier if(strlen(comp)+strlen(thestring)-2+1 >= sizeof comp) { 5477dd7cddfSDavid du Colombier diag("library component too long"); 5487dd7cddfSDavid du Colombier return; 5497dd7cddfSDavid du Colombier } 5509a747e4fSDavid du Colombier memmove(p+strlen(thestring), p+2, strlen(p+2)+1); 5519a747e4fSDavid du Colombier memmove(p, thestring, strlen(thestring)); 5527dd7cddfSDavid du Colombier } 5539a747e4fSDavid du Colombier if(strlen(name) + strlen(comp) + 3 >= sizeof(name)) { 5547dd7cddfSDavid du Colombier diag("library component too long"); 5557dd7cddfSDavid du Colombier return; 5567dd7cddfSDavid du Colombier } 5577dd7cddfSDavid du Colombier strcat(name, "/"); 5587dd7cddfSDavid du Colombier strcat(name, comp); 5597dd7cddfSDavid du Colombier } 5607dd7cddfSDavid du Colombier for(i=0; i<libraryp; i++) 5617dd7cddfSDavid du Colombier if(strcmp(name, library[i]) == 0) 5627dd7cddfSDavid du Colombier return; 56380ee5cbfSDavid du Colombier if(libraryp == nelem(library)){ 56480ee5cbfSDavid du Colombier diag("too many autolibs; skipping %s", name); 56580ee5cbfSDavid du Colombier return; 56680ee5cbfSDavid du Colombier } 5677dd7cddfSDavid du Colombier 5687dd7cddfSDavid du Colombier p = malloc(strlen(name) + 1); 5697dd7cddfSDavid du Colombier strcpy(p, name); 5707dd7cddfSDavid du Colombier library[libraryp] = p; 57180ee5cbfSDavid du Colombier p = malloc(strlen(obj) + 1); 57280ee5cbfSDavid du Colombier strcpy(p, obj); 57380ee5cbfSDavid du Colombier libraryobj[libraryp] = p; 5747dd7cddfSDavid du Colombier libraryp++; 5757dd7cddfSDavid du Colombier } 5767dd7cddfSDavid du Colombier 5777dd7cddfSDavid du Colombier void 5787dd7cddfSDavid du Colombier addhist(long line, int type) 5797dd7cddfSDavid du Colombier { 5807dd7cddfSDavid du Colombier Auto *u; 5817dd7cddfSDavid du Colombier Sym *s; 5827dd7cddfSDavid du Colombier int i, j, k; 5837dd7cddfSDavid du Colombier 5847dd7cddfSDavid du Colombier u = malloc(sizeof(Auto)); 5857dd7cddfSDavid du Colombier s = malloc(sizeof(Sym)); 5867dd7cddfSDavid du Colombier s->name = malloc(2*(histfrogp+1) + 1); 5877dd7cddfSDavid du Colombier 5887dd7cddfSDavid du Colombier u->sym = s; 5897dd7cddfSDavid du Colombier u->type = type; 590375daca8SDavid du Colombier u->aoffset = line; 5917dd7cddfSDavid du Colombier u->link = curhist; 5927dd7cddfSDavid du Colombier curhist = u; 5937dd7cddfSDavid du Colombier 5947dd7cddfSDavid du Colombier j = 1; 5957dd7cddfSDavid du Colombier for(i=0; i<histfrogp; i++) { 5967dd7cddfSDavid du Colombier k = histfrog[i]->value; 5977dd7cddfSDavid du Colombier s->name[j+0] = k>>8; 5987dd7cddfSDavid du Colombier s->name[j+1] = k; 5997dd7cddfSDavid du Colombier j += 2; 6007dd7cddfSDavid du Colombier } 6017dd7cddfSDavid du Colombier } 6027dd7cddfSDavid du Colombier 6037dd7cddfSDavid du Colombier void 6047dd7cddfSDavid du Colombier histtoauto(void) 6057dd7cddfSDavid du Colombier { 6067dd7cddfSDavid du Colombier Auto *l; 6077dd7cddfSDavid du Colombier 6087dd7cddfSDavid du Colombier while(l = curhist) { 6097dd7cddfSDavid du Colombier curhist = l->link; 6107dd7cddfSDavid du Colombier l->link = curauto; 6117dd7cddfSDavid du Colombier curauto = l; 6127dd7cddfSDavid du Colombier } 6137dd7cddfSDavid du Colombier } 6147dd7cddfSDavid du Colombier 6157dd7cddfSDavid du Colombier void 6167dd7cddfSDavid du Colombier collapsefrog(Sym *s) 6177dd7cddfSDavid du Colombier { 6187dd7cddfSDavid du Colombier int i; 6197dd7cddfSDavid du Colombier 6207dd7cddfSDavid du Colombier /* 6217dd7cddfSDavid du Colombier * bad encoding of path components only allows 6227dd7cddfSDavid du Colombier * MAXHIST components. if there is an overflow, 6237dd7cddfSDavid du Colombier * first try to collapse xxx/.. 6247dd7cddfSDavid du Colombier */ 6257dd7cddfSDavid du Colombier for(i=1; i<histfrogp; i++) 6267dd7cddfSDavid du Colombier if(strcmp(histfrog[i]->name+1, "..") == 0) { 6277dd7cddfSDavid du Colombier memmove(histfrog+i-1, histfrog+i+1, 6287dd7cddfSDavid du Colombier (histfrogp-i-1)*sizeof(histfrog[0])); 6297dd7cddfSDavid du Colombier histfrogp--; 6307dd7cddfSDavid du Colombier goto out; 6317dd7cddfSDavid du Colombier } 6327dd7cddfSDavid du Colombier 6337dd7cddfSDavid du Colombier /* 6347dd7cddfSDavid du Colombier * next try to collapse . 6357dd7cddfSDavid du Colombier */ 6367dd7cddfSDavid du Colombier for(i=0; i<histfrogp; i++) 6377dd7cddfSDavid du Colombier if(strcmp(histfrog[i]->name+1, ".") == 0) { 6387dd7cddfSDavid du Colombier memmove(histfrog+i, histfrog+i+1, 6397dd7cddfSDavid du Colombier (histfrogp-i-1)*sizeof(histfrog[0])); 6407dd7cddfSDavid du Colombier goto out; 6417dd7cddfSDavid du Colombier } 6427dd7cddfSDavid du Colombier 6437dd7cddfSDavid du Colombier /* 6447dd7cddfSDavid du Colombier * last chance, just truncate from front 6457dd7cddfSDavid du Colombier */ 6467dd7cddfSDavid du Colombier memmove(histfrog+0, histfrog+1, 6477dd7cddfSDavid du Colombier (histfrogp-1)*sizeof(histfrog[0])); 6487dd7cddfSDavid du Colombier 6497dd7cddfSDavid du Colombier out: 6507dd7cddfSDavid du Colombier histfrog[histfrogp-1] = s; 6517dd7cddfSDavid du Colombier } 6527dd7cddfSDavid du Colombier 6537dd7cddfSDavid du Colombier void 6547dd7cddfSDavid du Colombier nopout(Prog *p) 6557dd7cddfSDavid du Colombier { 6567dd7cddfSDavid du Colombier p->as = ANOP; 6577dd7cddfSDavid du Colombier p->from.type = D_NONE; 6587dd7cddfSDavid du Colombier p->to.type = D_NONE; 6597dd7cddfSDavid du Colombier } 6607dd7cddfSDavid du Colombier 6617dd7cddfSDavid du Colombier uchar* 6627dd7cddfSDavid du Colombier readsome(int f, uchar *buf, uchar *good, uchar *stop, int max) 6637dd7cddfSDavid du Colombier { 6647dd7cddfSDavid du Colombier int n; 6657dd7cddfSDavid du Colombier 6667dd7cddfSDavid du Colombier n = stop - good; 6677dd7cddfSDavid du Colombier memmove(buf, good, stop - good); 6687dd7cddfSDavid du Colombier stop = buf + n; 6697dd7cddfSDavid du Colombier n = MAXIO - n; 6707dd7cddfSDavid du Colombier if(n > max) 6717dd7cddfSDavid du Colombier n = max; 6727dd7cddfSDavid du Colombier n = read(f, stop, n); 6737dd7cddfSDavid du Colombier if(n <= 0) 6747dd7cddfSDavid du Colombier return 0; 6757dd7cddfSDavid du Colombier return stop + n; 6767dd7cddfSDavid du Colombier } 6777dd7cddfSDavid du Colombier 6787dd7cddfSDavid du Colombier void 6797dd7cddfSDavid du Colombier ldobj(int f, long c, char *pn) 6807dd7cddfSDavid du Colombier { 6817dd7cddfSDavid du Colombier Prog *p, *t; 6827dd7cddfSDavid du Colombier Sym *h[NSYM], *s, *di; 6837dd7cddfSDavid du Colombier int v, o, r, skip; 6847dd7cddfSDavid du Colombier long ipc; 6857dd7cddfSDavid du Colombier uchar *bloc, *bsize, *stop; 686375daca8SDavid du Colombier ulong sig; 687375daca8SDavid du Colombier static int files; 688375daca8SDavid du Colombier static char **filen; 689375daca8SDavid du Colombier char **nfilen; 690375daca8SDavid du Colombier 691375daca8SDavid du Colombier if((files&15) == 0){ 692375daca8SDavid du Colombier nfilen = malloc((files+16)*sizeof(char*)); 693375daca8SDavid du Colombier memmove(nfilen, filen, files*sizeof(char*)); 694375daca8SDavid du Colombier free(filen); 695375daca8SDavid du Colombier filen = nfilen; 696375daca8SDavid du Colombier } 697375daca8SDavid du Colombier filen[files++] = strdup(pn); 6987dd7cddfSDavid du Colombier 6997dd7cddfSDavid du Colombier bsize = buf.xbuf; 7007dd7cddfSDavid du Colombier bloc = buf.xbuf; 7017dd7cddfSDavid du Colombier di = S; 7027dd7cddfSDavid du Colombier 7037dd7cddfSDavid du Colombier newloop: 7047dd7cddfSDavid du Colombier memset(h, 0, sizeof(h)); 7057dd7cddfSDavid du Colombier histfrogp = 0; 7067dd7cddfSDavid du Colombier version++; 7077dd7cddfSDavid du Colombier ipc = pc; 7087dd7cddfSDavid du Colombier skip = 0; 7097dd7cddfSDavid du Colombier 7107dd7cddfSDavid du Colombier loop: 7117dd7cddfSDavid du Colombier if(c <= 0) 7127dd7cddfSDavid du Colombier goto eof; 7137dd7cddfSDavid du Colombier r = bsize - bloc; 7147dd7cddfSDavid du Colombier if(r < 100 && r < c) { /* enough for largest prog */ 7157dd7cddfSDavid du Colombier bsize = readsome(f, buf.xbuf, bloc, bsize, c); 7167dd7cddfSDavid du Colombier if(bsize == 0) 7177dd7cddfSDavid du Colombier goto eof; 7187dd7cddfSDavid du Colombier bloc = buf.xbuf; 7197dd7cddfSDavid du Colombier goto loop; 7207dd7cddfSDavid du Colombier } 7217dd7cddfSDavid du Colombier o = bloc[0]; /* as */ 7227dd7cddfSDavid du Colombier if(o <= 0 || o >= ALAST) { 7236b6b9ac8SDavid du Colombier diag("%s: opcode out of range %d", pn, o); 7247dd7cddfSDavid du Colombier print(" probably not a .q file\n"); 7257dd7cddfSDavid du Colombier errorexit(); 7267dd7cddfSDavid du Colombier } 727375daca8SDavid du Colombier if(o == ANAME || o == ASIGNAME) { 728375daca8SDavid du Colombier sig = 0; 729375daca8SDavid du Colombier if(o == ASIGNAME) { 730375daca8SDavid du Colombier sig = bloc[1] | (bloc[2]<<8) | (bloc[3]<<16) | (bloc[4]<<24); 731375daca8SDavid du Colombier bloc += 4; 732375daca8SDavid du Colombier c -= 4; 733375daca8SDavid du Colombier } 7347dd7cddfSDavid du Colombier stop = memchr(&bloc[3], 0, bsize-&bloc[3]); 7357dd7cddfSDavid du Colombier if(stop == 0){ 7367dd7cddfSDavid du Colombier bsize = readsome(f, buf.xbuf, bloc, bsize, c); 7377dd7cddfSDavid du Colombier if(bsize == 0) 7387dd7cddfSDavid du Colombier goto eof; 7397dd7cddfSDavid du Colombier bloc = buf.xbuf; 7407dd7cddfSDavid du Colombier stop = memchr(&bloc[3], 0, bsize-&bloc[3]); 7417dd7cddfSDavid du Colombier if(stop == 0){ 7427dd7cddfSDavid du Colombier fprint(2, "%s: name too long\n", pn); 7437dd7cddfSDavid du Colombier errorexit(); 7447dd7cddfSDavid du Colombier } 7457dd7cddfSDavid du Colombier } 7467dd7cddfSDavid du Colombier v = bloc[1]; /* type */ 7477dd7cddfSDavid du Colombier o = bloc[2]; /* sym */ 7487dd7cddfSDavid du Colombier bloc += 3; 7497dd7cddfSDavid du Colombier c -= 3; 7507dd7cddfSDavid du Colombier 7517dd7cddfSDavid du Colombier r = 0; 7527dd7cddfSDavid du Colombier if(v == D_STATIC) 7537dd7cddfSDavid du Colombier r = version; 7547dd7cddfSDavid du Colombier s = lookup((char*)bloc, r); 7557dd7cddfSDavid du Colombier c -= &stop[1] - bloc; 7567dd7cddfSDavid du Colombier bloc = stop + 1; 757375daca8SDavid du Colombier if(sig != 0){ 758375daca8SDavid du Colombier if(s->sig != 0 && s->sig != sig) 759375daca8SDavid du Colombier diag("incompatible type signatures %lux(%s) and %lux(%s) for %s", s->sig, filen[s->file], sig, pn, s->name); 760375daca8SDavid du Colombier s->sig = sig; 761375daca8SDavid du Colombier s->file = files-1; 762375daca8SDavid du Colombier } 763375daca8SDavid du Colombier 7647dd7cddfSDavid du Colombier 7657dd7cddfSDavid du Colombier if(debug['W']) 7667dd7cddfSDavid du Colombier print(" ANAME %s\n", s->name); 7677dd7cddfSDavid du Colombier h[o] = s; 7687dd7cddfSDavid du Colombier if((v == D_EXTERN || v == D_STATIC) && s->type == 0) 7697dd7cddfSDavid du Colombier s->type = SXREF; 7707dd7cddfSDavid du Colombier if(v == D_FILE) { 7717dd7cddfSDavid du Colombier if(s->type != SFILE) { 7727dd7cddfSDavid du Colombier histgen++; 7737dd7cddfSDavid du Colombier s->type = SFILE; 7747dd7cddfSDavid du Colombier s->value = histgen; 7757dd7cddfSDavid du Colombier } 7767dd7cddfSDavid du Colombier if(histfrogp < MAXHIST) { 7777dd7cddfSDavid du Colombier histfrog[histfrogp] = s; 7787dd7cddfSDavid du Colombier histfrogp++; 7797dd7cddfSDavid du Colombier } else 7807dd7cddfSDavid du Colombier collapsefrog(s); 7817dd7cddfSDavid du Colombier } 7827dd7cddfSDavid du Colombier goto loop; 7837dd7cddfSDavid du Colombier } 7847dd7cddfSDavid du Colombier 7857dd7cddfSDavid du Colombier if(nhunk < sizeof(Prog)) 7867dd7cddfSDavid du Colombier gethunk(); 7877dd7cddfSDavid du Colombier p = (Prog*)hunk; 7887dd7cddfSDavid du Colombier nhunk -= sizeof(Prog); 7897dd7cddfSDavid du Colombier hunk += sizeof(Prog); 7907dd7cddfSDavid du Colombier 7917dd7cddfSDavid du Colombier p->as = o; 7927dd7cddfSDavid du Colombier p->reg = bloc[1] & 0x3f; 7937dd7cddfSDavid du Colombier if(bloc[1] & 0x80) 7947dd7cddfSDavid du Colombier p->mark = NOSCHED; 7957dd7cddfSDavid du Colombier p->line = bloc[2] | (bloc[3]<<8) | (bloc[4]<<16) | (bloc[5]<<24); 7967dd7cddfSDavid du Colombier r = zaddr(bloc+6, &p->from, h) + 6; 7977dd7cddfSDavid du Colombier if(bloc[1] & 0x40) 7987dd7cddfSDavid du Colombier r += zaddr(bloc+r, &p->from3, h); 7997dd7cddfSDavid du Colombier else 8007dd7cddfSDavid du Colombier p->from3 = zprg.from3; 8017dd7cddfSDavid du Colombier r += zaddr(bloc+r, &p->to, h); 8027dd7cddfSDavid du Colombier bloc += r; 8037dd7cddfSDavid du Colombier c -= r; 8047dd7cddfSDavid du Colombier 8057dd7cddfSDavid du Colombier if(p->reg < 0 || p->reg > NREG) 8066b6b9ac8SDavid du Colombier diag("register out of range %d", p->reg); 8077dd7cddfSDavid du Colombier 8087dd7cddfSDavid du Colombier p->link = P; 8097dd7cddfSDavid du Colombier p->cond = P; 8107dd7cddfSDavid du Colombier 8117dd7cddfSDavid du Colombier if(debug['W']) 8127dd7cddfSDavid du Colombier print("%P\n", p); 8137dd7cddfSDavid du Colombier 8147dd7cddfSDavid du Colombier switch(o) { 8157dd7cddfSDavid du Colombier case AHISTORY: 8167dd7cddfSDavid du Colombier if(p->to.offset == -1) { 81780ee5cbfSDavid du Colombier addlib(pn); 8187dd7cddfSDavid du Colombier histfrogp = 0; 8197dd7cddfSDavid du Colombier goto loop; 8207dd7cddfSDavid du Colombier } 8217dd7cddfSDavid du Colombier addhist(p->line, D_FILE); /* 'z' */ 8227dd7cddfSDavid du Colombier if(p->to.offset) 8237dd7cddfSDavid du Colombier addhist(p->to.offset, D_FILE1); /* 'Z' */ 8247dd7cddfSDavid du Colombier histfrogp = 0; 8257dd7cddfSDavid du Colombier goto loop; 8267dd7cddfSDavid du Colombier 8277dd7cddfSDavid du Colombier case AEND: 8287dd7cddfSDavid du Colombier histtoauto(); 8297dd7cddfSDavid du Colombier if(curtext != P) 8307dd7cddfSDavid du Colombier curtext->to.autom = curauto; 8317dd7cddfSDavid du Colombier curauto = 0; 8327dd7cddfSDavid du Colombier curtext = P; 8337dd7cddfSDavid du Colombier if(c) 8347dd7cddfSDavid du Colombier goto newloop; 8357dd7cddfSDavid du Colombier return; 8367dd7cddfSDavid du Colombier 8377dd7cddfSDavid du Colombier case AGLOBL: 8387dd7cddfSDavid du Colombier s = p->from.sym; 8397dd7cddfSDavid du Colombier if(s == S) { 8406b6b9ac8SDavid du Colombier diag("GLOBL must have a name\n%P", p); 8417dd7cddfSDavid du Colombier errorexit(); 8427dd7cddfSDavid du Colombier } 8437dd7cddfSDavid du Colombier if(s->type == 0 || s->type == SXREF) { 8447dd7cddfSDavid du Colombier s->type = SBSS; 8457dd7cddfSDavid du Colombier s->value = 0; 8467dd7cddfSDavid du Colombier } 8477dd7cddfSDavid du Colombier if(s->type != SBSS) { 8486b6b9ac8SDavid du Colombier diag("redefinition: %s\n%P", s->name, p); 8497dd7cddfSDavid du Colombier s->type = SBSS; 8507dd7cddfSDavid du Colombier s->value = 0; 8517dd7cddfSDavid du Colombier } 8527dd7cddfSDavid du Colombier if(p->to.offset > s->value) 8537dd7cddfSDavid du Colombier s->value = p->to.offset; 8547dd7cddfSDavid du Colombier break; 8557dd7cddfSDavid du Colombier 8567dd7cddfSDavid du Colombier case ADYNT: 8577dd7cddfSDavid du Colombier if(p->to.sym == S) { 8586b6b9ac8SDavid du Colombier diag("DYNT without a sym\n%P", p); 8597dd7cddfSDavid du Colombier break; 8607dd7cddfSDavid du Colombier } 8617dd7cddfSDavid du Colombier di = p->to.sym; 8627dd7cddfSDavid du Colombier p->reg = 4; 8637dd7cddfSDavid du Colombier if(di->type == SXREF) { 8647dd7cddfSDavid du Colombier if(debug['z']) 8657dd7cddfSDavid du Colombier Bprint(&bso, "%P set to %d\n", p, dtype); 8667dd7cddfSDavid du Colombier di->type = SCONST; 8677dd7cddfSDavid du Colombier di->value = dtype; 8687dd7cddfSDavid du Colombier dtype += 4; 8697dd7cddfSDavid du Colombier } 8707dd7cddfSDavid du Colombier if(p->from.sym == S) 8717dd7cddfSDavid du Colombier break; 8727dd7cddfSDavid du Colombier 8737dd7cddfSDavid du Colombier p->from.offset = di->value; 8747dd7cddfSDavid du Colombier p->from.sym->type = SDATA; 8757dd7cddfSDavid du Colombier if(curtext == P) { 8766b6b9ac8SDavid du Colombier diag("DYNT not in text: %P", p); 8777dd7cddfSDavid du Colombier break; 8787dd7cddfSDavid du Colombier } 8797dd7cddfSDavid du Colombier p->to.sym = curtext->from.sym; 8807dd7cddfSDavid du Colombier p->to.type = D_CONST; 8817dd7cddfSDavid du Colombier p->link = datap; 8827dd7cddfSDavid du Colombier datap = p; 8837dd7cddfSDavid du Colombier break; 8847dd7cddfSDavid du Colombier 8857dd7cddfSDavid du Colombier case AINIT: 8867dd7cddfSDavid du Colombier if(p->from.sym == S) { 8876b6b9ac8SDavid du Colombier diag("INIT without a sym\n%P", p); 8887dd7cddfSDavid du Colombier break; 8897dd7cddfSDavid du Colombier } 8907dd7cddfSDavid du Colombier if(di == S) { 8916b6b9ac8SDavid du Colombier diag("INIT without previous DYNT\n%P", p); 8927dd7cddfSDavid du Colombier break; 8937dd7cddfSDavid du Colombier } 8947dd7cddfSDavid du Colombier p->from.offset = di->value; 8957dd7cddfSDavid du Colombier p->from.sym->type = SDATA; 8967dd7cddfSDavid du Colombier p->link = datap; 8977dd7cddfSDavid du Colombier datap = p; 8987dd7cddfSDavid du Colombier break; 8997dd7cddfSDavid du Colombier 9007dd7cddfSDavid du Colombier case ADATA: 9017dd7cddfSDavid du Colombier p->link = datap; 9027dd7cddfSDavid du Colombier datap = p; 9037dd7cddfSDavid du Colombier break; 9047dd7cddfSDavid du Colombier 9057dd7cddfSDavid du Colombier case AGOK: 9066b6b9ac8SDavid du Colombier diag("unknown opcode\n%P", p); 9077dd7cddfSDavid du Colombier p->pc = pc; 9087dd7cddfSDavid du Colombier pc++; 9097dd7cddfSDavid du Colombier break; 9107dd7cddfSDavid du Colombier 9117dd7cddfSDavid du Colombier case ATEXT: 9127dd7cddfSDavid du Colombier if(curtext != P) { 9137dd7cddfSDavid du Colombier histtoauto(); 9147dd7cddfSDavid du Colombier curtext->to.autom = curauto; 9157dd7cddfSDavid du Colombier curauto = 0; 9167dd7cddfSDavid du Colombier } 9177dd7cddfSDavid du Colombier curtext = p; 9187dd7cddfSDavid du Colombier autosize = (p->to.offset+3L) & ~3L; 9197dd7cddfSDavid du Colombier p->to.offset = autosize; 9207dd7cddfSDavid du Colombier autosize += 4; 9217dd7cddfSDavid du Colombier s = p->from.sym; 9227dd7cddfSDavid du Colombier if(s == S) { 9236b6b9ac8SDavid du Colombier diag("TEXT must have a name\n%P", p); 9247dd7cddfSDavid du Colombier errorexit(); 9257dd7cddfSDavid du Colombier } 9267dd7cddfSDavid du Colombier if(s->type != 0 && s->type != SXREF) { 9277dd7cddfSDavid du Colombier if(p->reg & DUPOK) { 9287dd7cddfSDavid du Colombier skip = 1; 9297dd7cddfSDavid du Colombier goto casedef; 9307dd7cddfSDavid du Colombier } 9316b6b9ac8SDavid du Colombier diag("redefinition: %s\n%P", s->name, p); 9327dd7cddfSDavid du Colombier } 9337dd7cddfSDavid du Colombier s->type = STEXT; 9347dd7cddfSDavid du Colombier s->value = pc; 9357dd7cddfSDavid du Colombier if(textp != P) { 9367dd7cddfSDavid du Colombier for(t = textp; t->cond != P; t = t->cond) 9377dd7cddfSDavid du Colombier ; 9387dd7cddfSDavid du Colombier t->cond = p; 9397dd7cddfSDavid du Colombier } else 9407dd7cddfSDavid du Colombier textp = p; 9417dd7cddfSDavid du Colombier lastp->link = p; 9427dd7cddfSDavid du Colombier lastp = p; 9437dd7cddfSDavid du Colombier p->pc = pc; 9447dd7cddfSDavid du Colombier pc++; 9457dd7cddfSDavid du Colombier break; 9467dd7cddfSDavid du Colombier 9477dd7cddfSDavid du Colombier case AFMOVS: 9487dd7cddfSDavid du Colombier if(skip) 9497dd7cddfSDavid du Colombier goto casedef; 9507dd7cddfSDavid du Colombier 9517dd7cddfSDavid du Colombier if(p->from.type == D_FCONST) { 9527dd7cddfSDavid du Colombier /* size sb 9 max */ 9537dd7cddfSDavid du Colombier sprint(literal, "$%lux", ieeedtof(&p->from.ieee)); 9547dd7cddfSDavid du Colombier s = lookup(literal, 0); 9557dd7cddfSDavid du Colombier if(s->type == 0) { 9567dd7cddfSDavid du Colombier s->type = SBSS; 9577dd7cddfSDavid du Colombier s->value = 4; 9587dd7cddfSDavid du Colombier t = prg(); 9597dd7cddfSDavid du Colombier t->as = ADATA; 9607dd7cddfSDavid du Colombier t->line = p->line; 9617dd7cddfSDavid du Colombier t->from.type = D_OREG; 9627dd7cddfSDavid du Colombier t->from.sym = s; 9637dd7cddfSDavid du Colombier t->from.name = D_EXTERN; 9647dd7cddfSDavid du Colombier t->reg = 4; 9657dd7cddfSDavid du Colombier t->to = p->from; 9667dd7cddfSDavid du Colombier t->link = datap; 9677dd7cddfSDavid du Colombier datap = t; 9687dd7cddfSDavid du Colombier } 9697dd7cddfSDavid du Colombier p->from.type = D_OREG; 9707dd7cddfSDavid du Colombier p->from.sym = s; 9717dd7cddfSDavid du Colombier p->from.name = D_EXTERN; 9727dd7cddfSDavid du Colombier p->from.offset = 0; 9737dd7cddfSDavid du Colombier } 9747dd7cddfSDavid du Colombier goto casedef; 9757dd7cddfSDavid du Colombier 9767dd7cddfSDavid du Colombier case AFMOVD: 9777dd7cddfSDavid du Colombier if(skip) 9787dd7cddfSDavid du Colombier goto casedef; 9797dd7cddfSDavid du Colombier if(p->from.type == D_FCONST) { 9807dd7cddfSDavid du Colombier /* size sb 18 max */ 9817dd7cddfSDavid du Colombier sprint(literal, "$%lux.%lux", 9827dd7cddfSDavid du Colombier p->from.ieee.l, p->from.ieee.h); 9837dd7cddfSDavid du Colombier s = lookup(literal, 0); 9847dd7cddfSDavid du Colombier if(s->type == 0) { 9857dd7cddfSDavid du Colombier s->type = SBSS; 9867dd7cddfSDavid du Colombier s->value = 8; 9877dd7cddfSDavid du Colombier t = prg(); 9887dd7cddfSDavid du Colombier t->as = ADATA; 9897dd7cddfSDavid du Colombier t->line = p->line; 9907dd7cddfSDavid du Colombier t->from.type = D_OREG; 9917dd7cddfSDavid du Colombier t->from.sym = s; 9927dd7cddfSDavid du Colombier t->from.name = D_EXTERN; 9937dd7cddfSDavid du Colombier t->reg = 8; 9947dd7cddfSDavid du Colombier t->to = p->from; 9957dd7cddfSDavid du Colombier t->link = datap; 9967dd7cddfSDavid du Colombier datap = t; 9977dd7cddfSDavid du Colombier } 9987dd7cddfSDavid du Colombier p->from.type = D_OREG; 9997dd7cddfSDavid du Colombier p->from.sym = s; 10007dd7cddfSDavid du Colombier p->from.name = D_EXTERN; 10017dd7cddfSDavid du Colombier p->from.offset = 0; 10027dd7cddfSDavid du Colombier } 10037dd7cddfSDavid du Colombier goto casedef; 10047dd7cddfSDavid du Colombier 10057dd7cddfSDavid du Colombier case ASUBC: 10067dd7cddfSDavid du Colombier if(p->from.type == D_CONST) { 10077dd7cddfSDavid du Colombier p->from.offset = -p->from.offset; 10087dd7cddfSDavid du Colombier p->as = AADDC; 10097dd7cddfSDavid du Colombier } 10107dd7cddfSDavid du Colombier goto casedef; 10117dd7cddfSDavid du Colombier 10127dd7cddfSDavid du Colombier case ASUBCCC: 10137dd7cddfSDavid du Colombier if(p->from.type == D_CONST) { 10147dd7cddfSDavid du Colombier p->from.offset = -p->from.offset; 10157dd7cddfSDavid du Colombier p->as = AADDCCC; 10167dd7cddfSDavid du Colombier } 10177dd7cddfSDavid du Colombier goto casedef; 10187dd7cddfSDavid du Colombier 10197dd7cddfSDavid du Colombier case ASUB: 10207dd7cddfSDavid du Colombier if(p->from.type == D_CONST) { 10217dd7cddfSDavid du Colombier p->from.offset = -p->from.offset; 10227dd7cddfSDavid du Colombier p->as = AADD; 10237dd7cddfSDavid du Colombier } 10247dd7cddfSDavid du Colombier goto casedef; 10257dd7cddfSDavid du Colombier 10267dd7cddfSDavid du Colombier default: 10277dd7cddfSDavid du Colombier casedef: 10287dd7cddfSDavid du Colombier if(skip) 10297dd7cddfSDavid du Colombier nopout(p); 10307dd7cddfSDavid du Colombier 10317dd7cddfSDavid du Colombier if(p->to.type == D_BRANCH) 10327dd7cddfSDavid du Colombier p->to.offset += ipc; 10337dd7cddfSDavid du Colombier lastp->link = p; 10347dd7cddfSDavid du Colombier lastp = p; 10357dd7cddfSDavid du Colombier p->pc = pc; 10367dd7cddfSDavid du Colombier pc++; 10377dd7cddfSDavid du Colombier break; 10387dd7cddfSDavid du Colombier } 10397dd7cddfSDavid du Colombier goto loop; 10407dd7cddfSDavid du Colombier 10417dd7cddfSDavid du Colombier eof: 10426b6b9ac8SDavid du Colombier diag("truncated object file: %s", pn); 10437dd7cddfSDavid du Colombier } 10447dd7cddfSDavid du Colombier 10457dd7cddfSDavid du Colombier Sym* 10467dd7cddfSDavid du Colombier lookup(char *symb, int v) 10477dd7cddfSDavid du Colombier { 10487dd7cddfSDavid du Colombier Sym *s; 10497dd7cddfSDavid du Colombier char *p; 10507dd7cddfSDavid du Colombier long h; 10517dd7cddfSDavid du Colombier int c, l; 10527dd7cddfSDavid du Colombier 10537dd7cddfSDavid du Colombier h = v; 10547dd7cddfSDavid du Colombier for(p=symb; c = *p; p++) 10557dd7cddfSDavid du Colombier h = h+h+h + c; 10567dd7cddfSDavid du Colombier l = (p - symb) + 1; 10577dd7cddfSDavid du Colombier if(h < 0) 10587dd7cddfSDavid du Colombier h = ~h; 10597dd7cddfSDavid du Colombier h %= NHASH; 10607dd7cddfSDavid du Colombier for(s = hash[h]; s != S; s = s->link) 10617dd7cddfSDavid du Colombier if(s->version == v) 10627dd7cddfSDavid du Colombier if(memcmp(s->name, symb, l) == 0) 10637dd7cddfSDavid du Colombier return s; 10647dd7cddfSDavid du Colombier 10657dd7cddfSDavid du Colombier while(nhunk < sizeof(Sym)) 10667dd7cddfSDavid du Colombier gethunk(); 10677dd7cddfSDavid du Colombier s = (Sym*)hunk; 10687dd7cddfSDavid du Colombier nhunk -= sizeof(Sym); 10697dd7cddfSDavid du Colombier hunk += sizeof(Sym); 10707dd7cddfSDavid du Colombier 10717dd7cddfSDavid du Colombier s->name = malloc(l + 1); 10727dd7cddfSDavid du Colombier memmove(s->name, symb, l); 10737dd7cddfSDavid du Colombier 10747dd7cddfSDavid du Colombier s->link = hash[h]; 10757dd7cddfSDavid du Colombier s->type = 0; 10767dd7cddfSDavid du Colombier s->version = v; 10777dd7cddfSDavid du Colombier s->value = 0; 1078375daca8SDavid du Colombier s->sig = 0; 10797dd7cddfSDavid du Colombier hash[h] = s; 10807dd7cddfSDavid du Colombier return s; 10817dd7cddfSDavid du Colombier } 10827dd7cddfSDavid du Colombier 10837dd7cddfSDavid du Colombier Prog* 10847dd7cddfSDavid du Colombier prg(void) 10857dd7cddfSDavid du Colombier { 10867dd7cddfSDavid du Colombier Prog *p; 10877dd7cddfSDavid du Colombier int n; 10887dd7cddfSDavid du Colombier 10897dd7cddfSDavid du Colombier n = (sizeof(Prog) + 3) & ~3; 10907dd7cddfSDavid du Colombier while(nhunk < n) 10917dd7cddfSDavid du Colombier gethunk(); 10927dd7cddfSDavid du Colombier 10937dd7cddfSDavid du Colombier p = (Prog*)hunk; 10947dd7cddfSDavid du Colombier nhunk -= n; 10957dd7cddfSDavid du Colombier hunk += n; 10967dd7cddfSDavid du Colombier 10977dd7cddfSDavid du Colombier *p = zprg; 10987dd7cddfSDavid du Colombier return p; 10997dd7cddfSDavid du Colombier } 11007dd7cddfSDavid du Colombier 11017dd7cddfSDavid du Colombier void 11027dd7cddfSDavid du Colombier gethunk(void) 11037dd7cddfSDavid du Colombier { 11047dd7cddfSDavid du Colombier char *h; 1105*3f193c01SDavid du Colombier long nh; 11067dd7cddfSDavid du Colombier 1107*3f193c01SDavid du Colombier nh = NHUNK; 1108*3f193c01SDavid du Colombier if(tothunk >= 5L*NHUNK) { 1109*3f193c01SDavid du Colombier nh = 5L*NHUNK; 1110*3f193c01SDavid du Colombier if(tothunk >= 25L*NHUNK) 1111*3f193c01SDavid du Colombier nh = 25L*NHUNK; 1112*3f193c01SDavid du Colombier } 1113*3f193c01SDavid du Colombier h = mysbrk(nh); 11147dd7cddfSDavid du Colombier if(h == (char *)-1) { 11156b6b9ac8SDavid du Colombier diag("out of memory"); 11167dd7cddfSDavid du Colombier errorexit(); 11177dd7cddfSDavid du Colombier } 11187dd7cddfSDavid du Colombier 11197dd7cddfSDavid du Colombier hunk = h; 1120*3f193c01SDavid du Colombier nhunk = nh; 1121*3f193c01SDavid du Colombier tothunk += nh; 11227dd7cddfSDavid du Colombier } 11237dd7cddfSDavid du Colombier 11247dd7cddfSDavid du Colombier void 11257dd7cddfSDavid du Colombier doprof1(void) 11267dd7cddfSDavid du Colombier { 11277dd7cddfSDavid du Colombier Sym *s; 11287dd7cddfSDavid du Colombier long n; 11297dd7cddfSDavid du Colombier Prog *p, *q; 11307dd7cddfSDavid du Colombier 11317dd7cddfSDavid du Colombier if(debug['v']) 11327dd7cddfSDavid du Colombier Bprint(&bso, "%5.2f profile 1\n", cputime()); 11337dd7cddfSDavid du Colombier Bflush(&bso); 11347dd7cddfSDavid du Colombier s = lookup("__mcount", 0); 11357dd7cddfSDavid du Colombier n = 1; 11367dd7cddfSDavid du Colombier for(p = firstp->link; p != P; p = p->link) { 11377dd7cddfSDavid du Colombier if(p->as == ATEXT) { 11387dd7cddfSDavid du Colombier q = prg(); 11397dd7cddfSDavid du Colombier q->line = p->line; 11407dd7cddfSDavid du Colombier q->link = datap; 11417dd7cddfSDavid du Colombier datap = q; 11427dd7cddfSDavid du Colombier q->as = ADATA; 11437dd7cddfSDavid du Colombier q->from.type = D_OREG; 11447dd7cddfSDavid du Colombier q->from.name = D_EXTERN; 11457dd7cddfSDavid du Colombier q->from.offset = n*4; 11467dd7cddfSDavid du Colombier q->from.sym = s; 11477dd7cddfSDavid du Colombier q->reg = 4; 11487dd7cddfSDavid du Colombier q->to = p->from; 11497dd7cddfSDavid du Colombier q->to.type = D_CONST; 11507dd7cddfSDavid du Colombier 11517dd7cddfSDavid du Colombier q = prg(); 11527dd7cddfSDavid du Colombier q->line = p->line; 11537dd7cddfSDavid du Colombier q->pc = p->pc; 11547dd7cddfSDavid du Colombier q->link = p->link; 11557dd7cddfSDavid du Colombier p->link = q; 11567dd7cddfSDavid du Colombier p = q; 11577dd7cddfSDavid du Colombier p->as = AMOVW; 11587dd7cddfSDavid du Colombier p->from.type = D_OREG; 11597dd7cddfSDavid du Colombier p->from.name = D_EXTERN; 11607dd7cddfSDavid du Colombier p->from.sym = s; 11617dd7cddfSDavid du Colombier p->from.offset = n*4 + 4; 11627dd7cddfSDavid du Colombier p->to.type = D_REG; 11637dd7cddfSDavid du Colombier p->to.reg = REGTMP; 11647dd7cddfSDavid du Colombier 11657dd7cddfSDavid du Colombier q = prg(); 11667dd7cddfSDavid du Colombier q->line = p->line; 11677dd7cddfSDavid du Colombier q->pc = p->pc; 11687dd7cddfSDavid du Colombier q->link = p->link; 11697dd7cddfSDavid du Colombier p->link = q; 11707dd7cddfSDavid du Colombier p = q; 11717dd7cddfSDavid du Colombier p->as = AADD; 11727dd7cddfSDavid du Colombier p->from.type = D_CONST; 11737dd7cddfSDavid du Colombier p->from.offset = 1; 11747dd7cddfSDavid du Colombier p->to.type = D_REG; 11757dd7cddfSDavid du Colombier p->to.reg = REGTMP; 11767dd7cddfSDavid du Colombier 11777dd7cddfSDavid du Colombier q = prg(); 11787dd7cddfSDavid du Colombier q->line = p->line; 11797dd7cddfSDavid du Colombier q->pc = p->pc; 11807dd7cddfSDavid du Colombier q->link = p->link; 11817dd7cddfSDavid du Colombier p->link = q; 11827dd7cddfSDavid du Colombier p = q; 11837dd7cddfSDavid du Colombier p->as = AMOVW; 11847dd7cddfSDavid du Colombier p->from.type = D_REG; 11857dd7cddfSDavid du Colombier p->from.reg = REGTMP; 11867dd7cddfSDavid du Colombier p->to.type = D_OREG; 11877dd7cddfSDavid du Colombier p->to.name = D_EXTERN; 11887dd7cddfSDavid du Colombier p->to.sym = s; 11897dd7cddfSDavid du Colombier p->to.offset = n*4 + 4; 11907dd7cddfSDavid du Colombier 11917dd7cddfSDavid du Colombier n += 2; 11927dd7cddfSDavid du Colombier continue; 11937dd7cddfSDavid du Colombier } 11947dd7cddfSDavid du Colombier } 11957dd7cddfSDavid du Colombier q = prg(); 11967dd7cddfSDavid du Colombier q->line = 0; 11977dd7cddfSDavid du Colombier q->link = datap; 11987dd7cddfSDavid du Colombier datap = q; 11997dd7cddfSDavid du Colombier 12007dd7cddfSDavid du Colombier q->as = ADATA; 12017dd7cddfSDavid du Colombier q->from.type = D_OREG; 12027dd7cddfSDavid du Colombier q->from.name = D_EXTERN; 12037dd7cddfSDavid du Colombier q->from.sym = s; 12047dd7cddfSDavid du Colombier q->reg = 4; 12057dd7cddfSDavid du Colombier q->to.type = D_CONST; 12067dd7cddfSDavid du Colombier q->to.offset = n; 12077dd7cddfSDavid du Colombier 12087dd7cddfSDavid du Colombier s->type = SBSS; 12097dd7cddfSDavid du Colombier s->value = n*4; 12107dd7cddfSDavid du Colombier } 12117dd7cddfSDavid du Colombier 12127dd7cddfSDavid du Colombier void 12137dd7cddfSDavid du Colombier doprof2(void) 12147dd7cddfSDavid du Colombier { 12157dd7cddfSDavid du Colombier Sym *s2, *s4; 12167dd7cddfSDavid du Colombier Prog *p, *q, *ps2, *ps4; 12177dd7cddfSDavid du Colombier 12187dd7cddfSDavid du Colombier if(debug['v']) 12197dd7cddfSDavid du Colombier Bprint(&bso, "%5.2f profile 2\n", cputime()); 12207dd7cddfSDavid du Colombier Bflush(&bso); 12217dd7cddfSDavid du Colombier 12227dd7cddfSDavid du Colombier s2 = lookup("_profin", 0); 12237dd7cddfSDavid du Colombier s4 = lookup("_profout", 0); 122459cc4ca5SDavid du Colombier if(s2->type != STEXT || s4->type != STEXT) { 12256b6b9ac8SDavid du Colombier diag("_profin/_profout not defined"); 122659cc4ca5SDavid du Colombier return; 122759cc4ca5SDavid du Colombier } 12287dd7cddfSDavid du Colombier 12297dd7cddfSDavid du Colombier ps2 = P; 12307dd7cddfSDavid du Colombier ps4 = P; 12317dd7cddfSDavid du Colombier for(p = firstp; p != P; p = p->link) { 12327dd7cddfSDavid du Colombier if(p->as == ATEXT) { 12337dd7cddfSDavid du Colombier if(p->from.sym == s2) { 12347dd7cddfSDavid du Colombier p->reg = 1; 12357dd7cddfSDavid du Colombier ps2 = p; 12367dd7cddfSDavid du Colombier } 12377dd7cddfSDavid du Colombier if(p->from.sym == s4) { 12387dd7cddfSDavid du Colombier p->reg = 1; 12397dd7cddfSDavid du Colombier ps4 = p; 12407dd7cddfSDavid du Colombier } 12417dd7cddfSDavid du Colombier } 12427dd7cddfSDavid du Colombier } 12437dd7cddfSDavid du Colombier for(p = firstp; p != P; p = p->link) { 12447dd7cddfSDavid du Colombier if(p->as == ATEXT) { 12457dd7cddfSDavid du Colombier curtext = p; 12467dd7cddfSDavid du Colombier 12477dd7cddfSDavid du Colombier if(p->reg & NOPROF) { /* dont profile */ 12487dd7cddfSDavid du Colombier for(;;) { 12497dd7cddfSDavid du Colombier q = p->link; 12507dd7cddfSDavid du Colombier if(q == P) 12517dd7cddfSDavid du Colombier break; 12527dd7cddfSDavid du Colombier if(q->as == ATEXT) 12537dd7cddfSDavid du Colombier break; 12547dd7cddfSDavid du Colombier p = q; 12557dd7cddfSDavid du Colombier } 12567dd7cddfSDavid du Colombier continue; 12577dd7cddfSDavid du Colombier } 12587dd7cddfSDavid du Colombier 12597dd7cddfSDavid du Colombier /* 12607dd7cddfSDavid du Colombier * BL profin 12617dd7cddfSDavid du Colombier */ 12627dd7cddfSDavid du Colombier q = prg(); 12637dd7cddfSDavid du Colombier q->line = p->line; 12647dd7cddfSDavid du Colombier q->pc = p->pc; 12657dd7cddfSDavid du Colombier q->link = p->link; 12667dd7cddfSDavid du Colombier p->link = q; 12677dd7cddfSDavid du Colombier p = q; 12687dd7cddfSDavid du Colombier p->as = ABL; 12697dd7cddfSDavid du Colombier p->to.type = D_BRANCH; 12707dd7cddfSDavid du Colombier p->cond = ps2; 12717dd7cddfSDavid du Colombier p->to.sym = s2; 12727dd7cddfSDavid du Colombier 12737dd7cddfSDavid du Colombier continue; 12747dd7cddfSDavid du Colombier } 12757dd7cddfSDavid du Colombier if(p->as == ARETURN) { 12767dd7cddfSDavid du Colombier 12777dd7cddfSDavid du Colombier /* 12787dd7cddfSDavid du Colombier * RETURN 12797dd7cddfSDavid du Colombier */ 12807dd7cddfSDavid du Colombier q = prg(); 12817dd7cddfSDavid du Colombier q->as = ARETURN; 12827dd7cddfSDavid du Colombier q->from = p->from; 12837dd7cddfSDavid du Colombier q->to = p->to; 12847dd7cddfSDavid du Colombier q->link = p->link; 12857dd7cddfSDavid du Colombier p->link = q; 12867dd7cddfSDavid du Colombier 12877dd7cddfSDavid du Colombier /* 12887dd7cddfSDavid du Colombier * BL profout 12897dd7cddfSDavid du Colombier */ 12907dd7cddfSDavid du Colombier p->as = ABL; 12917dd7cddfSDavid du Colombier p->from = zprg.from; 12927dd7cddfSDavid du Colombier p->to = zprg.to; 12937dd7cddfSDavid du Colombier p->to.type = D_BRANCH; 12947dd7cddfSDavid du Colombier p->cond = ps4; 12957dd7cddfSDavid du Colombier p->to.sym = s4; 12967dd7cddfSDavid du Colombier 12977dd7cddfSDavid du Colombier p = q; 12987dd7cddfSDavid du Colombier 12997dd7cddfSDavid du Colombier continue; 13007dd7cddfSDavid du Colombier } 13017dd7cddfSDavid du Colombier } 13027dd7cddfSDavid du Colombier } 13037dd7cddfSDavid du Colombier 13047dd7cddfSDavid du Colombier void 13057dd7cddfSDavid du Colombier nuxiinit(void) 13067dd7cddfSDavid du Colombier { 13077dd7cddfSDavid du Colombier int i, c; 13087dd7cddfSDavid du Colombier 13097dd7cddfSDavid du Colombier for(i=0; i<4; i++) { 13107dd7cddfSDavid du Colombier c = find1(0x01020304L, i+1); 13117dd7cddfSDavid du Colombier if(i >= 2) 13127dd7cddfSDavid du Colombier inuxi2[i-2] = c; 13137dd7cddfSDavid du Colombier if(i >= 3) 13147dd7cddfSDavid du Colombier inuxi1[i-3] = c; 13157dd7cddfSDavid du Colombier inuxi4[i] = c; 13167dd7cddfSDavid du Colombier 13177dd7cddfSDavid du Colombier fnuxi8[i] = c+4; 13187dd7cddfSDavid du Colombier fnuxi8[i+4] = c; 13197dd7cddfSDavid du Colombier } 13207dd7cddfSDavid du Colombier if(debug['v']) { 13217dd7cddfSDavid du Colombier Bprint(&bso, "inuxi = "); 13227dd7cddfSDavid du Colombier for(i=0; i<1; i++) 13237dd7cddfSDavid du Colombier Bprint(&bso, "%d", inuxi1[i]); 13247dd7cddfSDavid du Colombier Bprint(&bso, " "); 13257dd7cddfSDavid du Colombier for(i=0; i<2; i++) 13267dd7cddfSDavid du Colombier Bprint(&bso, "%d", inuxi2[i]); 13277dd7cddfSDavid du Colombier Bprint(&bso, " "); 13287dd7cddfSDavid du Colombier for(i=0; i<4; i++) 13297dd7cddfSDavid du Colombier Bprint(&bso, "%d", inuxi4[i]); 13307dd7cddfSDavid du Colombier Bprint(&bso, "\nfnuxi = "); 13317dd7cddfSDavid du Colombier for(i=0; i<8; i++) 13327dd7cddfSDavid du Colombier Bprint(&bso, "%d", fnuxi8[i]); 13337dd7cddfSDavid du Colombier Bprint(&bso, "\n"); 13347dd7cddfSDavid du Colombier } 13357dd7cddfSDavid du Colombier Bflush(&bso); 13367dd7cddfSDavid du Colombier } 13377dd7cddfSDavid du Colombier 13387dd7cddfSDavid du Colombier int 13397dd7cddfSDavid du Colombier find1(long l, int c) 13407dd7cddfSDavid du Colombier { 13417dd7cddfSDavid du Colombier char *p; 13427dd7cddfSDavid du Colombier int i; 13437dd7cddfSDavid du Colombier 13447dd7cddfSDavid du Colombier p = (char*)&l; 13457dd7cddfSDavid du Colombier for(i=0; i<4; i++) 13467dd7cddfSDavid du Colombier if(*p++ == c) 13477dd7cddfSDavid du Colombier return i; 13487dd7cddfSDavid du Colombier return 0; 13497dd7cddfSDavid du Colombier } 13507dd7cddfSDavid du Colombier 13517dd7cddfSDavid du Colombier long 1352375daca8SDavid du Colombier ieeedtof(Ieee *ieeep) 13537dd7cddfSDavid du Colombier { 13547dd7cddfSDavid du Colombier int exp; 13557dd7cddfSDavid du Colombier long v; 13567dd7cddfSDavid du Colombier 1357375daca8SDavid du Colombier if(ieeep->h == 0) 13587dd7cddfSDavid du Colombier return 0; 1359375daca8SDavid du Colombier exp = (ieeep->h>>20) & ((1L<<11)-1L); 13607dd7cddfSDavid du Colombier exp -= (1L<<10) - 2L; 1361375daca8SDavid du Colombier v = (ieeep->h & 0xfffffL) << 3; 1362375daca8SDavid du Colombier v |= (ieeep->l >> 29) & 0x7L; 1363375daca8SDavid du Colombier if((ieeep->l >> 28) & 1) { 13647dd7cddfSDavid du Colombier v++; 13657dd7cddfSDavid du Colombier if(v & 0x800000L) { 13667dd7cddfSDavid du Colombier v = (v & 0x7fffffL) >> 1; 13677dd7cddfSDavid du Colombier exp++; 13687dd7cddfSDavid du Colombier } 13697dd7cddfSDavid du Colombier } 13707dd7cddfSDavid du Colombier if(exp <= -126 || exp >= 130) 13716b6b9ac8SDavid du Colombier diag("double fp to single fp overflow"); 13727dd7cddfSDavid du Colombier v |= ((exp + 126) & 0xffL) << 23; 1373375daca8SDavid du Colombier v |= ieeep->h & 0x80000000L; 13747dd7cddfSDavid du Colombier return v; 13757dd7cddfSDavid du Colombier } 13767dd7cddfSDavid du Colombier 13777dd7cddfSDavid du Colombier double 1378375daca8SDavid du Colombier ieeedtod(Ieee *ieeep) 13797dd7cddfSDavid du Colombier { 13807dd7cddfSDavid du Colombier Ieee e; 13817dd7cddfSDavid du Colombier double fr; 13827dd7cddfSDavid du Colombier int exp; 13837dd7cddfSDavid du Colombier 1384375daca8SDavid du Colombier if(ieeep->h & (1L<<31)) { 1385375daca8SDavid du Colombier e.h = ieeep->h & ~(1L<<31); 1386375daca8SDavid du Colombier e.l = ieeep->l; 13877dd7cddfSDavid du Colombier return -ieeedtod(&e); 13887dd7cddfSDavid du Colombier } 1389375daca8SDavid du Colombier if(ieeep->l == 0 && ieeep->h == 0) 13907dd7cddfSDavid du Colombier return 0; 1391375daca8SDavid du Colombier fr = ieeep->l & ((1L<<16)-1L); 13927dd7cddfSDavid du Colombier fr /= 1L<<16; 1393375daca8SDavid du Colombier fr += (ieeep->l>>16) & ((1L<<16)-1L); 13947dd7cddfSDavid du Colombier fr /= 1L<<16; 1395375daca8SDavid du Colombier fr += (ieeep->h & (1L<<20)-1L) | (1L<<20); 13967dd7cddfSDavid du Colombier fr /= 1L<<21; 1397375daca8SDavid du Colombier exp = (ieeep->h>>20) & ((1L<<11)-1L); 13987dd7cddfSDavid du Colombier exp -= (1L<<10) - 2L; 13997dd7cddfSDavid du Colombier return ldexp(fr, exp); 14007dd7cddfSDavid du Colombier } 14017dd7cddfSDavid du Colombier 1402375daca8SDavid du Colombier void 1403375daca8SDavid du Colombier undefsym(Sym *s) 14047dd7cddfSDavid du Colombier { 1405375daca8SDavid du Colombier int n; 14067dd7cddfSDavid du Colombier 1407375daca8SDavid du Colombier n = imports; 1408375daca8SDavid du Colombier if(s->value != 0) 1409375daca8SDavid du Colombier diag("value != 0 on SXREF"); 1410375daca8SDavid du Colombier if(n >= 1<<Rindex) 1411375daca8SDavid du Colombier diag("import index %d out of range", n); 1412375daca8SDavid du Colombier s->value = n<<Roffset; 1413375daca8SDavid du Colombier s->type = SUNDEF; 1414375daca8SDavid du Colombier imports++; 14157dd7cddfSDavid du Colombier } 14167dd7cddfSDavid du Colombier 14177dd7cddfSDavid du Colombier void 1418375daca8SDavid du Colombier zerosig(char *sp) 14197dd7cddfSDavid du Colombier { 1420375daca8SDavid du Colombier Sym *s; 1421375daca8SDavid du Colombier 1422375daca8SDavid du Colombier s = lookup(sp, 0); 1423375daca8SDavid du Colombier s->sig = 0; 14247dd7cddfSDavid du Colombier } 14257dd7cddfSDavid du Colombier 1426375daca8SDavid du Colombier void 1427375daca8SDavid du Colombier readundefs(char *f, int t) 14287dd7cddfSDavid du Colombier { 1429375daca8SDavid du Colombier int i, n; 1430375daca8SDavid du Colombier Sym *s; 1431375daca8SDavid du Colombier Biobuf *b; 1432375daca8SDavid du Colombier char *l, buf[256], *fields[64]; 14337dd7cddfSDavid du Colombier 1434375daca8SDavid du Colombier if(f == nil) 1435375daca8SDavid du Colombier return; 1436375daca8SDavid du Colombier b = Bopen(f, OREAD); 1437375daca8SDavid du Colombier if(b == nil){ 1438375daca8SDavid du Colombier diag("could not open %s: %r", f); 1439375daca8SDavid du Colombier errorexit(); 14407dd7cddfSDavid du Colombier } 1441375daca8SDavid du Colombier while((l = Brdline(b, '\n')) != nil){ 1442375daca8SDavid du Colombier n = Blinelen(b); 1443375daca8SDavid du Colombier if(n >= sizeof(buf)){ 1444375daca8SDavid du Colombier diag("%s: line too long", f); 1445375daca8SDavid du Colombier errorexit(); 1446375daca8SDavid du Colombier } 1447375daca8SDavid du Colombier memmove(buf, l, n); 1448375daca8SDavid du Colombier buf[n-1] = '\0'; 1449375daca8SDavid du Colombier n = getfields(buf, fields, nelem(fields), 1, " \t\r\n"); 1450375daca8SDavid du Colombier if(n == nelem(fields)){ 1451375daca8SDavid du Colombier diag("%s: bad format", f); 1452375daca8SDavid du Colombier errorexit(); 1453375daca8SDavid du Colombier } 1454375daca8SDavid du Colombier for(i = 0; i < n; i++){ 1455375daca8SDavid du Colombier s = lookup(fields[i], 0); 1456375daca8SDavid du Colombier s->type = SXREF; 1457375daca8SDavid du Colombier s->subtype = t; 1458375daca8SDavid du Colombier if(t == SIMPORT) 1459375daca8SDavid du Colombier nimports++; 1460375daca8SDavid du Colombier else 1461375daca8SDavid du Colombier nexports++; 1462375daca8SDavid du Colombier } 1463375daca8SDavid du Colombier } 1464375daca8SDavid du Colombier Bterm(b); 14657dd7cddfSDavid du Colombier } 1466