⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 machine.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
private int printdisp(addr, nbytes, reg, mode)Address addr;int nbytes;char *reg;int mode;{    char byte;    short hword;    int argval;    Symbol f;    switch (nbytes) {	case 1:	    iread(&byte, addr, sizeof(byte));	    argval = byte;	    break;	case 2:	    iread(&hword, addr, sizeof(hword));	    argval = hword;	    break;	case 4:	    iread(&argval, addr, sizeof(argval));	    break;    }    if (reg == regname[PROGCTR] && mode >= BYTEDISP) {	argval += addr + nbytes;    }    if (reg == regname[PROGCTR]) {	f = whatblock((Address) argval + 2);	if (codeloc(f) == argval + 2) {	    printf("%s", symname(f));	} else {	    printf("%x", argval);	}    } else {	if (varIsSet("$hexoffsets")) {	    if (argval < 0) {		printf("-%x(%s)", -(argval), reg);	    } else {		printf("%x(%s)", argval, reg);	    }	} else {	    printf("%d(%s)", argval, reg);	}    }    return argval;}/* * Print the contents of the addresses within the given range * according to the given format. */typedef struct {    String name;    String printfstring;    int length;} Format;private Format fmt[] = {    { "d", " %d", sizeof(short) },    { "D", " %ld", sizeof(long) },    { "o", " %o", sizeof(short) },    { "O", " %lo", sizeof(long) },    { "x", " %04x", sizeof(short) },    { "X", " %08x", sizeof(long) },    { "b", " \\%o", sizeof(char) },    { "c", " '%c'", sizeof(char) },    { "s", "%c", sizeof(char) },    { "f", " %f", sizeof(float) },    { "g", " %g", sizeof(double) },    { "v", " (%ld,%ld)", 2 * sizeof(long) },    { "vx", " (0x%X,0x%X)", 2 * sizeof(long) },    { "vf", " (%f,%f)", sizeof(Vquad) },    { nil, nil, 0 }};private Format *findformat(s)String s;{    register Format *f;    f = &fmt[0];    while (f->name != nil and not streq(f->name, s)) {	++f;    }    if (f->name == nil) {	error("bad print format \"%s\"", s);    }    return f;}public Address printdata(lowaddr, highaddr, format)Address lowaddr;Address highaddr;String format;{    register int n;    register Address addr;    register Format *f;    int value;    if (lowaddr > highaddr) {	error("first address larger than second");    }    f = findformat(format);    n = 0;    value = 0;    for (addr = lowaddr; addr <= highaddr; addr += f->length) {	if (n == 0) {	    printf("%08x: ", addr);	}	if(streq(format, "vf")) {		Vquad value;				dread(&value, addr, f->length);		printf("(");	    prtreal(value.val[0]);		printf(",");	    prtreal(value.val[1]);		printf(")");	}	else {		dread(&value, addr, f->length);		if(streq(format, "g") || streq(format, "f")) {	    	prtreal(value);		} else {			printf(f->printfstring, value);		}	}	++n;	if (n >= (16 div f->length)) {	    putchar('\n');	    n = 0;	}    }    if (n != 0) {	putchar('\n');    }    prtaddr = addr;    return addr;}/* * The other approach is to print n items starting with a given address. */public printndata(count, startaddr, format)int count;Address startaddr;String format;{    register int i, n;    register Address addr;    register Format *f;    register Boolean isstring;    char c;    union {	char charv;	short shortv;	int intv;	float floatv;	double doublev;    } value;    if (count <= 0) {	error("non-positive repetition count");    }    f = findformat(format);    isstring = (Boolean) streq(f->name, "s");    n = 0;    addr = startaddr;    value.intv = 0;    for (i = 0; i < count; i++) {	if (n == 0) {	    printf("%08x: ", addr);	}	if (isstring) {	    putchar('"');	    dread(&c, addr, sizeof(char));	    while (c != '\0') {		printchar(c);		++addr;		dread(&c, addr, sizeof(char));	    }	    putchar('"');	    putchar('\n');	    n = 0;	    addr += sizeof(String);	} else {		if(streq(format, "vf")) {			Vquad value;					dread(&value, addr, f->length);			printf(" (");	    	prtreal(value.val[0]);			printf(",");	    	prtreal(value.val[1]);			printf(")");		}		else {			value.doublev = 0.0;			dread(&value, addr, f->length);			if(streq(format, "g") || streq(format, "f")) {				printf(" ");	    		prtreal(value);			}else {				printf(f->printfstring, value);			}		}	    ++n;	    if (n >= (16 div f->length)) {		putchar('\n');		n = 0;	    }	    addr += f->length;	}    }    if (n != 0) {	putchar('\n');    }    prtaddr = addr;}/* * Print out a value according to the given format. */public printvalue(v, format)long v;String format;{    Format *f;    char *p, *q;    f = findformat(format);    if (streq(f->name, "s")) {	putchar('"');	p = (char *) &v;	q = p + sizeof(v);	while (p < q) {	    printchar(*p);	    ++p;	}	putchar('"');    } else {	printf(f->printfstring, v);    }    putchar('\n');}/* * Print out an execution time error. * Assumes the source position of the error has been calculated. * * Have to check if the -r option was specified; if so then * the object file information hasn't been read in yet. */public printerror(){    extern Integer sys_nsig;    extern String sys_siglist[];    integer err;    if (isfinished(process)) {	err = exitcode(process);	if (err == 0) {	    printf("\"%s\" terminated normally\n", objname);	} else {	    printf("\"%s\" terminated abnormally (exit code %d)\n",		objname, err	    );	}	erecover();    }    if (runfirst) {	fprintf(stderr, "Entering debugger ...\n");	init();    }    err = errnum(process);    putchar('\n');    printsig(err);    putchar(' ');    printloc();    putchar('\n');    if (curline > 0) {	printlines(curline, curline);    } else {	printinst(pc, pc);    }    erecover();}/* * Print out a signal. */private String illinames[] = {    "reserved addressing fault",    "privileged instruction fault",    "reserved operand fault"};private String fpenames[] = {    nil,    "integer overflow trap",    "integer divide by zero trap",    "floating overflow trap",    "floating/decimal divide by zero trap",    "floating underflow trap",    "decimal overflow trap",    "subscript out of range trap",    "floating overflow fault",    "floating divide by zero fault",    "floating underflow fault"};public printsig (signo)integer signo;{    integer code;    if (signo < 0 or signo > sys_nsig) {	printf("[signal %d]", signo);    } else {	printf("%s", sys_siglist[signo]);    }    code = errcode(process);    if (signo == SIGILL) {	if (code >= 0 and code < sizeof(illinames) / sizeof(illinames[0])) {	    printf(" (%s)", illinames[code]);	}    } else if (signo == SIGFPE) {	if (code > 0 and code < sizeof(fpenames) / sizeof(fpenames[0])) {	    printf(" (%s)", fpenames[code]);	}    }}/* * Merge bit field into old value (on top of expression stack). */public void depositField(value, s)long value;Symbol s;{    unsigned n;    unsigned long offset;    unsigned long length;    offset = s->symvalue.field.offset mod 8;    length = s->symvalue.field.length;    n = pop(long);    n = (n & ((1 << length) - 1));    n = (n << offset) |	(value & ~( ((1 << length) - 1) << offset ));    push(long, n);}/* * Note the termination of the program.  We do this so as to avoid * having the process exit, which would make the values of variables * inaccessible.  We do want to flush all output buffers here, * otherwise it'll never get done. */public endprogram(){    Integer exitcode;    stepto(nextaddr(pc, true));    printnews();    exitcode = argn(1, nil);    if (exitcode != 0) {	printf("\nexecution completed (exit code %d)\n", exitcode);    } else {	printf("\nexecution completed\n");    }    getsrcpos();    erecover();}/* * Single step the machine a source line (or instruction if "inst_tracing" * is true).  If "isnext" is true, skip over procedure calls. */private Address getcall();public Boolean dostep(isnext, isvector)Boolean isnext, isvector;{    register Address addr;    register Lineno line;    String filename;	Boolean ret = false;    addr = nextaddr(pc, isnext);	if(!(isvector && found_a_vec_inst)) {    	if (not inst_tracing and nlhdr.nlines != 0) {			line = linelookup(addr);			while (line == 0) {	    		addr = nextaddr(addr, isnext);	    		line = linelookup(addr);			}			curline = line;    	} else {			curline = 0;    	}/* jlr005 * No need to check for one-line loops: since nextaddr() steps if there's * a jump, if addr==starting addr, there must have been a jump, and we're * already done. */    	stepto(addr);	}	else {		ret = true;	}    filename = srcfilename(addr);    setsource(filename);	return(ret);}/* * Compute the next address that will be executed from the given one. * If "isnext" is true then consider a procedure call as straight line code. * * We must unfortunately do much of the same work that is necessary * to print instructions.  In addition we have to deal with branches. * Unconditional branches we just follow, for conditional branches * we continue execution to the current location and then single step * the machine.  We assume that the last argument in an instruction * that branches is the branch address (or relative offset). */private Address findnextaddr();public Address nextaddr(startaddr, isnext)Address startaddr;boolean isnext;{    Address addr;    addr = usignal(process);    if (addr == 0 or addr == 1) {	addr = findnextaddr(startaddr, isnext);    }    return addr;}/* * Determine if it's ok to skip function f entered by instruction ins. * If so, we're going to compute the return address and step to it. * Therefore we cannot skip over a function entered by a jsb or bsb, * since the return address is not easily computed for them. */private boolean skipfunc (ins, f)VaxOpcode ins;Symbol f;{    boolean b;    b = (boolean) (	ins != O_JSB and ins != O_BSBB and ins != O_BSBW and	not inst_tracing and nlhdr.nlines != 0 and	nosource(curfunc) and canskip(curfunc)    );    return b;}private Address findnextaddr(startaddr, isnext)Address startaddr;Boolean isnext;{    register Address addr;    Optab op;    VaxOpcode ins, ins2;    unsigned char mode;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -