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

📄 8db.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 4 页
字号:
				ip->disp = s&0xffff;			}			if (igets(map, ip, (ushort*)&ip->seg) < 0)				return 0;			ip->jumptype = PTR;			break;		case AUXMM:	/* Multi-byte op code; prefix determines table selection */			if (igetc(map, ip, &c) < 0)				return 0;			obase = (Optable*)op->proto;			switch (ip->opre) {			case 0x66:	op = optab660F; break;			case 0xF2:	op = optabF20F; break;			case 0xF3:	op = optabF30F; break;			default:	op = nil; break;			}			if(op != nil && op[c].proto != nil)				obase = op;			norex = 1;	/* no more rex prefixes */			/* otherwise the optab entry captures it */			goto newop;		case AUX:	/* Multi-byte op code - Auxiliary table */			obase = (Optable*)op->proto;			if (igetc(map, ip, &c) < 0)				return 0;			goto newop;		case OPRE:	/* Instr Prefix or media op */			ip->opre = c;			/* fall through */		case PRE:	/* Instr Prefix */			ip->prefix = (char*)op->proto;			if (igetc(map, ip, &c) < 0)				return 0;			if (ip->opre && c == 0x0F)				ip->prefix = 0;			goto newop;		case SEG:	/* Segment Prefix */			ip->segment = (char*)op->proto;			if (igetc(map, ip, &c) < 0)				return 0;			goto newop;		case OPOVER:	/* Operand size override */			ip->opre = c;			ip->osize = 'W';			if (igetc(map, ip, &c) < 0)				return 0;			if (c == 0x0F)				ip->osize = 'L';			else if (ip->amd64 && (c&0xF0) == 0x40)				ip->osize = 'Q';			goto newop;		case ADDOVER:	/* Address size override */			ip->asize = 0;			if (igetc(map, ip, &c) < 0)				return 0;			goto newop;		case JUMP:	/* mark instruction as JUMP or RET */		case RET:			ip->jumptype = op->operand[i];			break;		default:			werrstr("bad operand type %d", op->operand[i]);			return 0;		}	}	return op;}#pragma	varargck	argpos	bprint		2static voidbprint(Instr *ip, char *fmt, ...){	va_list arg;	va_start(arg, fmt);	ip->curr = vseprint(ip->curr, ip->end, fmt, arg);	va_end(arg);}/* *  if we want to call 16 bit regs AX,BX,CX,... *  and 32 bit regs EAX,EBX,ECX,... then *  change the defs of ANAME and ONAME to: *  #define	ANAME(ip)	((ip->asize == 'E' ? "E" : "") *  #define	ONAME(ip)	((ip)->osize == 'L' ? "E" : "") */#define	ANAME(ip)	""#define	ONAME(ip)	""static char *reg[] =  {[AX]	"AX",[CX]	"CX",[DX]	"DX",[BX]	"BX",[SP]	"SP",[BP]	"BP",[SI]	"SI",[DI]	"DI",	/* amd64 */[R8]	"R8",[R9]	"R9",[R10]	"R10",[R11]	"R11",[R12]	"R12",[R13]	"R13",[R14]	"R14",[R15]	"R15",};static char *breg[] = { "AL", "CL", "DL", "BL", "AH", "CH", "DH", "BH" };static char *breg64[] = { "AL", "CL", "DL", "BL", "SPB", "BPB", "SIB", "DIB",	"R8B", "R9B", "R10B", "R11B", "R12B", "R13B", "R14B", "R15B" };static char *sreg[] = { "ES", "CS", "SS", "DS", "FS", "GS" };static voidplocal(Instr *ip){	int ret;	long offset;	Symbol s;	char *reg;	offset = ip->disp;	if (!findsym(ip->addr, CTEXT, &s) || !findlocal(&s, FRAMENAME, &s)) {		bprint(ip, "%lux(SP)", offset);		return;	}	if (s.value > ip->disp) {		ret = getauto(&s, s.value-ip->disp-mach->szaddr, CAUTO, &s);		reg = "(SP)";	} else {		offset -= s.value;		ret = getauto(&s, offset, CPARAM, &s);		reg = "(FP)";	}	if (ret)		bprint(ip, "%s+", s.name);	else		offset = ip->disp;	bprint(ip, "%lux%s", offset, reg);}static intisjmp(Instr *ip){	switch(ip->jumptype){	case Iwds:	case Jbs:	case JUMP:		return 1;	default:		return 0;	}}/* * This is too smart for its own good, but it really is nice * to have accurate translations when debugging, and it * helps us identify which code is different in binaries that * are changed on sources. */static intissymref(Instr *ip, Symbol *s, long w, long val){	Symbol next, tmp;	long isstring, size;	if (isjmp(ip))		return 1;	if (s->class==CTEXT && w==0)		return 1;	if (s->class==CDATA) {		/* use first bss symbol (or "end") rather than edata */		if (s->name[0]=='e' && strcmp(s->name, "edata") == 0){			if((s ->index >= 0 && globalsym(&tmp, s->index+1) && tmp.value==s->value)			|| (s->index > 0 && globalsym(&tmp, s->index-1) && tmp.value==s->value))				*s = tmp;		}		if (w == 0)			return 1;		for (next=*s; next.value==s->value; next=tmp)			if (!globalsym(&tmp, next.index+1))				break;		size = next.value - s->value;		if (w >= size)			return 0;		if (w > size-w)			w = size-w;		/* huge distances are usually wrong except in .string */		isstring = (s->name[0]=='.' && strcmp(s->name, ".string") == 0);		if (w > 8192 && !isstring)			return 0;		/* medium distances are tricky - look for constants */		/* near powers of two */		if ((val&(val-1)) == 0 || (val&(val+1)) == 0)			return 0;		return 1;	}	return 0;}static voidimmediate(Instr *ip, vlong val){	Symbol s;	long w;	if (findsym(val, CANY, &s)) {		/* TO DO */		w = val - s.value;		if (w < 0)			w = -w;		if (issymref(ip, &s, w, val)) {			if (w)				bprint(ip, "%s+%lux(SB)", s.name, w);			else				bprint(ip, "%s(SB)", s.name);			return;		}/*		if (s.class==CDATA && globalsym(&s, s.index+1)) {			w = s.value - val;			if (w < 0)				w = -w;			if (w < 4096) {				bprint(ip, "%s-%lux(SB)", s.name, w);				return;			}		}*/	}	if((ip->rex & REXW) == 0)		bprint(ip, "%lux", (long)val);	else		bprint(ip, "%llux", val);}static voidpea(Instr *ip){	if (ip->mod == 3) {		if (ip->osize == 'B')			bprint(ip, (ip->rex & REXB? breg64: breg)[ip->base]);		else if(ip->rex & REXB)			bprint(ip, "%s%s", ANAME(ip), reg[ip->base+8]);		else			bprint(ip, "%s%s", ANAME(ip), reg[ip->base]);		return;	}	if (ip->segment)		bprint(ip, ip->segment);	if (ip->asize == 'E' && ip->base == SP)		plocal(ip);	else {		if (ip->base < 0)			immediate(ip, ip->disp);		else {			bprint(ip, "%lux", ip->disp);			if(ip->rip)				bprint(ip, "(RIP)");			bprint(ip,"(%s%s)", ANAME(ip), reg[ip->rex&REXB? ip->base+8: ip->base]);		}	}	if (ip->index >= 0)		bprint(ip,"(%s%s*%d)", ANAME(ip), reg[ip->rex&REXX? ip->index+8: ip->index], 1<<ip->ss);}static voidprinstr(Instr *ip, char *fmt){	vlong v;	if (ip->prefix)		bprint(ip, "%s ", ip->prefix);	for (; *fmt && ip->curr < ip->end; fmt++) {		if (*fmt != '%'){			*ip->curr++ = *fmt;			continue;		}		switch(*++fmt){		case '%':			*ip->curr++ = '%';			break;		case 'A':			bprint(ip, "%s", ANAME(ip));			break;		case 'C':			bprint(ip, "CR%d", ip->reg);			break;		case 'D':			if (ip->reg < 4 || ip->reg == 6 || ip->reg == 7)				bprint(ip, "DR%d",ip->reg);			else				bprint(ip, "???");			break;		case 'I':			bprint(ip, "$");			immediate(ip, ip->imm2);			break;		case 'O':			bprint(ip,"%s", ONAME(ip));			break;		case 'i':			bprint(ip, "$");			v = ip->imm;			if(ip->rex & REXW)				v = ip->imm64;			immediate(ip, v);			break;		case 'R':			bprint(ip, "%s%s", ONAME(ip), reg[ip->rex&REXR? ip->reg+8: ip->reg]);			break;		case 'S':			if(ip->osize == 'Q' || ip->osize == 'L' && ip->rex & REXW)				bprint(ip, "Q");			else				bprint(ip, "%c", ip->osize);			break;		case 's':			if(ip->opre == 0 || ip->opre == 0x66)				bprint(ip, "P");			else				bprint(ip, "S");			if(ip->opre == 0xf2 || ip->opre == 0x66)				bprint(ip, "D");			else				bprint(ip, "S");			break;		case 'T':			if (ip->reg == 6 || ip->reg == 7)				bprint(ip, "TR%d",ip->reg);			else				bprint(ip, "???");			break;		case 'W':			if (ip->osize == 'Q' || ip->osize == 'L' && ip->rex & REXW)				bprint(ip, "CDQE");			else if (ip->osize == 'L')				bprint(ip,"CWDE");			else				bprint(ip, "CBW");			break;		case 'd':			bprint(ip,"%ux:%lux",ip->seg,ip->disp);			break;		case 'm':			if (ip->mod == 3 && ip->osize != 'B') {				if(fmt[1] != '*'){					if(ip->opre != 0) {						bprint(ip, "X%d", ip->rex&REXB? ip->base+8: ip->base);						break;					}				} else					fmt++;				bprint(ip, "M%d", ip->base);				break;			}			pea(ip);			break;		case 'e':			pea(ip);			break;		case 'f':			bprint(ip, "F%d", ip->base);			break;		case 'g':			if (ip->reg < 6)				bprint(ip,"%s",sreg[ip->reg]);			else				bprint(ip,"???");			break;		case 'p':			/*			 * signed immediate in the ulong ip->imm.			 */			v = (long)ip->imm;			immediate(ip, v+ip->addr+ip->n);			break;		case 'r':			if (ip->osize == 'B')				bprint(ip,"%s", (ip->rex? breg64: breg)[ip->rex&REXR? ip->reg+8: ip->reg]);			else				bprint(ip, reg[ip->rex&REXR? ip->reg+8: ip->reg]);			break;		case 'w':			if (ip->osize == 'Q' || ip->rex & REXW)				bprint(ip, "CQO");			else if (ip->osize == 'L')				bprint(ip,"CDQ");			else				bprint(ip, "CWD");			break;		case 'M':			if(ip->opre != 0)				bprint(ip, "X%d", ip->rex&REXR? ip->reg+8: ip->reg);			else				bprint(ip, "M%d", ip->reg);			break;		case 'x':			if (ip->mod == 3 && ip->osize != 'B') {				bprint(ip, "X%d", ip->rex&REXB? ip->base+8: ip->base);				break;			}			pea(ip);			break;		case 'X':			bprint(ip, "X%d", ip->rex&REXR? ip->reg+8: ip->reg);			break;		default:			bprint(ip, "%%%c", *fmt);			break;		}	}	*ip->curr = 0;		/* there's always room for 1 byte */}static inti386inst(Map *map, uvlong pc, char modifier, char *buf, int n){	Instr instr;	Optable *op;	USED(modifier);	op = mkinstr(map, &instr, pc);	if (op == 0) {		errstr(buf, n);		return -1;	}	instr.curr = buf;	instr.end = buf+n-1;	prinstr(&instr, op->proto);	return instr.n;}static inti386das(Map *map, uvlong pc, char *buf, int n){	Instr instr;	int i;	if (mkinstr(map, &instr, pc) == 0) {		errstr(buf, n);		return -1;	}	for(i = 0; i < instr.n && n > 2; i++) {		_hexify(buf, instr.mem[i], 1);		buf += 2;		n -= 2;	}	*buf = 0;	return instr.n;}static inti386instlen(Map *map, uvlong pc){	Instr i;	if (mkinstr(map, &i, pc))		return i.n;	return -1;}static inti386foll(Map *map, uvlong pc, Rgetter rget, uvlong *foll){	Instr i;	Optable *op;	ushort s;	uvlong l, addr;	vlong v;	int n;	op = mkinstr(map, &i, pc);	if (!op)		return -1;	n = 0;	switch(i.jumptype) {	case RET:		/* RETURN or LEAVE */	case Iw:		/* RETURN */		if (strcmp(op->proto, "LEAVE") == 0) {			if (geta(map, (*rget)(map, "BP"), &l) < 0)				return -1;		} else if (geta(map, (*rget)(map, mach->sp), &l) < 0)			return -1;		foll[0] = l;		return 1;	case Iwds:		/* pc relative JUMP or CALL*/	case Jbs:		/* pc relative JUMP or CALL */		v = (long)i.imm;		foll[0] = pc+v+i.n;		n = 1;		break;	case PTR:		/* seg:displacement JUMP or CALL */		foll[0] = (i.seg<<4)+i.disp;		return 1;	case JUMP:		/* JUMP or CALL EA */		if(i.mod == 3) {			foll[0] = (*rget)(map, reg[i.rex&REXB? i.base+8: i.base]);			return 1;		}			/* calculate the effective address */		addr = i.disp;		if (i.base >= 0) {			if (geta(map, (*rget)(map, reg[i.rex&REXB? i.base+8: i.base]), &l) < 0)				return -1;			addr += l;		}		if (i.index >= 0) {			if (geta(map, (*rget)(map, reg[i.rex&REXX? i.index+8: i.index]), &l) < 0)				return -1;			addr += l*(1<<i.ss);		}			/* now retrieve a seg:disp value at that address */		if (get2(map, addr, &s) < 0)			/* seg */			return -1;		foll[0] = s<<4;		addr += 2;		if (i.asize == 'L') {			if (geta(map, addr, &l) < 0)		/* disp32 */				return -1;			foll[0] += l;		} else {					/* disp16 */			if (get2(map, addr, &s) < 0)				return -1;			foll[0] += s;		}		return 1;	default:		break;	}			if (strncmp(op->proto,"JMP", 3) == 0 || strncmp(op->proto,"CALL", 4) == 0)		return 1;	foll[n++] = pc+i.n;	return n;}

⌨️ 快捷键说明

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