Пример #1
0
int
numinfo(void)
{
	return nelem(Infdir);
}
Пример #2
0
static int
tkwalk(Chan* c, char* name)
{
	return devwalk(c, name, tkdirtab, nelem(tkdirtab), devgen);
}
Пример #3
0
void
main(int argc, char *argv[])
{
	char buf[32];
	Dev *d, *ed;
	Ep *e;
	int i;

	ARGBEGIN {
	case 'D':
		chatty9p++;
		break;
	case 'd':
		usbdebug++;
		break;
	} ARGEND;

	if(argc == 0)
		usage();

	if((d = getdev(*argv)) == nil)
		sysfatal("getdev: %r");
	audiodev = d;

	/* parse descriptors, mark valid altc */
	for(i = 0; i < nelem(d->usb->ddesc); i++)
		parsedescr(d->usb->ddesc[i]);
	for(i = 0; i < nelem(d->usb->ep); i++){
		e = d->usb->ep[i];
		if(e != nil && e->type == Eiso && e->iface != nil && e->iface->csp == CSP(Claudio, 2, 0)){
			switch(e->dir){
			case Ein:
				if(audioepin != nil)
					continue;
				audioepin = e;
				break;
			case Eout:
				if(audioepout != nil)
					continue;
				audioepout = e;
				break;
			case Eboth:
				if(audioepin != nil && audioepout != nil)
					continue;
				if(audioepin == nil)
					audioepin = e;
				if(audioepout == nil)
					audioepout = e;
				break;
			}
			if((ed = setupep(audiodev, e, audiofreq)) == nil){
				fprint(2, "setupep: %r\n");

				if(e == audioepin)
					audioepin = nil;
				if(e == audioepout)
					audioepout = nil;
				continue;
			}
			closedev(ed);
		}
	}
	if(audioepout == nil)
		sysfatal("no endpoints found");

	fs.tree = alloctree(user, "usb", DMDIR|0555, nil);
	createfile(fs.tree->root, "volume", user, 0666, nil);

	snprint(buf, sizeof buf, "%d.audio", audiodev->id);
	postsharesrv(&fs, nil, "usb", buf);

	exits(0);
}
Пример #4
0
void
dostkoff(void)
{
	Prog *p, *q, *q1;
	int32 autoffset, deltasp;
	int a, pcsize;
	uint32 moreconst1, moreconst2, i;

	for(i=0; i<nelem(morename); i++) {
		symmorestack[i] = lookup(morename[i], 0);
		if(symmorestack[i]->type != STEXT)
			diag("morestack trampoline not defined - %s", morename[i]);
		pmorestack[i] = symmorestack[i]->text;
	}

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

		p = cursym->text;
		parsetextconst(p->to.offset);
		autoffset = textstksiz;
		if(autoffset < 0)
			autoffset = 0;

		if(autoffset < StackSmall && !(p->from.scale & NOSPLIT)) {
			for(q = p; q != P; q = q->link)
				if(q->as == ACALL)
					goto noleaf;
			p->from.scale |= NOSPLIT;
		noleaf:;
		}

		q = P;
		if((p->from.scale & NOSPLIT) && autoffset >= StackSmall)
			diag("nosplit func likely to overflow stack");

		if(!(p->from.scale & NOSPLIT)) {
			p = appendp(p);	// load g into CX
			p->as = AMOVQ;
			if(HEADTYPE == Hlinux || HEADTYPE == Hfreebsd
			|| HEADTYPE == Hopenbsd || HEADTYPE == Hnetbsd
			|| HEADTYPE == Hplan9x64)	// ELF uses FS
				p->from.type = D_INDIR+D_FS;
			else
				p->from.type = D_INDIR+D_GS;
			p->from.offset = tlsoffset+0;
			p->to.type = D_CX;
			if(HEADTYPE == Hwindows) {
				// movq %gs:0x28, %rcx
				// movq (%rcx), %rcx
				p->as = AMOVQ;
				p->from.type = D_INDIR+D_GS;
				p->from.offset = 0x28;
				p->to.type = D_CX;

			
				p = appendp(p);
				p->as = AMOVQ;
				p->from.type = D_INDIR+D_CX;
				p->from.offset = 0;
				p->to.type = D_CX;
			}

			if(debug['K']) {
				// 6l -K means check not only for stack
				// overflow but stack underflow.
				// On underflow, INT 3 (breakpoint).
				// Underflow itself is rare but this also
				// catches out-of-sync stack guard info

				p = appendp(p);
				p->as = ACMPQ;
				p->from.type = D_INDIR+D_CX;
				p->from.offset = 8;
				p->to.type = D_SP;

				p = appendp(p);
				p->as = AJHI;
				p->to.type = D_BRANCH;
				p->to.offset = 4;
				q1 = p;

				p = appendp(p);
				p->as = AINT;
				p->from.type = D_CONST;
				p->from.offset = 3;

				p = appendp(p);
				p->as = ANOP;
				q1->pcond = p;
			}

			if(autoffset < StackBig) {  // do we need to call morestack?
				if(autoffset <= StackSmall) {
					// small stack
					p = appendp(p);
					p->as = ACMPQ;
					p->from.type = D_SP;
					p->to.type = D_INDIR+D_CX;
				} else {
					// large stack
					p = appendp(p);
					p->as = ALEAQ;
					p->from.type = D_INDIR+D_SP;
					p->from.offset = -(autoffset-StackSmall);
					p->to.type = D_AX;

					p = appendp(p);
					p->as = ACMPQ;
					p->from.type = D_AX;
					p->to.type = D_INDIR+D_CX;
				}

				// common
				p = appendp(p);
				p->as = AJHI;
				p->to.type = D_BRANCH;
				p->to.offset = 4;
				q = p;
			}

			// If we ask for more stack, we'll get a minimum of StackMin bytes.
			// We need a stack frame large enough to hold the top-of-stack data,
			// the function arguments+results, our caller's PC, our frame,
			// a word for the return PC of the next call, and then the StackLimit bytes
			// that must be available on entry to any function called from a function
			// that did a stack check.  If StackMin is enough, don't ask for a specific
			// amount: then we can use the custom functions and save a few
			// instructions.
			moreconst1 = 0;
			if(StackTop + textarg + PtrSize + autoffset + PtrSize + StackLimit >= StackMin)
				moreconst1 = autoffset;
			moreconst2 = textarg;

			// 4 varieties varieties (const1==0 cross const2==0)
			// and 6 subvarieties of (const1==0 and const2!=0)
			p = appendp(p);
			if(moreconst1 == 0 && moreconst2 == 0) {
				p->as = ACALL;
				p->to.type = D_BRANCH;
				p->pcond = pmorestack[0];
				p->to.sym = symmorestack[0];
			} else
			if(moreconst1 != 0 && moreconst2 == 0) {
				p->as = AMOVL;
				p->from.type = D_CONST;
				p->from.offset = moreconst1;
				p->to.type = D_AX;

				p = appendp(p);
				p->as = ACALL;
				p->to.type = D_BRANCH;
				p->pcond = pmorestack[1];
				p->to.sym = symmorestack[1];
			} else
			if(moreconst1 == 0 && moreconst2 <= 48 && moreconst2%8 == 0) {
				i = moreconst2/8 + 3;
				p->as = ACALL;
				p->to.type = D_BRANCH;
				p->pcond = pmorestack[i];
				p->to.sym = symmorestack[i];
			} else
			if(moreconst1 == 0 && moreconst2 != 0) {
				p->as = AMOVL;
				p->from.type = D_CONST;
				p->from.offset = moreconst2;
				p->to.type = D_AX;

				p = appendp(p);
				p->as = ACALL;
				p->to.type = D_BRANCH;
				p->pcond = pmorestack[2];
				p->to.sym = symmorestack[2];
			} else {
				p->as = AMOVQ;
				p->from.type = D_CONST;
				p->from.offset = (uint64)moreconst2 << 32;
				p->from.offset |= moreconst1;
				p->to.type = D_AX;

				p = appendp(p);
				p->as = ACALL;
				p->to.type = D_BRANCH;
				p->pcond = pmorestack[3];
				p->to.sym = symmorestack[3];
			}
		}

		if(q != P)
			q->pcond = p->link;

		if(autoffset) {
			p = appendp(p);
			p->as = AADJSP;
			p->from.type = D_CONST;
			p->from.offset = autoffset;
			p->spadj = autoffset;
			if(q != P)
				q->pcond = p;
		} else {
			// zero-byte stack adjustment.
			// Insert a fake non-zero adjustment so that stkcheck can
			// recognize the end of the stack-splitting prolog.
			p = appendp(p);
			p->as = ANOP;
			p->spadj = -PtrSize;
			p = appendp(p);
			p->as = ANOP;
			p->spadj = PtrSize;
		}
		deltasp = autoffset;

		if(debug['K'] > 1 && autoffset) {
			// 6l -KK means double-check for stack overflow
			// even after calling morestack and even if the
			// function is marked as nosplit.
			p = appendp(p);
			p->as = AMOVQ;
			p->from.type = D_INDIR+D_CX;
			p->from.offset = 0;
			p->to.type = D_BX;

			p = appendp(p);
			p->as = ASUBQ;
			p->from.type = D_CONST;
			p->from.offset = StackSmall+32;
			p->to.type = D_BX;

			p = appendp(p);
			p->as = ACMPQ;
			p->from.type = D_SP;
			p->to.type = D_BX;

			p = appendp(p);
			p->as = AJHI;
			p->to.type = D_BRANCH;
			q1 = p;

			p = appendp(p);
			p->as = AINT;
			p->from.type = D_CONST;
			p->from.offset = 3;

			p = appendp(p);
			p->as = ANOP;
			q1->pcond = p;
		}
		
		if(debug['Z'] && autoffset && !(cursym->text->from.scale&NOSPLIT)) {
			// 6l -Z means zero the stack frame on entry.
			// This slows down function calls but can help avoid
			// false positives in garbage collection.
			p = appendp(p);
			p->as = AMOVQ;
			p->from.type = D_SP;
			p->to.type = D_DI;
			
			p = appendp(p);
			p->as = AMOVQ;
			p->from.type = D_CONST;
			p->from.offset = autoffset/8;
			p->to.type = D_CX;
			
			p = appendp(p);
			p->as = AMOVQ;
			p->from.type = D_CONST;
			p->from.offset = 0;
			p->to.type = D_AX;
			
			p = appendp(p);
			p->as = AREP;
			
			p = appendp(p);
			p->as = ASTOSQ;
		}
		
		for(; p != P; p = p->link) {
			pcsize = p->mode/8;
			a = p->from.type;
			if(a == D_AUTO)
				p->from.offset += deltasp;
			if(a == D_PARAM)
				p->from.offset += deltasp + pcsize;
			a = p->to.type;
			if(a == D_AUTO)
				p->to.offset += deltasp;
			if(a == D_PARAM)
				p->to.offset += deltasp + pcsize;
	
			switch(p->as) {
			default:
				continue;
			case APUSHL:
			case APUSHFL:
				deltasp += 4;
				p->spadj = 4;
				continue;
			case APUSHQ:
			case APUSHFQ:
				deltasp += 8;
				p->spadj = 8;
				continue;
			case APUSHW:
			case APUSHFW:
				deltasp += 2;
				p->spadj = 2;
				continue;
			case APOPL:
			case APOPFL:
				deltasp -= 4;
				p->spadj = -4;
				continue;
			case APOPQ:
			case APOPFQ:
				deltasp -= 8;
				p->spadj = -8;
				continue;
			case APOPW:
			case APOPFW:
				deltasp -= 2;
				p->spadj = -2;
				continue;
			case ARET:
				break;
			}
	
			if(autoffset != deltasp)
				diag("unbalanced PUSH/POP");
	
			if(autoffset) {
				p->as = AADJSP;
				p->from.type = D_CONST;
				p->from.offset = -autoffset;
				p->spadj = -autoffset;
				p = appendp(p);
				p->as = ARET;
				// If there are instructions following
				// this ARET, they come from a branch
				// with the same stackframe, so undo
				// the cleanup.
				p->spadj = +autoffset;
			}
		}
	}
}
Пример #5
0
Файл: main.c Проект: Fluray/NxM
void
confinit(void)
{
	char *p;
	int i, userpcnt;
	ulong kpages;

	if(p = getconf("*kernelpercent"))
		userpcnt = 100 - strtol(p, 0, 0);
	else
		userpcnt = 0;

	conf.npage = 0;
	for(i=0; i<nelem(conf.mem); i++)
		conf.npage += conf.mem[i].npage;

	conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
	if(cpuserver)
		conf.nproc *= 3;
	if(conf.nproc > 2000)
		conf.nproc = 2000;
	conf.nimage = 200;
	conf.nswap = conf.nproc*80;
	conf.nswppo = 4096;

	if(cpuserver) {
		if(userpcnt < 10)
			userpcnt = 70;
		kpages = conf.npage - (conf.npage*userpcnt)/100;

		/*
		 * Hack for the big boys. Only good while physmem < 4GB.
		 * Give the kernel fixed max + enough to allocate the
		 * page pool.
		 * This is an overestimate as conf.upages < conf.npages.
		 * The patch of nimage is a band-aid, scanning the whole
		 * page list in imagereclaim just takes too long.
		 */
		if(kpages > (64*MB + conf.npage*sizeof(Page))/BY2PG){
			kpages = (64*MB + conf.npage*sizeof(Page))/BY2PG;
			conf.nimage = 2000;
			kpages += (conf.nproc*KSTACK)/BY2PG;
		}
	} else {
		if(userpcnt < 10) {
			if(conf.npage*BY2PG < 16*MB)
				userpcnt = 40;
			else
				userpcnt = 60;
		}
		kpages = conf.npage - (conf.npage*userpcnt)/100;

		/*
		 * Make sure terminals with low memory get at least
		 * 4MB on the first Image chunk allocation.
		 */
		if(conf.npage*BY2PG < 16*MB)
			imagmem->minarena = 4*1024*1024;
	}

	/*
	 * can't go past the end of virtual memory
	 * (ulong)-KZERO is 2^32 - KZERO
	 */
	if(kpages > ((ulong)-KZERO)/BY2PG)
		kpages = ((ulong)-KZERO)/BY2PG;

	conf.upages = conf.npage - kpages;
	conf.ialloc = (kpages/2)*BY2PG;

	/*
	 * Guess how much is taken by the large permanent
	 * datastructures. Mntcache and Mntrpc are not accounted for
	 * (probably ~300KB).
	 */
	kpages *= BY2PG;
	kpages -= conf.upages*sizeof(Page)
		+ conf.nproc*sizeof(Proc)
		+ conf.nimage*sizeof(Image)
		+ conf.nswap
		+ conf.nswppo*sizeof(Page);
	mainmem->maxsize = kpages;
	if(!cpuserver){
		/*
		 * give terminals lots of image memory, too; the dynamic
		 * allocation will balance the load properly, hopefully.
		 * be careful with 32-bit overflow.
		 */
		imagmem->maxsize = kpages;
	}
}
Пример #6
0
// mkzasm writes zasm_$GOOS_$GOARCH.h,
// which contains struct offsets for use by
// assembly files.  It also writes a copy to the work space
// under the name zasm_GOOS_GOARCH.h (no expansion).
// 
void
mkzasm(char *dir, char *file)
{
	int i, n;
	char *aggr, *p;
	Buf in, b, out, exp;
	Vec argv, lines, fields;

	binit(&in);
	binit(&b);
	binit(&out);
	binit(&exp);
	vinit(&argv);
	vinit(&lines);
	vinit(&fields);
	
	bwritestr(&out, "// auto generated by go tool dist\n\n");
	for(i=0; i<nelem(zasmhdr); i++) {
		if(hasprefix(goarch, zasmhdr[i].goarch) && hasprefix(goos, zasmhdr[i].goos)) {
			bwritestr(&out, zasmhdr[i].hdr);
			goto ok;
		}
	}
	fatal("unknown $GOOS/$GOARCH in mkzasm");
ok:

	// Run 6c -D GOOS_goos -D GOARCH_goarch -I workdir -a -n -o workdir/proc.acid proc.c
	// to get acid [sic] output. Run once without the -a -o workdir/proc.acid in order to
	// report compilation failures (the -o redirects all messages, unfortunately).
	vreset(&argv);
	vadd(&argv, bpathf(&b, "%s/%sc", tooldir, gochar));
	vadd(&argv, "-D");
	vadd(&argv, bprintf(&b, "GOOS_%s", goos));
	vadd(&argv, "-D");
	vadd(&argv, bprintf(&b, "GOARCH_%s", goarch));
	vadd(&argv, "-I");
	vadd(&argv, bprintf(&b, "%s", workdir));
	vadd(&argv, "-n");
	vadd(&argv, "-a");
	vadd(&argv, "-o");
	vadd(&argv, bpathf(&b, "%s/proc.acid", workdir));
	vadd(&argv, "proc.c");
	runv(nil, dir, CheckExit, &argv);
	readfile(&in, bpathf(&b, "%s/proc.acid", workdir));
	
	// Convert input like
	//	aggr G
	//	{
	//		Gobuf 24 sched;
	//		'Y' 48 stack0;
	//	}
	//	StackMin = 128;
	// into output like
	//	#define g_sched 24
	//	#define g_stack0 48
	//	#define const_StackMin 128
	aggr = nil;
	splitlines(&lines, bstr(&in));
	for(i=0; i<lines.len; i++) {
		splitfields(&fields, lines.p[i]);
		if(fields.len == 2 && streq(fields.p[0], "aggr")) {
			if(streq(fields.p[1], "G"))
				aggr = "g";
			else if(streq(fields.p[1], "M"))
				aggr = "m";
			else if(streq(fields.p[1], "P"))
				aggr = "p";
			else if(streq(fields.p[1], "Gobuf"))
				aggr = "gobuf";
			else if(streq(fields.p[1], "LibCall"))
				aggr = "libcall";
			else if(streq(fields.p[1], "WinCallbackContext"))
				aggr = "cbctxt";
			else if(streq(fields.p[1], "SEH"))
				aggr = "seh";
		}
		if(hasprefix(lines.p[i], "}"))
			aggr = nil;
		if(aggr && hasprefix(lines.p[i], "\t") && fields.len >= 2) {
			n = fields.len;
			p = fields.p[n-1];
			if(p[xstrlen(p)-1] == ';')
				p[xstrlen(p)-1] = '\0';
			bwritestr(&out, bprintf(&b, "#define %s_%s %s\n", aggr, fields.p[n-1], fields.p[n-2]));
		}
		if(fields.len == 3 && streq(fields.p[1], "=")) { // generated from enumerated constants
			p = fields.p[2];
			if(p[xstrlen(p)-1] == ';')
				p[xstrlen(p)-1] = '\0';
			bwritestr(&out, bprintf(&b, "#define const_%s %s\n", fields.p[0], p));
		}
	}

	// Some #defines that are used for .c files.
	if(streq(goos, "windows")) {
		bwritestr(&out, bprintf(&b, "#define cb_max %d\n", MAXWINCB));
	}
	
	xgetenv(&exp, "GOEXPERIMENT");
	bwritestr(&out, bprintf(&b, "#define GOEXPERIMENT \"%s\"\n", bstr(&exp)));
	
	// Write both to file and to workdir/zasm_GOOS_GOARCH.h.
	writefile(&out, file, 0);
	writefile(&out, bprintf(&b, "%s/zasm_GOOS_GOARCH.h", workdir), 0);

	bfree(&in);
	bfree(&b);
	bfree(&out);
	bfree(&exp);
	vfree(&argv);
	vfree(&lines);
	vfree(&fields);
}
Пример #7
0
Файл: text.c Проект: npe9/harvey
Rune*
textcomplete(Text *t)
{
	int i, nstr, npath;
	uint q;
	Rune tmp[200];
	Rune *str, *path;
	Rune *rp;
	Completion *c;
	char *s, *dirs;
	Runestr dir;

	/* control-f: filename completion; works back to white space or / */
	if(t->q0<t->file->nc && textreadc(t, t->q0)>' ')	/* must be at end of word */
		return nil;
	nstr = textfilewidth(t, t->q0, TRUE);
	str = runemalloc(nstr);
	npath = textfilewidth(t, t->q0-nstr, FALSE);
	path = runemalloc(npath);

	c = nil;
	rp = nil;
	dirs = nil;

	q = t->q0-nstr;
	for(i=0; i<nstr; i++)
		str[i] = textreadc(t, q++);
	q = t->q0-nstr-npath;
	for(i=0; i<npath; i++)
		path[i] = textreadc(t, q++);
	/* is path rooted? if not, we need to make it relative to window path */
	if(npath>0 && path[0]=='/')
		dir = (Runestr){path, npath};
	else{
		dir = dirname(t, nil, 0);
		if(dir.nr + 1 + npath > nelem(tmp)){
			free(dir.r);
			goto Return;
		}
		if(dir.nr == 0){
			dir.nr = 1;
			dir.r = runestrdup(L".");
		}
		runemove(tmp, dir.r, dir.nr);
		tmp[dir.nr] = '/';
		runemove(tmp+dir.nr+1, path, npath);
		free(dir.r);
		dir.r = tmp;
		dir.nr += 1+npath;
		dir = cleanrname(dir);
	}

	s = smprint("%.*S", nstr, str);
	dirs = smprint("%.*S", dir.nr, dir.r);
	c = complete(dirs, s);
	free(s);
	if(c == nil){
		warning(nil, "error attempting completion: %r\n");
		goto Return;
	}

	if(!c->advance){
		warning(nil, "%.*S%s%.*S*%s\n",
			dir.nr, dir.r,
			dir.nr>0 && dir.r[dir.nr-1]!='/' ? "/" : "",
			nstr, str,
			c->nmatch? "" : ": no matches in:");
		for(i=0; i<c->nfile; i++)
			warning(nil, " %s\n", c->filename[i]);
	}

	if(c->advance)
		rp = runesmprint("%s", c->string);
	else
		rp = nil;
  Return:
	freecompletion(c);
	free(dirs);
	free(str);
	free(path);
	return rp;
}
Пример #8
0
static MSpan*
MHeap_AllocLocked(MHeap *h, uintptr npage, int32 sizeclass)
{
	uintptr n;
	MSpan *s, *t;
	PageID p;

	// Try in fixed-size lists up to max.
	for(n=npage; n < nelem(h->free); n++) {
		if(!runtime_MSpanList_IsEmpty(&h->free[n])) {
			s = h->free[n].next;
			goto HaveSpan;
		}
	}

	// Best fit in list of large spans.
	if((s = MHeap_AllocLarge(h, npage)) == nil) {
		if(!MHeap_Grow(h, npage))
			return nil;
		if((s = MHeap_AllocLarge(h, npage)) == nil)
			return nil;
	}

HaveSpan:
	// Mark span in use.
	if(s->state != MSpanFree)
		runtime_throw("MHeap_AllocLocked - MSpan not free");
	if(s->npages < npage)
		runtime_throw("MHeap_AllocLocked - bad npages");
	runtime_MSpanList_Remove(s);
	s->state = MSpanInUse;
	mstats.heap_idle -= s->npages<<PageShift;
	mstats.heap_released -= s->npreleased<<PageShift;
	if(s->npreleased > 0) {
		// We have called runtime_SysUnused with these pages, and on
		// Unix systems it called madvise.  At this point at least
		// some BSD-based kernels will return these pages either as
		// zeros or with the old data.  For our caller, the first word
		// in the page indicates whether the span contains zeros or
		// not (this word was set when the span was freed by
		// MCentral_Free or runtime_MCentral_FreeSpan).  If the first
		// page in the span is returned as zeros, and some subsequent
		// page is returned with the old data, then we will be
		// returning a span that is assumed to be all zeros, but the
		// actual data will not be all zeros.  Avoid that problem by
		// explicitly marking the span as not being zeroed, just in
		// case.  The beadbead constant we use here means nothing, it
		// is just a unique constant not seen elsewhere in the
		// runtime, as a clue in case it turns up unexpectedly in
		// memory or in a stack trace.
		*(uintptr*)(s->start<<PageShift) = (uintptr)0xbeadbeadbeadbeadULL;
	}
	s->npreleased = 0;

	if(s->npages > npage) {
		// Trim extra and put it back in the heap.
		t = runtime_FixAlloc_Alloc(&h->spanalloc);
		mstats.mspan_inuse = h->spanalloc.inuse;
		mstats.mspan_sys = h->spanalloc.sys;
		runtime_MSpan_Init(t, s->start + npage, s->npages - npage);
		s->npages = npage;
		p = t->start;
		p -= ((uintptr)h->arena_start>>PageShift);
		if(p > 0)
			h->map[p-1] = s;
		h->map[p] = t;
		h->map[p+t->npages-1] = t;
		*(uintptr*)(t->start<<PageShift) = *(uintptr*)(s->start<<PageShift);  // copy "needs zeroing" mark
		t->state = MSpanInUse;
		MHeap_FreeLocked(h, t);
		t->unusedsince = s->unusedsince; // preserve age
	}
Пример #9
0
/*
 *  All traps come here.  It is slower to have all traps call trap()
 *  rather than directly vectoring the handler.  However, this avoids a
 *  lot of code duplication and possible bugs.  The only exception is
 *  VectorSYSCALL.
 *  Trap is called with interrupts disabled via interrupt-gates.
 */
void
trap(Ureg* ureg)
{
	int clockintr, vno, user;
	// cache the previous vno to see what might be causing
	// trouble
	vno = ureg->type;
	uint64_t gsbase = rdmsr(GSbase);
	//if (sce > scx) iprint("====================");
	lastvno = vno;
	if (gsbase < 1ULL<<63)
		die("bogus gsbase");
	Proc *up = externup();
	char buf[ERRMAX];
	Vctl *ctl, *v;

	machp()->perf.intrts = perfticks();
	user = userureg(ureg);
	if(user && (machp()->NIX.nixtype == NIXTC)){
		up->dbgreg = ureg;
		cycles(&up->kentry);
	}

	clockintr = 0;

	//_pmcupdate(machp());

	if((ctl = vctl[vno]) != nil){
		if(ctl->isintr){
			machp()->intr++;
			if(vno >= VectorPIC && vno != VectorSYSCALL)
				machp()->lastintr = ctl->Vkey.irq;
		}else
			if(up)
				up->nqtrap++;

		if(ctl->isr){
			ctl->isr(vno);
			if(islo())print("trap %d: isr %p enabled interrupts\n", vno, ctl->isr);
		}
		for(v = ctl; v != nil; v = v->next){
			if(v->f){
				v->f(ureg, v->a);
				if(islo())print("trap %d: ctlf %p enabled interrupts\n", vno, v->f);
			}
		}
		if(ctl->eoi){
			ctl->eoi(vno);
			if(islo())print("trap %d: eoi %p enabled interrupts\n", vno, ctl->eoi);
		}

		intrtime(vno);
		if(ctl->isintr){
			if(ctl->Vkey.irq == IrqCLOCK || ctl->Vkey.irq == IrqTIMER)
				clockintr = 1;

			if (ctl->Vkey.irq == IrqTIMER)
				oprof_alarm_handler(ureg);

			if(up && !clockintr)
				preempted();
		}
	}
	else if(vno < nelem(excname) && user){
		spllo();
		snprint(buf, sizeof buf, "sys: trap: %s", excname[vno]);
		postnote(up, 1, buf, NDebug);
	}
	else if(vno >= VectorPIC && vno != VectorSYSCALL){
		/*
		 * An unknown interrupt.
		 * Check for a default IRQ7. This can happen when
		 * the IRQ input goes away before the acknowledge.
		 * In this case, a 'default IRQ7' is generated, but
		 * the corresponding bit in the ISR isn't set.
		 * In fact, just ignore all such interrupts.
		 */

		/* clear the interrupt */
		i8259isr(vno);

		iprint("cpu%d: spurious interrupt %d, last %d\n",
			machp()->machno, vno, machp()->lastintr);
		intrtime(vno);
		if(user)
			kexit(ureg);
		return;
	}
	else{
		if(vno == VectorNMI){
			nmienable();
			if(machp()->machno != 0){
				iprint("cpu%d: PC %#llx\n",
					machp()->machno, ureg->ip);
				for(;;);
			}
		}
		dumpregs(ureg);
		if(!user){
			ureg->sp = PTR2UINT(&ureg->sp);
			dumpstackwithureg(ureg);
		}
		if(vno < nelem(excname))
			panic("%s", excname[vno]);
		panic("unknown trap/intr: %d\n", vno);
	}
	splhi();

	/* delaysched set because we held a lock or because our quantum ended */
	if(up && up->delaysched && clockintr){
		if(0)
		if(user && up->ac == nil && up->nqtrap == 0 && up->nqsyscall == 0){
			if(!waserror()){
				up->ac = getac(up, -1);
				poperror();
				runacore();
				return;
			}
		}
		sched();
		splhi();
	}


	if(user){
		if(up != nil && (up->procctl || up->nnote))
			notify(ureg);
		kexit(ureg);
	}
}
Пример #10
0
static void *
_namenode_recv_worker(void *v_nn)
{
	const size_t RESIZE = 16*1024;

	bool nnlocked = false;
	int sock, obj_size, error, i;

	struct _hdfs_result *result;
	struct hdfs_rpc_response_future *future;
	struct hdfs_namenode *n = v_nn;
	struct hdfs_error herror;

	error = 0;

	while (true) {
		char *objbuffer;
		size_t *objused;

		_lock(&n->nn_lock);
		nnlocked = true;
		sock = n->nn_sock;

		// If hdfs_namenode_destroy() happened, die:
		if (n->nn_dead) {
			herror = error_from_hdfs(HDFS_ERR_NAMENODE_UNCONNECTED);
			break;
		}

		_unlock(&n->nn_lock);
		nnlocked = false;

		ASSERT(sock != -1);

		if (n->nn_sasl_ssf > 0) {
			objbuffer = n->nn_objbuf;
			objused = &n->nn_objbuf_used;
		} else {
			objbuffer = n->nn_recvbuf;
			objused = &n->nn_recvbuf_used;
		}

		if (n->nn_proto == HDFS_NN_v1)
			result = _hdfs_result_deserialize(objbuffer, *objused,
			    &obj_size);
		else if (n->nn_proto == HDFS_NN_v2) {
			_lock(&n->nn_lock);
			result = _hdfs_result_deserialize_v2(objbuffer,
			    *objused, &obj_size, n->nn_pending,
			    n->nn_pending_len);
			_unlock(&n->nn_lock);
		} else if (n->nn_proto == HDFS_NN_v2_2) {
			_lock(&n->nn_lock);
			result = _hdfs_result_deserialize_v2_2(objbuffer,
			    *objused, &obj_size, n->nn_pending,
			    n->nn_pending_len);
			_unlock(&n->nn_lock);
		} else
			ASSERT(false);

		if (!result) {
			ssize_t r, remain = n->nn_recvbuf_size - n->nn_recvbuf_used;

			if (remain < 4*1024) {
				n->nn_recvbuf_size += RESIZE;
				n->nn_recvbuf = realloc(n->nn_recvbuf, n->nn_recvbuf_size);
				ASSERT(n->nn_recvbuf);
				remain = n->nn_recvbuf_size - n->nn_recvbuf_used;
			}

			r = recv(sock, n->nn_recvbuf + n->nn_recvbuf_used,
			    remain, MSG_DONTWAIT);
			if (r == 0) {
				herror = error_from_hdfs(HDFS_ERR_END_OF_STREAM);
				goto out;
			}
			if (r > 0) {
				n->nn_recvbuf_used += r;
				if (n->nn_sasl_ssf > 0)
					_conn_try_desasl(n);
			} else {
				if (errno != EAGAIN && errno != EWOULDBLOCK) {
					// bail on socket errors
					error = errno;
					herror = error_from_errno(error);
					goto out;
				}

				struct pollfd pfds[] = { {
					.fd = sock,
					.events = POLLIN,
				}, {
					.fd = n->nn_recv_sigpipe[0],
					.events = POLLIN,
				} };
				int rc;

				do {
					rc = poll(pfds, nelem(pfds),
					    -1 /* infinite */);
				} while (rc < 0 && errno == EINTR);
				ASSERT(rc > 0);
			}
Пример #11
0
Файл: dn.c Проект: aahud/harvey
[Runimplimented] =	"unimplemented",
[Rrefused] =		"we don't like you",
[Ryxdomain] =		"name should not exist",
[Ryxrrset] =		"rr set should not exist",
[Rnxrrset] =		"rr set should exist",
[Rnotauth] =		"not authorative",
[Rnotzone] =		"not in zone",
[Rbadvers] =		"bad opt version",
/* [Rbadsig] =		"bad signature", */
[Rbadkey] =		"bad key",
[Rbadtime] =		"bad signature time",
[Rbadmode] =		"bad mode",
[Rbadname] =		"duplicate key name",
[Rbadalg] =		"bad algorithm",
};
unsigned nrname = nelem(rname);

/* names of op codes */
char *opname[] =
{
[Oquery] =	"query",
[Oinverse] =	"inverse query (retired)",
[Ostatus] =	"status",
[Oupdate] =	"update",
};

uint32_t target = Deftarget;
uint32_t start;
Lock	dnlock;

static uint32_t agefreq = Defagefreq;
Пример #12
0
void
_runetabinit(void)
{
	runeconsttab = _cvtstringtab(_runeconsttab, nelem(_runeconsttab));
	return;
}
Пример #13
0
const char *jsC_opcodestring(enum js_OpCode opcode)
{
	if (opcode < nelem(opname))
		return opname[opcode];
	return "<unknown>";
}
Пример #14
0
const char *jsP_aststring(enum js_AstType type)
{
	if (type < nelem(astname))
		return astname[type];
	return "<unknown>";
}
Пример #15
0
static long
floppywrite(Chan *c, void *a, long n, vlong off)
{
	FDrive *dp;
	long rv, i;
	char *aa = a;
	Cmdbuf *cb;
	Cmdtab *ct;
	ulong offset = off;

	rv = 0;
	dp = &fl.d[c->qid.path & ~Qmask];
	switch ((int)(c->qid.path & Qmask)) {
	case Qdata:
		islegal(offset, n, dp);
		qlock(&fl);
		if(waserror()){
			qunlock(&fl);
			nexterror();
		}
		floppyon(dp);
		changed(c, dp);
		for(rv = 0; rv < n; rv += i){
			floppypos(dp, offset+rv);
			if(dp->tcyl == dp->ccyl)
				dp->ccyl = -1;
			i = floppyxfer(dp, Fwrite, aa+rv, offset+rv, n-rv);
			if(i < 0)
				break;
			if(i == 0)
				error(Eio);
		}
		qunlock(&fl);
		poperror();
		break;
	case Qctl:
		rv = n;
		cb = parsecmd(a, n);
		if(waserror()){
			free(cb);
			nexterror();
		}
		qlock(&fl);
		if(waserror()){
			qunlock(&fl);
			nexterror();
		}
		ct = lookupcmd(cb, floppyctlmsg, nelem(floppyctlmsg));
		switch(ct->index){
		case CMeject:
			floppyeject(dp);
			break;
		case CMformat:
			floppyformat(dp, cb);
			break;
		case CMreset:
			fl.confused = 1;
			floppyon(dp);
			break;
		case CMdebug:
			floppydebug = 1;
			break;
		case CMnodebug:
			floppydebug = 0;
			break;
		}
		poperror();
		qunlock(&fl);
		poperror();
		free(cb);
		break;
	default:
		panic("floppywrite: bad qid");
	}

	return rv;
}
Пример #16
0
pdf_font_desc *
pdf_load_type3_font(pdf_document *xref, pdf_obj *rdb, pdf_obj *dict)
{
	char buf[256];
	char *estrings[256];
	pdf_font_desc *fontdesc = NULL;
	pdf_obj *encoding;
	pdf_obj *widths;
	pdf_obj *charprocs;
	pdf_obj *obj;
	int first, last;
	int i, k, n;
	fz_rect bbox;
	fz_matrix matrix;
	fz_context *ctx = xref->ctx;

	fz_var(fontdesc);

	fz_try(ctx)
	{
		obj = pdf_dict_gets(dict, "Name");
		if (pdf_is_name(obj))
			fz_strlcpy(buf, pdf_to_name(obj), sizeof buf);
		else
			sprintf(buf, "Unnamed-T3");

		fontdesc = pdf_new_font_desc(ctx);

		obj = pdf_dict_gets(dict, "FontMatrix");
		matrix = pdf_to_matrix(ctx, obj);

		obj = pdf_dict_gets(dict, "FontBBox");
		bbox = pdf_to_rect(ctx, obj);
		bbox = fz_transform_rect(matrix, bbox);

		fontdesc->font = fz_new_type3_font(ctx, buf, matrix);
		fontdesc->size += sizeof(fz_font) + 256 * (sizeof(fz_buffer*) + sizeof(float));

		fz_set_font_bbox(ctx, fontdesc->font, bbox.x0, bbox.y0, bbox.x1, bbox.y1);

		/* SumatraPDF: expose Type3 FontDescriptor flags */
		fontdesc->flags = pdf_to_int(pdf_dict_gets(pdf_dict_gets(dict, "FontDescriptor"), "Flags"));

		/* Encoding */

		for (i = 0; i < 256; i++)
			estrings[i] = NULL;

		encoding = pdf_dict_gets(dict, "Encoding");
		if (!encoding)
		{
			fz_throw(ctx, "syntaxerror: Type3 font missing Encoding");
		}

		if (pdf_is_name(encoding))
			pdf_load_encoding(estrings, pdf_to_name(encoding));

		if (pdf_is_dict(encoding))
		{
			pdf_obj *base, *diff, *item;

			base = pdf_dict_gets(encoding, "BaseEncoding");
			if (pdf_is_name(base))
				pdf_load_encoding(estrings, pdf_to_name(base));

			diff = pdf_dict_gets(encoding, "Differences");
			if (pdf_is_array(diff))
			{
				n = pdf_array_len(diff);
				k = 0;
				for (i = 0; i < n; i++)
				{
					item = pdf_array_get(diff, i);
					if (pdf_is_int(item))
						k = pdf_to_int(item);
					if (pdf_is_name(item) && k >= 0 && k < nelem(estrings))
						estrings[k++] = pdf_to_name(item);
				}
			}
		}

		fontdesc->encoding = pdf_new_identity_cmap(ctx, 0, 1);
		fontdesc->size += pdf_cmap_size(ctx, fontdesc->encoding);

		pdf_load_to_unicode(xref, fontdesc, estrings, NULL, pdf_dict_gets(dict, "ToUnicode"));

		/* SumatraPDF: trying to match Adobe Reader's behavior */
		if (!(fontdesc->flags & PDF_FD_SYMBOLIC) && fontdesc->cid_to_ucs_len >= 128)
			for (i = 32; i < 128; i++)
				if (fontdesc->cid_to_ucs[i] == '?' || fontdesc->cid_to_ucs[i] == '\0')
					fontdesc->cid_to_ucs[i] = i;

		/* Widths */

		pdf_set_default_hmtx(ctx, fontdesc, 0);

		first = pdf_to_int(pdf_dict_gets(dict, "FirstChar"));
		last = pdf_to_int(pdf_dict_gets(dict, "LastChar"));

		/* cf. http://code.google.com/p/sumatrapdf/issues/detail?id=1966 */
		if (first >= 256 && last - first < 256)
		{
			fz_warn(ctx, "ignoring out-of-bound values for FirstChar/LastChar: %d/%d", first, last);
			last -= first;
			first = 0;
		}

		if (first < 0 || last > 255 || first > last)
			first = last = 0;

		widths = pdf_dict_gets(dict, "Widths");
		if (!widths)
		{
			fz_throw(ctx, "syntaxerror: Type3 font missing Widths");
		}

		for (i = first; i <= last; i++)
		{
			float w = pdf_to_real(pdf_array_get(widths, i - first));
			w = fontdesc->font->t3matrix.a * w * 1000;
			fontdesc->font->t3widths[i] = w * 0.001f;
			pdf_add_hmtx(ctx, fontdesc, i, i, w);
		}

		pdf_end_hmtx(ctx, fontdesc);

		/* Resources -- inherit page resources if the font doesn't have its own */

		fontdesc->font->t3freeres = pdf_t3_free_resources;
		fontdesc->font->t3resources = pdf_dict_gets(dict, "Resources");
		if (!fontdesc->font->t3resources)
			fontdesc->font->t3resources = rdb;
		if (fontdesc->font->t3resources)
			pdf_keep_obj(fontdesc->font->t3resources);
		if (!fontdesc->font->t3resources)
			fz_warn(ctx, "no resource dictionary for type 3 font!");

		fontdesc->font->t3doc = xref;
		fontdesc->font->t3run = pdf_run_glyph_func;

		/* CharProcs */

		charprocs = pdf_dict_gets(dict, "CharProcs");
		if (!charprocs)
		{
			fz_throw(ctx, "syntaxerror: Type3 font missing CharProcs");
		}

		for (i = 0; i < 256; i++)
		{
			if (estrings[i])
			{
				/* SumatraPDF: don't reject fonts with few broken glyphs */
				fz_try(ctx)
				{

				obj = pdf_dict_gets(charprocs, estrings[i]);
				if (pdf_is_stream(xref, pdf_to_num(obj), pdf_to_gen(obj)))
				{
					fontdesc->font->t3procs[i] = pdf_load_stream(xref, pdf_to_num(obj), pdf_to_gen(obj));
					fontdesc->size += fontdesc->font->t3procs[i]->cap;
					fontdesc->size += 0; // TODO: display list size calculation
				}

				}
				fz_catch(ctx)
				{
					fz_warn(ctx, "failed to get data for type 3 glyph '%s'", estrings[i]);
				}
			}
		}
	}
	fz_catch(ctx)
	{
		if (fontdesc)
			pdf_drop_font(ctx, fontdesc);
		fz_throw(ctx, "cannot load type3 font (%d %d R)", pdf_to_num(dict), pdf_to_gen(dict));
	}
	return fontdesc;
}
Пример #17
0
/*
 *  format a track
 */
static void
floppyformat(FDrive *dp, Cmdbuf *cb)
{
 	int cyl, h, sec;
	ulong track;
	uchar *buf, *bp;
	FType *t;

	/*
	 *  set the type
	 */
	if(cb->nf == 2){
		for(t = floppytype; t < &floppytype[nelem(floppytype)]; t++){
			if(strcmp(cb->f[1], t->name)==0 && t->dt==dp->dt){
				dp->t = t;
				floppydir[1+NFDIR*dp->dev].length = dp->t->cap;
				break;
			}
		}
		if(t >= &floppytype[nelem(floppytype)])
			error(Ebadarg);
	} else if(cb->nf == 1){
		floppysetdef(dp);
		t = dp->t;
	} else {
		cmderror(cb, "invalid floppy format command");
		SET(t);
	}

	/*
	 *  buffer for per track info
	 */
	buf = smalloc(t->sectors*4);
	if(waserror()){
		free(buf);
		nexterror();
	}

	/* force a recalibrate to cylinder 0 */
	dp->confused = 1;
	if(!waserror()){
		floppyon(dp);
		poperror();
	}

	/*
	 *  format a track at time
	 */
	for(track = 0; track < t->tracks*t->heads; track++){
		cyl = track/t->heads;
		h = track % t->heads;

		/*
		 *  seek to track, ignore errors
		 */
		floppyseek(dp, track*t->tsize);
		dp->cyl = cyl;
		dp->confused = 0;

		/*
		 *  set up the dma (dp->len may be trimmed)
		 */
		bp = buf;
		for(sec = 1; sec <= t->sectors; sec++){
			*bp++ = cyl;
			*bp++ = h;
			*bp++ = sec;
			*bp++ = t->bcode;
		}
		if(waserror()){
			dmaend(DMAchan);
			nexterror();
		}
		if(dmasetup(DMAchan, buf, bp-buf, 0) < 0)
			error(Eio);

		/*
		 *  start operation
		 */
		fl.ncmd = 0;
		fl.cmd[fl.ncmd++] = Fformat;
		fl.cmd[fl.ncmd++] = (h<<2) | dp->dev;
		fl.cmd[fl.ncmd++] = t->bcode;
		fl.cmd[fl.ncmd++] = t->sectors;
		fl.cmd[fl.ncmd++] = t->fgpl;
		fl.cmd[fl.ncmd++] = 0x5a;
		if(floppycmd() < 0)
			error(Eio);

		/* Poll ready bits and transfer data */
		floppyexec((char *)buf, bp-buf, 0);

		/*
		 *  give bus to DMA, floppyintr() will read result
		 */
		floppywait(1);
		dmaend(DMAchan);
		poperror();

		/*
		 *  check for errors
		 */
		if(fl.nstat < 7){
			DPRINT("format: confused\n");
			fl.confused = 1;
			error(Eio);
		}
		if((fl.stat[0]&Codemask)!=0 || fl.stat[1]|| fl.stat[2]){
			DPRINT("format: failed %ux %ux %ux\n",
				fl.stat[0], fl.stat[1], fl.stat[2]);
			dp->confused = 1;
			error(Eio);
		}
	}
	free(buf);
	dp->confused = 1;
	poperror();
}
Пример #18
0
// shouldbuild reports whether we should build this file.
// It applies the same rules that are used with context tags
// in package go/build, except that the GOOS and GOARCH
// can appear anywhere in the file name, not just after _.
// In particular, they can be the entire file name (like windows.c).
// We also allow the special tag cmd_go_bootstrap.
// See ../go/bootstrap.go and package go/build.
static bool
shouldbuild(char *file, char *dir)
{
	char *name, *p;
	int i, j, ret;
	Buf b;
	Vec lines, fields;

	// On Plan 9, most of the libraries are already present.
	// The main exception is libmach which has been modified
	// in various places to support Go object files.
	if(streq(gohostos, "plan9")) {
		if(streq(dir, "lib9")) {
			name = lastelem(file);
			if(streq(name, "goos.c") || streq(name, "flag.c"))
				return 1;
			if(!contains(name, "plan9"))
				return 0;
		}
		if(streq(dir, "libbio"))
			return 0;
	}
	
	// Check file name for GOOS or GOARCH.
	name = lastelem(file);
	for(i=0; i<nelem(okgoos); i++)
		if(contains(name, okgoos[i]) && !streq(okgoos[i], goos))
			return 0;
	for(i=0; i<nelem(okgoarch); i++)
		if(contains(name, okgoarch[i]) && !streq(okgoarch[i], goarch))
			return 0;

	// Omit test files.
	if(contains(name, "_test"))
		return 0;

	// cmd/go/doc.go has a giant /* */ comment before
	// it gets to the important detail that it is not part of
	// package main.  We don't parse those comments,
	// so special case that file.
	if(hassuffix(file, "cmd/go/doc.go") || hassuffix(file, "cmd\\go\\doc.go"))
		return 0;
	if(hassuffix(file, "cmd/cgo/doc.go") || hassuffix(file, "cmd\\cgo\\doc.go"))
		return 0;

	// Check file contents for // +build lines.
	binit(&b);
	vinit(&lines);
	vinit(&fields);

	ret = 1;
	readfile(&b, file);
	splitlines(&lines, bstr(&b));
	for(i=0; i<lines.len; i++) {
		p = lines.p[i];
		while(*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
			p++;
		if(*p == '\0')
			continue;
		if(contains(p, "package documentation")) {
			ret = 0;
			goto out;
		}
		if(contains(p, "package main") && !streq(dir, "cmd/go") && !streq(dir, "cmd/cgo")) {
			ret = 0;
			goto out;
		}
		if(!hasprefix(p, "//"))
			break;
		if(!contains(p, "+build"))
			continue;
		splitfields(&fields, lines.p[i]);
		if(fields.len < 2 || !streq(fields.p[1], "+build"))
			continue;
		for(j=2; j<fields.len; j++) {
			p = fields.p[j];
			if((*p == '!' && !matchfield(p+1)) || matchfield(p))
				goto fieldmatch;
		}
		ret = 0;
		goto out;
	fieldmatch:;
	}

out:
	bfree(&b);
	vfree(&lines);
	vfree(&fields);

	return ret;
}
Пример #19
0
// mkzruntimedefs writes zruntime_defs_$GOOS_$GOARCH.h,
// which contains Go struct definitions equivalent to the C ones.
// Mostly we just write the output of 6c -q to the file.
// However, we run it on multiple files, so we have to delete
// the duplicated definitions, and we don't care about the funcs
// and consts, so we delete those too.
// 
void
mkzruntimedefs(char *dir, char *file)
{
	int i, skip;
	char *p;
	Buf in, b, b1, out;
	Vec argv, lines, fields, seen;
	
	binit(&in);
	binit(&b);
	binit(&b1);
	binit(&out);
	vinit(&argv);
	vinit(&lines);
	vinit(&fields);
	vinit(&seen);
	
	bwritestr(&out, "// auto generated by go tool dist\n"
		"\n"
		"package runtime\n"
		"import \"unsafe\"\n"
		"var _ unsafe.Pointer\n"
		"\n"
	);

	
	// Run 6c -D GOOS_goos -D GOARCH_goarch -I workdir -q -n -o workdir/runtimedefs
	// on each of the runtimedefs C files.
	vadd(&argv, bpathf(&b, "%s/%sc", tooldir, gochar));
	vadd(&argv, "-D");
	vadd(&argv, bprintf(&b, "GOOS_%s", goos));
	vadd(&argv, "-D");
	vadd(&argv, bprintf(&b, "GOARCH_%s", goarch));
	vadd(&argv, "-I");
	vadd(&argv, bprintf(&b, "%s", workdir));
	vadd(&argv, "-q");
	vadd(&argv, "-n");
	vadd(&argv, "-o");
	vadd(&argv, bpathf(&b, "%s/runtimedefs", workdir));
	vadd(&argv, "");
	p = argv.p[argv.len-1];
	for(i=0; i<nelem(runtimedefs); i++) {
		argv.p[argv.len-1] = runtimedefs[i];
		runv(nil, dir, CheckExit, &argv);
		readfile(&b, bpathf(&b1, "%s/runtimedefs", workdir));
		bwriteb(&in, &b);
	}
	argv.p[argv.len-1] = p;
		
	// Process the aggregate output.
	skip = 0;
	splitlines(&lines, bstr(&in));
	for(i=0; i<lines.len; i++) {
		p = lines.p[i];
		// Drop comment, func, and const lines.
		if(hasprefix(p, "//") || hasprefix(p, "const") || hasprefix(p, "func"))
			continue;
		
		// Note beginning of type or var decl, which can be multiline.
		// Remove duplicates.  The linear check of seen here makes the
		// whole processing quadratic in aggregate, but there are only
		// about 100 declarations, so this is okay (and simple).
		if(hasprefix(p, "type ") || hasprefix(p, "var ")) {
			splitfields(&fields, p);
			if(fields.len < 2)
				continue;
			if(find(fields.p[1], seen.p, seen.len) >= 0) {
				if(streq(fields.p[fields.len-1], "{"))
					skip = 1;  // skip until }
				continue;
			}
			vadd(&seen, fields.p[1]);
		}
		if(skip) {
			if(hasprefix(p, "}"))
				skip = 0;
			continue;
		}
		
		bwritestr(&out, p);
	}
	
	writefile(&out, file, 0);

	bfree(&in);
	bfree(&b);
	bfree(&b1);
	bfree(&out);
	vfree(&argv);
	vfree(&lines);
	vfree(&fields);
	vfree(&seen);
}
Пример #20
0
// setup sets up the tree for the initial build.
static void
setup(void)
{
	int i;
	Buf b;
	char *p;

	binit(&b);

	// Create bin directory.
	p = bpathf(&b, "%s/bin", goroot);
	if(!isdir(p))
		xmkdir(p);

	// Create package directory.
	p = bpathf(&b, "%s/pkg", goroot);
	if(!isdir(p))
		xmkdir(p);
	p = bpathf(&b, "%s/pkg/%s_%s", goroot, gohostos, gohostarch);
	if(rebuildall)
		xremoveall(p);
	xmkdirall(p);
	if(!streq(goos, gohostos) || !streq(goarch, gohostarch)) {
		p = bpathf(&b, "%s/pkg/%s_%s", goroot, goos, goarch);
		if(rebuildall)
			xremoveall(p);
		xmkdirall(p);
	}

	// Create object directory.
	// We keep it in pkg/ so that all the generated binaries
	// are in one tree.  If pkg/obj/libgc.a exists, it is a dreg from
	// before we used subdirectories of obj.  Delete all of obj
	// to clean up.
	bpathf(&b, "%s/pkg/obj/libgc.a", goroot);
	if(isfile(bstr(&b)))
		xremoveall(bpathf(&b, "%s/pkg/obj", goroot));
	p = bpathf(&b, "%s/pkg/obj/%s_%s", goroot, gohostos, gohostarch);
	if(rebuildall)
		xremoveall(p);
	xmkdirall(p);

	// Create tool directory.
	// We keep it in pkg/, just like the object directory above.
	if(rebuildall)
		xremoveall(tooldir);
	xmkdirall(tooldir);

	// Remove tool binaries from before the tool/gohostos_gohostarch
	xremoveall(bpathf(&b, "%s/bin/tool", goroot));

	// Remove old pre-tool binaries.
	for(i=0; i<nelem(oldtool); i++)
		xremove(bpathf(&b, "%s/bin/%s", goroot, oldtool[i]));

	// If $GOBIN is set and has a Go compiler, it must be cleaned.
	for(i=0; gochars[i]; i++) {
		if(isfile(bprintf(&b, "%s%s%c%s", gobin, slash, gochars[i], "g"))) {
			for(i=0; i<nelem(oldtool); i++)
				xremove(bprintf(&b, "%s%s%s", gobin, slash, oldtool[i]));
			break;
		}
	}

	// For release, make sure excluded things are excluded.
	if(hasprefix(goversion, "release.") || hasprefix(goversion, "go")) {
		for(i=0; i<nelem(unreleased); i++)
			if(isdir(bpathf(&b, "%s/%s", goroot, unreleased[i])))
				fatal("%s should not exist in release build", bstr(&b));
	}

	bfree(&b);
}
Пример #21
0
static char*
morename[] =
{
	"runtime.morestack00",
	"runtime.morestack10",
	"runtime.morestack01",
	"runtime.morestack11",

	"runtime.morestack8",
	"runtime.morestack16",
	"runtime.morestack24",
	"runtime.morestack32",
	"runtime.morestack40",
	"runtime.morestack48",
};
Prog*	pmorestack[nelem(morename)];
Sym*	symmorestack[nelem(morename)];

void
dostkoff(void)
{
	Prog *p, *q, *q1;
	int32 autoffset, deltasp;
	int a, pcsize;
	uint32 moreconst1, moreconst2, i;

	for(i=0; i<nelem(morename); i++) {
		symmorestack[i] = lookup(morename[i], 0);
		if(symmorestack[i]->type != STEXT)
			diag("morestack trampoline not defined - %s", morename[i]);
		pmorestack[i] = symmorestack[i]->text;
Пример #22
0
// install installs the library, package, or binary associated with dir,
// which is relative to $GOROOT/src.
static void
install(char *dir)
{
	char *name, *p, *elem, *prefix, *exe;
	bool islib, ispkg, isgo, stale, clang;
	Buf b, b1, path;
	Vec compile, files, link, go, missing, clean, lib, extra;
	Time ttarg, t;
	int i, j, k, n, doclean, targ, usecpp;

	if(vflag) {
		if(!streq(goos, gohostos) || !streq(goarch, gohostarch))
			errprintf("%s (%s/%s)\n", dir, goos, goarch);
		else
			errprintf("%s\n", dir);
	}

	binit(&b);
	binit(&b1);
	binit(&path);
	vinit(&compile);
	vinit(&files);
	vinit(&link);
	vinit(&go);
	vinit(&missing);
	vinit(&clean);
	vinit(&lib);
	vinit(&extra);


	// path = full path to dir.
	bpathf(&path, "%s/src/%s", goroot, dir);
	name = lastelem(dir);

	// For misc/prof, copy into the tool directory and we're done.
	if(hasprefix(dir, "misc/")) {
		copy(bpathf(&b, "%s/%s", tooldir, name),
			bpathf(&b1, "%s/misc/%s", goroot, name), 1);
		goto out;
	}

	// For release, cmd/prof is not included.
	if((streq(dir, "cmd/prof")) && !isdir(bstr(&path))) {
		if(vflag > 1)
			errprintf("skipping %s - does not exist\n", dir);
		goto out;
	}

	// set up gcc command line on first run.
	if(gccargs.len == 0) {
		xgetenv(&b, "CC");
		if(b.len == 0)
			bprintf(&b, "gcc");
		clang = contains(bstr(&b), "clang");
		splitfields(&gccargs, bstr(&b));
		for(i=0; i<nelem(proto_gccargs); i++)
			vadd(&gccargs, proto_gccargs[i]);
		if(clang) {
			// clang is too smart about unused command-line arguments
			vadd(&gccargs, "-Qunused-arguments");
		}
		if(streq(gohostos, "darwin")) {
			// golang.org/issue/5261
			vadd(&gccargs, "-mmacosx-version-min=10.6");
		}
	}

	islib = hasprefix(dir, "lib") || streq(dir, "cmd/cc") || streq(dir, "cmd/gc");
	ispkg = hasprefix(dir, "pkg");
	isgo = ispkg || streq(dir, "cmd/go") || streq(dir, "cmd/cgo");

	exe = "";
	if(streq(gohostos, "windows"))
		exe = ".exe";

	// Start final link command line.
	// Note: code below knows that link.p[targ] is the target.
	if(islib) {
		// C library.
		vadd(&link, "ar");
		if(streq(gohostos, "plan9"))
			vadd(&link, "rc");
		else
			vadd(&link, "rsc");
		prefix = "";
		if(!hasprefix(name, "lib"))
			prefix = "lib";
		targ = link.len;
		vadd(&link, bpathf(&b, "%s/pkg/obj/%s_%s/%s%s.a", goroot, gohostos, gohostarch, prefix, name));
	} else if(ispkg) {
		// Go library (package).
		vadd(&link, bpathf(&b, "%s/pack", tooldir));
		vadd(&link, "grc");
		p = bprintf(&b, "%s/pkg/%s_%s/%s", goroot, goos, goarch, dir+4);
		*xstrrchr(p, '/') = '\0';
		xmkdirall(p);
		targ = link.len;
		vadd(&link, bpathf(&b, "%s/pkg/%s_%s/%s.a", goroot, goos, goarch, dir+4));
	} else if(streq(dir, "cmd/go") || streq(dir, "cmd/cgo")) {
		// Go command.
		vadd(&link, bpathf(&b, "%s/%sl", tooldir, gochar));
		vadd(&link, "-o");
		elem = name;
		if(streq(elem, "go"))
			elem = "go_bootstrap";
		targ = link.len;
		vadd(&link, bpathf(&b, "%s/%s%s", tooldir, elem, exe));
	} else {
		// C command. Use gccargs.
		if(streq(gohostos, "plan9")) {
			vadd(&link, bprintf(&b, "%sl", gohostchar));
			vadd(&link, "-o");
			targ = link.len;
			vadd(&link, bpathf(&b, "%s/%s", tooldir, name));
		} else {
			vcopy(&link, gccargs.p, gccargs.len);
			vadd(&link, "-o");
			targ = link.len;
			vadd(&link, bpathf(&b, "%s/%s%s", tooldir, name, exe));
			if(streq(gohostarch, "amd64"))
				vadd(&link, "-m64");
			else if(streq(gohostarch, "386"))
				vadd(&link, "-m32");
		}
	}
	ttarg = mtime(link.p[targ]);

	// Gather files that are sources for this target.
	// Everything in that directory, and any target-specific
	// additions.
	xreaddir(&files, bstr(&path));

	// Remove files beginning with . or _,
	// which are likely to be editor temporary files.
	// This is the same heuristic build.ScanDir uses.
	// There do exist real C files beginning with _,
	// so limit that check to just Go files.
	n = 0;
	for(i=0; i<files.len; i++) {
		p = files.p[i];
		if(hasprefix(p, ".") || (hasprefix(p, "_") && hassuffix(p, ".go")))
			xfree(p);
		else
			files.p[n++] = p;
	}
	files.len = n;

	for(i=0; i<nelem(deptab); i++) {
		if(hasprefix(dir, deptab[i].prefix)) {
			for(j=0; (p=deptab[i].dep[j])!=nil; j++) {
				breset(&b1);
				bwritestr(&b1, p);
				bsubst(&b1, "$GOROOT", goroot);
				bsubst(&b1, "$GOOS", goos);
				bsubst(&b1, "$GOARCH", goarch);
				p = bstr(&b1);
				if(hassuffix(p, ".a")) {
					if(streq(gohostos, "plan9") && hassuffix(p, "libbio.a"))
						continue;
					vadd(&lib, bpathf(&b, "%s", p));
					continue;
				}
				if(hassuffix(p, "/*")) {
					bpathf(&b, "%s/%s", bstr(&path), p);
					b.len -= 2;
					xreaddir(&extra, bstr(&b));
					bprintf(&b, "%s", p);
					b.len -= 2;
					for(k=0; k<extra.len; k++)
						vadd(&files, bpathf(&b1, "%s/%s", bstr(&b), extra.p[k]));
					continue;
				}
				if(hasprefix(p, "-")) {
					p++;
					n = 0;
					for(k=0; k<files.len; k++) {
						if(hasprefix(files.p[k], p))
							xfree(files.p[k]);
						else
							files.p[n++] = files.p[k];
					}
					files.len = n;
					continue;
				}
				vadd(&files, p);
			}
		}
	}
	vuniq(&files);

	// Convert to absolute paths.
	for(i=0; i<files.len; i++) {
		if(!isabs(files.p[i])) {
			bpathf(&b, "%s/%s", bstr(&path), files.p[i]);
			xfree(files.p[i]);
			files.p[i] = btake(&b);
		}
	}

	// Is the target up-to-date?
	stale = rebuildall;
	n = 0;
	for(i=0; i<files.len; i++) {
		p = files.p[i];
		for(j=0; j<nelem(depsuffix); j++)
			if(hassuffix(p, depsuffix[j]))
				goto ok;
		xfree(files.p[i]);
		continue;
	ok:
		t = mtime(p);
		if(t != 0 && !hassuffix(p, ".a") && !shouldbuild(p, dir)) {
			xfree(files.p[i]);
			continue;
		}
		if(hassuffix(p, ".go"))
			vadd(&go, p);
		if(t > ttarg)
			stale = 1;
		if(t == 0) {
			vadd(&missing, p);
			files.p[n++] = files.p[i];
			continue;
		}
		files.p[n++] = files.p[i];
	}
	files.len = n;

	// If there are no files to compile, we're done.
	if(files.len == 0)
		goto out;
	
	for(i=0; i<lib.len && !stale; i++)
		if(mtime(lib.p[i]) > ttarg)
			stale = 1;

	if(!stale)
		goto out;

	// For package runtime, copy some files into the work space.
	if(streq(dir, "pkg/runtime")) {
		copy(bpathf(&b, "%s/arch_GOARCH.h", workdir),
			bpathf(&b1, "%s/arch_%s.h", bstr(&path), goarch), 0);
		copy(bpathf(&b, "%s/defs_GOOS_GOARCH.h", workdir),
			bpathf(&b1, "%s/defs_%s_%s.h", bstr(&path), goos, goarch), 0);
		p = bpathf(&b1, "%s/signal_%s_%s.h", bstr(&path), goos, goarch);
		if(isfile(p))
			copy(bpathf(&b, "%s/signal_GOOS_GOARCH.h", workdir), p, 0);
		copy(bpathf(&b, "%s/os_GOOS.h", workdir),
			bpathf(&b1, "%s/os_%s.h", bstr(&path), goos), 0);
		copy(bpathf(&b, "%s/signals_GOOS.h", workdir),
			bpathf(&b1, "%s/signals_%s.h", bstr(&path), goos), 0);
	}

	// Generate any missing files; regenerate existing ones.
	for(i=0; i<files.len; i++) {
		p = files.p[i];
		elem = lastelem(p);
		for(j=0; j<nelem(gentab); j++) {
			if(hasprefix(elem, gentab[j].nameprefix)) {
				if(vflag > 1)
					errprintf("generate %s\n", p);
				gentab[j].gen(bstr(&path), p);
				// Do not add generated file to clean list.
				// In pkg/runtime, we want to be able to
				// build the package with the go tool,
				// and it assumes these generated files already
				// exist (it does not know how to build them).
				// The 'clean' command can remove
				// the generated files.
				goto built;
			}
		}
		// Did not rebuild p.
		if(find(p, missing.p, missing.len) >= 0)
			fatal("missing file %s", p);
	built:;
	}

	// One more copy for package runtime.
	// The last batch was required for the generators.
	// This one is generated.
	if(streq(dir, "pkg/runtime")) {
		copy(bpathf(&b, "%s/zasm_GOOS_GOARCH.h", workdir),
			bpathf(&b1, "%s/zasm_%s_%s.h", bstr(&path), goos, goarch), 0);
	}

	// Generate .c files from .goc files.
	if(streq(dir, "pkg/runtime")) {
		for(i=0; i<files.len; i++) {
			p = files.p[i];
			if(!hassuffix(p, ".goc"))
				continue;
			// b = path/zp but with _goos_goarch.c instead of .goc
			bprintf(&b, "%s%sz%s", bstr(&path), slash, lastelem(p));
			b.len -= 4;
			bwritef(&b, "_%s_%s.c", goos, goarch);
			goc2c(p, bstr(&b));
			vadd(&files, bstr(&b));
		}
		vuniq(&files);
	}

	if((!streq(goos, gohostos) || !streq(goarch, gohostarch)) && isgo) {
		// We've generated the right files; the go command can do the build.
		if(vflag > 1)
			errprintf("skip build for cross-compile %s\n", dir);
		goto nobuild;
	}

	// The files generated by GNU Bison use macros that aren't
	// supported by the Plan 9 compilers so we have to use the
	// external preprocessor when compiling.
	usecpp = 0;
	if(streq(gohostos, "plan9")) {
		for(i=0; i<files.len; i++) {
			p = files.p[i];
			if(hassuffix(p, "y.tab.c") || hassuffix(p, "y.tab.h")){
				usecpp = 1;
				break;
			}
		}
	}

	// Compile the files.
	for(i=0; i<files.len; i++) {
		if(!hassuffix(files.p[i], ".c") && !hassuffix(files.p[i], ".s"))
			continue;
		name = lastelem(files.p[i]);

		vreset(&compile);
		if(!isgo) {
			// C library or tool.
			if(streq(gohostos, "plan9")) {
				vadd(&compile, bprintf(&b, "%sc", gohostchar));
				vadd(&compile, "-FTVw");
				if(usecpp)
					vadd(&compile, "-Bp+");
				vadd(&compile, bpathf(&b, "-I%s/include/plan9", goroot));
				vadd(&compile, bpathf(&b, "-I%s/include/plan9/%s", goroot, gohostarch));
			} else {
				vcopy(&compile, gccargs.p, gccargs.len);
				vadd(&compile, "-c");
				if(streq(gohostarch, "amd64"))
					vadd(&compile, "-m64");
				else if(streq(gohostarch, "386"))
					vadd(&compile, "-m32");
				if(streq(dir, "lib9"))
					vadd(&compile, "-DPLAN9PORT");
	
				vadd(&compile, "-I");
				vadd(&compile, bpathf(&b, "%s/include", goroot));
			}

			vadd(&compile, "-I");
			vadd(&compile, bstr(&path));

			// lib9/goos.c gets the default constants hard-coded.
			if(streq(name, "goos.c")) {
				vadd(&compile, "-D");
				vadd(&compile, bprintf(&b, "GOOS=\"%s\"", goos));
				vadd(&compile, "-D");
				vadd(&compile, bprintf(&b, "GOARCH=\"%s\"", goarch));
				bprintf(&b1, "%s", goroot_final);
				bsubst(&b1, "\\", "\\\\");  // turn into C string
				vadd(&compile, "-D");
				vadd(&compile, bprintf(&b, "GOROOT=\"%s\"", bstr(&b1)));
				vadd(&compile, "-D");
				vadd(&compile, bprintf(&b, "GOVERSION=\"%s\"", goversion));
				vadd(&compile, "-D");
				vadd(&compile, bprintf(&b, "GOARM=\"%s\"", goarm));
				vadd(&compile, "-D");
				vadd(&compile, bprintf(&b, "GO386=\"%s\"", go386));
				vadd(&compile, "-D");
				vadd(&compile, bprintf(&b, "GO_EXTLINK_ENABLED=\"%s\"", goextlinkenabled));
			}

			// gc/lex.c records the GOEXPERIMENT setting used during the build.
			if(streq(name, "lex.c")) {
				xgetenv(&b, "GOEXPERIMENT");
				vadd(&compile, "-D");
				vadd(&compile, bprintf(&b1, "GOEXPERIMENT=\"%s\"", bstr(&b)));
			}
		} else {
			// Supporting files for a Go package.
			if(hassuffix(files.p[i], ".s"))
				vadd(&compile, bpathf(&b, "%s/%sa", tooldir, gochar));
			else {
				vadd(&compile, bpathf(&b, "%s/%sc", tooldir, gochar));
				vadd(&compile, "-F");
				vadd(&compile, "-V");
				vadd(&compile, "-w");
			}
			vadd(&compile, "-I");
			vadd(&compile, workdir);
			vadd(&compile, "-I");
			vadd(&compile, bprintf(&b, "%s/pkg/%s_%s", goroot, goos, goarch));
			vadd(&compile, "-D");
			vadd(&compile, bprintf(&b, "GOOS_%s", goos));
			vadd(&compile, "-D");
			vadd(&compile, bprintf(&b, "GOARCH_%s", goarch));
		}

		bpathf(&b, "%s/%s", workdir, lastelem(files.p[i]));
		doclean = 1;
		if(!isgo && streq(gohostos, "darwin")) {
			// To debug C programs on OS X, it is not enough to say -ggdb
			// on the command line.  You have to leave the object files
			// lying around too.  Leave them in pkg/obj/, which does not
			// get removed when this tool exits.
			bpathf(&b1, "%s/pkg/obj/%s", goroot, dir);
			xmkdirall(bstr(&b1));
			bpathf(&b, "%s/%s", bstr(&b1), lastelem(files.p[i]));
			doclean = 0;
		}

		// Change the last character of the output file (which was c or s).
		if(streq(gohostos, "plan9"))
			b.p[b.len-1] = gohostchar[0];
		else
			b.p[b.len-1] = 'o';
		vadd(&compile, "-o");
		vadd(&compile, bstr(&b));
		vadd(&compile, files.p[i]);
		bgrunv(bstr(&path), CheckExit, &compile);

		vadd(&link, bstr(&b));
		if(doclean)
			vadd(&clean, bstr(&b));
	}
	bgwait();

	if(isgo) {
		// The last loop was compiling individual files.
		// Hand the Go files to the compiler en masse.
		vreset(&compile);
		vadd(&compile, bpathf(&b, "%s/%sg", tooldir, gochar));

		bpathf(&b, "%s/_go_.%s", workdir, gochar);
		vadd(&compile, "-o");
		vadd(&compile, bstr(&b));
		vadd(&clean, bstr(&b));
		vadd(&link, bstr(&b));

		vadd(&compile, "-p");
		if(hasprefix(dir, "pkg/"))
			vadd(&compile, dir+4);
		else
			vadd(&compile, "main");

		if(streq(dir, "pkg/runtime"))
			vadd(&compile, "-+");

		vcopy(&compile, go.p, go.len);

		runv(nil, bstr(&path), CheckExit, &compile);
	}

	if(!islib && !isgo) {
		// C binaries need the libraries explicitly, and -lm.
		vcopy(&link, lib.p, lib.len);
		if(!streq(gohostos, "plan9"))
			vadd(&link, "-lm");
	}

	// Remove target before writing it.
	xremove(link.p[targ]);

	runv(nil, nil, CheckExit, &link);

nobuild:
	// In package runtime, we install runtime.h and cgocall.h too,
	// for use by cgo compilation.
	if(streq(dir, "pkg/runtime")) {
		copy(bpathf(&b, "%s/pkg/%s_%s/cgocall.h", goroot, goos, goarch),
			bpathf(&b1, "%s/src/pkg/runtime/cgocall.h", goroot), 0);
		copy(bpathf(&b, "%s/pkg/%s_%s/runtime.h", goroot, goos, goarch),
			bpathf(&b1, "%s/src/pkg/runtime/runtime.h", goroot), 0);
	}


out:
	for(i=0; i<clean.len; i++)
		xremove(clean.p[i]);

	bfree(&b);
	bfree(&b1);
	bfree(&path);
	vfree(&compile);
	vfree(&files);
	vfree(&link);
	vfree(&go);
	vfree(&missing);
	vfree(&clean);
	vfree(&lib);
	vfree(&extra);
}
Пример #23
0
#include "threadimpl.h"

int	_threadnopasser;

#define	NFN		33
#define	ERRLEN	48
typedef struct Note Note;
struct Note
{
	Lock		inuse;
	Proc		*proc;		/* recipient */
	char		s[ERRMAX];	/* arg2 */
};

static Note	notes[128];
static Note	*enotes = notes+nelem(notes);
static int		(*onnote[NFN])(void*, char*);
static int		onnotepid[NFN];
static Lock	onnotelock;

int
threadnotify(int (*f)(void*, char*), int in)
{
	int i, topid;
	int (*from)(void*, char*), (*to)(void*, char*);

	if(in){
		from = nil;
		to = f;
		topid = _threadgetproc()->pid;
	}else{
Пример #24
0
// init handles initialization of the various global state, like goroot and goarch.
void
init(void)
{
	char *p;
	int i;
	Buf b;

	binit(&b);

	xgetenv(&b, "GOROOT");
	if(b.len > 0) {
		// if not "/", then strip trailing path separator
		if(b.len >= 2 && b.p[b.len - 1] == slash[0])
			b.len--;
		goroot = btake(&b);
	}

	xgetenv(&b, "GOBIN");
	if(b.len == 0)
		bprintf(&b, "%s%sbin", goroot, slash);
	gobin = btake(&b);

	xgetenv(&b, "GOOS");
	if(b.len == 0)
		bwritestr(&b, gohostos);
	goos = btake(&b);
	if(find(goos, okgoos, nelem(okgoos)) < 0)
		fatal("unknown $GOOS %s", goos);

	xgetenv(&b, "GOARM");
	if(b.len == 0)
		bwritestr(&b, xgetgoarm());
	goarm = btake(&b);

	xgetenv(&b, "GO386");
	if(b.len == 0) {
		if(cansse2())
			bwritestr(&b, "sse2");
		else
			bwritestr(&b, "387");
	}
	go386 = btake(&b);

	p = bpathf(&b, "%s/include/u.h", goroot);
	if(!isfile(p)) {
		fatal("$GOROOT is not set correctly or not exported\n"
			"\tGOROOT=%s\n"
			"\t%s does not exist", goroot, p);
	}

	xgetenv(&b, "GOHOSTARCH");
	if(b.len > 0)
		gohostarch = btake(&b);

	i = find(gohostarch, okgoarch, nelem(okgoarch));
	if(i < 0)
		fatal("unknown $GOHOSTARCH %s", gohostarch);
	bprintf(&b, "%c", gochars[i]);
	gohostchar = btake(&b);

	xgetenv(&b, "GOARCH");
	if(b.len == 0)
		bwritestr(&b, gohostarch);
	goarch = btake(&b);
	i = find(goarch, okgoarch, nelem(okgoarch));
	if(i < 0)
		fatal("unknown $GOARCH %s", goarch);
	bprintf(&b, "%c", gochars[i]);
	gochar = btake(&b);

	xgetenv(&b, "GO_EXTLINK_ENABLED");
	if(b.len > 0) {
		goextlinkenabled = btake(&b);
		if(!streq(goextlinkenabled, "0") && !streq(goextlinkenabled, "1"))
			fatal("unknown $GO_EXTLINK_ENABLED %s", goextlinkenabled);
	}

	xsetenv("GOROOT", goroot);
	xsetenv("GOARCH", goarch);
	xsetenv("GOOS", goos);
	xsetenv("GOARM", goarm);
	xsetenv("GO386", go386);

	// Make the environment more predictable.
	xsetenv("LANG", "C");
	xsetenv("LANGUAGE", "en_US.UTF8");

	goversion = findgoversion();

	workdir = xworkdir();
	xatexit(rmworkdir);

	bpathf(&b, "%s/pkg/tool/%s_%s", goroot, gohostos, gohostarch);
	tooldir = btake(&b);

	bfree(&b);
}
Пример #25
0
int
findalt(int rec, int nchan, int res, int speed)
{
	Ep *ep;
	Audioalt *a;
	Altc *da;
	int i, j, k, retval;

	retval = -1;
	controls[rec][Channel_control].min = 1000000;
	controls[rec][Channel_control].max = 0;
	controls[rec][Channel_control].step = Undef;
	controls[rec][Resolution_control].min = 1000000;
	controls[rec][Resolution_control].max = 0;
	controls[rec][Resolution_control].step = Undef;
	for(i = 0; i < nelem(ad->usb->ep); i++){
		if((ep = ad->usb->ep[i]) == nil)
			continue;
		if(ep->iface == nil){
			fprint(2, "\tno interface\n");
			return 0;
		}
		if(ep->iface->csp != CSP(Claudio, 2, 0))
			continue;
		if((rec == Play && (ep->addr &  0x80))
		|| (rec == Record && (ep->addr &  0x80) == 0))
			continue;
		for(j = 0; j < 16; j++){
			if((da = ep->iface->altc[j]) == nil || (a = da->aux) == nil)
				continue;
			if(a->nchan < controls[rec][Channel_control].min)
				controls[rec][Channel_control].min = a->nchan;
			if(a->nchan > controls[rec][Channel_control].max)
				controls[rec][Channel_control].max = a->nchan;
			if(a->res < controls[rec][Resolution_control].min)
				controls[rec][Resolution_control].min = a->res;
			if(a->res > controls[rec][Resolution_control].max)
				controls[rec][Resolution_control].max = a->res;
			controls[rec][Channel_control].settable = 1;
			controls[rec][Channel_control].readable = 1;
			controls[rec][Resolution_control].settable = 1;
			controls[rec][Resolution_control].readable = 1;
			controls[rec][Speed_control].settable = 1;
			controls[rec][Speed_control].readable = 1;
			if(a->nchan == nchan && a->res == res){
				if(speed == Undef)
					retval = j;
				else if(a->caps & (has_discfreq|onefreq)){
					for(k = 0; k < nelem(a->freqs); k++){
						if(a->freqs[k] == speed){
							retval = j;
							break;
						}
					}
				}else{
					if(speed >= a->minfreq && speed <= a->maxfreq)
						retval = j;
				}
			}
		}
	}
	if(usbdebug && retval < 0)
		fprint(2, "findalt(%d, %d, %d, %d) failed\n", rec, nchan, res, speed);
	return retval;
}
Пример #26
0
static void
add_property(fz_css_match *match, const char *name, fz_css_value *value, int spec)
{
	int i;

	if (!strcmp(name, "margin"))
	{
		add_shorthand_margin(match, value, spec);
		return;
	}
	if (!strcmp(name, "padding"))
	{
		add_shorthand_padding(match, value, spec);
		return;
	}
	if (!strcmp(name, "border-width"))
	{
		add_shorthand_border_width(match, value, spec);
		return;
	}
	if (!strcmp(name, "border-color"))
	{
		add_shorthand_border_color(match, value, spec);
		return;
	}
	if (!strcmp(name, "border-style"))
	{
		add_shorthand_border_style(match, value, spec);
		return;
	}
	if (!strcmp(name, "border"))
	{
		add_shorthand_border(match, value, spec, 1, 1, 1, 1);
		return;
	}
	if (!strcmp(name, "border-top"))
	{
		add_shorthand_border(match, value, spec, 1, 0, 0, 0);
		return;
	}
	if (!strcmp(name, "border-right"))
	{
		add_shorthand_border(match, value, spec, 0, 1, 0, 0);
		return;
	}
	if (!strcmp(name, "border-bottom"))
	{
		add_shorthand_border(match, value, spec, 0, 0, 1, 0);
		return;
	}
	if (!strcmp(name, "border-left"))
	{
		add_shorthand_border(match, value, spec, 0, 0, 0, 1);
		return;
	}
	if (!strcmp(name, "list-style"))
	{
		add_shorthand_list_style(match, value, spec);
		return;
	}

	/* shorthand expansions: */
	/* TODO: border-color */
	/* TODO: border-style */
	/* TODO: font */
	/* TODO: list-style */
	/* TODO: background */

	for (i = 0; i < match->count; ++i)
	{
		if (!strcmp(match->prop[i].name, name))
		{
			if (match->prop[i].spec <= spec)
			{
				match->prop[i].value = value;
				match->prop[i].spec = spec;
			}
			return;
		}
	}

	if (match->count + 1 >= nelem(match->prop))
	{
		// fz_warn(ctx, "too many css properties");
		return;
	}

	match->prop[match->count].name = name;
	match->prop[match->count].value = value;
	match->prop[match->count].spec = spec;
	++match->count;
}
Пример #27
0
static void
tkstat(Chan* c, char* db)
{
	devstat(c, db, tkdirtab, nelem(tkdirtab), devgen);
}
Пример #28
0
static void
floppyreset(void)
{
	FDrive *dp;
	FType *t;
	ulong maxtsize;
	
	floppysetup0(&fl);
	if(fl.ndrive == 0)
		return;

	/*
	 *  init dependent parameters
	 */
	maxtsize = 0;
	for(t = floppytype; t < &floppytype[nelem(floppytype)]; t++){
		t->cap = t->bytes * t->heads * t->sectors * t->tracks;
		t->bcode = b2c[t->bytes/128];
		t->tsize = t->bytes * t->sectors;
		if(maxtsize < t->tsize)
			maxtsize = t->tsize;
	}

	/*
	 * Should check if this fails. Can do so
	 * if there is no space <= 16MB for the DMA
	 * bounce buffer.
	 */
	dmainit(DMAchan, maxtsize);

	/*
	 *  allocate the drive storage
	 */
	fl.d = xalloc(fl.ndrive*sizeof(FDrive));
	fl.selected = fl.d;

	/*
	 *  stop the motors
	 */
	fl.motor = 0;
	delay(10);
	outb(Pdor, fl.motor | Fintena | Fena);
	delay(10);

	/*
	 *  init drives
	 */
	for(dp = fl.d; dp < &fl.d[fl.ndrive]; dp++){
		dp->dev = dp - fl.d;
		dp->dt = T1440kb;
		floppysetdef(dp);
		dp->cyl = -1;			/* because we don't know */
		dp->cache = (uchar*)xspanalloc(maxtsize, BY2PG, 64*1024);
		dp->ccyl = -1;
		dp->vers = 0;
	}

	/*
	 *  first operation will recalibrate
	 */
	fl.confused = 1;

	floppysetup1(&fl);
}
Пример #29
0
Файл: cout.c Проект: aiju/hdl
static char *
getcopdata(int op)
{
	if(op >= nelem(cops)) return nil;
	return cops[op];
}
Пример #30
0
Файл: obj.c Проект: hfeeki/go
void
ldobj1(Biobuf *f, char *pkg, int64 len, char *pn)
{
    vlong ipc;
    Prog *p;
    int v, o, r, skip, mode;
    Sym *h[NSYM], *s;
    uint32 sig;
    char *name, *x;
    int ntext;
    vlong eof;
    char src[1024];
    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;
    mode = 64;

loop:
    if(f->state == Bracteof || Boffset(f) >= eof)
        goto eof;
    o = BGETC(f);
    if(o == Beof)
        goto eof;
    o |= BGETC(f) << 8;
    if(o <= AXXX || o >= ALAST) {
        if(o < 0)
            goto eof;
        diag("%s:#%lld: opcode out of range: %#ux", pn, Boffset(f), o);
        print("	probably not a .6 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(debug['S'] && r == 0)
            sig = 1729;
        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))
            mangle(pn);
        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);
            dwarfaddfrag(s->value, s->name);
        }
        goto loop;
    }

    p = mal(sizeof(*p));
    p->as = o;
    p->line = Bget4(f);
    p->back = 2;
    p->mode = mode;
    p->ft = 0;
    p->tt = 0;
    zaddr(pn, f, &p->from, h);
    fromgotype = adrgotype;
    zaddr(pn, f, &p->to, h);

    switch(p->as) {
    case ATEXT:
    case ADATA:
    case AGLOBL:
        if(p->from.sym == S)
            mangle(pn);
        break;
    }

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

    switch(p->as) {
    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->type == 0 || s->type == SXREF) {
            s->type = SBSS;
            s->size = 0;
        }
        if(s->type != SBSS && s->type != SNOPTRBSS && !s->dupok) {
            diag("%s: redefinition: %s in %s",
                 pn, s->name, TNAME);
            s->type = SBSS;
            s->size = 0;
        }
        if(p->to.offset > s->size)
            s->size = p->to.offset;
        if(p->from.scale & DUPOK)
            s->dupok = 1;
        if(p->from.scale & RODATA)
            s->type = SRODATA;
        else if(p->from.scale & NOPTR)
            s->type = SNOPTRBSS;
        goto loop;

    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);
        goto loop;

    case AGOK:
        diag("%s: GOK opcode in %s", pn, TNAME);
        pc++;
        goto loop;

    case ATEXT:
        s = p->from.sym;
        if(s->text != nil) {
            if(p->from.scale & DUPOK) {
                skip = 1;
                goto casdef;
            }
            diag("%s: %s: redefinition", pn, s->name);
            return;
        }
        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;
        }
        if(cursym != nil && cursym->text) {
            histtoauto();
            cursym->autom = curauto;
            curauto = 0;
        }
        skip = 0;
        if(etextp)
            etextp->next = s;
        else
            textp = s;
        etextp = s;
        s->text = p;
        cursym = s;
        if(s->type != 0 && s->type != SXREF) {
            if(p->from.scale & DUPOK) {
                skip = 1;
                goto casdef;
            }
            diag("%s: redefinition: %s\n%P", pn, s->name, p);
        }
        if(fromgotype) {
            if(s->gotype && s->gotype != fromgotype)
                diag("%s: type mismatch for %s", pn, s->name);
            s->gotype = fromgotype;
        }
        s->type = STEXT;
        s->value = pc;
        lastp = p;
        p->pc = pc++;
        goto loop;

    case AMODE:
        if(p->from.type == D_CONST || p->from.type == D_INDIR+D_NONE) {
            switch((int)p->from.offset) {
            case 16:
            case 32:
            case 64:
                mode = p->from.offset;
                break;
            }
        }
        goto loop;

    case AFMOVF:
    case AFADDF:
    case AFSUBF:
    case AFSUBRF:
    case AFMULF:
    case AFDIVF:
    case AFDIVRF:
    case AFCOMF:
    case AFCOMFP:
    case AMOVSS:
    case AADDSS:
    case ASUBSS:
    case AMULSS:
    case ADIVSS:
    case ACOMISS:
    case AUCOMISS:
        if(skip)
            goto casdef;
        if(p->from.type == D_FCONST) {
            /* size sb 9 max */
            sprint(literal, "$%ux", ieeedtof(&p->from.ieee));
            s = lookup(literal, 0);
            if(s->type == 0) {
                s->type = SDATA;
                adduint32(s, ieeedtof(&p->from.ieee));
                s->reachable = 0;
            }
            p->from.type = D_EXTERN;
            p->from.sym = s;
            p->from.offset = 0;
        }
        goto casdef;

    case AFMOVD:
    case AFADDD:
    case AFSUBD:
    case AFSUBRD:
    case AFMULD:
    case AFDIVD:
    case AFDIVRD:
    case AFCOMD:
    case AFCOMDP:
    case AMOVSD:
    case AADDSD:
    case ASUBSD:
    case AMULSD:
    case ADIVSD:
    case ACOMISD:
    case AUCOMISD:
        if(skip)
            goto casdef;
        if(p->from.type == D_FCONST) {
            /* 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 = SDATA;
                adduint32(s, p->from.ieee.l);
                adduint32(s, p->from.ieee.h);
                s->reachable = 0;
            }
            p->from.type = D_EXTERN;
            p->from.sym = s;
            p->from.offset = 0;
        }
        goto casdef;

casdef:
    default:
        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);
            goto loop;
        }
        lastp->link = p;
        lastp = p;
        goto loop;
    }

eof:
    diag("truncated object file: %s", pn);
}