17edc7532SDavid du Colombier #define EXTERN
27edc7532SDavid du Colombier #include "l.h"
37edc7532SDavid du Colombier #include <ar.h>
47edc7532SDavid du Colombier
57edc7532SDavid du Colombier #ifndef DEFAULT
67edc7532SDavid du Colombier #define DEFAULT '9'
77edc7532SDavid du Colombier #endif
87edc7532SDavid du Colombier
97edc7532SDavid du Colombier char *noname = "<none>";
107edc7532SDavid du Colombier char symname[] = SYMDEF;
117edc7532SDavid du Colombier char thechar = '4';
127edc7532SDavid du Colombier char *thestring = "mips64";
13*f8bc6aafSDavid du Colombier int little;
14*f8bc6aafSDavid du Colombier
15*f8bc6aafSDavid du Colombier char** libdir;
16*f8bc6aafSDavid du Colombier int nlibdir = 0;
17*f8bc6aafSDavid du Colombier static int maxlibdir = 0;
187edc7532SDavid du Colombier
197edc7532SDavid du Colombier /*
207edc7532SDavid du Colombier * -H0 -T0x40004C -D0x10000000 is abbrev unix
217edc7532SDavid du Colombier * -H1 -T0x80020000 -R4 is bootp() format for 3k
22*f8bc6aafSDavid du Colombier * -H2 -T16416 -R16384 is plan9 mips64 format
237edc7532SDavid du Colombier * -H3 -T0x80020000 -R8 is bootp() format for 4k
247edc7532SDavid du Colombier * -H4 -T0x400000 -R4 is sgi unix coff executable
257edc7532SDavid du Colombier * -H5 -T0x4000A0 -R4 is sgi unix elf executable
26*f8bc6aafSDavid du Colombier * -H6 -T16416 -R16384 is plan9 mips format
27*f8bc6aafSDavid du Colombier * -H7 is 64-bit elf executable
287edc7532SDavid du Colombier */
297edc7532SDavid du Colombier
307edc7532SDavid du Colombier void
usage(void)31*f8bc6aafSDavid du Colombier usage(void)
32*f8bc6aafSDavid du Colombier {
33*f8bc6aafSDavid du Colombier diag("usage: %s [-options] objects", argv0);
34*f8bc6aafSDavid du Colombier errorexit();
35*f8bc6aafSDavid du Colombier }
36*f8bc6aafSDavid du Colombier
37*f8bc6aafSDavid du Colombier void
main(int argc,char * argv[])387edc7532SDavid du Colombier main(int argc, char *argv[])
397edc7532SDavid du Colombier {
407edc7532SDavid du Colombier int c;
417edc7532SDavid du Colombier char *a;
42*f8bc6aafSDavid du Colombier char name[LIBNAMELEN];
437edc7532SDavid du Colombier
447edc7532SDavid du Colombier Binit(&bso, 1, OWRITE);
457edc7532SDavid du Colombier cout = -1;
467edc7532SDavid du Colombier listinit();
477edc7532SDavid du Colombier outfile = 0;
487edc7532SDavid du Colombier nerrors = 0;
497edc7532SDavid du Colombier curtext = P;
507edc7532SDavid du Colombier HEADTYPE = -1;
517edc7532SDavid du Colombier INITTEXT = -1;
52*f8bc6aafSDavid du Colombier INITTEXTP = -1;
537edc7532SDavid du Colombier INITDAT = -1;
547edc7532SDavid du Colombier INITRND = -1;
557edc7532SDavid du Colombier INITENTRY = 0;
567edc7532SDavid du Colombier M64 = 1;
577edc7532SDavid du Colombier
587edc7532SDavid du Colombier ARGBEGIN {
597edc7532SDavid du Colombier default:
607edc7532SDavid du Colombier c = ARGC();
617edc7532SDavid du Colombier if(c >= 0 && c < sizeof(debug))
627edc7532SDavid du Colombier debug[c]++;
637edc7532SDavid du Colombier break;
647edc7532SDavid du Colombier case 'o':
657edc7532SDavid du Colombier outfile = ARGF();
667edc7532SDavid du Colombier break;
677edc7532SDavid du Colombier case 'E':
687edc7532SDavid du Colombier a = ARGF();
697edc7532SDavid du Colombier if(a)
707edc7532SDavid du Colombier INITENTRY = a;
717edc7532SDavid du Colombier break;
72*f8bc6aafSDavid du Colombier case 'm': /* for little-endian mips */
73*f8bc6aafSDavid du Colombier thechar = 'x'; /* XXX the char unknown */
74*f8bc6aafSDavid du Colombier thestring = "spim64";
75*f8bc6aafSDavid du Colombier little = 1;
76*f8bc6aafSDavid du Colombier break;
777edc7532SDavid du Colombier case 'T':
787edc7532SDavid du Colombier a = ARGF();
797edc7532SDavid du Colombier if(a)
807edc7532SDavid du Colombier INITTEXT = atolwhex(a);
817edc7532SDavid du Colombier break;
82*f8bc6aafSDavid du Colombier case 'P':
83*f8bc6aafSDavid du Colombier a = ARGF();
84*f8bc6aafSDavid du Colombier if(a)
85*f8bc6aafSDavid du Colombier INITTEXTP = atolwhex(a);
86*f8bc6aafSDavid du Colombier break;
877edc7532SDavid du Colombier case 'D':
887edc7532SDavid du Colombier a = ARGF();
897edc7532SDavid du Colombier if(a)
907edc7532SDavid du Colombier INITDAT = atolwhex(a);
917edc7532SDavid du Colombier break;
927edc7532SDavid du Colombier case 'R':
937edc7532SDavid du Colombier a = ARGF();
947edc7532SDavid du Colombier if(a)
957edc7532SDavid du Colombier INITRND = atolwhex(a);
967edc7532SDavid du Colombier break;
977edc7532SDavid du Colombier case 'H':
987edc7532SDavid du Colombier a = ARGF();
997edc7532SDavid du Colombier if(a)
1007edc7532SDavid du Colombier HEADTYPE = atolwhex(a);
1017edc7532SDavid du Colombier /* do something about setting INITTEXT */
1027edc7532SDavid du Colombier break;
103*f8bc6aafSDavid du Colombier case 'L':
104*f8bc6aafSDavid du Colombier addlibpath(EARGF(usage()));
105*f8bc6aafSDavid du Colombier break;
1067edc7532SDavid du Colombier } ARGEND
1077edc7532SDavid du Colombier
1087edc7532SDavid du Colombier USED(argc);
1097edc7532SDavid du Colombier
110*f8bc6aafSDavid du Colombier if(*argv == 0)
111*f8bc6aafSDavid du Colombier usage();
1127edc7532SDavid du Colombier if(!debug['9'] && !debug['U'] && !debug['B'])
1137edc7532SDavid du Colombier debug[DEFAULT] = 1;
114*f8bc6aafSDavid du Colombier a = getenv("ccroot");
115*f8bc6aafSDavid du Colombier if(a != nil && *a != '\0') {
116*f8bc6aafSDavid du Colombier if(!fileexists(a)) {
117*f8bc6aafSDavid du Colombier diag("nonexistent $ccroot: %s", a);
118*f8bc6aafSDavid du Colombier errorexit();
119*f8bc6aafSDavid du Colombier }
120*f8bc6aafSDavid du Colombier }else
121*f8bc6aafSDavid du Colombier a = "";
122*f8bc6aafSDavid du Colombier snprint(name, sizeof(name), "%s/%s/lib", a, thestring);
123*f8bc6aafSDavid du Colombier addlibpath(name);
1247edc7532SDavid du Colombier if(HEADTYPE == -1) {
1257edc7532SDavid du Colombier if(debug['U'])
1267edc7532SDavid du Colombier HEADTYPE = 0;
1277edc7532SDavid du Colombier if(debug['B'])
1287edc7532SDavid du Colombier HEADTYPE = 1;
1297edc7532SDavid du Colombier if(debug['9'])
1307edc7532SDavid du Colombier HEADTYPE = 2;
1317edc7532SDavid du Colombier }
1327edc7532SDavid du Colombier switch(HEADTYPE) {
1337edc7532SDavid du Colombier default:
1347edc7532SDavid du Colombier diag("unknown -H option");
1357edc7532SDavid du Colombier errorexit();
1367edc7532SDavid du Colombier
1377edc7532SDavid du Colombier case 0: /* unix simple */
1387edc7532SDavid du Colombier HEADR = 20L+56L;
1397edc7532SDavid du Colombier if(INITTEXT == -1)
1407edc7532SDavid du Colombier INITTEXT = 0x40004CL;
1417edc7532SDavid du Colombier if(INITDAT == -1)
1427edc7532SDavid du Colombier INITDAT = 0x10000000L;
1437edc7532SDavid du Colombier if(INITRND == -1)
1447edc7532SDavid du Colombier INITRND = 0;
1457edc7532SDavid du Colombier break;
1467edc7532SDavid du Colombier case 1: /* boot for 3k */
1477edc7532SDavid du Colombier HEADR = 20L+60L;
1487edc7532SDavid du Colombier if(INITTEXT == -1)
1497edc7532SDavid du Colombier INITTEXT = 0x80020000L;
1507edc7532SDavid du Colombier if(INITDAT == -1)
1517edc7532SDavid du Colombier INITDAT = 0;
1527edc7532SDavid du Colombier if(INITRND == -1)
1537edc7532SDavid du Colombier INITRND = 4;
1547edc7532SDavid du Colombier break;
155*f8bc6aafSDavid du Colombier case 2: /* plan 9 mips64 */
1567edc7532SDavid du Colombier HEADR = 32L;
1577edc7532SDavid du Colombier if(INITDAT == -1)
1587edc7532SDavid du Colombier INITDAT = 0;
1597edc7532SDavid du Colombier if(INITRND == -1)
160*f8bc6aafSDavid du Colombier INITRND = 16*1024;
161*f8bc6aafSDavid du Colombier if(INITTEXT == -1)
162*f8bc6aafSDavid du Colombier INITTEXT = INITRND + HEADR;
1637edc7532SDavid du Colombier break;
1647edc7532SDavid du Colombier case 3: /* boot for 4k */
1657edc7532SDavid du Colombier HEADR = 20L+56L+3*40L;
1667edc7532SDavid du Colombier if(INITTEXT == -1)
1677edc7532SDavid du Colombier INITTEXT = 0x80020000L;
1687edc7532SDavid du Colombier if(INITDAT == -1)
1697edc7532SDavid du Colombier INITDAT = 0;
1707edc7532SDavid du Colombier if(INITRND == -1)
1717edc7532SDavid du Colombier INITRND = 8;
1727edc7532SDavid du Colombier break;
1737edc7532SDavid du Colombier case 4: /* sgi unix coff executable */
1747edc7532SDavid du Colombier HEADR = 20L+56L+3*40L;
1757edc7532SDavid du Colombier if(INITTEXT == -1)
1767edc7532SDavid du Colombier INITTEXT = 0x00400000L+HEADR;
1777edc7532SDavid du Colombier if(INITDAT == -1)
1787edc7532SDavid du Colombier INITDAT = 0x10000000;
1797edc7532SDavid du Colombier if(INITRND == -1)
1807edc7532SDavid du Colombier INITRND = 0;
1817edc7532SDavid du Colombier break;
1827edc7532SDavid du Colombier case 5: /* sgi unix elf executable */
183*f8bc6aafSDavid du Colombier HEADR = rnd(Ehdr32sz+3*Phdr32sz, 16);
1847edc7532SDavid du Colombier if(INITTEXT == -1)
1857edc7532SDavid du Colombier INITTEXT = 0x00400000L+HEADR;
1867edc7532SDavid du Colombier if(INITDAT == -1)
1877edc7532SDavid du Colombier INITDAT = 0x10000000;
1887edc7532SDavid du Colombier if(INITRND == -1)
1897edc7532SDavid du Colombier INITRND = 0;
1907edc7532SDavid du Colombier break;
1917edc7532SDavid du Colombier case 6: /* plan 9 mips */
1927edc7532SDavid du Colombier HEADR = 32L;
1937edc7532SDavid du Colombier if(INITDAT == -1)
1947edc7532SDavid du Colombier INITDAT = 0;
1957edc7532SDavid du Colombier if(INITRND == -1)
196*f8bc6aafSDavid du Colombier INITRND = 16*1024;
197*f8bc6aafSDavid du Colombier if(INITTEXT == -1)
198*f8bc6aafSDavid du Colombier INITTEXT = INITRND + HEADR;
1997edc7532SDavid du Colombier break;
200*f8bc6aafSDavid du Colombier case 7: /* 64-bit elf executable */
2017edc7532SDavid du Colombier HEADR = rnd(64L+3*56L, 16);
2027edc7532SDavid du Colombier if(INITTEXT == -1)
2037edc7532SDavid du Colombier INITTEXT = 0xa800000020040000ULL;
2047edc7532SDavid du Colombier if(INITDAT == -1)
2057edc7532SDavid du Colombier INITDAT = 0;
2067edc7532SDavid du Colombier if(INITRND == -1)
2077edc7532SDavid du Colombier INITRND = 8;
2087edc7532SDavid du Colombier break;
2097edc7532SDavid du Colombier }
210*f8bc6aafSDavid du Colombier if (INITTEXTP == -1)
211*f8bc6aafSDavid du Colombier INITTEXTP = INITTEXT;
2127edc7532SDavid du Colombier if(INITDAT != 0 && INITRND != 0)
213*f8bc6aafSDavid du Colombier print("warning: -D%#llux is ignored because of -R%#llux\n",
2147edc7532SDavid du Colombier INITDAT, INITRND);
2157edc7532SDavid du Colombier if(debug['v'])
216*f8bc6aafSDavid du Colombier Bprint(&bso, "HEADER = -H%d -T%#llux -D%#llux -R%#llux\n",
2177edc7532SDavid du Colombier HEADTYPE, INITTEXT, INITDAT, INITRND);
2187edc7532SDavid du Colombier Bflush(&bso);
2197edc7532SDavid du Colombier zprg.as = AGOK;
2207edc7532SDavid du Colombier zprg.reg = NREG;
2217edc7532SDavid du Colombier zprg.from.name = D_NONE;
2227edc7532SDavid du Colombier zprg.from.type = D_NONE;
2237edc7532SDavid du Colombier zprg.from.reg = NREG;
2247edc7532SDavid du Colombier zprg.to = zprg.from;
2257edc7532SDavid du Colombier buildop();
2267edc7532SDavid du Colombier histgen = 0;
2277edc7532SDavid du Colombier textp = P;
2287edc7532SDavid du Colombier datap = P;
2297edc7532SDavid du Colombier pc = 0;
2307edc7532SDavid du Colombier dtype = 4;
231*f8bc6aafSDavid du Colombier if(outfile == 0) {
232*f8bc6aafSDavid du Colombier static char name[20];
233*f8bc6aafSDavid du Colombier
234*f8bc6aafSDavid du Colombier snprint(name, sizeof name, "%c.out", thechar);
235*f8bc6aafSDavid du Colombier outfile = name;
236*f8bc6aafSDavid du Colombier }
2377edc7532SDavid du Colombier cout = create(outfile, 1, 0775);
2387edc7532SDavid du Colombier if(cout < 0) {
239*f8bc6aafSDavid du Colombier diag("cannot create %s: %r", outfile);
2407edc7532SDavid du Colombier errorexit();
2417edc7532SDavid du Colombier }
2427edc7532SDavid du Colombier nuxiinit();
2437edc7532SDavid du Colombier
2447edc7532SDavid du Colombier version = 0;
2457edc7532SDavid du Colombier cbp = buf.cbuf;
2467edc7532SDavid du Colombier cbc = sizeof(buf.cbuf);
2477edc7532SDavid du Colombier firstp = prg();
2487edc7532SDavid du Colombier lastp = firstp;
2497edc7532SDavid du Colombier
2507edc7532SDavid du Colombier if(INITENTRY == 0) {
2517edc7532SDavid du Colombier INITENTRY = "_main";
2527edc7532SDavid du Colombier if(debug['p'])
2537edc7532SDavid du Colombier INITENTRY = "_mainp";
2547edc7532SDavid du Colombier if(!debug['l'])
2557edc7532SDavid du Colombier lookup(INITENTRY, 0)->type = SXREF;
256*f8bc6aafSDavid du Colombier } else if(!(*INITENTRY >= '0' && *INITENTRY <= '9'))
2577edc7532SDavid du Colombier lookup(INITENTRY, 0)->type = SXREF;
2587edc7532SDavid du Colombier
2597edc7532SDavid du Colombier while(*argv)
2607edc7532SDavid du Colombier objfile(*argv++);
2617edc7532SDavid du Colombier if(!debug['l'])
262*f8bc6aafSDavid du Colombier loadlib();
2637edc7532SDavid du Colombier firstp = firstp->link;
2647edc7532SDavid du Colombier if(firstp == P)
2657edc7532SDavid du Colombier goto out;
2667edc7532SDavid du Colombier patch();
2677edc7532SDavid du Colombier if(debug['p'])
2687edc7532SDavid du Colombier if(debug['1'])
2697edc7532SDavid du Colombier doprof1();
2707edc7532SDavid du Colombier else
2717edc7532SDavid du Colombier doprof2();
2727edc7532SDavid du Colombier dodata();
2737edc7532SDavid du Colombier follow();
2747edc7532SDavid du Colombier if(firstp == P)
2757edc7532SDavid du Colombier goto out;
2767edc7532SDavid du Colombier noops();
2777edc7532SDavid du Colombier span();
2787edc7532SDavid du Colombier asmb();
2797edc7532SDavid du Colombier undef();
2807edc7532SDavid du Colombier
2817edc7532SDavid du Colombier out:
2827edc7532SDavid du Colombier if(debug['v']) {
2837edc7532SDavid du Colombier Bprint(&bso, "%5.2f cpu time\n", cputime());
2847edc7532SDavid du Colombier Bprint(&bso, "%ld memory used\n", thunk);
2857edc7532SDavid du Colombier Bprint(&bso, "%d sizeof adr\n", sizeof(Adr));
2867edc7532SDavid du Colombier Bprint(&bso, "%d sizeof prog\n", sizeof(Prog));
2877edc7532SDavid du Colombier }
2887edc7532SDavid du Colombier Bflush(&bso);
2897edc7532SDavid du Colombier errorexit();
2907edc7532SDavid du Colombier }
2917edc7532SDavid du Colombier
2927edc7532SDavid du Colombier void
addlibpath(char * arg)293*f8bc6aafSDavid du Colombier addlibpath(char *arg)
2947edc7532SDavid du Colombier {
295*f8bc6aafSDavid du Colombier char **p;
2967edc7532SDavid du Colombier
297*f8bc6aafSDavid du Colombier if(nlibdir >= maxlibdir) {
298*f8bc6aafSDavid du Colombier if(maxlibdir == 0)
299*f8bc6aafSDavid du Colombier maxlibdir = 8;
300*f8bc6aafSDavid du Colombier else
301*f8bc6aafSDavid du Colombier maxlibdir *= 2;
302*f8bc6aafSDavid du Colombier p = malloc(maxlibdir*sizeof(*p));
303*f8bc6aafSDavid du Colombier if(p == nil) {
304*f8bc6aafSDavid du Colombier diag("out of memory");
305*f8bc6aafSDavid du Colombier errorexit();
3067edc7532SDavid du Colombier }
307*f8bc6aafSDavid du Colombier memmove(p, libdir, nlibdir*sizeof(*p));
308*f8bc6aafSDavid du Colombier free(libdir);
309*f8bc6aafSDavid du Colombier libdir = p;
310*f8bc6aafSDavid du Colombier }
311*f8bc6aafSDavid du Colombier libdir[nlibdir++] = strdup(arg);
312*f8bc6aafSDavid du Colombier }
313*f8bc6aafSDavid du Colombier
314*f8bc6aafSDavid du Colombier char*
findlib(char * file)315*f8bc6aafSDavid du Colombier findlib(char *file)
316*f8bc6aafSDavid du Colombier {
317*f8bc6aafSDavid du Colombier int i;
318*f8bc6aafSDavid du Colombier char name[LIBNAMELEN];
319*f8bc6aafSDavid du Colombier
320*f8bc6aafSDavid du Colombier for(i = 0; i < nlibdir; i++) {
321*f8bc6aafSDavid du Colombier snprint(name, sizeof(name), "%s/%s", libdir[i], file);
322*f8bc6aafSDavid du Colombier if(fileexists(name))
323*f8bc6aafSDavid du Colombier return libdir[i];
324*f8bc6aafSDavid du Colombier }
325*f8bc6aafSDavid du Colombier return nil;
326*f8bc6aafSDavid du Colombier }
327*f8bc6aafSDavid du Colombier
328*f8bc6aafSDavid du Colombier void
loadlib(void)329*f8bc6aafSDavid du Colombier loadlib(void)
330*f8bc6aafSDavid du Colombier {
331*f8bc6aafSDavid du Colombier int i;
332*f8bc6aafSDavid du Colombier long h;
333*f8bc6aafSDavid du Colombier Sym *s;
334*f8bc6aafSDavid du Colombier
335*f8bc6aafSDavid du Colombier loop:
336*f8bc6aafSDavid du Colombier xrefresolv = 0;
337*f8bc6aafSDavid du Colombier for(i=0; i<libraryp; i++) {
338*f8bc6aafSDavid du Colombier if(debug['v'])
339*f8bc6aafSDavid du Colombier Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(), library[i], libraryobj[i]);
340*f8bc6aafSDavid du Colombier objfile(library[i]);
341*f8bc6aafSDavid du Colombier }
342*f8bc6aafSDavid du Colombier if(xrefresolv)
343*f8bc6aafSDavid du Colombier for(h=0; h<nelem(hash); h++)
344*f8bc6aafSDavid du Colombier for(s = hash[h]; s != S; s = s->link)
345*f8bc6aafSDavid du Colombier if(s->type == SXREF)
346*f8bc6aafSDavid du Colombier goto loop;
3477edc7532SDavid du Colombier }
3487edc7532SDavid du Colombier
3497edc7532SDavid du Colombier void
errorexit(void)3507edc7532SDavid du Colombier errorexit(void)
3517edc7532SDavid du Colombier {
3527edc7532SDavid du Colombier
3537edc7532SDavid du Colombier if(nerrors) {
3547edc7532SDavid du Colombier if(cout >= 0)
3557edc7532SDavid du Colombier remove(outfile);
3567edc7532SDavid du Colombier exits("error");
3577edc7532SDavid du Colombier }
3587edc7532SDavid du Colombier exits(0);
3597edc7532SDavid du Colombier }
3607edc7532SDavid du Colombier
3617edc7532SDavid du Colombier void
objfile(char * file)3627edc7532SDavid du Colombier objfile(char *file)
3637edc7532SDavid du Colombier {
3647edc7532SDavid du Colombier vlong off, esym, cnt, l;
3657edc7532SDavid du Colombier int f, work;
3667edc7532SDavid du Colombier Sym *s;
3677edc7532SDavid du Colombier char magbuf[SARMAG];
3687edc7532SDavid du Colombier char name[100], pname[150];
3697edc7532SDavid du Colombier struct ar_hdr arhdr;
3707edc7532SDavid du Colombier char *e, *start, *stop;
3717edc7532SDavid du Colombier
3727edc7532SDavid du Colombier if(file[0] == '-' && file[1] == 'l') {
3737edc7532SDavid du Colombier if(debug['9'])
3747edc7532SDavid du Colombier sprint(name, "/%s/lib/lib", thestring);
3757edc7532SDavid du Colombier else
3767edc7532SDavid du Colombier sprint(name, "/usr/%clib/lib", thechar);
3777edc7532SDavid du Colombier strcat(name, file+2);
3787edc7532SDavid du Colombier strcat(name, ".a");
3797edc7532SDavid du Colombier file = name;
3807edc7532SDavid du Colombier }
3817edc7532SDavid du Colombier if(debug['v'])
3827edc7532SDavid du Colombier Bprint(&bso, "%5.2f ldobj: %s\n", cputime(), file);
3837edc7532SDavid du Colombier Bflush(&bso);
3847edc7532SDavid du Colombier f = open(file, 0);
3857edc7532SDavid du Colombier if(f < 0) {
3867edc7532SDavid du Colombier diag("cannot open file: %s", file);
3877edc7532SDavid du Colombier errorexit();
3887edc7532SDavid du Colombier }
3897edc7532SDavid du Colombier l = read(f, magbuf, SARMAG);
3907edc7532SDavid du Colombier if(l != SARMAG || strncmp(magbuf, ARMAG, SARMAG)){
3917edc7532SDavid du Colombier /* load it as a regular file */
3927edc7532SDavid du Colombier l = seek(f, 0L, 2);
3937edc7532SDavid du Colombier seek(f, 0L, 0);
3947edc7532SDavid du Colombier ldobj(f, l, file);
3957edc7532SDavid du Colombier close(f);
3967edc7532SDavid du Colombier return;
3977edc7532SDavid du Colombier }
3987edc7532SDavid du Colombier
3997edc7532SDavid du Colombier if(debug['v'])
4007edc7532SDavid du Colombier Bprint(&bso, "%5.2f ldlib: %s\n", cputime(), file);
4017edc7532SDavid du Colombier l = read(f, &arhdr, SAR_HDR);
4027edc7532SDavid du Colombier if(l != SAR_HDR) {
4037edc7532SDavid du Colombier diag("%s: short read on archive file symbol header", file);
4047edc7532SDavid du Colombier goto out;
4057edc7532SDavid du Colombier }
4067edc7532SDavid du Colombier if(strncmp(arhdr.name, symname, strlen(symname))) {
4077edc7532SDavid du Colombier diag("%s: first entry not symbol header", file);
4087edc7532SDavid du Colombier goto out;
4097edc7532SDavid du Colombier }
4107edc7532SDavid du Colombier
4117edc7532SDavid du Colombier esym = SARMAG + SAR_HDR + atolwhex(arhdr.size);
4127edc7532SDavid du Colombier off = SARMAG + SAR_HDR;
4137edc7532SDavid du Colombier
4147edc7532SDavid du Colombier /*
4157edc7532SDavid du Colombier * just bang the whole symbol file into memory
4167edc7532SDavid du Colombier */
4177edc7532SDavid du Colombier seek(f, off, 0);
4187edc7532SDavid du Colombier cnt = esym - off;
4197edc7532SDavid du Colombier start = malloc(cnt + 10);
4207edc7532SDavid du Colombier cnt = read(f, start, cnt);
4217edc7532SDavid du Colombier if(cnt <= 0){
4227edc7532SDavid du Colombier close(f);
4237edc7532SDavid du Colombier return;
4247edc7532SDavid du Colombier }
4257edc7532SDavid du Colombier stop = &start[cnt];
4267edc7532SDavid du Colombier memset(stop, 0, 10);
4277edc7532SDavid du Colombier
4287edc7532SDavid du Colombier work = 1;
4297edc7532SDavid du Colombier while(work){
4307edc7532SDavid du Colombier if(debug['v'])
4317edc7532SDavid du Colombier Bprint(&bso, "%5.2f library pass: %s\n", cputime(), file);
4327edc7532SDavid du Colombier Bflush(&bso);
4337edc7532SDavid du Colombier work = 0;
4347edc7532SDavid du Colombier for(e = start; e < stop; e = strchr(e+5, 0) + 1) {
4357edc7532SDavid du Colombier s = lookup(e+5, 0);
4367edc7532SDavid du Colombier if(s->type != SXREF)
4377edc7532SDavid du Colombier continue;
4387edc7532SDavid du Colombier sprint(pname, "%s(%s)", file, s->name);
4397edc7532SDavid du Colombier if(debug['v'])
4407edc7532SDavid du Colombier Bprint(&bso, "%5.2f library: %s\n", cputime(), pname);
4417edc7532SDavid du Colombier Bflush(&bso);
4427edc7532SDavid du Colombier l = e[1] & 0xff;
4437edc7532SDavid du Colombier l |= (e[2] & 0xff) << 8;
4447edc7532SDavid du Colombier l |= (e[3] & 0xff) << 16;
4457edc7532SDavid du Colombier l |= (e[4] & 0xff) << 24;
4467edc7532SDavid du Colombier seek(f, l, 0);
447*f8bc6aafSDavid du Colombier /* need readn to read the dumps (at least) */
448*f8bc6aafSDavid du Colombier l = readn(f, &arhdr, SAR_HDR);
4497edc7532SDavid du Colombier if(l != SAR_HDR)
4507edc7532SDavid du Colombier goto bad;
4517edc7532SDavid du Colombier if(strncmp(arhdr.fmag, ARFMAG, sizeof(arhdr.fmag)))
4527edc7532SDavid du Colombier goto bad;
4537edc7532SDavid du Colombier l = atolwhex(arhdr.size);
4547edc7532SDavid du Colombier ldobj(f, l, pname);
4557edc7532SDavid du Colombier if(s->type == SXREF) {
4567edc7532SDavid du Colombier diag("%s: failed to load: %s", file, s->name);
4577edc7532SDavid du Colombier errorexit();
4587edc7532SDavid du Colombier }
4597edc7532SDavid du Colombier work = 1;
460*f8bc6aafSDavid du Colombier xrefresolv = 1;
4617edc7532SDavid du Colombier }
4627edc7532SDavid du Colombier }
4637edc7532SDavid du Colombier return;
4647edc7532SDavid du Colombier
4657edc7532SDavid du Colombier bad:
4667edc7532SDavid du Colombier diag("%s: bad or out of date archive", file);
4677edc7532SDavid du Colombier out:
4687edc7532SDavid du Colombier close(f);
4697edc7532SDavid du Colombier }
4707edc7532SDavid du Colombier
4717edc7532SDavid du Colombier int
zaddr(uchar * p,Adr * a,Sym * h[])4727edc7532SDavid du Colombier zaddr(uchar *p, Adr *a, Sym *h[])
4737edc7532SDavid du Colombier {
4747edc7532SDavid du Colombier int i, c;
4757edc7532SDavid du Colombier long l;
4767edc7532SDavid du Colombier Sym *s;
4777edc7532SDavid du Colombier Auto *u;
4787edc7532SDavid du Colombier
4797edc7532SDavid du Colombier c = p[2];
4807edc7532SDavid du Colombier if(c < 0 || c > NSYM){
4817edc7532SDavid du Colombier print("sym out of range: %d\n", c);
4827edc7532SDavid du Colombier p[0] = ALAST+1;
4837edc7532SDavid du Colombier return 0;
4847edc7532SDavid du Colombier }
4857edc7532SDavid du Colombier a->type = p[0];
4867edc7532SDavid du Colombier a->reg = p[1];
4877edc7532SDavid du Colombier a->sym = h[c];
4887edc7532SDavid du Colombier a->name = p[3];
4897edc7532SDavid du Colombier c = 4;
4907edc7532SDavid du Colombier
4917edc7532SDavid du Colombier if(a->reg < 0 || a->reg > NREG) {
4927edc7532SDavid du Colombier print("register out of range %d\n", a->reg);
4937edc7532SDavid du Colombier p[0] = ALAST+1;
4947edc7532SDavid du Colombier return 0; /* force real diagnostic */
4957edc7532SDavid du Colombier }
4967edc7532SDavid du Colombier
4977edc7532SDavid du Colombier switch(a->type) {
4987edc7532SDavid du Colombier default:
4997edc7532SDavid du Colombier print("unknown type %d\n", a->type);
5007edc7532SDavid du Colombier p[0] = ALAST+1;
5017edc7532SDavid du Colombier return 0; /* force real diagnostic */
5027edc7532SDavid du Colombier
5037edc7532SDavid du Colombier case D_NONE:
5047edc7532SDavid du Colombier case D_REG:
5057edc7532SDavid du Colombier case D_FREG:
5067edc7532SDavid du Colombier case D_MREG:
5077edc7532SDavid du Colombier case D_FCREG:
5087edc7532SDavid du Colombier case D_LO:
5097edc7532SDavid du Colombier case D_HI:
5107edc7532SDavid du Colombier break;
5117edc7532SDavid du Colombier
5127edc7532SDavid du Colombier case D_BRANCH:
5137edc7532SDavid du Colombier case D_OREG:
5147edc7532SDavid du Colombier case D_CONST:
5157edc7532SDavid du Colombier case D_OCONST:
516*f8bc6aafSDavid du Colombier l = p[4] | (p[5]<<8) | (p[6]<<16) | (p[7]<<24);
517*f8bc6aafSDavid du Colombier a->offset = l;
5187edc7532SDavid du Colombier c += 4;
5197edc7532SDavid du Colombier break;
5207edc7532SDavid du Colombier
5217edc7532SDavid du Colombier case D_SCONST:
522*f8bc6aafSDavid du Colombier while(nhunk < NSNAME)
523*f8bc6aafSDavid du Colombier gethunk();
524*f8bc6aafSDavid du Colombier a->sval = (char*)hunk;
525*f8bc6aafSDavid du Colombier nhunk -= NSNAME;
526*f8bc6aafSDavid du Colombier hunk += NSNAME;
527*f8bc6aafSDavid du Colombier
5287edc7532SDavid du Colombier memmove(a->sval, p+4, NSNAME);
5297edc7532SDavid du Colombier c += NSNAME;
5307edc7532SDavid du Colombier break;
5317edc7532SDavid du Colombier
5327edc7532SDavid du Colombier case D_FCONST:
533*f8bc6aafSDavid du Colombier while(nhunk < sizeof(Ieee))
534*f8bc6aafSDavid du Colombier gethunk();
535*f8bc6aafSDavid du Colombier a->ieee = (Ieee*)hunk;
536*f8bc6aafSDavid du Colombier nhunk -= sizeof(Ieee);
537*f8bc6aafSDavid du Colombier hunk += sizeof(Ieee);
538*f8bc6aafSDavid du Colombier
5397edc7532SDavid du Colombier a->ieee->l = p[4] | (p[5]<<8) |
5407edc7532SDavid du Colombier (p[6]<<16) | (p[7]<<24);
5417edc7532SDavid du Colombier a->ieee->h = p[8] | (p[9]<<8) |
5427edc7532SDavid du Colombier (p[10]<<16) | (p[11]<<24);
5437edc7532SDavid du Colombier c += 8;
5447edc7532SDavid du Colombier break;
5457edc7532SDavid du Colombier
5467edc7532SDavid du Colombier case D_VCONST:
547*f8bc6aafSDavid du Colombier l = p[4] | (p[5]<<8) | (p[6]<<16) | (p[7]<<24);
548*f8bc6aafSDavid du Colombier a->offset = (uvlong)l & 0xfffffffful;
549*f8bc6aafSDavid du Colombier l = p[8] | (p[9]<<8) | (p[10]<<16) | (p[11]<<24);
550*f8bc6aafSDavid du Colombier a->offset |= (vlong)l << 32;
5517edc7532SDavid du Colombier c += 8;
552*f8bc6aafSDavid du Colombier a->type = D_CONST;
5537edc7532SDavid du Colombier break;
5547edc7532SDavid du Colombier }
5557edc7532SDavid du Colombier s = a->sym;
5567edc7532SDavid du Colombier if(s == S)
5577edc7532SDavid du Colombier return c;
5587edc7532SDavid du Colombier i = a->name;
5597edc7532SDavid du Colombier if(i != D_AUTO && i != D_PARAM)
5607edc7532SDavid du Colombier return c;
5617edc7532SDavid du Colombier
5627edc7532SDavid du Colombier l = a->offset;
5637edc7532SDavid du Colombier for(u=curauto; u; u=u->link)
5647edc7532SDavid du Colombier if(u->asym == s)
5657edc7532SDavid du Colombier if(u->type == i) {
5667edc7532SDavid du Colombier if(u->aoffset > l)
5677edc7532SDavid du Colombier u->aoffset = l;
5687edc7532SDavid du Colombier return c;
5697edc7532SDavid du Colombier }
5707edc7532SDavid du Colombier
5717edc7532SDavid du Colombier while(nhunk < sizeof(Auto))
5727edc7532SDavid du Colombier gethunk();
5737edc7532SDavid du Colombier u = (Auto*)hunk;
5747edc7532SDavid du Colombier nhunk -= sizeof(Auto);
5757edc7532SDavid du Colombier hunk += sizeof(Auto);
5767edc7532SDavid du Colombier
5777edc7532SDavid du Colombier u->link = curauto;
5787edc7532SDavid du Colombier curauto = u;
5797edc7532SDavid du Colombier u->asym = s;
5807edc7532SDavid du Colombier u->aoffset = l;
5817edc7532SDavid du Colombier u->type = i;
5827edc7532SDavid du Colombier return c;
5837edc7532SDavid du Colombier }
5847edc7532SDavid du Colombier
5857edc7532SDavid du Colombier void
addlib(char * obj)5867edc7532SDavid du Colombier addlib(char *obj)
5877edc7532SDavid du Colombier {
588*f8bc6aafSDavid du Colombier char fn1[LIBNAMELEN], fn2[LIBNAMELEN], comp[LIBNAMELEN], *p, *name;
589*f8bc6aafSDavid du Colombier int i, search;
5907edc7532SDavid du Colombier
5917edc7532SDavid du Colombier if(histfrogp <= 0)
5927edc7532SDavid du Colombier return;
5937edc7532SDavid du Colombier
594*f8bc6aafSDavid du Colombier name = fn1;
595*f8bc6aafSDavid du Colombier search = 0;
5967edc7532SDavid du Colombier if(histfrog[0]->name[1] == '/') {
5977edc7532SDavid du Colombier sprint(name, "");
5987edc7532SDavid du Colombier i = 1;
599*f8bc6aafSDavid du Colombier } else if(histfrog[0]->name[1] == '.') {
6007edc7532SDavid du Colombier sprint(name, ".");
6017edc7532SDavid du Colombier i = 0;
6027edc7532SDavid du Colombier } else {
603*f8bc6aafSDavid du Colombier sprint(name, "");
6047edc7532SDavid du Colombier i = 0;
605*f8bc6aafSDavid du Colombier search = 1;
6067edc7532SDavid du Colombier }
6077edc7532SDavid du Colombier
6087edc7532SDavid du Colombier for(; i<histfrogp; i++) {
6097edc7532SDavid du Colombier snprint(comp, sizeof comp, histfrog[i]->name+1);
6107edc7532SDavid du Colombier for(;;) {
6117edc7532SDavid du Colombier p = strstr(comp, "$O");
6127edc7532SDavid du Colombier if(p == 0)
6137edc7532SDavid du Colombier break;
6147edc7532SDavid du Colombier memmove(p+1, p+2, strlen(p+2)+1);
6157edc7532SDavid du Colombier p[0] = thechar;
6167edc7532SDavid du Colombier }
6177edc7532SDavid du Colombier for(;;) {
6187edc7532SDavid du Colombier p = strstr(comp, "$M");
6197edc7532SDavid du Colombier if(p == 0)
6207edc7532SDavid du Colombier break;
6217edc7532SDavid du Colombier if(strlen(comp)+strlen(thestring)-2+1 >= sizeof comp) {
6227edc7532SDavid du Colombier diag("library component too long");
6237edc7532SDavid du Colombier return;
6247edc7532SDavid du Colombier }
6257edc7532SDavid du Colombier memmove(p+strlen(thestring), p+2, strlen(p+2)+1);
6267edc7532SDavid du Colombier memmove(p, thestring, strlen(thestring));
6277edc7532SDavid du Colombier }
628*f8bc6aafSDavid du Colombier if(strlen(fn1) + strlen(comp) + 3 >= sizeof(fn1)) {
6297edc7532SDavid du Colombier diag("library component too long");
6307edc7532SDavid du Colombier return;
6317edc7532SDavid du Colombier }
632*f8bc6aafSDavid du Colombier if(i > 0 || !search)
633*f8bc6aafSDavid du Colombier strcat(fn1, "/");
634*f8bc6aafSDavid du Colombier strcat(fn1, comp);
6357edc7532SDavid du Colombier }
636*f8bc6aafSDavid du Colombier
637*f8bc6aafSDavid du Colombier cleanname(name);
638*f8bc6aafSDavid du Colombier
639*f8bc6aafSDavid du Colombier if(search){
640*f8bc6aafSDavid du Colombier p = findlib(name);
641*f8bc6aafSDavid du Colombier if(p != nil){
642*f8bc6aafSDavid du Colombier snprint(fn2, sizeof(fn2), "%s/%s", p, name);
643*f8bc6aafSDavid du Colombier name = fn2;
644*f8bc6aafSDavid du Colombier }
645*f8bc6aafSDavid du Colombier }
646*f8bc6aafSDavid du Colombier
6477edc7532SDavid du Colombier for(i=0; i<libraryp; i++)
6487edc7532SDavid du Colombier if(strcmp(name, library[i]) == 0)
6497edc7532SDavid du Colombier return;
6507edc7532SDavid du Colombier if(libraryp == nelem(library)){
6517edc7532SDavid du Colombier diag("too many autolibs; skipping %s", name);
6527edc7532SDavid du Colombier return;
6537edc7532SDavid du Colombier }
6547edc7532SDavid du Colombier
6557edc7532SDavid du Colombier p = malloc(strlen(name) + 1);
6567edc7532SDavid du Colombier strcpy(p, name);
6577edc7532SDavid du Colombier library[libraryp] = p;
6587edc7532SDavid du Colombier p = malloc(strlen(obj) + 1);
6597edc7532SDavid du Colombier strcpy(p, obj);
6607edc7532SDavid du Colombier libraryobj[libraryp] = p;
6617edc7532SDavid du Colombier libraryp++;
6627edc7532SDavid du Colombier }
6637edc7532SDavid du Colombier
6647edc7532SDavid du Colombier void
addhist(long line,int type)6657edc7532SDavid du Colombier addhist(long line, int type)
6667edc7532SDavid du Colombier {
6677edc7532SDavid du Colombier Auto *u;
6687edc7532SDavid du Colombier Sym *s;
6697edc7532SDavid du Colombier int i, j, k;
6707edc7532SDavid du Colombier
6717edc7532SDavid du Colombier u = malloc(sizeof(Auto));
6727edc7532SDavid du Colombier s = malloc(sizeof(Sym));
6737edc7532SDavid du Colombier s->name = malloc(2*(histfrogp+1) + 1);
6747edc7532SDavid du Colombier
6757edc7532SDavid du Colombier u->asym = s;
6767edc7532SDavid du Colombier u->type = type;
6777edc7532SDavid du Colombier u->aoffset = line;
6787edc7532SDavid du Colombier u->link = curhist;
6797edc7532SDavid du Colombier curhist = u;
6807edc7532SDavid du Colombier
6817edc7532SDavid du Colombier j = 1;
6827edc7532SDavid du Colombier for(i=0; i<histfrogp; i++) {
6837edc7532SDavid du Colombier k = histfrog[i]->value;
6847edc7532SDavid du Colombier s->name[j+0] = k>>8;
6857edc7532SDavid du Colombier s->name[j+1] = k;
6867edc7532SDavid du Colombier j += 2;
6877edc7532SDavid du Colombier }
6887edc7532SDavid du Colombier }
6897edc7532SDavid du Colombier
6907edc7532SDavid du Colombier void
histtoauto(void)6917edc7532SDavid du Colombier histtoauto(void)
6927edc7532SDavid du Colombier {
6937edc7532SDavid du Colombier Auto *l;
6947edc7532SDavid du Colombier
6957edc7532SDavid du Colombier while(l = curhist) {
6967edc7532SDavid du Colombier curhist = l->link;
6977edc7532SDavid du Colombier l->link = curauto;
6987edc7532SDavid du Colombier curauto = l;
6997edc7532SDavid du Colombier }
7007edc7532SDavid du Colombier }
7017edc7532SDavid du Colombier
7027edc7532SDavid du Colombier void
collapsefrog(Sym * s)7037edc7532SDavid du Colombier collapsefrog(Sym *s)
7047edc7532SDavid du Colombier {
7057edc7532SDavid du Colombier int i;
7067edc7532SDavid du Colombier
7077edc7532SDavid du Colombier /*
7087edc7532SDavid du Colombier * bad encoding of path components only allows
7097edc7532SDavid du Colombier * MAXHIST components. if there is an overflow,
7107edc7532SDavid du Colombier * first try to collapse xxx/..
7117edc7532SDavid du Colombier */
7127edc7532SDavid du Colombier for(i=1; i<histfrogp; i++)
7137edc7532SDavid du Colombier if(strcmp(histfrog[i]->name+1, "..") == 0) {
7147edc7532SDavid du Colombier memmove(histfrog+i-1, histfrog+i+1,
7157edc7532SDavid du Colombier (histfrogp-i-1)*sizeof(histfrog[0]));
7167edc7532SDavid du Colombier histfrogp--;
7177edc7532SDavid du Colombier goto out;
7187edc7532SDavid du Colombier }
7197edc7532SDavid du Colombier
7207edc7532SDavid du Colombier /*
7217edc7532SDavid du Colombier * next try to collapse .
7227edc7532SDavid du Colombier */
7237edc7532SDavid du Colombier for(i=0; i<histfrogp; i++)
7247edc7532SDavid du Colombier if(strcmp(histfrog[i]->name+1, ".") == 0) {
7257edc7532SDavid du Colombier memmove(histfrog+i, histfrog+i+1,
7267edc7532SDavid du Colombier (histfrogp-i-1)*sizeof(histfrog[0]));
7277edc7532SDavid du Colombier goto out;
7287edc7532SDavid du Colombier }
7297edc7532SDavid du Colombier
7307edc7532SDavid du Colombier /*
7317edc7532SDavid du Colombier * last chance, just truncate from front
7327edc7532SDavid du Colombier */
7337edc7532SDavid du Colombier memmove(histfrog+0, histfrog+1,
7347edc7532SDavid du Colombier (histfrogp-1)*sizeof(histfrog[0]));
7357edc7532SDavid du Colombier
7367edc7532SDavid du Colombier out:
7377edc7532SDavid du Colombier histfrog[histfrogp-1] = s;
7387edc7532SDavid du Colombier }
7397edc7532SDavid du Colombier
7407edc7532SDavid du Colombier void
nopout(Prog * p)7417edc7532SDavid du Colombier nopout(Prog *p)
7427edc7532SDavid du Colombier {
7437edc7532SDavid du Colombier p->as = ANOP;
7447edc7532SDavid du Colombier p->from.type = D_NONE;
7457edc7532SDavid du Colombier p->to.type = D_NONE;
7467edc7532SDavid du Colombier }
7477edc7532SDavid du Colombier
7487edc7532SDavid du Colombier uchar*
readsome(int f,uchar * buf,uchar * good,uchar * stop,int max)7497edc7532SDavid du Colombier readsome(int f, uchar *buf, uchar *good, uchar *stop, int max)
7507edc7532SDavid du Colombier {
7517edc7532SDavid du Colombier int n;
7527edc7532SDavid du Colombier
7537edc7532SDavid du Colombier n = stop - good;
7547edc7532SDavid du Colombier memmove(buf, good, stop - good);
7557edc7532SDavid du Colombier stop = buf + n;
7567edc7532SDavid du Colombier n = MAXIO - n;
7577edc7532SDavid du Colombier if(n > max)
7587edc7532SDavid du Colombier n = max;
7597edc7532SDavid du Colombier n = read(f, stop, n);
7607edc7532SDavid du Colombier if(n <= 0)
7617edc7532SDavid du Colombier return 0;
7627edc7532SDavid du Colombier return stop + n;
7637edc7532SDavid du Colombier }
7647edc7532SDavid du Colombier
7657edc7532SDavid du Colombier void
ldobj(int f,long c,char * pn)7667edc7532SDavid du Colombier ldobj(int f, long c, char *pn)
7677edc7532SDavid du Colombier {
7687edc7532SDavid du Colombier vlong ipc;
7697edc7532SDavid du Colombier Prog *p, *t;
7707edc7532SDavid du Colombier uchar *bloc, *bsize, *stop;
7717edc7532SDavid du Colombier Sym *h[NSYM], *s, *di;
7727edc7532SDavid du Colombier int v, o, r, skip;
7737edc7532SDavid du Colombier
7747edc7532SDavid du Colombier bsize = buf.xbuf;
7757edc7532SDavid du Colombier bloc = buf.xbuf;
7767edc7532SDavid du Colombier di = S;
7777edc7532SDavid du Colombier
7787edc7532SDavid du Colombier newloop:
7797edc7532SDavid du Colombier memset(h, 0, sizeof(h));
7807edc7532SDavid du Colombier version++;
7817edc7532SDavid du Colombier histfrogp = 0;
7827edc7532SDavid du Colombier ipc = pc;
7837edc7532SDavid du Colombier skip = 0;
7847edc7532SDavid du Colombier
7857edc7532SDavid du Colombier loop:
7867edc7532SDavid du Colombier if(c <= 0)
7877edc7532SDavid du Colombier goto eof;
7887edc7532SDavid du Colombier r = bsize - bloc;
7897edc7532SDavid du Colombier if(r < 100 && r < c) { /* enough for largest prog */
7907edc7532SDavid du Colombier bsize = readsome(f, buf.xbuf, bloc, bsize, c);
7917edc7532SDavid du Colombier if(bsize == 0)
7927edc7532SDavid du Colombier goto eof;
7937edc7532SDavid du Colombier bloc = buf.xbuf;
7947edc7532SDavid du Colombier goto loop;
7957edc7532SDavid du Colombier }
7967edc7532SDavid du Colombier o = bloc[0]; /* as */
7977edc7532SDavid du Colombier if(o <= AXXX || o >= ALAST) {
798*f8bc6aafSDavid du Colombier diag("%s: line %lld: opcode out of range %d", pn, pc-ipc, o);
799*f8bc6aafSDavid du Colombier print(" probably not a .%c file\n", thechar);
8007edc7532SDavid du Colombier errorexit();
8017edc7532SDavid du Colombier }
802*f8bc6aafSDavid du Colombier if(o == ANAME || o == ASIGNAME) {
803*f8bc6aafSDavid du Colombier if(o == ASIGNAME) {
804*f8bc6aafSDavid du Colombier bloc += 4;
805*f8bc6aafSDavid du Colombier c -= 4;
806*f8bc6aafSDavid du Colombier }
8077edc7532SDavid du Colombier stop = memchr(&bloc[3], 0, bsize-&bloc[3]);
8087edc7532SDavid du Colombier if(stop == 0){
8097edc7532SDavid du Colombier bsize = readsome(f, buf.xbuf, bloc, bsize, c);
8107edc7532SDavid du Colombier if(bsize == 0)
8117edc7532SDavid du Colombier goto eof;
8127edc7532SDavid du Colombier bloc = buf.xbuf;
8137edc7532SDavid du Colombier stop = memchr(&bloc[3], 0, bsize-&bloc[3]);
8147edc7532SDavid du Colombier if(stop == 0){
8157edc7532SDavid du Colombier fprint(2, "%s: name too long\n", pn);
8167edc7532SDavid du Colombier errorexit();
8177edc7532SDavid du Colombier }
8187edc7532SDavid du Colombier }
8197edc7532SDavid du Colombier v = bloc[1]; /* type */
8207edc7532SDavid du Colombier o = bloc[2]; /* sym */
8217edc7532SDavid du Colombier bloc += 3;
8227edc7532SDavid du Colombier c -= 3;
8237edc7532SDavid du Colombier
8247edc7532SDavid du Colombier r = 0;
8257edc7532SDavid du Colombier if(v == D_STATIC)
8267edc7532SDavid du Colombier r = version;
8277edc7532SDavid du Colombier s = lookup((char*)bloc, r);
8287edc7532SDavid du Colombier c -= &stop[1] - bloc;
8297edc7532SDavid du Colombier bloc = stop + 1;
8307edc7532SDavid du Colombier
8317edc7532SDavid du Colombier if(debug['W'])
8327edc7532SDavid du Colombier print(" ANAME %s\n", s->name);
8337edc7532SDavid du Colombier h[o] = s;
8347edc7532SDavid du Colombier if((v == D_EXTERN || v == D_STATIC) && s->type == 0)
8357edc7532SDavid du Colombier s->type = SXREF;
8367edc7532SDavid du Colombier if(v == D_FILE) {
8377edc7532SDavid du Colombier if(s->type != SFILE) {
8387edc7532SDavid du Colombier histgen++;
8397edc7532SDavid du Colombier s->type = SFILE;
8407edc7532SDavid du Colombier s->value = histgen;
8417edc7532SDavid du Colombier }
8427edc7532SDavid du Colombier if(histfrogp < MAXHIST) {
8437edc7532SDavid du Colombier histfrog[histfrogp] = s;
8447edc7532SDavid du Colombier histfrogp++;
8457edc7532SDavid du Colombier } else
8467edc7532SDavid du Colombier collapsefrog(s);
8477edc7532SDavid du Colombier }
8487edc7532SDavid du Colombier goto loop;
8497edc7532SDavid du Colombier }
8507edc7532SDavid du Colombier
8517edc7532SDavid du Colombier if(nhunk < sizeof(Prog))
8527edc7532SDavid du Colombier gethunk();
8537edc7532SDavid du Colombier p = (Prog*)hunk;
8547edc7532SDavid du Colombier nhunk -= sizeof(Prog);
8557edc7532SDavid du Colombier hunk += sizeof(Prog);
8567edc7532SDavid du Colombier
8577edc7532SDavid du Colombier p->as = o;
8587edc7532SDavid du Colombier p->reg = bloc[1] & 0x7f;
8597edc7532SDavid du Colombier if(bloc[1] & 0x80)
8607edc7532SDavid du Colombier p->mark = NOSCHED;
8617edc7532SDavid du Colombier p->line = bloc[2] | (bloc[3]<<8) | (bloc[4]<<16) | (bloc[5]<<24);
8627edc7532SDavid du Colombier
8637edc7532SDavid du Colombier r = zaddr(bloc+6, &p->from, h) + 6;
8647edc7532SDavid du Colombier r += zaddr(bloc+r, &p->to, h);
8657edc7532SDavid du Colombier bloc += r;
8667edc7532SDavid du Colombier c -= r;
8677edc7532SDavid du Colombier
8687edc7532SDavid du Colombier if(p->reg < 0 || p->reg > NREG)
8697edc7532SDavid du Colombier diag("register out of range %d", p->reg);
8707edc7532SDavid du Colombier
8717edc7532SDavid du Colombier p->link = P;
8727edc7532SDavid du Colombier p->cond = P;
8737edc7532SDavid du Colombier
8747edc7532SDavid du Colombier if(debug['W'])
8757edc7532SDavid du Colombier print("%P\n", p);
8767edc7532SDavid du Colombier
8777edc7532SDavid du Colombier switch(o) {
8787edc7532SDavid du Colombier case AHISTORY:
8797edc7532SDavid du Colombier if(p->to.offset == -1) {
8807edc7532SDavid du Colombier addlib(pn);
8817edc7532SDavid du Colombier histfrogp = 0;
8827edc7532SDavid du Colombier goto loop;
8837edc7532SDavid du Colombier }
8847edc7532SDavid du Colombier addhist(p->line, D_FILE); /* 'z' */
8857edc7532SDavid du Colombier if(p->to.offset)
8867edc7532SDavid du Colombier addhist(p->to.offset, D_FILE1); /* 'Z' */
8877edc7532SDavid du Colombier histfrogp = 0;
8887edc7532SDavid du Colombier goto loop;
8897edc7532SDavid du Colombier
8907edc7532SDavid du Colombier case AEND:
8917edc7532SDavid du Colombier histtoauto();
8927edc7532SDavid du Colombier if(curtext != P)
8937edc7532SDavid du Colombier curtext->to.autom = curauto;
8947edc7532SDavid du Colombier curauto = 0;
8957edc7532SDavid du Colombier curtext = P;
8967edc7532SDavid du Colombier if(c)
8977edc7532SDavid du Colombier goto newloop;
8987edc7532SDavid du Colombier return;
8997edc7532SDavid du Colombier
9007edc7532SDavid du Colombier case AGLOBL:
9017edc7532SDavid du Colombier s = p->from.sym;
9027edc7532SDavid du Colombier if(s == S) {
9037edc7532SDavid du Colombier diag("GLOBL must have a name\n%P", p);
9047edc7532SDavid du Colombier errorexit();
9057edc7532SDavid du Colombier }
9067edc7532SDavid du Colombier if(s->type == 0 || s->type == SXREF) {
9077edc7532SDavid du Colombier s->type = SBSS;
9087edc7532SDavid du Colombier s->value = 0;
9097edc7532SDavid du Colombier }
9107edc7532SDavid du Colombier if(s->type != SBSS) {
9117edc7532SDavid du Colombier diag("redefinition: %s\n%P", s->name, p);
9127edc7532SDavid du Colombier s->type = SBSS;
9137edc7532SDavid du Colombier s->value = 0;
9147edc7532SDavid du Colombier }
9157edc7532SDavid du Colombier if(p->to.offset > s->value)
9167edc7532SDavid du Colombier s->value = p->to.offset;
9177edc7532SDavid du Colombier break;
9187edc7532SDavid du Colombier
9197edc7532SDavid du Colombier case ADYNT:
9207edc7532SDavid du Colombier if(p->to.sym == S) {
9217edc7532SDavid du Colombier diag("DYNT without a sym\n%P", p);
9227edc7532SDavid du Colombier break;
9237edc7532SDavid du Colombier }
9247edc7532SDavid du Colombier di = p->to.sym;
9257edc7532SDavid du Colombier p->reg = 4;
9267edc7532SDavid du Colombier if(di->type == SXREF) {
9277edc7532SDavid du Colombier if(debug['z'])
9287edc7532SDavid du Colombier Bprint(&bso, "%P set to %d\n", p, dtype);
9297edc7532SDavid du Colombier di->type = SCONST;
9307edc7532SDavid du Colombier di->value = dtype;
9317edc7532SDavid du Colombier dtype += 4;
9327edc7532SDavid du Colombier }
9337edc7532SDavid du Colombier if(p->from.sym == S)
9347edc7532SDavid du Colombier break;
9357edc7532SDavid du Colombier
9367edc7532SDavid du Colombier p->from.offset = di->value;
9377edc7532SDavid du Colombier p->from.sym->type = SDATA;
9387edc7532SDavid du Colombier if(curtext == P) {
9397edc7532SDavid du Colombier diag("DYNT not in text: %P", p);
9407edc7532SDavid du Colombier break;
9417edc7532SDavid du Colombier }
9427edc7532SDavid du Colombier p->to.sym = curtext->from.sym;
9437edc7532SDavid du Colombier p->to.type = D_CONST;
9447edc7532SDavid du Colombier p->link = datap;
9457edc7532SDavid du Colombier datap = p;
9467edc7532SDavid du Colombier break;
9477edc7532SDavid du Colombier
9487edc7532SDavid du Colombier case AINIT:
9497edc7532SDavid du Colombier if(p->from.sym == S) {
9507edc7532SDavid du Colombier diag("INIT without a sym\n%P", p);
9517edc7532SDavid du Colombier break;
9527edc7532SDavid du Colombier }
9537edc7532SDavid du Colombier if(di == S) {
9547edc7532SDavid du Colombier diag("INIT without previous DYNT\n%P", p);
9557edc7532SDavid du Colombier break;
9567edc7532SDavid du Colombier }
9577edc7532SDavid du Colombier p->from.offset = di->value;
9587edc7532SDavid du Colombier p->from.sym->type = SDATA;
9597edc7532SDavid du Colombier p->link = datap;
9607edc7532SDavid du Colombier datap = p;
9617edc7532SDavid du Colombier break;
9627edc7532SDavid du Colombier
9637edc7532SDavid du Colombier case ADATA:
9647edc7532SDavid du Colombier if(p->from.sym == S) {
9657edc7532SDavid du Colombier diag("DATA without a sym\n%P", p);
9667edc7532SDavid du Colombier break;
9677edc7532SDavid du Colombier }
9687edc7532SDavid du Colombier p->link = datap;
9697edc7532SDavid du Colombier datap = p;
9707edc7532SDavid du Colombier break;
9717edc7532SDavid du Colombier
9727edc7532SDavid du Colombier case AGOK:
9737edc7532SDavid du Colombier diag("unknown opcode\n%P", p);
9747edc7532SDavid du Colombier p->pc = pc;
9757edc7532SDavid du Colombier pc++;
9767edc7532SDavid du Colombier break;
9777edc7532SDavid du Colombier
9787edc7532SDavid du Colombier case ATEXT:
9797edc7532SDavid du Colombier if(curtext != P) {
9807edc7532SDavid du Colombier histtoauto();
9817edc7532SDavid du Colombier curtext->to.autom = curauto;
9827edc7532SDavid du Colombier curauto = 0;
9837edc7532SDavid du Colombier }
9847edc7532SDavid du Colombier skip = 0;
9857edc7532SDavid du Colombier curtext = p;
9867edc7532SDavid du Colombier s = p->from.sym;
9877edc7532SDavid du Colombier if(s == S) {
9887edc7532SDavid du Colombier diag("TEXT must have a name\n%P", p);
9897edc7532SDavid du Colombier errorexit();
9907edc7532SDavid du Colombier }
9917edc7532SDavid du Colombier autosize = p->to.offset;
9927edc7532SDavid du Colombier if(autosize & 7) {
9937edc7532SDavid du Colombier diag("stack frame not 8 multiple: %s\n%P", s->name, p);
9947edc7532SDavid du Colombier autosize = autosize + 7 & ~7;
9957edc7532SDavid du Colombier p->to.offset = autosize;
9967edc7532SDavid du Colombier }
9977edc7532SDavid du Colombier autosize += 8;
9987edc7532SDavid du Colombier if(s->type != 0 && s->type != SXREF) {
9997edc7532SDavid du Colombier if(p->reg & DUPOK) {
10007edc7532SDavid du Colombier skip = 1;
10017edc7532SDavid du Colombier goto casedef;
10027edc7532SDavid du Colombier }
10037edc7532SDavid du Colombier diag("redefinition: %s\n%P", s->name, p);
10047edc7532SDavid du Colombier }
10057edc7532SDavid du Colombier s->type = STEXT;
10067edc7532SDavid du Colombier s->value = pc;
10077edc7532SDavid du Colombier lastp->link = p;
10087edc7532SDavid du Colombier lastp = p;
10097edc7532SDavid du Colombier p->pc = pc;
10107edc7532SDavid du Colombier pc++;
10117edc7532SDavid du Colombier if(textp == P) {
10127edc7532SDavid du Colombier textp = p;
10137edc7532SDavid du Colombier etextp = p;
10147edc7532SDavid du Colombier goto loop;
10157edc7532SDavid du Colombier }
10167edc7532SDavid du Colombier etextp->cond = p;
10177edc7532SDavid du Colombier etextp = p;
10187edc7532SDavid du Colombier break;
10197edc7532SDavid du Colombier
10207edc7532SDavid du Colombier case ASUB:
10217edc7532SDavid du Colombier case ASUBU:
10227edc7532SDavid du Colombier if(p->from.type == D_CONST)
10237edc7532SDavid du Colombier if(p->from.name == D_NONE) {
10247edc7532SDavid du Colombier p->from.offset = -p->from.offset;
10257edc7532SDavid du Colombier if(p->as == ASUB)
10267edc7532SDavid du Colombier p->as = AADD;
10277edc7532SDavid du Colombier else
10287edc7532SDavid du Colombier p->as = AADDU;
10297edc7532SDavid du Colombier }
10307edc7532SDavid du Colombier goto casedef;
10317edc7532SDavid du Colombier
1032*f8bc6aafSDavid du Colombier case ASUBV:
1033*f8bc6aafSDavid du Colombier case ASUBVU:
1034*f8bc6aafSDavid du Colombier if(p->from.type == D_CONST)
1035*f8bc6aafSDavid du Colombier if(p->from.name == D_NONE) {
1036*f8bc6aafSDavid du Colombier p->from.offset = -p->from.offset;
1037*f8bc6aafSDavid du Colombier if(p->as == ASUBV)
1038*f8bc6aafSDavid du Colombier p->as = AADDV;
1039*f8bc6aafSDavid du Colombier else
1040*f8bc6aafSDavid du Colombier p->as = AADDVU;
1041*f8bc6aafSDavid du Colombier }
1042*f8bc6aafSDavid du Colombier goto casedef;
1043*f8bc6aafSDavid du Colombier
10447edc7532SDavid du Colombier case AMOVF:
10457edc7532SDavid du Colombier if(skip)
10467edc7532SDavid du Colombier goto casedef;
10477edc7532SDavid du Colombier
10487edc7532SDavid du Colombier if(p->from.type == D_FCONST) {
10497edc7532SDavid du Colombier /* size sb 9 max */
10507edc7532SDavid du Colombier sprint(literal, "$%lux", ieeedtof(p->from.ieee));
10517edc7532SDavid du Colombier s = lookup(literal, 0);
10527edc7532SDavid du Colombier if(s->type == 0) {
10537edc7532SDavid du Colombier s->type = SBSS;
10547edc7532SDavid du Colombier s->value = 4;
10557edc7532SDavid du Colombier t = prg();
10567edc7532SDavid du Colombier t->as = ADATA;
10577edc7532SDavid du Colombier t->line = p->line;
10587edc7532SDavid du Colombier t->from.type = D_OREG;
10597edc7532SDavid du Colombier t->from.sym = s;
10607edc7532SDavid du Colombier t->from.name = D_EXTERN;
10617edc7532SDavid du Colombier t->reg = 4;
10627edc7532SDavid du Colombier t->to = p->from;
10637edc7532SDavid du Colombier t->link = datap;
10647edc7532SDavid du Colombier datap = t;
10657edc7532SDavid du Colombier }
10667edc7532SDavid du Colombier p->from.type = D_OREG;
10677edc7532SDavid du Colombier p->from.sym = s;
10687edc7532SDavid du Colombier p->from.name = D_EXTERN;
10697edc7532SDavid du Colombier p->from.offset = 0;
10707edc7532SDavid du Colombier }
10717edc7532SDavid du Colombier goto casedef;
10727edc7532SDavid du Colombier
10737edc7532SDavid du Colombier case AMOVD:
10747edc7532SDavid du Colombier if(skip)
10757edc7532SDavid du Colombier goto casedef;
10767edc7532SDavid du Colombier
10777edc7532SDavid du Colombier if(p->from.type == D_FCONST) {
10787edc7532SDavid du Colombier /* size sb 18 max */
10797edc7532SDavid du Colombier sprint(literal, "$%lux.%lux",
1080*f8bc6aafSDavid du Colombier p->from.ieee->l, p->from.ieee->h);
10817edc7532SDavid du Colombier s = lookup(literal, 0);
10827edc7532SDavid du Colombier if(s->type == 0) {
10837edc7532SDavid du Colombier s->type = SBSS;
10847edc7532SDavid du Colombier s->value = 8;
10857edc7532SDavid du Colombier t = prg();
10867edc7532SDavid du Colombier t->as = ADATA;
10877edc7532SDavid du Colombier t->line = p->line;
10887edc7532SDavid du Colombier t->from.type = D_OREG;
10897edc7532SDavid du Colombier t->from.sym = s;
10907edc7532SDavid du Colombier t->from.name = D_EXTERN;
10917edc7532SDavid du Colombier t->reg = 8;
10927edc7532SDavid du Colombier t->to = p->from;
10937edc7532SDavid du Colombier t->link = datap;
10947edc7532SDavid du Colombier datap = t;
10957edc7532SDavid du Colombier }
10967edc7532SDavid du Colombier p->from.type = D_OREG;
10977edc7532SDavid du Colombier p->from.sym = s;
10987edc7532SDavid du Colombier p->from.name = D_EXTERN;
10997edc7532SDavid du Colombier p->from.offset = 0;
11007edc7532SDavid du Colombier }
11017edc7532SDavid du Colombier goto casedef;
11027edc7532SDavid du Colombier
11037edc7532SDavid du Colombier case AMOVV:
11047edc7532SDavid du Colombier if(skip)
11057edc7532SDavid du Colombier goto casedef;
11067edc7532SDavid du Colombier
1107*f8bc6aafSDavid du Colombier if(p->from.type == D_CONST)
1108*f8bc6aafSDavid du Colombier if(!isint32(p->from.offset)) {
11097edc7532SDavid du Colombier /* size sb 18 max */
1110*f8bc6aafSDavid du Colombier sprint(literal, "$%llux", p->from.offset);
11117edc7532SDavid du Colombier s = lookup(literal, 0);
11127edc7532SDavid du Colombier if(s->type == 0) {
11137edc7532SDavid du Colombier s->type = SBSS;
11147edc7532SDavid du Colombier s->value = 8;
11157edc7532SDavid du Colombier t = prg();
11167edc7532SDavid du Colombier t->as = ADATA;
11177edc7532SDavid du Colombier t->line = p->line;
11187edc7532SDavid du Colombier t->from.type = D_OREG;
11197edc7532SDavid du Colombier t->from.sym = s;
11207edc7532SDavid du Colombier t->from.name = D_EXTERN;
11217edc7532SDavid du Colombier t->reg = 8;
11227edc7532SDavid du Colombier t->to = p->from;
11237edc7532SDavid du Colombier t->link = datap;
11247edc7532SDavid du Colombier datap = t;
11257edc7532SDavid du Colombier }
11267edc7532SDavid du Colombier p->from.type = D_OREG;
11277edc7532SDavid du Colombier p->from.sym = s;
11287edc7532SDavid du Colombier p->from.name = D_EXTERN;
11297edc7532SDavid du Colombier p->from.offset = 0;
11307edc7532SDavid du Colombier }
11317edc7532SDavid du Colombier goto casedef;
11327edc7532SDavid du Colombier
11337edc7532SDavid du Colombier default:
11347edc7532SDavid du Colombier casedef:
11357edc7532SDavid du Colombier if(skip)
11367edc7532SDavid du Colombier nopout(p);
11377edc7532SDavid du Colombier
11387edc7532SDavid du Colombier if(p->to.type == D_BRANCH)
11397edc7532SDavid du Colombier p->to.offset += ipc;
11407edc7532SDavid du Colombier lastp->link = p;
11417edc7532SDavid du Colombier lastp = p;
11427edc7532SDavid du Colombier p->pc = pc;
11437edc7532SDavid du Colombier pc++;
11447edc7532SDavid du Colombier break;
11457edc7532SDavid du Colombier }
11467edc7532SDavid du Colombier goto loop;
11477edc7532SDavid du Colombier
11487edc7532SDavid du Colombier eof:
11497edc7532SDavid du Colombier diag("truncated object file: %s", pn);
11507edc7532SDavid du Colombier }
11517edc7532SDavid du Colombier
11527edc7532SDavid du Colombier Sym*
lookup(char * symb,int v)11537edc7532SDavid du Colombier lookup(char *symb, int v)
11547edc7532SDavid du Colombier {
11557edc7532SDavid du Colombier Sym *s;
11567edc7532SDavid du Colombier char *p;
11577edc7532SDavid du Colombier long h;
11587edc7532SDavid du Colombier int c, l;
11597edc7532SDavid du Colombier
11607edc7532SDavid du Colombier h = v;
11617edc7532SDavid du Colombier for(p=symb; c = *p; p++)
11627edc7532SDavid du Colombier h = h+h+h + c;
11637edc7532SDavid du Colombier l = (p - symb) + 1;
11647edc7532SDavid du Colombier if(h < 0)
11657edc7532SDavid du Colombier h = ~h;
1166*f8bc6aafSDavid du Colombier h &= 0xffffff; // XXX
11677edc7532SDavid du Colombier h %= NHASH;
11687edc7532SDavid du Colombier for(s = hash[h]; s != S; s = s->link)
11697edc7532SDavid du Colombier if(s->version == v)
11707edc7532SDavid du Colombier if(memcmp(s->name, symb, l) == 0)
11717edc7532SDavid du Colombier return s;
11727edc7532SDavid du Colombier
11737edc7532SDavid du Colombier while(nhunk < sizeof(Sym))
11747edc7532SDavid du Colombier gethunk();
11757edc7532SDavid du Colombier s = (Sym*)hunk;
11767edc7532SDavid du Colombier nhunk -= sizeof(Sym);
11777edc7532SDavid du Colombier hunk += sizeof(Sym);
11787edc7532SDavid du Colombier
11797edc7532SDavid du Colombier s->name = malloc(l);
11807edc7532SDavid du Colombier memmove(s->name, symb, l);
11817edc7532SDavid du Colombier
11827edc7532SDavid du Colombier s->link = hash[h];
11837edc7532SDavid du Colombier s->type = 0;
11847edc7532SDavid du Colombier s->version = v;
11857edc7532SDavid du Colombier s->value = 0;
11867edc7532SDavid du Colombier hash[h] = s;
11877edc7532SDavid du Colombier return s;
11887edc7532SDavid du Colombier }
11897edc7532SDavid du Colombier
11907edc7532SDavid du Colombier Prog*
prg(void)11917edc7532SDavid du Colombier prg(void)
11927edc7532SDavid du Colombier {
11937edc7532SDavid du Colombier Prog *p;
11947edc7532SDavid du Colombier
11957edc7532SDavid du Colombier while(nhunk < sizeof(Prog))
11967edc7532SDavid du Colombier gethunk();
11977edc7532SDavid du Colombier p = (Prog*)hunk;
11987edc7532SDavid du Colombier nhunk -= sizeof(Prog);
11997edc7532SDavid du Colombier hunk += sizeof(Prog);
12007edc7532SDavid du Colombier
12017edc7532SDavid du Colombier *p = zprg;
12027edc7532SDavid du Colombier return p;
12037edc7532SDavid du Colombier }
12047edc7532SDavid du Colombier
12057edc7532SDavid du Colombier void
gethunk(void)12067edc7532SDavid du Colombier gethunk(void)
12077edc7532SDavid du Colombier {
12087edc7532SDavid du Colombier char *h;
12097edc7532SDavid du Colombier long nh;
12107edc7532SDavid du Colombier
12117edc7532SDavid du Colombier nh = NHUNK;
12127edc7532SDavid du Colombier if(thunk >= 5L*NHUNK) {
12137edc7532SDavid du Colombier nh = 5L*NHUNK;
12147edc7532SDavid du Colombier if(thunk >= 25L*NHUNK)
12157edc7532SDavid du Colombier nh = 25L*NHUNK;
12167edc7532SDavid du Colombier }
12177edc7532SDavid du Colombier h = mysbrk(nh);
12187edc7532SDavid du Colombier if(h == (char*)-1) {
12197edc7532SDavid du Colombier diag("out of memory");
12207edc7532SDavid du Colombier errorexit();
12217edc7532SDavid du Colombier }
12227edc7532SDavid du Colombier hunk = h;
12237edc7532SDavid du Colombier nhunk = nh;
12247edc7532SDavid du Colombier thunk += nh;
12257edc7532SDavid du Colombier }
12267edc7532SDavid du Colombier
12277edc7532SDavid du Colombier void
doprof1(void)12287edc7532SDavid du Colombier doprof1(void)
12297edc7532SDavid du Colombier {
12307edc7532SDavid du Colombier Sym *s;
12317edc7532SDavid du Colombier long n;
12327edc7532SDavid du Colombier Prog *p, *q;
12337edc7532SDavid du Colombier
12347edc7532SDavid du Colombier if(debug['v'])
12357edc7532SDavid du Colombier Bprint(&bso, "%5.2f profile 1\n", cputime());
12367edc7532SDavid du Colombier Bflush(&bso);
12377edc7532SDavid du Colombier s = lookup("__mcount", 0);
12387edc7532SDavid du Colombier n = 1;
12397edc7532SDavid du Colombier for(p = firstp->link; p != P; p = p->link) {
12407edc7532SDavid du Colombier if(p->as == ATEXT) {
12417edc7532SDavid du Colombier q = prg();
12427edc7532SDavid du Colombier q->line = p->line;
12437edc7532SDavid du Colombier q->link = datap;
12447edc7532SDavid du Colombier datap = q;
12457edc7532SDavid du Colombier q->as = ADATA;
12467edc7532SDavid du Colombier q->from.type = D_OREG;
12477edc7532SDavid du Colombier q->from.name = D_EXTERN;
12487edc7532SDavid du Colombier q->from.offset = n*4;
12497edc7532SDavid du Colombier q->from.sym = s;
12507edc7532SDavid du Colombier q->reg = 4;
12517edc7532SDavid du Colombier q->to = p->from;
12527edc7532SDavid du Colombier q->to.type = D_CONST;
12537edc7532SDavid du Colombier
12547edc7532SDavid du Colombier q = prg();
12557edc7532SDavid du Colombier q->line = p->line;
12567edc7532SDavid du Colombier q->pc = p->pc;
12577edc7532SDavid du Colombier q->link = p->link;
12587edc7532SDavid du Colombier p->link = q;
12597edc7532SDavid du Colombier p = q;
12607edc7532SDavid du Colombier p->as = AMOVW;
12617edc7532SDavid du Colombier p->from.type = D_OREG;
12627edc7532SDavid du Colombier p->from.name = D_EXTERN;
12637edc7532SDavid du Colombier p->from.sym = s;
12647edc7532SDavid du Colombier p->from.offset = n*4 + 4;
12657edc7532SDavid du Colombier p->to.type = D_REG;
12667edc7532SDavid du Colombier p->to.reg = REGTMP;
12677edc7532SDavid du Colombier
12687edc7532SDavid du Colombier q = prg();
12697edc7532SDavid du Colombier q->line = p->line;
12707edc7532SDavid du Colombier q->pc = p->pc;
12717edc7532SDavid du Colombier q->link = p->link;
12727edc7532SDavid du Colombier p->link = q;
12737edc7532SDavid du Colombier p = q;
12747edc7532SDavid du Colombier p->as = AADDU;
12757edc7532SDavid du Colombier p->from.type = D_CONST;
12767edc7532SDavid du Colombier p->from.offset = 1;
12777edc7532SDavid du Colombier p->to.type = D_REG;
12787edc7532SDavid du Colombier p->to.reg = REGTMP;
12797edc7532SDavid du Colombier
12807edc7532SDavid du Colombier q = prg();
12817edc7532SDavid du Colombier q->line = p->line;
12827edc7532SDavid du Colombier q->pc = p->pc;
12837edc7532SDavid du Colombier q->link = p->link;
12847edc7532SDavid du Colombier p->link = q;
12857edc7532SDavid du Colombier p = q;
12867edc7532SDavid du Colombier p->as = AMOVW;
12877edc7532SDavid du Colombier p->from.type = D_REG;
12887edc7532SDavid du Colombier p->from.reg = REGTMP;
12897edc7532SDavid du Colombier p->to.type = D_OREG;
12907edc7532SDavid du Colombier p->to.name = D_EXTERN;
12917edc7532SDavid du Colombier p->to.sym = s;
12927edc7532SDavid du Colombier p->to.offset = n*4 + 4;
12937edc7532SDavid du Colombier
12947edc7532SDavid du Colombier n += 2;
12957edc7532SDavid du Colombier continue;
12967edc7532SDavid du Colombier }
12977edc7532SDavid du Colombier }
12987edc7532SDavid du Colombier q = prg();
12997edc7532SDavid du Colombier q->line = 0;
13007edc7532SDavid du Colombier q->link = datap;
13017edc7532SDavid du Colombier datap = q;
13027edc7532SDavid du Colombier
13037edc7532SDavid du Colombier q->as = ADATA;
13047edc7532SDavid du Colombier q->from.type = D_OREG;
13057edc7532SDavid du Colombier q->from.name = D_EXTERN;
13067edc7532SDavid du Colombier q->from.sym = s;
13077edc7532SDavid du Colombier q->reg = 4;
13087edc7532SDavid du Colombier q->to.type = D_CONST;
13097edc7532SDavid du Colombier q->to.offset = n;
13107edc7532SDavid du Colombier
13117edc7532SDavid du Colombier s->type = SBSS;
13127edc7532SDavid du Colombier s->value = n*4;
13137edc7532SDavid du Colombier }
13147edc7532SDavid du Colombier
13157edc7532SDavid du Colombier void
doprof2(void)13167edc7532SDavid du Colombier doprof2(void)
13177edc7532SDavid du Colombier {
13187edc7532SDavid du Colombier Sym *s2, *s4;
1319*f8bc6aafSDavid du Colombier Prog *p, *q, *q2, *ps2, *ps4;
13207edc7532SDavid du Colombier
13217edc7532SDavid du Colombier if(debug['v'])
13227edc7532SDavid du Colombier Bprint(&bso, "%5.2f profile 2\n", cputime());
13237edc7532SDavid du Colombier Bflush(&bso);
1324*f8bc6aafSDavid du Colombier
1325*f8bc6aafSDavid du Colombier if(debug['e']){
1326*f8bc6aafSDavid du Colombier s2 = lookup("_tracein", 0);
1327*f8bc6aafSDavid du Colombier s4 = lookup("_traceout", 0);
1328*f8bc6aafSDavid du Colombier }else{
13297edc7532SDavid du Colombier s2 = lookup("_profin", 0);
13307edc7532SDavid du Colombier s4 = lookup("_profout", 0);
1331*f8bc6aafSDavid du Colombier }
13327edc7532SDavid du Colombier if(s2->type != STEXT || s4->type != STEXT) {
1333*f8bc6aafSDavid du Colombier if(debug['e'])
1334*f8bc6aafSDavid du Colombier diag("_tracein/_traceout not defined %d %d", s2->type, s4->type);
1335*f8bc6aafSDavid du Colombier else
13367edc7532SDavid du Colombier diag("_profin/_profout not defined");
13377edc7532SDavid du Colombier return;
13387edc7532SDavid du Colombier }
13397edc7532SDavid du Colombier
13407edc7532SDavid du Colombier ps2 = P;
13417edc7532SDavid du Colombier ps4 = P;
13427edc7532SDavid du Colombier for(p = firstp; p != P; p = p->link) {
13437edc7532SDavid du Colombier if(p->as == ATEXT) {
13447edc7532SDavid du Colombier if(p->from.sym == s2) {
13457edc7532SDavid du Colombier ps2 = p;
13467edc7532SDavid du Colombier p->reg = 1;
13477edc7532SDavid du Colombier }
13487edc7532SDavid du Colombier if(p->from.sym == s4) {
13497edc7532SDavid du Colombier ps4 = p;
13507edc7532SDavid du Colombier p->reg = 1;
13517edc7532SDavid du Colombier }
13527edc7532SDavid du Colombier }
13537edc7532SDavid du Colombier }
13547edc7532SDavid du Colombier for(p = firstp; p != P; p = p->link) {
13557edc7532SDavid du Colombier if(p->as == ATEXT) {
13567edc7532SDavid du Colombier if(p->reg & NOPROF) {
13577edc7532SDavid du Colombier for(;;) {
13587edc7532SDavid du Colombier q = p->link;
13597edc7532SDavid du Colombier if(q == P)
13607edc7532SDavid du Colombier break;
13617edc7532SDavid du Colombier if(q->as == ATEXT)
13627edc7532SDavid du Colombier break;
13637edc7532SDavid du Colombier p = q;
13647edc7532SDavid du Colombier }
13657edc7532SDavid du Colombier continue;
13667edc7532SDavid du Colombier }
13677edc7532SDavid du Colombier
13687edc7532SDavid du Colombier /*
13697edc7532SDavid du Colombier * JAL profin, R2
13707edc7532SDavid du Colombier */
13717edc7532SDavid du Colombier q = prg();
13727edc7532SDavid du Colombier q->line = p->line;
13737edc7532SDavid du Colombier q->pc = p->pc;
13747edc7532SDavid du Colombier q->link = p->link;
1375*f8bc6aafSDavid du Colombier if(debug['e']){ /* embedded tracing */
1376*f8bc6aafSDavid du Colombier q2 = prg();
1377*f8bc6aafSDavid du Colombier p->link = q2;
1378*f8bc6aafSDavid du Colombier q2->link = q;
1379*f8bc6aafSDavid du Colombier
1380*f8bc6aafSDavid du Colombier q2->line = p->line;
1381*f8bc6aafSDavid du Colombier q2->pc = p->pc;
1382*f8bc6aafSDavid du Colombier
1383*f8bc6aafSDavid du Colombier q2->as = AJMP;
1384*f8bc6aafSDavid du Colombier q2->to.type = D_BRANCH;
1385*f8bc6aafSDavid du Colombier q2->to.sym = p->to.sym;
1386*f8bc6aafSDavid du Colombier q2->cond = q->link;
1387*f8bc6aafSDavid du Colombier }else
13887edc7532SDavid du Colombier p->link = q;
13897edc7532SDavid du Colombier p = q;
13907edc7532SDavid du Colombier p->as = AJAL;
13917edc7532SDavid du Colombier p->to.type = D_BRANCH;
13927edc7532SDavid du Colombier p->cond = ps2;
13937edc7532SDavid du Colombier p->to.sym = s2;
13947edc7532SDavid du Colombier
13957edc7532SDavid du Colombier continue;
13967edc7532SDavid du Colombier }
13977edc7532SDavid du Colombier if(p->as == ARET) {
13987edc7532SDavid du Colombier /*
1399*f8bc6aafSDavid du Colombier * RET (default)
1400*f8bc6aafSDavid du Colombier */
1401*f8bc6aafSDavid du Colombier if(debug['e']){ /* embedded tracing */
1402*f8bc6aafSDavid du Colombier q = prg();
1403*f8bc6aafSDavid du Colombier q->line = p->line;
1404*f8bc6aafSDavid du Colombier q->pc = p->pc;
1405*f8bc6aafSDavid du Colombier q->link = p->link;
1406*f8bc6aafSDavid du Colombier p->link = q;
1407*f8bc6aafSDavid du Colombier p = q;
1408*f8bc6aafSDavid du Colombier }
1409*f8bc6aafSDavid du Colombier /*
14107edc7532SDavid du Colombier * RET
14117edc7532SDavid du Colombier */
14127edc7532SDavid du Colombier q = prg();
14137edc7532SDavid du Colombier q->as = ARET;
14147edc7532SDavid du Colombier q->from = p->from;
14157edc7532SDavid du Colombier q->to = p->to;
14167edc7532SDavid du Colombier q->link = p->link;
14177edc7532SDavid du Colombier p->link = q;
14187edc7532SDavid du Colombier
14197edc7532SDavid du Colombier /*
14207edc7532SDavid du Colombier * JAL profout
14217edc7532SDavid du Colombier */
14227edc7532SDavid du Colombier p->as = AJAL;
14237edc7532SDavid du Colombier p->from = zprg.from;
14247edc7532SDavid du Colombier p->to = zprg.to;
14257edc7532SDavid du Colombier p->to.type = D_BRANCH;
14267edc7532SDavid du Colombier p->cond = ps4;
14277edc7532SDavid du Colombier p->to.sym = s4;
14287edc7532SDavid du Colombier
14297edc7532SDavid du Colombier p = q;
14307edc7532SDavid du Colombier
14317edc7532SDavid du Colombier continue;
14327edc7532SDavid du Colombier }
14337edc7532SDavid du Colombier }
14347edc7532SDavid du Colombier }
14357edc7532SDavid du Colombier
14367edc7532SDavid du Colombier void
nuxiinit(void)14377edc7532SDavid du Colombier nuxiinit(void)
14387edc7532SDavid du Colombier {
14397edc7532SDavid du Colombier int i, c;
14407edc7532SDavid du Colombier
1441*f8bc6aafSDavid du Colombier for(i=0; i<4; i++)
1442*f8bc6aafSDavid du Colombier if (!little) { /* normal big-endian case */
14437edc7532SDavid du Colombier c = find1(0x01020304L, i+1);
14447edc7532SDavid du Colombier if(i >= 2)
14457edc7532SDavid du Colombier inuxi2[i-2] = c;
14467edc7532SDavid du Colombier if(i >= 3)
14477edc7532SDavid du Colombier inuxi1[i-3] = c;
14487edc7532SDavid du Colombier inuxi4[i] = c;
1449*f8bc6aafSDavid du Colombier inuxi8[i] = c+4;
1450*f8bc6aafSDavid du Colombier inuxi8[i+4] = c;
1451*f8bc6aafSDavid du Colombier fnuxi4[i] = c;
14527edc7532SDavid du Colombier fnuxi8[i] = c+4;
14537edc7532SDavid du Colombier fnuxi8[i+4] = c;
1454*f8bc6aafSDavid du Colombier } else { /* oddball little-endian case */
1455*f8bc6aafSDavid du Colombier c = find1(0x04030201L, i+1);
1456*f8bc6aafSDavid du Colombier if(i < 2)
1457*f8bc6aafSDavid du Colombier inuxi2[i] = c;
1458*f8bc6aafSDavid du Colombier if(i < 1)
1459*f8bc6aafSDavid du Colombier inuxi1[i] = c;
1460*f8bc6aafSDavid du Colombier inuxi4[i] = c;
1461*f8bc6aafSDavid du Colombier inuxi8[i] = c;
1462*f8bc6aafSDavid du Colombier inuxi8[i+4] = c+4;
1463*f8bc6aafSDavid du Colombier fnuxi4[i] = c;
1464*f8bc6aafSDavid du Colombier fnuxi8[i] = c;
1465*f8bc6aafSDavid du Colombier fnuxi8[i+4] = c+4;
14667edc7532SDavid du Colombier }
14677edc7532SDavid du Colombier if(debug['v']) {
14687edc7532SDavid du Colombier Bprint(&bso, "inuxi = ");
14697edc7532SDavid du Colombier for(i=0; i<1; i++)
14707edc7532SDavid du Colombier Bprint(&bso, "%d", inuxi1[i]);
14717edc7532SDavid du Colombier Bprint(&bso, " ");
14727edc7532SDavid du Colombier for(i=0; i<2; i++)
14737edc7532SDavid du Colombier Bprint(&bso, "%d", inuxi2[i]);
14747edc7532SDavid du Colombier Bprint(&bso, " ");
14757edc7532SDavid du Colombier for(i=0; i<4; i++)
14767edc7532SDavid du Colombier Bprint(&bso, "%d", inuxi4[i]);
14777edc7532SDavid du Colombier Bprint(&bso, "\nfnuxi = ");
14787edc7532SDavid du Colombier for(i=0; i<8; i++)
1479*f8bc6aafSDavid du Colombier Bprint(&bso, "%d", inuxi8[i]);
1480*f8bc6aafSDavid du Colombier Bprint(&bso, "\n");
1481*f8bc6aafSDavid du Colombier for(i=0; i<4; i++)
1482*f8bc6aafSDavid du Colombier Bprint(&bso, "%d", fnuxi4[i]);
1483*f8bc6aafSDavid du Colombier Bprint(&bso, "\nfnuxi = ");
1484*f8bc6aafSDavid du Colombier for(i=0; i<8; i++)
14857edc7532SDavid du Colombier Bprint(&bso, "%d", fnuxi8[i]);
14867edc7532SDavid du Colombier Bprint(&bso, "\n");
14877edc7532SDavid du Colombier }
14887edc7532SDavid du Colombier Bflush(&bso);
14897edc7532SDavid du Colombier }
14907edc7532SDavid du Colombier
14917edc7532SDavid du Colombier int
find1(long l,int c)14927edc7532SDavid du Colombier find1(long l, int c)
14937edc7532SDavid du Colombier {
14947edc7532SDavid du Colombier char *p;
14957edc7532SDavid du Colombier int i;
14967edc7532SDavid du Colombier
14977edc7532SDavid du Colombier p = (char*)&l;
14987edc7532SDavid du Colombier for(i=0; i<4; i++)
14997edc7532SDavid du Colombier if(*p++ == c)
15007edc7532SDavid du Colombier return i;
15017edc7532SDavid du Colombier return 0;
15027edc7532SDavid du Colombier }
15037edc7532SDavid du Colombier
15047edc7532SDavid du Colombier vlong
ieeedtov(Ieee * ieeep)15057edc7532SDavid du Colombier ieeedtov(Ieee *ieeep)
15067edc7532SDavid du Colombier {
15077edc7532SDavid du Colombier vlong v;
15087edc7532SDavid du Colombier
15097edc7532SDavid du Colombier v = (vlong)ieeep->l & 0xffffffffLL;
15107edc7532SDavid du Colombier v |= (vlong)ieeep->h << 32;
15117edc7532SDavid du Colombier return v;
15127edc7532SDavid du Colombier }
15137edc7532SDavid du Colombier
15147edc7532SDavid du Colombier long
ieeedtof(Ieee * ieeep)15157edc7532SDavid du Colombier ieeedtof(Ieee *ieeep)
15167edc7532SDavid du Colombier {
15177edc7532SDavid du Colombier int exp;
15187edc7532SDavid du Colombier long v;
15197edc7532SDavid du Colombier
15207edc7532SDavid du Colombier if(ieeep->h == 0)
15217edc7532SDavid du Colombier return 0;
15227edc7532SDavid du Colombier exp = (ieeep->h>>20) & ((1L<<11)-1L);
15237edc7532SDavid du Colombier exp -= (1L<<10) - 2L;
15247edc7532SDavid du Colombier v = (ieeep->h & 0xfffffL) << 3;
15257edc7532SDavid du Colombier v |= (ieeep->l >> 29) & 0x7L;
15267edc7532SDavid du Colombier if((ieeep->l >> 28) & 1) {
15277edc7532SDavid du Colombier v++;
15287edc7532SDavid du Colombier if(v & 0x800000L) {
15297edc7532SDavid du Colombier v = (v & 0x7fffffL) >> 1;
15307edc7532SDavid du Colombier exp++;
15317edc7532SDavid du Colombier }
15327edc7532SDavid du Colombier }
15337edc7532SDavid du Colombier if(exp <= -126 || exp >= 130)
15347edc7532SDavid du Colombier diag("double fp to single fp overflow");
15357edc7532SDavid du Colombier v |= ((exp + 126) & 0xffL) << 23;
15367edc7532SDavid du Colombier v |= ieeep->h & 0x80000000L;
15377edc7532SDavid du Colombier return v;
15387edc7532SDavid du Colombier }
15397edc7532SDavid du Colombier
15407edc7532SDavid du Colombier double
ieeedtod(Ieee * ieeep)15417edc7532SDavid du Colombier ieeedtod(Ieee *ieeep)
15427edc7532SDavid du Colombier {
15437edc7532SDavid du Colombier Ieee e;
15447edc7532SDavid du Colombier double fr;
15457edc7532SDavid du Colombier int exp;
15467edc7532SDavid du Colombier
15477edc7532SDavid du Colombier if(ieeep->h & (1L<<31)) {
15487edc7532SDavid du Colombier e.h = ieeep->h & ~(1L<<31);
15497edc7532SDavid du Colombier e.l = ieeep->l;
15507edc7532SDavid du Colombier return -ieeedtod(&e);
15517edc7532SDavid du Colombier }
15527edc7532SDavid du Colombier if(ieeep->l == 0 && ieeep->h == 0)
15537edc7532SDavid du Colombier return 0;
15547edc7532SDavid du Colombier fr = ieeep->l & ((1L<<16)-1L);
15557edc7532SDavid du Colombier fr /= 1L<<16;
15567edc7532SDavid du Colombier fr += (ieeep->l>>16) & ((1L<<16)-1L);
15577edc7532SDavid du Colombier fr /= 1L<<16;
15587edc7532SDavid du Colombier fr += (ieeep->h & (1L<<20)-1L) | (1L<<20);
15597edc7532SDavid du Colombier fr /= 1L<<21;
15607edc7532SDavid du Colombier exp = (ieeep->h>>20) & ((1L<<11)-1L);
15617edc7532SDavid du Colombier exp -= (1L<<10) - 2L;
15627edc7532SDavid du Colombier return ldexp(fr, exp);
15637edc7532SDavid du Colombier }
1564