Ejemplo n.º 1
0
/*
 * Disassemble instruction at 'loc'.  'altfmt' specifies an
 * (optional) alternate format.  Return address of start of
 * next instruction.
 */
db_addr_t
db_disasm(db_addr_t loc, boolean_t altfmt)
{
	int	inst;
	int	size;
	int	short_addr;
	char *	seg;
	struct inst *	ip;
	char *	i_name;
	int	i_size;
	int	i_mode;
	int	regmodrm = 0;
	boolean_t	first;
	int	displ;
	int	prefix;
	int	imm;
	int	imm2;
	int	len;
	struct i_addr	address;
	char	tmpfmt[24];

	get_value_inc(inst, loc, 1, FALSE);
	short_addr = FALSE;
	size = LONG;
	seg = 0;

	/*
	 * Get prefixes
	 */
	prefix = TRUE;
	do {
		switch (inst) {
		    case 0x66:		/* data16 */
			size = WORD;
			break;
		    case 0x67:
			short_addr = TRUE;
			break;
		    case 0x26:
			seg = "%es";
			break;
		    case 0x36:
			seg = "%ss";
			break;
		    case 0x2e:
			seg = "%cs";
			break;
		    case 0x3e:
			seg = "%ds";
			break;
		    case 0x64:
			seg = "%fs";
			break;
		    case 0x65:
			seg = "%gs";
			break;
		    case 0xf0:
			db_printf("lock ");
			break;
		    case 0xf2:
			db_printf("repne ");
			break;
		    case 0xf3:
			db_printf("repe ");	/* XXX repe VS rep */
			break;
		    default:
			prefix = FALSE;
			break;
		}
		if (prefix)
			get_value_inc(inst, loc, 1, FALSE);
	} while (prefix);

	if (inst >= 0xd8 && inst <= 0xdf) {
		loc = db_disasm_esc(loc, inst, short_addr, size, seg);
		db_printf("\n");
		return (loc);
	}

	if (inst == 0x0f) {
		get_value_inc(inst, loc, 1, FALSE);
		ip = db_inst_0f[inst>>4];
		if (ip == 0)
			ip = &db_bad_inst;
		else
			ip = &ip[inst&0xf];
	} else {
Ejemplo n.º 2
0
/*
 * Disassemble instruction at 'loc'.  'altfmt' specifies an
 * (optional) alternate format.  Return address of start of
 * next instruction.
 */
db_addr_t
db_disasm(db_addr_t loc, boolean_t altfmt)
{
	int	inst;
	int	size;
	int	short_addr;
	char *	seg;
	struct inst *	ip;
	char *	i_name;
	int	i_size;
	int	i_mode;
	int	regmodrm = 0;
	boolean_t	first;
	int	displ;
	int	prefix;
	long	imm;
	int	imm2;
	int	len;
	int	rex = 0;
	int	segovr_grp;
	int	repe, repne;
	struct i_addr	address;
	db_addr_t	loc_orig = loc;
	char	tmpfmt[28];

	get_value_inc(inst, loc, 1, FALSE);
	short_addr = FALSE;
	size = LONG;
	seg = 0;
	segovr_grp = 0;
	repe = 0;
	repne = 0;

	/*
	 * Get prefixes
	 */
	prefix = TRUE;
	do {
		switch (inst) {
		case 0x66:		/* data16 */
			size = WORD;
			break;
		case 0x67:
			short_addr = TRUE;
			break;
		case 0x26:
			segovr_grp++;
			db_printf(" <segment override prefix ignored>");
			break;
		case 0x36:
			db_printf(" <segment override prefix ignored>");
			segovr_grp++;
			break;
		case 0x2e:
			db_printf(" <segment override prefix ignored>");
			segovr_grp++;
			break;
		case 0x3e:
			db_printf(" <segment override prefix ignored>");
			segovr_grp++;
			break;
		case 0x64:
			segovr_grp++;
			seg = "%fs";
			break;
		case 0x65:
			segovr_grp++;
			seg = "%gs";
			break;
		case 0xf0:
			db_printf("lock ");
			break;
		case 0xf2:
			repne++;
			break;
		case 0xf3:
			repe++;
			break;
		default:
			prefix = FALSE;
			break;
		}
		if (prefix)
			get_value_inc(inst, loc, 1, FALSE);
	} while (prefix);
	if (segovr_grp > 1)
		seg = "<bad segment override prefix combination> ";
	if (repe > 0 && repne > 0)
		db_printf("<bad repeat prefex combination> ");
	else if (repe > 0)
		db_printf("repe ");	/* XXX "rep" if not CMPSx or SCASx */
	else if (repne > 0)
		db_printf("repne ");

	if (inst >= 0x40 && inst <= 0x4f) {
		// rex page 14
		rex = inst;
		if (REX_W(rex))
			size = QUAD;
		get_value_inc(inst, loc, 1, FALSE);
	}

	if (inst >= 0xd8 && inst <= 0xdf) {
		loc = db_disasm_esc(loc, inst, short_addr, size, rex, seg);
		goto done;
	}

	if (inst == 0x0f) {
		get_value_inc(inst, loc, 1, FALSE);
		if (inst == 0x0f) {
			loc = db_disasm_3dnow(loc, short_addr, size, rex, seg);
			goto done;
		}
		ip = db_inst_0f[inst>>4];
		if (ip == 0)
			ip = &db_bad_inst;
		else
			ip = &ip[inst&0xf];
	} else {
Ejemplo n.º 3
0
/*
 * Disassemble instruction at 'loc'.  'altfmt' specifies an
 * (optional) alternate format.  Return address of start of
 * next instruction.
 */
db_addr_t
db_disasm(
    db_addr_t	loc,
    bool	altfmt)
{
	int	inst;
	int	size;
	int	short_addr;
	const char *	seg;
	const struct inst *	ip;
	const char *	i_name;
	int	i_size;
	int	i_mode;
	int	regmodrm = 0;
	bool	first;
	int	displ;
	int	prefix;
	int	imm;
	int	imm2;
	int	len;
	struct i_addr	address;

#ifdef _KERNEL
	pt_entry_t *pte, *pde;

	/*
	 * Don't try to disassemble the location if the mapping is invalid.
	 * If we do, we'll fault, and end up debugging the debugger!
	 * in the case of largepages, "pte" is really the pde and "pde" is
	 * really the entry for the pdp itself.
	 */
	if ((vaddr_t)loc >= VM_MIN_KERNEL_ADDRESS)
		pte = kvtopte((vaddr_t)loc);
	else
		pte = vtopte((vaddr_t)loc);
	pde = vtopte((vaddr_t)pte);
	if ((*pde & PG_V) == 0 || (*pte & PG_V) == 0) {
		db_printf("invalid address\n");
		return (loc);
	}
#endif

	get_value_inc(inst, loc, 1, false);
	short_addr = false;
	size = LONG;
	seg = 0;

	/*
	 * Get prefixes
	 */
	prefix = true;
	do {
		switch (inst) {
		    case 0x66:		/* data16 */
			size = WORD;
			break;
		    case 0x67:
			short_addr = true;
			break;
		    case 0x26:
			seg = "%es";
			break;
		    case 0x36:
			seg = "%ss";
			break;
		    case 0x2e:
			seg = "%cs";
			break;
		    case 0x3e:
			seg = "%ds";
			break;
		    case 0x64:
			seg = "%fs";
			break;
		    case 0x65:
			seg = "%gs";
			break;
		    case 0xf0:
			db_printf("lock ");
			break;
		    case 0xf2:
			db_printf("repne ");
			break;
		    case 0xf3:
			db_printf("repe ");	/* XXX repe VS rep */
			break;
		    default:
			prefix = false;
			break;
		}
		if (prefix)
			get_value_inc(inst, loc, 1, false);
	} while (prefix);

	if (inst >= 0xd8 && inst <= 0xdf) {
		loc = db_disasm_esc(loc, inst, short_addr, size, seg);
		db_printf("\n");
		return (loc);
	}

	if (inst == 0x0f) {
		get_value_inc(inst, loc, 1, false);
		ip = db_inst_0f[inst>>4];
		if (ip == 0)
			ip = &db_bad_inst;
		else
			ip = &ip[inst&0xf];
	} else {