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

📄 vax.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1983 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)vax.c	5.8 (Berkeley) 6/1/90";#endif /* not lint *//* * Target machine dependent stuff. */#include "defs.h"#include "machine.h"#include "process.h"#include "runtime.h"#include "events.h"#include "main.h"#include "symbols.h"#include "source.h"#include "mappings.h"#include "object.h"#include "tree.h"#include "eval.h"#include "keywords.h"#include "ops.h"#ifndef publictypedef unsigned int Address;typedef unsigned char Byte;typedef unsigned int Word;#define NREG 16#define ARGP 12#define FRP 13#define STKP 14#define PROGCTR 15#define CODESTART 0#define FUNCOFFSET 2#define nargspassed(frame) argn(0, frame)#define BITSPERBYTE 8#define BITSPERWORD (BITSPERBYTE * sizeof(Word))/* * This magic macro enables us to look at the process' registers * in its user structure. */#define regloc(reg)	(ctob(UPAGES) + (sizeof(Word) * (reg)))#include "source.h"#include "symbols.h"#include <signal.h>#include <sys/param.h>#include <machine/psl.h>#include <machine/pte.h>#include <sys/user.h>#undef DELETE /* XXX */#include <sys/vm.h>#include <machine/reg.h>Address pc;Address prtaddr;#endif/* * Indices into u. for use in collecting registers values. */public int rloc[] ={    R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, AP, FP, SP, PC};private Address printop();private Optab *ioptab[256];	/* index by opcode to optab */private Optab *esctab[256];	/* for extended opcodes *//* * Initialize the opcode lookup table. */public optab_init(){    register Optab *p;    for (p = optab; p->iname; p++) {	if (p->format == O_ESCD) {	    esctab[p->val] = p;	} else if (p->format != O_ESCD && p->format != O_ESCE) {	    ioptab[p->val] = p;	}    }}/* * Decode and print the instructions within the given address range. */public printinst(lowaddr, highaddr)Address lowaddr;Address highaddr;{    register Address addr;    for (addr = lowaddr; addr <= highaddr; ) {	addr = printop(addr);    }    prtaddr = addr;}/* * Another approach:  print n instructions starting at the given address. */public printninst(count, addr)int count;Address addr;{    register Integer i;    register Address newaddr;    if (count <= 0) {	error("non-positive repetition count");    } else {	newaddr = addr;	for (i = 0; i < count; i++) {	    newaddr = printop(newaddr);	}	prtaddr = newaddr;    }}/* * 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) },    { 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;}/* * Retrieve and print out the appropriate data in the given format. * Floats have to be handled specially to allow the compiler to * convert them to doubles when passing to printf. */private printformat (f, addr)Format *f;Address addr;{    union {	char charv;	short shortv;	int intv;	float floatv;	double doublev;    } value;    value.intv = 0;    dread(&value, addr, f->length);    if (streq(f->name, "f")) {	printf(f->printfstring, value.floatv);    } else {	printf(f->printfstring, value);    }}public Address printdata(lowaddr, highaddr, format)Address lowaddr;Address highaddr;String format;{    int n;    register Address addr;    Format *f;    if (lowaddr > highaddr) {	error("first address larger than second");    }    f = findformat(format);    n = 0;    for (addr = lowaddr; addr <= highaddr; addr += f->length) {	if (n == 0) {	    printf("%08x: ", addr);	}	printformat(f, addr);	++n;	if (n >= (16 div f->length)) {	    printf("\n");	    n = 0;	}    }    if (n != 0) {	printf("\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;{    int i, n;    Address addr;    Format *f;    Boolean isstring;    char c;    if (count <= 0) {	error("non-positive repetition count");    }    f = findformat(format);    isstring = (Boolean) streq(f->name, "s");    n = 0;    addr = startaddr;    for (i = 0; i < count; i++) {	if (n == 0) {	    printf("%08x: ", addr);	}	if (isstring) {	    printf("\"");	    dread(&c, addr, sizeof(char));	    while (c != '\0') {		printchar(c);		++addr;		dread(&c, addr, sizeof(char));	    }	    printf("\"\n");	    n = 0;	    addr += sizeof(String);	} else {	    printformat(f, addr);	    ++n;	    if (n >= (16 div f->length)) {		printf("\n");		n = 0;	    }	    addr += f->length;	}    }    if (n != 0) {	printf("\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();    }    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]);	}    }}/* * 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 dostep(isnext)Boolean isnext;{    register Address addr;    register Lineno line;    String filename;    Address startaddr;    startaddr = pc;    addr = nextaddr(pc, isnext);    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;    }    stepto(addr);    filename = srcfilename(addr);    setsource(filename);}typedef char Bpinst;#define BP_OP       O_BPT       /* breakpoint trap */#define BP_ERRNO    SIGTRAP     /* signal received at a breakpoint *//* * Setting a breakpoint at a location consists of saving * the word at the location and poking a BP_OP there. * * We save the locations and words on a list for use in unsetting. */typedef struct Savelist *Savelist;struct Savelist {    Address location;    Bpinst save;    short refcount;    Savelist link;};private Savelist savelist;/* * Set a breakpoint at the given address.  Only save the word there * if it's not already a breakpoint. */public setbp(addr)Address addr;{    Bpinst w, save;    register Savelist newsave, s;    for (s = savelist; s != nil; s = s->link) {	if (s->location == addr) {	    s->refcount++;	    return;	}    }    iread(&save, addr, sizeof(save));    newsave = new(Savelist);    newsave->location = addr;    newsave->save = save;    newsave->refcount = 1;    newsave->link = savelist;    savelist = newsave;    w = BP_OP;    iwrite(&w, addr, sizeof(w));}/* * Unset a breakpoint; unfortunately we have to search the SAVELIST * to find the saved value.  The assumption is that the SAVELIST will * usually be quite small. */public unsetbp(addr)Address addr;{    register Savelist s, prev;    prev = nil;    for (s = savelist; s != nil; s = s->link) {	if (s->location == addr) {	    iwrite(&s->save, addr, sizeof(s->save));	    s->refcount--;	    if (s->refcount == 0) {		if (prev == nil) {		    savelist = s->link;		} else {		    prev->link = s->link;		}		dispose(s);	    }	    return;	}	prev = s;    }    panic("unsetbp: couldn't find address %d", addr);}/* * VAX instruction decoder, derived from adb. */private Address printop(addr)Address addr;{    register Optab *op;    VaxOpcode ins;    unsigned char mode;    int argtype, amode, argno, argval;    String reg;    Boolean indexf;    short offset;    argval = 0;    indexf = false;    printf("%08x  ", addr);    iread(&ins, addr, sizeof(ins));    addr += 1;    if (ins == O_ESCF) {	iread(&ins, addr, sizeof(ins));	addr += 1;	op = ioptab[ins];    } else if (ins == O_ESCD) {	iread(&ins, addr, sizeof(ins));	addr += 1;	op = esctab[ins];    } else {	op = ioptab[ins];    }    if (op == nil) {	printf("[unrecognized opcode %#0x]\n", ins);	return addr;    }    printf("%s", op->iname);    for (argno = 0; argno < op->numargs; argno++) {	if (indexf == true) {	    indexf = false;	} else if (argno == 0) {	    printf("\t");	} else {	    printf(",");	}	argtype = op->argtype[argno];	if (is_branch_disp(argtype)) {	    mode = 0xAF + (typelen(argtype) << 5);	} else {	    iread(&mode, addr, sizeof(mode));	    addr += 1;	}	reg = regname[regnm(mode)];	amode = addrmode(mode);	switch (amode) {	    case LITSHORT:	    case LITUPTO31:	    case LITUPTO47:	    case LITUPTO63:		if (typelen(argtype) == TYPF || typelen(argtype) == TYPD ||		    typelen(argtype) == TYPG || typelen(argtype) == TYPH)		    printf("$%s", fltimm[mode]);		else		    printf("$%x", mode);		argval = mode;		break;	    case INDEX:		printf("[%s]", reg);		indexf = true;		argno--;		break;	    case REG:		printf("%s", reg);		break;	    case REGDEF:		printf("(%s)", reg);		break;	    case AUTODEC:		printf("-(%s)", reg);		break;	    case AUTOINC:		if (reg != regname[PROGCTR]) {		    printf("(%s)+", reg);		} else {		    printf("$");		    switch (typelen(argtype)) {			case TYPB:			    argval = printdisp(addr, 1, reg, amode);			    addr += 1;			    break;			case TYPW:			    argval = printdisp(addr, 2, reg, amode);			    addr += 2;			    break;			case TYPL:			    argval = printdisp(addr, 4, reg, amode);			    addr += 4;			    break;			case TYPF:			    iread(&argval, addr, sizeof(argval));			    if ((argval & 0xffff007f) == 0x8000) {				printf("[reserved operand]");			    } else {

⌨️ 快捷键说明

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