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

📄 5db.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <u.h>#include <libc.h>#include <bio.h>#include <mach.h>static int debug = 0;#define	BITS(a, b)	((1<<(b+1))-(1<<a))#define LSR(v, s)	((ulong)(v) >> (s))#define ASR(v, s)	((long)(v) >> (s))#define ROR(v, s)	(LSR((v), (s)) | (((v) & ((1 << (s))-1)) << (32 - (s))))typedef struct	Instr	Instr;struct	Instr{	Map	*map;	ulong	w;	uvlong	addr;	uchar	op;			/* super opcode */	uchar	cond;			/* bits 28-31 */	uchar	store;			/* bit 20 */	uchar	rd;			/* bits 12-15 */	uchar	rn;			/* bits 16-19 */	uchar	rs;			/* bits 0-11 (shifter operand) */	long	imm;			/* rotated imm */	char*	curr;			/* fill point in buffer */	char*	end;			/* end of buffer */	char*	err;			/* error message */};typedef struct Opcode Opcode;struct Opcode{	char*	o;	void	(*fmt)(Opcode*, Instr*);	uvlong	(*foll)(Map*, Rgetter, Instr*, uvlong);	char*	a;};static	void	format(char*, Instr*, char*);static	char	FRAMENAME[] = ".frame";/* * Arm-specific debugger interface */static	char	*armexcep(Map*, Rgetter);static	int	armfoll(Map*, uvlong, Rgetter, uvlong*);static	int	arminst(Map*, uvlong, char, char*, int);static	int	armdas(Map*, uvlong, char*, int);static	int	arminstlen(Map*, uvlong);/* *	Debugger interface */Machdata armmach ={	{0, 0, 0, 0xD},		/* break point */	4,			/* break point size */	leswab,			/* short to local byte order */	leswal,			/* long to local byte order */	leswav,			/* long to local byte order */	risctrace,		/* C traceback */	riscframe,		/* Frame finder */	armexcep,			/* print exception */	0,			/* breakpoint fixup */	0,			/* single precision float printer */	0,			/* double precision float printer */	armfoll,		/* following addresses */	arminst,		/* print instruction */	armdas,			/* dissembler */	arminstlen,		/* instruction size */};static char*armexcep(Map *map, Rgetter rget){	uvlong c;	c = (*rget)(map, "TYPE");	switch ((int)c&0x1f) {	case 0x11:		return "Fiq interrupt";	case 0x12:		return "Mirq interrupt";	case 0x13:		return "SVC/SWI Exception";	case 0x17:		return "Prefetch Abort/Data Abort";	case 0x18:		return "Data Abort";	case 0x1b:		return "Undefined instruction/Breakpoint";	case 0x1f:		return "Sys trap";	default:		return "Undefined trap";	}}staticchar*	cond[16] ={	"EQ",	"NE",	"CS",	"CC",	"MI",	"PL",	"VS",	"VC",	"HI",	"LS",	"GE",	"LT",	"GT",	"LE",	0,	"NV"};staticchar*	shtype[4] ={	"<<",	">>",	"->",	"@>"};staticchar *hb[4] ={	"???",	"HU", "B", "H"};staticchar*	addsub[2] ={	"-",	"+",};intarmclass(long w){	int op;	op = (w >> 25) & 0x7;	switch(op) {	case 0:	/* data processing r,r,r */		op = ((w >> 4) & 0xf);		if(op == 0x9) {			op = 48+16;		/* mul */			if(w & (1<<24)) {				op += 2;				if(w & (1<<22))					op++;	/* swap */				break;			}			if(w & (1<<23)) {	/* mullu */				op = (48+24+4+4+2+2+4);				if(w & (1<<22))	/* mull */					op += 2;			}			if(w & (1<<21))				op++;		/* mla */			break;		}		if((op & 0x9) == 0x9)		/* ld/st byte/half s/u */		{			op = (48+16+4) + ((w >> 22) & 0x1) + ((w >> 19) & 0x2);			break;		}		op = (w >> 21) & 0xf;		if(w & (1<<4))			op += 32;		else		if((w & (31<<7)) || (w & (1<<5)))			op += 16;		break;	case 1:	/* data processing i,r,r */		op = (48) + ((w >> 21) & 0xf);		break;	case 2:	/* load/store byte/word i(r) */		op = (48+24) + ((w >> 22) & 0x1) + ((w >> 19) & 0x2);		break;	case 3:	/* load/store byte/word (r)(r) */		op = (48+24+4) + ((w >> 22) & 0x1) + ((w >> 19) & 0x2);		break;	case 4:	/* block data transfer (r)(r) */		op = (48+24+4+4) + ((w >> 20) & 0x1);		break;	case 5:	/* branch / branch link */		op = (48+24+4+4+2) + ((w >> 24) & 0x1);		break;	case 7:	/* coprocessor crap */		op = (48+24+4+4+2+2) + ((w >> 3) & 0x2) + ((w >> 20) & 0x1);		break;	default:		op = (48+24+4+4+2+2+4+4);		break;	}	return op;}static intdecode(Map *map, uvlong pc, Instr *i){	ulong w;	if(get4(map, pc, &w) < 0) {		werrstr("can't read instruction: %r");		return -1;	}	i->w = w;	i->addr = pc;	i->cond = (w >> 28) & 0xF;	i->op = armclass(w);	i->map = map;	return 1;}#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 intplocal(Instr *i){	char *reg;	Symbol s;	char *fn;	int class;	int offset;	if(!findsym(i->addr, CTEXT, &s)) {		if(debug)fprint(2,"fn not found @%llux: %r\n", i->addr);		return 0;	}	fn = s.name;	if (!findlocal(&s, FRAMENAME, &s)) {		if(debug)fprint(2,"%s.%s not found @%s: %r\n", fn, FRAMENAME, s.name);			return 0;	}	if(s.value > i->imm) {		class = CAUTO;		offset = s.value-i->imm;		reg = "(SP)";	} else {		class = CPARAM;		offset = i->imm-s.value-4;		reg = "(FP)";	}	if(!getauto(&s, offset, class, &s)) {		if(debug)fprint(2,"%s %s not found @%ux: %r\n", fn,			class == CAUTO ? " auto" : "param", offset);		return 0;	}	bprint(i, "%s%c%lld%s", s.name, class == CPARAM ? '+' : '-', s.value, reg);	return 1;}/* * Print value v as name[+offset] */static intgsymoff(char *buf, int n, long v, int space){	Symbol s;	int r;	long delta;	r = delta = 0;		/* to shut compiler up */	if (v) {		r = findsym(v, space, &s);		if (r)			delta = v-s.value;		if (delta < 0)			delta = -delta;	}	if (v == 0 || r == 0 || delta >= 4096)		return snprint(buf, n, "#%lux", v);	if (strcmp(s.name, ".string") == 0)		return snprint(buf, n, "#%lux", v);	if (!delta)		return snprint(buf, n, "%s", s.name);	if (s.type != 't' && s.type != 'T')		return snprint(buf, n, "%s+%llux", s.name, v-s.value);	else		return snprint(buf, n, "#%lux", v);}static voidarmdps(Opcode *o, Instr *i){	i->store = (i->w >> 20) & 1;	i->rn = (i->w >> 16) & 0xf;	i->rd = (i->w >> 12) & 0xf;	i->rs = (i->w >> 0) & 0xf;	if(i->rn == 15 && i->rs == 0) {		if(i->op == 8) {			format("MOVW", i,"CPSR, R%d");			return;		} else		if(i->op == 10) {			format("MOVW", i,"SPSR, R%d");			return;		}	} else	if(i->rn == 9 && i->rd == 15) {		if(i->op == 9) {			format("MOVW", i, "R%s, CPSR");			return;		} else		if(i->op == 11) {			format("MOVW", i, "R%s, SPSR");			return;		}	}	format(o->o, i, o->a);}static voidarmdpi(Opcode *o, Instr *i){	ulong v;	int c;	v = (i->w >> 0) & 0xff;	c = (i->w >> 8) & 0xf;	while(c) {		v = (v<<30) | (v>>2);		c--;	}	i->imm = v;	i->store = (i->w >> 20) & 1;	i->rn = (i->w >> 16) & 0xf;	i->rd = (i->w >> 12) & 0xf;	i->rs = i->w&0x0f;		/* RET is encoded as ADD #0,R14,R15 */	if((i->w & 0x0fffffff) == 0x028ef000){		format("RET%C", i, "");		return;	}	if((i->w & 0x0ff0ffff) == 0x0280f000){		format("B%C", i, "0(R%n)");		return;	}	format(o->o, i, o->a);}static voidarmsdti(Opcode *o, Instr *i){	ulong v;	v = i->w & 0xfff;	if(!(i->w & (1<<23)))		v = -v;	i->store = ((i->w >> 23) & 0x2) | ((i->w >>21) & 0x1);	i->imm = v;	i->rn = (i->w >> 16) & 0xf;	i->rd = (i->w >> 12) & 0xf;		/* RET is encoded as LW.P x,R13,R15 */	if ((i->w & 0x0ffff000) == 0x049df000)	{		format("RET%C%p", i, "%I");		return;	}	format(o->o, i, o->a);}/* arm V4 ld/st halfword, signed byte */static voidarmhwby(Opcode *o, Instr *i){	i->store = ((i->w >> 23) & 0x2) | ((i->w >>21) & 0x1);	i->imm = (i->w & 0xf) | ((i->w >> 8) & 0xf);	if (!(i->w & (1 << 23)))		i->imm = - i->imm;	i->rn = (i->w >> 16) & 0xf;	i->rd = (i->w >> 12) & 0xf;	i->rs = (i->w >> 0) & 0xf;	format(o->o, i, o->a);}static voidarmsdts(Opcode *o, Instr *i){	i->store = ((i->w >> 23) & 0x2) | ((i->w >>21) & 0x1);	i->rs = (i->w >> 0) & 0xf;	i->rn = (i->w >> 16) & 0xf;	i->rd = (i->w >> 12) & 0xf;	format(o->o, i, o->a);}static voidarmbdt(Opcode *o, Instr *i){	i->store = (i->w >> 21) & 0x3;		/* S & W bits */	i->rn = (i->w >> 16) & 0xf;	i->imm = i->w & 0xffff;	if(i->w == 0xe8fd8000)		format("RFE", i, "");	else		format(o->o, i, o->a);}static voidarmund(Opcode *o, Instr *i){	format(o->o, i, o->a);}static voidarmcdt(Opcode *o, Instr *i){	format(o->o, i, o->a);}static voidarmunk(Opcode *o, Instr *i){	format(o->o, i, o->a);}static voidarmb(Opcode *o, Instr *i){	ulong v;	v = i->w & 0xffffff;	if(v & 0x800000)		v |= ~0xffffff;	i->imm = (v<<2) + i->addr + 8;	format(o->o, i, o->a);}static voidarmco(Opcode *o, Instr *i)		/* coprocessor instructions */{	int op, p, cp;	char buf[1024];	i->rn = (i->w >> 16) & 0xf;	i->rd = (i->w >> 12) & 0xf;	i->rs = i->w&0xf;	cp = (i->w >> 8) & 0xf;	p = (i->w >> 5) & 0x7;	if(i->w&(1<<4)) {		op = (i->w >> 21) & 0x07;		snprint(buf, sizeof(buf), "#%x, #%x, R%d, C(%d), C(%d), #%x\n", cp, op, i->rd, i->rn, i->rs, p);	} else {		op = (i->w >> 20) & 0x0f;		snprint(buf, sizeof(buf), "#%x, #%x, C(%d), C(%d), C(%d), #%x\n", cp, op, i->rd, i->rn, i->rs, p);	}	format(o->o, i, buf);}static intarmcondpass(Map *map, Rgetter rget, uchar cond){	uvlong psr;	uchar n;	uchar z;	uchar c;	uchar v;	psr = rget(map, "PSR");	n = (psr >> 31) & 1;	z = (psr >> 30) & 1;	c = (psr >> 29) & 1;	v = (psr >> 28) & 1;	switch(cond) {	default:	case 0:		return z;	case 1:		return !z;	case 2:		return c;	case 3:		return !c;	case 4:		return n;	case 5:		return !n;	case 6:		return v;	case 7:		return !v;	case 8:		return c && !z;	case 9:		return !c || z;	case 10:	return n == v;	case 11:	return n != v;	case 12:	return !z && (n == v);	case 13:	return z && (n != v);	case 14:	return 1;	case 15:	return 0;	}}static ulongarmshiftval(Map *map, Rgetter rget, Instr *i){	if(i->w & (1 << 25)) {				/* immediate */		ulong imm = i->w & BITS(0, 7);		ulong s = (i->w & BITS(8, 11)) >> 7; /* this contains the *2 */		return ROR(imm, s);	} else {		char buf[8];		ulong v;		ulong s = (i->w & BITS(7,11)) >> 7;		sprint(buf, "R%ld", i->w & 0xf);		v = rget(map, buf);		switch((i->w & BITS(4, 6)) >> 4) {		default:		case 0:					/* LSLIMM */			return v << s;		case 1:					/* LSLREG */			sprint(buf, "R%lud", s >> 1);			s = rget(map, buf) & 0xFF;			if(s >= 32) return 0;			return v << s;		case 2:					/* LSRIMM */			return LSR(v, s);		case 3:					/* LSRREG */			sprint(buf, "R%ld", s >> 1);			s = rget(map, buf) & 0xFF;			if(s >= 32) return 0;			return LSR(v, s);		case 4:					/* ASRIMM */			if(s == 0) {				if((v & (1U<<31)) == 0)					return 0;				return 0xFFFFFFFF;			}			return ASR(v, s);		case 5:					/* ASRREG */			sprint(buf, "R%ld", s >> 1);			s = rget(map, buf) & 0xFF;			if(s >= 32) {

⌨️ 快捷键说明

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