コード例 #1
0
ファイル: executable.c プロジェクト: 8l/go-learn
/*
 *	mips4k bootable image.
 */
static int
mips4kboot(int fd, Fhdr *fp, ExecHdr *hp)
{
abort();
#ifdef unused
	USED(fd);
	fp->type = FMIPSB;
	switch(hp->e.h.amagic) {
	default:
	case 0407:	/* some kind of mips */
		settext(fp, (u32int)hp->e.h.mentry, (u32int)hp->e.h.text_start,
			hp->e.h.tsize, sizeof(struct mips4kexec));
		setdata(fp, (u32int)hp->e.h.data_start, hp->e.h.dsize,
			fp->txtoff+hp->e.h.tsize, hp->e.h.bsize);
		break;
	case 0413:	/* some kind of mips */
		settext(fp, (u32int)hp->e.h.mentry, (u32int)hp->e.h.text_start,
			hp->e.h.tsize, 0);
		setdata(fp, (u32int)hp->e.h.data_start, hp->e.h.dsize,
			hp->e.h.tsize, hp->e.h.bsize);
		break;
	}
	setsym(fp, hp->e.h.nsyms, 0, hp->e.h.pcsize, hp->e.h.symptr);
	fp->hdrsz = 0;			/* header stripped */
#endif
	return 1;
}
コード例 #2
0
ファイル: executable.c プロジェクト: AustenConrad/plan-9
static int
commonllp64(int, Fhdr *fp, ExecHdr *hp)
{
	long pgsize;
	uvlong entry;

	hswal(&hp->e, sizeof(Exec)/sizeof(long), beswal);
	if(!(hp->e.magic & HDR_MAGIC))
		return 0;

	/*
	 * There can be more magic here if the
	 * header ever needs more expansion.
	 * For now just catch use of any of the
	 * unused bits.
	 */
	if((hp->e.magic & ~DYN_MAGIC)>>16)
		return 0;
	entry = beswav(hp->e.hdr[0]);

	pgsize = mach->pgsize;
	settext(fp, entry, pgsize+fp->hdrsz, hp->e.text, fp->hdrsz);
	setdata(fp, _round(pgsize+fp->txtsz+fp->hdrsz, pgsize),
		hp->e.data, fp->txtsz+fp->hdrsz, hp->e.bss);
	setsym(fp, hp->e.syms, hp->e.spsz, hp->e.pcsz, fp->datoff+fp->datsz);

	if(hp->e.magic & DYN_MAGIC) {
		fp->txtaddr = 0;
		fp->dataddr = fp->txtsz;
		return 1;
	}
	commonboot(fp);
	return 1;
}
コード例 #3
0
ファイル: executable.c プロジェクト: AustenConrad/plan-9
/*
 *	sparc bootable image
 */
static int
sparcboot(int fd, Fhdr *fp, ExecHdr *hp)
{
	USED(fd);
	fp->type = FSPARCB;
	settext(fp, hp->e.sentry, hp->e.sentry, hp->e.stext,
		sizeof(struct sparcexec));
	setdata(fp, hp->e.sentry+hp->e.stext, hp->e.sdata,
		fp->txtoff+hp->e.stext, hp->e.sbss);
	setsym(fp, hp->e.ssyms, 0, hp->e.sdrsize, fp->datoff+hp->e.sdata);
	fp->hdrsz = 0;			/* header stripped */
	return 1;
}
コード例 #4
0
ファイル: executable.c プロジェクト: AustenConrad/plan-9
/*
 *	next bootable image
 */
static int
nextboot(int fd, Fhdr *fp, ExecHdr *hp)
{
	USED(fd);
	fp->type = FNEXTB;
	settext(fp, hp->e.textc.vmaddr, hp->e.textc.vmaddr,
		hp->e.texts.size, hp->e.texts.offset);
	setdata(fp, hp->e.datac.vmaddr, hp->e.datas.size,
		hp->e.datas.offset, hp->e.bsss.size);
	setsym(fp, hp->e.symc.nsyms, hp->e.symc.spoff, hp->e.symc.pcoff,
		hp->e.symc.symoff);
	fp->hdrsz = 0;			/* header stripped */
	return 1;
}
コード例 #5
0
ファイル: executable.c プロジェクト: AustenConrad/plan-9
/*
 *	Crack a normal a.out-type header
 */
static int
adotout(int fd, Fhdr *fp, ExecHdr *hp)
{
	long pgsize;

	USED(fd);
	pgsize = mach->pgsize;
	settext(fp, hp->e.entry, pgsize+sizeof(Exec),
			hp->e.text, sizeof(Exec));
	setdata(fp, _round(pgsize+fp->txtsz+sizeof(Exec), pgsize),
		hp->e.data, fp->txtsz+sizeof(Exec), hp->e.bss);
	setsym(fp, hp->e.syms, hp->e.spsz, hp->e.pcsz, fp->datoff+fp->datsz);
	return 1;
}
コード例 #6
0
ファイル: executable.c プロジェクト: AustenConrad/plan-9
/*
 * (Free|Net)BSD ARM header.
 */
static int
armdotout(int fd, Fhdr *fp, ExecHdr *hp)
{
	uvlong kbase;

	USED(fd);
	settext(fp, hp->e.entry, sizeof(Exec), hp->e.text, sizeof(Exec));
	setdata(fp, fp->txtsz, hp->e.data, fp->txtsz, hp->e.bss);
	setsym(fp, hp->e.syms, hp->e.spsz, hp->e.pcsz, fp->datoff+fp->datsz);

	kbase = 0xF0000000;
	if ((fp->entry & kbase) == kbase) {		/* Boot image */
		fp->txtaddr = kbase+sizeof(Exec);
		fp->name = "ARM *BSD boot image";
		fp->hdrsz = 0;		/* header stripped */
		fp->dataddr = kbase+fp->txtsz;
	}
	return 1;
}
コード例 #7
0
ファイル: parse_cpp.c プロジェクト: staalmannen/p9p-mkmk
static void
dodefine(State *s, char *p)
{
	int brace;
	Symb *sym;
	char *name, *val;

	if(peek(s) & (Tdisable|Tinherit))
		return;

	if(! Name1(*p))
		cpperr(s, "%q - bad character in macro name\n", p);
	name = p;
	while(NameN(*p))
		p++;

	val = nil;
	if(*p == '('){
		*p++ = 0;
		brace = 1;
		while(*p){
			switch(*p++){
			case '(': brace++; break;
			case ')': brace--; break;
			default: break;
			}
			if(brace == 0)
				break;
		}
		val = p;
		
	}
	if(isspace(*p)){
		*p++ = 0;
		while(isspace(*p))
			p++;
		val = p;
	}

	if(val == nil || ! *val)
		val = "1";
	setsym(name, val);
}
コード例 #8
0
ファイル: executable.c プロジェクト: ZhuZhiMing/go-internals
static int
commonllp64(int unused, Fhdr *fp, ExecHdr *hp)
{
	int32 pgsize;
	uvlong entry;

	USED(unused);

	hswal(&hp->e, sizeof(Exec)/sizeof(int32), beswal);
	if(!(hp->e.exechdr.magic & HDR_MAGIC))
		return 0;

	/*
	 * There can be more magic here if the
	 * header ever needs more expansion.
	 * For now just catch use of any of the
	 * unused bits.
	 */
	if((hp->e.exechdr.magic & ~DYN_MAGIC)>>16)
		return 0;
	union {
		char *p;
		uvlong *v;
	} u;
	u.p = (char*)&hp->e.exechdr;
	entry = beswav(*u.v);

	pgsize = mach->pgsize;
	settext(fp, entry, pgsize+fp->hdrsz, hp->e.exechdr.text, fp->hdrsz);
	setdata(fp, _round(pgsize+fp->txtsz+fp->hdrsz, pgsize),
		hp->e.exechdr.data, fp->txtsz+fp->hdrsz, hp->e.exechdr.bss);
	setsym(fp, fp->datoff+fp->datsz, hp->e.exechdr.syms, 0, hp->e.exechdr.spsz, 0, hp->e.exechdr.pcsz);

	if(hp->e.exechdr.magic & DYN_MAGIC) {
		fp->txtaddr = 0;
		fp->dataddr = fp->txtsz;
		return 1;
	}
	commonboot(fp);
	return 1;
}
コード例 #9
0
ファイル: executable.c プロジェクト: AustenConrad/plan-9
/*
 *	mips bootable image.
 */
static int
mipsboot(int fd, Fhdr *fp, ExecHdr *hp)
{
	USED(fd);
	fp->type = FMIPSB;
	switch(hp->e.amagic) {
	default:
	case 0407:	/* some kind of mips */
		settext(fp, (u32int)hp->e.mentry, (u32int)hp->e.text_start,
			hp->e.tsize, sizeof(struct mipsexec)+4);
		setdata(fp, (u32int)hp->e.data_start, hp->e.dsize,
			fp->txtoff+hp->e.tsize, hp->e.bsize);
		break;
	case 0413:	/* some kind of mips */
		settext(fp, (u32int)hp->e.mentry, (u32int)hp->e.text_start,
			hp->e.tsize, 0);
		setdata(fp, (u32int)hp->e.data_start, hp->e.dsize,
			hp->e.tsize, hp->e.bsize);
		break;
	}
	setsym(fp, hp->e.nsyms, 0, hp->e.pcsize, hp->e.symptr);
	fp->hdrsz = 0;			/* header stripped */
	return 1;
}
コード例 #10
0
ファイル: executable.c プロジェクト: AustenConrad/plan-9
/*
 * Elf32 binaries.
 */
static int
elfdotout(int fd, Fhdr *fp, ExecHdr *hp)
{

	ulong (*swal)(ulong);
	ushort (*swab)(ushort);
	Ehdr *ep;
	Phdr *ph;
	int i, it, id, is, phsz;

	/* bitswap the header according to the DATA format */
	ep = &hp->e;
	if(ep->ident[CLASS] != ELFCLASS32) {
		werrstr("bad ELF class - not 32 bit");
		return 0;
	}
	if(ep->ident[DATA] == ELFDATA2LSB) {
		swab = leswab;
		swal = leswal;
	} else if(ep->ident[DATA] == ELFDATA2MSB) {
		swab = beswab;
		swal = beswal;
	} else {
		werrstr("bad ELF encoding - not big or little endian");
		return 0;
	}

	ep->type = swab(ep->type);
	ep->machine = swab(ep->machine);
	ep->version = swal(ep->version);
	ep->elfentry = swal(ep->elfentry);
	ep->phoff = swal(ep->phoff);
	ep->shoff = swal(ep->shoff);
	ep->flags = swal(ep->flags);
	ep->ehsize = swab(ep->ehsize);
	ep->phentsize = swab(ep->phentsize);
	ep->phnum = swab(ep->phnum);
	ep->shentsize = swab(ep->shentsize);
	ep->shnum = swab(ep->shnum);
	ep->shstrndx = swab(ep->shstrndx);
	if(ep->type != EXEC || ep->version != CURRENT)
		return 0;

	/* we could definitely support a lot more machines here */
	fp->magic = ELF_MAG;
	fp->hdrsz = (ep->ehsize+ep->phnum*ep->phentsize+16)&~15;
	switch(ep->machine) {
	case I386:
		mach = &mi386;
		fp->type = FI386;
		break;
	case MIPS:
		mach = &mmips;
		fp->type = FMIPS;
		break;
	case SPARC64:
		mach = &msparc64;
		fp->type = FSPARC64;
		break;
	case POWER:
		mach = &mpower;
		fp->type = FPOWER;
		break;
	case AMD64:
		mach = &mamd64;
		fp->type = FAMD64;
		break;
	case ARM:
		mach = &marm;
		fp->type = FARM;
		break;
	default:
		return 0;
	}

	if(ep->phentsize != sizeof(Phdr)) {
		werrstr("bad ELF header size");
		return 0;
	}
	phsz = sizeof(Phdr)*ep->phnum;
	ph = malloc(phsz);
	if(!ph)
		return 0;
	seek(fd, ep->phoff, 0);
	if(read(fd, ph, phsz) < 0) {
		free(ph);
		return 0;
	}
	hswal(ph, phsz/sizeof(ulong), swal);

	/* find text, data and symbols and install them */
	it = id = is = -1;
	for(i = 0; i < ep->phnum; i++) {
		if(ph[i].type == LOAD
		&& (ph[i].flags & (R|X)) == (R|X) && it == -1)
			it = i;
		else if(ph[i].type == LOAD
		&& (ph[i].flags & (R|W)) == (R|W) && id == -1)
			id = i;
		else if(ph[i].type == NOPTYPE && is == -1)
			is = i;
	}
	if(it == -1 || id == -1) {
		/*
		 * The SPARC64 boot image is something of an ELF hack.
		 * Text+Data+BSS are represented by ph[0].  Symbols
		 * are represented by ph[1]:
		 *
		 *		filesz, memsz, vaddr, paddr, off
		 * ph[0] : txtsz+datsz, txtsz+datsz+bsssz, txtaddr-KZERO, datasize, txtoff
		 * ph[1] : symsz, lcsz, 0, 0, symoff
		 */
		if(ep->machine == SPARC64 && ep->phnum == 2) {
			ulong txtaddr, txtsz, dataddr, bsssz;

			txtaddr = ph[0].vaddr | 0x80000000;
			txtsz = ph[0].filesz - ph[0].paddr;
			dataddr = txtaddr + txtsz;
			bsssz = ph[0].memsz - ph[0].filesz;
			settext(fp, ep->elfentry | 0x80000000, txtaddr, txtsz, ph[0].offset);
			setdata(fp, dataddr, ph[0].paddr, ph[0].offset + txtsz, bsssz);
			setsym(fp, ph[1].filesz, 0, ph[1].memsz, ph[1].offset);
			free(ph);
			return 1;
		}

		werrstr("No TEXT or DATA sections");
		free(ph);
		return 0;
	}

	settext(fp, ep->elfentry, ph[it].vaddr, ph[it].memsz, ph[it].offset);
	setdata(fp, ph[id].vaddr, ph[id].filesz, ph[id].offset, ph[id].memsz - ph[id].filesz);
	if(is != -1)
		setsym(fp, ph[is].filesz, 0, ph[is].memsz, ph[is].offset);
	free(ph);
	return 1;
}
コード例 #11
0
ファイル: executable.c プロジェクト: grobe0ba/plan9front
/*
 * ELF64 binaries.
 */
static int
elf64dotout(int fd, Fhdr *fp, ExecHdr *hp)
{
	E64hdr *ep;
	P64hdr *ph;
	ushort (*swab)(ushort);
	ulong (*swal)(ulong);
	uvlong (*swav)(uvlong);
	int i, it, id, is, phsz;
	uvlong uvl;

	ep = &hp->e;
	if(ep->ident[DATA] == ELFDATA2LSB) {
		swab = leswab;
		swal = leswal;
		swav = leswav;
	} else if(ep->ident[DATA] == ELFDATA2MSB) {
		swab = beswab;
		swal = beswal;
		swav = beswav;
	} else {
		werrstr("bad ELF64 encoding - not big or little endian");
		return 0;
	}

	ep->type = swab(ep->type);
	ep->machine = swab(ep->machine);
	ep->version = swal(ep->version);
	if(ep->type != EXEC || ep->version != CURRENT)
		return 0;
	ep->elfentry = swav(ep->elfentry);
	ep->phoff = swav(ep->phoff);
	ep->shoff = swav(ep->shoff);
	ep->flags = swal(ep->flags);
	ep->ehsize = swab(ep->ehsize);
	ep->phentsize = swab(ep->phentsize);
	ep->phnum = swab(ep->phnum);
	ep->shentsize = swab(ep->shentsize);
	ep->shnum = swab(ep->shnum);
	ep->shstrndx = swab(ep->shstrndx);

	fp->magic = ELF_MAG;
	fp->hdrsz = (ep->ehsize+ep->phnum*ep->phentsize+16)&~15;
	switch(ep->machine) {
	default:
		return 0;
	case AMD64:
		mach = &mamd64;
		fp->type = FAMD64;
		fp->name = "amd64 ELF64 executable";
		break;
	case POWER64:
		mach = &mpower64;
		fp->type = FPOWER64;
		fp->name = "power64 ELF64 executable";
		break;
	}

	if(ep->phentsize != sizeof(P64hdr)) {
		werrstr("bad ELF64 header size");
		return 0;
	}
	phsz = sizeof(P64hdr)*ep->phnum;
	ph = malloc(phsz);
	if(!ph)
		return 0;
	seek(fd, ep->phoff, 0);
	if(read(fd, ph, phsz) < 0) {
		free(ph);
		return 0;
	}
	for(i = 0; i < ep->phnum; i++) {
		ph[i].type = swal(ph[i].type);
		ph[i].flags = swal(ph[i].flags);
		ph[i].offset = swav(ph[i].offset);
		ph[i].vaddr = swav(ph[i].vaddr);
		ph[i].paddr = swav(ph[i].paddr);
		ph[i].filesz = swav(ph[i].filesz);
		ph[i].memsz = swav(ph[i].memsz);
		ph[i].align = swav(ph[i].align);
	}

	/* find text, data and symbols and install them */
	it = id = is = -1;
	for(i = 0; i < ep->phnum; i++) {
		if(ph[i].type == LOAD
		&& (ph[i].flags & (R|X)) == (R|X) && it == -1)
			it = i;
		else if(ph[i].type == LOAD
		&& (ph[i].flags & (R|W)) == (R|W) && id == -1)
			id = i;
		else if(ph[i].type == NOPTYPE && is == -1)
			is = i;
	}
	if(it == -1 || id == -1) {
		werrstr("No ELF64 TEXT or DATA sections");
		free(ph);
		return 0;
	}

	settext(fp, ep->elfentry, ph[it].vaddr, ph[it].memsz, ph[it].offset);
	/* 8c: out of fixed registers */
	uvl = ph[id].memsz - ph[id].filesz;
	setdata(fp, ph[id].vaddr, ph[id].filesz, ph[id].offset, uvl);
	if(is != -1)
		setsym(fp, ph[is].filesz, 0, ph[is].memsz, ph[is].offset);
	free(ph);
	return 1;
}
コード例 #12
0
ファイル: executable.c プロジェクト: aryx/fork-kencc
static int
machdotout(int fd, Fhdr *fp, ExecHdr *hp)
{
	uvlong (*swav)(uvlong);
	uint32 (*swal)(uint32);
	Machhdr *mp;
	MachCmd **cmd;
	MachSymSeg *symtab;
	MachSymSeg *pclntab;
	MachSeg64 *seg;
	MachSect64 *sect;
	MachSeg32 *seg32;
	MachSect32 *sect32;
	uvlong textsize, datasize, bsssize;
	uchar *cmdbuf;
	uchar *cmdp;
	int i, j, hdrsize;
	uint32 textva, textoff, datava, dataoff, symoff, symsize, pclnoff, pclnsize;

	mp = &hp->e.machhdr;
	if (leswal(mp->filetype) != MACH_EXECUTABLE_TYPE) {
		werrstr("bad MACH executable type %#ux", leswal(mp->filetype));
		return 0;
	}

	swal = leswal;
	swav = leswav;

	mp->magic = swal(mp->magic);
	mp->cputype = swal(mp->cputype);
	mp->cpusubtype = swal(mp->cpusubtype);
	mp->filetype = swal(mp->filetype);
	mp->ncmds = swal(mp->ncmds);
	mp->sizeofcmds = swal(mp->sizeofcmds);
	mp->flags = swal(mp->flags);
	mp->reserved = swal(mp->reserved);

	switch(mp->magic) {
	case 0xFEEDFACE:	// 32-bit mach
		if (mp->cputype != MACH_CPU_TYPE_X86) {
			werrstr("bad MACH cpu type - not 386");
			return 0;
		}
		if (mp->cpusubtype != MACH_CPU_SUBTYPE_X86) {
			werrstr("bad MACH cpu subtype - not 386");
			return 0;
		}
		if (mp->filetype != MACH_EXECUTABLE_TYPE) {
			werrstr("bad MACH executable type");
			return 0;
		}
		mach = &mi386;
		fp->type = FI386;
		hdrsize = 28;
		break;

	case 0xFEEDFACF:	// 64-bit mach
		werrstr("64 bit mach NOT SUPPORTED");
		return 0;
		//if (mp->cputype != MACH_CPU_TYPE_X86_64) {
		//	werrstr("bad MACH cpu type - not amd64");
		//	return 0;
		//}
        //
		//if (mp->cpusubtype != MACH_CPU_SUBTYPE_X86 && mp->cpusubtype != MACH_CPU_SUBTYPE_X86_64) {
		//	werrstr("bad MACH cpu subtype - not amd64");
		//	return 0;
		//}
		//mach = &mamd64;
		//fp->type = FAMD64;
		//hdrsize = 32;
		//break;

	default:
		werrstr("not mach %#ux", mp->magic);
		return 0;
	}

	cmdbuf = malloc(mp->sizeofcmds);
	if(!cmdbuf) {
		werrstr("out of memory");
		return 0;
	}
	seek(fd, hdrsize, 0);
	if(read(fd, cmdbuf, mp->sizeofcmds) != mp->sizeofcmds) {
		free(cmdbuf);
		return 0;
	}
	cmd = malloc(mp->ncmds * sizeof(MachCmd*));
	if(!cmd) {
		free(cmdbuf);
		werrstr("out of memory");
		return 0;
	}
	cmdp = cmdbuf;
	textva = 0;
	textoff = 0;
	dataoff = 0;
	datava = 0;
	symtab = 0;
	pclntab = 0;
	textsize = 0;
	datasize = 0;
	bsssize = 0;
	symoff = 0;
	symsize = 0;
	pclnoff = 0;
	pclnsize = 0;
	for (i = 0; i < mp->ncmds; i++) {
		MachCmd *c;

		cmd[i] = (MachCmd*)cmdp;
		c = cmd[i];
		c->type = swal(c->type);
		c->size = swal(c->size);
		switch(c->type) {
		case MACH_SEGMENT_32:
			if(mp->magic != 0xFEEDFACE) {
				werrstr("segment 32 in mach 64");
				goto bad;
			}
			seg32 = (MachSeg32*)c;
			seg32->vmaddr = swav(seg32->vmaddr);
			seg32->vmsize = swav(seg32->vmsize);
			seg32->fileoff = swav(seg32->fileoff);
			seg32->filesize = swav(seg32->filesize);
			seg32->maxprot = swal(seg32->maxprot);
			seg32->initprot = swal(seg32->initprot);
			seg32->nsects = swal(seg32->nsects);
			seg32->flags = swal(seg32->flags);
			if (strcmp(seg32->segname, "__TEXT") == 0) {
				textva = seg32->vmaddr;
				textoff = seg32->fileoff;
				textsize = seg32->vmsize;
				sect32 = (MachSect32*)(cmdp + sizeof(MachSeg32));
				for(j = 0; j < seg32->nsects; j++, sect32++) {
					if (strcmp(sect32->sectname, "__gosymtab") == 0) {
						symoff = swal(sect32->offset);
						symsize = swal(sect32->size);
					}
					if (strcmp(sect32->sectname, "__gopclntab") == 0) {
						pclnoff = swal(sect32->offset);
						pclnsize = swal(sect32->size);
					}
				}
			}
			if (strcmp(seg32->segname, "__DATA") == 0) {
				datava = seg32->vmaddr;
				dataoff = seg32->fileoff;
				datasize = seg32->filesize;
				bsssize = seg32->vmsize - seg32->filesize;
			}
			break;

		case MACH_SEGMENT_64:
			werrstr("MACH SEGMENT 64 NOT SUPPORTED");
				goto bad;
			//if(mp->magic != 0xFEEDFACF) {
			//	werrstr("segment 32 in mach 64");
			//	goto bad;
			//}
			//seg = (MachSeg64*)c;
			//seg->vmaddr = swav(seg->vmaddr);
			//seg->vmsize = swav(seg->vmsize);
			//seg->fileoff = swav(seg->fileoff);
			//seg->filesize = swav(seg->filesize);
			//seg->maxprot = swal(seg->maxprot);
			//seg->initprot = swal(seg->initprot);
			//seg->nsects = swal(seg->nsects);
			//seg->flags = swal(seg->flags);
			//if (strcmp(seg->segname, "__TEXT") == 0) {
			//	textva = seg->vmaddr;
			//	textoff = seg->fileoff;
			//	textsize = seg->vmsize;
			//	sect = (MachSect64*)(cmdp + sizeof(MachSeg64));
			//	for(j = 0; j < seg->nsects; j++, sect++) {
			//		if (strcmp(sect->sectname, "__gosymtab") == 0) {
			//			symoff = swal(sect->offset);
			//			symsize = swal(sect->size);
			//		}
			//		if (strcmp(sect->sectname, "__gopclntab") == 0) {
			//			pclnoff = swal(sect->offset);
			//			pclnsize = swal(sect->size);
			//		}
			//	}
			//}
			//if (strcmp(seg->segname, "__DATA") == 0) {
			//	datava = seg->vmaddr;
			//	dataoff = seg->fileoff;
			//	datasize = seg->filesize;
			//	bsssize = seg->vmsize - seg->filesize;
			//}
			break;
		case MACH_UNIXTHREAD:
			break;
		case MACH_SYMSEG:
			if (symtab == 0) {
				symtab = (MachSymSeg*)c;
				symoff = swal(symtab->fileoff);
				symsize = swal(symtab->filesize);
			} else if (pclntab == 0) {
				pclntab = (MachSymSeg*)c;
				pclnoff = swal(pclntab->fileoff);
				pclnsize = swal(pclntab->filesize);
			}
			break;
		}
		cmdp += c->size;
	}
	if (textva == 0 || datava == 0) {
		free(cmd);
		free(cmdbuf);
		return 0;
	}
	/* compute entry by taking address after header - weird - BUG? */
	settext(fp, textva+sizeof(Machhdr) + mp->sizeofcmds, textva, textsize, textoff);
	setdata(fp, datava, datasize, dataoff, bsssize);
	if(symoff > 0)
		setsym(fp, symoff, symsize, 0, 0, pclnoff, pclnsize);
	free(cmd);
	free(cmdbuf);
	return 1;
bad:
	free(cmd);
	free(cmdbuf);
	return 0;
}
コード例 #13
0
ファイル: executable.c プロジェクト: 8l/go-learn
static int
machdotout(int fd, Fhdr *fp, ExecHdr *hp)
{
	uvlong (*swav)(uvlong);
	uint32 (*swal)(uint32);
	ushort (*swab)(ushort);
	Machhdr *mp;
	MachCmd **cmd;
	MachSymSeg *symtab;
	MachSymSeg *pclntab;
	MachSeg64 *seg;
	MachSect64 *sect;
	MachSeg32 *seg32;
	MachSect32 *sect32;
	uvlong textsize, datasize, bsssize;
	uchar *cmdbuf;
	uchar *cmdp;
	int i, hdrsize;
	uint32 textva, textoff, datava, dataoff;

	mp = &hp->e.machhdr;
	if (leswal(mp->filetype) != MACH_EXECUTABLE_TYPE) {
		werrstr("bad MACH executable type %#ux", leswal(mp->filetype));
		return 0;
	}

	swab = leswab;
	swal = leswal;
	swav = leswav;

	mp->magic = swal(mp->magic);
	mp->cputype = swal(mp->cputype);
	mp->cpusubtype = swal(mp->cpusubtype);
	mp->filetype = swal(mp->filetype);
	mp->ncmds = swal(mp->ncmds);
	mp->sizeofcmds = swal(mp->sizeofcmds);
	mp->flags = swal(mp->flags);
	mp->reserved = swal(mp->reserved);
	hdrsize = 0;

	switch(mp->magic) {
	case 0xFEEDFACE:	// 32-bit mach
		if (mp->cputype != MACH_CPU_TYPE_X86) {
			werrstr("bad MACH cpu type - not 386");
			return 0;
		}
		if (mp->cpusubtype != MACH_CPU_SUBTYPE_X86) {
			werrstr("bad MACH cpu subtype - not 386");
			return 0;
		}
		if (mp->filetype != MACH_EXECUTABLE_TYPE) {
			werrstr("bad MACH executable type");
			return 0;
		}
		mach = &mi386;
		fp->type = FI386;
		hdrsize = 28;
		break;

	case 0xFEEDFACF:	// 64-bit mach
		if (mp->cputype != MACH_CPU_TYPE_X86_64) {
			werrstr("bad MACH cpu type - not amd64");
			return 0;
		}

		if (mp->cpusubtype != MACH_CPU_SUBTYPE_X86) {
			werrstr("bad MACH cpu subtype - not amd64");
			return 0;
		}
		mach = &mamd64;
		fp->type = FAMD64;
		hdrsize = 32;
		break;

	default:
		werrstr("not mach %#ux", mp->magic);
		return 0;
	}

	cmdbuf = malloc(mp->sizeofcmds);
	seek(fd, hdrsize, 0);
	if(read(fd, cmdbuf, mp->sizeofcmds) != mp->sizeofcmds) {
		free(cmdbuf);
		return 0;
	}
	cmd = malloc(mp->ncmds * sizeof(MachCmd*));
	cmdp = cmdbuf;
	textva = 0;
	textoff = 0;
	dataoff = 0;
	datava = 0;
	symtab = 0;
	pclntab = 0;
	textsize = datasize = bsssize = 0;
	for (i = 0; i < mp->ncmds; i++) {
		MachCmd *c;

		cmd[i] = (MachCmd*)cmdp;
		c = cmd[i];
		c->type = swal(c->type);
		c->size = swal(c->size);
		switch(c->type) {
		case MACH_SEGMENT_32:
			if(mp->magic != 0xFEEDFACE) {
				werrstr("segment 32 in mach 64");
				goto bad;
			}
			seg32 = (MachSeg32*)c;
			seg32->vmaddr = swav(seg32->vmaddr);
			seg32->vmsize = swav(seg32->vmsize);
			seg32->fileoff = swav(seg32->fileoff);
			seg32->filesize = swav(seg32->filesize);
			seg32->maxprot = swal(seg32->maxprot);
			seg32->initprot = swal(seg32->initprot);
			seg32->nsects = swal(seg32->nsects);
			seg32->flags = swal(seg32->flags);
			if (strcmp(seg32->segname, "__TEXT") == 0) {
				textva = seg32->vmaddr;
				textoff = seg32->fileoff;
				sect32 = (MachSect32*)(cmdp + sizeof(MachSeg32));
				if (strcmp(sect32->sectname, "__text") == 0) {
					textsize = swal(sect32->size);
				} else {
					werrstr("no text section");
					goto bad;
				}
			}
			if (strcmp(seg32->segname, "__DATA") == 0) {
				datava = seg32->vmaddr;
				dataoff = seg32->fileoff;
				sect32 = (MachSect32*)(cmdp + sizeof(MachSeg32));
				if (strcmp(sect32->sectname, "__data") == 0) {
					datasize = swal(sect32->size);
				} else {
					werrstr("no data section");
					goto bad;
				}
				sect32++;
				if (strcmp(sect32->sectname, "__nl_symbol_ptr") == 0)
					sect32++;
				if (strcmp(sect32->sectname, "__bss") == 0) {
					bsssize = swal(sect32->size);
				} else {
					werrstr("no bss section");
					goto bad;
				}
			}
			break;

		case MACH_SEGMENT_64:
			if(mp->magic != 0xFEEDFACF) {
				werrstr("segment 32 in mach 64");
				goto bad;
			}
			seg = (MachSeg64*)c;
			seg->vmaddr = swav(seg->vmaddr);
			seg->vmsize = swav(seg->vmsize);
			seg->fileoff = swav(seg->fileoff);
			seg->filesize = swav(seg->filesize);
			seg->maxprot = swal(seg->maxprot);
			seg->initprot = swal(seg->initprot);
			seg->nsects = swal(seg->nsects);
			seg->flags = swal(seg->flags);
			if (strcmp(seg->segname, "__TEXT") == 0) {
				textva = seg->vmaddr;
				textoff = seg->fileoff;
				sect = (MachSect64*)(cmdp + sizeof(MachSeg64));
				if (strcmp(sect->sectname, "__text") == 0) {
					textsize = swav(sect->size);
				} else {
					werrstr("no text section");
					goto bad;
				}
			}
			if (strcmp(seg->segname, "__DATA") == 0) {
				datava = seg->vmaddr;
				dataoff = seg->fileoff;
				sect = (MachSect64*)(cmdp + sizeof(MachSeg64));
				if (strcmp(sect->sectname, "__data") == 0) {
					datasize = swav(sect->size);
				} else {
					werrstr("no data section");
					goto bad;
				}
				sect++;
				if (strcmp(sect->sectname, "__bss") == 0) {
					bsssize = swav(sect->size);
				} else {
					werrstr("no bss section");
					goto bad;
				}
			}
			break;
		case MACH_UNIXTHREAD:
			break;
		case MACH_SYMSEG:
			if (symtab == 0)
				symtab = (MachSymSeg*)c;
			else if (pclntab == 0)
				pclntab = (MachSymSeg*)c;
			break;
		}
		cmdp += c->size;
	}
	if (textva == 0 || datava == 0) {
		free(cmd);
		free(cmdbuf);
		return 0;
	}
	/* compute entry by taking address after header - weird - BUG? */
	settext(fp, textva+sizeof(Machhdr) + mp->sizeofcmds, textva, textsize, textoff);
	setdata(fp, datava, datasize, dataoff, bsssize);
	if(symtab != 0)
		setsym(fp, symtab->filesize, 0, pclntab? pclntab->filesize : 0, symtab->fileoff);
	free(cmd);
	free(cmdbuf);
	return 1;
bad:
	free(cmd);
	free(cmdbuf);
	return 0;
}
コード例 #14
0
ファイル: executable.c プロジェクト: 8l/go-learn
static int
elfdotout(int fd, Fhdr *fp, ExecHdr *hp)
{

	uint32 (*swal)(uint32);
	ushort (*swab)(ushort);
	Ehdr32 *ep;
	Phdr32 *ph;
	int i, it, id, is, phsz, shsz;
	Shdr32 *sh;

	/* bitswap the header according to the DATA format */
	ep = &hp->e.elfhdr32;
	if(ep->ident[CLASS] != ELFCLASS32) {
		return elf64dotout(fd, fp, hp);
	}
	if(ep->ident[DATA] == ELFDATA2LSB) {
		swab = leswab;
		swal = leswal;
	} else if(ep->ident[DATA] == ELFDATA2MSB) {
		swab = beswab;
		swal = beswal;
	} else {
		werrstr("bad ELF encoding - not big or little endian");
		return 0;
	}

	ep->type = swab(ep->type);
	ep->machine = swab(ep->machine);
	ep->version = swal(ep->version);
	ep->elfentry = swal(ep->elfentry);
	ep->phoff = swal(ep->phoff);
	ep->shoff = swal(ep->shoff);
	ep->flags = swal(ep->flags);
	ep->ehsize = swab(ep->ehsize);
	ep->phentsize = swab(ep->phentsize);
	ep->phnum = swab(ep->phnum);
	ep->shentsize = swab(ep->shentsize);
	ep->shnum = swab(ep->shnum);
	ep->shstrndx = swab(ep->shstrndx);
	if(ep->type != EXEC || ep->version != CURRENT)
		return 0;

	/* we could definitely support a lot more machines here */
	fp->magic = ELF_MAG;
	fp->hdrsz = (ep->ehsize+ep->phnum*ep->phentsize+16)&~15;
	switch(ep->machine) {
	case I386:
		mach = &mi386;
		fp->type = FI386;
		break;
	case MIPS:
		mach = &mmips;
		fp->type = FMIPS;
		break;
	case SPARC64:
		mach = &msparc64;
		fp->type = FSPARC64;
		break;
	case POWER:
		mach = &mpower;
		fp->type = FPOWER;
		break;
	case ARM:
		mach = &marm;
		fp->type = FARM;
		break;
	default:
		return 0;
	}

	if(ep->phentsize != sizeof(Phdr32)) {
		werrstr("bad ELF header size");
		return 0;
	}
	phsz = sizeof(Phdr32)*ep->phnum;
	ph = malloc(phsz);
	if(!ph)
		return 0;
	seek(fd, ep->phoff, 0);
	if(read(fd, ph, phsz) < 0) {
		free(ph);
		return 0;
	}
	hswal(ph, phsz/sizeof(uint32), swal);

	shsz = sizeof(Shdr32)*ep->shnum;
	sh = malloc(shsz);
	if(sh) {
		seek(fd, ep->shoff, 0);
		if(read(fd, sh, shsz) < 0) {
			free(sh);
			sh = 0;
		} else
			hswal(sh, shsz/sizeof(uint32), swal);
	}

	/* find text, data and symbols and install them */
	it = id = is = -1;
	for(i = 0; i < ep->phnum; i++) {
		if(ph[i].type == LOAD
		&& (ph[i].flags & (R|X)) == (R|X) && it == -1)
			it = i;
		else if(ph[i].type == LOAD
		&& (ph[i].flags & (R|W)) == (R|W) && id == -1)
			id = i;
		else if(ph[i].type == NOPTYPE && is == -1)
			is = i;
	}
	if(it == -1 || id == -1) {
		/*
		 * The SPARC64 boot image is something of an ELF hack.
		 * Text+Data+BSS are represented by ph[0].  Symbols
		 * are represented by ph[1]:
		 *
		 *		filesz, memsz, vaddr, paddr, off
		 * ph[0] : txtsz+datsz, txtsz+datsz+bsssz, txtaddr-KZERO, datasize, txtoff
		 * ph[1] : symsz, lcsz, 0, 0, symoff
		 */
		if(ep->machine == SPARC64 && ep->phnum == 2) {
			uint32 txtaddr, txtsz, dataddr, bsssz;

			txtaddr = ph[0].vaddr | 0x80000000;
			txtsz = ph[0].filesz - ph[0].paddr;
			dataddr = txtaddr + txtsz;
			bsssz = ph[0].memsz - ph[0].filesz;
			settext(fp, ep->elfentry | 0x80000000, txtaddr, txtsz, ph[0].offset);
			setdata(fp, dataddr, ph[0].paddr, ph[0].offset + txtsz, bsssz);
			setsym(fp, ph[1].filesz, 0, ph[1].memsz, ph[1].offset);
			free(ph);
			return 1;
		}

		werrstr("No TEXT or DATA sections");
error:
		free(sh);
		free(ph);
		return 0;
	}

	settext(fp, ep->elfentry, ph[it].vaddr, ph[it].memsz, ph[it].offset);
	setdata(fp, ph[id].vaddr, ph[id].filesz, ph[id].offset, ph[id].memsz - ph[id].filesz);
	if(is != -1)
		setsym(fp, ph[is].filesz, 0, ph[is].memsz, ph[is].offset);
	else if(sh != 0){
		char *buf;
		uvlong symsize = 0;
		uvlong symoff = 0;
		uvlong pclnsz = 0;

		/* load shstrtab names */
		buf = malloc(sh[ep->shstrndx].size);
		if (buf == 0)
			goto done;
		memset(buf, 0, sizeof buf);
		seek(fd, sh[ep->shstrndx].offset, 0);
		read(fd, buf, sh[ep->shstrndx].size);

		for(i = 0; i < ep->shnum; i++) {
			if (strcmp(&buf[sh[i].name], ".gosymtab") == 0) {
				symsize = sh[i].size;
				symoff = sh[i].offset;
			}
			if (strcmp(&buf[sh[i].name], ".gopclntab") == 0) {
				if (sh[i].offset != symoff+symsize) {
					werrstr("pc line table not contiguous with symbol table");
					free(buf);
					goto error;
				}
				pclnsz = sh[i].size;
			}
		}
		setsym(fp, symsize, 0, pclnsz, symoff);
		free(buf);
	}
done:
	free(sh);
	free(ph);
	return 1;
}
コード例 #15
0
ファイル: main.c プロジェクト: 00001/plan9port
void
main(int argc, char **argv)
{
	int omode;
	volatile int quiet;
	char *s;
	char *name;

	quiet = 0;
	name = 0;
	outputinit();
	maxoff = MAXOFF;
	omode = OREAD;
	ARGBEGIN{
	default:
		usage();
	case 'A':
		abort();
	case 'k':
		kflag = 1;
		break;
	case 'w':
		omode = ORDWR;
		break;
	case 'I':
		s = ARGF();
		if(s == 0)
			dprint("missing -I argument\n");
		else
			Ipath = s;
		break;
	case 'm':
		name = ARGF();
		if(name == 0)
			dprint("missing -m argument\n");
		break;
	case 'q':
		quiet = 1;
		break;
	}ARGEND

	attachargs(argc, argv, omode, !quiet);

	dotmap = dumbmap(-1);

	/*
	 * show initial state and drop into the execution loop.
	 */
	notify(fault);
	setsym();
	if(setjmp(env) == 0){
		if (pid || corhdr)
			setcor();	/* could get error */
		if (correg && !quiet) {
			dprint("%s\n", mach->exc(cormap, correg));
			printpc();
		}
	}

	setjmp(env);
	if (executing)
		delbp();
	executing = FALSE;
	for (;;) {
		flushbuf();
		if (errmsg) {
			dprint(errmsg);
			printc('\n');
			errmsg = 0;
			exitflg = 0;
		}
		if (mkfault) {
			mkfault=0;
			printc('\n');
			prints(DBNAME);
		}
		clrinp();
		rdc();
		reread();
		if (eof) {
			if (infile == STDIN)
				done();
			iclose(-1, 0);
			eof = 0;
			longjmp(env, 1);
		}
		exitflg = 0;
		command(0, 0);
		reread();
		if (rdc() != '\n')
			error("newline expected");
	}
}
コード例 #16
0
ファイル: executable.c プロジェクト: ZhuZhiMing/go-internals
/*
 * Read from Windows PE/COFF .exe file image.
 */
static int
pedotout(int fd, Fhdr *fp, ExecHdr *hp)
{
	uint32 start, magic;
	uint32 symtab, esymtab, pclntab, epclntab;
	IMAGE_FILE_HEADER fh;
	IMAGE_SECTION_HEADER sh;
	IMAGE_OPTIONAL_HEADER oh;
	PE64_IMAGE_OPTIONAL_HEADER oh64;
	uint8 sym[18];
	uint32 *valp, ib, entry;
	int i, ohoffset;

	USED(hp);
	seek(fd, 0x3c, 0);
	if (readn(fd, &start, sizeof(start)) != sizeof(start)) {
		werrstr("crippled PE MSDOS header");
		return 0;
	}
	start = leswal(start);

	seek(fd, start, 0);
	if (readn(fd, &magic, sizeof(magic)) != sizeof(magic)) {
		werrstr("no PE magic number found");
		return 0;
	}
	if (beswal(magic) != 0x50450000) {  /* "PE\0\0" */
		werrstr("incorrect PE magic number");
		return 0;
	}

	if (readn(fd, &fh, sizeof(fh)) != sizeof(fh)) {
		werrstr("crippled PE File Header");
		return 0;
	}
	if (fh.PointerToSymbolTable == 0) {
		werrstr("zero pointer to COFF symbol table");
		return 0;
	}

	ohoffset = seek(fd, 0, 1);
	if (readn(fd, &oh, sizeof(oh)) != sizeof(oh)) {
		werrstr("crippled PE Optional Header");
		return 0;
	}

	switch(oh.Magic) {
	case 0x10b:	// PE32
		fp->type = FI386;
		ib = leswal(oh.ImageBase);
		entry = leswal(oh.AddressOfEntryPoint);
		break;
	case 0x20b:	// PE32+
		fp->type = FAMD64;
		seek(fd, ohoffset, 0);
		if (readn(fd, &oh64, sizeof(oh64)) != sizeof(oh64)) {
			werrstr("crippled PE32+ Optional Header");
			return 0;
		}
		ib = leswal(oh64.ImageBase);
		entry = leswal(oh64.AddressOfEntryPoint);
		break;
	default:
		werrstr("invalid PE Optional Header magic number");
		return 0;
	}

	fp->txtaddr = 0;
	fp->dataddr = 0;
	for (i=0; i<leswab(fh.NumberOfSections); i++) {
		if (readn(fd, &sh, sizeof(sh)) != sizeof(sh)) {
			werrstr("could not read Section Header %d", i+1);
			return 0;
		}
		if (match8(sh.Name, ".text"))
			settext(fp, ib+entry, ib+leswal(sh.VirtualAddress), leswal(sh.VirtualSize), leswal(sh.PointerToRawData));
		if (match8(sh.Name, ".data"))
			setdata(fp, ib+leswal(sh.VirtualAddress), leswal(sh.SizeOfRawData), leswal(sh.PointerToRawData), leswal(sh.VirtualSize)-leswal(sh.SizeOfRawData));
	}
	if (fp->txtaddr==0 || fp->dataddr==0) {
		werrstr("no .text or .data");
		return 0;
	}

	seek(fd, leswal(fh.PointerToSymbolTable), 0);
	symtab = esymtab = pclntab = epclntab = 0;
	for (i=0; i<leswal(fh.NumberOfSymbols); i++) {
		if (readn(fd, sym, sizeof(sym)) != sizeof(sym)) {
			werrstr("crippled COFF symbol %d", i);
			return 0;
		}
		valp = (uint32 *)&sym[8];
		if (match8(sym, "symtab"))
			symtab = leswal(*valp);
		if (match8(sym, "esymtab"))
			esymtab = leswal(*valp);
		if (match8(sym, "pclntab"))
			pclntab = leswal(*valp);
		if (match8(sym, "epclntab"))
			epclntab = leswal(*valp);
	}
	if (symtab==0 || esymtab==0 || pclntab==0 || epclntab==0) {
		werrstr("no symtab or esymtab or pclntab or epclntab in COFF symbol table");
		return 0;
	}
	setsym(fp, symtab, esymtab-symtab, 0, 0, pclntab, epclntab-pclntab);

	return 1;
}