Пример #1
0
void
asmb(void)
{
	Prog *p;
	long t;
	Optab *o;
	long prevpc;

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

	/* emit text segment */
	seek(cout, HEADR, 0);
	prevpc = pc = INITTEXT;
	for(p = firstp; p != P; p = p->link) {
		if(p->as == ATEXT) {
			curtext = p;
			autosize = p->to.offset + 4;
			if(p->from3.type == D_CONST) {
				for(; pc < p->pc; pc++)
					CPUT(0);
			}
		}
		if(p->pc != pc) {
			diag("phase error %lux sb %lux",
				p->pc, pc);
			if(!debug['a'])
				prasm(curp);
			pc = p->pc;
		}
		curp = p;
		o = oplook(p);	/* could probably avoid this call */
		if(asmout(p, o, 0)) {
			p = p->link;
			pc += 4;
		}
		pc += o->size;
		if (prevpc & (1<<31) && (pc & (1<<31)) == 0) {
			char *tn;

			tn = "??none??";
			if(curtext != P && curtext->from.sym != S)
				tn = curtext->from.sym->name;
			Bprint(&bso, "%s: warning: text segment wrapped past 0\n", tn);
		}
		prevpc = pc;
	}

	if(debug['a'])
		Bprint(&bso, "\n");
	Bflush(&bso);
	cflush();

	/* emit data segment */
	curtext = P;
	switch(HEADTYPE) {
	case 6:
		/*
		 * but first, for virtex 4, inject a jmp instruction after
		 * other text: branch to absolute entry address (0xfffe2100).
		 */
		lput((18 << 26) | (0x03FFFFFC & entryvalue()) | 2);
		textsize += JMPSZ;
		cflush();
		/* fall through */
	case 0:
	case 1:
	case 2:
	case 5:
		seek(cout, HEADR+textsize, 0);
		break;
	case 3:
		seek(cout, rnd(HEADR+textsize, 4), 0);
		break;
	case 4:
		seek(cout, rnd(HEADR+textsize, 4096), 0);
		break;
	}

	if(dlm){
		char buf[8];

		write(cout, buf, INITDAT-textsize);
		textsize = INITDAT;
	}

	for(t = 0; t < datsize; t += sizeof(buf)-100) {
		if(datsize-t > sizeof(buf)-100)
			datblk(t, sizeof(buf)-100);
		else
			datblk(t, datsize-t);
	}

	symsize = 0;
	lcsize = 0;
	if(!debug['s']) {
		if(debug['v'])
			Bprint(&bso, "%5.2f sym\n", cputime());
		Bflush(&bso);
		switch(HEADTYPE) {
		case 0:
		case 1:
		case 2:
		case 5:
		case 6:
			seek(cout, HEADR+textsize+datsize, 0);
			break;
		case 3:
			seek(cout, rnd(HEADR+textsize, 4)+datsize, 0);
			break;
		case 4:
			seek(cout, rnd(HEADR+textsize, 4096)+datsize, 0);
			break;
		}
		if(!debug['s'])
			asmsym();
		if(debug['v'])
			Bprint(&bso, "%5.2f sp\n", cputime());
		Bflush(&bso);
		if(!debug['s'])
			asmlc();
		if(dlm)
			asmdyn();
		if(HEADTYPE == 0 || HEADTYPE == 1)	/* round up file length for boot image */
			if((symsize+lcsize) & 1)
				CPUT(0);
		cflush();
	}
	else if(dlm){
		asmdyn();
		cflush();
	}

	/* back up and write the header */
	seek(cout, 0L, 0);
	switch(HEADTYPE) {
	case 0:
		lput(0x1030107);		/* magic and sections */
		lput(textsize);			/* sizes */
		lput(datsize);
		lput(bsssize);
		lput(symsize);			/* nsyms */
		lput(entryvalue());		/* va of entry */
		lput(0L);
		lput(lcsize);
		break;
	case 1:
		lput(0x4a6f7921);		/* Joy! */
		lput(0x70656666);		/* peff */
		lput(0x70777063);		/* pwpc */
		lput(1);
		lput(0);
		lput(0);
		lput(0);
		lput(0);
		lput(0x30002);			/*YY*/
		lput(0);
		lput(~0);
		lput(0);
		lput(textsize+datsize);
		lput(textsize+datsize);
		lput(textsize+datsize);
		lput(0xd0);			/* header size */
		lput(0x10400);
		lput(~0);
		lput(0);
		lput(0xc);
		lput(0xc);
		lput(0xc);
		lput(0xc0);
		lput(0x01010400);
		lput(~0);
		lput(0);
		lput(0x38);
		lput(0x38);
		lput(0x38);
		lput(0x80);
		lput(0x04040400);
		lput(0);
		lput(1);
		lput(0);
		lput(~0);
		lput(0);
		lput(~0);
		lput(0);
		lput(0);
		lput(0);
		lput(0);
		lput(0);
		lput(0);
		lput(0);
		lput(0);
		lput(0);
		lput(0);
		lput(0);
		lput(0x3100);			/* load address */
		lput(0);
		lput(0);
		lput(0);			/* whew! */
		break;
	case 2:
		if(dlm)
			lput(0x80000000 | (4*21*21+7));		/* magic */
		else
			lput(4*21*21+7);	/* magic */
		lput(textsize);			/* sizes */
		lput(datsize);
		lput(bsssize);
		lput(symsize);			/* nsyms */
		lput(entryvalue());		/* va of entry */
		lput(0L);
		lput(lcsize);
		break;
	case 3:
		break;
	case 4:
		lput((0x1DFL<<16)|3L);		/* magic and sections */
		lput(time(0));			/* time and date */
		lput(rnd(HEADR+textsize, 4096)+datsize);
		lput(symsize);			/* nsyms */
		lput((0x48L<<16)|15L);		/* size of optional hdr and flags */

		lput((0413<<16)|01L);		/* magic and version */
		lput(textsize);			/* sizes */
		lput(datsize);
		lput(bsssize);
		lput(entryvalue());		/* va of entry */
		lput(INITTEXT);			/* va of base of text */
		lput(INITDAT);			/* va of base of data */
		lput(INITDAT);			/* address of TOC */
		lput((1L<<16)|1);		/* sn(entry) | sn(text) */
		lput((2L<<16)|1);		/* sn(data) | sn(toc) */
		lput((0L<<16)|3);		/* sn(loader) | sn(bss) */
		lput((3L<<16)|3);		/* maxalign(text) | maxalign(data) */
		lput(('1'<<24)|('L'<<16)|0);	/* type field, and reserved */
		lput(0);			/* max stack allowed */
		lput(0);			/* max data allowed */
		lput(0); lput(0); lput(0);	/* reserved */

		strnput(".text", 8);		/* text segment */
		lput(INITTEXT);			/* address */
		lput(INITTEXT);
		lput(textsize);
		lput(HEADR);
		lput(0L);
		lput(HEADR+textsize+datsize+symsize);
		lput(lcsize);			/* line number size */
		lput(0x20L);			/* flags */

		strnput(".data", 8);		/* data segment */
		lput(INITDAT);			/* address */
		lput(INITDAT);
		lput(datsize);
		lput(rnd(HEADR+textsize, 4096));/* sizes */
		lput(0L);
		lput(0L);
		lput(0L);
		lput(0x40L);			/* flags */

		strnput(".bss", 8);		/* bss segment */
		lput(INITDAT+datsize);		/* address */
		lput(INITDAT+datsize);
		lput(bsssize);
		lput(0L);
		lput(0L);
		lput(0L);
		lput(0L);
		lput(0x80L);			/* flags */
		break;
	case 5:
		/*
		 * intended for blue/gene
		 */
		elf32(POWER, ELFDATA2MSB, 0, nil);
		break;
	case 6:
		/*
		 * intended for virtex 4 boot
		 */
		debug['S'] = 1;			/* symbol table */
		elf32(POWER, ELFDATA2MSB, 1, elf32jmp);
		break;
	}
	cflush();
}
Пример #2
0
void
asmb(void)
{
	Prog *p;
	long t;
	Optab *o;

	if(debug['v'])
		Bprint(&bso, "%5.2f asm\n", cputime());
	Bflush(&bso);
	seek(cout, HEADR, 0);
	pc = INITTEXT;
	for(p = firstp; p != P; p = p->link) {
		if(p->as == ATEXT) {
			curtext = p;
			autosize = p->to.offset + 4;
			if(p->from3.type == D_CONST) {
				for(; pc < p->pc; pc++)
					CPUT(0);
			}
		}
		if(p->pc != pc) {
			diag("phase error %lux sb %lux",
				p->pc, pc);
			if(!debug['a'])
				prasm(curp);
			pc = p->pc;
		}
		curp = p;
		o = oplook(p);	/* could probably avoid this call */
		if(asmout(p, o, 0)) {
			p = p->link;
			pc += 4;
		}
		pc += o->size;
	}
	if(debug['a'])
		Bprint(&bso, "\n");
	Bflush(&bso);
	cflush();

	curtext = P;
	switch(HEADTYPE) {
	case 0:
	case 1:
	case 2:
	case 5:
		seek(cout, HEADR+textsize, 0);
		break;
	case 3:
		seek(cout, rnd(HEADR+textsize, 4), 0);
		break;
	case 4:
		seek(cout, rnd(HEADR+textsize, 4096), 0);
		break;
	}

	if(dlm){
		char buf[8];

		write(cout, buf, INITDAT-textsize);
		textsize = INITDAT;
	}

	for(t = 0; t < datsize; t += sizeof(buf)-100) {
		if(datsize-t > sizeof(buf)-100)
			datblk(t, sizeof(buf)-100);
		else
			datblk(t, datsize-t);
	}

	symsize = 0;
	lcsize = 0;
	if(!debug['s']) {
		if(debug['v'])
			Bprint(&bso, "%5.2f sym\n", cputime());
		Bflush(&bso);
		switch(HEADTYPE) {
		case 0:
		case 1:
		case 2:
		case 5:
			seek(cout, HEADR+textsize+datsize, 0);
			break;
		case 3:
			seek(cout, rnd(HEADR+textsize, 4)+datsize, 0);
			break;
		case 4:
			seek(cout, rnd(HEADR+textsize, 4096)+datsize, 0);
			break;
		}
		if(!debug['s'])
			asmsym();
		if(debug['v'])
			Bprint(&bso, "%5.2f sp\n", cputime());
		Bflush(&bso);
		if(!debug['s'])
			asmlc();
		if(dlm)
			asmdyn();
		if(HEADTYPE == 0 || HEADTYPE == 1)	/* round up file length for boot image */
			if((symsize+lcsize) & 1)
				CPUT(0);
		cflush();
	}
	else if(dlm){
		asmdyn();
		cflush();
	}

	seek(cout, 0L, 0);
	switch(HEADTYPE) {
	case 0:
		lput(0x1030107);		/* magic and sections */
		lput(textsize);			/* sizes */
		lput(datsize);
		lput(bsssize);
		lput(symsize);			/* nsyms */
		lput(entryvalue());		/* va of entry */
		lput(0L);
		lput(lcsize);
		break;
	case 1:
		lput(0x4a6f7921);		/* Joy! */
		lput(0x70656666);		/* peff */
		lput(0x70777063);		/* pwpc */
		lput(1);
		lput(0);
		lput(0);
		lput(0);
		lput(0);
		lput(0x30002);			/*YY*/
		lput(0);
		lput(~0);
		lput(0);
		lput(textsize+datsize);
		lput(textsize+datsize);
		lput(textsize+datsize);
		lput(0xd0);			/* header size */
		lput(0x10400);
		lput(~0);
		lput(0);
		lput(0xc);
		lput(0xc);
		lput(0xc);
		lput(0xc0);
		lput(0x01010400);
		lput(~0);
		lput(0);
		lput(0x38);
		lput(0x38);
		lput(0x38);
		lput(0x80);
		lput(0x04040400);
		lput(0);
		lput(1);
		lput(0);
		lput(~0);
		lput(0);
		lput(~0);
		lput(0);
		lput(0);
		lput(0);
		lput(0);
		lput(0);
		lput(0);
		lput(0);
		lput(0);
		lput(0);
		lput(0);
		lput(0);
		lput(0x3100);			/* load address */
		lput(0);
		lput(0);
		lput(0);			/* whew! */
		break;
	case 2:
		if(dlm)
			lput(0x80000000 | (4*21*21+7));		/* magic */
		else
			lput(4*21*21+7);	/* magic */
		lput(textsize);			/* sizes */
		lput(datsize);
		lput(bsssize);
		lput(symsize);			/* nsyms */
		lput(entryvalue());		/* va of entry */
		lput(0L);
		lput(lcsize);
		break;
	case 3:
		break;
	case 4:
		lput((0x1DFL<<16)|3L);		/* magic and sections */
		lput(time(0));			/* time and date */
		lput(rnd(HEADR+textsize, 4096)+datsize);
		lput(symsize);			/* nsyms */
		lput((0x48L<<16)|15L);		/* size of optional hdr and flags */

		lput((0413<<16)|01L);		/* magic and version */
		lput(textsize);			/* sizes */
		lput(datsize);
		lput(bsssize);
		lput(entryvalue());		/* va of entry */
		lput(INITTEXT);			/* va of base of text */
		lput(INITDAT);			/* va of base of data */
		lput(INITDAT);			/* address of TOC */
		lput((1L<<16)|1);		/* sn(entry) | sn(text) */
		lput((2L<<16)|1);		/* sn(data) | sn(toc) */
		lput((0L<<16)|3);		/* sn(loader) | sn(bss) */
		lput((3L<<16)|3);		/* maxalign(text) | maxalign(data) */
		lput(('1'<<24)|('L'<<16)|0);	/* type field, and reserved */
		lput(0);			/* max stack allowed */
		lput(0);			/* max data allowed */
		lput(0); lput(0); lput(0);	/* reserved */

		strnput(".text", 8);		/* text segment */
		lput(INITTEXT);			/* address */
		lput(INITTEXT);
		lput(textsize);
		lput(HEADR);
		lput(0L);
		lput(HEADR+textsize+datsize+symsize);
		lput(lcsize);			/* line number size */
		lput(0x20L);			/* flags */

		strnput(".data", 8);		/* data segment */
		lput(INITDAT);			/* address */
		lput(INITDAT);
		lput(datsize);
		lput(rnd(HEADR+textsize, 4096));/* sizes */
		lput(0L);
		lput(0L);
		lput(0L);
		lput(0x40L);			/* flags */

		strnput(".bss", 8);		/* bss segment */
		lput(INITDAT+datsize);		/* address */
		lput(INITDAT+datsize);
		lput(bsssize);
		lput(0L);
		lput(0L);
		lput(0L);
		lput(0L);
		lput(0x80L);			/* flags */
		break;
	case 5:
		strnput("\177ELF", 4);		/* e_ident */
		CPUT(1);			/* class = 32 bit */
		CPUT(2);			/* data = MSB */
		CPUT(1);			/* version = CURRENT */
		strnput("", 9);
		lput((2L<<16)|20L);		/* type = EXEC; machine = PowerPC */
		lput(1L);			/* version = CURRENT */
		lput(entryvalue() & ~KMASK);	/* entry vaddr */
		lput(52L);			/* offset to first phdr */
		lput(0L);			/* offset to first shdr */
		lput(0L);			/* flags = PPC */
		lput((52L<<16)|32L);		/* Ehdr & Phdr sizes*/
		lput((3L<<16)|0L);		/* # Phdrs & Shdr size */
		lput((0L<<16)|0L);		/* # Shdrs & shdr string size */

		lput(1L);			/* text - type = PT_LOAD */
		lput(HEADR);			/* file offset */
		lput(INITTEXT & ~KMASK);	/* vaddr */
		lput(INITTEXT);			/* paddr */
		lput(textsize);			/* file size */
		lput(textsize);			/* memory size */
		lput(0x05L);			/* protections = RX */
		lput(0x10000L);			/* alignment */

		lput(1L);			/* data - type = PT_LOAD */
		lput(HEADR+textsize);		/* file offset */
		lput(INITDAT & ~KMASK);		/* vaddr */
		lput(INITDAT);			/* paddr */
		lput(datsize);			/* file size */
		lput(datsize);			/* memory size */
		lput(0x07L);			/* protections = RWX */
		lput(0x10000L);			/* alignment */

		lput(0L);			/* data - type = PT_NULL */
		lput(HEADR+textsize+datsize);	/* file offset */
		lput(0L);
		lput(0L);
		lput(symsize);			/* symbol table size */
		lput(lcsize);			/* line number size */
		lput(0x04L);			/* protections = R */
		lput(0x04L);			/* alignment code?? */
		break;
	}
	cflush();
}
Пример #3
0
void
asmb(void)
{
	Prog *p;
	long t, etext;
	Optab *o;

	if(debug['v'])
		Bprint(&bso, "%5.2f asm\n", cputime());
	Bflush(&bso);
	OFFSET = HEADR;
	seek(cout, OFFSET, 0);
	pc = INITTEXT;
	for(p = firstp; p != P; p = p->link) {
		if(p->as == ATEXT) {
			curtext = p;
			autosize = p->to.offset + 4;
		}
		if(p->pc != pc) {
			diag("phase error %lux sb %lux",
				p->pc, pc);
			if(!debug['a'])
				prasm(curp);
			pc = p->pc;
		}
		curp = p;
		o = oplook(p);	/* could probably avoid this call */
		asmout(p, o);
		pc += o->size;
	}

	if(debug['a'])
		Bprint(&bso, "\n");
	Bflush(&bso);
	cflush();

	/* output strings in text segment */
	etext = INITTEXT + textsize;
	for(t = pc; t < etext; t += sizeof(buf)-100) {
		if(etext-t > sizeof(buf)-100)
			datblk(t, sizeof(buf)-100, 1);
		else
			datblk(t, etext-t, 1);
	}

	curtext = P;
	switch(HEADTYPE) {
	case 0:
	case 1:
	case 2:
	case 5:
	case 7:
		OFFSET = HEADR+textsize;
		seek(cout, OFFSET, 0);
		break;
	case 3:
	case 6:	/* no header, padded segments */
		OFFSET = rnd(HEADR+textsize, 4096);
		seek(cout, OFFSET, 0);
		break;
	}
	if(dlm){
		char buf[8];

		write(cout, buf, INITDAT-textsize);
		textsize = INITDAT;
	}
	for(t = 0; t < datsize; t += sizeof(buf)-100) {
		if(datsize-t > sizeof(buf)-100)
			datblk(t, sizeof(buf)-100, 0);
		else
			datblk(t, datsize-t, 0);
	}

	symsize = 0;
	lcsize = 0;
	if(!debug['s']) {
		if(debug['v'])
			Bprint(&bso, "%5.2f sym\n", cputime());
		Bflush(&bso);
		switch(HEADTYPE) {
		case 0:
		case 1:
		case 4:
		case 5:
			debug['s'] = 1;
			break;
		case 2:
			OFFSET = HEADR+textsize+datsize;
			seek(cout, OFFSET, 0);
			break;
		case 3:
		case 6:	/* no header, padded segments */
			OFFSET += rnd(datsize, 4096);
			seek(cout, OFFSET, 0);
			break;
		case 7:
			break;
		}
		if(!debug['s'])
			asmsym();
		if(debug['v'])
			Bprint(&bso, "%5.2f pc\n", cputime());
		Bflush(&bso);
		if(!debug['s'])
			asmlc();
		if(dlm)
			asmdyn();
		cflush();
	}
	else if(dlm){
		seek(cout, HEADR+textsize+datsize, 0);
		asmdyn();
		cflush();
	}

	if(debug['v'])
		Bprint(&bso, "%5.2f header\n", cputime());
	Bflush(&bso);
	OFFSET = 0;
	seek(cout, OFFSET, 0);
	switch(HEADTYPE) {
	case 0:	/* no header */
	case 6:	/* no header, padded segments */
		break;
	case 1:	/* aif for risc os */
		lputl(0xe1a00000);		/* NOP - decompress code */
		lputl(0xe1a00000);		/* NOP - relocation code */
		lputl(0xeb000000 + 12);		/* BL - zero init code */
		lputl(0xeb000000 +
			(entryvalue()
			 - INITTEXT
			 + HEADR
			 - 12
			 - 8) / 4);		/* BL - entry code */

		lputl(0xef000011);		/* SWI - exit code */
		lputl(textsize+HEADR);		/* text size */
		lputl(datsize);			/* data size */
		lputl(0);			/* sym size */

		lputl(bsssize);			/* bss size */
		lputl(0);			/* sym type */
		lputl(INITTEXT-HEADR);		/* text addr */
		lputl(0);			/* workspace - ignored */

		lputl(32);			/* addr mode / data addr flag */
		lputl(0);			/* data addr */
		for(t=0; t<2; t++)
			lputl(0);		/* reserved */

		for(t=0; t<15; t++)
			lputl(0xe1a00000);	/* NOP - zero init code */
		lputl(0xe1a0f00e);		/* B (R14) - zero init return */
		break;
	case 2:	/* plan 9 */
		if(dlm)
			lput(0x80000000|0x647);	/* magic */
		else
			lput(0x647);			/* magic */
		lput(textsize);			/* sizes */
		lput(datsize);
		lput(bsssize);
		lput(symsize);			/* nsyms */
		lput(entryvalue());		/* va of entry */
		lput(0L);
		lput(lcsize);
		break;
	case 3:	/* boot for NetBSD */
		lput((143<<16)|0413);		/* magic */
		lputl(rnd(HEADR+textsize, 4096));
		lputl(rnd(datsize, 4096));
		lputl(bsssize);
		lputl(symsize);			/* nsyms */
		lputl(entryvalue());		/* va of entry */
		lputl(0L);
		lputl(0L);
		break;
	case 4: /* boot for IXP1200 */
		break;
	case 5: /* boot for ipaq */
		lputl(0xe3300000);		/* nop */
		lputl(0xe3300000);		/* nop */
		lputl(0xe3300000);		/* nop */
		lputl(0xe3300000);		/* nop */
		break;
	case 7:	/* elf */
		debug['S'] = 1;			/* symbol table */
		elf32(ARM, ELFDATA2LSB, 0, nil);
		break;
	}
	cflush();
}
Пример #4
0
void
asmb(void)
{
	Prog *p;
	long t;
	Optab *o;

	if(debug['v'])
		Bprint(&bso, "%5.2f asm\n", cputime());
	Bflush(&bso);
	seek(cout, HEADR, 0);
	pc = INITTEXT;
	for(p = firstp; p != P; p = p->link) {
		if(p->as == ATEXT) {
			curtext = p;
			autosize = p->to.offset + 4;
		}
		if(p->pc != pc) {
			diag("phase error %lux sb %lux",
				p->pc, pc);
			if(!debug['a'])
				prasm(curp);
			pc = p->pc;
		}
		curp = p;
		o = oplook(p);	/* could probably avoid this call */
		if(asmout(p, o, 0)) {
			p = p->link;
			pc += 4;
		}
		pc += o->size;
	}
	if(debug['a'])
		Bprint(&bso, "\n");
	Bflush(&bso);
	cflush();

	curtext = P;
	switch(HEADTYPE) {
	case 0:
	case 3:
		seek(cout, HEADR+textsize, 0);
		break;
	case 1:
	case 2:
		seek(cout, HEADR+textsize, 0);
		break;
	}
	for(t = 0; t < datsize; t += sizeof(buf)-100) {
		if(datsize-t > sizeof(buf)-100)
			datblk(t, sizeof(buf)-100);
		else
			datblk(t, datsize-t);
	}

	symsize = 0;
	lcsize = 0;
	if(!debug['s']) {
		if(debug['v'])
			Bprint(&bso, "%5.2f sym\n", cputime());
		Bflush(&bso);
		switch(HEADTYPE) {
		case 0:
		case 3:
			seek(cout, HEADR+textsize+datsize, 0);
			break;
		case 2:
		case 1:
			seek(cout, HEADR+textsize+datsize, 0);
			break;
		}
		if(!debug['s'])
			asmsym();
		if(debug['v'])
			Bprint(&bso, "%5.2f sp\n", cputime());
		Bflush(&bso);
		if(!debug['s'])
			asmlc();
		 /* round up file length for boot image */
		if(HEADTYPE == 0 || HEADTYPE == 3)
			if((symsize+lcsize) & 1)
				CPUT(0);
		cflush();
	}

	seek(cout, 0L, 0);
	switch(HEADTYPE) {
	case 0:
		lput(0x1030107);		/* magic and sections */
		lput(textsize);			/* sizes */
		lput(datsize);
		lput(bsssize);
		lput(symsize);			/* nsyms */
		lput(entryvalue());		/* va of entry */
		lput(0L);
		lput(lcsize);
		break;
	case 1:
		break;
	case 2:
		lput(4*13*13+7);		/* magic */
		lput(textsize);			/* sizes */
		lput(datsize);
		lput(bsssize);
		lput(symsize);			/* nsyms */
		lput(entryvalue());		/* va of entry */
		lput(0L);
		lput(lcsize);
		break;
	case 3:
		lput(0x1030107);		/* magic and sections */
		lput(0x90100000);
#define SPARC_NOOP 0x01000000
		lput(SPARC_NOOP);
		lput(SPARC_NOOP);
		lput(SPARC_NOOP);
		lput(SPARC_NOOP);
		lput(SPARC_NOOP);
		lput(SPARC_NOOP);
		break;
	}
	cflush();
}
Пример #5
0
void
asmb(void)
{
	Prog *p;
	long t, magic;
	Optab *o;
	vlong vl;

	if(debug['v'])
		Bprint(&bso, "%5.2f asm\n", cputime());
	Bflush(&bso);
	seek(cout, HEADR, 0);
	pc = INITTEXT;
	for(p = firstp; p != P; p = p->link) {
		if(p->as == ATEXT) {
			curtext = p;
			autosize = p->to.offset + 8;
			if(p->from3.type == D_CONST) {
				for(; pc < p->pc; pc++)
					CPUT(0);
			}
		}
		if(p->pc != pc) {
			diag("phase error %llux sb %llux",
				p->pc, pc);
			if(!debug['a'])
				prasm(curp);
			pc = p->pc;
		}
		curp = p;
		o = oplook(p);	/* could probably avoid this call */
		if(asmout(p, o, 0)) {
			p = p->link;
			pc += 4;
		}
		pc += o->size;
	}
	if(debug['a'])
		Bprint(&bso, "\n");
	Bflush(&bso);
	cflush();

	curtext = P;
	switch(HEADTYPE) {
	case 0:
	case 1:
	case 2:
	case 5:
	case 9:
	case 10:
		seek(cout, HEADR+textsize, 0);
		break;
	case 3:
		seek(cout, rnd(HEADR+textsize, 4), 0);
		break;
	}

	if(dlm){
		char buf[8];

		write(cout, buf, INITDAT-textsize);
		textsize = INITDAT;
	}

	for(t = 0; t < datsize; t += sizeof(buf)-100) {
		if(datsize-t > sizeof(buf)-100)
			datblk(t, sizeof(buf)-100);
		else
			datblk(t, datsize-t);
	}

	symsize = 0;
	lcsize = 0;
	if(!debug['s']) {
		if(debug['v'])
			Bprint(&bso, "%5.2f sym\n", cputime());
		Bflush(&bso);
		switch(HEADTYPE) {
		case 0:
		case 1:
		case 2:
		case 5:
		case 9:
		case 10:
			seek(cout, HEADR+textsize+datsize, 0);
			break;
		case 3:
			seek(cout, rnd(HEADR+textsize, 4)+datsize, 0);
			break;
		}
		if(!debug['s'])
			asmsym();
		if(debug['v'])
			Bprint(&bso, "%5.2f sp\n", cputime());
		Bflush(&bso);
		if(!debug['s'])
			asmlc();
		if(dlm)
			asmdyn();
		if(HEADTYPE == 0 || HEADTYPE == 1)	/* round up file length for boot image */
			if((symsize+lcsize) & 1)
				CPUT(0);
		cflush();
	}
	else if(dlm){
		asmdyn();
		cflush();
	}

	seek(cout, 0L, 0);
	switch(HEADTYPE) {
	case 0:
		lput(0x1030107);		/* magic and sections */
		lput(textsize);			/* sizes */
		lput(datsize);
		lput(bsssize);
		lput(symsize);			/* nsyms */
		lput(entryvalue());		/* va of entry */
		lput(0L);
		lput(lcsize);
		break;
	case 1:
		if(dlm)
			lput(0x80000000 | (4*21*21+7));		/* q.out magic */
		else
			lput(4*21*21+7);	/* q.out magic */
		lput(textsize);			/* sizes */
		lput(datsize);
		lput(bsssize);
		lput(symsize);			/* nsyms */
		lput(entryvalue());		/* va of entry */
		lput(0L);
		lput(lcsize);
		break;
	case 2:	/* plan9 */
		magic = 4*27*27+7;
		magic |= 0x00008000;		/* fat header */
		if(dlm)
			magic |= 0x80000000;	/* dlm */
		lput(magic);
		lput(textsize);			/* sizes */
		lput(datsize);
		lput(bsssize);
		lput(symsize);			/* nsyms */
		vl = entryvalue();
		lput(PADDR(vl));		/* va of entry (real mode on boot) */
		lput(0L);
		lput(lcsize);
		llput(vl);			/* va of entry */
		break;
	case 3:
		break;
	case 5:
		elf32(POWER, ELFDATA2MSB, 0, nil);
		break;
	case 9:					/* ELF64 Header */
	case 10:				/* A2 weirdness */
		elf64(POWER64, ELFDATA2MSB, 0, nil);
		break;
	}
	cflush();
}
Пример #6
0
void
asmb(void)
{
	Prog *p;
	long t;
	Optab *o;
	long prevpc;

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

	/* emit text segment */
	seek(cout, HEADR, 0);
	prevpc = pc = INITTEXT;
	for(p = firstp; p != P; p = p->link) {
		if(p->as == ATEXT) {
			curtext = p;
			autosize = p->to.offset + 4;
			if(p->from3.type == D_CONST) {
				for(; pc < p->pc; pc++)
					CPUT(0);
			}
		}
		if(p->pc != pc) {
			diag("phase error %lux sb %lux",
				p->pc, pc);
			if(!debug['a'])
				prasm(curp);
			pc = p->pc;
		}
		curp = p;
		o = oplook(p);	/* could probably avoid this call */
		if(asmout(p, o, 0)) {
			p = p->link;
			pc += 4;
		}
		pc += o->size;
		if (prevpc & (1<<31) && (pc & (1<<31)) == 0) {
			char *tn;

			tn = "?none?";
			if(curtext != P && curtext->from.sym != S)
				tn = curtext->from.sym->name;
			Bprint(&bso, "%s: warning: text segment wrapped past 0\n", tn);
		}
		prevpc = pc;
	}
	/* for virtex 4, inject a jmp instruction after other text */
	if(HEADTYPE == 6)
		/* branch to absolute entry address (0xfffe2100) */
		lput((18 << 26) | (0x03FFFFFC & entryvalue()) | 2);

	if(debug['a'])
		Bprint(&bso, "\n");
	Bflush(&bso);
	cflush();

	/* emit data segment */
	curtext = P;
	switch(HEADTYPE) {
	case 6:
		textsize += JMPSZ;
		/* fall through */
	case 0:
	case 1:
	case 2:
	case 5:
		seek(cout, HEADR+textsize, 0);
		break;
	case 3:
		seek(cout, rnd(HEADR+textsize, 4), 0);
		break;
	case 4:
		seek(cout, rnd(HEADR+textsize, 4096), 0);
		break;
	}

	if(dlm){
		char buf[8];

		write(cout, buf, INITDAT-textsize);
		textsize = INITDAT;
	}

	for(t = 0; t < datsize; t += sizeof(buf)-100) {
		if(datsize-t > sizeof(buf)-100)
			datblk(t, sizeof(buf)-100);
		else
			datblk(t, datsize-t);
	}

	symsize = 0;
	lcsize = 0;
	if(!debug['s']) {
		if(debug['v'])
			Bprint(&bso, "%5.2f sym\n", cputime());
		Bflush(&bso);
		switch(HEADTYPE) {
		case 0:
		case 1:
		case 2:
		case 5:
		case 6:
			seek(cout, HEADR+textsize+datsize, 0);
			break;
		case 3:
			seek(cout, rnd(HEADR+textsize, 4)+datsize, 0);
			break;
		case 4:
			seek(cout, rnd(HEADR+textsize, 4096)+datsize, 0);
			break;
		}
		if(!debug['s'])
			asmsym();
		if(debug['v'])
			Bprint(&bso, "%5.2f sp\n", cputime());
		Bflush(&bso);
		if(!debug['s'])
			asmlc();
		if(dlm)
			asmdyn();
		if(HEADTYPE == 0 || HEADTYPE == 1)	/* round up file length for boot image */
			if((symsize+lcsize) & 1)
				CPUT(0);
		cflush();
	}
	else if(dlm){
		asmdyn();
		cflush();
	}

	/* back up and write the header */
	seek(cout, 0L, 0);
	switch(HEADTYPE) {
	case 0:
		lput(0x1030107);		/* magic and sections */
		lput(textsize);			/* sizes */
		lput(datsize);
		lput(bsssize);
		lput(symsize);			/* nsyms */
		lput(entryvalue());		/* va of entry */
		lput(0L);
		lput(lcsize);
		break;
	case 1:
		lput(0x4a6f7921);		/* Joy! */
		lput(0x70656666);		/* peff */
		lput(0x70777063);		/* pwpc */
		lput(1);
		lput(0);
		lput(0);
		lput(0);
		lput(0);
		lput(0x30002);			/*YY*/
		lput(0);
		lput(~0);
		lput(0);
		lput(textsize+datsize);
		lput(textsize+datsize);
		lput(textsize+datsize);
		lput(0xd0);			/* header size */
		lput(0x10400);
		lput(~0);
		lput(0);
		lput(0xc);
		lput(0xc);
		lput(0xc);
		lput(0xc0);
		lput(0x01010400);
		lput(~0);
		lput(0);
		lput(0x38);
		lput(0x38);
		lput(0x38);
		lput(0x80);
		lput(0x04040400);
		lput(0);
		lput(1);
		lput(0);
		lput(~0);
		lput(0);
		lput(~0);
		lput(0);
		lput(0);
		lput(0);
		lput(0);
		lput(0);
		lput(0);
		lput(0);
		lput(0);
		lput(0);
		lput(0);
		lput(0);
		lput(0x3100);			/* load address */
		lput(0);
		lput(0);
		lput(0);			/* whew! */
		break;
	case 2:
		if(dlm)
			lput(0x80000000 | (4*21*21+7));		/* magic */
		else
			lput(4*21*21+7);	/* magic */
		lput(textsize);			/* sizes */
		lput(datsize);
		lput(bsssize);
		lput(symsize);			/* nsyms */
		lput(entryvalue());		/* va of entry */
		lput(0L);
		lput(lcsize);
		break;
	case 3:
		break;
	case 4:
		lput((0x1DFL<<16)|3L);		/* magic and sections */
		lput(time(0));			/* time and date */
		lput(rnd(HEADR+textsize, 4096)+datsize);
		lput(symsize);			/* nsyms */
		lput((0x48L<<16)|15L);		/* size of optional hdr and flags */

		lput((0413<<16)|01L);		/* magic and version */
		lput(textsize);			/* sizes */
		lput(datsize);
		lput(bsssize);
		lput(entryvalue());		/* va of entry */
		lput(INITTEXT);			/* va of base of text */
		lput(INITDAT);			/* va of base of data */
		lput(INITDAT);			/* address of TOC */
		lput((1L<<16)|1);		/* sn(entry) | sn(text) */
		lput((2L<<16)|1);		/* sn(data) | sn(toc) */
		lput((0L<<16)|3);		/* sn(loader) | sn(bss) */
		lput((3L<<16)|3);		/* maxalign(text) | maxalign(data) */
		lput(('1'<<24)|('L'<<16)|0);	/* type field, and reserved */
		lput(0);			/* max stack allowed */
		lput(0);			/* max data allowed */
		lput(0); lput(0); lput(0);	/* reserved */

		strnput(".text", 8);		/* text segment */
		lput(INITTEXT);			/* address */
		lput(INITTEXT);
		lput(textsize);
		lput(HEADR);
		lput(0L);
		lput(HEADR+textsize+datsize+symsize);
		lput(lcsize);			/* line number size */
		lput(0x20L);			/* flags */

		strnput(".data", 8);		/* data segment */
		lput(INITDAT);			/* address */
		lput(INITDAT);
		lput(datsize);
		lput(rnd(HEADR+textsize, 4096));/* sizes */
		lput(0L);
		lput(0L);
		lput(0L);
		lput(0x40L);			/* flags */

		strnput(".bss", 8);		/* bss segment */
		lput(INITDAT+datsize);		/* address */
		lput(INITDAT+datsize);
		lput(bsssize);
		lput(0L);
		lput(0L);
		lput(0L);
		lput(0L);
		lput(0x80L);			/* flags */
		break;
	case 5:
		/*
		 * customised for blue/gene,
		 * notably the alignment and KMASK masking.
		 */
		strnput("\177ELF", 4);		/* e_ident */
		CPUT(1);			/* class = 32 bit */
		CPUT(2);			/* data = MSB */
		CPUT(1);			/* version = CURRENT */
		strnput("", 9);
		lput((2L<<16)|20L);		/* type = EXEC; machine = PowerPC */
		lput(1L);			/* version = CURRENT */
		lput(entryvalue() & ~KMASK);	/* entry vaddr */
		lput(52L);			/* offset to first phdr */

		if(debug['S']){
			lput(HEADR+textsize+datsize+symsize);	/* offset to first shdr */
			lput(0L);		/* flags = PPC */
			lput((52L<<16)|32L);	/* Ehdr & Phdr sizes*/
			lput((3L<<16)|40L);	/* # Phdrs & Shdr size */
			lput((3L<<16)|2L);	/* # Shdrs & shdr string size */
		}
		else{
			lput(0L);
			lput(0L);		/* flags = PPC */
			lput((52L<<16)|32L);	/* Ehdr & Phdr sizes*/
			lput((3L<<16)|0L);	/* # Phdrs & Shdr size */
			lput((3L<<16)|0L);	/* # Shdrs & shdr string size */
		}

		lput(1L);			/* text - type = PT_LOAD */
		lput(HEADR);			/* file offset */
		lput(INITTEXT & ~KMASK);	/* vaddr */
		lput(INITTEXT);			/* paddr */
		lput(textsize);			/* file size */
		lput(textsize);			/* memory size */
		lput(0x05L);			/* protections = RX */
		lput(0x10000L);			/* alignment */

		lput(1L);			/* data - type = PT_LOAD */
		lput(HEADR+textsize);		/* file offset */
		lput(INITDAT & ~KMASK);		/* vaddr */
		lput(INITDAT);			/* paddr */
		lput(datsize);			/* file size */
		lput(datsize);			/* memory size */
		lput(0x07L);			/* protections = RWX */
		lput(0x10000L);			/* alignment */

		lput(0L);			/* data - type = PT_NULL */
		lput(HEADR+textsize+datsize);	/* file offset */
		lput(0L);			/* vaddr */
		lput(0L);			/* paddr */
		lput(symsize);			/* symbol table size */
		lput(lcsize);			/* line number size */
		lput(0x04L);			/* protections = R */
		lput(0x04L);			/* alignment code?? */
		cflush();

		if(!debug['S'])
			break;

		seek(cout, HEADR+textsize+datsize+symsize, 0);
		lput(1);			/* Section name (string tbl index) */
		lput(1);			/* Section type */
		lput(2|4);			/* Section flags */
		lput(INITTEXT & ~KMASK);	/* Section virtual addr at execution */
		lput(HEADR);			/* Section file offset */
		lput(textsize);			/* Section size in bytes */
		lput(0);			/* Link to another section */
		lput(0);			/* Additional section information */
		lput(0x10000L);			/* Section alignment */
		lput(0);			/* Entry size if section holds table */

		lput(7);			/* Section name (string tbl index) */
		lput(1);			/* Section type */
		lput(2|1);			/* Section flags */
		lput(INITDAT & ~KMASK);		/* Section virtual addr at execution */
		lput(HEADR+textsize);		/* Section file offset */
		lput(datsize);			/* Section size in bytes */
		lput(0);			/* Link to another section */
		lput(0);			/* Additional section information */
		lput(0x10000L);			/* Section alignment */
		lput(0);			/* Entry size if section holds table */

		/* string section header */
		lput(12);			/* Section name (string tbl index) */
		lput(3);			/* Section type */
		lput(1 << 5);			/* Section flags */
		lput(0);			/* Section virtual addr at execution */
		lput(HEADR+textsize+datsize+symsize+3*40);	/* Section file offset */
		lput(14);			/* Section size in bytes */
		lput(0);			/* Link to another section */
		lput(0);			/* Additional section information */
		lput(1);			/* Section alignment */
		lput(0);			/* Entry size if section holds table */

		/* string table */
		cput(0);
		strnput(".text", 5);
		cput(0);
		strnput(".data", 5);
		cput(0);
		strnput(".strtab", 7);
		cput(0);
		cput(0);

		break;
	case 6:
		/*
		 * customised for virtex 4 boot,
		 * notably the alignment and KMASK masking.
		 */
		strnput("\177ELF", 4);		/* e_ident */
		CPUT(1);			/* class = 32 bit */
		CPUT(2);			/* data = MSB */
		CPUT(1);			/* version = CURRENT */
		strnput("", 9);
		lput((2L<<16)|20L);		/* type = EXEC; machine = PowerPC */
		lput(1L);			/* version = CURRENT */
		lput(entryvalue());		/* entry vaddr */
		lput(52L);			/* offset to first phdr */

		debug['S'] = 1;			/* no symbol table */
		if(debug['S']){
			lput(HEADR+textsize+datsize+symsize);	/* offset to first shdr */
			lput(0L);		/* flags = PPC */
			lput((52L<<16)|32L);	/* Ehdr & Phdr sizes*/
			lput((4L<<16)|40L);	/* # Phdrs & Shdr size */
			lput((4L<<16)|2L);	/* # Shdrs & shdr string size */
		}
		else{
			lput(0L);
			lput(0L);		/* flags = PPC */
			lput((52L<<16)|32L);	/* Ehdr & Phdr sizes*/
			lput((4L<<16)|0L);	/* # Phdrs & Shdr size */
			lput((4L<<16)|0L);	/* # Shdrs & shdr string size */
		}

		lput(1L);			/* text - type = PT_LOAD */
		lput(HEADR);			/* file offset */
		lput(INITTEXT);			/* vaddr */
		lput(INITTEXT);			/* paddr */
		lput(textsize-JMPSZ);		/* file size */
		lput(textsize-JMPSZ);		/* memory size */
		lput(0x05L);			/* protections = RX */
		lput(0);			/* alignment */

		lput(1L);			/* data - type = PT_LOAD */
		lput(HEADR+textsize);		/* file offset */
		lput(INITDAT);			/* vaddr */
		lput(INITDAT);			/* paddr */
		lput(datsize);			/* file size */
		lput(datsize+bsssize);		/* memory size */
		lput(0x07L);			/* protections = RWX */
		lput(0);			/* alignment */

		lput(0L);			/* data - type = PT_NULL */
		lput(HEADR+textsize+datsize);	/* file offset */
		lput(0L);			/* vaddr */
		lput(0L);			/* paddr */
		lput(symsize);			/* symbol table size */
		lput(lcsize);			/* line number size */
		lput(0x04L);			/* protections = R */
		lput(0x04L);			/* alignment code?? */

		/* add tiny text section at end with jmp to start */
		lput(1L);			/* text - type = PT_LOAD */
		lput(HEADR+textsize-JMPSZ);	/* file offset */
		lput(0xFFFFFFFC);		/* vaddr */
		lput(0xFFFFFFFC);		/* paddr */
		lput(JMPSZ);			/* file size */
		lput(JMPSZ);			/* memory size */
		lput(0x05L);			/* protections = RX */
		lput(0);			/* disable alignment */

		cflush();
		break;
	}
	cflush();
}
Пример #7
0
Файл: asm.c Проект: 8l/go-learn
void
asmb(void)
{
	Prog *p;
	int32 t, etext;
	int np;
	vlong va, fo, w, symo;
	int strtabsize;
	vlong symdatva = 0x99LL<<24;
	Optab *o;

	strtabsize = 0;
	symo = 0;

	if(debug['v'])
		Bprint(&bso, "%5.2f asm\n", cputime());
	Bflush(&bso);
	OFFSET = HEADR;
	seek(cout, OFFSET, 0);
	pc = INITTEXT;
	for(p = firstp; p != P; p = p->link) {
		setarch(p);
		if(p->as == ATEXT) {
			curtext = p;
			autosize = p->to.offset + 4;
		}
		if(p->pc != pc) {
			diag("phase error %lux sb %lux",
				p->pc, pc);
			if(!debug['a'])
				prasm(curp);
			pc = p->pc;
		}
		curp = p;
		o = oplook(p);	/* could probably avoid this call */
		if(thumb)
			thumbasmout(p, o);
		else
			asmout(p, o);
		pc += o->size;
	}
	while(pc-INITTEXT < textsize) {
		cput(0);
		pc++;
	}

	if(debug['a'])
		Bprint(&bso, "\n");
	Bflush(&bso);
	cflush();

	/* output strings in text segment */
	etext = INITTEXT + textsize;
	for(t = pc; t < etext; t += sizeof(buf)-100) {
		if(etext-t > sizeof(buf)-100)
			datblk(t, sizeof(buf)-100, 1);
		else
			datblk(t, etext-t, 1);
	}

	/* output section header strings */
	curtext = P;
	switch(HEADTYPE) {
	case 0:
	case 1:
	case 2:
	case 5:
		OFFSET = HEADR+textsize;
		seek(cout, OFFSET, 0);
		break;
	case 3:
		OFFSET = rnd(HEADR+textsize, 4096);
		seek(cout, OFFSET, 0);
		break;
	case 6:
		seek(cout, rnd(HEADR+textsize, INITRND)+datsize, 0);
		strtabsize = linuxstrtable();
		cflush();
		t = rnd(HEADR+textsize, INITRND);
		seek(cout, t, 0);
		break;
	}
	if(dlm){
		char buf[8];

		write(cout, buf, INITDAT-textsize);
		textsize = INITDAT;
	}
	for(t = 0; t < datsize; t += sizeof(buf)-100) {
		if(datsize-t > sizeof(buf)-100)
			datblk(t, sizeof(buf)-100, 0);
		else
			datblk(t, datsize-t, 0);
	}
	cflush();

	/* output symbol table */
	symsize = 0;
	lcsize = 0;
	if(!debug['s']) {
		if(debug['v'])
			Bprint(&bso, "%5.2f sym\n", cputime());
		Bflush(&bso);
		switch(HEADTYPE) {
		case 0:
		case 1:
		case 4:
		case 5:
			debug['s'] = 1;
			break;
		case 2:
			OFFSET = HEADR+textsize+datsize;
			seek(cout, OFFSET, 0);
			break;
		case 3:
			OFFSET += rnd(datsize, 4096);
			seek(cout, OFFSET, 0);
			break;
		case 6:
			symo = rnd(HEADR+textsize, INITRND)+datsize+strtabsize;
			symo = rnd(symo, INITRND);
			seek(cout, symo + 8, 0);
			break;
		}
		if(!debug['s'])
			asmsym();
		if(debug['v'])
			Bprint(&bso, "%5.2f pc\n", cputime());
		Bflush(&bso);
		if(!debug['s'])
			asmlc();
		if(!debug['s'])
			asmthumbmap();
		if(dlm)
			asmdyn();
		cflush();
	}
	else if(dlm){
		seek(cout, HEADR+textsize+datsize, 0);
		asmdyn();
		cflush();
	}

	curtext = P;
	if(debug['v'])
		Bprint(&bso, "%5.2f header\n", cputime());
	Bflush(&bso);
	OFFSET = 0;
	seek(cout, OFFSET, 0);
	switch(HEADTYPE) {
	case 0:	/* no header */
		break;
	case 1:	/* aif for risc os */
		lputl(0xe1a00000);		/* NOP - decompress code */
		lputl(0xe1a00000);		/* NOP - relocation code */
		lputl(0xeb000000 + 12);		/* BL - zero init code */
		lputl(0xeb000000 +
			(entryvalue()
			 - INITTEXT
			 + HEADR
			 - 12
			 - 8) / 4);		/* BL - entry code */

		lputl(0xef000011);		/* SWI - exit code */
		lputl(textsize+HEADR);		/* text size */
		lputl(datsize);			/* data size */
		lputl(0);			/* sym size */

		lputl(bsssize);			/* bss size */
		lputl(0);			/* sym type */
		lputl(INITTEXT-HEADR);		/* text addr */
		lputl(0);			/* workspace - ignored */

		lputl(32);			/* addr mode / data addr flag */
		lputl(0);			/* data addr */
		for(t=0; t<2; t++)
			lputl(0);		/* reserved */

		for(t=0; t<15; t++)
			lputl(0xe1a00000);	/* NOP - zero init code */
		lputl(0xe1a0f00e);		/* B (R14) - zero init return */
		break;
	case 2:	/* plan 9 */
		if(dlm)
			lput(0x80000000|0x647);	/* magic */
		else
			lput(0x647);			/* magic */
		lput(textsize);			/* sizes */
		lput(datsize);
		lput(bsssize);
		lput(symsize);			/* nsyms */
		lput(entryvalue());		/* va of entry */
		lput(0L);
		lput(lcsize);
		break;
	case 3:	/* boot for NetBSD */
		lput((143<<16)|0413);		/* magic */
		lputl(rnd(HEADR+textsize, 4096));
		lputl(rnd(datsize, 4096));
		lputl(bsssize);
		lputl(symsize);			/* nsyms */
		lputl(entryvalue());		/* va of entry */
		lputl(0L);
		lputl(0L);
		break;
	case 4: /* boot for IXP1200 */
		break;
	case 5: /* boot for ipaq */
		lputl(0xe3300000);		/* nop */
		lputl(0xe3300000);		/* nop */
		lputl(0xe3300000);		/* nop */
		lputl(0xe3300000);		/* nop */
		break;
	case 6:
		/* elf arm */
		strnput("\177ELF", 4);		/* e_ident */
		cput(1);			/* class = 32 bit */
		cput(1);			/* data = LSB */
		cput(1);			/* version = CURRENT */
		strnput("", 9);

		wputl(2);			/* type = EXEC */
		wputl(40);			/* machine = ARM */
		lputl(1L);			/* version = CURRENT */
		lputl(entryvalue());		/* entry vaddr */
		lputl(52L);			/* offset to first phdr */
		np = 3;
		if(!debug['s'])
			np++;
		lputl(52L+32*np);		/* offset to first shdr */
		lputl(0L);			/* processor specific flags */
		wputl(52);			/* Ehdr size */
		wputl(32);			/* Phdr size */
		wputl(np);			/* # of Phdrs */
		wputl(40);			/* Shdr size */
		if (!debug['s'])
			wputl(7);			/* # of Shdrs */
		else
			wputl(5);			/* # of Shdrs */
		wputl(4);			/* Shdr with strings */

		fo = 0;
		va = INITTEXT & ~((vlong)INITRND - 1);
		w = HEADR+textsize;

		linuxphdr(1,			/* text - type = PT_LOAD */
			1L+4L,			/* text - flags = PF_X+PF_R */
			0,			/* file offset */
			va,			/* vaddr */
			va,			/* paddr */
			w,			/* file size */
			w,			/* memory size */
			INITRND);		/* alignment */

		fo = rnd(fo+w, INITRND);
		va = rnd(va+w, INITRND);
		w = datsize;

		linuxphdr(1,			/* data - type = PT_LOAD */
			2L+4L,			/* data - flags = PF_W+PF_R */
			fo,			/* file offset */
			va,			/* vaddr */
			va,			/* paddr */
			w,			/* file size */
			w+bsssize,		/* memory size */
			INITRND);		/* alignment */

		if(!debug['s']) {
			linuxphdr(1,			/* data - type = PT_LOAD */
				2L+4L,			/* data - flags = PF_W+PF_R */
				symo,		/* file offset */
				symdatva,			/* vaddr */
				symdatva,			/* paddr */
				8+symsize+lcsize,			/* file size */
				8+symsize+lcsize,		/* memory size */
				INITRND);		/* alignment */
		}

		linuxphdr(0x6474e551,		/* gok - type = gok */
			1L+2L+4L,		/* gok - flags = PF_X+PF_W+PF_R */
			0,			/* file offset */
			0,			/* vaddr */
			0,			/* paddr */
			0,			/* file size */
			0,			/* memory size */
			8);			/* alignment */

		linuxshdr(nil,			/* name */
			0,			/* type */
			0,			/* flags */
			0,			/* addr */
			0,			/* off */
			0,			/* size */
			0,			/* link */
			0,			/* info */
			0,			/* align */
			0);			/* entsize */

		stroffset = 1;  /* 0 means no name, so start at 1 */
		fo = HEADR;
		va = (INITTEXT & ~((vlong)INITRND - 1)) + HEADR;
		w = textsize;

		linuxshdr(".text",		/* name */
			1,			/* type */
			6,			/* flags */
			va,			/* addr */
			fo,			/* off */
			w,			/* size */
			0,			/* link */
			0,			/* info */
			8,			/* align */
			0);			/* entsize */

		fo = rnd(fo+w, INITRND);
		va = rnd(va+w, INITRND);
		w = datsize;

		linuxshdr(".data",		/* name */
			1,			/* type */
			3,			/* flags */
			va,			/* addr */
			fo,			/* off */
			w,			/* size */
			0,			/* link */
			0,			/* info */
			8,			/* align */
			0);			/* entsize */

		fo += w;
		va += w;
		w = bsssize;

		linuxshdr(".bss",		/* name */
			8,			/* type */
			3,			/* flags */
			va,			/* addr */
			fo,			/* off */
			w,			/* size */
			0,			/* link */
			0,			/* info */
			8,			/* align */
			0);			/* entsize */

		w = strtabsize;

		linuxshdr(".shstrtab",		/* name */
			3,			/* type */
			0,			/* flags */
			0,			/* addr */
			fo,			/* off */
			w,			/* size */
			0,			/* link */
			0,			/* info */
			1,			/* align */
			0);			/* entsize */

		if (debug['s'])
			break;

		fo = symo+8;
		w = symsize;

		linuxshdr(".gosymtab",		/* name */
			1,			/* type 1 = SHT_PROGBITS */
			0,			/* flags */
			0,			/* addr */
			fo,			/* off */
			w,			/* size */
			0,			/* link */
			0,			/* info */
			1,			/* align */
			24);			/* entsize */

		fo += w;
		w = lcsize;

		linuxshdr(".gopclntab",		/* name */
			1,			/* type 1 = SHT_PROGBITS*/
			0,			/* flags */
			0,			/* addr */
			fo,			/* off */
			w,			/* size */
			0,			/* link */
			0,			/* info */
			1,			/* align */
			24);			/* entsize */
		break;
	}
	cflush();
	if(debug['c']){
		print("textsize=%ld\n", textsize);
		print("datsize=%ld\n", datsize);
		print("bsssize=%ld\n", bsssize);
		print("symsize=%ld\n", symsize);
		print("lcsize=%ld\n", lcsize);
		print("total=%ld\n", textsize+datsize+bsssize+symsize+lcsize);
	}
}
Пример #8
0
void
asmb(void)
{
	Prog *p;
	long magic, t, etext;
	vlong vl;
	Optab *o;

	if(debug['v'])
		Bprint(&bso, "%5.2f asm\n", cputime());
	Bflush(&bso);
	OFFSET = HEADR;
	seek(cout, OFFSET, 0);
	pc = INITTEXT;
	for(p = firstp; p != P; p = p->link) {
		if(p->as == ATEXT) {
			curtext = p;
			autosize = p->to.offset + PCSZ;
		}
		if(p->as == ADWORD && (pc & 7) != 0) {
			lputl(0);
			pc += 4;
		}
		if(p->pc != pc) {
			diag("phase error %llux sb %llux",
				p->pc, pc);
			if(!debug['a'])
				prasm(curp);
			pc = p->pc;
		}
		curp = p;
		o = oplook(p);	/* could probably avoid this call */
		asmout(p, o);
		pc += o->size;
	}

	if(debug['a'])
		Bprint(&bso, "\n");
	Bflush(&bso);
	cflush();

	/* output strings in text segment */
	etext = INITTEXT + textsize;
	for(t = pc; t < etext; t += sizeof(buf)-100) {
		if(etext-t > sizeof(buf)-100)
			datblk(t, sizeof(buf)-100, 1);
		else
			datblk(t, etext-t, 1);
	}

	curtext = P;
	switch(HEADTYPE) {
	case 0:
	case 2:
	case 7:
		OFFSET = HEADR+textsize;
		seek(cout, OFFSET, 0);
		break;
	case 6:	/* no header, padded segments */
		OFFSET = rnd(HEADR+textsize, 4096);
		seek(cout, OFFSET, 0);
		break;
	}
	if(dlm){
		char buf[8];

		write(cout, buf, INITDAT-textsize);
		textsize = INITDAT;
	}
	for(t = 0; t < datsize; t += sizeof(buf)-100) {
		if(datsize-t > sizeof(buf)-100)
			datblk(t, sizeof(buf)-100, 0);
		else
			datblk(t, datsize-t, 0);
	}

	symsize = 0;
	lcsize = 0;
	if(!debug['s']) {
		if(debug['v'])
			Bprint(&bso, "%5.2f sym\n", cputime());
		Bflush(&bso);
		switch(HEADTYPE) {
		case 0:
			debug['s'] = 1;
			break;
		case 2:
			OFFSET = HEADR+textsize+datsize;
			seek(cout, OFFSET, 0);
			break;
		case 6:	/* no header, padded segments */
			OFFSET += rnd(datsize, 4096);
			seek(cout, OFFSET, 0);
			break;
		case 7:
			break;
		}
		if(!debug['s'])
			asmsym();
		if(debug['v'])
			Bprint(&bso, "%5.2f pc\n", cputime());
		Bflush(&bso);
		if(!debug['s'])
			asmlc();
		if(dlm)
			asmdyn();
		cflush();
	}
	else if(dlm){
		seek(cout, HEADR+textsize+datsize, 0);
		asmdyn();
		cflush();
	}

	if(debug['v'])
		Bprint(&bso, "%5.2f header\n", cputime());
	Bflush(&bso);
	OFFSET = 0;
	seek(cout, OFFSET, 0);
	switch(HEADTYPE) {
	case 0:	/* no header */
	case 6:	/* no header, padded segments */
		break;
	case 2:	/* plan 9 */
		magic = 4*28*28+7;
		magic |= 0x00008000;		/* fat header */
		if(dlm)
			magic |= 0x80000000;	/* dlm */
		lput(magic);			/* magic */
		lput(textsize);			/* sizes */
		lput(datsize);
		lput(bsssize);
		lput(symsize);			/* nsyms */
		vl = entryvalue();
		lput(PADDR(vl));		/* va of entry */
		lput(0L);
		lput(lcsize);
		llput(vl);			/* va of entry */
		break;
	case 7:	/* elf */
		debug['S'] = 1;			/* symbol table */
		elf64(ARM64, ELFDATA2LSB, 0, nil);
		break;
	}
	cflush();
}