Exemplo n.º 1
0
void
loadlib(void)
{
	int i, w, x;
	LSym *s, *gmsym;
	char* cgostrsym;

	if(flag_shared) {
		s = linklookup(ctxt, "runtime.islibrary", 0);
		s->dupok = 1;
		adduint8(ctxt, s, 1);
	}

	loadinternal("runtime");
	if(thechar == '5')
		loadinternal("math");
	if(flag_race)
		loadinternal("runtime/race");

	for(i=0; i<ctxt->libraryp; i++) {
		if(debug['v'] > 1)
			Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(), ctxt->library[i].file, ctxt->library[i].objref);
		iscgo |= strcmp(ctxt->library[i].pkg, "runtime/cgo") == 0;
		objfile(ctxt->library[i].file, ctxt->library[i].pkg);
	}
	
	if(linkmode == LinkExternal && !iscgo) {
		// This indicates a user requested -linkmode=external.
		// The startup code uses an import of runtime/cgo to decide
		// whether to initialize the TLS.  So give it one.  This could
		// be handled differently but it's an unusual case.
		loadinternal("runtime/cgo");

		// Pretend that we really imported the package.
		s = linklookup(ctxt, "go.importpath.runtime/cgo.", 0);
		s->type = SDATA;
		s->dupok = 1;
		s->reachable = 1;

		// Provided by the code that imports the package.
		// Since we are simulating the import, we have to provide this string.
		cgostrsym = "go.string.\"runtime/cgo\"";
		if(linkrlookup(ctxt, cgostrsym, 0) == nil)
			addstrdata(cgostrsym, "runtime/cgo");
	}

	if(linkmode == LinkAuto) {
		if(iscgo && externalobj)
			linkmode = LinkExternal;
		else
			linkmode = LinkInternal;
	}

	if(linkmode == LinkInternal) {
		// Drop all the cgo_import_static declarations.
		// Turns out we won't be needing them.
		for(s = ctxt->allsym; s != S; s = s->allsym)
			if(s->type == SHOSTOBJ) {
				// If a symbol was marked both
				// cgo_import_static and cgo_import_dynamic,
				// then we want to make it cgo_import_dynamic
				// now.
				if(s->extname != nil && s->dynimplib != nil && s->cgoexport == 0) {
					s->type = SDYNIMPORT;
				} else
					s->type = 0;
			}
	}
	
	gmsym = linklookup(ctxt, "runtime.tlsgm", 0);
	gmsym->type = STLSBSS;
	gmsym->size = 2*PtrSize;
	gmsym->hide = 1;
	gmsym->reachable = 1;

	// Now that we know the link mode, trim the dynexp list.
	x = CgoExportDynamic;
	if(linkmode == LinkExternal)
		x = CgoExportStatic;
	w = 0;
	for(i=0; i<ndynexp; i++)
		if(dynexp[i]->cgoexport & x)
			dynexp[w++] = dynexp[i];
	ndynexp = w;
	
	// In internal link mode, read the host object files.
	if(linkmode == LinkInternal)
		hostobjs();
	else
		hostlinksetup();

	// We've loaded all the code now.
	// If there are no dynamic libraries needed, gcc disables dynamic linking.
	// Because of this, glibc's dynamic ELF loader occasionally (like in version 2.13)
	// assumes that a dynamic binary always refers to at least one dynamic library.
	// Rather than be a source of test cases for glibc, disable dynamic linking
	// the same way that gcc would.
	//
	// Exception: on OS X, programs such as Shark only work with dynamic
	// binaries, so leave it enabled on OS X (Mach-O) binaries.
	// Also leave it enabled on Solaris which doesn't support
	// statically linked binaries.
	if(!flag_shared && !havedynamic && HEADTYPE != Hdarwin && HEADTYPE != Hsolaris)
		debug['d'] = 1;
	
	importcycles();
}
Exemplo 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':
		debug['I'] = 1; // denote cmdline interpreter override
		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'] = 0;	// with dynamic linking
		tlsoffset = -8; // hardcoded number, first 4-byte word for g, and then 4-byte word for m
		                // this number is known to ../../pkg/runtime/cgo/gcc_linux_arm.c
		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();
	addexport();
	// textaddress() functionality is handled in 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();
}
Exemplo n.º 3
0
void
deadcode(void)
{
	int i;
	Sym *s, *last, *p;
	Auto *z;
	Fmt fmt;

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

	mark(lookup(INITENTRY, 0));
	for(i=0; i<nelem(markextra); i++)
		mark(lookup(markextra[i], 0));

	for(i=0; i<ndynexp; i++)
		mark(dynexp[i]);

	markflood();
	
	// keep each beginning with 'typelink.' if the symbol it points at is being kept.
	for(s = allsym; s != S; s = s->allsym) {
		if(strncmp(s->name, "go.typelink.", 12) == 0)
			s->reachable = s->nr==1 && s->r[0].sym->reachable;
	}

	// remove dead text but keep file information (z symbols).
	last = nil;
	z = nil;
	for(s = textp; s != nil; s = s->next) {
		if(!s->reachable) {
			if(isz(s->autom))
				z = s->autom;
			continue;
		}
		if(last == nil)
			textp = s;
		else
			last->next = s;
		last = s;
		if(z != nil) {
			if(!isz(s->autom))
				addz(s, z);
			z = nil;
		}
	}
	if(last == nil)
		textp = nil;
	else
		last->next = nil;
	
	for(s = allsym; s != S; s = s->allsym)
		if(strncmp(s->name, "go.weak.", 8) == 0) {
			s->special = 1;  // do not lay out in data segment
			s->reachable = 1;
			s->hide = 1;
		}
	
	// record field tracking references
	fmtstrinit(&fmt);
	for(s = allsym; s != S; s = s->allsym) {
		if(strncmp(s->name, "go.track.", 9) == 0) {
			s->special = 1;  // do not lay out in data segment
			s->hide = 1;
			if(s->reachable) {
				fmtprint(&fmt, "%s", s->name+9);
				for(p=s->reachparent; p; p=p->reachparent)
					fmtprint(&fmt, "\t%s", p->name);
				fmtprint(&fmt, "\n");
			}
			s->type = SCONST;
			s->value = 0;
		}
	}
	if(tracksym == nil)
		return;
	s = lookup(tracksym, 0);
	if(!s->reachable)
		return;
	addstrdata(tracksym, fmtstrflush(&fmt));
}
Exemplo n.º 4
0
Arquivo: obj.c Projeto: pipul/lab
void
main(int argc, char *argv[])
{
	int c;
	char *name, *val;

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

	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 = headtype(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 'V':
		print("%cl version %s\n", thechar, getgoversion());
		errorexit();
	case 'X':
		name = EARGF(usage());
		val = EARGF(usage());
		addstrdata(name, val);
		break;
	} ARGEND

	if(argc != 1)
		usage();

	mywhatsys();	// get goos

	if(HEADTYPE == -1)
		HEADTYPE = headtype(goos);

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

	libinit();

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

	case Hgarbunix:	/* this is garbage */
		HEADR = 20L+56L;
		if(INITTEXT == -1)
			INITTEXT = 0x40004CL;
		if(INITDAT == -1)
			INITDAT = 0x10000000L;
		if(INITRND == -1)
			INITRND = 0;
		break;
	case Hunixcoff:	/* is unix coff */
		HEADR = 0xd0L;
		if(INITTEXT == -1)
			INITTEXT = 0xd0;
		if(INITDAT == -1)
			INITDAT = 0x400000;
		if(INITRND == -1)
			INITRND = 0;
		break;
	case Hplan9x32:	/* plan 9 */
		tlsoffset = -8;
		HEADR = 32L;
		if(INITTEXT == -1)
			INITTEXT = 4096+32;
		if(INITDAT == -1)
			INITDAT = 0;
		if(INITRND == -1)
			INITRND = 4096;
		break;
	case Hmsdoscom:	/* MS-DOS .COM */
		HEADR = 0;
		if(INITTEXT == -1)
			INITTEXT = 0x0100;
		if(INITDAT == -1)
			INITDAT = 0;
		if(INITRND == -1)
			INITRND = 4;
		break;
	case Hmsdosexe:	/* 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%d\n", HEADR);
		break;
	case Hdarwin:	/* apple MACH */
		/*
		 * OS X system constant - offset from %gs to our TLS.
		 * Explained in ../../pkg/runtime/cgo/gcc_darwin_386.c.
		 */
		tlsoffset = 0x468;
		machoinit();
		HEADR = INITIAL_MACHO_HEADR;
		if(INITTEXT == -1)
			INITTEXT = 4096+HEADR;
		if(INITDAT == -1)
			INITDAT = 0;
		if(INITRND == -1)
			INITRND = 4096;
		break;
	case Hlinux:	/* elf32 executable */
	case Hfreebsd:
	case Hnetbsd:
	case Hopenbsd:
		/*
		 * ELF uses TLS offsets negative from %gs.
		 * Translate 0(GS) and 4(GS) into -8(GS) and -4(GS).
		 * Also known to ../../pkg/runtime/sys_linux_386.s
		 * and ../../pkg/runtime/cgo/gcc_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 Hwindows: /* PE executable */
		peinit();
		HEADR = PEFILEHEADR;
		if(INITTEXT == -1)
			INITTEXT = PEBASE+PESECTHEADR;
		if(INITDAT == -1)
			INITDAT = 0;
		if(INITRND == -1)
			INITRND = PESECTALIGN;
		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);

	instinit();
	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 = "%.6ux ";
	histgen = 0;
	pc = 0;
	dtype = 4;
	version = 0;
	cbp = buf.cbuf;
	cbc = sizeof(buf.cbuf);

	addlibpath("command line", "command line", argv[0], "main");
	loadlib();
	deadcode();
	patch();
	follow();
	doelf();
	if(HEADTYPE == Hdarwin)
		domacho();
	if(HEADTYPE == Hwindows)
		dope();
	dostkoff();
	if(debug['p'])
		if(debug['1'])
			doprof1();
		else
			doprof2();
	span();
	addexport();
	textaddress();
	pclntab();
	symtab();
	dodata();
	address();
	doweak();
	reloc();
	asmb();
	undef();
	if(debug['v']) {
		Bprint(&bso, "%5.2f cpu time\n", cputime());
		Bprint(&bso, "%d symbols\n", nsymbol);
		Bprint(&bso, "%d sizeof adr\n", sizeof(Adr));
		Bprint(&bso, "%d sizeof prog\n", sizeof(Prog));
	}
	Bflush(&bso);

	errorexit();
}
Exemplo n.º 5
0
Arquivo: obj.c Projeto: hfeeki/go
void
main(int argc, char *argv[])
{
    int c;
    char *name, *val;

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

    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 = headtype(EARGF(usage()));
        break;
    case 'I':
        debug['I'] = 1; // denote cmdline interpreter override
        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 'V':
        print("%cl version %s\n", thechar, getgoversion());
        errorexit();
    case 'X':
        name = EARGF(usage());
        val = EARGF(usage());
        addstrdata(name, val);
        break;
    case 'B':
        val = EARGF(usage());
        addbuildinfo(val);
        break;
    } ARGEND

    if(argc != 1)
        usage();

    mywhatsys();	// get goos

    if(HEADTYPE == -1)
        HEADTYPE = headtype(goos);

    if(outfile == nil) {
        if(HEADTYPE == Hwindows)
            outfile = "6.out.exe";
        else
            outfile = "6.out";
    }

    libinit();

    switch(HEADTYPE) {
    default:
        diag("unknown -H option");
        errorexit();
    case Hplan9x32:	/* plan 9 */
        HEADR = 32L;
        if(INITTEXT == -1)
            INITTEXT = 4096+HEADR;
        if(INITDAT == -1)
            INITDAT = 0;
        if(INITRND == -1)
            INITRND = 4096;
        break;
    case Hplan9x64:	/* plan 9 */
        HEADR = 32L + 8L;
        if(INITTEXT == -1)
            INITTEXT = 0x200000+HEADR;
        if(INITDAT == -1)
            INITDAT = 0;
        if(INITRND == -1)
            INITRND = 0x200000;
        break;
    case Helf:	/* elf32 executable */
        HEADR = rnd(52L+3*32L, 16);
        if(INITTEXT == -1)
            INITTEXT = 0x80110000L;
        if(INITDAT == -1)
            INITDAT = 0;
        if(INITRND == -1)
            INITRND = 4096;
        break;
    case Hdarwin:	/* apple MACH */
        /*
         * OS X system constant - offset from 0(GS) to our TLS.
         * Explained in ../../pkg/runtime/cgo/gcc_darwin_amd64.c.
         */
        tlsoffset = 0x8a0;
        machoinit();
        HEADR = INITIAL_MACHO_HEADR;
        if(INITRND == -1)
            INITRND = 4096;
        if(INITTEXT == -1)
            INITTEXT = 4096+HEADR;
        if(INITDAT == -1)
            INITDAT = 0;
        break;
    case Hlinux:	/* elf64 executable */
    case Hfreebsd:	/* freebsd */
    case Hnetbsd:	/* netbsd */
    case Hopenbsd:	/* openbsd */
        /*
         * ELF uses TLS offset negative from FS.
         * Translate 0(FS) and 8(FS) into -16(FS) and -8(FS).
         * Also known to ../../pkg/runtime/sys_linux_amd64.s
         * and ../../pkg/runtime/cgo/gcc_linux_amd64.c.
         */
        tlsoffset = -16;
        elfinit();
        HEADR = ELFRESERVE;
        if(INITTEXT == -1)
            INITTEXT = (1<<22)+HEADR;
        if(INITDAT == -1)
            INITDAT = 0;
        if(INITRND == -1)
            INITRND = 4096;
        break;
    case Hwindows: /* PE executable */
        peinit();
        HEADR = PEFILEHEADR;
        if(INITTEXT == -1)
            INITTEXT = PEBASE+PESECTHEADR;
        if(INITDAT == -1)
            INITDAT = 0;
        if(INITRND == -1)
            INITRND = PESECTALIGN;
        break;
    }
    if(INITDAT != 0 && INITRND != 0)
        print("warning: -D0x%llux is ignored because of -R0x%ux\n",
              INITDAT, INITRND);
    if(debug['v'])
        Bprint(&bso, "HEADER = -H%d -T0x%llux -D0x%llux -R0x%ux\n",
               HEADTYPE, INITTEXT, INITDAT, INITRND);
    Bflush(&bso);
    instinit();

    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;
    zprg.mode = 64;

    pcstr = "%.6llux ";
    histgen = 0;
    pc = 0;
    dtype = 4;
    version = 0;
    cbp = buf.cbuf;
    cbc = sizeof(buf.cbuf);

    addlibpath("command line", "command line", argv[0], "main");
    loadlib();
    deadcode();
    patch();
    follow();
    doelf();
    if(HEADTYPE == Hdarwin)
        domacho();
    dostkoff();
    dostkcheck();
    paramspace = "SP";	/* (FP) now (SP) on output */
    if(debug['p'])
        if(debug['1'])
            doprof1();
        else
            doprof2();
    span();
    if(HEADTYPE == Hwindows)
        dope();
    addexport();
    textaddress();
    pclntab();
    symtab();
    dodata();
    address();
    doweak();
    reloc();
    asmb();
    undef();
    if(debug['v']) {
        Bprint(&bso, "%5.2f cpu time\n", cputime());
        Bprint(&bso, "%d symbols\n", nsymbol);
        Bprint(&bso, "%d sizeof adr\n", sizeof(Adr));
        Bprint(&bso, "%d sizeof prog\n", sizeof(Prog));
    }
    Bflush(&bso);

    errorexit();
}