Ejemplo n.º 1
0
void
dodata(void)
{
    int i, t;
    Sym *s;
    Prog *p;
    long orig, v;

    if(debug['v'])
        Bprint(&bso, "%5.2f dodata\n", cputime());
    Bflush(&bso);
    for(p = datap; p != P; p = p->link) {
        s = p->from.sym;
        if(p->as == ADYNT || p->as == AINIT)
            s->value = dtype;
        if(s->type == SBSS)
            s->type = SDATA;
        if(s->type != SDATA)
            diag("initialize non-data (%d): %s\n%P",
                 s->type, s->name, p);
        v = p->from.offset + p->reg;
        if(v > s->value)
            diag("initialize bounds (%ld): %s\n%P",
                 s->value, s->name, p);
        if((s->type == SBSS || s->type == SDATA) && (p->to.type == D_CONST || p->to.type == D_OCONST) && (p->to.name == D_EXTERN || p->to.name == D_STATIC)) {
            s = p->to.sym;
            if(s != S && (s->type == STEXT || s->type == SLEAF || s->type == SCONST || s->type == SXREF))
                s->fnptr = 1;
        }
    }

    if(debug['t']) {
        /*
         * pull out string constants
         */
        for(p = datap; p != P; p = p->link) {
            s = p->from.sym;
            if(p->to.type == D_SCONST)
                s->type = SSTRING;
        }
    }

    /*
     * pass 1
     *	assign 'small' variables to data segment
     *	(rational is that data segment is more easily
     *	 addressed through offset on R12)
     */
    orig = 0;
    for(i=0; i<NHASH; i++)
        for(s = hash[i]; s != S; s = s->link) {
            t = s->type;
            if(t != SDATA && t != SBSS)
                continue;
            v = s->value;
            if(v == 0) {
                diag("%s: no size", s->name);
                v = 1;
            }
            while(v & 3)
                v++;
            s->value = v;
            if(v > MINSIZ)
                continue;
            s->value = orig;
            orig += v;
            s->type = SDATA1;
        }

    /*
     * pass 2
     *	assign large 'data' variables to data segment
     */
    for(i=0; i<NHASH; i++)
        for(s = hash[i]; s != S; s = s->link) {
            t = s->type;
            if(t != SDATA) {
                if(t == SDATA1)
                    s->type = SDATA;
                continue;
            }
            v = s->value;
            s->value = orig;
            orig += v;
        }

    while(orig & 7)
        orig++;
    datsize = orig;

    /*
     * pass 3
     *	everything else to bss segment
     */
    for(i=0; i<NHASH; i++)
        for(s = hash[i]; s != S; s = s->link) {
            if(s->type != SBSS)
                continue;
            v = s->value;
            s->value = orig;
            orig += v;
        }
    while(orig & 7)
        orig++;
    bsssize = orig-datsize;

    xdefine("setR12", SDATA, 0L+BIG);
    xdefine("bdata", SDATA, 0L);
    xdefine("edata", SDATA, datsize);
    xdefine("end", SBSS, datsize+bsssize);
    xdefine("etext", STEXT, 0L);
}
Ejemplo n.º 2
0
void
main(int argc, char *argv[])
{
	int c;
	char *p, *name, *val;

	Binit(&bso, 1, OWRITE);
	listinit();
	nerrors = 0;
	outfile = "5.out";
	HEADTYPE = -1;
	INITTEXT = -1;
	INITDAT = -1;
	INITRND = -1;
	INITENTRY = 0;
	nuxiinit();
	
	p = getenv("GOARM");
	if(p != nil && strcmp(p, "5") == 0)
		debug['F'] = 1;

	ARGBEGIN {
	default:
		c = ARGC();
		if(c == 'l')
			usage();
 		if(c >= 0 && c < sizeof(debug))
			debug[c]++;
		break;
	case 'o':
		outfile = EARGF(usage());
		break;
	case 'E':
		INITENTRY = EARGF(usage());
		break;
	case 'I':
		interpreter = EARGF(usage());
		break;
	case 'L':
		Lflag(EARGF(usage()));
		break;
	case 'T':
		INITTEXT = atolwhex(EARGF(usage()));
		break;
	case 'D':
		INITDAT = atolwhex(EARGF(usage()));
		break;
	case 'R':
		INITRND = atolwhex(EARGF(usage()));
		break;
	case 'r':
		rpath = EARGF(usage());
		break;
	case 'H':
		HEADTYPE = headtype(EARGF(usage()));
		/* do something about setting INITTEXT */
		break;
	case 'V':
		print("%cl version %s\n", thechar, getgoversion());
		errorexit();
	case 'X':
		name = EARGF(usage());
		val = EARGF(usage());
		addstrdata(name, val);
		break;
	} ARGEND

	USED(argc);

	if(argc != 1)
		usage();

	libinit();

	if(HEADTYPE == -1)
		HEADTYPE = Hlinux;
	switch(HEADTYPE) {
	default:
		diag("unknown -H option");
		errorexit();
	case Hnoheader:	/* no header */
		HEADR = 0L;
		if(INITTEXT == -1)
			INITTEXT = 0;
		if(INITDAT == -1)
			INITDAT = 0;
		if(INITRND == -1)
			INITRND = 4;
		break;
	case Hrisc:	/* aif for risc os */
		HEADR = 128L;
		if(INITTEXT == -1)
			INITTEXT = 0x10005000 + HEADR;
		if(INITDAT == -1)
			INITDAT = 0;
		if(INITRND == -1)
			INITRND = 4;
		break;
	case Hplan9x32:	/* plan 9 */
		HEADR = 32L;
		if(INITTEXT == -1)
			INITTEXT = 4128;
		if(INITDAT == -1)
			INITDAT = 0;
		if(INITRND == -1)
			INITRND = 4096;
		break;
	case Hnetbsd:	/* boot for NetBSD */
		HEADR = 32L;
		if(INITTEXT == -1)
			INITTEXT = 0xF0000020L;
		if(INITDAT == -1)
			INITDAT = 0;
		if(INITRND == -1)
			INITRND = 4096;
		break;
	case Hixp1200: /* boot for IXP1200 */
		HEADR = 0L;
		if(INITTEXT == -1)
			INITTEXT = 0x0;
		if(INITDAT == -1)
			INITDAT = 0;
		if(INITRND == -1)
			INITRND = 4;
		break;
	case Hipaq: /* boot for ipaq */
		HEADR = 16L;
		if(INITTEXT == -1)
			INITTEXT = 0xC0008010;
		if(INITDAT == -1)
			INITDAT = 0;
		if(INITRND == -1)
			INITRND = 1024;
		break;
	case Hlinux:	/* arm elf */
		debug['d'] = 1;	// no dynamic linking
		elfinit();
		HEADR = ELFRESERVE;
		if(INITTEXT == -1)
			INITTEXT = 0x10000 + HEADR;
		if(INITDAT == -1)
			INITDAT = 0;
		if(INITRND == -1)
			INITRND = 4096;
		break;
	}
	if(INITDAT != 0 && INITRND != 0)
		print("warning: -D0x%ux is ignored because of -R0x%ux\n",
			INITDAT, INITRND);
	if(debug['v'])
		Bprint(&bso, "HEADER = -H0x%d -T0x%ux -D0x%ux -R0x%ux\n",
			HEADTYPE, INITTEXT, INITDAT, INITRND);
	Bflush(&bso);
	zprg.as = AGOK;
	zprg.scond = 14;
	zprg.reg = NREG;
	zprg.from.name = D_NONE;
	zprg.from.type = D_NONE;
	zprg.from.reg = NREG;
	zprg.to = zprg.from;
	buildop();
	histgen = 0;
	pc = 0;
	dtype = 4;

	version = 0;
	cbp = buf.cbuf;
	cbc = sizeof(buf.cbuf);

	addlibpath("command line", "command line", argv[0], "main");
	loadlib();

	// mark some functions that are only referenced after linker code editing
	if(debug['F'])
		mark(rlookup("_sfloat", 0));
	deadcode();
	if(textp == nil) {
		diag("no code");
		errorexit();
	}

	patch();
	if(debug['p'])
		if(debug['1'])
			doprof1();
		else
			doprof2();
	doelf();
	follow();
	softfloat();
	noops();
	dostkcheck();
	span();
	pclntab();
	symtab();
	dodata();
	address();
	doweak();
	reloc();
	asmb();
	undef();

	if(debug['c'])
		print("ARM size = %d\n", armsize);
	if(debug['v']) {
		Bprint(&bso, "%5.2f cpu time\n", cputime());
		Bprint(&bso, "%d sizeof adr\n", sizeof(Adr));
		Bprint(&bso, "%d sizeof prog\n", sizeof(Prog));
	}
	Bflush(&bso);
	errorexit();
}
Ejemplo n.º 3
0
void
span(void)
{
	Prog *p, *q;
	long v;
	vlong c, idat;
	int m, n, again;

	xdefine("etext", STEXT, 0L);
	idat = INITDAT;
	for(p = firstp; p != P; p = p->link) {
		if(p->as == ATEXT)
			curtext = p;
		n = 0;
		if(p->to.type == D_BRANCH)
			if(p->pcond == P)
				p->pcond = p;
		if((q = p->pcond) != P)
			if(q->back != 2)
				n = 1;
		p->back = n;
		if(p->as == AADJSP) {
			p->to.type = D_SP;
			v = -p->from.offset;
			p->from.offset = v;
			p->as = p->mode != 64? AADDL: AADDQ;
			if(v < 0) {
				p->as = p->mode != 64? ASUBL: ASUBQ;
				v = -v;
				p->from.offset = v;
			}
			if(v == 0)
				p->as = ANOP;
		}
	}
	n = 0;

start:
	if(debug['v'])
		Bprint(&bso, "%5.2f span\n", cputime());
	Bflush(&bso);
	c = INITTEXT;
	for(p = firstp; p != P; p = p->link) {
		if(p->as == ATEXT)
			curtext = p;
		if(p->to.type == D_BRANCH)
			if(p->back)
				p->pc = c;
		asmins(p);
		p->pc = c;
		m = andptr-and;
		p->mark = m;
		c += m;
	}

loop:
	n++;
	if(debug['v'])
		Bprint(&bso, "%5.2f span %d\n", cputime(), n);
	Bflush(&bso);
	if(n > 50) {
		print("span must be looping\n");
		errorexit();
	}
	again = 0;
	c = INITTEXT;
	for(p = firstp; p != P; p = p->link) {
		if(p->as == ATEXT)
			curtext = p;
		if(p->to.type == D_BRANCH || p->back & 0100) {
			if(p->back)
				p->pc = c;
			asmins(p);
			m = andptr-and;
			if(m != p->mark) {
				p->mark = m;
				again++;
			}
		}
		p->pc = c;
		c += p->mark;
	}
	if(again) {
		textsize = c;
		goto loop;
	}
	if(INITRND) {
		INITDAT = rnd(c, INITRND);
		if(INITDAT != idat) {
			idat = INITDAT;
			goto start;
		}
	}
	xdefine("etext", STEXT, c);
	if(debug['v'])
		Bprint(&bso, "etext = %llux\n", c);
	Bflush(&bso);
	for(p = textp; p != P; p = p->pcond)
		p->from.sym->value = p->pc;
	textsize = c - INITTEXT;
}
Ejemplo n.º 4
0
void
isum(void)
{
	Inst *i;
	int pct, j, k;
	int total, loads, stores, arith, branch;
	int taken, powerreg, syscall, realarith, control;

	total = 0;
	loads = 0;
	stores = 0;
	arith = 0;
	branch = 0;
	taken = 0;
	powerreg = 0;
	syscall = 0;
	realarith = 0;
	control = 0;

	/* Compute the total so we can have percentages */
	for(j = 0; tables[j]; j++)
		for(k = tables[j]->nel; --k >= 0;) {
			i = &tables[j]->tab[k];
			if(i->name && i->func)
				total += i->count;
		}

	Bprint(bioout, "\nInstruction summary.\n\n");

	for(j = 0; tables[j]; j++) {
		for(k =tables[j]->nel; --k>=0; ) {
			i = &tables[j]->tab[k];
			if(i->name && i->func) {
				if(i->count == 0)
					continue;
				pct = Percent(i->count, total);
				if(pct != 0)
					Bprint(bioout, "%-8ud %3d%% %s\n",
					i->count, Percent(i->count, total), i->name);
				else
					Bprint(bioout, "%-8ud      %s\n",
					i->count, i->name);
	
				switch(i->type) {
				default:
					fatal(0, "isum bad stype %d\n", i->type);
				case Iload:
					loads += i->count;
					break;
				case Istore:
					stores += i->count;
					break;
				case Ilog:
				case Iarith:
					arith += i->count;
					break;
				case Ibranch:
					branch += i->count;
					taken += i->taken;
					break;
				case Ireg:
					powerreg += i->count;
					break;
				case Isyscall:
					syscall += i->count;
					break;
				case Ifloat:
					realarith += i->count;
					break;
				case Inop:
					arith += i->count;
					i->count -= nopcount;
					break;
				case Icontrol:
					control += i->count;
					break;
				}
			}
		}
	}

	Bprint(bioout, "\n%-8ud      Memory cycles\n", loads+stores+total);

	if(total == 0)
		return;

	Bprint(bioout, "%-8ud %3d%% Instruction cycles\n",
				total, Percent(total, loads+stores+total));

	Bprint(bioout, "%-8ud %3d%% Data cycles\n\n",
				loads+stores, Percent(loads+stores, loads+stores+total));	

	Bprint(bioout, "%-8ud %3d%% Stores\n", stores, Percent(stores, total));

	Bprint(bioout, "%-8ud %3d%% Loads\n", loads, Percent(loads, total));

	Bprint(bioout, "   %-8ud Store stall\n", stores*2);

	Bprint(bioout, "   %-8lud Load stall\n", loadlock);

	Bprint(bioout, "%-8ud %3d%% Arithmetic\n", arith, Percent(arith, total));

	Bprint(bioout, "%-8ud %3d%% Floating point\n",
					realarith, Percent(realarith, total));

	Bprint(bioout, "%-8ud %3d%% PowerPC special register load/stores\n",
					powerreg, Percent(powerreg, total));

	Bprint(bioout, "%-8ud %3d%% PowerPC control instructions\n",
					control, Percent(control, total));

	Bprint(bioout, "%-8ud %3d%% System calls\n", syscall, Percent(syscall, total));

	Bprint(bioout, "%-8ud %3d%% Branches\n", branch, Percent(branch, total));

	Bprint(bioout, "   %-8ud %3d%% Branches taken\n",
					taken, Percent(taken, branch));
}
Ejemplo n.º 5
0
//
// check for new messages on imap4 server
// download new messages, mark deleted messages
//
static char*
imap4read(Imap *imap, Mailbox *mb, int doplumb)
{
    char *s;
    int i, ignore, nnew, t;
    Message *m, *next, **l;

    imap4cmd(imap, "STATUS %Z (MESSAGES UIDVALIDITY)", imap->mbox);
    if(!isokay(s = imap4resp(imap)))
        return s;

    imap->nuid = 0;
    imap->uid = erealloc(imap->uid, imap->nmsg*sizeof(imap->uid[0]));
    imap->muid = imap->nmsg;

    if(imap->nmsg > 0) {
        imap4cmd(imap, "UID FETCH 1:* UID");
        if(!isokay(s = imap4resp(imap)))
            return s;
    }

    l = &mb->root->part;
    for(i=0; i<imap->nuid; i++) {
        ignore = 0;
        while(*l != nil) {
            if((*l)->imapuid == imap->uid[i]) {
                ignore = 1;
                l = &(*l)->next;
                break;
            } else {
                // old mail, we don't have it anymore
                if(doplumb)
                    mailplumb(mb, *l, 1);
                (*l)->inmbox = 0;
                (*l)->deleted = 1;
                l = &(*l)->next;
            }
        }
        if(ignore)
            continue;

        // new message
        m = newmessage(mb->root);
        m->mallocd = 1;
        m->inmbox = 1;
        m->imapuid = imap->uid[i];

        // add to chain, will download soon
        *l = m;
        l = &m->next;
    }

    // whatever is left at the end of the chain is gone
    while(*l != nil) {
        if(doplumb)
            mailplumb(mb, *l, 1);
        (*l)->inmbox = 0;
        (*l)->deleted = 1;
        l = &(*l)->next;
    }

    // download new messages
    t = imap->tag;
    if(pipeline)
        switch(rfork(RFPROC|RFMEM)) {
        case -1:
            sysfatal("rfork: %r");
        default:
            break;
        case 0:
            for(m = mb->root->part; m != nil; m = m->next) {
                if(m->start != nil)
                    continue;
                if(imap->debug)
                    fprint(2, "9X%d UID FETCH %lud (UID RFC822.SIZE BODY[])\r\n",
                           t, (ulong)m->imapuid);
                Bprint(&imap->bout, "9X%d UID FETCH %lud (UID RFC822.SIZE BODY[])\r\n",
                       t++, (ulong)m->imapuid);
            }
            Bflush(&imap->bout);
            _exits(nil);
        }

    nnew = 0;
    for(m=mb->root->part; m!=nil; m=next) {
        next = m->next;
        if(m->start != nil)
            continue;

        if(!pipeline) {
            Bprint(&imap->bout, "9X%lud UID FETCH %lud (UID RFC822.SIZE BODY[])\r\n",
                   (ulong)imap->tag, (ulong)m->imapuid);
            Bflush(&imap->bout);
        }

        if(s = imap4fetch(mb, m)) {
            // message disappeared?  unchain
            fprint(2, "download %lud: %s\n", (ulong)m->imapuid, s);
            delmessage(mb, m);
            mb->root->subname--;
            continue;
        }
        nnew++;
        if(doplumb)
            mailplumb(mb, m, 0);
    }
    if(pipeline)
        waitpid();

    if(nnew || mb->vers == 0) {
        mb->vers++;
        henter(PATH(0, Qtop), mb->name,
        (Qid) {
            PATH(mb->id, Qmbox), mb->vers, QTDIR
        }, nil, mb);
    }
    return nil;
}
Ejemplo n.º 6
0
void
dobplist(void)
{
	Breakpoint *b;
	char buf[512];

	for(b = bplist; b; b = b->next) {
		switch(b->type) {
		case Instruction:
			Bprint(bioout, "0x%lux,%d:b %d done, at ", b->addr, b->count, b->done);
			symoff(buf, sizeof(buf), b->addr, CTEXT);
			Bprint(bioout, "%s", buf);
			break;

		case Access:
			Bprint(bioout, "0x%lux,%d:ba %d done, at ", b->addr, b->count, b->done);
			symoff(buf, sizeof(buf), b->addr, CDATA);
			Bprint(bioout, "%s", buf);
			break;

		case Read:
			Bprint(bioout, "0x%lux,%d:br %d done, at ", b->addr, b->count, b->done);
			symoff(buf, sizeof(buf), b->addr, CDATA);
			Bprint(bioout, "%s", buf);
			break;

		case Write:
			Bprint(bioout, "0x%lux,%d:bw %d done, at ", b->addr, b->count, b->done);
			symoff(buf, sizeof(buf), b->addr, CDATA);
			Bprint(bioout, "%s", buf);
			break;

		case Equal:
			Bprint(bioout, "0x%lux,%d:be at ", b->addr, b->count);
			symoff(buf, sizeof(buf), b->addr, CDATA);
			Bprint(bioout, "%s", buf);
			break;
		}
		Bprint(bioout, "\n");
	}
}
Ejemplo n.º 7
0
void
sdis(char a1, char a2)
{
	int c1, c2;
	int eqnf;
	int lct;

	if(a1 == 'P'){
		while(C1 == ' ')
			;
		if(c == '<') {
			SKIP1;
			return;
		}
	}
	lct = 0;
	eqnf = 1;
	if(c != '\n')
		SKIP1;
	for(;;) {
		while(C1 != '.')
			if(c == '\n')
				continue;
			else
				SKIP1;
		if((c1=C1) == '\n')
			continue;
		if((c2=C1) == '\n') {
			if(a1 == 'f' && (c1 == 'P' || c1 == 'H'))
				return;
			continue;
		}
		if(c1==a1 && c2 == a2) {
			SKIP1;
			if(lct != 0){
				lct--;
				continue;
			}
			if(eqnf)
				Bprint(&(bout.Biobufhdr), " .");
			Bputc(&(bout.Biobufhdr), '\n');
			return;
		} else
		if(a1 == 'L' && c2 == 'L') {
			lct++;
			SKIP1;
		} else
		if(a1 == 'D' && c1 == 'E' && c2 == 'Q') {
			eqn(); 
			eqnf = 0;
		} else
		if(a1 == 'f') {
			if((mac == MS && c2 == 'P') ||
				(mac == MM && c1 == 'H' && c2 == 'U')){
				SKIP1;
				return;
			}
			SKIP1;
		}
		else
			SKIP1;
	}
}
Ejemplo n.º 8
0
void
main(int argc, char *argv[])
{
	int i, c;

	Binit(&bso, 1, OWRITE);
	cout = -1;
	listinit();
	memset(debug, 0, sizeof(debug));
	nerrors = 0;
	outfile = nil;
	HEADTYPE = -1;
	INITTEXT = -1;
	INITDAT = -1;
	INITRND = -1;
	INITENTRY = 0;

	ARGBEGIN {
	default:
		c = ARGC();
		if(c == 'l')
			usage();
 		if(c >= 0 && c < sizeof(debug))
			debug[c]++;
		break;
	case 'o': /* output to (next arg) */
		outfile = EARGF(usage());
		break;
	case 'E':
		INITENTRY = EARGF(usage());
		break;
	case 'H':
		HEADTYPE = atolwhex(EARGF(usage()));
		break;
	case 'L':
		Lflag(EARGF(usage()));
		break;
	case 'T':
		INITTEXT = atolwhex(EARGF(usage()));
		break;
	case 'D':
		INITDAT = atolwhex(EARGF(usage()));
		break;
	case 'R':
		INITRND = atolwhex(EARGF(usage()));
		break;
	case 'r':
		rpath = EARGF(usage());
		break;
	case 'x':	/* produce export table */
		doexp = 1;
		if(argv[1] != nil && argv[1][0] != '-' && !isobjfile(argv[1]))
			readundefs(ARGF(), SEXPORT);
		break;
	case 'u':	/* produce dynamically loadable module */
		dlm = 1;
		if(argv[1] != nil && argv[1][0] != '-' && !isobjfile(argv[1]))
			readundefs(ARGF(), SIMPORT);
		break;
	case 'V':
		print("%cl version %s\n", thechar, getgoversion());
		errorexit();
	} ARGEND

	if(argc != 1)
		usage();

	mywhatsys();	// get goos

	if(HEADTYPE == -1) {
		HEADTYPE = 2;
		if(strcmp(goos, "linux") == 0)
			HEADTYPE = 7;
		else
		if(strcmp(goos, "darwin") == 0)
			HEADTYPE = 6;
		else
		if(strcmp(goos, "nacl") == 0)
			HEADTYPE = 8;
		else
		if(strcmp(goos, "freebsd") == 0)
			HEADTYPE = 9;
		else
		if(strcmp(goos, "mingw") == 0)
			HEADTYPE = 10;
		else
		if(strcmp(goos, "pchw") == 0)
			HEADTYPE = 11;
		else
			print("goos is not known: %s\n", goos);
	}

	if(outfile == nil) {
		if(HEADTYPE == 10)
			outfile = "8.out.exe";
		else
			outfile = "8.out";
	}

	libinit();

	switch(HEADTYPE) {
	default:
		diag("unknown -H option");
		errorexit();

	case 0:	/* this is garbage */
		HEADR = 20L+56L;
		if(INITTEXT == -1)
			INITTEXT = 0x40004CL;
		if(INITDAT == -1)
			INITDAT = 0x10000000L;
		if(INITRND == -1)
			INITRND = 0;
		break;
	case 1:	/* is unix coff */
		HEADR = 0xd0L;
		if(INITTEXT == -1)
			INITTEXT = 0xd0;
		if(INITDAT == -1)
			INITDAT = 0x400000;
		if(INITRND == -1)
			INITRND = 0;
		break;
	case 2:	/* plan 9 */
		HEADR = 32L;
		if(INITTEXT == -1)
			INITTEXT = 4096+32;
		if(INITDAT == -1)
			INITDAT = 0;
		if(INITRND == -1)
			INITRND = 4096;
		break;
	case 3:	/* MS-DOS .COM */
		HEADR = 0;
		if(INITTEXT == -1)
			INITTEXT = 0x0100;
		if(INITDAT == -1)
			INITDAT = 0;
		if(INITRND == -1)
			INITRND = 4;
		break;
	case 4:	/* fake MS-DOS .EXE */
		HEADR = 0x200;
		if(INITTEXT == -1)
			INITTEXT = 0x0100;
		if(INITDAT == -1)
			INITDAT = 0;
		if(INITRND == -1)
			INITRND = 4;
		HEADR += (INITTEXT & 0xFFFF);
		if(debug['v'])
			Bprint(&bso, "HEADR = 0x%ld\n", HEADR);
		break;
	case 6:	/* apple MACH */
		/*
		 * OS X system constant - offset from %gs to our TLS.
		 * Explained in ../../libcgo/darwin_386.c.
		 */
		tlsoffset = 0x468;
		machoinit();
		HEADR = MACHORESERVE;
		if(INITTEXT == -1)
			INITTEXT = 4096+HEADR;
		if(INITDAT == -1)
			INITDAT = 0;
		if(INITRND == -1)
			INITRND = 4096;
		break;
	case 7:	/* elf32 executable */
	case 9:
		/*
		 * Linux ELF uses TLS offsets negative from %gs.
		 * Translate 0(GS) and 4(GS) into -8(GS) and -4(GS).
		 * Also known to ../../pkg/runtime/linux/386/sys.s
		 * and ../../libcgo/linux_386.c.
		 */
		tlsoffset = -8;
		elfinit();
		HEADR = ELFRESERVE;
		if(INITTEXT == -1)
			INITTEXT = 0x08048000+HEADR;
		if(INITDAT == -1)
			INITDAT = 0;
		if(INITRND == -1)
			INITRND = 4096;
		break;
	case 8:	/* native client elf32 executable */
		elfinit();
		HEADR = 4096;
		if(INITTEXT == -1)
			INITTEXT = 0x20000;
		if(INITDAT == -1)
			INITDAT = 0;
		if(INITRND == -1)
			INITRND = 4096;
		break;
	case 10: /* PE executable */
		peinit();
		HEADR = PERESERVE;
		if(INITTEXT == -1)
			INITTEXT = PEBASE+0x1000;
		if(INITDAT == -1)
			INITDAT = 0;
		if(INITRND == -1)
			INITRND = PEALIGN;
		break;
	case 11:
		tlsoffset = 0;
		elfinit();
		HEADR = ELFRESERVE;
		if(INITTEXT == -1)
			INITTEXT = 0x100000+HEADR;
		if(INITDAT == -1)
			INITDAT = 0;
		if(INITRND == -1)
			INITRND = 4096;
		break;
	}
	if(INITDAT != 0 && INITRND != 0)
		print("warning: -D0x%lux is ignored because of -R0x%lux\n",
			INITDAT, INITRND);
	if(debug['v'])
		Bprint(&bso, "HEADER = -H0x%ld -T0x%lux -D0x%lux -R0x%lux\n",
			HEADTYPE, INITTEXT, INITDAT, INITRND);
	Bflush(&bso);
	for(i=1; optab[i].as; i++)
		if(i != optab[i].as) {
			diag("phase error in optab: %d", i);
			errorexit();
		}
	maxop = i;

	for(i=0; i<Ymax; i++)
		ycover[i*Ymax + i] = 1;

	ycover[Yi0*Ymax + Yi8] = 1;
	ycover[Yi1*Ymax + Yi8] = 1;

	ycover[Yi0*Ymax + Yi32] = 1;
	ycover[Yi1*Ymax + Yi32] = 1;
	ycover[Yi8*Ymax + Yi32] = 1;

	ycover[Yal*Ymax + Yrb] = 1;
	ycover[Ycl*Ymax + Yrb] = 1;
	ycover[Yax*Ymax + Yrb] = 1;
	ycover[Ycx*Ymax + Yrb] = 1;
	ycover[Yrx*Ymax + Yrb] = 1;

	ycover[Yax*Ymax + Yrx] = 1;
	ycover[Ycx*Ymax + Yrx] = 1;

	ycover[Yax*Ymax + Yrl] = 1;
	ycover[Ycx*Ymax + Yrl] = 1;
	ycover[Yrx*Ymax + Yrl] = 1;

	ycover[Yf0*Ymax + Yrf] = 1;

	ycover[Yal*Ymax + Ymb] = 1;
	ycover[Ycl*Ymax + Ymb] = 1;
	ycover[Yax*Ymax + Ymb] = 1;
	ycover[Ycx*Ymax + Ymb] = 1;
	ycover[Yrx*Ymax + Ymb] = 1;
	ycover[Yrb*Ymax + Ymb] = 1;
	ycover[Ym*Ymax + Ymb] = 1;

	ycover[Yax*Ymax + Yml] = 1;
	ycover[Ycx*Ymax + Yml] = 1;
	ycover[Yrx*Ymax + Yml] = 1;
	ycover[Yrl*Ymax + Yml] = 1;
	ycover[Ym*Ymax + Yml] = 1;

	for(i=0; i<D_NONE; i++) {
		reg[i] = -1;
		if(i >= D_AL && i <= D_BH)
			reg[i] = (i-D_AL) & 7;
		if(i >= D_AX && i <= D_DI)
			reg[i] = (i-D_AX) & 7;
		if(i >= D_F0 && i <= D_F0+7)
			reg[i] = (i-D_F0) & 7;
	}

	zprg.link = P;
	zprg.pcond = P;
	zprg.back = 2;
	zprg.as = AGOK;
	zprg.from.type = D_NONE;
	zprg.from.index = D_NONE;
	zprg.from.scale = 1;
	zprg.to = zprg.from;

	pcstr = "%.6lux ";
	nuxiinit();
	histgen = 0;
	textp = P;
	datap = P;
	edatap = P;
	pc = 0;
	dtype = 4;
	version = 0;
	cbp = buf.cbuf;
	cbc = sizeof(buf.cbuf);
	firstp = prg();
	lastp = firstp;

	addlibpath("command line", "command line", argv[0], "main");
	loadlib();

	deadcode();

	firstp = firstp->link;
	if(firstp == P)
		errorexit();
	if(doexp || dlm){
		EXPTAB = "_exporttab";
		zerosig(EXPTAB);
		zerosig("etext");
		zerosig("edata");
		zerosig("end");
		if(dlm){
			import();
			HEADTYPE = 2;
			INITTEXT = INITDAT = 0;
			INITRND = 8;
			INITENTRY = EXPTAB;
		}
		export();
Ejemplo n.º 9
0
void
drawline(int i, int cl, int cr, int lintype, int noheight, int shortl)
{
	char	*exhr, *exhl, *lnch;
	int	lcount, ln, linpos, oldpos, nodata;

	lcount = 0;
	exhr = exhl = "";
	switch (lintype) {
	case '-':
		lcount = 1;
		break;
	case '=':
		lcount = pr1403 ? 1 : 2;
		break;
	case SHORTLINE:
		lcount = 1;
		break;
	}
	if (lcount <= 0)
		return;
	nodata = cr - cl >= ncol || noheight || allh(i);
	if (!nodata)
		Bprint(&tabout, "\\v'-.5m'");
	for (ln = oldpos = 0; ln < lcount; ln++) {
		linpos = 2 * ln - lcount + 1;
		if (linpos != oldpos)
			Bprint(&tabout, "\\v'%dp'", linpos - oldpos);
		oldpos = linpos;
		if (shortl == 0) {
			tohcol(cl);
			if (lcount > 1) {
				switch (interv(i, cl)) {
				case TOP:
					exhl = ln == 0 ? "1p" : "-1p";
					break;
				case BOT:
					exhl = ln == 1 ? "1p" : "-1p";
					break;
				case THRU:
					exhl = "1p";
					break;
				}
				if (exhl[0])
					Bprint(&tabout, "\\h'%s'", exhl);
			} else if (lcount == 1) {
				switch (interv(i, cl)) {
				case TOP:
				case BOT:
					exhl = "-1p";
					break;
				case THRU:
					exhl = "1p";
					break;
				}
				if (exhl[0])
					Bprint(&tabout, "\\h'%s'", exhl);
			}
			if (lcount > 1) {
				switch (interv(i, cr + 1)) {
				case TOP:
					exhr = ln == 0 ? "-1p" : "+1p";
					break;
				case BOT:
					exhr = ln == 1 ? "-1p" : "+1p";
					break;
				case THRU:
					exhr = "-1p";
					break;
				}
			} else if (lcount == 1) {
				switch (interv(i, cr + 1)) {
				case TOP:
				case BOT:
					exhr = "+1p";
					break;
				case THRU:
					exhr = "-1p";
					break;
				}
			}
		} else
			Bprint(&tabout, "\\h'|\\n(%2su'", reg(cl, CLEFT));
		Bprint(&tabout, "\\s\\n(%d", LSIZE);
		if (linsize)
			Bprint(&tabout, "\\v'-\\n(%dp/6u'", LSIZE);
		if (shortl)
			Bprint(&tabout, "\\l'|\\n(%2su'", reg(cr, CRIGHT));
		else
		 {
			lnch = "\\(ul";
			if (pr1403)
				lnch = lintype == 2 ? "=" : "\\(ru";
			if (cr + 1 >= ncol)
				Bprint(&tabout, "\\l'|\\n(TWu%s%s'", exhr, lnch);
			else
				Bprint(&tabout, "\\l'(|\\n(%2su+|\\n(%2su)/2u%s%s'", reg(cr, CRIGHT),
				    reg(cr + 1, CLEFT), exhr, lnch);
		}
		if (linsize)
			Bprint(&tabout, "\\v'\\n(%dp/6u'", LSIZE);
		Bprint(&tabout, "\\s0");
	}
	if (oldpos != 0)
		Bprint(&tabout, "\\v'%dp'", -oldpos);
	if (!nodata)
		Bprint(&tabout, "\\v'+.5m'");
}
Ejemplo n.º 10
0
static void
printtypename(Type *t)
{
    Sym *s;
    Type *t1;
    int w;
    char *n;

    for( ; t != nil; t = t->link) {
        switch(t->etype) {
        case TIND:
            // Special handling of *void.
            if(t->link != nil && t->link->etype==TVOID) {
                Bprint(&outbuf, "unsafe.Pointer");
                return;
            }
            // *func == func
            if(t->link != nil && t->link->etype==TFUNC)
                continue;
            Bprint(&outbuf, "*");
            continue;
        case TARRAY:
            w = t->width;
            if(t->link && t->link->width)
                w /= t->link->width;
            Bprint(&outbuf, "[%d]", w);
            continue;
        }
        break;
    }

    if(t == nil) {
        Bprint(&outbuf, "bad // should not happen");
        return;
    }

    switch(t->etype) {
    case TINT:
        Bprint(&outbuf, "int32");
        break;
    case TUINT:
        Bprint(&outbuf, "uint32");
        break;
    case TCHAR:
        Bprint(&outbuf, "int8");
        break;
    case TUCHAR:
        Bprint(&outbuf, "uint8");
        break;
    case TSHORT:
        Bprint(&outbuf, "int16");
        break;
    case TUSHORT:
        Bprint(&outbuf, "uint16");
        break;
    case TLONG:
        Bprint(&outbuf, "int32");
        break;
    case TULONG:
        Bprint(&outbuf, "uint32");
        break;
    case TVLONG:
        Bprint(&outbuf, "int64");
        break;
    case TUVLONG:
        Bprint(&outbuf, "uint64");
        break;
    case TFLOAT:
        Bprint(&outbuf, "float32");
        break;
    case TDOUBLE:
        Bprint(&outbuf, "float64");
        break;
    case TUNION:
    case TSTRUCT:
        s = findsue(t->link);
        n = "bad";
        if(s != S)
            n = s->name;
        else if(t->tag)
            n = t->tag->name;
        if(strcmp(n, "String") == 0) {
            Bprint(&outbuf, "string");
        } else if(strcmp(n, "Slice") == 0) {
            Bprint(&outbuf, "[]byte");
        } else
            Bprint(&outbuf, "%U", n);
        break;
    case TFUNC:
        Bprint(&outbuf, "func(");
        for(t1 = t->down; t1 != T; t1 = t1->down) {
            if(t1->etype == TVOID)
                break;
            if(t1 != t->down)
                Bprint(&outbuf, ", ");
            printtypename(t1);
        }
        Bprint(&outbuf, ")");
        if(t->link && t->link->etype != TVOID) {
            Bprint(&outbuf, " ");
            printtypename(t->link);
        }
        break;
    case TDOT:
        Bprint(&outbuf, "...interface{}");
        break;
    default:
        Bprint(&outbuf, " weird<%T>", t);
    }
}
Ejemplo n.º 11
0
void
godefvar(Sym *s)
{
    Type *t, *t1;
    char n;

    if(dontrun())
        return;

    t = s->type;
    if(t == nil)
        return;

    switch(t->etype) {
    case TENUM:
        if(!typefd[t->etype])
            Bprint(&outbuf, "const %U = %lld\n", s->name, s->vconst);
        else
            Bprint(&outbuf, "const %U = %f\n;", s->name, s->fconst);
        break;

    case TFUNC:
        Bprint(&outbuf, "func %U(", s->name);
        n = 'a';
        for(t1 = t->down; t1 != T; t1 = t1->down) {
            if(t1->etype == TVOID)
                break;
            if(t1 != t->down)
                Bprint(&outbuf, ", ");
            Bprint(&outbuf, "%c ", n++);
            printtypename(t1);
        }
        Bprint(&outbuf, ")");
        if(t->link && t->link->etype != TVOID) {
            Bprint(&outbuf, " ");
            printtypename(t->link);
        }
        Bprint(&outbuf, "\n");
        break;

    default:
        switch(s->class) {
        case CTYPEDEF:
            if(!typesu[t->etype]) {
                Bprint(&outbuf, "// type %U\t", s->name);
                printtypename(t);
                Bprint(&outbuf, "\n");
            }
            break;
        case CSTATIC:
        case CEXTERN:
        case CGLOBL:
            if(strchr(s->name, '$') != nil)	 // TODO(lvd)
                break;
            Bprint(&outbuf, "var %U\t", s->name);
            printtypename(t);
            Bprint(&outbuf, "\n");
            break;
        }
        break;
    }
}
Ejemplo n.º 12
0
static void
dump(Vga* vga, Ctlr* ctlr)
{
	int i;

	printitem(ctlr->name, "misc");
	printreg(vga->misc);
	printitem(ctlr->name, "feature");
	printreg(vga->feature);

	printitem(ctlr->name, "sequencer");
	for(i = 0; i < NSeqx; i++)
		printreg(vga->sequencer[i]);

	printitem(ctlr->name, "crt");
	for(i = 0; i < NCrtx; i++)
		printreg(vga->crt[i]);

	printitem(ctlr->name, "graphics");
	for(i = 0; i < NGrx; i++)
		printreg(vga->graphics[i]);

	printitem(ctlr->name, "attribute");
	for(i = 0; i < NAttrx; i++)
		printreg(vga->attribute[i]);

	if(dflag)
		palette.dump(vga, ctlr);

	printitem(ctlr->name, "virtual");
	Bprint(&stdout, "%ld %ld\n", vga->virtx, vga->virty);
	printitem(ctlr->name, "panning");
	Bprint(&stdout, "%s\n", vga->panning ? "on" : "off");
	if(vga->f[0]){
		printitem(ctlr->name, "clock[0] f");
		Bprint(&stdout, "%9ld\n", vga->f[0]);
		printitem(ctlr->name, "clock[0] d i m");
		Bprint(&stdout, "%9ld %8ld       - %8ld\n",
			vga->d[0], vga->i[0], vga->m[0]);
		printitem(ctlr->name, "clock[0] n p q r");
		Bprint(&stdout, "%9ld %8ld       - %8ld %8ld\n",
			vga->n[0], vga->p[0], vga->q[0], vga->r[0]);
	}
	if(vga->f[1]){
		printitem(ctlr->name, "clock[1] f");
		Bprint(&stdout, "%9ld\n", vga->f[1]);
		printitem(ctlr->name, "clock[1] d i m");
		Bprint(&stdout, "%9ld %8ld       - %8ld\n",
			vga->d[1], vga->i[1], vga->m[1]);
		printitem(ctlr->name, "clock[1] n p q r");
		Bprint(&stdout, "%9ld %8ld       - %8ld %8ld\n",
			vga->n[1], vga->p[1], vga->q[1], vga->r[1]);
	}

	if(vga->vma || vga->vmb){
		printitem(ctlr->name, "vm a b");
		Bprint(&stdout, "%9lud %8lud\n", vga->vma, vga->vmb);
	}
	if(vga->vmz){
		printitem(ctlr->name, "vmz");
		Bprint(&stdout, "%9lud\n", vga->vmz);
	}
	printitem(ctlr->name, "apz");
	Bprint(&stdout, "%9lud\n", vga->apz);

	printitem(ctlr->name, "linear");
	Bprint(&stdout, "%9d\n", vga->linear);
}
Ejemplo n.º 13
0
void
patch(void)
{
	int32 c;
	Prog *p, *q;
	Sym *s;
	int32 vexit;
	Sym *plan9_tos;

	if(debug['v'])
		Bprint(&bso, "%5.2f mkfwd\n", cputime());
	Bflush(&bso);
	mkfwd();
	if(debug['v'])
		Bprint(&bso, "%5.2f patch\n", cputime());
	Bflush(&bso);
	s = lookup("exit", 0);
	vexit = s->value;
	
	plan9_tos = S;
	if(HEADTYPE == Hplan9x32)
		plan9_tos = lookup("_tos", 0);
	
	for(cursym = textp; cursym != nil; cursym = cursym->next) {
		for(p = cursym->text; p != P; p = p->link) {
			if(HEADTYPE == Hwindows) {
				// Convert
				//   op	  n(GS), reg
				// to
				//   MOVL 0x14(FS), reg
				//   op	  n(reg), reg
				// The purpose of this patch is to fix some accesses
				// to extern register variables (TLS) on Windows, as
				// a different method is used to access them.
				if(p->from.type == D_INDIR+D_GS
				&& p->to.type >= D_AX && p->to.type <= D_DI) {
					q = appendp(p);
					q->from = p->from;
					q->from.type = D_INDIR + p->to.type;
					q->to = p->to;
					q->as = p->as;
					p->as = AMOVL;
					p->from.type = D_INDIR+D_FS;
					p->from.offset = 0x14;
				}
			}
			if(HEADTYPE == Hlinux) {
				// Running binaries under Xen requires using
				//	MOVL 0(GS), reg
				// and then off(reg) instead of saying off(GS) directly
				// when the offset is negative.
				if(p->from.type == D_INDIR+D_GS && p->from.offset < 0
				&& p->to.type >= D_AX && p->to.type <= D_DI) {
					q = appendp(p);
					q->from = p->from;
					q->from.type = D_INDIR + p->to.type;
					q->to = p->to;
					q->as = p->as;
					p->as = AMOVL;
					p->from.type = D_INDIR+D_GS;
					p->from.offset = 0;
				}
			}
			if(HEADTYPE == Hplan9x32) {
				if(p->from.type == D_INDIR+D_GS
				&& p->to.type >= D_AX && p->to.type <= D_DI) {
					q = appendp(p);
					q->from = p->from;
					q->from.type = D_INDIR + p->to.type;
					q->to = p->to;
					q->as = p->as;
					p->as = AMOVL;
					p->from.type = D_EXTERN;
					p->from.sym = plan9_tos;
					p->from.offset = 0;
				}
			}
			if((p->as == ACALL && p->to.type != D_BRANCH) || (p->as == AJMP && p->to.type != D_BRANCH)) {
				s = p->to.sym;
				if(p->to.type == D_INDIR+D_ADDR) {
					 /* skip check if this is an indirect call (CALL *symbol(SB)) */
					 continue;
				} else if(s) {
					if(debug['c'])
						Bprint(&bso, "%s calls %s\n", TNAME, s->name);
					if((s->type&~SSUB) != STEXT) {
						/* diag prints TNAME first */
						diag("undefined: %s", s->name);
						s->type = STEXT;
						s->value = vexit;
						continue;	// avoid more error messages
					}
					if(s->text == nil)
						continue;
					p->to.type = D_BRANCH;
					p->to.offset = s->text->pc;
					p->pcond = s->text;
					continue;
				}
			}
			if(p->to.type != D_BRANCH)
				continue;
			c = p->to.offset;
			for(q = cursym->text; q != P;) {
				if(c == q->pc)
					break;
				if(q->forwd != P && c >= q->forwd->pc)
					q = q->forwd;
				else
					q = q->link;
			}
			if(q == P) {
				diag("branch out of range in %s (%#ux)\n%P [%s]",
					TNAME, c, p, p->to.sym ? p->to.sym->name : "<nil>");
				p->to.type = D_NONE;
			}
			p->pcond = q;
		}
	}

	for(cursym = textp; cursym != nil; cursym = cursym->next) {
		if(cursym->text == nil || cursym->p != nil)
			continue;

		for(p = cursym->text; p != P; p = p->link) {
			p->mark = 0;	/* initialization for follow */
			if(p->pcond != P) {
				p->pcond = brloop(p->pcond);
				if(p->pcond != P)
				if(p->to.type == D_BRANCH)
					p->to.offset = p->pcond->pc;
			}
		}
	}
}
Ejemplo n.º 14
0
void
patch(void)
{
    long c, vexit;
    Prog *p, *q;
    Sym *s, *s1;
    int a;

    if(debug['v'])
        Bprint(&bso, "%5.2f patch\n", cputime());
    Bflush(&bso);
    mkfwd();
    s = lookup("exit", 0);
    vexit = s->value;
    for(p = firstp; p != P; p = p->link) {
        setarch(p);
        a = p->as;
        if(a == ATEXT)
            curtext = p;
        if(seenthumb && a == ABL) {
            // if((s = p->to.sym) != S && (s1 = curtext->from.sym) != S)
            //	print("%s calls %s\n", s1->name, s->name);
            if((s = p->to.sym) != S && (s1 = curtext->from.sym) != S && s->thumb != s1->thumb)
                s->foreign = 1;
        }
        if((a == ABL || a == ABX || a == AB || a == ARET) &&
                p->to.type != D_BRANCH && p->to.sym != S) {
            s = p->to.sym;
            switch(s->type) {
            default:
                diag("undefined: %s\n%P", s->name, p);
                s->type = STEXT;
                s->value = vexit;
                break;
            case STEXT:
                p->to.offset = s->value;
                p->to.type = D_BRANCH;
                break;
            case SUNDEF:
                if(p->as != ABL)
                    diag("help: SUNDEF in AB || ARET");
                p->to.offset = 0;
                p->to.type = D_BRANCH;
                p->cond = UP;
                break;
            }
        }
        if(p->to.type != D_BRANCH || p->cond == UP)
            continue;
        c = p->to.offset;
        for(q = firstp; q != P;) {
            if(q->forwd != P)
                if(c >= q->forwd->pc) {
                    q = q->forwd;
                    continue;
                }
            if(c == q->pc)
                break;
            q = q->link;
        }
        if(q == P) {
            diag("branch out of range %ld\n%P", c, p);
            p->to.type = D_NONE;
        }
        p->cond = q;
    }

    for(p = firstp; p != P; p = p->link) {
        setarch(p);
        a = p->as;
        if(p->as == ATEXT)
            curtext = p;
        if(seenthumb && a == ABL) {
#ifdef CALLEEBX
            if(0)
            {}
#else
            if((s = p->to.sym) != S && (s->foreign || s->fnptr))
                p->as = ABX;
#endif
            else if(p->to.type == D_OREG)
                p->as = ABX;
        }
        if(p->cond != P && p->cond != UP) {
            p->cond = brloop(p->cond);
            if(p->cond != P)
                if(p->to.type == D_BRANCH)
                    p->to.offset = p->cond->pc;
        }
    }
}
Ejemplo n.º 15
0
Archivo: asm.c Proyecto: 8l/go
void
asmb(void)
{
	int32 magic;
	int i;
	vlong vl, symo, dwarfoff, machlink;
	Section *sect;
	LSym *sym;

	if(debug['v'])
		Bprint(&bso, "%5.2f asmb\n", cputime());
	Bflush(&bso);

	if(debug['v'])
		Bprint(&bso, "%5.2f codeblk\n", cputime());
	Bflush(&bso);

	if(iself)
		asmbelfsetup();

	sect = segtext.sect;
	cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
	codeblk(sect->vaddr, sect->len);
	for(sect = sect->next; sect != nil; sect = sect->next) {
		cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
		datblk(sect->vaddr, sect->len);
	}

	if(segrodata.filelen > 0) {
		if(debug['v'])
			Bprint(&bso, "%5.2f rodatblk\n", cputime());
		Bflush(&bso);

		cseek(segrodata.fileoff);
		datblk(segrodata.vaddr, segrodata.filelen);
	}

	if(debug['v'])
		Bprint(&bso, "%5.2f datblk\n", cputime());
	Bflush(&bso);

	cseek(segdata.fileoff);
	datblk(segdata.vaddr, segdata.filelen);

	machlink = 0;
	if(HEADTYPE == Hdarwin) {
		if(debug['v'])
			Bprint(&bso, "%5.2f dwarf\n", cputime());

		dwarfoff = rnd(HEADR+segtext.len, INITRND) + rnd(segdata.filelen, INITRND);
		cseek(dwarfoff);

		segdwarf.fileoff = cpos();
		dwarfemitdebugsections();
		segdwarf.filelen = cpos() - segdwarf.fileoff;

		machlink = domacholink();
	}

	switch(HEADTYPE) {
	default:
		diag("unknown header type %d", HEADTYPE);
	case Hplan9:
	case Helf:
		break;
	case Hdarwin:
		debug['8'] = 1;	/* 64-bit addresses */
		break;
	case Hlinux:
	case Hfreebsd:
	case Hnetbsd:
	case Hopenbsd:
	case Hdragonfly:
	case Hsolaris:
		debug['8'] = 1;	/* 64-bit addresses */
		break;
	case Hnacl:
	case Hwindows:
		break;
	}

	symsize = 0;
	spsize = 0;
	lcsize = 0;
	symo = 0;
	if(!debug['s']) {
		if(debug['v'])
			Bprint(&bso, "%5.2f sym\n", cputime());
		Bflush(&bso);
		switch(HEADTYPE) {
		default:
		case Hplan9:
		case Helf:
			debug['s'] = 1;
			symo = segdata.fileoff+segdata.filelen;
			break;
		case Hdarwin:
			symo = segdata.fileoff+rnd(segdata.filelen, INITRND)+machlink;
			break;
		case Hlinux:
		case Hfreebsd:
		case Hnetbsd:
		case Hopenbsd:
		case Hdragonfly:
		case Hsolaris:
		case Hnacl:
			symo = segdata.fileoff+segdata.filelen;
			symo = rnd(symo, INITRND);
			break;
		case Hwindows:
			symo = segdata.fileoff+segdata.filelen;
			symo = rnd(symo, PEFILEALIGN);
			break;
		}
		cseek(symo);
		switch(HEADTYPE) {
		default:
			if(iself) {
				cseek(symo);
				asmelfsym();
				cflush();
				cwrite(elfstrdat, elfstrsize);

				if(debug['v'])
				       Bprint(&bso, "%5.2f dwarf\n", cputime());

				dwarfemitdebugsections();
				
				if(linkmode == LinkExternal)
					elfemitreloc();
			}
			break;
		case Hplan9:
			asmplan9sym();
			cflush();

			sym = linklookup(ctxt, "pclntab", 0);
			if(sym != nil) {
				lcsize = sym->np;
				for(i=0; i < lcsize; i++)
					cput(sym->p[i]);
				
				cflush();
			}
			break;
		case Hwindows:
			if(debug['v'])
			       Bprint(&bso, "%5.2f dwarf\n", cputime());

			dwarfemitdebugsections();
			break;
		case Hdarwin:
			if(linkmode == LinkExternal)
				machoemitreloc();
			break;
		}
	}

	if(debug['v'])
		Bprint(&bso, "%5.2f headr\n", cputime());
	Bflush(&bso);
	cseek(0L);
	switch(HEADTYPE) {
	default:
	case Hplan9:	/* plan9 */
		magic = 4*26*26+7;
		magic |= 0x00008000;		/* fat header */
		lputb(magic);			/* magic */
		lputb(segtext.filelen);			/* sizes */
		lputb(segdata.filelen);
		lputb(segdata.len - segdata.filelen);
		lputb(symsize);			/* nsyms */
		vl = entryvalue();
		lputb(PADDR(vl));		/* va of entry */
		lputb(spsize);			/* sp offsets */
		lputb(lcsize);			/* line offsets */
		vputb(vl);			/* va of entry */
		break;
	case Hdarwin:
		asmbmacho();
		break;
	case Hlinux:
	case Hfreebsd:
	case Hnetbsd:
	case Hopenbsd:
	case Hdragonfly:
	case Hsolaris:
	case Hnacl:
		asmbelf(symo);
		break;
	case Hwindows:
		asmbpe();
		break;
	}
	cflush();
}
Ejemplo n.º 16
0
void
datblk(int64 addr, int64 size)
{
	LSym *sym;
	int64 i, eaddr;
	uchar *p, *ep;
	char *typ, *rsname;
	Reloc *r;

	if(debug['a'])
		Bprint(&bso, "datblk [%#x,%#x) at offset %#llx\n", addr, addr+size, cpos());

	blk(datap, addr, size);

	/* again for printing */
	if(!debug['a'])
		return;

	for(sym = datap; sym != nil; sym = sym->next)
		if(sym->value >= addr)
			break;

	eaddr = addr + size;
	for(; sym != nil; sym = sym->next) {
		if(sym->value >= eaddr)
			break;
		if(addr < sym->value) {
			Bprint(&bso, "\t%.8ux| 00 ...\n", addr);
			addr = sym->value;
		}
		Bprint(&bso, "%s\n\t%.8ux|", sym->name, (uint)addr);
		p = sym->p;
		ep = p + sym->np;
		while(p < ep) {
			if(p > sym->p && (int)(p-sym->p)%16 == 0)
				Bprint(&bso, "\n\t%.8ux|", (uint)(addr+(p-sym->p)));
			Bprint(&bso, " %.2ux", *p++);
		}
		addr += sym->np;
		for(; addr < sym->value+sym->size; addr++)
			Bprint(&bso, " %.2ux", 0);
		Bprint(&bso, "\n");
		
		if(linkmode == LinkExternal) {
			for(i=0; i<sym->nr; i++) {
				r = &sym->r[i];
				rsname = "";
				if(r->sym)
					rsname = r->sym->name;
				typ = "?";
				switch(r->type) {
				case R_ADDR:
					typ = "addr";
					break;
				case R_PCREL:
					typ = "pcrel";
					break;
				case R_CALL:
					typ = "call";
					break;
				}
				Bprint(&bso, "\treloc %.8ux/%d %s %s+%#llx [%#llx]\n",
					(uint)(sym->value+r->off), r->siz, typ, rsname, (vlong)r->add, (vlong)(r->sym->value+r->add));
			}
		}				
	}

	if(addr < eaddr)
		Bprint(&bso, "\t%.8ux| 00 ...\n", (uint)addr);
	Bprint(&bso, "\t%.8ux|\n", (uint)eaddr);
}
Ejemplo n.º 17
0
Archivo: pass.c Proyecto: gnanderson/go
void
patch(void)
{
	int32 c, vexit;
	Prog *p, *q;
	Sym *s;
	int a;

	if(debug['v'])
		Bprint(&bso, "%5.2f patch\n", cputime());
	Bflush(&bso);
	mkfwd();
	s = lookup("exit", 0);
	vexit = s->value;
	for(cursym = textp; cursym != nil; cursym = cursym->next) {
		for(p = cursym->text; p != P; p = p->link) {
			a = p->as;
			if((a == ABL || a == ABX || a == AB || a == ARET) &&
			   p->to.type != D_BRANCH && p->to.sym != S) {
				s = p->to.sym;
				if(s->text == nil)
					continue;
				switch(s->type&SMASK) {
				default:
					diag("undefined: %s", s->name);
					s->type = STEXT;
					s->value = vexit;
					continue;	// avoid more error messages
				case STEXT:
					p->to.offset = s->value;
					p->to.type = D_BRANCH;
					p->cond = s->text;
					continue;
				}
			}
			if(p->to.type != D_BRANCH)
				continue;
			c = p->to.offset;
			for(q = cursym->text; q != P;) {
				if(c == q->pc)
					break;
				if(q->forwd != P && c >= q->forwd->pc)
					q = q->forwd;
				else
					q = q->link;
			}
			if(q == P) {
				diag("branch out of range %d\n%P", c, p);
				p->to.type = D_NONE;
			}
			p->cond = q;
		}
	}

	for(cursym = textp; cursym != nil; cursym = cursym->next) {
		for(p = cursym->text; p != P; p = p->link) {
			if(p->cond != P) {
				p->cond = brloop(p->cond);
				if(p->cond != P)
				if(p->to.type == D_BRANCH)
					p->to.offset = p->cond->pc;
			}
		}
	}
}
Ejemplo n.º 18
0
void
dodata(void)
{
	int32 n;
	vlong datsize;
	Section *sect;
	Segment *segro;
	LSym *s, *last, **l;
	LSym *gcdata, *gcbss;
	ProgGen gen;

	if(debug['v'])
		Bprint(&bso, "%5.2f dodata\n", cputime());
	Bflush(&bso);

	last = nil;
	datap = nil;

	for(s=ctxt->allsym; s!=S; s=s->allsym) {
		if(!s->reachable || s->special)
			continue;
		if(STEXT < s->type && s->type < SXREF) {
			if(s->onlist)
				sysfatal("symbol %s listed multiple times", s->name);
			s->onlist = 1;
			if(last == nil)
				datap = s;
			else
				last->next = s;
			s->next = nil;
			last = s;
		}
	}

	for(s = datap; s != nil; s = s->next) {
		if(s->np > s->size)
			diag("%s: initialize bounds (%lld < %d)",
				s->name, (vlong)s->size, s->np);
	}


	/*
	 * now that we have the datap list, but before we start
	 * to assign addresses, record all the necessary
	 * dynamic relocations.  these will grow the relocation
	 * symbol, which is itself data.
	 *
	 * on darwin, we need the symbol table numbers for dynreloc.
	 */
	if(HEADTYPE == Hdarwin)
		machosymorder();
	dynreloc();

	/* some symbols may no longer belong in datap (Mach-O) */
	for(l=&datap; (s=*l) != nil; ) {
		if(s->type <= STEXT || SXREF <= s->type)
			*l = s->next;
		else
			l = &s->next;
	}
	*l = nil;

	datap = listsort(datap, datcmp, offsetof(LSym, next));

	/*
	 * allocate sections.  list is sorted by type,
	 * so we can just walk it for each piece we want to emit.
	 * segdata is processed before segtext, because we need
	 * to see all symbols in the .data and .bss sections in order
	 * to generate garbage collection information.
	 */

	/* begin segdata */

	/* skip symbols belonging to segtext */
	s = datap;
	for(; s != nil && s->type < SELFSECT; s = s->next)
		;

	/* writable ELF sections */
	datsize = 0;
	for(; s != nil && s->type < SNOPTRDATA; s = s->next) {
		sect = addsection(&segdata, s->name, 06);
		sect->align = symalign(s);
		datsize = rnd(datsize, sect->align);
		sect->vaddr = datsize;
		s->sect = sect;
		s->type = SDATA;
		s->value = datsize - sect->vaddr;
		growdatsize(&datsize, s);
		sect->len = datsize - sect->vaddr;
	}

	/* pointer-free data */
	sect = addsection(&segdata, ".noptrdata", 06);
	sect->align = maxalign(s, SINITARR-1);
	datsize = rnd(datsize, sect->align);
	sect->vaddr = datsize;
	linklookup(ctxt, "runtime.noptrdata", 0)->sect = sect;
	linklookup(ctxt, "runtime.enoptrdata", 0)->sect = sect;
	for(; s != nil && s->type < SINITARR; s = s->next) {
		datsize = aligndatsize(datsize, s);
		s->sect = sect;
		s->type = SDATA;
		s->value = datsize - sect->vaddr;
		growdatsize(&datsize, s);
	}
	sect->len = datsize - sect->vaddr;

	/* shared library initializer */
	if(flag_shared) {
		sect = addsection(&segdata, ".init_array", 06);
		sect->align = maxalign(s, SINITARR);
		datsize = rnd(datsize, sect->align);
		sect->vaddr = datsize;
		for(; s != nil && s->type == SINITARR; s = s->next) {
			datsize = aligndatsize(datsize, s);
			s->sect = sect;
			s->value = datsize - sect->vaddr;
			growdatsize(&datsize, s);
		}
		sect->len = datsize - sect->vaddr;
	}

	/* data */
	sect = addsection(&segdata, ".data", 06);
	sect->align = maxalign(s, SBSS-1);
	datsize = rnd(datsize, sect->align);
	sect->vaddr = datsize;
	linklookup(ctxt, "runtime.data", 0)->sect = sect;
	linklookup(ctxt, "runtime.edata", 0)->sect = sect;
	gcdata = linklookup(ctxt, "runtime.gcdata", 0);
	proggeninit(&gen, gcdata);
	for(; s != nil && s->type < SBSS; s = s->next) {
		if(s->type == SINITARR) {
			ctxt->cursym = s;
			diag("unexpected symbol type %d", s->type);
		}
		s->sect = sect;
		s->type = SDATA;
		datsize = aligndatsize(datsize, s);
		s->value = datsize - sect->vaddr;
		proggenaddsym(&gen, s);  // gc
		growdatsize(&datsize, s);
	}
	sect->len = datsize - sect->vaddr;
	proggenfini(&gen, sect->len);  // gc

	/* bss */
	sect = addsection(&segdata, ".bss", 06);
	sect->align = maxalign(s, SNOPTRBSS-1);
	datsize = rnd(datsize, sect->align);
	sect->vaddr = datsize;
	linklookup(ctxt, "runtime.bss", 0)->sect = sect;
	linklookup(ctxt, "runtime.ebss", 0)->sect = sect;
	gcbss = linklookup(ctxt, "runtime.gcbss", 0);
	proggeninit(&gen, gcbss);
	for(; s != nil && s->type < SNOPTRBSS; s = s->next) {
		s->sect = sect;
		datsize = aligndatsize(datsize, s);
		s->value = datsize - sect->vaddr;
		proggenaddsym(&gen, s);  // gc
		growdatsize(&datsize, s);
	}
	sect->len = datsize - sect->vaddr;
	proggenfini(&gen, sect->len);  // gc

	/* pointer-free bss */
	sect = addsection(&segdata, ".noptrbss", 06);
	sect->align = maxalign(s, SNOPTRBSS);
	datsize = rnd(datsize, sect->align);
	sect->vaddr = datsize;
	linklookup(ctxt, "runtime.noptrbss", 0)->sect = sect;
	linklookup(ctxt, "runtime.enoptrbss", 0)->sect = sect;
	for(; s != nil && s->type == SNOPTRBSS; s = s->next) {
		datsize = aligndatsize(datsize, s);
		s->sect = sect;
		s->value = datsize - sect->vaddr;
		growdatsize(&datsize, s);
	}
	sect->len = datsize - sect->vaddr;
	linklookup(ctxt, "runtime.end", 0)->sect = sect;

	// 6g uses 4-byte relocation offsets, so the entire segment must fit in 32 bits.
	if(datsize != (uint32)datsize) {
		diag("data or bss segment too large");
	}
	
	if(iself && linkmode == LinkExternal && s != nil && s->type == STLSBSS && HEADTYPE != Hopenbsd) {
		sect = addsection(&segdata, ".tbss", 06);
		sect->align = PtrSize;
		sect->vaddr = 0;
		datsize = 0;
		for(; s != nil && s->type == STLSBSS; s = s->next) {
			datsize = aligndatsize(datsize, s);
			s->sect = sect;
			s->value = datsize - sect->vaddr;
			growdatsize(&datsize, s);
		}
		sect->len = datsize;
	} else {
		// Might be internal linking but still using cgo.
		// In that case, the only possible STLSBSS symbol is runtime.tlsg.
		// Give it offset 0, because it's the only thing here.
		if(s != nil && s->type == STLSBSS && strcmp(s->name, "runtime.tlsg") == 0) {
			s->value = 0;
			s = s->next;
		}
	}
	
	if(s != nil) {
		ctxt->cursym = nil;
		diag("unexpected symbol type %d for %s", s->type, s->name);
	}

	/*
	 * We finished data, begin read-only data.
	 * Not all systems support a separate read-only non-executable data section.
	 * ELF systems do.
	 * OS X and Plan 9 do not.
	 * Windows PE may, but if so we have not implemented it.
	 * And if we're using external linking mode, the point is moot,
	 * since it's not our decision; that code expects the sections in
	 * segtext.
	 */
	if(iself && linkmode == LinkInternal)
		segro = &segrodata;
	else
		segro = &segtext;

	s = datap;
	
	datsize = 0;
	
	/* read-only executable ELF, Mach-O sections */
	for(; s != nil && s->type < STYPE; s = s->next) {
		sect = addsection(&segtext, s->name, 04);
		sect->align = symalign(s);
		datsize = rnd(datsize, sect->align);
		sect->vaddr = datsize;
		s->sect = sect;
		s->type = SRODATA;
		s->value = datsize - sect->vaddr;
		growdatsize(&datsize, s);
		sect->len = datsize - sect->vaddr;
	}

	/* read-only data */
	sect = addsection(segro, ".rodata", 04);
	sect->align = maxalign(s, STYPELINK-1);
	datsize = rnd(datsize, sect->align);
	sect->vaddr = 0;
	linklookup(ctxt, "runtime.rodata", 0)->sect = sect;
	linklookup(ctxt, "runtime.erodata", 0)->sect = sect;
	for(; s != nil && s->type < STYPELINK; s = s->next) {
		datsize = aligndatsize(datsize, s);
		s->sect = sect;
		s->type = SRODATA;
		s->value = datsize - sect->vaddr;
		growdatsize(&datsize, s);
	}
	sect->len = datsize - sect->vaddr;

	/* typelink */
	sect = addsection(segro, ".typelink", 04);
	sect->align = maxalign(s, STYPELINK);
	datsize = rnd(datsize, sect->align);
	sect->vaddr = datsize;
	linklookup(ctxt, "runtime.typelink", 0)->sect = sect;
	linklookup(ctxt, "runtime.etypelink", 0)->sect = sect;
	for(; s != nil && s->type == STYPELINK; s = s->next) {
		datsize = aligndatsize(datsize, s);
		s->sect = sect;
		s->type = SRODATA;
		s->value = datsize - sect->vaddr;
		growdatsize(&datsize, s);
	}
	sect->len = datsize - sect->vaddr;

	/* gosymtab */
	sect = addsection(segro, ".gosymtab", 04);
	sect->align = maxalign(s, SPCLNTAB-1);
	datsize = rnd(datsize, sect->align);
	sect->vaddr = datsize;
	linklookup(ctxt, "runtime.symtab", 0)->sect = sect;
	linklookup(ctxt, "runtime.esymtab", 0)->sect = sect;
	for(; s != nil && s->type < SPCLNTAB; s = s->next) {
		datsize = aligndatsize(datsize, s);
		s->sect = sect;
		s->type = SRODATA;
		s->value = datsize - sect->vaddr;
		growdatsize(&datsize, s);
	}
	sect->len = datsize - sect->vaddr;

	/* gopclntab */
	sect = addsection(segro, ".gopclntab", 04);
	sect->align = maxalign(s, SELFROSECT-1);
	datsize = rnd(datsize, sect->align);
	sect->vaddr = datsize;
	linklookup(ctxt, "runtime.pclntab", 0)->sect = sect;
	linklookup(ctxt, "runtime.epclntab", 0)->sect = sect;
	for(; s != nil && s->type < SELFROSECT; s = s->next) {
		datsize = aligndatsize(datsize, s);
		s->sect = sect;
		s->type = SRODATA;
		s->value = datsize - sect->vaddr;
		growdatsize(&datsize, s);
	}
	sect->len = datsize - sect->vaddr;

	/* read-only ELF, Mach-O sections */
	for(; s != nil && s->type < SELFSECT; s = s->next) {
		sect = addsection(segro, s->name, 04);
		sect->align = symalign(s);
		datsize = rnd(datsize, sect->align);
		sect->vaddr = datsize;
		s->sect = sect;
		s->type = SRODATA;
		s->value = datsize - sect->vaddr;
		growdatsize(&datsize, s);
		sect->len = datsize - sect->vaddr;
	}

	// 6g uses 4-byte relocation offsets, so the entire segment must fit in 32 bits.
	if(datsize != (uint32)datsize) {
		diag("read-only data segment too large");
	}
	
	/* number the sections */
	n = 1;
	for(sect = segtext.sect; sect != nil; sect = sect->next)
		sect->extnum = n++;
	for(sect = segrodata.sect; sect != nil; sect = sect->next)
		sect->extnum = n++;
	for(sect = segdata.sect; sect != nil; sect = sect->next)
		sect->extnum = n++;
}
Ejemplo n.º 19
0
void
comline(void)
{
	long c1, c2;

	while(C==' ' || c=='\t')
		;
comx:
	if((c1=c) == '\n')
		return;
	c2 = C;
	if(c1=='.' && c2!='.')
		inmacro = NO;
	if(msflag && c1 == '['){
		refer(c2);
		return;
	}
	if(c2 == '\n')
		return;
	if(c1 == '\\' && c2 == '\"')
		SKIP;
	else
	if (filesp==files && c1=='E' && c2=='Q')
			eqn();
	else
	if(filesp==files && c1=='T' && (c2=='S' || c2=='C' || c2=='&')) {
		if(msflag)
			stbl(); 
		else
			tbl();
	}
	else
	if(c1=='T' && c2=='E')
		intable = NO;
	else if (!inmacro &&
			((c1 == 'd' && c2 == 'e') ||
		   	 (c1 == 'i' && c2 == 'g') ||
		   	 (c1 == 'a' && c2 == 'm')))
				macro();
	else
	if(c1=='s' && c2=='o') {
		if(iflag)
			SKIP;
		else {
			getfname();
			if(fname[0]) {
				if(infile = opn(fname))
					*++filesp = infile;
				else infile = *filesp;
			}
		}
	}
	else
	if(c1=='n' && c2=='x')
		if(iflag)
			SKIP;
		else {
			getfname();
			if(fname[0] == '\0')
				exits(0);
			if(Bfildes(&(infile->Biobufhdr)) != 0)
				Bterm(&(infile->Biobufhdr));
			infile = *filesp = opn(fname);
		}
	else
	if(c1 == 't' && c2 == 'm')
		SKIP;
	else
	if(c1=='h' && c2=='w')
		SKIP; 
	else
	if(msflag && c1 == 'T' && c2 == 'L') {
		SKIP_TO_COM;
		goto comx; 
	}
	else
	if(msflag && c1=='N' && c2 == 'R')
		SKIP;
	else
	if(msflag && c1 == 'A' && (c2 == 'U' || c2 == 'I')){
		if(mac==MM)SKIP;
		else {
			SKIP_TO_COM;
			goto comx; 
		}
	} else
	if(msflag && c1=='F' && c2=='S') {
		SKIP_TO_COM;
		goto comx; 
	}
	else
	if(msflag && (c1=='S' || c1=='N') && c2=='H') {
		SKIP_TO_COM;
		goto comx; 
	} else
	if(c1 == 'U' && c2 == 'X') {
		if(wordflag)
			Bprint(&(bout.Biobufhdr), "UNIX\n");
		else
			Bprint(&(bout.Biobufhdr), "UNIX ");
	} else
	if(msflag && c1=='O' && c2=='K') {
		SKIP_TO_COM;
		goto comx; 
	} else
	if(msflag && c1=='N' && c2=='D')
		SKIP;
	else
	if(msflag && mac==MM && c1=='H' && (c2==' '||c2=='U'))
		SKIP;
	else
	if(msflag && mac==MM && c2=='L') {
		if(disp || c1=='R')
			sdis('L', 'E');
		else {
			SKIP;
			Bprint(&(bout.Biobufhdr), " .");
		}
	} else
	if(!msflag && c1=='P' && c2=='S') {
		inpic();
	} else
	if(msflag && (c1=='D' || c1=='N' || c1=='K'|| c1=='P') && c2=='S') { 
		sdis(c1, 'E'); 
	} else
	if(msflag && (c1 == 'K' && c2 == 'F')) { 
		sdis(c1,'E'); 
	} else
	if(msflag && c1=='n' && c2=='f')
		sdis('f','i');
	else
	if(msflag && c1=='c' && c2=='e')
		sce();
	else {
		if(c1=='.' && c2=='.') {
			if(msflag) {
				SKIP;
				return;
			}
			while(C == '.')
				;
		}
		inmacro++;
		if(c1 <= 'Z' && msflag)
			regline(YES,ONE);
		else {
			if(wordflag)
				C;
			regline(YES,TWO);
		}
		inmacro--;
	}
}
Ejemplo n.º 20
0
Archivo: qi.c Proyecto: 99years/plan9
void
procinit(int pid)
{
	char *p;
	Segment *s;
	int n, m, sg, i;
	ulong vastart, vaend;
	char mfile[128], tfile[128], sfile[1024];

	sprint(mfile, "/proc/%d/mem", pid);
	sprint(tfile, "/proc/%d/text", pid);
	sprint(sfile, "/proc/%d/segment", pid);

	text = open(tfile, OREAD);
	if(text < 0)
		fatal(1, "open text %s", tfile);
	inithdr(text);

	sg = open(sfile, OREAD);
	if(sg < 0)
		fatal(1, "open text %s", sfile);

	n = read(sg, sfile, sizeof(sfile));
	if(n >= sizeof(sfile))
		fatal(0, "segment file buffer too small");
	close(sg);

	m = open(mfile, OREAD);
	if(m < 0)
		fatal(1, "open %s", mfile);

	initmap();

	p = strstr(sfile, "Data");
	if(p == 0)
		fatal(0, "no data");

	vastart = strtoul(p+9, 0, 16);
	vaend = strtoul(p+18, 0, 16);
	s = &memory.seg[Data];
	if(s->base != vastart || s->end != vaend) {
		s->base = vastart;
		s->end = vaend;
		free(s->table);
		s->table = malloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
	}
	seginit(m, s, 0, vastart, vaend);
	
	p = strstr(sfile, "Bss");
	if(p == 0)
		fatal(0, "no bss");

	vastart = strtoul(p+9, 0, 16);
	vaend = strtoul(p+18, 0, 16);
	s = &memory.seg[Bss];
	if(s->base != vastart || s->end != vaend) {
		s->base = vastart;
		s->end = vaend;
		free(s->table);
		s->table = malloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
	}
	seginit(m, s, 0, vastart, vaend);

	reg.pc = greg(m, REGOFF(pc));
	reg.r[1] = greg(m, REGOFF(sp));
	reg.r[2] = greg(m, REGOFF(r2));
	reg.r[30] = greg(m, REGOFF(r30));
	reg.r[31] = greg(m, REGOFF(r31));

	for(i = 0; i < 32; i++)
		reg.r[i] = greg(m, roff[i-1]);

	s = &memory.seg[Stack];
	vastart = reg.r[1] & ~(BY2PG-1);
	seginit(m, s, (vastart-s->base)/BY2PG, vastart, STACKTOP);
	close(m);
	Bprint(bioout, "qi\n"); 
}
Ejemplo n.º 21
0
void
patch(void)
{
	int32 c;
	Prog *p, *q;
	Sym *s;
	int32 vexit;

	if(debug['v'])
		Bprint(&bso, "%5.2f mkfwd\n", cputime());
	Bflush(&bso);
	mkfwd();
	if(debug['v'])
		Bprint(&bso, "%5.2f patch\n", cputime());
	Bflush(&bso);

	s = lookup("exit", 0);
	vexit = s->value;
	for(cursym = textp; cursym != nil; cursym = cursym->next)
	for(p = cursym->text; p != P; p = p->link) {
		if(HEADTYPE == Hwindows) { 
			// Windows
			// Convert
			//   op	  n(GS), reg
			// to
			//   MOVL 0x28(GS), reg
			//   op	  n(reg), reg
			// The purpose of this patch is to fix some accesses
			// to extern register variables (TLS) on Windows, as
			// a different method is used to access them.
			if(p->from.type == D_INDIR+D_GS
			&& p->to.type >= D_AX && p->to.type <= D_DI 
			&& p->from.offset <= 8) {
				q = appendp(p);
				q->from = p->from;
				q->from.type = D_INDIR + p->to.type;
				q->to = p->to;
				q->as = p->as;
				p->as = AMOVQ;
				p->from.type = D_INDIR+D_GS;
				p->from.offset = 0x28;
			}
		}
		if(HEADTYPE == Hlinux || HEADTYPE == Hfreebsd
		|| HEADTYPE == Hopenbsd || HEADTYPE == Hnetbsd) {
			// ELF uses FS instead of GS.
			if(p->from.type == D_INDIR+D_GS)
				p->from.type = D_INDIR+D_FS;
			if(p->to.type == D_INDIR+D_GS)
				p->to.type = D_INDIR+D_FS;
		}
		if(p->as == ACALL || (p->as == AJMP && p->to.type != D_BRANCH)) {
			s = p->to.sym;
			if(s) {
				if(debug['c'])
					Bprint(&bso, "%s calls %s\n", TNAME, s->name);
				if((s->type&~SSUB) != STEXT) {
					/* diag prints TNAME first */
					diag("undefined: %s", s->name);
					s->type = STEXT;
					s->value = vexit;
					continue;	// avoid more error messages
				}
				if(s->text == nil)
					continue;
				p->to.type = D_BRANCH;
				p->to.offset = s->text->pc;
				p->pcond = s->text;
				continue;
			}
		}
		if(p->to.type != D_BRANCH)
			continue;
		c = p->to.offset;
		for(q = cursym->text; q != P;) {
			if(c == q->pc)
				break;
			if(q->forwd != P && c >= q->forwd->pc)
				q = q->forwd;
			else
				q = q->link;
		}
		if(q == P) {
			diag("branch out of range in %s (%#ux)\n%P [%s]",
				TNAME, c, p, p->to.sym ? p->to.sym->name : "<nil>");
			p->to.type = D_NONE;
		}
		p->pcond = q;
	}

	for(cursym = textp; cursym != nil; cursym = cursym->next)
	for(p = cursym->text; p != P; p = p->link) {
		p->mark = 0;	/* initialization for follow */
		if(p->pcond != P) {
			p->pcond = brloop(p->pcond);
			if(p->pcond != P)
			if(p->to.type == D_BRANCH)
				p->to.offset = p->pcond->pc;
		}
	}
}
Ejemplo n.º 22
0
void
main(int argc, char *argv[])
{
	int i, c;
	char *a;

	Binit(&bso, 1, OWRITE);
	cout = -1;
	listinit();
	memset(debug, 0, sizeof(debug));
	nerrors = 0;
	outfile = "8.out";
	HEADTYPE = -1;
	INITTEXT = -1;
	INITDAT = -1;
	INITRND = -1;
	INITENTRY = 0;
	ARGBEGIN {
	default:
		c = ARGC();
		if(c >= 0 && c < sizeof(debug))
			debug[c]++;
		break;
	case 'o': /* output to (next arg) */
		outfile = ARGF();
		break;
	case 'E':
		a = ARGF();
		if(a)
			INITENTRY = a;
		break;
	case 'H':
		a = ARGF();
		if(a)
			HEADTYPE = atolwhex(a);
		break;
	case 'T':
		a = ARGF();
		if(a)
			INITTEXT = atolwhex(a);
		break;
	case 'D':
		a = ARGF();
		if(a)
			INITDAT = atolwhex(a);
		break;
	case 'R':
		a = ARGF();
		if(a)
			INITRND = atolwhex(a);
		break;
	case 'x':	/* produce export table */
		doexp = 1;
		if(argv[1] != nil && argv[1][0] != '-' && !isobjfile(argv[1]))
			readundefs(ARGF(), SEXPORT);
		break;
	case 'u':	/* produce dynamically loadable module */
		dlm = 1;
		debug['l']++;
		if(argv[1] != nil && argv[1][0] != '-' && !isobjfile(argv[1]))
			readundefs(ARGF(), SIMPORT);
		break;
	} ARGEND
	USED(argc);
	if(*argv == 0) {
		diag("usage: 8l [-options] objects");
		errorexit();
	}
	if(!debug['9'] && !debug['U'] && !debug['B'])
		debug[DEFAULT] = 1;
	if(HEADTYPE == -1) {
		if(debug['U'])
			HEADTYPE = 1;
		if(debug['B'])
			HEADTYPE = 2;
		if(debug['9'])
			HEADTYPE = 2;
	}
	switch(HEADTYPE) {
	default:
		diag("unknown -H option");
		errorexit();

	case 0:	/* this is garbage */
		HEADR = 20L+56L;
		if(INITTEXT == -1)
			INITTEXT = 0x40004CL;
		if(INITDAT == -1)
			INITDAT = 0x10000000L;
		if(INITRND == -1)
			INITRND = 0;
		break;
	case 1:	/* is unix coff */
		HEADR = 0xd0L;
		if(INITTEXT == -1)
			INITTEXT = 0xd0;
		if(INITDAT == -1)
			INITDAT = 0x400000;
		if(INITRND == -1)
			INITRND = 0;
		break;
	case 2:	/* plan 9 */
		HEADR = 32L;
		if(INITTEXT == -1)
			INITTEXT = 4096+32;
		if(INITDAT == -1)
			INITDAT = 0;
		if(INITRND == -1)
			INITRND = 4096;
		break;
	case 3:	/* MS-DOS .COM */
		HEADR = 0;
		if(INITTEXT == -1)
			INITTEXT = 0x0100;
		if(INITDAT == -1)
			INITDAT = 0;
		if(INITRND == -1)
			INITRND = 4;
		break;
	case 4:	/* fake MS-DOS .EXE */
		HEADR = 0x200;
		if(INITTEXT == -1)
			INITTEXT = 0x0100;
		if(INITDAT == -1)
			INITDAT = 0;
		if(INITRND == -1)
			INITRND = 4;
		HEADR += (INITTEXT & 0xFFFF);
		if(debug['v'])
			Bprint(&bso, "HEADR = 0x%ld\n", HEADR);
		break;
	case 5:	/* elf executable */
		HEADR = rnd(52L+3*32L, 16);
		if(INITTEXT == -1)
			INITTEXT = 0x80100020L;
		if(INITDAT == -1)
			INITDAT = 0;
		if(INITRND == -1)
			INITRND = 4096;
		break;
	}
	if(INITDAT != 0 && INITRND != 0)
		print("warning: -D0x%lux is ignored because of -R0x%lux\n",
			INITDAT, INITRND);
	if(debug['v'])
		Bprint(&bso, "HEADER = -H0x%ld -T0x%lux -D0x%lux -R0x%lux\n",
			HEADTYPE, INITTEXT, INITDAT, INITRND);
	Bflush(&bso);
	for(i=1; optab[i].as; i++)
		if(i != optab[i].as) {
			diag("phase error in optab: %d", i);
			errorexit();
		}

	for(i=0; i<Ymax; i++)
		ycover[i*Ymax + i] = 1;

	ycover[Yi0*Ymax + Yi8] = 1;
	ycover[Yi1*Ymax + Yi8] = 1;

	ycover[Yi0*Ymax + Yi32] = 1;
	ycover[Yi1*Ymax + Yi32] = 1;
	ycover[Yi8*Ymax + Yi32] = 1;

	ycover[Yal*Ymax + Yrb] = 1;
	ycover[Ycl*Ymax + Yrb] = 1;
	ycover[Yax*Ymax + Yrb] = 1;
	ycover[Ycx*Ymax + Yrb] = 1;
	ycover[Yrx*Ymax + Yrb] = 1;

	ycover[Yax*Ymax + Yrx] = 1;
	ycover[Ycx*Ymax + Yrx] = 1;

	ycover[Yax*Ymax + Yrl] = 1;
	ycover[Ycx*Ymax + Yrl] = 1;
	ycover[Yrx*Ymax + Yrl] = 1;

	ycover[Yf0*Ymax + Yrf] = 1;

	ycover[Yal*Ymax + Ymb] = 1;
	ycover[Ycl*Ymax + Ymb] = 1;
	ycover[Yax*Ymax + Ymb] = 1;
	ycover[Ycx*Ymax + Ymb] = 1;
	ycover[Yrx*Ymax + Ymb] = 1;
	ycover[Yrb*Ymax + Ymb] = 1;
	ycover[Ym*Ymax + Ymb] = 1;

	ycover[Yax*Ymax + Yml] = 1;
	ycover[Ycx*Ymax + Yml] = 1;
	ycover[Yrx*Ymax + Yml] = 1;
	ycover[Yrl*Ymax + Yml] = 1;
	ycover[Ym*Ymax + Yml] = 1;

	for(i=0; i<D_NONE; i++) {
		reg[i] = -1;
		if(i >= D_AL && i <= D_BH)
			reg[i] = (i-D_AL) & 7;
		if(i >= D_AX && i <= D_DI)
			reg[i] = (i-D_AX) & 7;
		if(i >= D_F0 && i <= D_F0+7)
			reg[i] = (i-D_F0) & 7;
	}

	zprg.link = P;
	zprg.pcond = P;
	zprg.back = 2;
	zprg.as = AGOK;
	zprg.from.type = D_NONE;
	zprg.from.index = D_NONE;
	zprg.from.scale = 1;
	zprg.to = zprg.from;

	pcstr = "%.6lux ";
	nuxiinit();
	histgen = 0;
	textp = P;
	datap = P;
	edatap = P;
	pc = 0;
	dtype = 4;
	cout = create(outfile, 1, 0775);
	if(cout < 0) {
		diag("cannot create %s", outfile);
		errorexit();
	}
	version = 0;
	cbp = buf.cbuf;
	cbc = sizeof(buf.cbuf);
	firstp = prg();
	lastp = firstp;

	if(INITENTRY == 0) {
		INITENTRY = "_main";
		if(debug['p'])
			INITENTRY = "_mainp";
		if(!debug['l'])
			lookup(INITENTRY, 0)->type = SXREF;
	} else
		lookup(INITENTRY, 0)->type = SXREF;

	while(*argv)
		objfile(*argv++);
	if(!debug['l'])
		loadlib();
	firstp = firstp->link;
	if(firstp == P)
		errorexit();
	if(doexp || dlm){
		EXPTAB = "_exporttab";
		zerosig(EXPTAB);
		zerosig("etext");
		zerosig("edata");
		zerosig("end");
		if(dlm){
			import();
			HEADTYPE = 2;
			INITTEXT = INITDAT = 0;
			INITRND = 8;
			INITENTRY = EXPTAB;
		}
		export();
Ejemplo n.º 23
0
void
slangprintkey(void)
{
	Bprint(bout, "No key\n");
}
Ejemplo n.º 24
0
void
main(int argc, char *argv[])
{
	Dir *db;
	Lsym *l;
	Node *n;
	char buf[128], *s;
	int pid, i;
	char *p;
	char afile[512];

	argv0 = argv[0];
	pid = 0;
	aout = "v.out";
	quiet = 1;
	/* turn off all debugging */
	protodebug = 0;

	mtype = 0;
	ARGBEGIN{
	case 'm':
		mtype = ARGF();
		break;
	case 'w':
		wtflag = 1;
		break;
	case 'l':
		s = ARGF();
		if(s == 0)
			usage();
		lm[nlm++] = s;
		break;
	case 'd':
		p = ARGF();
		if (p == 0)
			usage();
		while (*p) {
			setdbg_opt(*p, 0); /* don't print set message */
			p++;
		}
		break;
	case 'k':
		kernel++;
		break;
	case 'q':
		quiet = 0;
		break;
	case 'r':
		pid = 1;
		remote++;
		kernel++;
		break;
	case 'R':
		pid = 1;
		rdebug++;
		s = ARGF();
		if(s == 0)
			usage();
		remfd = opentty(s, 0);
		if(remfd < 0){
			fprint(2, "acid: can't open %s: %r\n", s);
			exits("open");
		}
		break;
	default:
		usage();
	}ARGEND

	if(argc > 0) {
		if(remote || rdebug)
			aout = argv[0];
		else
		if(isnumeric(argv[0])) {
			pid = atoi(argv[0]);
			sprint(prog, "/proc/%d/text", pid);
			aout = prog;
			if(argc > 1)
				aout = argv[1];
			else if(kernel)
				aout = mysystem();
		}
		else {
			if(kernel) {
				print("-k requires a pid");
				kernel = 0;
			}
			aout = argv[0];
		}
	} else if(rdebug)
		aout = "/386/bpc";
	else if(remote)
		aout = "/mips/bcarrera";

	fmtinstall('x', xfmt);
	fmtinstall('L', Lfmt);
	fmtinstall('f', gfltconv);
	fmtinstall('F', gfltconv);
	fmtinstall('g', gfltconv);
	fmtinstall('G', gfltconv);
	fmtinstall('e', gfltconv);
	fmtinstall('E', gfltconv);
	Binit(&bioout, 1, OWRITE);
	bout = &bioout;

	kinit();
	initialising = 1;
	pushfile(0);
	loadvars();
	installbuiltin();

	if(mtype && machbyname(mtype) == 0)
		print("unknown machine %s", mtype);

	if (attachfiles(aout, pid) < 0)
		varreg();		/* use default register set on error */

	acidlib = getenv("ACIDLIB");
	if(acidlib == nil){
		p = getenv("ROOT");
		if(p == nil)
			p = "/usr/inferno";
		snprint(afile, sizeof(afile)-1, "%s/lib/acid", p);
		acidlib = strdup(afile);
	}

	snprint(afile, sizeof(afile)-1, "%s/port", acidlib);
	loadmodule(afile);
	for(i = 0; i < nlm; i++) {
		if((db = dirstat(lm[i])) != nil) {
			free(db);
			loadmodule(lm[i]);
		} else {
			sprint(buf, "%s/%s", acidlib, lm[i]);
			loadmodule(buf);
		}
	}

	userinit();
	varsym();

	l = look("acidmap");
	if(l && l->proc) {
		n = an(ONAME, ZN, ZN);
		n->sym = l;
		n = an(OCALL, n, ZN);
		execute(n);
	}

	interactive = 1;
	initialising = 0;
	line = 1;

	setup_os_notify();

	for(;;) {
		if(setjmp(err)) {
			Binit(&bioout, 1, OWRITE);
			unwind();
		}
		stacked = 0;

		Bprint(bout, "acid: ");

		if(yyparse() != 1)
			die();
		restartio();

		unwind();
	}
	/* not reached */
}
Ejemplo n.º 25
0
void
ldobj1(Biobuf *f, char *pkg, int64 len, char *pn)
{
	int32 ipc;
	Prog *p;
	Sym *h[NSYM], *s;
	int v, o, r, skip;
	uint32 sig;
	char *name;
	int ntext;
	int32 eof;
	char src[1024], *x;
	Prog *lastp;

	lastp = nil;
	ntext = 0;
	eof = Boffset(f) + len;
	src[0] = 0;

newloop:
	memset(h, 0, sizeof(h));
	version++;
	histfrogp = 0;
	ipc = pc;
	skip = 0;

loop:
	if(f->state == Bracteof || Boffset(f) >= eof)
		goto eof;
	o = Bgetc(f);
	if(o == Beof)
		goto eof;

	if(o <= AXXX || o >= ALAST) {
		diag("%s:#%lld: opcode out of range: %#ux", pn, Boffset(f), o);
		print("	probably not a .5 file\n");
		errorexit();
	}
	if(o == ANAME || o == ASIGNAME) {
		sig = 0;
		if(o == ASIGNAME)
			sig = Bget4(f);
		v = Bgetc(f); /* type */
		o = Bgetc(f); /* sym */
		r = 0;
		if(v == D_STATIC)
			r = version;
		name = Brdline(f, '\0');
		if(name == nil) {
			if(Blinelen(f) > 0) {
				fprint(2, "%s: name too long\n", pn);
				errorexit();
			}
			goto eof;
		}
		x = expandpkg(name, pkg);
		s = lookup(x, r);
		if(x != name)
			free(x);

		if(sig != 0){
			if(s->sig != 0 && s->sig != sig)
				diag("incompatible type signatures %ux(%s) and %ux(%s) for %s", s->sig, s->file, sig, pn, s->name);
			s->sig = sig;
			s->file = pn;
		}

		if(debug['W'])
			print("	ANAME	%s\n", s->name);
		if(o < 0 || o >= nelem(h)) {
			fprint(2, "%s: mangled input file\n", pn);
			errorexit();
		}
		h[o] = s;
		if((v == D_EXTERN || v == D_STATIC) && s->type == 0)
			s->type = SXREF;
		if(v == D_FILE) {
			if(s->type != SFILE) {
				histgen++;
				s->type = SFILE;
				s->value = histgen;
			}
			if(histfrogp < MAXHIST) {
				histfrog[histfrogp] = s;
				histfrogp++;
			} else
				collapsefrog(s);
		}
		goto loop;
	}

	p = mal(sizeof(Prog));
	p->as = o;
	p->scond = Bgetc(f);
	p->reg = Bgetc(f);
	p->line = Bget4(f);

	zaddr(f, &p->from, h);
	zaddr(f, &p->to, h);

	if(p->as != ATEXT && p->as != AGLOBL && p->reg > NREG)
		diag("register out of range %A %d", p->as, p->reg);

	p->link = P;
	p->cond = P;

	if(debug['W'])
		print("%P\n", p);

	switch(o) {
	case AHISTORY:
		if(p->to.offset == -1) {
			addlib(src, pn);
			histfrogp = 0;
			goto loop;
		}
		if(src[0] == '\0')
			copyhistfrog(src, sizeof src);
		addhist(p->line, D_FILE);		/* 'z' */
		if(p->to.offset)
			addhist(p->to.offset, D_FILE1);	/* 'Z' */
		histfrogp = 0;
		goto loop;

	case AEND:
		histtoauto();
		if(cursym != nil && cursym->text)
			cursym->autom = curauto;
		curauto = 0;
		cursym = nil;
		if(Boffset(f) == eof)
			return;
		goto newloop;

	case AGLOBL:
		s = p->from.sym;
		if(s == S) {
			diag("GLOBL must have a name\n%P", p);
			errorexit();
		}
		if(s->type == 0 || s->type == SXREF) {
			s->type = SBSS;
			s->value = 0;
		}
		if(s->type != SBSS && s->type != SNOPTRBSS && !s->dupok) {
			diag("redefinition: %s\n%P", s->name, p);
			s->type = SBSS;
			s->value = 0;
		}
		if(p->to.offset > s->size)
			s->size = p->to.offset;
		if(p->reg & DUPOK)
			s->dupok = 1;
		if(p->reg & RODATA)
			s->type = SRODATA;
		else if(p->reg & NOPTR)
			s->type = SNOPTRBSS;
		break;

	case ADATA:
		// Assume that AGLOBL comes after ADATA.
		// If we've seen an AGLOBL that said this sym was DUPOK,
		// ignore any more ADATA we see, which must be
		// redefinitions.
		s = p->from.sym;
		if(s->dupok) {
//			if(debug['v'])
//				Bprint(&bso, "skipping %s in %s: dupok\n", s->name, pn);
			goto loop;
		}
		if(s->file == nil)
			s->file = pn;
		else if(s->file != pn) {
			diag("multiple initialization for %s: in both %s and %s", s->name, s->file, pn);
			errorexit();
		}
		savedata(s, p, pn);
		unmal(p, sizeof *p);
		break;

	case AGOK:
		diag("unknown opcode\n%P", p);
		p->pc = pc;
		pc++;
		break;

	case ATEXT:
		if(cursym != nil && cursym->text) {
			histtoauto();
			cursym->autom = curauto;
			curauto = 0;
		}
		s = p->from.sym;
		if(s == S) {
			diag("TEXT must have a name\n%P", p);
			errorexit();
		}
		cursym = s;
		if(s->type != 0 && s->type != SXREF && (p->reg & DUPOK)) {
			skip = 1;
			goto casedef;
		}
		if(ntext++ == 0 && s->type != 0 && s->type != SXREF) {
			/* redefinition, so file has probably been seen before */
			if(debug['v'])
				Bprint(&bso, "skipping: %s: redefinition: %s", pn, s->name);
			return;
		}
		skip = 0;
		if(s->type != 0 && s->type != SXREF)
			diag("redefinition: %s\n%P", s->name, p);
		if(etextp)
			etextp->next = s;
		else
			textp = s;
		etextp = s;
		p->align = 4;
		autosize = (p->to.offset+3L) & ~3L;
		p->to.offset = autosize;
		autosize += 4;
		s->type = STEXT;
		s->text = p;
		s->value = pc;
		lastp = p;
		p->pc = pc;
		pc++;
		break;

	case ASUB:
		if(p->from.type == D_CONST)
		if(p->from.name == D_NONE)
		if(p->from.offset < 0) {
			p->from.offset = -p->from.offset;
			p->as = AADD;
		}
		goto casedef;

	case AADD:
		if(p->from.type == D_CONST)
		if(p->from.name == D_NONE)
		if(p->from.offset < 0) {
			p->from.offset = -p->from.offset;
			p->as = ASUB;
		}
		goto casedef;

	case AMOVWD:
	case AMOVWF:
	case AMOVDW:
	case AMOVFW:
	case AMOVFD:
	case AMOVDF:
	// case AMOVF:
	// case AMOVD:
	case ACMPF:
	case ACMPD:
	case AADDF:
	case AADDD:
	case ASUBF:
	case ASUBD:
	case AMULF:
	case AMULD:
	case ADIVF:
	case ADIVD:
		goto casedef;

	case AMOVF:
		if(skip)
			goto casedef;

		if(p->from.type == D_FCONST && chipfloat(&p->from.ieee) < 0 &&
		   (chipzero(&p->from.ieee) < 0 || (p->scond & C_SCOND) != C_SCOND_NONE)) {
			/* size sb 9 max */
			sprint(literal, "$%ux", ieeedtof(&p->from.ieee));
			s = lookup(literal, 0);
			if(s->type == 0) {
				s->type = SBSS;
				adduint32(s, ieeedtof(&p->from.ieee));
				s->reachable = 0;
			}
			p->from.type = D_OREG;
			p->from.sym = s;
			p->from.name = D_EXTERN;
			p->from.offset = 0;
		}
		goto casedef;

	case AMOVD:
		if(skip)
			goto casedef;

		if(p->from.type == D_FCONST && chipfloat(&p->from.ieee) < 0 &&
		   (chipzero(&p->from.ieee) < 0 || (p->scond & C_SCOND) != C_SCOND_NONE)) {
			/* size sb 18 max */
			sprint(literal, "$%ux.%ux",
				p->from.ieee.l, p->from.ieee.h);
			s = lookup(literal, 0);
			if(s->type == 0) {
				s->type = SBSS;
				adduint32(s, p->from.ieee.l);
				adduint32(s, p->from.ieee.h);
				s->reachable = 0;
			}
			p->from.type = D_OREG;
			p->from.sym = s;
			p->from.name = D_EXTERN;
			p->from.offset = 0;
		}
		goto casedef;

	default:
	casedef:
		if(skip)
			nopout(p);
		p->pc = pc;
		pc++;
		if(p->to.type == D_BRANCH)
			p->to.offset += ipc;
		if(lastp == nil) {
			if(p->as != ANOP)
				diag("unexpected instruction: %P", p);
			break;
		}
		lastp->link = p;
		lastp = p;
		break;
	}
	goto loop;

eof:
	diag("truncated object file: %s", pn);
}
Ejemplo n.º 26
0
Archivo: t4.c Proyecto: aahud/harvey
void
readspec(void)
{
	int	icol, c, sawchar, stopc, i;
	char	sn[10], *snp, *temp;

	sawchar = icol = 0;
	while (c = get1char()) {
		switch (c) {
		default:
			if (c != tab) {
				char buf[64];
				sprint(buf, "bad table specification character %c", c);
				error(buf);
			}
		case ' ': /* note this is also case tab */
			continue;
		case '\n':
			if (sawchar == 0) 
				continue;
		case ',':
		case '.': /* end of table specification */
			ncol = max(ncol, icol);
			if (lefline[ncol][nclin] > 0) {
				ncol++; 
				rightl++;
			};
			if (sawchar)
				nclin++;
			if (nclin >= MAXHEAD)
				error("too many lines in specification");
			icol = 0;
			if (ncol == 0 || nclin == 0)
				error("no specification");
			if (c == '.') {
				while ((c = get1char()) && c != '\n')
					if (c != ' ' && c != '\t')
						error("dot not last character on format line");
				/* fix up sep - default is 3 except at edge */
				for (icol = 0; icol < ncol; icol++)
					if (sep[icol] < 0)
						sep[icol] =  icol + 1 < ncol ? 3 : 2;
				if (oncol == 0)
					oncol = ncol;
				else if (oncol + 2 < ncol)
					error("tried to widen table in T&, not allowed");
				return;
			}
			sawchar = 0;
			continue;
		case 'C': 
		case 'S': 
		case 'R': 
		case 'N': 
		case 'L':  
		case 'A':
			c += ('a' - 'A');
		case '_': 
			if (c == '_') 
				c = '-';
		case '=': 
		case '-':
		case '^':
		case 'c': 
		case 's': 
		case 'n': 
		case 'r': 
		case 'l':  
		case 'a':
			style[icol][nclin] = c;
			if (c == 's' && icol <= 0)
				error("first column can not be S-type");
			if (c == 's' && style[icol-1][nclin] == 'a') {
				Bprint(&tabout, ".tm warning: can't span a-type cols, changed to l\n");
				style[icol-1][nclin] = 'l';
			}
			if (c == 's' && style[icol-1][nclin] == 'n') {
				Bprint(&tabout, ".tm warning: can't span n-type cols, changed to c\n");
				style[icol-1][nclin] = 'c';
			}
			icol++;
			if (c == '^' && nclin <= 0)
				error("first row can not contain vertical span");
			if (icol > qcol)
				error("too many columns in table");
			sawchar = 1;
			continue;
		case 'b': 
		case 'i':
			c += 'A' - 'a';
		case 'B': 
		case 'I':
			if (icol == 0) 
				continue;
			snp = font[icol-1][nclin];
			snp[0] = (c == 'I' ? '2' : '3');
			snp[1] = 0;
			continue;
		case 't': 
		case 'T':
			if (icol > 0)
				flags[icol-1][nclin] |= CTOP;
			continue;
		case 'd': 
		case 'D':
			if (icol > 0)
				flags[icol-1][nclin] |= CDOWN;
			continue;
		case 'f': 
		case 'F':
			if (icol == 0) 
				continue;
			snp = font[icol-1][nclin];
			snp[0] = snp[1] = stopc = 0;
			for (i = 0; i < 2; i++) {
				c = get1char();
				if (i == 0 && c == '(') {
					stopc = ')';
					c = get1char();
				}
				if (c == 0) 
					break;
				if (c == stopc) {
					stopc = 0; 
					break;
				}
				if (stopc == 0)  
					if (c == ' ' || c == tab ) 
						break;
				if (c == '\n' || c == '|') {
					un1getc(c); 
					break;
				}
				snp[i] = c;
				if (c >= '0' && c <= '9') 
					break;
			}
			if (stopc) 
				if (get1char() != stopc)
					error("Nonterminated font name");
			continue;
		case 'P': 
		case 'p':
			if (icol <= 0) 
				continue;
			temp = snp = csize[icol-1][nclin];
			while (c = get1char()) {
				if (c == ' ' || c == tab || c == '\n') 
					break;
				if (c == '-' || c == '+')
					if (snp > temp)
						break;
					else
						*snp++ = c;
				else if (digit(c))
					*snp++ = c;
				else 
					break;
				if (snp - temp > 4)
					error("point size too large");
			}
			*snp = 0;
			if (atoi(temp) > 36)
				error("point size unreasonable");
			un1getc (c);
			continue;
		case 'V': 
		case 'v':
			if (icol <= 0) 
				continue;
			temp = snp = vsize[icol-1][nclin];
			while (c = get1char()) {
				if (c == ' ' || c == tab || c == '\n') 
					break;
				if (c == '-' || c == '+')
					if (snp > temp)
						break;
					else
						*snp++ = c;
				else if (digit(c))
					*snp++ = c;
				else 
					break;
				if (snp - temp > 4)
					error("vertical spacing value too large");
			}
			*snp = 0;
			un1getc(c);
			continue;
		case 'w': 
		case 'W':
			snp = cll [icol-1];
			/* Dale Smith didn't like this check - possible to have two text blocks
		   of different widths now ....
			if (*snp)
				{
				Bprint(&tabout, "Ignored second width specification");
				continue;
				}
		/* end commented out code ... */
			stopc = 0;
			while (c = get1char()) {
				if (snp == cll[icol-1] && c == '(') {
					stopc = ')';
					continue;
				}
				if ( !stopc && (c > '9' || c < '0'))
					break;
				if (stopc && c == stopc)
					break;
				*snp++ = c;
			}
			*snp = 0;
			if (snp - cll[icol-1] > CLLEN)
				error ("column width too long");
			if (!stopc)
				un1getc(c);
			continue;
		case 'e': 
		case 'E':
			if (icol < 1) 
				continue;
			evenup[icol-1] = 1;
			evenflg = 1;
			continue;
		case 'z': 
		case 'Z': /* zero width-ignre width this item */
			if (icol < 1) 
				continue;
			flags[icol-1][nclin] |= ZEROW;
			continue;
		case 'u': 
		case 'U': /* half line up */
			if (icol < 1) 
				continue;
			flags[icol-1][nclin] |= HALFUP;
			continue;
		case '0': 
		case '1': 
		case '2': 
		case '3': 
		case '4':
		case '5': 
		case '6': 
		case '7': 
		case '8': 
		case '9':
			sn[0] = c;
			snp = sn + 1;
			while (digit(*snp++ = c = get1char()))
				;
			un1getc(c);
			sep[icol-1] = max(sep[icol-1], numb(sn));
			continue;
		case '|':
			lefline[icol][nclin]++;
			if (icol == 0) 
				left1flg = 1;
			continue;
		}
	}
	error("EOF reading table specification");
}
Ejemplo n.º 27
0
Archivo: pop3.c Proyecto: 99years/plan9
//
// check for new messages on pop server
// UIDL is not required by RFC 1939, but 
// netscape requires it, so almost every server supports it.
// we'll use it to make our lives easier.
//
static char*
pop3read(Pop *pop, Mailbox *mb, int doplumb)
{
	char *s, *p, *uidl, *f[2];
	int mesgno, ignore, nnew;
	Message *m, *next, **l;

	// Some POP servers disallow UIDL if the maildrop is empty.
	pop3cmd(pop, "STAT");
	if(!isokay(s = pop3resp(pop)))
		return s;

	// fetch message listing; note messages to grab
	l = &mb->root->part;
	if(strncmp(s, "+OK 0 ", 6) != 0) {
		pop3cmd(pop, "UIDL");
		if(!isokay(s = pop3resp(pop)))
			return s;

		for(;;){
			p = pop3resp(pop);
			if(strcmp(p, ".") == 0 || strcmp(p, "unexpected eof") == 0)
				break;

			if(tokenize(p, f, 2) != 2)
				continue;

			mesgno = atoi(f[0]);
			uidl = f[1];
			if(strlen(uidl) > 75)	// RFC 1939 says 70 characters max
				continue;

			ignore = 0;
			while(*l != nil) {
				if(strcmp((*l)->uidl, uidl) == 0) {
					// matches mail we already have, note mesgno for deletion
					(*l)->mesgno = mesgno;
					ignore = 1;
					l = &(*l)->next;
					break;
				} else {
					// old mail no longer in box mark deleted
					if(doplumb)
						mailplumb(mb, *l, 1);
					(*l)->inmbox = 0;
					(*l)->deleted = 1;
					l = &(*l)->next;
				}
			}
			if(ignore)
				continue;

			m = newmessage(mb->root);
			m->mallocd = 1;
			m->inmbox = 1;
			m->mesgno = mesgno;
			strcpy(m->uidl, uidl);

			// chain in; will fill in message later
			*l = m;
			l = &m->next;
		}
	}

	// whatever is left has been removed from the mbox, mark as deleted
	while(*l != nil) {
		if(doplumb)
			mailplumb(mb, *l, 1);
		(*l)->inmbox = 0;
		(*l)->deleted = 1;
		l = &(*l)->next;
	}

	// download new messages
	nnew = 0;
	if(pop->pipeline){
		switch(rfork(RFPROC|RFMEM)){
		case -1:
			fprint(2, "rfork: %r\n");
			pop->pipeline = 0;

		default:
			break;

		case 0:
			for(m = mb->root->part; m != nil; m = m->next){
				if(m->start != nil)
					continue;
				Bprint(&pop->bout, "LIST %d\r\nRETR %d\r\n", m->mesgno, m->mesgno);
			}
			Bflush(&pop->bout);
			_exits(nil);
		}
	}

	for(m = mb->root->part; m != nil; m = next) {
		next = m->next;

		if(m->start != nil)
			continue;

		if(s = pop3download(pop, m)) {
			// message disappeared? unchain
			fprint(2, "download %d: %s\n", m->mesgno, s);
			delmessage(mb, m);
			mb->root->subname--;
			continue;
		}
		nnew++;
		parse(m, 0, mb, 1);

		if(doplumb)
			mailplumb(mb, m, 0);
	}
	if(pop->pipeline)
		waitpid();

	if(nnew || mb->vers == 0) {
		mb->vers++;
		henter(PATH(0, Qtop), mb->name,
			(Qid){PATH(mb->id, Qmbox), mb->vers, QTDIR}, nil, mb);
	}

	return nil;	
}
Ejemplo n.º 28
0
Archivo: cal.c Proyecto: 99years/plan9
void
main(int argc, char *argv[])
{
	int y, i, j, m;

	if(argc > 3) {
		fprint(2, "usage: cal [month] [year]\n");
		exits("usage");
	}
	Binit(&bout, 1, OWRITE);

/*
 * no arg, print current month
 */
	if(argc == 1) {
		m = curmo();
		y = curyr();
		goto xshort;
	}

/*
 * one arg
 *	if looks like a month, print month
 *	else print year
 */
	if(argc == 2) {
		y = number(argv[1]);
		if(y < 0)
			y = -y;
		if(y >= 1 && y <= 12) {
			m = y;
			y = curyr();
			goto xshort;
		}
		goto xlong;
	}

/*
 * two arg, month and year
 */
	m = number(argv[1]);
	if(m < 0)
		m = -m;
	y = number(argv[2]);
	goto xshort;

/*
 *	print out just month
 */
xshort:
	if(m < 1 || m > 12)
		goto badarg;
	if(y < 1 || y > 9999)
		goto badarg;
	Bprint(&bout, "   %s %ud\n", smon[m-1], y);
	Bprint(&bout, "%s\n", dayw);
	cal(m, y, string, 24);
	for(i=0; i<6*24; i+=24)
		pstr(string+i, 24);
	exits(0);

/*
 *	print out complete year
 */
xlong:
	y = number(argv[1]);
	if(y<1 || y>9999)
		goto badarg;
	Bprint(&bout, "\n\n\n");
	Bprint(&bout, "                                %ud\n", y);
	Bprint(&bout, "\n");
	for(i=0; i<12; i+=3) {
		for(j=0; j<6*72; j++)
			string[j] = '\0';
		Bprint(&bout, "         %.3s", smon[i]);
		Bprint(&bout, "                    %.3s", smon[i+1]);
		Bprint(&bout, "                    %.3s\n", smon[i+2]);
		Bprint(&bout, "%s   %s   %s\n", dayw, dayw, dayw);
		cal(i+1, y, string, 72);
		cal(i+2, y, string+23, 72);
		cal(i+3, y, string+46, 72);
		for(j=0; j<6*72; j+=72)
			pstr(string+j, 72);
	}
	Bprint(&bout, "\n\n\n");
	exits(0);

badarg:
	Bprint(&bout, "cal: bad argument\n");
}
Ejemplo n.º 29
0
void
main(int argc, char** argv)
{
	char *bios, buf[256], sizeb[256], *p, *vsize, *psize;
	char *type, *vtype;
	int virtual, len;
	Ctlr *ctlr;
	Vga *vga;

	fmtinstall('H', encodefmt);
	Binit(&stdout, 1, OWRITE);

	bios = getenv("vgactlr");
	if((type = getenv("monitor")) == 0)
		type = "vga";
	psize = vsize = "640x480x8";

	ARGBEGIN{
	default:
		usage();
		break;
	case 'b':
		bios = EARGF(usage());
		break;
	case 'B':
		dumpbios(0x10000);
		exits(0);
	case 'c':
		cflag = 1;
		break;
	case 'd':
		dflag = 1;
		break;
	case 'i':
		iflag = 1;
		break;
	case 'l':
		lflag = 1;
		break;
	case 'm':
		type = EARGF(usage());
		break;
	case 'p':
		pflag = 1;
		break;
	case 'r':
		/*
		 * rflag > 1 means "leave me alone, I know what I'm doing."
		 */
		rflag++;
		break;
	case 'v':
		vflag = 1;
		break;
	case 'V':
		vflag = 1;
		Vflag = 1;
		break;
	case 'x':
		dbname = EARGF(usage());
		break;
	}ARGEND

	virtual = 0;
	switch(argc){
	default:
		usage();
		break;
	case 1:
		vsize = psize = argv[0];
		break;
	case 2:
		psize = argv[0];
		vsize = argv[1];
		virtual = 1;
		break;
	case 0:
		break;
	}

	if(lflag && strcmp(vsize, "text") == 0){
		vesatextmode();
		vgactlw("textmode", "");
		exits(0);
	}

	vga = alloc(sizeof(Vga));
	if(bios){
		if((vga->offset = strtol(bios, &p, 0)) == 0 || *p++ != '=')
			error("main: bad BIOS string format - %s\n", bios);
		len = strlen(p);
		vga->bios = alloc(len+1);
		strncpy(vga->bios, p, len);
		trace("main->BIOS %s\n", bios);
	}

	/*
	 * Try to identify the VGA card and grab
	 * registers.  Print them out if requested.
	 * If monitor=vesa or our vga controller can't be found
	 * in vgadb, try vesa modes; failing that, try vga.
	 */
	if(strcmp(type, "vesa") == 0 || dbctlr(dbname, vga) == 0 ||
	    vga->ctlr == 0)
		if(dbvesa(vga) == 0 || vga->ctlr == 0){
			Bprint(&stdout, "%s: controller not in %s, not vesa\n",
				argv0, dbname);
			dumpbios(256);
			type = "vga";
			vsize = psize = "640x480x1";
			virtual = 0;
			vga->ctlr = &generic;
			vga->link = &generic;
		}
Ejemplo n.º 30
0
void
patch(void)
{
	long c;
	Prog *p, *q;
	Sym *s;
	long vexit;

	if(debug['v'])
		Bprint(&bso, "%5.2f mkfwd\n", cputime());
	Bflush(&bso);
	mkfwd();
	if(debug['v'])
		Bprint(&bso, "%5.2f patch\n", cputime());
	Bflush(&bso);
	s = lookup("exit", 0);
	vexit = s->value;
	for(p = firstp; p != P; p = p->link) {
		if(p->as == ATEXT)
			curtext = p;
		if(p->as == ACALL || p->as == ARET) {
			s = p->to.sym;
			if(s) {
				if(debug['c'])
					Bprint(&bso, "%s calls %s\n", TNAME, s->name);
				switch(s->type) {
				default:
					/* diag prints TNAME first */
					diag("undefined: %s", s->name);
					s->type = STEXT;
					s->value = vexit;
					break;	/* or fall through to set offset? */
				case STEXT:
					p->to.offset = s->value;
					break;
				case SUNDEF:
					p->pcond = UP;
					p->to.offset = 0;
					break;
				}
				p->to.type = D_BRANCH;
			}
		}
		if(p->to.type != D_BRANCH || p->pcond == UP)
			continue;
		c = p->to.offset;
		for(q = firstp; q != P;) {
			if(q->forwd != P)
			if(c >= q->forwd->pc) {
				q = q->forwd;
				continue;
			}
			if(c == q->pc)
				break;
			q = q->link;
		}
		if(q == P) {
			diag("branch out of range in %s\n%P", TNAME, p);
			p->to.type = D_NONE;
		}
		p->pcond = q;
	}

	for(p = firstp; p != P; p = p->link) {
		if(p->as == ATEXT)
			curtext = p;
		p->mark = 0;	/* initialization for follow */
		if(p->pcond != P && p->pcond != UP) {
			p->pcond = brloop(p->pcond);
			if(p->pcond != P)
			if(p->to.type == D_BRANCH)
				p->to.offset = p->pcond->pc;
		}
	}
}