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

📄 qdb.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <u.h>#include <libc.h>#include <bio.h>#include <mach.h>/* * PowerPC-specific debugger interface *	forsyth@terzarima.net */static	char	*powerexcep(Map*, Rgetter);static	int	powerfoll(Map*, uvlong, Rgetter, uvlong*);static	int	powerinst(Map*, uvlong, char, char*, int);static	int	powerinstlen(Map*, uvlong);static	int	powerdas(Map*, uvlong, char*, int);/* *	Machine description */Machdata powermach ={	{0x02, 0x8f, 0xff, 0xff},		/* break point */	/* BUG */	4,			/* break point size */	beswab,			/* short to local byte order */	beswal,			/* long to local byte order */	beswav,			/* vlong to local byte order */	risctrace,		/* print C traceback */	riscframe,		/* frame finder */	powerexcep,		/* print exception */	0,			/* breakpoint fixup */	beieeesftos,		/* single precision float printer */	beieeedftos,		/* double precisioin float printer */	powerfoll,		/* following addresses */	powerinst,		/* print instruction */	powerdas,		/* dissembler */	powerinstlen,		/* instruction size */};static char *excname[] ={	"reserved 0",	"system reset",	"machine check",	"data access",	"instruction access",	"external interrupt",	"alignment",	"program exception",	"floating-point unavailable",	"decrementer",	"i/o controller interface error",	"reserved B",	"system call",	"trace trap",	"floating point assist",	"reserved",	"ITLB miss",	"DTLB load miss",	"DTLB store miss",	"instruction address breakpoint"	"SMI interrupt"	"reserved 15",	"reserved 16",	"reserved 17",	"reserved 18",	"reserved 19",	"reserved 1A",	/* the following are made up on a program exception */	"floating point exception",		/* FPEXC */	"illegal instruction",	"privileged instruction",	"trap",	"illegal operation",};static char*powerexcep(Map *map, Rgetter rget){	long c;	static char buf[32];	c = (*rget)(map, "CAUSE") >> 8;	if(c < nelem(excname))		return excname[c];	sprint(buf, "unknown trap #%lx", c);	return buf;}/* * disassemble PowerPC opcodes */#define	REGSP	1	/* should come from q.out.h, but there's a clash */#define	REGSB	2static	char FRAMENAME[] = ".frame";static Map *mymap;/* * ibm conventions for these: bit 0 is top bit *	from table 10-1 */typedef struct {	uchar	aa;		/* bit 30 */	uchar	crba;		/* bits 11-15 */	uchar	crbb;		/* bits 16-20 */	long	bd;		/* bits 16-29 */	uchar	crfd;		/* bits 6-8 */	uchar	crfs;		/* bits 11-13 */	uchar	bi;		/* bits 11-15 */	uchar	bo;		/* bits 6-10 */	uchar	crbd;		/* bits 6-10 */	union {		short	d;	/* bits 16-31 */		short	simm;		ushort	uimm;	};	uchar	fm;		/* bits 7-14 */	uchar	fra;		/* bits 11-15 */	uchar	frb;		/* bits 16-20 */	uchar	frc;		/* bits 21-25 */	uchar	frs;		/* bits 6-10 */	uchar	frd;		/* bits 6-10 */	uchar	crm;		/* bits 12-19 */	long	li;		/* bits 6-29 || b'00' */	uchar	lk;		/* bit 31 */	uchar	mb;		/* bits 21-25 */	uchar	me;		/* bits 26-30 */	uchar	nb;		/* bits 16-20 */	uchar	op;		/* bits 0-5 */	uchar	oe;		/* bit 21 */	uchar	ra;		/* bits 11-15 */	uchar	rb;		/* bits 16-20 */	uchar	rc;		/* bit 31 */	union {		uchar	rs;	/* bits 6-10 */		uchar	rd;	};	uchar	sh;		/* bits 16-20 */	ushort	spr;		/* bits 11-20 */	uchar	to;		/* bits 6-10 */	uchar	imm;		/* bits 16-19 */	ushort	xo;		/* bits 21-30, 22-30, 26-30, or 30 (beware) */	long	immediate;	long w0;	long w1;	uvlong	addr;		/* pc of instruction */	short	target;	char	*curr;		/* current fill level in output buffer */	char	*end;		/* end of buffer */	int 	size;		/* number of longs in instr */	char	*err;		/* errmsg */} Instr;#define	IBF(v,a,b) (((ulong)(v)>>(32-(b)-1)) & ~(~0L<<(((b)-(a)+1))))#define	IB(v,b) IBF((v),(b),(b))#pragma	varargck	argpos	bprint		2static voidbprint(Instr *i, char *fmt, ...){	va_list arg;	va_start(arg, fmt);	i->curr = vseprint(i->curr, i->end, fmt, arg);	va_end(arg);}static intdecode(uvlong pc, Instr *i){	ulong w;	if (get4(mymap, pc, &w) < 0) {		werrstr("can't read instruction: %r");		return -1;	}	i->aa = IB(w, 30);	i->crba = IBF(w, 11, 15);	i->crbb = IBF(w, 16, 20);	i->bd = IBF(w, 16, 29)<<2;	if(i->bd & 0x8000)		i->bd |= ~0L<<16;	i->crfd = IBF(w, 6, 8);	i->crfs = IBF(w, 11, 13);	i->bi = IBF(w, 11, 15);	i->bo = IBF(w, 6, 10);	i->crbd = IBF(w, 6, 10);	i->uimm = IBF(w, 16, 31);	/* also d, simm */	i->fm = IBF(w, 7, 14);	i->fra = IBF(w, 11, 15);	i->frb = IBF(w, 16, 20);	i->frc = IBF(w, 21, 25);	i->frs = IBF(w, 6, 10);	i->frd = IBF(w, 6, 10);	i->crm = IBF(w, 12, 19);	i->li = IBF(w, 6, 29)<<2;	if(IB(w, 6))		i->li |= ~0<<25;	i->lk = IB(w, 31);	i->mb = IBF(w, 21, 25);	i->me = IBF(w, 26, 30);	i->nb = IBF(w, 16, 20);	i->op = IBF(w, 0, 5);	i->oe = IB(w, 21);	i->ra = IBF(w, 11, 15);	i->rb = IBF(w, 16, 20);	i->rc = IB(w, 31);	i->rs = IBF(w, 6, 10);	/* also rd */	i->sh = IBF(w, 16, 20);	i->spr = IBF(w, 11, 20);	i->to = IBF(w, 6, 10);	i->imm = IBF(w, 16, 19);	i->xo = IBF(w, 21, 30);		/* bits 21-30, 22-30, 26-30, or 30 (beware) */	i->immediate = i->simm;	if(i->op == 15)		i->immediate <<= 16;	i->w0 = w;	i->target = -1;	i->addr = pc;	i->size = 1;	return 1;}static intmkinstr(uvlong pc, Instr *i){	Instr x;	if(decode(pc, i) < 0)		return -1;	/*	 * combine ADDIS/ORI (CAU/ORIL) into MOVW	 */	if (i->op == 15 && i->ra==0) {		if(decode(pc+4, &x) < 0)			return -1;		if (x.op == 24 && x.rs == x.ra && x.ra == i->rd) {			i->immediate |= (x.immediate & 0xFFFF);			i->w1 = x.w0;			i->target = x.rd;			i->size++;			return 1;		}	}	return 1;}static intplocal(Instr *i){	long offset;	Symbol s;	if (!findsym(i->addr, CTEXT, &s) || !findlocal(&s, FRAMENAME, &s))		return -1;	offset = s.value - i->immediate;	if (offset > 0) {		if(getauto(&s, offset, CAUTO, &s)) {			bprint(i, "%s+%lld(SP)", s.name, s.value);			return 1;		}	} else {		if (getauto(&s, -offset-4, CPARAM, &s)) {			bprint(i, "%s+%ld(FP)", s.name, -offset);			return 1;		}	}	return -1;}static intpglobal(Instr *i, uvlong off, int anyoff, char *reg){	Symbol s, s2;	uvlong off1;	if(findsym(off, CANY, &s) &&	   s.value-off < 4096 &&	   (s.class == CDATA || s.class == CTEXT)) {		if(off==s.value && s.name[0]=='$'){			off1 = 0;			geta(mymap, s.value, &off1);			if(off1 && findsym(off1, CANY, &s2) && s2.value == off1){				bprint(i, "$%s%s", s2.name, reg);				return 1;			}		}		bprint(i, "%s", s.name);		if (s.value != off)			bprint(i, "+%llux", off-s.value);		bprint(i, reg);		return 1;	}	if(!anyoff)		return 0;	bprint(i, "%llux%s", off, reg);	return 1;}static voidaddress(Instr *i){	if (i->ra == REGSP && plocal(i) >= 0)		return;	if (i->ra == REGSB && mach->sb && pglobal(i, mach->sb+i->immediate, 0, "(SB)") >= 0)		return;	if(i->simm < 0)		bprint(i, "-%x(R%d)", -i->simm, i->ra);	else		bprint(i, "%lux(R%d)", i->immediate, i->ra);}static	char	*tcrbits[] = {"LT", "GT", "EQ", "VS"};static	char	*fcrbits[] = {"GE", "LE", "NE", "VC"};typedef struct Opcode Opcode;struct Opcode {	uchar	op;	ushort	xo;	ushort	xomask;	char	*mnemonic;	void	(*f)(Opcode *, Instr *);	char	*ken;	int	flags;};static void format(char *, Instr *, char *);static voidbranch(Opcode *o, Instr *i){	char buf[8];	int bo, bi;	bo = i->bo & ~1;	/* ignore prediction bit */	if(bo==4 || bo==12 || bo==20) {	/* simple forms */		if(bo != 20) {			bi = i->bi&3;			sprint(buf, "B%s%%L", bo==12? tcrbits[bi]: fcrbits[bi]);			format(buf, i, 0);			bprint(i, "\t");			if(i->bi > 4)				bprint(i, "CR(%d),", i->bi/4);		} else			format("BR%L\t", i, 0);		if(i->op == 16)			format(0, i, "%J");		else if(i->op == 19 && i->xo == 528)			format(0, i, "(CTR)");		else if(i->op == 19 && i->xo == 16)			format(0, i, "(LR)");	} else		format(o->mnemonic, i, o->ken);}static voidaddi(Opcode *o, Instr *i){	if (i->op==14 && i->ra == 0)		format("MOVW", i, "%i,R%d");	else if (i->ra == REGSB) {		bprint(i, "MOVW\t$");		address(i);		bprint(i, ",R%d", i->rd);	} else if(i->op==14 && i->simm < 0) {		bprint(i, "SUB\t$%d,R%d", -i->simm, i->ra);		if(i->rd != i->ra)			bprint(i, ",R%d", i->rd);	} else if(i->ra == i->rd) {		format(o->mnemonic, i, "%i");		bprint(i, ",R%d", i->rd);	} else		format(o->mnemonic, i, o->ken);}static voidaddis(Opcode *o, Instr *i){	long v;	v = i->immediate;	if (i->op==15 && i->ra == 0)		bprint(i, "MOVW\t$%lux,R%d", v, i->rd);	else if (i->op==15 && i->ra == REGSB) {		bprint(i, "MOVW\t$");		address(i);		bprint(i, ",R%d", i->rd);	} else if(i->op==15 && v < 0) {		bprint(i, "SUB\t$%ld,R%d", -v, i->ra);		if(i->rd != i->ra)			bprint(i, ",R%d", i->rd);	} else {		format(o->mnemonic, i, 0);		bprint(i, "\t$%ld,R%d", v, i->ra);		if(i->rd != i->ra)			bprint(i, ",R%d", i->rd);	}}static voidandi(Opcode *o, Instr *i){	if (i->ra == i->rs)		format(o->mnemonic, i, "%I,R%d");	else		format(o->mnemonic, i, o->ken);}static voidgencc(Opcode *o, Instr *i){	format(o->mnemonic, i, o->ken);}static voidgen(Opcode *o, Instr *i){	format(o->mnemonic, i, o->ken);	if (i->rc)		bprint(i, " [illegal Rc]");}static voidldx(Opcode *o, Instr *i){	if(i->ra == 0)		format(o->mnemonic, i, "(R%b),R%d");	else		format(o->mnemonic, i, "(R%b+R%a),R%d");	if(i->rc)		bprint(i, " [illegal Rc]");}static voidstx(Opcode *o, Instr *i){	if(i->ra == 0)		format(o->mnemonic, i, "R%d,(R%b)");	else		format(o->mnemonic, i, "R%d,(R%b+R%a)");	if(i->rc && i->xo != 150)		bprint(i, " [illegal Rc]");}static voidfldx(Opcode *o, Instr *i){	if(i->ra == 0)		format(o->mnemonic, i, "(R%b),F%d");	else		format(o->mnemonic, i, "(R%b+R%a),F%d");	if(i->rc)		bprint(i, " [illegal Rc]");}static voidfstx(Opcode *o, Instr *i){	if(i->ra == 0)		format(o->mnemonic, i, "F%d,(R%b)");	else		format(o->mnemonic, i, "F%d,(R%b+R%a)");	if(i->rc)		bprint(i, " [illegal Rc]");}static voiddcb(Opcode *o, Instr *i){	if(i->ra == 0)		format(o->mnemonic, i, "(R%b)");	else		format(o->mnemonic, i, "(R%b+R%a)");	if(i->rd)		bprint(i, " [illegal Rd]");	if(i->rc)		bprint(i, " [illegal Rc]");}static voidlw(Opcode *o, Instr *i, char r){	bprint(i, "%s\t", o->mnemonic);	address(i);	bprint(i, ",%c%d", r, i->rd);}static voidload(Opcode *o, Instr *i){	lw(o, i, 'R');}static voidfload(Opcode *o, Instr *i){	lw(o, i, 'F');}static voidsw(Opcode *o, Instr *i, char r){	int offset;	char *m;	Symbol s;	m = o->mnemonic;	if (i->rs == REGSP) {		if (findsym(i->addr, CTEXT, &s) && findlocal(&s, FRAMENAME, &s)) {			offset = s.value-i->immediate;			if (offset > 0 && getauto(&s, offset, CAUTO, &s)) {				bprint(i, "%s\t%c%d,%s-%d(SP)", m, r, i->rd,					s.name, offset);				return;			}		}	}	if (i->rs == REGSB && mach->sb) {		bprint(i, "%s\t%c%d,", m, r, i->rd);		address(i);		return;	}	if (r == 'F')		format(m, i, "F%d,%l");	else		format(m, i, o->ken);}static voidstore(Opcode *o, Instr *i){	sw(o, i, 'R');}static voidfstore(Opcode *o, Instr *i){	sw(o, i, 'F');}static voidshifti(Opcode *o, Instr *i){	if (i->ra == i->rs)		format(o->mnemonic, i, "$%k,R%a");	else		format(o->mnemonic, i, o->ken);}static voidshift(Opcode *o, Instr *i){	if (i->ra == i->rs)		format(o->mnemonic, i, "R%b,R%a");	else		format(o->mnemonic, i, o->ken);}static voidadd(Opcode *o, Instr *i){	if (i->rd == i->ra)		format(o->mnemonic, i, "R%b,R%d");	else if (i->rd == i->rb)		format(o->mnemonic, i, "R%a,R%d");	else		format(o->mnemonic, i, o->ken);}static voidsub(Opcode *o, Instr *i){	format(o->mnemonic, i, 0);	bprint(i, "\t");	if(i->op == 31) {		bprint(i, "\tR%d,R%d", i->ra, i->rb);	/* subtract Ra from Rb */		if(i->rd != i->rb)			bprint(i, ",R%d", i->rd);	} else		bprint(i, "\tR%d,$%d,R%d", i->ra, i->simm, i->rd);}static voidqdiv(Opcode *o, Instr *i){	format(o->mnemonic, i, 0);	if(i->op == 31)		bprint(i, "\tR%d,R%d", i->rb, i->ra);	else		bprint(i, "\t$%d,R%d", i->simm, i->ra);	if(i->ra != i->rd)		bprint(i, ",R%d", i->rd);}static voidand(Opcode *o, Instr *i){	if (i->op == 31) {		/* Rb,Rs,Ra */		if (i->ra == i->rs)			format(o->mnemonic, i, "R%b,R%a");		else if (i->ra == i->rb)			format(o->mnemonic, i, "R%s,R%a");		else			format(o->mnemonic, i, o->ken);	} else {		/* imm,Rs,Ra */		if (i->ra == i->rs)			format(o->mnemonic, i, "%I,R%a");		else			format(o->mnemonic, i, o->ken);	}}static voidor(Opcode *o, Instr *i){	if (i->op == 31) {		/* Rb,Rs,Ra */		if (i->rs == 0 && i->ra == 0 && i->rb == 0)			format("NOP", i, 0);		else if (i->rs == i->rb)			format("MOVW", i, "R%b,R%a");		else			and(o, i);	} else

⌨️ 快捷键说明

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