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

📄 machine.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
    extern String sys_siglist[];    Integer err;    if (isfinished(process)) {	printf("\"%s\" exits with code %d\n", objname, exitcode(process));	erecover();    }    if (runfirst) {	fprintf(stderr, "Entering debugger ...");	init();	fprintf(stderr, " type 'help' for help\n");    }    err = errnum(process);    if (err == SIGINT) {	printf("\n\ninterrupt ");	printloc();    } else if (err == SIGTRAP) {	printf("\nerror ");	printloc();    } else {	if (err < 0 or err > sys_nsig) {	    printf("\nsignal %d ", err);	} else {	    printf("\n%s ", sys_siglist[err]);	}	printloc();    }    putchar('\n');    if (curline > 0) {	printlines(curline, curline);    } else {	printinst(pc, pc);    }    erecover();}/* * 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);    printf("\nexecution completed, exit code is %d\n", exitcode);    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, prevaddr;    startaddr = pc;    prevaddr = startaddr;    addr = nextaddr(pc, isnext);    if (not inst_tracing and nlhdr.nlines != 0) {	line = linelookup(addr);	while (line == 0) {	    prevaddr = addr;	    addr = nextaddr(addr, isnext);	    line = linelookup(addr);	}	curline = line;    } else {	curline = 0;    }    if (addr == startaddr) {	stepto(prevaddr);    }    stepto(addr);    filename = srcfilename(addr);    setsource(filename);}/* * 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;}private Address findnextaddr(startaddr, isnext)Address startaddr;Boolean isnext;{    register Address addr;    Optab op;    VaxOpcode ins;    unsigned char mode;    int argtype, amode, argno, argval;    String r;    Boolean indexf;    enum { KNOWN, SEQUENTIAL, BRANCH } addrstatus;    argval = 0;    indexf = false;    addr = startaddr;    iread(&ins, addr, sizeof(ins));    switch (ins) {	case O_BRB:	case O_BRW:	    addrstatus = BRANCH;	    break;	    	case O_BSBB:	case O_BSBW:	case O_JSB:	case O_CALLG:	case O_CALLS:	    if (isnext) {		addrstatus = SEQUENTIAL;	    } else {		addrstatus = KNOWN;		stepto(addr);		pstep(process, DEFSIG);		addr = reg(PROGCTR);		pc = addr;		setcurfunc(whatblock(pc));		if (not isbperr()) {		    printstatus();		    /* NOTREACHED */		}		bpact();		if (nosource(curfunc) and canskip(curfunc) and		  nlhdr.nlines != 0) {		    addrstatus = KNOWN;		    addr = return_addr();		    stepto(addr);		    bpact();		} else {		    callnews(/* iscall = */ true);		}	    }	    break;	case O_RSB:	case O_RET:	    addrstatus = KNOWN;	    callnews(/* iscall = */ false);	    addr = return_addr();	    if (addr == pc) {	/* recursive ret to self */		pstep(process, DEFSIG);	    } else {		stepto(addr);	    }	    bpact();	    break;	case O_JMP: /* because it may be jmp (r1) */	case O_BNEQ: case O_BEQL: case O_BGTR:	case O_BLEQ: case O_BGEQ: case O_BLSS:	case O_BGTRU: case O_BLEQU: case O_BVC:	case O_BVS: case O_BCC: case O_BCS:	case O_CASEB: case O_CASEW: case O_CASEL:	case O_BBS: case O_BBC: case O_BBSS: case O_BBCS:	case O_BBSC: case O_BBCC: case O_BBSSI:	case O_BBCCI: case O_BLBS: case O_BLBC:	case O_ACBL: case O_AOBLSS: case O_AOBLEQ:	case O_SOBGEQ: case O_SOBGTR:	    addrstatus = KNOWN;	    stepto(addr);	    pstep(process, DEFSIG);	    addr = reg(PROGCTR);	    pc = addr;	    if (not isbperr()) {		printstatus();	    }	    break;	default:	    addrstatus = SEQUENTIAL;	    break;    }    if (addrstatus != KNOWN) {	addr += 1;	op = optab[ins];	for (argno = 0; argno < op.numargs; argno++) {	    if (indexf == true) {		indexf = false;	    }	    argtype = op.argtype[argno];	    if (is_branch_disp(argtype)) {		mode = 0xAF + (typelen(argtype) << 5);	    } else {		iread(&mode, addr, sizeof(mode));		addr += 1;	    }	    r = regname[regnm(mode)];	    amode = addrmode(mode);	    switch (amode) {		case LITSHORT:		case LITUPTO31:		case LITUPTO47:		case LITUPTO63:		    argval = mode;		    break;		case INDEX:		    indexf = true;		    --argno;		    break;		case REG:		case REGDEF:		case AUTODEC:		    break;		case AUTOINC:		    if (r == regname[PROGCTR]) {			switch (typelen(argtype)) {			    case TYPB:				argval = getdisp(addr, 1, r, amode);				addr += 1;				break;			    case TYPW:				argval = getdisp(addr, 2, r, amode);				addr += 2;				break;			    case TYPL:				argval = getdisp(addr, 4, r, amode);				addr += 4;				break;			    case TYPF:				iread(&argval, addr, sizeof(argval));				addr += 4;				break;			    case TYPQ:			    case TYPD:				iread(&argval, addr+4, sizeof(argval));				addr += 8;				break;			}		    }		    break;		case AUTOINCDEF:		    if (r == regname[PROGCTR]) {			argval = getdisp(addr, 4, r, amode);			addr += 4;		    }		    break;		case BYTEDISP:		case BYTEDISPDEF:		    argval = getdisp(addr, 1, r, amode);		    addr += 1;		    break;		case WORDDISP:		case WORDDISPDEF:		    argval = getdisp(addr, 2, r, amode);		    addr += 2;		    break;		case LONGDISP:		case LONGDISPDEF:		    argval = getdisp(addr, 4, r, amode);		    addr += 4;		    break;	    }	}	if (ins == O_CALLS or ins == O_CALLG) {	    argval += 2;	}	if (addrstatus == BRANCH) {	    addr = argval;	}    }    return addr;}/* * Get the displacement of an instruction that uses displacement addressing. */private int getdisp(addr, nbytes, reg, mode)Address addr;int nbytes;String reg;int mode;{    char byte;    short hword;    int argval;    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;    }    return argval;}#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;    Byte save;    Byte 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;{    Byte w;    Byte 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);}/* * Predicate to test if the reason the process stopped was because * of a breakpoint. */public Boolean isbperr(){    return (Boolean) (not isfinished(process) and errnum(process) == SIGTRAP);}/* * Enter a procedure by creating and executing a call instruction. */#define CALLSIZE 7	/* size of call instruction */public beginproc(p, argc)Symbol p;Integer argc;{    char save[CALLSIZE];    struct {	VaxOpcode op;	unsigned char numargs;	unsigned char mode;	char addr[sizeof(long)];	/* unaligned long */    } call;    long dest;    pc = 2;    iread(save, pc, sizeof(save));    call.op = O_CALLS;    call.numargs = argc;    call.mode = 0xef;    dest = codeloc(p) - 2 - (pc + 7);    mov(&dest, call.addr, sizeof(call.addr));    iwrite(&call, pc, sizeof(call));    setreg(PROGCTR, pc);    pstep(process, DEFSIG);    iwrite(save, pc, sizeof(save));    pc = reg(PROGCTR);    if (not isbperr()) {	printstatus();    }}

⌨️ 快捷键说明

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