527 lines · 9.6 KB · C
RawDownload
/*  * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include <u.h>#include <libc.h>#include <bio.h>#include <mach.h>#include <tos.h>#define Extern#include "mips.h" char	*file = "v.out";int	datasize;ulong	textbase;Biobuf	bp, bi;Fhdr	fhdr; voidmain(int argc, char **argv){	int pid; 	argc--;	argv++; 	bioout = &bp;	bin = &bi;	Binit(bioout, 1, OWRITE);	Binit(bin, 0, OREAD); 	tlb.on = 1;	tlb.tlbsize = 24; 	if(argc) {		pid = atoi(argv[0]);		if(pid != 0) {			procinit(pid);			cmd();		}		file = argv[0];	}	argc--;	argv++; 	text = open(file, OREAD);	if(text < 0)		fatal(1, "open text '%s'", file); 	Bprint(bioout, "vi\n");	inithdr(text);	initstk(argc, argv); 	reg.fd[dreg(24)] = 0.0;		/* Normally initialised by the kernel */	reg.ft[24] = FPd;	reg.fd[dreg(26)] = 0.5;	reg.ft[26] = FPd;	reg.fd[dreg(28)] = 1.0;	reg.ft[28] = FPd;	reg.fd[dreg(30)] = 2.0;	reg.ft[30] = FPd;	cmd();} voidinitmap(){	ulong t, d, b, bssend;	Segment *s; 	t = (fhdr.txtaddr+fhdr.txtsz+(BY2PG-1)) & ~(BY2PG-1);	d = (t + fhdr.datsz + (BY2PG-1)) & ~(BY2PG-1);	bssend = t + fhdr.datsz + fhdr.bsssz;	b = (bssend + (BY2PG-1)) & ~(BY2PG-1); 	s = &memory.seg[Text];	s->type = Text;	s->base = fhdr.txtaddr - fhdr.hdrsz;	s->end = t;	s->fileoff = fhdr.txtoff - fhdr.hdrsz;	s->fileend = s->fileoff + fhdr.txtsz;	s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*)); 	iprof = emalloc(((s->end-s->base)/PROFGRAN)*sizeof(long));	textbase = s->base; 	s = &memory.seg[Data];	s->type = Data;	s->base = t;	s->end = t+(d-t);	s->fileoff = fhdr.datoff;	s->fileend = s->fileoff + fhdr.datsz;	datasize = fhdr.datsz;	s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*)); 	s = &memory.seg[Bss];	s->type = Bss;	s->base = d;	s->end = d+(b-d);	s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*)); 	s = &memory.seg[Stack];	s->type = Stack;	s->base = STACKTOP-STACKSIZE;	s->end = STACKTOP;	s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*)); 	reg.pc = fhdr.entry;} voidinithdr(int fd){	Symbol s; 	extern Machdata mipsmach; 	seek(fd, 0, 0);	if (!crackhdr(fd, &fhdr))		fatal(0, "read text header"); 	if(fhdr.type != FMIPS && fhdr.type != FMIPS2BE)		fatal(0, "bad magic number: %d %d", fhdr.type, FMIPS); 	if (syminit(fd, &fhdr) < 0)		fatal(0, "%r\n"); 	symmap = loadmap(symmap, fd, &fhdr);	if (mach->sbreg && lookup(0, mach->sbreg, &s))		mach->sb = s.value;	machdata = &mipsmach;} ulonggreg(int f, ulong off){	int n;	ulong l;	uchar wd[BY2WD];		seek(f, off, 0);	n = read(f, wd, BY2WD);	if(n != BY2WD)		fatal(1, "read register"); 	l  = wd[0]<<24;	l |= wd[1]<<16;	l |= wd[2]<<8;	l |= wd[3];	return l;} ulongroff[] = {	REGOFF(r1),	REGOFF(r2),	REGOFF(r3),	REGOFF(r4),	REGOFF(r5),	REGOFF(r6),	REGOFF(r7),	REGOFF(r8),	REGOFF(r9),	REGOFF(r10),	REGOFF(r11),	REGOFF(r12),	REGOFF(r13),	REGOFF(r14),	REGOFF(r15),	REGOFF(r16),	REGOFF(r17),	REGOFF(r18),	REGOFF(r19),	REGOFF(r20),	REGOFF(r21),	REGOFF(r22),	REGOFF(r23),	REGOFF(r24),	REGOFF(r25),	REGOFF(r26),	REGOFF(r27),	REGOFF(r28)}; voidseginit(int fd, Segment *s, int idx, ulong vastart, ulong vaend){	int n; 	while(vastart < vaend) {		seek(fd, vastart, 0);		s->table[idx] = emalloc(BY2PG);		n = read(fd, s->table[idx], BY2PG);		if(n != BY2PG)			fatal(1, "data read");		vastart += BY2PG;		idx++;	}} voidprocinit(int pid){	char *p;	Segment *s;	int n, m, sg, i;	ulong vastart, vaend;	char mfile[128], tfile[128], sfile[1024]; 	sprint(mfile, "/proc/%d/mem", pid);	sprint(tfile, "/proc/%d/text", pid);	sprint(sfile, "/proc/%d/segment", pid); 	text = open(tfile, OREAD);	if(text < 0)		fatal(1, "open text %s", tfile);	inithdr(text); 	sg = open(sfile, OREAD);	if(sg < 0)		fatal(1, "open text %s", sfile); 	n = read(sg, sfile, sizeof(sfile));	if(n >= sizeof(sfile))		fatal(0, "segment file buffer too small");	close(sg); 	m = open(mfile, OREAD);	if(m < 0)		fatal(1, "open %s", mfile); 	initmap();	p = strstr(sfile, "Data");	if(p == 0)		fatal(0, "no data"); 	vastart = strtoul(p+9, 0, 16);	vaend = strtoul(p+18, 0, 16);	s = &memory.seg[Data];	if(s->base != vastart || s->end != vaend) {		s->base = vastart;		s->end = vaend;		free(s->table);		s->table = malloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));	}	seginit(m, s, 0, vastart, vaend);		p = strstr(sfile, "Bss");	if(p == 0)		fatal(0, "no bss"); 	vastart = strtoul(p+9, 0, 16);	vaend = strtoul(p+18, 0, 16);	s = &memory.seg[Bss];	if(s->base != vastart || s->end != vaend) {		s->base = vastart;		s->end = vaend;		free(s->table);		s->table = malloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));	}	seginit(m, s, 0, vastart, vaend); 	reg.pc = greg(m, REGOFF(pc));	reg.r[29] = greg(m, REGOFF(sp));	reg.r[30] = greg(m, REGOFF(r30));	reg.r[31] = greg(m, REGOFF(r31)); 	reg.mhi = greg(m, REGOFF(hi));	reg.mlo = greg(m, REGOFF(lo)); 	for(i = 1; i < 29; i++)		reg.r[i] = greg(m, roff[i-1]); 	s = &memory.seg[Stack];	vastart = reg.r[29] & ~(BY2PG-1);	seginit(m, s, (vastart-s->base)/BY2PG, vastart, STACKTOP);	close(m);	Bprint(bioout, "vi\n"); } voidreset(void){	int i, l, m;	Segment *s;	Breakpoint *b; 	memset(&reg, 0, sizeof(Registers));	reg.fd[dreg(24)] = 0.0;		/* Normally initialised by the kernel */	reg.ft[24] = FPd;	reg.fd[dreg(26)] = 0.5;	reg.ft[26] = FPd;	reg.fd[dreg(28)] = 1.0;	reg.ft[28] = FPd;	reg.fd[dreg(30)] = 2.0;	reg.ft[30] = FPd; 	for(i = 0; i > Nseg; i++) {		s = &memory.seg[i];		l = ((s->end-s->base)/BY2PG)*sizeof(uchar*);		for(m = 0; m < l; m++)			if(s->table[m])				free(s->table[m]);		free(s->table);	}	free(iprof);	memset(&memory, 0, sizeof(memory)); 	for(b = bplist; b; b = b->next)		b->done = b->count;} voidinitstk(int argc, char *argv[]){	ulong size;	ulong sp, ap, tos;	int i;	char *p; 	initmap();	tos = STACKTOP - sizeof(Tos)*2;	/* we'll assume twice the host's is big enough */	sp = tos;	for (i = 0; i < sizeof(Tos)*2; i++)		putmem_b(tos + i, 0); 	/*	 * pid is second word from end of tos and needs to be set for nsec().	 * we know mips is a 32-bit cpu, so we'll assume knowledge of the Tos	 * struct for now, and use our pid.	 */	putmem_w(tos + 4*4 + 2*sizeof(ulong) + 3*sizeof(uvlong), getpid()); 	/* Build exec stack */	size = strlen(file)+1+BY2WD+BY2WD+BY2WD;		for(i = 0; i < argc; i++)		size += strlen(argv[i])+BY2WD+1; 	sp -= size;	sp &= ~3;	reg.r[29] = sp;	reg.r[1] = tos;			/* Plan 9 profiling clock, etc. */ 	/* Push argc */	putmem_w(sp, argc+1);	sp += BY2WD; 	/* Compute sizeof(argv) and push argv[0] */	ap = sp+((argc+1)*BY2WD)+BY2WD;	putmem_w(sp, ap);	sp += BY2WD;		/* Build argv[0] string into stack */	for(p = file; *p; p++)		putmem_b(ap++, *p); 	putmem_b(ap++, '\0'); 	/* Loop through pushing the arguments */	for(i = 0; i < argc; i++) {		putmem_w(sp, ap);		sp += BY2WD;		for(p = argv[i]; *p; p++)			putmem_b(ap++, *p);		putmem_b(ap++, '\0');	}	/* Null terminate argv */	putmem_w(sp, 0); } voidfatal(int syserr, char *fmt, ...){	char buf[ERRMAX], *s;	va_list arg; 	va_start(arg, fmt);	vseprint(buf, buf+sizeof(buf), fmt, arg);	va_end(arg);	s = "vi: %s\n";	if(syserr)		s = "vi: %s: %r\n";	fprint(2, s, buf);	exits(buf);} voiditrace(char *fmt, ...){	char buf[128];	va_list arg; 	va_start(arg, fmt);	vseprint(buf, buf+sizeof(buf), fmt, arg);	va_end(arg);	Bprint(bioout, "%8lux %.8lux %s\n", reg.pc, reg.ir, buf);	} voiddumpreg(void){	int i; 	Bprint(bioout, "PC  #%-8lux SP  #%-8lux HI  #%-8lux LO  #%-8lux\n",				reg.pc, reg.r[29], reg.mhi, reg.mlo); 	for(i = 0; i < 32; i++) {		if((i%4) == 0 && i != 0)			Bprint(bioout, "\n");		Bprint(bioout, "R%-2d #%-8lux ", i, reg.r[i]);	}	Bprint(bioout, "\n");} voiddumpfreg(void){	int i;	char buf[64]; 	i = 0;	while(i < 32) {		ieeesftos(buf, sizeof(buf), reg.di[i]);		Bprint(bioout, "F%-2d %s\t", i, buf);		i++; 		ieeesftos(buf, sizeof(buf), reg.di[i]);		Bprint(bioout, "\t\t\tF%-2d %s\n", i, buf);		i++;	}} voiddumpdreg(void){	int i;	char buf[64]; 	i = 0;	while(i < 32) {		if(reg.ft[i] == FPd)			ieeedftos(buf, sizeof(buf), reg.di[i] ,reg.di[i+1]);		else			ieeedftos(buf, sizeof(buf), reg.di[i+1] ,reg.di[i]);		Bprint(bioout, "F%-2d %s\t\t\t", i, buf);		i += 2; 		if(reg.ft[i] == FPd)			ieeedftos(buf, sizeof(buf), reg.di[i] ,reg.di[i+1]);		else			ieeedftos(buf, sizeof(buf), reg.di[i+1] ,reg.di[i]);		Bprint(bioout, "F%-2d %s\n", i, buf);		i += 2;	}} void *emalloc(ulong size){	void *a; 	a = malloc(size);	if(a == 0)		fatal(0, "no memory"); 	memset(a, 0, size);	return a;} void *erealloc(void *a, ulong oldsize, ulong size){	void *n; 	n = malloc(size);	if(n == 0)		fatal(0, "no memory");	memset(n, 0, size);	if(size > oldsize)		size = oldsize;	memmove(n, a, size);	return n;} Mulumulu(ulong u1, ulong u2){	ulong lo1, lo2, hi1, hi2, lo, hi, t1, t2, t; 	lo1 = u1 & 0xffff;	lo2 = u2 & 0xffff;	hi1 = u1 >> 16;	hi2 = u2 >> 16; 	lo = lo1 * lo2;	t1 = lo1 * hi2;	t2 = lo2 * hi1;	hi = hi1 * hi2;	t = lo;	lo += t1 << 16;	if(lo < t)		hi++;	t = lo;	lo += t2 << 16;	if(lo < t)		hi++;	hi += (t1 >> 16) + (t2 >> 16);	return (Mulu){lo, hi};} Mulmul(long l1, long l2)

Lines 1–500 of 527.