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

📄 vax.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
				printf("%g", *(float *)&argval);			    }			    addr += 4;			    break;			case TYPD:			    /* XXX this bags the low order bits */			    iread(&argval, addr, sizeof(argval));			    if ((argval & 0xffff007f) == 0x8000) {				printf("[reserved operand]");			    } else {				printf("%g", *(float *)&argval);			    }			    addr += 8;			    break;			case TYPG:			case TYPQ:			    iread(&argval, addr+4, sizeof(argval));			    printf("%08x", argval);			    iread(&argval, addr, sizeof(argval));			    printf("%08x", argval);			    addr += 8;			    break;			case TYPH:			case TYPO:			    iread(&argval, addr+12, sizeof(argval));			    printf("%08x", argval);			    iread(&argval, addr+8, sizeof(argval));			    printf("%08x", argval);			    iread(&argval, addr+4, sizeof(argval));			    printf("%08x", argval);			    iread(&argval, addr, sizeof(argval));			    printf("%08x", argval);			    addr += 16;			    break;		    }		}		break;	    case AUTOINCDEF:		if (reg == regname[PROGCTR]) {		    printf("*$");		    argval = printdisp(addr, 4, reg, amode);		    addr += 4;		} else {		    printf("*(%s)+", reg);		}		break;	    case BYTEDISP:		argval = printdisp(addr, 1, reg, amode);		addr += 1;		break;	    case BYTEDISPDEF:		printf("*");		argval = printdisp(addr, 1, reg, amode);		addr += 1;		break;	    case WORDDISP:		argval = printdisp(addr, 2, reg, amode);		addr += 2;		break;	    case WORDDISPDEF:		printf("*");		argval = printdisp(addr, 2, reg, amode);		addr += 2;		break;	    case LONGDISP:		argval = printdisp(addr, 4, reg, amode);		addr += 4;		break;	    case LONGDISPDEF:		printf("*");		argval = printdisp(addr, 4, reg, amode);		addr += 4;		break;	}    }    if (ins == O_CASEB || ins == O_CASEW || ins == O_CASEL) {	for (argno = 0; argno <= argval; argno++) {	    iread(&offset, addr, sizeof(offset));	    printf("\n\t\t%d", offset);	    addr += 2;	}    }    printf("\n");    return addr;}/* * Print the displacement of an instruction that uses displacement * addressing. */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;}/* * 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;    register Optab *op;    VaxOpcode ins, ins2;    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) {	/*	 * It used to be that unconditional jumps and branches were handled	 * by taking their destination address as the next address.  While	 * saving the cost of starting up the process, this approach	 * doesn't work when jumping indirect (since the value in the	 * register might not yet have been set).	 *	 * So unconditional jumps and branches are now handled the same way	 * as conditional jumps and branches.	 *	case O_BRB:	case O_BRW:	    addrstatus = BRANCH;	    break;	 *	 */	    	case O_BSBB:	case O_BSBW:	case O_JSB:	case O_CALLG:	case O_CALLS:	    addrstatus = KNOWN;	    stepto(addr);	    pstep(process, DEFSIG);	    addr = reg(PROGCTR);	    pc = addr;	    setcurfunc(whatblock(pc));	    if (not isbperr()) {		printstatus();		/* NOTREACHED */	    }	    bpact();	    if (isnext or skipfunc(ins, curfunc)) {		addrstatus = KNOWN;		addr = return_addr();		stepto(addr);		bpact();	    } else {		callnews(/* iscall = */ true);	    }	    break;	case O_RSB:	case O_RET:	    addrstatus = KNOWN;	    stepto(addr);	    callnews(/* iscall = */ false);	    pstep(process, DEFSIG);	    addr = reg(PROGCTR);	    pc = addr;	    if (not isbperr()) {		printstatus();	    }	    bpact();	    break;	case O_BRB: case O_BRW:	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:	case O_ESCF: /* bugchecks */	branches:	    addrstatus = KNOWN;	    stepto(addr);	    pstep(process, DEFSIG);	    addr = reg(PROGCTR);	    pc = addr;	    if (not isbperr()) {		printstatus();	    }	    break;	case O_ESCD:	    iread(&ins2, addr+1, sizeof(ins2));	    if (ins2 == O_ACBF || ins2 == O_ACBD)		/* actually ACBG and ACBH */		goto branches;	    /* fall through */	default:	    addrstatus = SEQUENTIAL;	    break;    }    if (addrstatus != KNOWN) {	addr += 1;	if (ins == O_ESCD) {	    ins = ins2;	    addr += 1;	    op = esctab[ins];	    if (op == nil) {		printf("[bad extended opcode %#x in findnextaddr]\n", ins);		return addr;	    }	} else {	    op = ioptab[ins];	    if (op == nil) {		printf("[bad opcode %#x in findnextaddr]\n", ins);		return addr;	    }	}	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:			    case TYPG:				iread(&argval, addr+4, sizeof(argval));				addr += 8;				break;			    case TYPO:			    case TYPH:				iread(&argval, addr+12, sizeof(argval));				addr += 16;				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;}/* * 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();    }}/* * Special variables for debugging the kernel. */public integer masterpcbb;public integer slr;public struct pte *sbr;private struct pcb pcb;public getpcb (){    integer i;    fseek(corefile, masterpcbb & ~0x80000000, 0);    get(corefile, pcb);    pcb.pcb_p0lr &= ~AST_CLR;    printf("p0br %lx p0lr %lx p1br %lx p1lr %lx\n",	pcb.pcb_p0br, pcb.pcb_p0lr, pcb.pcb_p1br, pcb.pcb_p1lr    );    setreg(0, pcb.pcb_r0);    setreg(1, pcb.pcb_r1);    setreg(2, pcb.pcb_r2);    setreg(3, pcb.pcb_r3);    setreg(4, pcb.pcb_r4);    setreg(5, pcb.pcb_r5);    setreg(6, pcb.pcb_r6);    setreg(7, pcb.pcb_r7);    setreg(8, pcb.pcb_r8);    setreg(9, pcb.pcb_r9);    setreg(10, pcb.pcb_r10);    setreg(11, pcb.pcb_r11);    setreg(ARGP, pcb.pcb_ap);    setreg(FRP, pcb.pcb_fp);    setreg(STKP, pcb.pcb_ksp);    setreg(PROGCTR, pcb.pcb_pc);}public copyregs (savreg, reg)Word savreg[], reg[];{    reg[0] = savreg[R0];    reg[1] = savreg[R1];    reg[2] = savreg[R2];    reg[3] = savreg[R3];    reg[4] = savreg[R4];    reg[5] = savreg[R5];    reg[6] = savreg[R6];    reg[7] = savreg[R7];    reg[8] = savreg[R8];    reg[9] = savreg[R9];    reg[10] = savreg[R10];    reg[11] = savreg[R11];    reg[ARGP] = savreg[AP];    reg[FRP] = savreg[FP];    reg[STKP] = savreg[SP];    reg[PROGCTR] = savreg[PC];}/* * Map a virtual address to a physical address. */public Address vmap (addr)Address addr;{    Address r;    integer v, n;    struct pte pte;    r = addr & ~0xc0000000;    v = btop(r);    switch (addr&0xc0000000) {	case 0xc0000000:	case 0x80000000:	    /*	     * In system space, so get system pte.	     * If it is valid or reclaimable then the physical address	     * is the combination of its page number and the page offset	     * of the original address.	     */	    if (v >= slr) {		error("address %x out of segment", addr);	    }	    r = ((long) (sbr + v)) & ~0x80000000;	    goto simple;	case 0x40000000:	    /*	     * In p1 space, must not be in shadow region.	     */	    if (v < pcb.pcb_p1lr) {		error("address %x out of segment", addr);	    }	    r = (Address) (pcb.pcb_p1br + v);	    break;	case 0x00000000:	    /*	     * In p0 space, must not be off end of region.	     */	    if (v >= pcb.pcb_p0lr) {		error("address %x out of segment", addr);	    }	    r = (Address) (pcb.pcb_p0br + v);	    break;	default:	    /* do nothing */	    break;    }    /*     * For p0/p1 address, user-level page table should be in     * kernel virtual memory.  Do second-level indirect by recursing.     */    if ((r & 0x80000000) == 0) {	error("bad p0br or p1br in pcb");    }    r = vmap(r);simple:    /*     * "r" is now the address of the pte of the page     * we are interested in; get the pte and paste up the physical address.     */    fseek(corefile, r, 0);    n = fread(&pte, sizeof(pte), 1, corefile);    if (n != 1) {	error("page table botch (fread at %x returns %d)", r, n);    }    if (pte.pg_v == 0 and (pte.pg_fod != 0 or pte.pg_pfnum == 0)) {	error("page no valid or reclamable");    }    return (addr&PGOFSET) + ((Address) ptob(pte.pg_pfnum));}/* * Extract a bit field from an integer. */public integer extractField (s)Symbol s;{    integer n, nbytes, r;    n = 0;    nbytes = size(s);    if (nbytes > sizeof(n)) {	printf("[bad size in extractField -- word assumed]\n");	nbytes = sizeof(n);    }    popn(nbytes, &n);    r = n >> (s->symvalue.field.offset mod BITSPERBYTE);    r &= ((1 << s->symvalue.field.length) - 1);    return r;}/* * Change the length of a value in memory according to a given difference * in the lengths of its new and old types. */public loophole (oldlen, newlen)integer oldlen, newlen;{    integer n, i;    n = newlen - oldlen;    if (n > 0) {	for (i = 0; i < n; i++) {	    sp[i] = '\0';	}    }    sp += n;}

⌨️ 快捷键说明

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