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

📄 udb.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <u.h>#include <libc.h>#include <bio.h>#include <mach.h>/* * Sparc64-specific debugger interface */static	char	*sparc64excep(Map*, Rgetter);static	int	sparc64foll(Map*, uvlong, Rgetter, uvlong*);static	int	sparc64inst(Map*, uvlong, char, char*, int);static	int	sparc64das(Map*, uvlong, char*, int);static	int	sparc64instlen(Map*, uvlong);Machdata sparc64mach ={	{0x91, 0xd0, 0x20, 0x01},	/* breakpoint: TA $1 */	4,			/* break point size */	beswab,			/* convert short to local byte order */	beswal,			/* convert long to local byte order */	beswav,			/* convert vlong to local byte order */	risctrace,		/* C traceback */	riscframe,		/* frame finder */	sparc64excep,		/* print exception */	0,			/* breakpoint fixup */	beieeesftos,		/* single precision float printer */	beieeedftos,		/* double precision float printer */	sparc64foll,		/* following addresses */	sparc64inst,		/* print instruction */	sparc64das,		/* dissembler */	sparc64instlen,		/* instruction size */};static char *trapname[] ={	0,	"power on reset",	"watchdog reset",	"external reset",	"software reset",	"RED",	0, 0,	"instruction access exception",	"instruction access MMU miss",	"instruction access error",	0, 0, 0, 0, 0,	"illegal instruction",	"privileged opcode",	"unimplemented LDD",	"unimplemented STD",	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	"fp disabled",	"fp exception ieee 754",	"fp exception other",	0, 0, 0, 0,	"division by zero",	"internal processor error",	0, 0, 0, 0, 0, 0,	"data access exception",	"data access MMU miss",	"data access error",	"data access protection",	"mem address not aligned",	"LDDF mem address not aligned",	"STDF mem address not aligned",	"privileged action",	"LDQF mem address nto aligned",	"STQF mem address not aligned",};static char*excname(ulong tt){	static char buf[32];	if(tt < sizeof trapname/sizeof(char*) && trapname[tt])		return trapname[tt];	if(tt >= 258)		sprint(buf, "trap instruction %ld", tt-128);	else if(65<=tt && tt<=79)		sprint(buf, "interrupt level %ld", tt-64);	else switch(tt){	case 64:		return "async data error";	case 96:		return "mondo interrupt";	case 100:		return "instruction access MMU miss";	case 104:		return "data access MMU miss";	case 108:		return "data access protection";	case 256:		return "syscall";	case 257:		return "breakpoint";	default:		sprint(buf, "unknown trap %ld", tt);	}	return buf;}static char*sparc64excep(Map *map, Rgetter rget){	long tt;	tt = (*rget)(map, "TT");	return excname(tt);}	/* Sparc disassembler and related functions */struct opcode {	char	*mnemonic;	void	(*f)(struct instr*, char*);	int	flag;};static	char FRAMENAME[] = ".frame";typedef struct instr Instr;struct instr {	uchar	op;		/* bits 31-30 */	uchar	rd;		/* bits 29-25 */	uchar	op2;		/* bits 24-22 */	uchar	a;		/* bit  29    */	uchar	cond;		/* bits 28-25 */	uchar	op3;		/* bits 24-19 */	uchar	rs1;		/* bits 18-14 */	uchar	i;		/* bit  13    */	uchar	asi;		/* bits 12-05 */	uchar	rs2;		/* bits 04-00 */	short	simm13;		/* bits 12-00, signed */	ushort	opf;		/* bits 13-05 */	ulong	immdisp22;	/* bits 21-00 */	ulong	simmdisp22;	/* bits 21-00, signed */	ulong	disp30;		/* bits 30-00 */	ulong	imm32;		/* SETHI+ADD constant */	int	target;		/* SETHI+ADD dest reg */	long	w0;	long	w1;	uvlong	addr;		/* pc of instruction */	char	*curr;		/* current fill level in output buffer */	char	*end;		/* end of buffer */	int 	size;		/* number of longs in instr */	char	*err;		/* errmsg */};static	Map	*mymap;		/* disassembler context */static	int	dascase;static int	mkinstr(uvlong, Instr*);static void	bra1(Instr*, char*, char*[]);static void	bra(Instr*, char*);static void	fbra(Instr*, char*);static void	cbra(Instr*, char*);static void	unimp(Instr*, char*);static void	fpop(Instr*, char*);static void	shift(Instr*, char*);static void	sethi(Instr*, char*);static void	load(Instr*, char*);static void	loada(Instr*, char*);static void	store(Instr*, char*);static void	storea(Instr*, char*);static void	add(Instr*, char*);static void	cmp(Instr*, char*);static void	wr(Instr*, char*);static void	jmpl(Instr*, char*);static void	rd(Instr*, char*);static void	loadf(Instr*, char*);static void	storef(Instr*, char*);static void	loadc(Instr*, char*);static void	loadcsr(Instr*, char*);static void	trap(Instr*, char*);static struct opcode sparc64op0[8] = {	[0]	"UNIMP",	unimp,	0,	/* page 137 */	[2]	"B",		bra,	0,	/* page 119 */	[4]	"SETHI",	sethi,	0,	/* page 104 */	[6]	"FB",		fbra,	0,	/* page 121 */	[7]	"CB",		cbra,	0,	/* page 123 */};static struct opcode sparc64op2[64] = {	[0x00]	"ADD",		add,	0,	/* page 108 */	[0x10]	"ADDCC",	add,	0,	[0x08]	"ADDX",		add,	0,	[0x18]	"ADDXCC",	add,	0,	[0x20]	"TADD",		add,	0,	/* page 109 */	[0x22]	"TADDCCTV",	add,	0,	[0x04]	"SUB",		add,	0,	/* page 110 */	[0x14]	"SUBCC",	cmp,	0,	[0x0C]	"SUBX",		add,	0,	[0x1C]	"SUBXCC",	add,	0,	[0x21]	"TSUB",		add,	0,	/* page 111 */	[0x23]	"TSUBCCTV",	add,	0,	[0x24]	"MULSCC",	add,	0,	/* page 112 */	[0x0A]	"UMUL",		add,	0,	/* page 113 */	[0x0B]	"SMUL",		add,	0,	[0x1A]	"UMULCC",	add,	0,	[0x1B]	"SMULCC",	add,	0,	[0x0E]	"UDIV",		add,	0,	/* page 115 */	[0x0F]	"SDIV",		add,	0,	[0x1E]	"UDIVCC",	add,	0,	[0x1F]	"SDIVCC",	add,	0,	[0x01]	"AND",		add,	0,	/* page 106 */	[0x11]	"ANDCC",	add,	0,	[0x05]	"ANDN",		add,	0,	[0x15]	"ANDNCC",	add,	0,	[0x02]	"OR",		add,	0,	[0x12]	"ORCC",		add,	0,	[0x06]	"ORN",		add,	0,	[0x16]	"ORNCC",	add,	0,	[0x03]	"XOR",		add,	0,	[0x13]	"XORCC",	add,	0,	[0x07]	"XORN",		add,	0,	[0x17]	"XORNCC",	add,	0,	[0x25]	"SLL",		shift,	0,	/* page 107 */	[0x26]	"SRL",		shift,	0,	[0x27]	"SRA",		shift,	0,	[0x3C]	"SAVE",		add,	0,	/* page 117 */	[0x3D]	"RESTORE",	add,	0,	[0x38]	"JMPL",		jmpl,	0,	/* page 126 */	[0x39]	"RETT",		add,	0,	/* page 127 */	[0x3A]	"T",		trap,	0,	/* page 129 */	[0x28]	"rdy",		rd,	0,	/* page 131 */	[0x29]	"rdpsr",	rd,	0,	[0x2A]	"rdwim",	rd,	0,	[0x2B]	"rdtbr",	rd,	0,	[0x30]	"wry",		wr,	0,	/* page 133 */	[0x31]	"wrpsr",	wr,	0,	[0x32]	"wrwim",	wr,	0,	[0x33]	"wrtbr",	wr,	0,	[0x3B]	"flush",	add,	0,	/* page 138 */	[0x34]	"FPOP",		fpop,	0,	/* page 140 */	[0x35]	"FPOP",		fpop,	0,};static struct opcode sparc64op3[64]={	[0x09]	"ldsb",		load,	0,	/* page 90 */	[0x19]	"ldsba",	loada,	0,	[0x0A]	"ldsh",		load,	0,	[0x1A]	"ldsha",	loada,	0,	[0x01]	"ldub",		load,	0,	[0x11]	"lduba",	loada,	0,	[0x02]	"lduh",		load,	0,	[0x12]	"lduha",	loada,	0,	[0x00]	"ld",		load,	0,	[0x10]	"lda",		loada,	0,	[0x03]	"ldd",		load,	0,	[0x13]	"ldda",		loada,	0,	[0x20]	"ldf",		loadf,	0,	/* page 92 */	[0x23]	"lddf",		loadf,	0,	[0x21]	"ldfsr",	loadf,0,	[0x30]	"ldc",		loadc,	0,	/* page 94 */	[0x33]	"lddc",		loadc,	0,	[0x31]	"ldcsr",	loadcsr,0,	[0x05]	"stb",		store,	0,	/* page 95 */	[0x15]	"stba",		storea,	0,	[0x06]	"sth",		store,	0,	[0x16]	"stha",		storea,	0,	[0x04]	"st",		store,	0,	[0x14]	"sta",		storea,	0,	[0x07]	"std",		store,	0,	[0x17]	"stda",		storea,	0,	[0x24]	"stf",		storef,	0,	/* page 97 */	[0x27]	"stdf",		storef,	0,	[0x25]	"stfsr",	storef,0,	[0x26]	"stdfq",	storef,0,	[0x34]	"stc",		loadc,	0,	/* page 99 */	[0x37]	"stdc",		loadc,	0,	[0x35]	"stcsr",	loadcsr,0,	[0x36]	"stdcq",	loadcsr,0,	[0x0D]	"ldstub",	store,	0,	/* page 101 */	[0x1D]	"ldstuba",	storea,	0,	[0x0F]	"swap",		load,	0,	/* page 102 */	[0x1F]	"swapa",	loada,	0,};#pragma	varargck	argpos	bprint	2#pragma	varargck	type	"T"	char*/* convert to lower case from upper, according to dascase */static intTfmt(Fmt *f){	char buf[128];	char *s, *t, *oa;	oa = va_arg(f->args, char*);	if(dascase){		for(s=oa,t=buf; *t = *s; s++,t++)			if('A'<=*t && *t<='Z')				*t += 'a'-'A';		return fmtstrcpy(f, buf);	}	return fmtstrcpy(f, oa);}static 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(ulong pc, Instr *i){	ulong w;	if (get4(mymap, pc, &w) < 0) {		werrstr("can't read instruction: %r");		return -1;	}	i->op = (w >> 30) & 0x03;	i->rd = (w >> 25) & 0x1F;	i->op2 = (w >> 22) & 0x07;	i->a = (w >> 29) & 0x01;	i->cond = (w >> 25) & 0x0F;	i->op3 = (w >> 19) & 0x3F;	i->rs1 = (w >> 14) & 0x1F;	i->i = (w >> 13) & 0x01;	i->asi = (w >> 5) & 0xFF;	i->rs2 = (w >> 0) & 0x1F;	i->simm13 = (w >> 0) & 0x1FFF;	if(i->simm13 & (1<<12))		i->simm13 |= ~((1<<13)-1);	i->opf = (w >> 5) & 0x1FF;	i->immdisp22 = (w >> 0) & 0x3FFFFF;	i->simmdisp22 = i->immdisp22;	if(i->simmdisp22 & (1<<21))		i->simmdisp22 |= ~((1<<22)-1);	i->disp30 = (w >> 0) & 0x3FFFFFFF;	i->w0 = w;	i->target = -1;	i->addr = pc;	i->size = 1;	return 1;}static intmkinstr(uvlong pc, Instr *i){	Instr xi;	if (decode(pc, i) < 0)		return -1;	if(i->op==0 && i->op2==4 && !dascase){	/* SETHI */		if (decode(pc+4, &xi) < 0)			return -1;		if(xi.op==2 && xi.op3==0)		/* ADD */		if(xi.i == 1 && xi.rs1 == i->rd){	/* immediate to same reg */			i->imm32 = xi.simm13 + (i->immdisp22<<10);			i->target = xi.rd;			i->w1 = xi.w0;			i->size++;			return 1;		}	}	if(i->op==2 && i->opf==1 && !dascase){	/* FMOVS */		if (decode(pc+4, &xi) < 0)			return -1;		if(i->op==2 && i->opf==1)		/* FMOVS */		if(xi.rd==i->rd+1 && xi.rs2==i->rs2+1){	/* next pair */			i->w1 = xi.w0;			i->size++;		}	}	return 1;}static intprintins(Map *map, uvlong pc, char *buf, int n){	Instr instr;	void (*f)(Instr*, char*);	mymap = map;	memset(&instr, 0, sizeof(instr));	instr.curr = buf;	instr.end = buf+n-1;	if (mkinstr(pc, &instr) < 0)		return -1;	switch(instr.op){	case 0:		f = sparc64op0[instr.op2].f;		if(f)			(*f)(&instr, sparc64op0[instr.op2].mnemonic);		else			bprint(&instr, "unknown %lux", instr.w0);		break;	case 1:		bprint(&instr, "CALL\t");		instr.curr += symoff(instr.curr, instr.end-instr.curr,					pc+instr.disp30*4, CTEXT);		if (!dascase)			bprint(&instr, "(SB)");		break;	case 2:		f = sparc64op2[instr.op3].f;		if(f)			(*f)(&instr, sparc64op2[instr.op3].mnemonic);		else			bprint(&instr, "unknown %lux", instr.w0);		break;	case 3:		f = sparc64op3[instr.op3].f;		if(f)			(*f)(&instr, sparc64op3[instr.op3].mnemonic);		else			bprint(&instr, "unknown %lux", instr.w0);		break;	}	if (instr.err) {		if (instr.curr != buf)			bprint(&instr, "\t\t;");		bprint(&instr, instr.err);	}	return instr.size*4;}static intsparc64inst(Map *map, uvlong pc, char modifier, char *buf, int n){	static int fmtinstalled = 0;		/* a modifier of 'I' toggles the dissassembler type */	if (!fmtinstalled) {		fmtinstalled = 1;		fmtinstall('T', Tfmt);	}	if ((asstype == ASUNSPARC && modifier == 'i')		|| (asstype == ASPARC && modifier == 'I'))		dascase = 'a'-'A';	else		dascase = 0;	return printins(map, pc, buf, n);}static intsparc64das(Map *map, uvlong pc, char *buf, int n){	Instr instr;	mymap = map;	memset(&instr, 0, sizeof(instr));	instr.curr = buf;	instr.end = buf+n-1;	if (mkinstr(pc, &instr) < 0)		return -1;	if (instr.end-instr.curr > 8)		instr.curr = _hexify(instr.curr, instr.w0, 7);	if (instr.end-instr.curr > 9 && instr.size == 2) {		*instr.curr++ = ' ';		instr.curr = _hexify(instr.curr, instr.w1, 7);	}	*instr.curr = 0;	return instr.size*4;}static intsparc64instlen(Map *map, uvlong pc){	Instr i;	mymap = map;	if (mkinstr(pc, &i) < 0)		return -1;	return i.size*4;}static intplocal(Instr *i){	long offset;	Symbol s;	if (!findsym(i->addr, CTEXT, &s) || !findlocal(&s, FRAMENAME, &s))		return -1;	if (s.value > i->simm13) {		if(getauto(&s, s.value-i->simm13, CAUTO, &s)) {			bprint(i, "%s+%lld(SP)", s.name, s.value);			return 1;		}	} else {		offset = i->simm13-s.value;		if (getauto(&s, offset-4, CPARAM, &s)) {			bprint(i, "%s+%ld(FP)", s.name, offset);			return 1;		}	}	return -1;}static voidaddress(Instr *i){	Symbol s, s2;	uvlong off, off1;	if (i->rs1 == 1 && plocal(i) >= 0)		return;	off = mach->sb+i->simm13;	if(i->rs1 == 2	&& findsym(off, CANY, &s)			&& s.value-off < 4096			&& (s.class == CDATA || s.class == CTEXT)) {

⌨️ 快捷键说明

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