コード例 #1
0
ファイル: strbuf.c プロジェクト: 13572293130/radare2
R_API bool r_strbuf_setf(RStrBuf *sb, const char *fmt, ...) {
	int rc;
	bool ret;
	char string[1024];
	va_list ap;

	if (!sb || !fmt)
		return false;
	va_start (ap, fmt);
	rc = vsnprintf (string, sizeof (string), fmt, ap);
	if (rc >= sizeof (string)) {
		char *p = malloc (rc + 2);
		if (!p) {
			va_end (ap);
			return false;
		}
		vsnprintf (p, rc + 1, fmt, ap);
		ret = r_strbuf_set (sb, p);
		free (p);
	} else {
		ret = r_strbuf_set (sb, string);
	}
	va_end (ap);
	return ret;
}
コード例 #2
0
ファイル: asm_arc.c プロジェクト: moebiuz/radare2
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
	static struct disassemble_info disasm_obj;
	if (len < 2) {
		return -1;
	}
	buf_global = r_strbuf_get (&op->buf_asm);
	Offset = a->pc;
	if (len > sizeof (bytes)) {
		len = sizeof (bytes);
	}
	memcpy (bytes, buf, len); // TODO handle compact
	buf_len = len;
	/* prepare disassembler */
	memset (&disasm_obj,'\0', sizeof (struct disassemble_info));
	disasm_obj.buffer = bytes;
	disasm_obj.buffer_length = len;
	disasm_obj.read_memory_func = &arc_buffer_read_memory;
	disasm_obj.symbol_at_address_func = &symbol_at_address;
	disasm_obj.memory_error_func = &memory_error_func;
	disasm_obj.print_address_func = &print_address;
	disasm_obj.endian = !a->big_endian;
	disasm_obj.fprintf_func = &buf_fprintf;
	disasm_obj.stream = stdout;
	disasm_obj.mach = 0;
	r_strbuf_set (&op->buf_asm, "");
	if (a->bits == 16) {
		op->size = ARCompact_decodeInstr ((bfd_vma)Offset, &disasm_obj);
	} else {
		op->size = ARCTangent_decodeInstr ((bfd_vma)Offset, &disasm_obj);
	}
	if (op->size == -1) {
		r_strbuf_set (&op->buf_asm, "(data)");
	}
	return op->size;
}
コード例 #3
0
ファイル: anal_bf.c プロジェクト: yd0str/radare2
static int bf_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
	ut64 dst = 0LL;
	if (op == NULL)
		return 1;
	/* Ayeeee! What's inside op? Do we have an initialized RAnalOp? Are we going to have a leak here? :-( */
	memset (op, 0, sizeof (RAnalOp)); /* We need to refactorize this. Something like r_anal_op_init would be more appropiate */
	r_strbuf_init (&op->esil);
	op->size = 1;
	switch (buf[0]) {
	case '[': op->type = R_ANAL_OP_TYPE_CJMP;
		  op->fail = addr+1;
		  {
			 const ut8 *p = buf + 1;
			 int lev = 0, i = 1;
			 while (*p && i<len) {
				 if (*p == '[')
					 lev++;
				 if (*p == ']') {
					 lev--;
					 if (lev==-1) {
						 dst = addr + (size_t)(p-buf);
						 op->jump = dst;
						 r_strbuf_setf (&op->esil,
							"if (!*ptr) pc=0x%"PFMT64x, dst);
						 break;
					 }
				 }
				 p++;
				i++;
			 }
		  }
	// ?1[ptr],pc=${NEW_PC
	break;
	case ']': op->type = R_ANAL_OP_TYPE_UJMP; break;
	case '>': op->type = R_ANAL_OP_TYPE_ADD;
		r_strbuf_set (&op->esil, "ptr++");
		break;
	case '<': op->type = R_ANAL_OP_TYPE_SUB;
		r_strbuf_set (&op->esil, "ptr--");
		break;
	case '+': op->type = R_ANAL_OP_TYPE_ADD;
		r_strbuf_set (&op->esil, "*ptr++");
		break;
	case '-': op->type = R_ANAL_OP_TYPE_SUB;
		r_strbuf_set (&op->esil, "*ptr--");
		break;
	case '.': op->type = R_ANAL_OP_TYPE_STORE;
		r_strbuf_set (&op->esil, "=*ptr");
		break;
	case ',': op->type = R_ANAL_OP_TYPE_LOAD; break;
	case 0x00:
	case 0xff:
		op->type = R_ANAL_OP_TYPE_TRAP; break;
	default: op->type = R_ANAL_OP_TYPE_NOP; break;
	}
	return op->size;
}
コード例 #4
0
ファイル: asm_lanai_gnu.c プロジェクト: aronsky/radare2
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
	struct disassemble_info disasm_obj;
	if (len < 4) {
		return -1;
	}
	buf_global = &op->buf_asm;
	Offset = a->pc;
	memcpy (bytes, buf, 4); // TODO handle thumb

	/* prepare disassembler */
	memset (&disasm_obj, '\0', sizeof (struct disassemble_info));
	disasm_obj.disassembler_options = (a->bits==64)? "64": "";
	disasm_obj.buffer = bytes;
	disasm_obj.read_memory_func = &lanai_buffer_read_memory;
	disasm_obj.symbol_at_address_func = &symbol_at_address;
	disasm_obj.memory_error_func = &memory_error_func;
	disasm_obj.print_address_func = &generic_print_address_func;
	disasm_obj.endian = BFD_ENDIAN_BIG;
	disasm_obj.fprintf_func = &generic_fprintf_func;
	disasm_obj.stream = stdout;

	op->size = print_insn_lanai ((bfd_vma)Offset, &disasm_obj);
	if (op->size == -1) {
		r_strbuf_set (&op->buf_asm, "(data)");
	}
	return op->size;
}
コード例 #5
0
ファイル: asm_mips_gnu.c プロジェクト: jroimartin/radare2
static int disassemble(struct r_asm_t *a, struct r_asm_op_t *op, const ut8 *buf, int len) {
	static struct disassemble_info disasm_obj;
	if (len < 4) {
		return -1;
	}
	buf_global = r_strbuf_get (&op->buf_asm);
	Offset = a->pc;
	memcpy (bytes, buf, 4); // TODO handle thumb

	/* prepare disassembler */
	memset (&disasm_obj,'\0', sizeof (struct disassemble_info));
	mips_mode = a->bits;
	disasm_obj.arch = CPU_LOONGSON_2F;
	disasm_obj.buffer = bytes;
	disasm_obj.read_memory_func = &mips_buffer_read_memory;
	disasm_obj.symbol_at_address_func = &symbol_at_address;
	disasm_obj.memory_error_func = &memory_error_func;
	disasm_obj.print_address_func = &print_address;
	disasm_obj.buffer_vma = Offset;
	disasm_obj.buffer_length = 4;
	disasm_obj.endian = !a->big_endian;
	disasm_obj.fprintf_func = &buf_fprintf;
	disasm_obj.stream = stdout;

	op->size = (disasm_obj.endian == BFD_ENDIAN_LITTLE)
		? print_insn_little_mips ((bfd_vma)Offset, &disasm_obj)
		: print_insn_big_mips ((bfd_vma)Offset, &disasm_obj);
	if (op->size == -1) {
		r_strbuf_set (&op->buf_asm, "(data)");
	}
	return op->size;
}
コード例 #6
0
ファイル: op.c プロジェクト: montekki/radare2
/* apply hint to op, return the number of hints applied */
R_API int r_anal_op_hint(RAnalOp *op, RAnalHint *hint) {
	int changes = 0;
	if (hint) {
		if (hint->jump != UT64_MAX) {
			changes++;
			op->jump = hint->jump;
		}
		if (hint->fail != UT64_MAX) {
			changes++;
			op->fail = hint->fail;
		}
		if (hint->opcode) {
			changes++;
			/* XXX: this is not correct */
			free (op->mnemonic);
			op->mnemonic = strdup (hint->opcode);
		}
		if (hint->esil) {
			changes++;
			r_strbuf_set (&op->esil, hint->esil);
		}
		if (hint->size) {
			changes++;
			op->size = hint->size;
		}
	}
	return changes;
}
コード例 #7
0
ファイル: strbuf.c プロジェクト: jdukes/radare2
R_API int r_strbuf_setf(RStrBuf *sb, const char *fmt, ...) {
    int ret;
    char string[4096];
    va_list ap;

    va_start (ap, fmt);
    ret = vsnprintf (string, sizeof (string), fmt, ap);
    if (ret>=sizeof (string)) {
        char *p = malloc (ret+2);
        if (!p) return R_FALSE;
        vsnprintf (p, ret+1, fmt, ap);
        ret = r_strbuf_set (sb, p);
        free (p);
    } else ret = r_strbuf_set (sb, string);
    va_end (ap);
    return ret;
}
コード例 #8
0
ファイル: asm_mcs96.c プロジェクト: aronsky/radare2
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
	if (len > 1 && !memcmp (buf, "\xff\xff", 2)) {
		return -1;
	}
	r_strbuf_set (&op->buf_asm, mcs96_op[buf[0]].ins);
	op->size = mcs96_len (buf[0]);
	return op->size;
}
コード例 #9
0
ファイル: asm_lm32.c プロジェクト: jroimartin/radare2
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
	RAsmLm32Instruction instr = {0};
	instr.value = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3];
	instr.addr = a->pc;
	if (r_asm_lm32_decode (&instr)) {
		r_strbuf_set (&op->buf_asm, "invalid");
		a->invhex = 1;
		return -1;
	}
	//op->buf_asm is 256 chars long, which is more than sufficient
	if (r_asm_lm32_stringify (&instr, r_strbuf_get (&op->buf_asm))) {
		r_strbuf_set (&op->buf_asm, "invalid");
		a->invhex = 1;
		return -1;
	}
	return 4;
}
コード例 #10
0
ファイル: asm_dcpu16.c プロジェクト: jroimartin/radare2
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
	char buf_asm[32];
	if (len < 2) {
		return -1; // at least 2 bytes!
	}
	op->size = dcpu16_disasm (buf_asm, (const ut16*)buf, len, NULL);
	r_strbuf_set (&op->buf_asm, (op->size > 0) ? buf_asm: "(data)");
	return op->size;
}
コード例 #11
0
ファイル: asm_lh5801.c プロジェクト: jroimartin/radare2
static int disassemble(RAsm *as, RAsmOp *op, const ut8 *buf, int len) {
	struct lh5801_insn insn;
	if (!op) {
		return 0;
	}
	int consumed = lh5801_decode (&insn, buf, len);
	if (consumed == -1 || consumed == 0) {
		r_strbuf_set (&op->buf_asm, "invalid");
		op->size = 1;
		return 0;
	}
	char buf_asm[128] = {0};
	lh5801_print_insn (buf_asm, sizeof (buf_asm), &insn);
	r_strbuf_set (&op->buf_asm, buf_asm);
	op->size = consumed;
	//op->payload = lh5801_insn_descs[insn.type].format & 3;
	// ^ MAYBE?
	return op->size;
}
コード例 #12
0
ファイル: anal.c プロジェクト: radare/radare2-bindings
static int py_anal(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len, RAnalOpMask mask) {
	PyObject *tmpreg = NULL;
	int size = 0;
	int seize = -1;
	int i = 0;
	if (!op) return -1;
	if (py_anal_cb) {
		memset(op, 0, sizeof (RAnalOp));
		// anal(addr, buf) - returns size + dictionary (structure) for RAnalOp
		Py_buffer pybuf = {
			.buf = (void *) buf, // Warning: const is lost when casting
			.len = len,
			.readonly = 1,
			.ndim = 1,
			.itemsize = 1,
		};
		PyObject *memview = PyMemoryView_FromBuffer (&pybuf);
		PyObject *arglist = Py_BuildValue ("(NK)", memview, addr);
		PyObject *result = PyEval_CallObject (py_anal_cb, arglist);
		if (result && PyList_Check (result)) {
			PyObject *len = PyList_GetItem (result, 0);
			PyObject *dict = PyList_GetItem (result, 1);
			if (dict && PyDict_Check (dict)) {
				seize = PyNumber_AsSsize_t (len, NULL);
				op->type = getI (dict, "type");
				op->cycles = getI (dict, "cycles");
				op->size = seize;
				op->addr = getI (dict, "addr");
				op->jump = getI (dict, "jump");
				op->fail = getI (dict, "fail");
				op->stackop = getI (dict, "stackop");
				op->stackptr = getI (dict, "stackptr");
				op->ptr = getI (dict, "ptr");
				op->eob = getB (dict, "eob");
				// Loading 'src' and 'dst' values
				// SRC is is a list of 3 elements
				PyObject *tmpsrc = getO (dict, "src");
				if (tmpsrc && PyList_Check (tmpsrc)) {
					for (i = 0; i < 3; i++) {
						PyObject *tmplst = PyList_GetItem (tmpsrc, i);
						// Read value and underlying regs
						READ_VAL(tmplst, op->src[i], tmpreg)
					}
				}
				PyObject *tmpdst = getO (dict, "dst");
				// Read value and underlying regs
				READ_VAL(tmpdst, op->dst, tmpreg)
				// Loading 'var' value if presented
				r_strbuf_set (&op->esil, getS (dict, "esil"));
				// TODO: Add opex support here
				Py_DECREF (dict);
			}
			Py_DECREF (result);
		} else {
コード例 #13
0
ファイル: op.c プロジェクト: commiebstrd/radare2
R_API RAnalOp *r_anal_op_copy (RAnalOp *op) {
	RAnalOp *nop = R_NEW (RAnalOp);
	*nop = *op;
	nop->mnemonic = strdup (op->mnemonic);
	nop->src[0] = r_anal_value_copy (op->src[0]);
	nop->src[1] = r_anal_value_copy (op->src[1]);
	nop->src[2] = r_anal_value_copy (op->src[2]);
	nop->dst = r_anal_value_copy (op->dst);
	r_strbuf_init (&nop->esil);
	r_strbuf_set (&nop->esil, r_strbuf_get (&op->esil));
	return nop;
}
コード例 #14
0
ファイル: op.c プロジェクト: aronsky/radare2
R_API int r_asm_op_set_hex(RAsmOp *op, const char *str) {
	r_strbuf_set (&op->buf_hex, str);
	ut8 *bin = (ut8*)strdup (str);
	if (bin) {
		int len = r_hex_str2bin (str, bin);
		if (len > 0) {
			r_strbuf_setbin (&op->buf, bin, len);
		}
		free (bin);
		return len;
	}
	return 0;
}
コード例 #15
0
ファイル: asm_cris_gnu.c プロジェクト: montekki/radare2
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
	struct disassemble_info disasm_obj;
	int mode = 2;
	if (len < 4) {
		return -1;
	}
	buf_global = &op->buf_asm;
	Offset = a->pc;
	memcpy (bytes, buf, R_MIN (len, 8)); // TODO handle thumb

	/* prepare disassembler */
	memset (&disasm_obj, '\0', sizeof (struct disassemble_info));
	disasm_obj.disassembler_options=(a->bits==64)?"64":"";
	disasm_obj.buffer = bytes;
	disasm_obj.read_memory_func = &cris_buffer_read_memory;
	disasm_obj.symbol_at_address_func = &symbol_at_address;
	disasm_obj.memory_error_func = &memory_error_func;
	disasm_obj.print_address_func = &generic_print_address_func;
	disasm_obj.endian = !a->big_endian;
	disasm_obj.fprintf_func = &generic_fprintf_func;
	disasm_obj.stream = stdout;

	if (a->cpu && *a->cpu) {
		if (!strcmp (a->cpu, "v10+v32")) {
			mode = 1;
		} else if (!strcmp (a->cpu, "v10")) {
			mode = 0;
		} else {
			mode = 2;
		}
	} else {
		mode = 2;
	}
	(void)cris_parse_disassembler_options (&disasm_obj, mode);
	if (a->syntax == R_ASM_SYNTAX_ATT) {
		op->size = print_insn_crisv10_v32_with_register_prefix (
			(bfd_vma)Offset, &disasm_obj);
	} else {
		op->size = print_insn_crisv10_v32_without_register_prefix (
			(bfd_vma)Offset, &disasm_obj);
	}
	if (op->size == -1) {
		r_strbuf_set (&op->buf_asm, "(data)");
	}
	return op->size;
}
コード例 #16
0
ファイル: op.c プロジェクト: m-emerson/radare2
R_API RAnalOp *r_anal_op_copy (RAnalOp *op) {
	RAnalOp *nop = R_NEW0 (RAnalOp);
	if (!nop) return NULL;
	*nop = *op;
	if (op->mnemonic) {
		nop->mnemonic = strdup (op->mnemonic);
		if (!nop->mnemonic) {
			free (nop);
			return NULL;
		}
	} else {
		nop->mnemonic = NULL;
	}
	nop->src[0] = r_anal_value_copy (op->src[0]);
	nop->src[1] = r_anal_value_copy (op->src[1]);
	nop->src[2] = r_anal_value_copy (op->src[2]);
	nop->dst = r_anal_value_copy (op->dst);
	r_strbuf_init (&nop->esil);
	r_strbuf_set (&nop->esil, r_strbuf_get (&op->esil));
	return nop;
}
コード例 #17
0
ファイル: anal_8051.c プロジェクト: flatz/radare2
static void analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf) {
	r_strbuf_init (&op->esil);
	r_strbuf_set (&op->esil, "");

	switch (buf[0]) {
	// Irregulars sorted by lower nibble
	case 0x00: /* nop */
		emit (",");
		break;

	case 0x10: /* jbc bit, offset */
		k (BIT_R "?{," BIT_MASK XI(BIT, "&") JMP ",}");
		break;
	case 0x20: /* jb bit, offset */
		k (BIT_R CJMP);
		break;
	case 0x30: /* jnb bit, offset */
		k (BIT_R "!," CJMP);
		break;
	case 0x40: /* jc offset */
		h ("c,1,&," CJMP);
		break;
	case 0x50: /* jnc offset */
		h ("c,1,&,!," CJMP );
		break;
	case 0x60: /* jz offset */
		h ("a,0,==," CJMP);
		break;
	case 0x70: /* jnz offset */
		h ("a,0,==,!," CJMP);
		break;

	case 0x11: case 0x31: case 0x51: case 0x71:
	case 0x91: case 0xB1: case 0xD1: case 0xF1: /* acall addr11 */
	case 0x12: /* lcall addr16 */
		j (CALL);
		/* fall through */
	case 0x01: case 0x21: case 0x41: case 0x61:
	case 0x81: case 0xA1: case 0xC1: case 0xE1: /* ajmp addr11 */	
	case 0x02: /* ljmp addr16 */
	case 0x80: /* sjmp offset */
		j (JMP);
		break;

	case 0x22: /* ret */
	case 0x32: /* reti */
		emitf (POP2 "pc,=");
		break;

	case 0x03: /* rr a */
		emit ("1,a,0x101,*,>>,a,=," FLAG_P);
		break;
	case 0x04: /* inc a */
		h (XI(A, "++") FLAG_P);
		break;
	case 0x05: /* inc direct */
		h (XI(IB1, "++"));
		break;
	case 0x06: case 0x07: /* inc @Ri */
		j (XI(RI, "++"));
		break;
	case 0x08: case 0x09: case 0x0A: case 0x0B:
	case 0x0C: case 0x0D: case 0x0E: case 0x0F: /* dec @Rn */
		h (XI(RN, "++"));
		break;
	case 0x13: /* rrc a */
		emit ("7,c,<<,1,a,&,c,=,0x7f,1,a,>>,&,+,a,=," FLAG_P);
		break;
	case 0x14: /* dec a */
		h (XI(A, "--") FLAG_P);
		break;
	case 0x15: /* dec direct */
		h (XI(IB1, "--"));
		break;
	case 0x16: case 0x17: /* dec @Ri */
		j (XI(RI, "--"));
		break;
	case 0x18: case 0x19: case 0x1A: case 0x1B:
	case 0x1C: case 0x1D: case 0x1E: case 0x1F: /* dec @Rn */
		h (XI(RN, "--"));
		break;
	case 0x23: /* rl a */
		h ("7,a,0x101,*,>>,a,=," FLAG_P);
		break;
	TEMPLATE_ALU (0x20, "+", FLAG_C FLAG_AC FLAG_OV FLAG_P) /* 0x24..0x2f add a,.. */
	case 0x33: /* rlc a */
		h ("c,1,&,a,a,+=,$c7,c,=,a,+=," FLAG_P);
		break;
	TEMPLATE_ALU_C (0x30, "+", FLAG_C FLAG_AC FLAG_OV FLAG_P) /* 0x34..0x2f addc a,.. */
	case 0x42: /* orl direct, a */
		h (XR(A) XI(IB1, "|"));
		break;
	case 0x43: /* orl direct, imm */
		h (XR(L2) XI(IB1, "|"));
		break;
	TEMPLATE_ALU (0x40, "|", FLAG_P) /* 0x44..0x4f orl a,.. */
	case 0x52: /* anl direct, a */
		h (XR(A) XI(IB1, "&"));
		break;
	case 0x53: /* anl direct, imm */
		h (XR(L2) XI(IB1, "&"));
		break;
	TEMPLATE_ALU (0x50, "&", FLAG_P) /* 0x54..0x5f anl a,.. */
	case 0x62: /* xrl direct, a */
		h (XR(A) XI(IB1, "^"));
		break;
	case 0x63: /* xrl direct, imm */
		h (XR(L2) XI(IB1, "^"));
		break;
	TEMPLATE_ALU (0x60, "^", FLAG_P) /* 0x64..0x6f xrl a,.. */
	case 0x72: /* orl C, bit */
		k (BIT_R XI(C, "|"));
		break;
	case 0x73: /* jmp @a+dptr */
		emit ("dptr,a,+,pc,="); break;
	case 0x74: /* mov a, imm */
		h (XR(L1) XW(A) FLAG_P);
		break;
	case 0x75: /* mov direct, imm */
		h (XR(L2) XW(IB1));
		break;
	case 0x76: case 0x77: /* mov @Ri, imm */
		j (XR(L1) XW(RI));
		break;
	case 0x78: case 0x79: case 0x7A: case 0x7B:
	case 0x7C: case 0x7D: case 0x7E: case 0x7F: /* mov Rn, imm */
		h (XR(L1) XW(RN));
		break;
	case 0x82: /* anl C, bit */
		k (BIT_R XI(C, "&"));
		break;
	case 0x83: /* movc a, @a+pc */
		emit ("a,pc,--,+,[1]," XW(A) FLAG_P);
		break;
	case 0x84: /* div ab */
		emit ("b,!,OV,=,0,a,b,a,/=,a,b,*,-,-,b,=,0,c,=");
		break;
	case 0x85: /* mov direct, direct */
		h (XR(IB1) XW(IB2));
		break;
	case 0x86: case 0x87: /* mov direct, @Ri */
		j (XR(RI) XW(IB1));
		break;
	case 0x88: case 0x89: case 0x8A: case 0x8B:
	case 0x8C: case 0x8D: case 0x8E: case 0x8F: /* mov direct, Rn */
		h (XR(RN) XW(IB1));
		break;
	case 0x90: /* mov dptr, imm */
		h (XR(L16) XW(DP));
		break;
	case 0x92: /* mov bit, C */
		k (BIT_C BIT_MASK XR(BIT) "&,|," XW(BIT));
		break;
	case 0x93: /* movc a, @a+dptr */
		h ("a,dptr,+,[1]," XW(A) FLAG_P);
		break;
	TEMPLATE_ALU_C (0x90, "-", FLAG_B FLAG_AB FLAG_OB FLAG_P) /* 0x94..0x9f subb a,.. */
	case 0xA0: /* orl C, /bit */
		k (BIT_R "!," XI(C, "|"));
		break;
	case 0xA2: /* mov C, bit */
		k (BIT_R XW(C));
		break;
	case 0xA3: /* inc dptr */
		h (XI(DP, "++"));
		break;
	case 0xA4: /* mul ab */
		emit ("8,a,b,*,NUM,>>,NUM,!,!,ov,=,b,=,a,=,0,c,=");
		break;
	case 0xA5: /* "reserved" */
		emit ("0,trap");
		break;
	case 0xA6: case 0xA7: /* mov @Ri, direct */
		j (XR(IB1) XW(RI));
		break;
	case 0xA8: case 0xA9: case 0xAA: case 0xAB:
	case 0xAC: case 0xAD: case 0xAE: case 0xAF: /* mov Rn, direct */
		h (XR(IB1) XW(RN));
		break;
	case 0xB0: /* anl C, /bit */
		k (BIT_R "!," XI(C, "&"));
		break;
	case 0xB2: /* cpl bit */
		k (BIT_SET XI(BIT, "^"));
		break;
	case 0xB3: /* cpl C */
		h ("1," XI(C, "^"));
		break;
	case 0xB4: /* cjne a, imm, offset */
		h (XR(L1) XR(A) "-," CJMP);
		break;
	case 0xB5: /* cjne a, direct, offset */
		h (XR(IB1) XR(A) "-," CJMP);
		break;
	case 0xB6: case 0xB7: /* cjne @ri, imm, offset */
		j (XR(L1) XR(RI) "-," CJMP);
		break;
	case 0xB8: case 0xB9: case 0xBA: case 0xBB:
	case 0xBC: case 0xBD: case 0xBE: case 0xBF: /* cjne Rn, imm, offset */
		h (XR(L1) XR(RN) "-," CJMP);
		break;
	case 0xC0: /* push direct */
		h (XR(IB1) PUSH1);
		break;
	case 0xC2: /* clr bit */
		k (BIT_MASK XI(BIT, "&"));
		break;
	case 0xC3: /* clr C */
		h ("0," XW(C));
		break;
	case 0xC4: /* swap a */
		h ("0xff,4,a,0x101,*,>>,&," XW(A) FLAG_P);
		break;
	case 0xC5: /* xch a, direct */
		h (XR(A) "0,+," XR(IB1) XW(A) XW(IB1) FLAG_P);
		break;
	case 0xC6: case 0xC7: /* xch a, @Ri */ 
		j (XR(A) "0,+," XR(RI) XW(A) XW(RI) FLAG_P);
		break;
	case 0xC8: case 0xC9: case 0xCA: case 0xCB:
	case 0xCC: case 0xCD: case 0xCE: case 0xCF: /* xch a, Rn */
		h (XR(A) "0,+," XR(RN) XW(A) XW(RN) FLAG_P);
		break;
	case 0xD0: /* pop direct */
		h (POP1 XW(IB1));
		break;
	case 0xD2: /* setb bit */
		k (BIT_SET XI(BIT, "|"));
		break;
	case 0xD3: /* setb C */
		h ("1," XW(C));
		break;
	case 0xD4: /* da a */
		// BCD adjust after add:
		// if (lower nibble > 9) or (AC == 1) add 6
		// if (higher nibble > 9) or (C == 1) add 0x60
		// carry |= carry caused by this operation
		emit ("a,0x0f,&,9,<,ac,|,?{,6,a,+=,$c7,c,|=,},a,0xf0,&,0x90,<,c,|,?{,0x60,a,+=,$c7,c,|=,}," FLAG_P);
		break;
	case 0xD5: /* djnz direct, offset */
		h (XI(IB1, "--") XR(IB1) "0,==,!," CJMP);
		break;
	case 0xD6:
	case 0xD7: /* xchd a, @Ri*/
		j (XR(A) "0xf0,&," XR(RI) "0x0f,&,|," XR(RI) "0xf0,&," XR(A) "0x0f,&,|," XW(RI) XW(A) FLAG_P);
		break;
	case 0xD8: case 0xD9: case 0xDA: case 0xDB:
	case 0xDC: case 0xDD: case 0xDE: case 0xDF: /* djnz Rn, offset */
		h (XI(RN, "--") XR(RN) "0,==,!," CJMP);
		break;
	case 0xE0: /* movx a, @dptr */
		h (XR(DPX) XW(A) FLAG_P);
		break;
	case 0xE2: case 0xE3: /* movx a, @Ri */
		j (XR(R0X) XW(A) FLAG_P);
		break;
	case 0xE4: /* clr a */
		emit ("0," XW(A) FLAG_P);
		break;
	case 0xE5: /* mov a, direct */
		h (XR(IB1) XW(A) FLAG_P);
		break;
	case 0xE6: case 0xE7: /* mov a, @Ri */
		j (XR(RI) XW(A) FLAG_P);
		break;
	case 0xE8: case 0xE9: case 0xEA: case 0xEB:
	case 0xEC: case 0xED: case 0xEE: case 0xEF: /* mov a, Rn */
		h (XR(RN) XW(A) FLAG_P);
		break;
	case 0xF0: /* movx @dptr, a */
		h (XR(A) XW(DPX));
		break;
	case 0xF2: case 0xF3: /* movx @Ri, a */
		j (XR(A) XW(R0X));
		break;
	case 0xF4: /* cpl a */
		h ("255," XI(A, "^") FLAG_P);
		break;
	case 0xF5: /* mov direct, a */
		h (XR(A) XW(IB1));
		break;
	case 0xF6: case 0xF7: /* mov  @Ri, a */
		j (XR(A) XW(RI));
		break;
	case 0xF8: case 0xF9: case 0xFA: case 0xFB:
	case 0xFC: case 0xFD: case 0xFE: case 0xFF: /* mov Rn, a */
		h (XR(A) XW(RN));
		break;
	default:
		break;
	}
}
コード例 #18
0
ファイル: anal_arm_cs.c プロジェクト: AnwarMohamed/radare2
static int analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len, csh *handle, cs_insn *insn) {
	int i;
	char str[32][32];
	r_strbuf_init (&op->esil);
	r_strbuf_set (&op->esil, "");
	switch (insn->detail->arm.cc) {
	case ARM_CC_AL:
		// no condition
		break;
	case ARM_CC_EQ:
		r_strbuf_setf (&op->esil, "zf,0,?,");
		break;
	case ARM_CC_NE:
		r_strbuf_setf (&op->esil, "zf,!,0,?,");
		break;
	case ARM_CC_GT:
	case ARM_CC_LE:
		break;
	default:
		break;
	}
	// TODO: PREFIX CONDITIONAL
	switch (insn->id) {
	case ARM_INS_PUSH:
		// TODO: increment stack
	case ARM_INS_STM:
		for (i=1; i<insn->detail->arm.op_count; i++) {
			r_strbuf_appendf (&op->esil, "%s,%s,%d,+,=[4],",
				REG (i), ARG (0), i*4);
		}
		break;
	case ARM_INS_POP:
		// TODO: decrement stack
	case ARM_INS_LDM:
		for (i=1; i<insn->detail->arm.op_count; i++) {
			r_strbuf_appendf (&op->esil, "%s,%d,+,[4],%s,=",
				ARG (0), i*4, REG (i));
		}
		break;
	case ARM_INS_CMP:
		r_strbuf_appendf (&op->esil, "%s,%s,==", ARG(1), ARG(0));
		break;
	case ARM_INS_LSL:
		// suffix 'S' forces conditional flag to be updated
		r_strbuf_appendf (&op->esil, "%s,%s,<<=", ARG(1), ARG(0));
		break;
	case ARM_INS_LSR:
		// suffix 'S' forces conditional flag to be updated
		r_strbuf_appendf (&op->esil, "%s,%s,>>=", ARG(1), ARG(0));
		break;
	case ARM_INS_B:
		r_strbuf_appendf (&op->esil, "%s,pc,=", ARG(0));
		break;
	case ARM_INS_BL:
	case ARM_INS_BLX:
		r_strbuf_appendf (&op->esil, "4,pc,+,lr,=,%s,pc,=", ARG(0));
		break;
	case ARM_INS_MOV:
	case ARM_INS_MOVS:
		r_strbuf_appendf (&op->esil, "%s,%s,=", ARG(1), REG(0));
		break;
	case ARM_INS_SSUB16:
	case ARM_INS_SSUB8:
	case ARM_INS_SUB:
		r_strbuf_appendf (&op->esil, "%s,%s,-=", ARG(1), ARG(0));
		break;
	case ARM_INS_SADD16:
	case ARM_INS_SADD8:
	case ARM_INS_ADD:
		if (!strcmp (ARG(0),ARG(1))) {
			r_strbuf_appendf (&op->esil, "%s,%s,+=", ARG(2), ARG(0));
		} else if (!strcmp (ARG(2),"0")) {
			r_strbuf_appendf (&op->esil, "%s,%s,=", ARG(1), ARG(0));
		} else {
			r_strbuf_appendf (&op->esil, "%s,%s,+,%s,=", ARG(2), ARG(1), ARG(0));
		}
		break;
	case ARM_INS_STR:
		r_strbuf_appendf (&op->esil, "%s,%s,%d,+,=[4]",
			REG(0), MEMBASE(1), MEMDISP(1));
		break;
	case ARM_INS_STRB:
		r_strbuf_appendf (&op->esil, "%s,%s,%d,+,=[1]",
			REG(0), MEMBASE(1), MEMDISP(1));
		break;
	case ARM_INS_LDR:
		if (MEMDISP(1)<0) {
			if (REGBASE(1) == ARM_REG_PC) {
				r_strbuf_appendf (&op->esil, "8,%s,+,%d,-,[4],%s,=",
						MEMBASE(1), -MEMDISP(1), REG(0));
				switch (a->bits) {
				case 32:
					op->ptr = addr + 8 - MEMDISP(1);
					op->refptr = 4;
					break;
				case 16:
					if ( (addr % 4) == 0 ) {
						op->ptr = addr + 4 - MEMDISP(1);
						op->refptr = 4;
					} else {
						op->ptr = addr + 2 - MEMDISP(1);
						op->refptr = 4;
					}
					break;
				}
			} else {
				r_strbuf_appendf (&op->esil, "%s,%d,-,[4],%s,=",
					MEMBASE(1), -MEMDISP(1), REG(0));
			}
		} else {
			if (REGBASE(1) == ARM_REG_PC) {
				r_strbuf_appendf (&op->esil, "8,%s,+,%d,+,[4],%s,=",
					MEMBASE(1), MEMDISP(1), REG(0));
				if (a->bits==32) {
					op->ptr = addr + 8 + MEMDISP(1);
					op->refptr = 4;
				} else if (a->bits==16) {
					if ( (addr % 4) == 0 ) {
						op->ptr = addr + 4 + MEMDISP(1);
						op->refptr = 4;
					} else {
						op->ptr = addr + 2 + MEMDISP(1);
						op->refptr = 4;
					}
				}
			} else {
				r_strbuf_appendf (&op->esil, "%s,%d,+,[4],%s,=",
					MEMBASE(1), MEMDISP(1), REG(0));
			}
			op->refptr = 4;
		}
		break;
	case ARM_INS_LDRD:
	case ARM_INS_LDRB:
		r_strbuf_appendf (&op->esil, "%s,%d,+,[1],%s,=",
			MEMBASE(1), MEMDISP(1), REG(0));
		break;
	default:
		break;
	}
	return 0;
}
コード例 #19
0
ファイル: op.c プロジェクト: aronsky/radare2
R_API void r_asm_op_set_asm(RAsmOp *op, const char *str) {
	r_return_if_fail (op && str);
	r_strbuf_set (&op->buf_asm, str);
}
コード例 #20
0
ファイル: anal_bf.c プロジェクト: jpenalbae/radare2
static int bf_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
	ut64 dst = 0LL;
	if (op == NULL)
		return 1;
	/* Ayeeee! What's inside op? Do we have an initialized RAnalOp? Are we going to have a leak here? :-( */
	memset (op, 0, sizeof (RAnalOp)); /* We need to refactorize this. Something like r_anal_op_init would be more appropiate */
	r_strbuf_init (&op->esil);
	op->size = 1;
	switch (buf[0]) {
	case '[': op->type = R_ANAL_OP_TYPE_CJMP;
		  op->fail = addr+1;
		  {
			 const ut8 *p = buf + 1;
			 int lev = 0, i = 1;
			 while (*p && i<len) {
				 if (*p == '[')
					 lev++;
				 if (*p == ']') {
					 lev--;
					 if (lev==-1) {
						 dst = addr + (size_t)(p-buf);
						 dst ++;
						 op->jump = dst;
						 r_strbuf_setf (&op->esil,
							 "pc,brk,=[1],brk,++=,"
							 "ptr,[1],!,?{,0x%"PFMT64x",pc,=,}", dst);
						 break;
					 }
				 }
				 p++;
				i++;
			 }
		  }
	// ?1[ptr],pc=${NEW_PC
	break;
	case ']': op->type = R_ANAL_OP_TYPE_UJMP;
		// XXX This is wrong esil
		r_strbuf_set (&op->esil, "brk,--=,brk,[1],pc,=");
		break;
	case '>': op->type = R_ANAL_OP_TYPE_ADD;
		r_strbuf_set (&op->esil, "ptr,++=");
		break;
	case '<': op->type = R_ANAL_OP_TYPE_SUB;
		r_strbuf_set (&op->esil, "ptr,--=");
		break;
	case '+':
		op->size = countChar (buf, len, '+');
		op->type = R_ANAL_OP_TYPE_ADD;
		r_strbuf_setf (&op->esil, "ptr,[1],%d,+,ptr,=[1]", op->size);
		break;
	case '-':
		op->type = R_ANAL_OP_TYPE_SUB;
		op->size = countChar (buf, len, '-');
		r_strbuf_setf (&op->esil, "ptr,[1],%d,-,ptr,=[1]", op->size);
		break;
	case '.':
		// print element in stack to screen
		op->type = R_ANAL_OP_TYPE_STORE;
		r_strbuf_set (&op->esil, "ptr,[1],scr,=[1],scr,++=");
		break;
	case ',':
		op->type = R_ANAL_OP_TYPE_LOAD;
		r_strbuf_set (&op->esil, "kbd,[1],ptr,=[1],kbd,++=");
		break;
	case 0x00:
	case 0xff:
		op->type = R_ANAL_OP_TYPE_TRAP;
		break;
	default:
		op->type = R_ANAL_OP_TYPE_NOP;
		r_strbuf_set (&op->esil, ",");
		break;
	}
	return op->size;
}
コード例 #21
0
ファイル: strbuf.c プロジェクト: jahrome/radare2
R_API RStrBuf *r_strbuf_new(const char *str) {
	RStrBuf *s = R_NEW0 (RStrBuf);
	if (str) r_strbuf_set (s, str);
	return s;
}
コード例 #22
0
ファイル: anal_h8300.c プロジェクト: das-labor/radare2
static int analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf) {
	int ret = -1;
	ut8 opcode = buf[0];
	if (!op) {
		return 2;
	}
	r_strbuf_init (&op->esil);
	r_strbuf_set (&op->esil, "");
	switch (opcode >> 4) {
	case H8300_CMP_4BIT:
		//acc. to manual this is how it's done, could use == in esil
		r_strbuf_appendf(&op->esil, "0x%02x,r%u%c,-", imm, rdB(0));
		//setZ
		setV("%o");
		setN;
		setHb_B;
		setCb_B;
		maskB(0);
		setZ;
		return 0;
	case H8300_OR_4BIT:
		r_strbuf_appendf(&op->esil, "0x%02x,r%u%c,|=", imm, rdB(0));
		//setZ
		setV("0");
		setN;
		maskB(0);
		setZ;
		return 0;
	case H8300_XOR_4BIT:
		r_strbuf_appendf(&op->esil, "0x%02x,r%u%c,^=", imm, rdB(0));
		//setZ
		setN;
		setV("0");
		maskB(0);
		setZ;
		return 0;
	case H8300_AND_4BIT:
		r_strbuf_appendf(&op->esil, "0x%02x,r%u%c,&=", imm, rdB(0));
		//setZ
		setN;
		setV("0");
		maskB(0);
		setZ;
		return 0;
	case H8300_ADD_4BIT:
		r_strbuf_appendf(&op->esil, "0x%02x,r%u%c,+=", imm, rdB(0));
		//setZ
		setV("%o");
		setN;
		setH_B;
		setC_B;
		maskB(0);
		setZ;
		return 0;
	case H8300_ADDX_4BIT:
		r_strbuf_appendf(&op->esil, "0x%02x,C,+,r%u%c,+= ", imm,
				rdB(0), rdB(0));
		//setZ
		setV("%o");
		setN;
		setH_B;
		setC_B;
		maskB(0);
		setZ;
		return 0;
	case H8300_SUBX_4BIT:
		//Rd – imm – C → Rd
		r_strbuf_appendf(&op->esil, "0x%02x,r%u%c,-=,C,r%u%c,-=", imm, rdB(0), rdB(0));
		//setZ
		setV("%o");
		setN;
		setHb_B;
		setCb_B;
		maskB(0);
		setZ;
		return 0;
	case H8300_MOV_4BIT_2: /*TODO*/
	case H8300_MOV_4BIT_3: /*TODO*/
	case H8300_MOV_4BIT: /*TODO*/
		return 0;
	default:
		break;
	};

	switch (opcode) {
	case H8300_NOP:
		r_strbuf_set (&op->esil, ",");
		return 0;
	case H8300_SLEEP: /* TODO */
		return 0;
	case H8300_STC:
		r_strbuf_appendf(&op->esil, "ccr,r%u%c,=", rdB(1));
		return 0;
	case H8300_LDC:
		r_strbuf_appendf(&op->esil, "r%u%c,ccr,=", rdB(1));
		return 0;
	case H8300_ORC:
		r_strbuf_appendf(&op->esil, "0x%02x,ccr,|=", imm);
		return 0;
	case H8300_XORC:
		r_strbuf_appendf(&op->esil, "0x%02x,ccr,^=", imm);
		return 0;
	case H8300_ANDC:
		r_strbuf_appendf(&op->esil, "0x%02x,ccr,&=", imm);
		return 0;
	case H8300_LDC_2:
		r_strbuf_appendf(&op->esil, "0x%02x,ccr,=", imm);
		return 0;
	case H8300_ADDB_DIRECT:
		r_strbuf_appendf(&op->esil, "r%u%c,r%u%c,+=", rsB(), rdB(1));
		setH_B;
		setV("%o");
		setC_B ;
		setN;
		//setZ;
		maskB(1);
		setZ;
		return 0;
	case H8300_ADDW_DIRECT:
		r_strbuf_appendf (&op->esil, "r%u,r%u,+=", rs(), rd());
		setH_W;
		setV("%o");
		setC_W;
		setN;
		mask();
		setZ;
		return 0;
	case H8300_INC:
		r_strbuf_appendf(&op->esil, "1,r%u%c,+=", rdB(1));
		//setZ
		setV("%o") ;
		setN;
		maskB(1);
		setZ;
		return 0;
	case H8300_ADDS:
		r_strbuf_appendf (&op->esil, "%d,r%u,+=",
			((buf[1] & 0xf0) == 0x80) ? 2 : 1, rd());
		return 0;
	case H8300_MOV_1:
		/*TODO check if flags are set internally or not*/
		r_strbuf_appendf (&op->esil, "r%u%c,r%u%c,=", rsB(), rdB(1));
		//setZ
		setN;
		maskB(1);
		setZ;
		return 0;
	case H8300_MOV_2:
		r_strbuf_appendf(&op->esil, "r%u,r%u,=", rs(), rd());
		//setZ
		setN;
		mask();
		setZ;
		return 0;
	case H8300_ADDX:
		//Rd + (Rs) + C → Rd
		r_strbuf_appendf (&op->esil, "r%u%c,C,+,r%u%c,+=",
				rsB(), rdB(1), rdB(1));
		//setZ
		setV("%o");
		setN;
		setH_B ;
		setC_B;
		maskB(1);
		setZ;
		return 0;
	case H8300_DAA: /*TODO*/
		return 0;
	case H8300_SHL: /*TODO*/
		return 0;
	case H8300_SHR: /*TODO*/
		return 0;
	case H8300_ROTL: /*TODO*/
		return 0;
	case H8300_ROTR: /*TODO*/
		return 0;
	case H8300_OR:
		r_strbuf_appendf(&op->esil, "r%u%c,r%u%c,|=", rsB(), rdB(1));
		//setZ
		setV("0");
		setN;
		maskB(1);
		setZ;
		return 0;
	case H8300_XOR:
		r_strbuf_appendf(&op->esil, "r%u%c,r%u%c,^=", rsB(), rdB(1));
		//setZ
		setV("0") ;
		setN;
		maskB(1);
		setZ;
		return 0;
	case H8300_AND:
		r_strbuf_appendf(&op->esil, "r%u%c,r%u%c,&=", rsB(), rdB(1));
		//setZ
		setV("0");
		setN;
		maskB(1);
		setZ;
		return 0;
	case H8300_NOT_NEG:
		if ((buf[1] & 0xf0) == 0x80) { //NEG
			r_strbuf_appendf(&op->esil, "r%u%c,0,-,r%u%c,=", rdB(1), rdB(1));
			//setZ
			setHb_B;
			setV("%o") ;
			setCb_B ;
			setN;
			maskB(1);
			setZ;
		} else if ((buf[1] & 0xf0) == 0x00) { //NOT
			r_strbuf_appendf(&op->esil, "r%u%c,!=", rdB(1));
			//setZ
			setV("0");
			setN;
			maskB(1);
			setZ;
		}
		return 0;
	case H8300_SUB_1:
		r_strbuf_appendf(&op->esil, "r%u%c,r%u%c,-=", rsB(), rdB(1));
		//setZ
		setHb_B;
		setV("%o");
		setCb_B;
		setN;
		maskB(1);
		setZ;
		return 0;
	case H8300_SUBW:
		r_strbuf_appendf (&op->esil, "r%u,r%u,-=", rs(), rd());
		setHb_W;
		setV ("%o");
		setCb_W;
		setN;
		mask();
		setZ;
		return 0;
	case H8300_DEC:
		r_strbuf_appendf (&op->esil, "1,r%u%c,-=", rdB(1));
		//setZ
		setV("%o");
		setN;
		maskB(1);
		setZ;
		return 0;
	case H8300_SUBS:
		r_strbuf_appendf(&op->esil, "%d,r%u,-=",
			( (buf[1] & 0xf0) == 0x80) ? 2 : 1, rd());
		return 0;
	case H8300_CMP_1:
		r_strbuf_appendf(&op->esil, "r%u%c,r%u%c,-", rsB(), rdB(1));
		//setZ
		setHb_B;
		setV("%o");
		setCb_B;
		setN;
		maskB(1);
		setZ;
		return 0;
	case H8300_CMP_2:
		r_strbuf_appendf(&op->esil, "r%u,r%u,-", rs(), rd());
		//setZ
		setHb_W;
		setV("%o");
		setCb_W;
		setN;
		mask();
		setZ;
		return 0;
	case H8300_SUBX:
		//Rd – (Rs) – C → Rd
		r_strbuf_appendf(&op->esil, "r%u%c,r%u%c,-=,C,r%u%c,-=",
			rsB(), rdB(1), rdB(1));
		//setZ
		setHb_B;
		setV("%o");
		setCb_B;
		setN;
		maskB(1);
		setZ;
		return 0;
	case H8300_DAS: /*TODO*/
		return 0;
	case H8300_BRA:
		r_strbuf_appendf(&op->esil, "0x%02x,pc,+=", buf[1]);
		return 0;
	case H8300_BRN:
		r_strbuf_appendf(&op->esil,",");
		return 0;
	case H8300_BHI:
		r_strbuf_appendf(&op->esil, "C,Z,|,!,?{0x%02x,pc,+=}", buf[1]);
		return 0;
	case H8300_BLS:
		r_strbuf_appendf(&op->esil, "C,Z,|,?{0x%02x,pc,+=}", buf[1]);
		return 0;
	case H8300_BCC:
		r_strbuf_appendf(&op->esil, "C,!,?{0x%02x,pc,+=}", buf[1]);
		return 0;
	case H8300_BCS:
		r_strbuf_appendf(&op->esil, "C,?{0x%02x,pc,+=}", buf[1]);
		return 0;
	case H8300_BNE:
		r_strbuf_appendf(&op->esil, "Z,!,?{0x%02x,pc,+=}", buf[1]);
		return 0;
	case H8300_BEQ:
		r_strbuf_appendf(&op->esil, "Z,?{0x%02x,pc,+=}", buf[1]);
		return 0;
	case H8300_BVC:
		r_strbuf_appendf(&op->esil, "V,!,?{0x%02x,pc,+=}", buf[1]);
		return 0;
	case H8300_BVS:
		r_strbuf_appendf(&op->esil, "V,?{0x%02x,pc,+=}", buf[1]);
		return 0;
	case H8300_BPL:
		r_strbuf_appendf(&op->esil, "N,!,?{0x%02x,pc,+=}", buf[1]);
		return 0;
	case H8300_BMI:
		r_strbuf_appendf(&op->esil, "N,?{0x%02x,pc,+=}", buf[1]);
		return 0;
	case H8300_BGE:
		r_strbuf_appendf(&op->esil, "N,V,^,!,?{0x%02x,pc,+=}", buf[1]);
		return 0;
	case H8300_BLT:
		r_strbuf_appendf(&op->esil, "N,V,^,?{0x%02x,pc,+=}", buf[1]);
		return 0;
	case H8300_BGT:
		r_strbuf_appendf(&op->esil, "Z,N,V,^,|,!,?{0x%02x,pc,+=}", buf[1]);
		return 0;
	case H8300_BLE:
		r_strbuf_appendf(&op->esil, "Z,N,V,^,|,?{0x%02x,pc,+=}", buf[1]);
		return 0;
	case H8300_MULXU:
		//Refer to pg. 100 of the manual linked at the beginning
		r_strbuf_appendf(&op->esil, "r%u%c,r%ul,*,r%u,=",
				rsB(), rd(), rd());
		return 0;
	case H8300_DIVXU: /*TODO*/ return 0;
	case H8300_RTS: /*TODO*/ return 0;
	case H8300_BSR: /*TODO*/ return 0;
	case H8300_RTE: /*TODO*/ return 0;
	case H8300_JMP_1: /*TODO*/ return 0;
	case H8300_JMP_2: /*TODO*/ return 0;
	case H8300_JMP_3: /*TODO*/ return 0;
	case H8300_JSR_1: /*TODO*/ return 0;
	case H8300_JSR_2: /*TODO*/ return 0;
	case H8300_JSR_3: /*TODO*/
		return 0;
		//NOTE - cases marked with TODO have mem. access also(not impl.)
	case H8300_BSET_1: /*TODO*/
		//set rs&0x7th bit of rd. expr.- rd|= 1<<(rs&0x07)
		r_strbuf_appendf(&op->esil, "0x7,r%u%c,&,1,<<,r%u%c,|=", rsB(), rdB(1));
		return 0;
	case H8300_BNOT_1: /*TODO*/
		//invert rs&0x7th bit of rd. expr.- rd^= 1<<(rs&0x07)
		r_strbuf_appendf(&op->esil,"0x07,r%u%c,&,1,<<,r%u%c,^=", rsB(), rdB(1));
		return 0;
	case H8300_BCLR_R2R8: /*TODO*/
		//clear rs&0x7th bit of rd. expr.- rd&= !(1<<(rs&0x07))
		r_strbuf_appendf(&op->esil, "0x7,r%u%c,&,1,<<,!,r%u%c,&=", rsB(), rdB(1));
		return 0;
	case H8300_BTST_R2R8: /*TODO*/
		//¬ (<Bit No.> of <EAd>) → Z, extract bit value and shift it back
		r_strbuf_appendf(&op->esil, "0x7,r%u%c,&,0x7,r%u%c,&,1,<<,r%u%c,&,>>,!,Z,=",
				rsB(), rsB(), rdB(1));
		return 0;
	case H8300_BST_BIST: /*TODO*/
		if (!(buf[1] & 0x80)) { //BST
			r_strbuf_appendf(&op->esil,"%d,C,<<,r%u%c,|=",rs(),rdB(1));
		} else { //BIST
			r_strbuf_appendf (&op->esil, "%d,C,!,<<,r%u%c,|=", rs (), rdB (1));
		}
		return 0;
	case H8300_MOV_R82IND16: /*TODO*/ return 0;
	case H8300_MOV_IND162R16: /*TODO*/ return 0;
	case H8300_MOV_R82ABS16: /*TODO*/ return 0;
	case H8300_MOV_ABS162R16: /*TODO*/ return 0;
	case H8300_MOV_R82RDEC16: /*TODO*/ return 0;
	case H8300_MOV_INDINC162R16: /*TODO*/ return 0;
	case H8300_MOV_R82DISPR16: /*TODO*/ return 0;
	case H8300_MOV_DISP162R16: /*TODO*/
		return 0;
	case H8300_BSET_2: /*TODO*/
		//set imm bit of rd. expr.- rd|= (1<<imm)
		r_strbuf_appendf(&op->esil, "%d,1,<<,r%u%c,|=", rs(), rdB(1));
		return 0;
	case H8300_BNOT_2: /*TODO*/
		//inv. imm bit of rd. expr.- rd^= (1<<imm)
		r_strbuf_appendf(&op->esil,"%d,1,<<,r%u%c,^=",rs(),rdB(1));
		return 0;
	case H8300_BCLR_IMM2R8:
		//clear imm bit of rd. expr.- rd&= !(1<<imm)
		r_strbuf_appendf(&op->esil, "%d,1,<<,!,r%u%c,&=", rs(), rdB(1));
		return 0;
	case H8300_BTST: /*TODO*/
		//see BTST above
		r_strbuf_appendf(&op->esil, "%d,%d,1,<<,r%u%c,&,>>,!,Z,=",
				rs(), rs(), rdB(1));
		return 0;
	case H8300_BOR_BIOR: /*TODO*/
		if (!(buf[1] & 0x80)) { //BOR
			//C|=(rd&(1<<imm))>>imm
			r_strbuf_appendf(&op->esil, "%d,%d,1,<<,r%u%c,&,>>,C,|=",
					rs(), rs(), rdB(1));
		} else { //BIOR
			//C|=!(rd&(1<<imm))>>imm
			r_strbuf_appendf (&op->esil, "%d,%d,1,<<,r%u%c,&,>>,!,C,|=",
				rs (), rs (), rdB (1));
		}
		return 0;
	case H8300_BXOR_BIXOR: /*TODO*/
		if (!(buf[1] & 0x80)) { //BXOR
			//C^=(rd&(1<<imm))>>imm
			r_strbuf_appendf(&op->esil, "%d,%d,1,<<,r%u%c,&,>>,C,^=",
					rs(), rs(), rdB(1));
		} else { //BIXOR
			r_strbuf_appendf (&op->esil, "%d,%d,1,<<,r%u%c,&,>>,!,C,^=",
				rs (), rs (), rdB (1));
		}
		return 0;
	case H8300_BAND_BIAND:
		/*TODO check functionality*/
		//C&=(rd&(1<<imm))>>imm
		if (!(buf[1] & 0x80)) { //BAND
			r_strbuf_appendf(&op->esil, "%d,%d,1,<<,r%u%c,&,>>,C,&=",
					rs(), rs(), rdB(1));
		} else { //BIAND
			r_strbuf_appendf (&op->esil, "%d,%d,1,<<,r%u%c,&,>>,!,C,&=",
				rs (), rs (), rdB (1));
		}
		return 0;
	case H8300_BILD_IMM2R8:
		/*TODO*/
		if (!(buf[1] & 0x80)) { //BLD
			r_strbuf_appendf(&op->esil, "%d,%d,1,<<,r%u%c,&,>>,C,=",
					rs(), rs(), rdB(1));
		} else { //BILD
			r_strbuf_appendf (&op->esil, "%d,%d,1,<<,r%u%c,&,>>,!,C,=",
				rs (), rs (), rdB (1));
		}
		return 0;
	case H8300_MOV_IMM162R16: /*TODO*/ return 0;
	case H8300_EEPMOV: /*TODO*/ return 0;
	case H8300_BIAND_IMM2IND16: /*TODO*/ return 0;
	case H8300_BCLR_R2IND16: /*TODO*/ return 0;
	case H8300_BIAND_IMM2ABS8: /*TODO*/ return 0;
	case H8300_BCLR_R2ABS8: /*TODO*/ return 0;
	default:
		break;
	};

	return ret;
}
コード例 #23
0
ファイル: anal_8051.c プロジェクト: nirouviere/radare2
static void analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf) {
	r_strbuf_init (&op->esil);
	r_strbuf_set (&op->esil, "");

	switch (buf[0]) {
	// Irregulars sorted by lower nibble
	case 0x00: /* nop */
		e (",");
		break;

	case 0x10: /* jbc bit, offset */
		bit_r; e ("?{,"); bit_mask; xi (bit, "&"); jmp; e (",}");
		break;
	case 0x20: /* jb bit, offset */
		bit_r; cjmp;
		break;
	case 0x30: /* jnb bit, offset */
		bit_r; e ("!,"); cjmp;
		break;
	case 0x40: /* jc offset */
		e ("c,1,&,"); cjmp;
		break;
	case 0x50: /* jnc offset */
		e ("c,1,&,!,"); cjmp;
		break;
	case 0x60: /* jz offset */
		e ("a,0,==,"); cjmp;
		break;
	case 0x70: /* jnz offset */
		e ("a,0,==,!,"); cjmp;
		break;

	case 0x11: case 0x31: case 0x51: case 0x71:
	case 0x91: case 0xB1: case 0xD1: case 0xF1: /* acall addr11 */
	case 0x12: /* lcall addr16 */
		call;
		break;
	case 0x01: case 0x21: case 0x41: case 0x61:
	case 0x81: case 0xA1: case 0xC1: case 0xE1: /* ajmp addr11 */	
	case 0x02: /* ljmp addr16 */
	case 0x80: /* sjmp offset */
		jmp;
		break;

	case 0x22: /* ret */
	case 0x32: /* reti */
		xr (sp2); e ("pc,=");
		break;

	case 0x03: /* rr a */
		e ("1,a,0x101,*,>>,a,=," flag_p);
		break;
	case 0x04: /* inc a */
		xi (a, "++"); e (flag_p);
		break;
	case 0x05: /* inc direct */
		xi (dir1, "++");
		break;
	case 0x06: case 0x07: /* inc @Ri */
		xi (ri, "++");
		break;
	case 0x08: case 0x09: case 0x0A: case 0x0B:
	case 0x0C: case 0x0D: case 0x0E: case 0x0F: /* inc @Rn */
		xi (rn, "++");
		break;
	case 0x13: /* rrc a */
		e ("7,c,<<,1,a,&,c,=,0x7f,1,a,>>,&,+,a,=," flag_p);
		break;
	case 0x14: /* dec a */
		xi (a, "--"); e (flag_p);
		break;
	case 0x15: /* dec direct */
		xi (dir1, "--"); e (flag_p);
		break;
	case 0x16: case 0x17: /* dec @Ri */
		xi (ri, "--");
		break;
	case 0x18: case 0x19: case 0x1A: case 0x1B:
	case 0x1C: case 0x1D: case 0x1E: case 0x1F: /* dec @Rn */
		xi (rn, "--");
		break;
	case 0x23: /* rl a */
		e ("7,a,0x101,*,>>,a,=," flag_p);
		break;
	template_alu4 (0x20, "+", flag_c flag_ac flag_ov flag_p) /* 0x24..0x2f add a,.. */
	case 0x33: /* rlc a */
		e ("c,1,&,a,a,+=,$c7,c,=,a,+=," flag_p);
		break;
	template_alu4_c (0x30, "+", flag_c flag_ac flag_ov flag_p) /* 0x34..0x3f addc a,.. */
	template_alu2 (0x40, "|") /* 0x42..0x43 orl direct,.. */
	template_alu4 (0x40, "|", flag_p) /* 0x44..0x4f orl a,.. */
	template_alu2 (0x50, "&") /* 0x52..0x53 anl direct,.. */
	template_alu4 (0x50, "&", flag_p) /* 0x54..0x5f anl a,.. */
	template_alu2 (0x60, "^") /* 0x62..0x63 xrl direct,.. */
	template_alu4 (0x60, "^", flag_p) /* 0x64..0x6f xrl a,.. */
	case 0x72: /* orl C, bit */
		bit_r; xi (c, "|");
		break;
	case 0x73: /* jmp @a+dptr */
		e ("dptr,a,+,pc,=");
		break;
	case 0x74: /* mov a, imm */
		xr (imm1); xw (a); e (flag_p);
		break;
	case 0x75: /* mov direct, imm */
		xr (imm2); xw (dir1);
		break;
	case 0x76: case 0x77: /* mov @Ri, imm */
		xr (imm1); xw (ri);
		break;
	case 0x78: case 0x79: case 0x7A: case 0x7B:
	case 0x7C: case 0x7D: case 0x7E: case 0x7F: /* mov Rn, imm */
		xr (imm1); xw (rn);
		break;
	case 0x82: /* anl C, bit */
		bit_r; xi (c, "&");
		break;
	case 0x83: /* movc a, @a+pc */
		e ("a,pc,--,+,[1],a,=," flag_p);
		break;
	case 0x84: /* div ab */
		// note: escape % if this becomes a format string
		e ("b,0,==,ov,=,b,a,%,b,a,/=,b,=,0,c,=," flag_p);
		break;
	case 0x85: /* mov direct, direct */
		xr (dir1); xw (dir2);
		break;
	case 0x86: case 0x87: /* mov direct, @Ri */
		xr (ri); xw (dir1);
		break;
	case 0x88: case 0x89: case 0x8A: case 0x8B:
	case 0x8C: case 0x8D: case 0x8E: case 0x8F: /* mov direct, Rn */
		xr (rn); xw (dir1);
		break;
	case 0x90: /* mov dptr, imm */
		xr (imm16); xw (dp);
		break;
	case 0x92: /* mov bit, C */
		bit_c; bit_mask; xr (bit); e ("&,|,"); xw(bit);
		break;
	case 0x93: /* movc a, @a+dptr */
		e ("a,dptr,+,[1],a,=," flag_p);
		break;
	template_alu4_c (0x90, "-", flag_b flag_ab flag_ob flag_p) /* 0x94..0x9f subb a,.. */
	case 0xA0: /* orl C, /bit */
		bit_r; e ("!,"); xi (c, "|");
		break;
	case 0xA2: /* mov C, bit */
		bit_r; xw (c);
		break;
	case 0xA3: /* inc dptr */
		xi (dp, "++");
		break;
	case 0xA4: /* mul ab */
		e ("8,a,b,*,DUP,a,=,>>,DUP,b,=,0,==,!,ov,=,0,c,=," flag_p);
		break;
	case 0xA5: /* "reserved" */
		e ("0,trap");
		break;
	case 0xA6: case 0xA7: /* mov @Ri, direct */
		xr (dir1); xw (ri);
		break;
	case 0xA8: case 0xA9: case 0xAA: case 0xAB:
	case 0xAC: case 0xAD: case 0xAE: case 0xAF: /* mov Rn, direct */
		xr (dir1); xw (rn);
		break;
	case 0xB0: /* anl C, /bit */
		bit_r; e ("!,"); xi (c, "&");
		break;
	case 0xB2: /* cpl bit */
		bit_set; xi (bit, "^");
		break;
	case 0xB3: /* cpl C */
		e ("1,"); xi (c, "^");
		break;
	case 0xB4: /* cjne a, imm, offset */
		xr (imm1); xr (a); e ("-," flag_b); cjmp;
		break;
	case 0xB5: /* cjne a, direct, offset */
		xr (dir1); xr (a); e ("-," flag_b); cjmp;
		break;
	case 0xB6: case 0xB7: /* cjne @ri, imm, offset */
		xr (imm1); xr (ri); e ("-," flag_b); cjmp;
		break;
	case 0xB8: case 0xB9: case 0xBA: case 0xBB:
	case 0xBC: case 0xBD: case 0xBE: case 0xBF: /* cjne Rn, imm, offset */
		xr (imm1); xr (rn); e ("-," flag_b); cjmp;
		break;
	case 0xC0: /* push direct */
		xr (dir1); xw (sp1);
		break;
	case 0xC2: /* clr bit */
		bit_mask; xi (bit, "&");
		break;
	case 0xC3: /* clr C */
		e ("0,"); xw (c);
		break;
	case 0xC4: /* swap a */
		e ("0xff,4,a,0x101,*,>>,&,a,=," flag_p);
		break;
	case 0xC5: /* xch a, direct */
		xr (a); e ("0,+,"); xr (dir1); xw (a); xw (dir1); e (flag_p);
		break;
	case 0xC6: case 0xC7: /* xch a, @Ri */ 
		xr (a); e ("0,+,"); xr (ri); xw (a); xw (ri); e (flag_p);
		break;
	case 0xC8: case 0xC9: case 0xCA: case 0xCB:
	case 0xCC: case 0xCD: case 0xCE: case 0xCF: /* xch a, Rn */
		xr (a); e ("0,+,"); xr (rn); xw (a); xw (rn); e (flag_p);
		break;
	case 0xD0: /* pop direct */
		xr (sp1); xw (dir1);
		break;
	case 0xD2: /* setb bit */
		bit_set; xi (bit, "|");
		break;
	case 0xD3: /* setb C */
		e ("1,"); xw (c);
		break;
	case 0xD4: /* da a */
		// BCD adjust after add:
		// if (lower nibble > 9) or (AC == 1) add 6
		// if (higher nibble > 9) or (C == 1) add 0x60
		// carry |= carry caused by this operation
		e ("a,0x0f,&,9,<,ac,|,?{,6,a,+=,$c7,c,|=,},a,0xf0,&,0x90,<,c,|,?{,0x60,a,+=,$c7,c,|=,}," flag_p);
		break;
	case 0xD5: /* djnz direct, offset */
		xi (dir1, "--"); xr (dir1); e ("0,==,!,"); cjmp;
		break;
	case 0xD6:
	case 0xD7: /* xchd a, @Ri*/
		xr (a); e ("0xf0,&,"); xr (ri); e ("0x0f,&,|,");
		xr (ri); e ("0xf0,&,"); xr (a); e ("0x0f,&,|,");
		xw (ri); xw (a); e (flag_p);
		break;
	case 0xD8: case 0xD9: case 0xDA: case 0xDB:
	case 0xDC: case 0xDD: case 0xDE: case 0xDF: /* djnz Rn, offset */
		xi (rn, "--"); xr (rn); e ("0,==,!,"); cjmp;
		break;
	case 0xE0: /* movx a, @dptr */
		xr (dpx); xw (a); e (flag_p);
		break;
	case 0xE2: case 0xE3: /* movx a, @Ri */
		xr (rix); xw (a); e (flag_p);
		break;
	case 0xE4: /* clr a */
		e ("0,"); xw (a); e (flag_p);
		break;
	case 0xE5: /* mov a, direct */
		xr (dir1); xw (a); e (flag_p);
		break;
	case 0xE6: case 0xE7: /* mov a, @Ri */
		xr (ri); xw (a); e (flag_p);
		break;
	case 0xE8: case 0xE9: case 0xEA: case 0xEB:
	case 0xEC: case 0xED: case 0xEE: case 0xEF: /* mov a, Rn */
		xr (rn); xw (a); e (flag_p);
		break;
	case 0xF0: /* movx @dptr, a */
		xr (a); xw (dpx);
		break;
	case 0xF2: case 0xF3: /* movx @Ri, a */
		xr (a); xw (rix);
		break;
	case 0xF4: /* cpl a */
		e ("255,"); xi (a, "^"); e (flag_p);
		break;
	case 0xF5: /* mov direct, a */
		xr (a); xw (dir1);
		break;
	case 0xF6: case 0xF7: /* mov  @Ri, a */
		xr (a); xw (ri);
		break;
	case 0xF8: case 0xF9: case 0xFA: case 0xFB:
	case 0xFC: case 0xFD: case 0xFE: case 0xFF: /* mov Rn, a */
		xr (a); xw (rn);
		break;
	default:
		break;
	}
}
コード例 #24
0
ファイル: asm_h8300.c プロジェクト: jroimartin/radare2
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
	struct h8300_cmd cmd;
	int ret = h8300_decode_command(buf, &cmd);
	r_strbuf_set (&op->buf_asm, sdb_fmt ("%s %s", cmd.instr, cmd.operands));
	return op->size = ret;
}
コード例 #25
0
ファイル: anal_arm_cs.c プロジェクト: cephurs/radare2
static int analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len, csh *handle, cs_insn *insn) {
	int i;
	char str[32][32];
	r_strbuf_init (&op->esil);
	r_strbuf_set (&op->esil, "");
	switch (insn->detail->arm.cc) {
	case ARM_CC_AL:
		// no condition
		break;
	case ARM_CC_EQ:
		r_strbuf_setf (&op->esil, "zf,0,?,");
		break;
	case ARM_CC_NE:
		r_strbuf_setf (&op->esil, "zf,!,0,?,");
		break;
	case ARM_CC_GT:
	case ARM_CC_LE:
		break;
	}
	// TODO: PREFIX CONDITIONAL
	switch (insn->id) {
	case ARM_INS_PUSH:
		// TODO: increment stack
	case ARM_INS_STM:
		for (i=1; i<insn->detail->arm.op_count; i++) {
			r_strbuf_appendf (&op->esil, "%s,%s,%d,+,=[4],",
				REG (i), ARG (0), i*4);
		}
		break;
	case ARM_INS_POP:
		// TODO: decrement stack
	case ARM_INS_LDM:
		for (i=1; i<insn->detail->arm.op_count; i++) {
			r_strbuf_appendf (&op->esil, "%s,%d,+,[4],%s,=",
				ARG (0), i*4, REG (i));
		}
		break;
	case ARM_INS_CMP:
		r_strbuf_appendf (&op->esil, "%s,%s,==", ARG(1), ARG(0));
		break;
	case ARM_INS_LSL:
		// suffix 'S' forces conditional flag to be updated
		r_strbuf_appendf (&op->esil, "%s,%s,<<=", ARG(1), ARG(0));
		break;
	case ARM_INS_LSR:
		// suffix 'S' forces conditional flag to be updated
		r_strbuf_appendf (&op->esil, "%s,%s,>>=", ARG(1), ARG(0));
		break;
	case ARM_INS_B:
	case ARM_INS_BL:
	case ARM_INS_BLX:
		r_strbuf_appendf (&op->esil, "%s,pc,=", ARG(0));
		break;
	case ARM_INS_MOV:
	case ARM_INS_MOVS:
		r_strbuf_appendf (&op->esil, "%s,%s,=", ARG(1), REG(0));
		break;
	case ARM_INS_SSUB16:
	case ARM_INS_SSUB8:
	case ARM_INS_SUB:
		r_strbuf_appendf (&op->esil, "%s,%s,-=", ARG(1), ARG(0));
		break;
	case ARM_INS_SADD16:
	case ARM_INS_SADD8:
	case ARM_INS_ADD:
		r_strbuf_appendf (&op->esil, "%s,%s,+=", ARG(1), ARG(0));
		break;
	case ARM_INS_LDR:
		r_strbuf_appendf (&op->esil, "%s,%d,+,[4],%s,=",
			MEMBASE(1), MEMDISP(1), REG(0));
		break;
	case ARM_INS_LDRB:
		r_strbuf_appendf (&op->esil, "%s,%d,+,[1],%s,=",
			MEMBASE(1), MEMDISP(1), REG(0));
		break;
	}
	return 0;
}
コード例 #26
0
ファイル: anal_ppc_cs.c プロジェクト: agatti/radare2
static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
	static csh handle = 0;
	static int omode = -1, obits = -1;
	int n, ret;
	cs_insn *insn;
	int mode = (a->bits == 64) ? CS_MODE_64 : (a->bits == 32) ? CS_MODE_32 : 0;
	mode |= a->big_endian ? CS_MODE_BIG_ENDIAN : CS_MODE_LITTLE_ENDIAN;

	op->delay = 0;
	op->type = R_ANAL_OP_TYPE_NULL;
	op->jump = UT64_MAX;
	op->fail = UT64_MAX;
	op->ptr = op->val = UT64_MAX;
	if (a->cpu && strncmp (a->cpu, "vle", 3) == 0) {
		// vle is big-endian only
		if (!a->big_endian) {
			return -1;
		}
		ret = analop_vle (a, op, addr, buf, len);
		if (ret >= 0) {
			return op->size;
		}
	}

	if (mode != omode || a->bits != obits) {
		cs_close (&handle);
		handle = 0;
		omode = mode;
		obits = a->bits;
	}
	if (handle == 0) {
		ret = cs_open (CS_ARCH_PPC, mode, &handle);
		if (ret != CS_ERR_OK) {
			return -1;
		}
		cs_option (handle, CS_OPT_DETAIL, CS_OPT_ON);
	}
	op->size = 4;

	r_strbuf_init (&op->esil);
	r_strbuf_set (&op->esil, "");

	// capstone-next
	n = cs_disasm (handle, (const ut8*)buf, len, addr, 1, &insn);
	if (n < 1) {
		op->type = R_ANAL_OP_TYPE_ILL;
	} else {
		opex (&op->opex, handle, insn);
		struct Getarg gop = {
			.handle = handle,
			.insn = insn,
			.bits = a->bits
		};
		op->size = insn->size;
		op->id = insn->id;
		switch (insn->id) {
#if CS_API_MAJOR >= 4
		case PPC_INS_CMPB:
#endif
		case PPC_INS_CMPD:
		case PPC_INS_CMPDI:
		case PPC_INS_CMPLD:
		case PPC_INS_CMPLDI:
		case PPC_INS_CMPLW:
		case PPC_INS_CMPLWI:
		case PPC_INS_CMPW:
		case PPC_INS_CMPWI:
			op->type = R_ANAL_OP_TYPE_CMP;
			op->sign = true;
			if (ARG (2)[0] == '\0') esilprintf (op, "%s,%s,-,0xff,&,cr0,=", ARG (1), ARG (0));
			else esilprintf (op, "%s,%s,-,0xff,&,%s,=", ARG (2), ARG (1), ARG (0));
			break;
		case PPC_INS_MFLR:
			op->type = R_ANAL_OP_TYPE_MOV;
			esilprintf (op, "lr,%s,=", ARG (0));
			break;
		case PPC_INS_MTLR:
			op->type = R_ANAL_OP_TYPE_MOV;
			esilprintf (op, "%s,lr,=", ARG (0));
			break;
		case PPC_INS_MR:
		case PPC_INS_LI:
			op->type = R_ANAL_OP_TYPE_MOV;
			esilprintf (op, "%s,%s,=", ARG (1), ARG (0));
			break;
		case PPC_INS_LIS:
			op->type = R_ANAL_OP_TYPE_MOV;
			esilprintf (op, "%s0000,%s,=", ARG (1), ARG (0));
			break;
		case PPC_INS_CLRLWI:
			op->type = R_ANAL_OP_TYPE_AND;
			esilprintf (op, "%s,%s,&,%s,=", ARG (1), cmask32 (ARG (2), "0x1F"), ARG (0));
			break;
		case PPC_INS_RLWINM:
			op->type = R_ANAL_OP_TYPE_ROL;
			esilprintf (op, "%s,%s,<<<,%s,&,%s,=", ARG (2), ARG (1), cmask32 (ARG (3), ARG (4)), ARG (0));
			break;
		case PPC_INS_SC:
			op->type = R_ANAL_OP_TYPE_SWI;
			esilprintf (op, "0,$");
			break;
		case PPC_INS_EXTSB:
			op->sign = true;
			op->type = R_ANAL_OP_TYPE_MOV;
			if (a->bits == 64) esilprintf (op, "%s,0x80,&,?{,0xFFFFFFFFFFFFFF00,%s,|,%s,=,}", ARG (1), ARG (1), ARG (0));
			else esilprintf (op, "%s,0x80,&,?{,0xFFFFFF00,%s,|,%s,=,}", ARG (1), ARG (1), ARG (0));
			break;
		case PPC_INS_EXTSH:
			op->sign = true;
			if (a->bits == 64) esilprintf (op, "%s,0x8000,&,?{,0xFFFFFFFFFFFF0000,%s,|,%s,=,}", ARG (1), ARG (1), ARG (0));
			else esilprintf (op, "%s,0x8000,&,?{,0xFFFF0000,%s,|,%s,=,}", ARG (1), ARG (1), ARG (0));
			break;
		case PPC_INS_EXTSW:
			op->sign = true;
			esilprintf (op, "%s,0x80000000,&,?{,0xFFFFFFFF00000000,%s,|,%s,=,}", ARG (1), ARG (1), ARG (0));
			break;
		case PPC_INS_SYNC:
		case PPC_INS_ISYNC:
		case PPC_INS_LWSYNC:
		case PPC_INS_MSYNC:
		case PPC_INS_PTESYNC:
		case PPC_INS_TLBSYNC:
		case PPC_INS_SLBIA:
		case PPC_INS_SLBIE:
		case PPC_INS_SLBMFEE:
		case PPC_INS_SLBMTE:
		case PPC_INS_EIEIO:
		case PPC_INS_NOP:
			op->type = R_ANAL_OP_TYPE_NOP;
			esilprintf (op, ",");
			break;
		case PPC_INS_STW:
		case PPC_INS_STWU:
		case PPC_INS_STWUX:
		case PPC_INS_STWX:
		case PPC_INS_STWCX:
			op->type = R_ANAL_OP_TYPE_STORE;
			esilprintf (op, "%s,%s", ARG (0), ARG2 (1, "=[4]"));
			break;
		case PPC_INS_STWBRX:
			op->type = R_ANAL_OP_TYPE_STORE;
			break;
		case PPC_INS_STB:
		case PPC_INS_STBU:
			op->type = R_ANAL_OP_TYPE_STORE;
			esilprintf (op, "%s,%s", ARG (0), ARG2 (1, "=[1]"));
			break;
		case PPC_INS_STH:
		case PPC_INS_STHU:
			op->type = R_ANAL_OP_TYPE_STORE;
			esilprintf (op, "%s,%s", ARG (0), ARG2 (1, "=[2]"));
			break;
		case PPC_INS_STD:
		case PPC_INS_STDU:
			op->type = R_ANAL_OP_TYPE_STORE;
			esilprintf (op, "%s,%s", ARG (0), ARG2 (1, "=[8]"));
			break;
		case PPC_INS_LBZ:
#if CS_API_MAJOR >= 4
		case PPC_INS_LBZCIX:
#endif
		case PPC_INS_LBZU:
		case PPC_INS_LBZUX:
		case PPC_INS_LBZX:
			op->type = R_ANAL_OP_TYPE_LOAD;
			esilprintf (op, "%s,%s,=", ARG2 (1, "[1]"), ARG (0));
			break;
		case PPC_INS_LD:
		case PPC_INS_LDARX:
#if CS_API_MAJOR >= 4
		case PPC_INS_LDCIX:
#endif
		case PPC_INS_LDU:
		case PPC_INS_LDUX:
		case PPC_INS_LDX:
			op->type = R_ANAL_OP_TYPE_LOAD;
			esilprintf (op, "%s,%s,=", ARG2 (1, "[8]"), ARG (0));
			break;
		case PPC_INS_LDBRX:
			op->type = R_ANAL_OP_TYPE_LOAD;
			break;
		case PPC_INS_LFD:
		case PPC_INS_LFDU:
		case PPC_INS_LFDUX:
		case PPC_INS_LFDX:
		case PPC_INS_LFIWAX:
		case PPC_INS_LFIWZX:
		case PPC_INS_LFS:
		case PPC_INS_LFSU:
		case PPC_INS_LFSUX:
		case PPC_INS_LFSX:
			op->type = R_ANAL_OP_TYPE_LOAD;
			esilprintf (op, "%s,%s,=", ARG2 (1, "[4]"), ARG (0));
			break;
		case PPC_INS_LHA:
		case PPC_INS_LHAU:
		case PPC_INS_LHAUX:
		case PPC_INS_LHAX:
		case PPC_INS_LHZ:
		case PPC_INS_LHZU:
			op->type = R_ANAL_OP_TYPE_LOAD;
			esilprintf (op, "%s,%s,=", ARG2 (1, "[2]"), ARG (0));
			break;
		case PPC_INS_LHBRX:
			op->type = R_ANAL_OP_TYPE_LOAD;
			break;
		case PPC_INS_LWA:
		case PPC_INS_LWARX:
		case PPC_INS_LWAUX:
		case PPC_INS_LWAX:
		case PPC_INS_LWZ:
#if CS_API_MAJOR >= 4
		case PPC_INS_LWZCIX:
#endif
		case PPC_INS_LWZU:
		case PPC_INS_LWZUX:
		case PPC_INS_LWZX:
			op->type = R_ANAL_OP_TYPE_LOAD;
			esilprintf (op, "%s,%s,=", ARG2 (1, "[4]"), ARG (0));
			break;
		case PPC_INS_LWBRX:
			op->type = R_ANAL_OP_TYPE_LOAD;
			break;
		case PPC_INS_SLW:
		case PPC_INS_SLWI:
			op->type = R_ANAL_OP_TYPE_SHL;
			esilprintf (op, "%s,%s,<<,%s,=", ARG (2), ARG (1), ARG (0));
			break;
		case PPC_INS_SRW:
		case PPC_INS_SRWI:
			op->type = R_ANAL_OP_TYPE_SHR;
			esilprintf (op, "%s,%s,>>,%s,=", ARG (2), ARG (1), ARG (0));
			break;
		case PPC_INS_MULLI:
			op->sign = true;
		case PPC_INS_MULLW:
		case PPC_INS_MULLD:
			op->type = R_ANAL_OP_TYPE_MUL;
			esilprintf (op, "%s,%s,*,%s,=", ARG (2), ARG (1), ARG (0));
			break;
		case PPC_INS_SUB:
		case PPC_INS_SUBC:
		case PPC_INS_SUBF:
		case PPC_INS_SUBFIC:
		case PPC_INS_SUBFZE:
			op->type = R_ANAL_OP_TYPE_SUB;
			esilprintf (op, "%s,%s,-,%s,=", ARG (1), ARG (2), ARG (0));
			break;
		case PPC_INS_ADD:
		case PPC_INS_ADDI:
			op->sign = true;
			op->type = R_ANAL_OP_TYPE_ADD;
			esilprintf (op, "%s,%s,+,%s,=", ARG (2), ARG (1), ARG (0));
			break;
		case PPC_INS_ADDC:
		case PPC_INS_ADDIC:
			op->type = R_ANAL_OP_TYPE_ADD;
			esilprintf (op, "%s,%s,+,%s,=", ARG (2), ARG (1), ARG (0));
			break;
		case PPC_INS_ADDE:
		case PPC_INS_ADDIS:
		case PPC_INS_ADDME:
		case PPC_INS_ADDZE:
			op->type = R_ANAL_OP_TYPE_ADD;
			esilprintf (op, "%s,%s,+,%s,=", ARG (2), ARG (1), ARG (0));
			break;
		case PPC_INS_MTSPR:
			op->type = R_ANAL_OP_TYPE_MOV;
			esilprintf (op, "%s,%s,=", ARG (1), PPCSPR (0));
			break;
		case PPC_INS_BCTR: // switch table here
			op->type = R_ANAL_OP_TYPE_UJMP;
			esilprintf (op, "ctr,pc,=");
			break;
		case PPC_INS_BCTRL: // switch table here
			op->type = R_ANAL_OP_TYPE_CALL;
			esilprintf (op, "pc,lr,=,ctr,pc,=");
			break;
		case PPC_INS_B:
		case PPC_INS_BC:
			op->jump = ARG (1)[0] == '\0' ? IMM (0) : IMM (1);
			op->type = R_ANAL_OP_TYPE_CJMP;
			op->fail = addr + op->size;
			switch (insn->detail->ppc.bc) {
			case PPC_BC_LT:
				if (ARG (1)[0] == '\0') {
					esilprintf (op, "0,cr0,<,?{,%s,pc,=,},", ARG (0));
				} else {
					esilprintf (op, "0,%s,<,?{,%s,pc,=,},", ARG (0), ARG (1));
				}
				break;
			case PPC_BC_LE:
				if (ARG (1)[0] == '\0') {
					esilprintf (op, "0,cr0,<=,?{,%s,pc,=,},", ARG (0));
				} else {
					esilprintf (op, "0,%s,<=,?{,%s,pc,=,},", ARG (0), ARG (1));
				}
				break;
			case PPC_BC_EQ:
				if (ARG (1)[0] == '\0') {
					esilprintf (op, "0,cr0,==,?{,%s,pc,=,},", ARG (0));
				} else {
					esilprintf (op, "0,%s,==,?{,%s,pc,=,},", ARG (0), ARG (1));
				}
				break;
			case PPC_BC_GE:
				if (ARG (1)[0] == '\0') {
					esilprintf (op, "0,cr0,>=,?{,%s,pc,=,},", ARG (0));
				} else {
					esilprintf (op, "0,%s,>=,?{,%s,pc,=,},", ARG (0), ARG (1));
				}
				break;
			case PPC_BC_GT:
				if (ARG (1)[0] == '\0') {
					esilprintf (op, "0,cr0,>,?{,%s,pc,=,},", ARG (0));
				} else {
					esilprintf (op, "0,%s,>,?{,%s,pc,=,},", ARG (0), ARG (1));
				}
				break;
			case PPC_BC_NE:
				if (ARG (1)[0] == '\0') {
					esilprintf (op, "cr0,?{,%s,pc,=,},", ARG (0));
				} else {
					esilprintf (op, "%s,?{,%s,pc,=,},", ARG (0), ARG (1));
				}
				break;
			case PPC_BC_INVALID:
				op->type = R_ANAL_OP_TYPE_JMP;
				esilprintf (op, "%s,pc,=", ARG (0));
			case PPC_BC_UN: // unordered
			case PPC_BC_NU: // not unordered
			case PPC_BC_SO: // summary overflow
			case PPC_BC_NS: // not summary overflow
			default:
				break;
			}
			break;
		case PPC_INS_BA:
			switch (insn->detail->ppc.operands[0].type) {
			case PPC_OP_CRX:
				op->type = R_ANAL_OP_TYPE_CJMP;
				op->fail = addr + op->size;
				break;
			case PPC_OP_REG:
				if (op->type == R_ANAL_OP_TYPE_CJMP) {
					op->type = R_ANAL_OP_TYPE_UCJMP;
				} else {
					op->type = R_ANAL_OP_TYPE_CJMP;
				}
				op->jump = IMM (1);
				op->fail = addr + op->size;
				//op->type = R_ANAL_OP_TYPE_UJMP;
			default:
				break;
			}
			break;
		case PPC_INS_BDNZ:
			op->type = R_ANAL_OP_TYPE_CJMP;
			op->jump = IMM (0);
			op->fail = addr + op->size;
			esilprintf (op, "1,ctr,-=,ctr,?{,%s,pc,=,}", ARG (0));
			break;
		case PPC_INS_BDNZA:
			op->type = R_ANAL_OP_TYPE_CJMP;
			op->jump = IMM (0);
			op->fail = addr + op->size;
			break;
		case PPC_INS_BDNZL:
			op->type = R_ANAL_OP_TYPE_CJMP;
			op->jump = IMM (0);
			op->fail = addr + op->size;
			break;
		case PPC_INS_BDNZLA:
			op->type = R_ANAL_OP_TYPE_CJMP;
			op->jump = IMM (0);
			op->fail = addr + op->size;
			break;
		case PPC_INS_BDNZLR:
			op->type = R_ANAL_OP_TYPE_CJMP;
			op->fail = addr + op->size;
			esilprintf (op, "1,ctr,-=,ctr,?{,lr,pc,=,},");
			break;
		case PPC_INS_BDNZLRL:
			op->fail = addr + op->size;
			op->type = R_ANAL_OP_TYPE_CJMP;
			break;
		case PPC_INS_BDZ:
			op->type = R_ANAL_OP_TYPE_CJMP;
			op->jump = IMM (0);
			op->fail = addr + op->size;
			esilprintf (op, "1,ctr,-=,ctr,0,==,?{,%s,pc,=,}", ARG (0));
			break;
		case PPC_INS_BDZA:
			op->type = R_ANAL_OP_TYPE_CJMP;
			op->jump = IMM (0);
			op->fail = addr + op->size;
			break;
		case PPC_INS_BDZL:
			op->type = R_ANAL_OP_TYPE_CJMP;
			op->jump = IMM (0);
			op->fail = addr + op->size;
			break;
		case PPC_INS_BDZLA:
			op->type = R_ANAL_OP_TYPE_CJMP;
			op->jump = IMM (0);
			op->fail = addr + op->size;
			break;
		case PPC_INS_BDZLR:
			op->type = R_ANAL_OP_TYPE_CJMP;
			op->fail = addr + op->size;
			esilprintf (op, "1,ctr,-=,ctr,0,==,?{,lr,pc,=,}");
			break;
		case PPC_INS_BDZLRL:
			op->type = R_ANAL_OP_TYPE_CJMP;
			op->fail = addr + op->size;
			break;
		case PPC_INS_BLR:
		case PPC_INS_BLRL:
		case PPC_INS_BCLR:
		case PPC_INS_BCLRL:
			op->type = R_ANAL_OP_TYPE_CRET;
			op->fail = addr + op->size;
			switch (insn->detail->ppc.bc) {
			case PPC_BC_INVALID:
				op->type = R_ANAL_OP_TYPE_RET;
				esilprintf (op, "lr,pc,=");
				break;
			case PPC_BC_LT:
				if (ARG (0)[0] == '\0') {
					esilprintf (op, "0,cr0,<,?{,lr,pc,=,},");
				} else {
					esilprintf (op, "0,%s,<,?{,lr,pc,=,},", ARG (0));
				}
				break;
			case PPC_BC_LE:
				if (ARG (0)[0] == '\0') {
					esilprintf (op, "0,cr0,<=,?{,lr,pc,=,},");
				} else {
					esilprintf (op, "0,%s,<=,?{,lr,pc,=,},", ARG (0));
				}
				break;
			case PPC_BC_EQ:
				if (ARG (0)[0] == '\0') {
					esilprintf (op, "0,cr0,==,?{,lr,pc,=,},");
				} else {
					esilprintf (op, "0,%s,==,?{,lr,pc,=,},", ARG (0));
				}
				break;
			case PPC_BC_GE:
				if (ARG (0)[0] == '\0') {
					esilprintf (op, "0,cr0,>=,?{,lr,pc,=,},");
				} else {
					esilprintf (op, "0,%s,>=,?{,lr,pc,=,},", ARG (0));
				}
				break;
			case PPC_BC_GT:
				if (ARG (0)[0] == '\0') {
					esilprintf (op, "0,cr0,>,?{,lr,pc,=,},");
				} else {
					esilprintf (op, "0,%s,>,?{,lr,pc,=,},", ARG (0));
				}
				break;
			case PPC_BC_NE:
				if (ARG (0)[0] == '\0') {
					esilprintf (op, "cr0,?{,lr,pc,=,},");
				} else {
					esilprintf (op, "%s,?{,lr,pc,=,},", ARG (0));
				}
				break;
			case PPC_BC_UN: // unordered
			case PPC_BC_NU: // not unordered
			case PPC_BC_SO: // summary overflow
			case PPC_BC_NS: // not summary overflow
			default:
				break;
			}
			break;
		case PPC_INS_NOR:
			op->type = R_ANAL_OP_TYPE_NOR;
			esilprintf (op, "%s,%s,|,!,%s,=", ARG (2), ARG (1), ARG (0));
			break;
		case PPC_INS_XOR:
		case PPC_INS_XORI:
			op->type = R_ANAL_OP_TYPE_XOR;
			esilprintf (op, "%s,%s,^,%s,=", ARG (2), ARG (1), ARG (0));
			break;
		case PPC_INS_XORIS:
			op->type = R_ANAL_OP_TYPE_XOR;
			esilprintf (op, "16,%s,<<,%s,^,%s,=", ARG (2), ARG (1), ARG (0));
			break;
		case PPC_INS_DIVD:
		case PPC_INS_DIVW:
			op->sign = true;
			op->type = R_ANAL_OP_TYPE_DIV;
			esilprintf (op, "%s,%s,/,%s,=", ARG (2), ARG (1), ARG (0));
			break;
		case PPC_INS_DIVDU:
		case PPC_INS_DIVWU:
			op->type = R_ANAL_OP_TYPE_DIV;
			esilprintf (op, "%s,%s,/,%s,=", ARG (2), ARG (1), ARG (0));
			break;
		case PPC_INS_BL:
		case PPC_INS_BLA:
			op->type = R_ANAL_OP_TYPE_CALL;
			op->jump = IMM (0);
			op->fail = addr + op->size;
			esilprintf (op, "pc,lr,=,%s,pc,=", ARG (0));
			break;
		case PPC_INS_TRAP:
			op->sign = true;
			op->type = R_ANAL_OP_TYPE_TRAP;
			break;
		case PPC_INS_AND:
		case PPC_INS_NAND:
		case PPC_INS_ANDI:
			op->type = R_ANAL_OP_TYPE_AND;
			esilprintf (op, "%s,%s,&,%s,=", ARG (2), ARG (1), ARG (0));
			break;
		case PPC_INS_ANDIS:
			op->type = R_ANAL_OP_TYPE_AND;
			esilprintf (op, "16,%s,<<,%s,&,%s,=", ARG (2), ARG (1), ARG (0));
			break;
		case PPC_INS_OR:
		case PPC_INS_ORI:
			op->type = R_ANAL_OP_TYPE_OR;
			esilprintf (op, "%s,%s,|,%s,=", ARG (2), ARG (1), ARG (0));
			break;
		case PPC_INS_ORIS:
			op->type = R_ANAL_OP_TYPE_OR;
			esilprintf (op, "16,%s,<<,%s,|,%s,=", ARG (2), ARG (1), ARG (0));
			break;
		case PPC_INS_MFPVR:
			op->type = R_ANAL_OP_TYPE_MOV;
			esilprintf (op, "pvr,%s,=", ARG (0));
			break;
		case PPC_INS_MFSPR:
			op->type = R_ANAL_OP_TYPE_MOV;
			esilprintf (op, "%s,%s,=", PPCSPR (1), ARG (0));
			break;
		case PPC_INS_MFCTR:
			op->type = R_ANAL_OP_TYPE_MOV;
			esilprintf (op, "ctr,%s,=", ARG (0));
			break;
		case PPC_INS_MFDCCR:
			op->type = R_ANAL_OP_TYPE_MOV;
			esilprintf (op, "dccr,%s,=", ARG (0));
			break;
		case PPC_INS_MFICCR:
			op->type = R_ANAL_OP_TYPE_MOV;
			esilprintf (op, "iccr,%s,=", ARG (0));
			break;
		case PPC_INS_MFDEAR:
			op->type = R_ANAL_OP_TYPE_MOV;
			esilprintf (op, "dear,%s,=", ARG (0));
			break;
		case PPC_INS_MFMSR:
			op->type = R_ANAL_OP_TYPE_MOV;
			esilprintf (op, "msr,%s,=", ARG (0));
			break;
		case PPC_INS_MTCTR:
			op->type = R_ANAL_OP_TYPE_MOV;
			esilprintf (op, "%s,ctr,=", ARG (0));
			break;
		case PPC_INS_MTDCCR:
			op->type = R_ANAL_OP_TYPE_MOV;
			esilprintf (op, "%s,dccr,=", ARG (0));
			break;
		case PPC_INS_MTICCR:
			op->type = R_ANAL_OP_TYPE_MOV;
			esilprintf (op, "%s,iccr,=", ARG (0));
			break;
		case PPC_INS_MTDEAR:
			op->type = R_ANAL_OP_TYPE_MOV;
			esilprintf (op, "%s,dear,=", ARG (0));
			break;
		case PPC_INS_MTMSR:
		case PPC_INS_MTMSRD:
			op->type = R_ANAL_OP_TYPE_MOV;
			esilprintf (op, "%s,msr,=", ARG (0));
			break;
			// Data Cache Block Zero
		case PPC_INS_DCBZ:
			op->type = R_ANAL_OP_TYPE_STORE;
			esilprintf (op, "%s,%s", ARG (0), ARG2 (1, ",=[128]"));
			break;
		case PPC_INS_CLRLDI:
			op->type = R_ANAL_OP_TYPE_AND;
			esilprintf (op, "%s,%s,&,%s,=", ARG (1), cmask64 (ARG (2), "0x3F"), ARG (0));
			break;
		case PPC_INS_ROTLDI:
			op->type = R_ANAL_OP_TYPE_ROL;
			esilprintf (op, "%s,%s,<<<,%s,=", ARG (2), ARG (1), ARG (0));
			break;
		case PPC_INS_RLDCL:
		case PPC_INS_RLDICL:
			op->type = R_ANAL_OP_TYPE_ROL;
			esilprintf (op, "%s,%s,<<<,%s,&,%s,=", ARG (2), ARG (1), cmask64 (ARG (3), "0x3F"), ARG (0));
			break;
		case PPC_INS_RLDCR:
		case PPC_INS_RLDICR:
			op->type = R_ANAL_OP_TYPE_ROL;
			esilprintf (op, "%s,%s,<<<,%s,&,%s,=", ARG (2), ARG (1), cmask64 (0, ARG (3)), ARG (0));
			break;
		}
		if (a->fillval) {
			op_fillval (op, handle, insn);
		}
		r_strbuf_fini (&op->esil);
		cs_free (insn, n);
		//cs_close (&handle);
	}
	return op->size;
}

static int archinfo(RAnal *a, int q) {
	if (a->cpu && !strncmp (a->cpu, "vle", 3)) {
		return 2;
	}
	return 4;
}

RAnalPlugin r_anal_plugin_ppc_cs = {
	.name = "ppc",
	.desc = "Capstone PowerPC analysis",
	.license = "BSD",
	.esil = true,
	.arch = "ppc",
	.bits = 32 | 64,
	.archinfo = archinfo,
	.op = &analop,
	.set_reg_profile = &set_reg_profile,
};

#ifndef CORELIB
RLibStruct radare_plugin = {
	.type = R_LIB_TYPE_ANAL,
	.data = &r_anal_plugin_ppc_cs,
	.version = R2_VERSION
};
コード例 #27
0
ファイル: anal_mips_cs.c プロジェクト: 13572293130/radare2
static int analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len, csh *handle, cs_insn *insn) {
	char str[8][32];
	int i;
	r_strbuf_init (&op->esil);
	r_strbuf_set (&op->esil, "");

	if (insn) {
		// caching operands
		for (i=0; i<insn->detail->mips.op_count && i<8; i++) {
			*str[i]=0;
			ARG (i);
		}
	}

	if (insn)
	switch (insn->id) {
	case MIPS_INS_NOP:
		r_strbuf_setf (&op->esil, ",");
		break;
	case MIPS_INS_BREAK:
		r_strbuf_setf (&op->esil, "%s,%s,TRAP", ARG (0), ARG (0));
		break;
	case MIPS_INS_SW:
	case MIPS_INS_SWL:
	case MIPS_INS_SWR:
		r_strbuf_appendf (&op->esil, "%s,%s,=[4]",
			ARG (0), ARG (1));
		break;
	case MIPS_INS_SH:
		r_strbuf_appendf (&op->esil, "%s,%s,=[2]",
			ARG (0), ARG (1));
		break;
	case MIPS_INS_SWC1:
	case MIPS_INS_SWC2:
		r_strbuf_setf (&op->esil, "%s,$", ARG (1));
		break;
	case MIPS_INS_SB:
		r_strbuf_appendf (&op->esil, "%s,%s,=[1]",
			ARG (0), ARG (1));
		break;
	case MIPS_INS_CMP:
	case MIPS_INS_CMPU:
	case MIPS_INS_CMPGU:
	case MIPS_INS_CMPGDU:
	case MIPS_INS_CMPI:
		r_strbuf_appendf (&op->esil, "%s,%s,==", ARG (1), ARG (0));
		break;
	case MIPS_INS_SHRAV:
	case MIPS_INS_SHRAV_R:
	case MIPS_INS_SHRA:
	case MIPS_INS_SHRA_R:
	case MIPS_INS_SRA:
		r_strbuf_appendf (&op->esil, "%s,%s,>>,31,%s,>>,?{,32,%s,-,%s,1,<<,1,-,<<,}{,0,},|,%s,=,",
			ARG (2), ARG (1), ARG (1), ARG (2), ARG (2), ARG (0));
		break;
	case MIPS_INS_SHRL:
		// suffix 'S' forces conditional flag to be updated
	case MIPS_INS_SRLV:
	case MIPS_INS_SRL:
		r_strbuf_appendf (&op->esil, "%s,%s,>>,%s,=", ARG (2), ARG (1), ARG (0));
		break;
	case MIPS_INS_SLLV:
	case MIPS_INS_SLL:
		r_strbuf_appendf (&op->esil, "%s,%s,<<,%s,=", ARG (2), ARG (1), ARG (0));
		break;
	case MIPS_INS_BAL:
	case MIPS_INS_JAL:
		r_strbuf_appendf (&op->esil, ES_TRAP_DS () "," ES_CALL_D ("%s"), ARG (0));
		break;
	case MIPS_INS_JALR:
	case MIPS_INS_JALRS:
		if (OPCOUNT () < 2) {
			r_strbuf_appendf (&op->esil, ES_TRAP_DS () "," ES_CALL_D ("%s"), ARG (0));
		} else {
			PROTECT_ZERO () {
				r_strbuf_appendf (&op->esil, ES_TRAP_DS () "," ES_CALL_DR ("%s","%s"), ARG (0), ARG (1));
			}
		}
		break;
	case MIPS_INS_JALRC: // no delay
		if (OPCOUNT () < 2) {
			r_strbuf_appendf (&op->esil, ES_TRAP_DS () "," ES_CALL_ND ("%s"), ARG (0));
		} else {
			PROTECT_ZERO () {
				r_strbuf_appendf (&op->esil, ES_TRAP_DS () "," ES_CALL_NDR ("%s","%s"), ARG (0), ARG (1));
			}
		}
		break;
	case MIPS_INS_JRADDIUSP:
		// increment stackpointer in X and jump to %ra
		r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",%d,sp,+=,"ES_J ("ra"), ARG (0));
		break;
	case MIPS_INS_JR:
	case MIPS_INS_JRC:
	case MIPS_INS_J:
	case MIPS_INS_B: // ???
		// jump to address with conditional
		r_strbuf_appendf (&op->esil, ES_TRAP_DS () "," ES_J ("%s"), ARG (0));
		break;
	case MIPS_INS_BNE:  // bne $s, $t, offset
		r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",%s,%s,==,$z,!,?{,"ES_J ("%s")",}",
			ARG (0), ARG (1), ARG (2));
		break;
	case MIPS_INS_BEQ:
		r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",%s,%s,==,$z,?{,"ES_J ("%s")",}",
			ARG (0), ARG (1), ARG (2));
		break;
	case MIPS_INS_BZ:
	case MIPS_INS_BEQZ:
	case MIPS_INS_BEQZC:
		r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",%s,0,==,$z,?{,"ES_J ("%s")",}",
			ARG (0), ARG (1));
		break;
	case MIPS_INS_BNEZ:
		r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",%s,0,==,$z,!,?{,"ES_J ("%s")",}",
			ARG (0), ARG (1));
		break;
	case MIPS_INS_BEQZALC:
		r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",%s,0,==,$z,?{,"ES_CALL_ND ("%s")",}",
			ARG (0), ARG (1));
		break;
	case MIPS_INS_BLEZ:
	case MIPS_INS_BLEZC:
		r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",0,%s,==,$z,?{,"ES_J ("%s")",BREAK,},",
			ARG (0), ARG (1));
		r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",1,"ES_IS_NEGATIVE ("%s")",==,$z,?{,"ES_J ("%s")",}",
			ARG (0), ARG (1));
		break;
	case MIPS_INS_BGEZ:
	case MIPS_INS_BGEZC:
		r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",0,"ES_IS_NEGATIVE ("%s")",==,$z,?{,"ES_J ("%s")",}",
			ARG (0), ARG (1));
		break;
	case MIPS_INS_BGEZAL:
		r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",0,"ES_IS_NEGATIVE ("%s")",==,$z,?{,"ES_CALL_D ("%s")",}",
			ARG (0), ARG (1));
		break;
	case MIPS_INS_BGEZALC:
		r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",0,"ES_IS_NEGATIVE ("%s")",==,$z,?{,"ES_CALL_ND ("%s")",}",
			ARG (0), ARG (1));
		break;
	case MIPS_INS_BGTZALC:
		r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",0,%s,==,$z,?{,BREAK,},", ARG(0));
		r_strbuf_appendf (&op->esil, "0,"ES_IS_NEGATIVE ("%s")",==,$z,?{,"ES_CALL_ND ("%s")",}",
			ARG (0), ARG (1));
		break;
	case MIPS_INS_BLTZAL:
		r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",1,"ES_IS_NEGATIVE ("%s")",==,$z,?{,"ES_CALL_D ("%s")",}", ARG(0), ARG(1));
		break;
	case MIPS_INS_BLTZ:
	case MIPS_INS_BLTZC:
		r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",1,"ES_IS_NEGATIVE ("%s")",==,$z,?{,"ES_J ("%s")",}",
			ARG (0), ARG (1));
		break;
	case MIPS_INS_BGTZ:
	case MIPS_INS_BGTZC:
		r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",0,%s,==,$z,?{,BREAK,},", ARG (0));
		r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",0,"ES_IS_NEGATIVE ("%s")",==,$z,?{,"ES_J("%s")",}",
			ARG (0), ARG (1));		
		break;
	case MIPS_INS_BTEQZ:
		r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",0,t,==,$z,?{,"ES_J ("%s")",}", ARG (0));
		break;
	case MIPS_INS_BTNEZ:
		r_strbuf_appendf (&op->esil, ES_TRAP_DS () ",0,t,==,$z,!,?{,"ES_J ("%s")",}", ARG (0));
		break;
	case MIPS_INS_MOV:
	case MIPS_INS_MOVE:
		PROTECT_ZERO () {
			r_strbuf_appendf (&op->esil, "%s,%s,=", ARG (1), REG (0));
		}
		break;
	case MIPS_INS_MOVZ:
	case MIPS_INS_MOVF:
		PROTECT_ZERO () {
			r_strbuf_appendf (&op->esil, "0,%s,==,$z,?{,%s,%s,=,}",
				ARG (2), ARG (1), REG (0));
		}
		break;
	case MIPS_INS_MOVT:
		PROTECT_ZERO () {
			r_strbuf_appendf (&op->esil, "1,%s,==,$z,?{,%s,%s,=,}",
				ARG (2), ARG (1), REG (0));
		}
		break;
	case MIPS_INS_FSUB:
	case MIPS_INS_SUB:
		PROTECT_ZERO () {
			r_strbuf_appendf(&op->esil, "%s,%s,-,%s,=",
				ARG (1), ARG (2), ARG (0));
			//r_strbuf_appendf(&op->esil, "%s,%s,>,?{,1,TRAP,}{,%s,%s,-,%s,=",
			//	ARG (1), ARG (2), ARG (1), ARG (2), ARG (0));
		}
		break;
	case MIPS_INS_SUBU:
	case MIPS_INS_DSUB:
	case MIPS_INS_DSUBU:
		{
		const char *arg0 = ARG(0);
		const char *arg1 = ARG(1);
		const char *arg2 = ARG(2);
		r_strbuf_appendf (&op->esil, "%s,%s,-,%s,=",
			arg2, arg1, arg0);
		}
		break;
	case MIPS_INS_NEG:
	case MIPS_INS_NEGU:
		r_strbuf_appendf (&op->esil, "%s,0,-,%s,=,",
			ARG (1), ARG (0));
		break;

	/** signed -- sets overflow flag */
	case MIPS_INS_ADD:
		{
		PROTECT_ZERO () {
			r_strbuf_appendf(&op->esil, "%s,%s,-,%s,=",
				ARG (1), ARG (2), ARG (0));
#if 0
			r_strbuf_appendf (&op->esil,
				"0,32,%s,%s,+,>>,>,?{,1,TRAP,}{,%s,%s,+,%s,=,}",
				ARG(2), ARG(1), ARG(2), ARG(1), ARG(0));
#endif
		}
		}
		break;
	case MIPS_INS_ADDI:
		PROTECT_ZERO () {
			r_strbuf_appendf (&op->esil, "0,32,%s,0xffffffff,&,%s,+,>>,>,?{,1,TRAP,}{,%s,%s,+,%s,=,}",
				ARG(2), ARG(1), ARG(2), ARG(1), ARG(0));
		}
		break;
	case MIPS_INS_DADD:
	case MIPS_INS_DADDI:
	/** unsigned */
	case MIPS_INS_ADDU:
	case MIPS_INS_ADDIU:
	case MIPS_INS_DADDIU:
		{
		const char *arg0 = ARG(0);
		const char *arg1 = ARG(1);
		const char *arg2 = ARG(2);
		PROTECT_ZERO () {
			if (*arg2 == '-') {
				r_strbuf_appendf (&op->esil, "%s,%s,-,%s,=",
						arg2+1, arg1, arg0);
			} else {
				r_strbuf_appendf (&op->esil, "%s,%s,+,%s,=",
						arg2, arg1, arg0);
			}
		}
		}
		break;
	case MIPS_INS_LI:
		r_strbuf_appendf (&op->esil, "0x%"PFMT64x",%s,=", IMM(1), ARG(0));
		break;
	case MIPS_INS_LUI:
		r_strbuf_appendf (&op->esil, "0x%"PFMT64x"0000,%s,=", IMM(1), ARG(0));
		break;
	case MIPS_INS_LB:
	case MIPS_INS_LBU:
		//one of these is wrong
		ESIL_LOAD ("1");
		break;
	case MIPS_INS_LW:
	case MIPS_INS_LWC1:
	case MIPS_INS_LWC2:
	case MIPS_INS_LWL:
	case MIPS_INS_LWR:
	case MIPS_INS_LWU:
	case MIPS_INS_LL:
	case MIPS_INS_LLD:
	case MIPS_INS_LD:
	case MIPS_INS_LDI:
	case MIPS_INS_LDL:
	case MIPS_INS_LDC1:
	case MIPS_INS_LDC2:
		ESIL_LOAD ("4");
		break;

	case MIPS_INS_LWX:
	case MIPS_INS_LH:
	case MIPS_INS_LHU:
	case MIPS_INS_LHX:
		ESIL_LOAD ("2");
		break;

	case MIPS_INS_AND:
	case MIPS_INS_ANDI:
		{
		const char *arg0 = ARG(0);
		const char *arg1 = ARG(1);
		const char *arg2 = ARG(2);
		r_strbuf_appendf (&op->esil, "%s,%s,&,%s,=",
			arg2, arg1, arg0);
		}
		break;
	case MIPS_INS_OR:
	case MIPS_INS_ORI:
		{
		const char *arg0 = ARG(0);
		const char *arg1 = ARG(1);
		const char *arg2 = ARG(2);
		PROTECT_ZERO () {
			r_strbuf_appendf (&op->esil, "%s,%s,|,%s,=",
				arg2, arg1, arg0);
		}
		}
		break;
	case MIPS_INS_XOR:
	case MIPS_INS_XORI:
		{
		const char *arg0 = ARG(0);
		const char *arg1 = ARG(1);
		const char *arg2 = ARG(2);
		PROTECT_ZERO () {
			r_strbuf_appendf (&op->esil, "%s,%s,^,%s,=",
				arg2, arg1, arg0);
		}
		}
		break;
	case MIPS_INS_NOR:
		{
		const char *arg0 = ARG(0);
		const char *arg1 = ARG(1);
		const char *arg2 = ARG(2);
		PROTECT_ZERO () {
			r_strbuf_appendf (&op->esil, "%s,%s,|,0xffffffff,^,%s,=",
				arg2, arg1, arg0);
		}
		}
		break;
	case MIPS_INS_SLT:
	case MIPS_INS_SLTI:
		if (OPCOUNT () < 3) {
			r_strbuf_appendf (&op->esil,
				ES_IS_NEGATIVE ("%s")","
				ES_IS_NEGATIVE ("%s")","
				"==,$z,?{,"
					"%s,%s,<,t,=,"
				"}{,"
					"%s,%s,>=,t,=,"
				"}",

				ARG (1),
				ARG (0),
				ARG (1), ARG (0),
				ARG (1), ARG (0));
		} else {
			r_strbuf_appendf (&op->esil,
				ES_IS_NEGATIVE ("%s")","
				ES_IS_NEGATIVE ("%s")","
				"==,$z,?{,"
					"%s,%s,<,%s,=,"
				"}{,"
					"%s,%s,>=,%s,=,"
				"}",

				ARG (2),
				ARG (1),
				ARG (2), ARG (1), ARG (0),
				ARG (2), ARG (1), ARG (0));
		}
		break;
	case MIPS_INS_SLTU:
	case MIPS_INS_SLTIU:
		if (OPCOUNT () < 3) {
			r_strbuf_appendf (&op->esil, "%s,0xffffffff,&,%s,0xffffffff,&,<,t,=",
				ARG (1), ARG (0));
		} else {
			r_strbuf_appendf (&op->esil, "%s,0xffffffff,&,%s,0xffffffff,&,<,%s,=",
				ARG (2), ARG (1), ARG (0));
		}
		break;
	case MIPS_INS_MULT:
	case MIPS_INS_MULTU:
		r_strbuf_appendf (&op->esil,
			"%s,%s,*,0xffffffff,&,lo,=,"
			ES_SIGN_EXT64 ("lo")
			",32,%s,%s,*,>>,0xffffffff,&,hi,=,"
			ES_SIGN_EXT64 ("hi"),

			ARG (0), ARG (1), ARG (0), ARG (1));
		break;
	case MIPS_INS_MFLO:
		PROTECT_ZERO () {
			r_strbuf_appendf (&op->esil, "lo,%s,=", REG (0));
		}
		break;
	case MIPS_INS_MFHI:
		PROTECT_ZERO () {
			r_strbuf_appendf (&op->esil, "hi,%s,=", REG (0));
		}
		break;
	case MIPS_INS_MTLO:
		r_strbuf_appendf (&op->esil, "%s,lo,=,"ES_SIGN_EXT64 ("lo"), REG (0));
		break;
	case MIPS_INS_MTHI:
		r_strbuf_appendf (&op->esil, "%s,hi,=,"ES_SIGN_EXT64 ("hi"), REG (0));
		break;
#if 0
	// could not test div
	case MIPS_INS_DIV:
	case MIPS_INS_DIVU:
	case MIPS_INS_DDIV:
	case MIPS_INS_DDIVU:
		PROTECT_ZERO () {
			// 32 bit needs sign extend
			r_strbuf_appendf (&op->esil, "%s,%s,/,lo,=,%s,%s,%%,hi,=", REG(1), REG(0), REG(1), REG(0));
		}
		break;
#endif
	default:
		return -1;
	}
	return 0;
}
コード例 #28
0
ファイル: anal_6502.c プロジェクト: Dev-Tech-Studio/radare2
static int _6502_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len) {
	char addrbuf[64];
	const int buffsize = sizeof(addrbuf)-1;

	memset (op, '\0', sizeof (RAnalOp));
	op->size = snes_op[data[0]].len;	//snes-arch is similiar to nes/6502
	op->addr = addr;
	op->type = R_ANAL_OP_TYPE_UNK;
	r_strbuf_init (&op->esil);
	switch (data[0]) {
	case 0x02:
	case 0x03:
	case 0x04:
	case 0x07:
	case 0x0b:
	case 0x0c:
	case 0x0f:
	case 0x12:
	case 0x13:
	case 0x14:
	case 0x17:
	case 0x1a:
	case 0x1b:
	case 0x1c:
	case 0x1f:
	case 0x22:
	case 0x23:
	case 0x27:
	case 0x2b:
	case 0x2f:
	case 0x32:
	case 0x33:
	case 0x34:
	case 0x37:
	case 0x3a:
	case 0x3b:
	case 0x3c:
	case 0x3f:
	case 0x42:
	case 0x43:
	case 0x44:
	case 0x47:
	case 0x4b:
	case 0x4f:
	case 0x52:
	case 0x53:
	case 0x54:
	case 0x57:
	case 0x5a:
	case 0x5b:
	case 0x5c:
	case 0x5f:
	case 0x62:
	case 0x63:
	case 0x64:
	case 0x67:
	case 0x6b:
	case 0x6f:
	case 0x72:
	case 0x73:
	case 0x74:
	case 0x77:
	case 0x7a:
	case 0x7b:
	case 0x7c:
	case 0x7f:
	case 0x80:
	case 0x82:
	case 0x83:
	case 0x87:
	case 0x89:
	case 0x8b:
	case 0x8f:
	case 0x92:
	case 0x93:
	case 0x97:
	case 0x9b:
	case 0x9c:
	case 0x9e:
	case 0x9f:
	case 0xa3:
	case 0xa7:
	case 0xab:
	case 0xaf:
	case 0xb2:
	case 0xb3:
	case 0xb7:
	case 0xbb:
	case 0xbf:
	case 0xc2:
	case 0xc3:
	case 0xc7:
	case 0xcb:
	case 0xcf:
	case 0xd2:
	case 0xd3:
	case 0xd4:
	case 0xd7:
	case 0xda:
	case 0xdb:
	case 0xdc:
	case 0xdf:
	case 0xe2:
	case 0xe3:
	case 0xe7:
	case 0xeb:
	case 0xef:
	case 0xf2:
	case 0xf3:
	case 0xf4:
	case 0xf7:
	case 0xfa:
	case 0xfb:
	case 0xfc:
	case 0xff:
		// undocumented or not-implemented opcodes for 6502.
		// some of them might be implemented in 65816
		op->size = 1;
		op->type = R_ANAL_OP_TYPE_ILL;
		break;

	// BRK
	case 0x00: // brk
		op->cycles = 7;
		op->type = R_ANAL_OP_TYPE_SWI;
		// override 65816 code which seems to be wrong: size is 1, but pc = pc + 2
		op->size = 1;
		// PC + 2 to Stack, P to Stack  B=1 D=0 I=1. "B" is not a flag. Only its bit is pushed on the stack
		// PC was already incremented by one at this point. Needs to incremented once more
		// New PC is Interrupt Vector: $fffe. (FIXME: Confirm this is valid for all 6502)
		r_strbuf_set (&op->esil, ",1,I,=,0,D,=,flags,0x10,|,0x100,sp,+,=[1],pc,1,+,0xfe,sp,+,=[2],3,sp,-=,0xfffe,[2],pc,=");
		break;

	// FLAGS
	case 0x78: // sei
	case 0x58: // cli
	case 0x38: // sec
	case 0x18: // clc
	case 0xf8: // sed
	case 0xd8: // cld
	case 0xb8: // clv
		op->cycles = 2;
		// FIXME: what opcode for this?
		op->type = R_ANAL_OP_TYPE_NOP;
		_6502_anal_esil_flags (op, data[0]);
		break;
	// BIT
	case 0x24: // bit $ff
	case 0x2c: // bit $ffff
		op->type = R_ANAL_OP_TYPE_MOV;
		_6502_anal_esil_get_addr_pattern3 (op, data, addrbuf, buffsize, 0);
		r_strbuf_setf (&op->esil, "a,%s,[1],&,0x80,&,!,!,N,=,a,%s,[1],&,0x40,&,!,!,V,=,a,%s,[1],&,0xff,&,!,Z,=",addrbuf, addrbuf, addrbuf);
		break;
	// ADC
	case 0x69: // adc #$ff
	case 0x65: // adc $ff
	case 0x75: // adc $ff,x
	case 0x6d: // adc $ffff
	case 0x7d: // adc $ffff,x
	case 0x79: // adc $ffff,y
	case 0x61: // adc ($ff,x)
	case 0x71: // adc ($ff,y)
		// FIXME: update V
		// FIXME: support BCD mode
		op->type = R_ANAL_OP_TYPE_ADD;
		_6502_anal_esil_get_addr_pattern1 (op, data, addrbuf, buffsize);
		if (data[0] == 0x69) // immediate mode
			r_strbuf_setf (&op->esil, "%s,a,+=,C,NUM,$c7,C,=,a,+=,$c7,C,|=", addrbuf);
		else	r_strbuf_setf (&op->esil, "%s,[1],a,+=,C,NUM,$c7,C,=,a,+=,$c7,C,|=", addrbuf);
		_6502_anal_update_flags (op, _6502_FLAGS_NZ);
		// fix Z
		r_strbuf_append (&op->esil, ",a,a,=,$z,Z,=");
		break;
	// SBC
	case 0xe9: // sbc #$ff
	case 0xe5: // sbc $ff
	case 0xf5: // sbc $ff,x
	case 0xed: // sbc $ffff
	case 0xfd: // sbc $ffff,x
	case 0xf9: // sbc $ffff,y
	case 0xe1: // sbc ($ff,x)
	case 0xf1: // sbc ($ff,y)
		// FIXME: update V
		// FIXME: support BCD mode
		op->type = R_ANAL_OP_TYPE_SUB;
		_6502_anal_esil_get_addr_pattern1 (op, data, addrbuf, buffsize);
		if (data[0] == 0xe9) // immediate mode
			r_strbuf_setf (&op->esil, "C,!,%s,+,a,-=", addrbuf);
		else	r_strbuf_setf (&op->esil, "C,!,%s,[1],+,a,-=", addrbuf);
		_6502_anal_update_flags (op, _6502_FLAGS_BNZ);
		// fix Z and revert C
		r_strbuf_append (&op->esil, ",a,a,=,$z,Z,=,C,!=");
		break;
	// ORA
	case 0x09: // ora #$ff
	case 0x05: // ora $ff
	case 0x15: // ora $ff,x
	case 0x0d: // ora $ffff
	case 0x1d: // ora $ffff,x
	case 0x19: // ora $ffff,y
	case 0x01: // ora ($ff,x)
	case 0x11: // ora ($ff),y
		op->type = R_ANAL_OP_TYPE_OR;
		_6502_anal_esil_get_addr_pattern1 (op, data, addrbuf, buffsize);
		if (data[0] == 0x09) // immediate mode
			r_strbuf_setf (&op->esil, "%s,a,|=", addrbuf);
		else	r_strbuf_setf (&op->esil, "%s,[1],a,|=", addrbuf);
		_6502_anal_update_flags (op, _6502_FLAGS_NZ);
		break;
	// AND
	case 0x29: // and #$ff
	case 0x25: // and $ff
	case 0x35: // and $ff,x
	case 0x2d: // and $ffff
	case 0x3d: // and $ffff,x
	case 0x39: // and $ffff,y
	case 0x21: // and ($ff,x)
	case 0x31: // and ($ff),y
		op->type = R_ANAL_OP_TYPE_AND;
		_6502_anal_esil_get_addr_pattern1 (op, data, addrbuf, buffsize);
		if (data[0] == 0x29) // immediate mode
			r_strbuf_setf (&op->esil, "%s,a,&=", addrbuf);
		else	r_strbuf_setf (&op->esil, "%s,[1],a,&=", addrbuf);
		_6502_anal_update_flags (op, _6502_FLAGS_NZ);
		break;
	// EOR
	case 0x49: // eor #$ff
	case 0x45: // eor $ff
	case 0x55: // eor $ff,x
	case 0x4d: // eor $ffff
	case 0x5d: // eor $ffff,x
	case 0x59: // eor $ffff,y
	case 0x41: // eor ($ff,x)
	case 0x51: // eor ($ff),y
		op->type = R_ANAL_OP_TYPE_XOR;
		_6502_anal_esil_get_addr_pattern1 (op, data, addrbuf, buffsize);
		if (data[0] == 0x49) // immediate mode
			r_strbuf_setf (&op->esil, "%s,a,^=", addrbuf);
		else	r_strbuf_setf (&op->esil, "%s,[1],a,^=", addrbuf);
		_6502_anal_update_flags (op, _6502_FLAGS_NZ);
		break;
	// ASL
	case 0x0a: // asl a
	case 0x06: // asl $ff
	case 0x16: // asl $ff,x
	case 0x0e: // asl $ffff
	case 0x1e: // asl $ffff,x
		op->type = R_ANAL_OP_TYPE_SHL;
		if (data[0] == 0x0a) {
			r_strbuf_set (&op->esil, "1,a,<<=,$c7,C,=,a,a,=");
		} else  {
			_6502_anal_esil_get_addr_pattern2 (op, data, addrbuf, buffsize, 'x');
			r_strbuf_setf (&op->esil, "1,%s,[1],<<,%s,=[1],$c7,C,=", addrbuf, addrbuf);
		}
		_6502_anal_update_flags (op, _6502_FLAGS_NZ);
		break;
	// LSR
	case 0x4a: // lsr a
	case 0x46: // lsr $ff
	case 0x56: // lsr $ff,x
	case 0x4e: // lsr $ffff
	case 0x5e: // lsr $ffff,x
		op->type = R_ANAL_OP_TYPE_SHR;
		if (data[0] == 0x4a) {
			r_strbuf_set (&op->esil, "1,a,&,C,=,1,a,>>=");
		} else {
			_6502_anal_esil_get_addr_pattern2 (op, data, addrbuf, buffsize, 'x');
			r_strbuf_setf (&op->esil, "1,%s,[1],&,C,=,1,%s,[1],>>,%s,=[1]", addrbuf, addrbuf, addrbuf);
		}
		_6502_anal_update_flags (op, _6502_FLAGS_NZ);
		break;
	// ROL
	case 0x2a: // rol a
	case 0x26: // rol $ff
	case 0x36: // rol $ff,x
	case 0x2e: // rol $ffff
	case 0x3e: // rol $ffff,x
		op->type = R_ANAL_OP_TYPE_ROL;
		if (data[0] == 0x2a) {
			r_strbuf_set (&op->esil, "1,a,<<,C,|,a,=,$c7,C,=,a,a,=");
		} else {
			_6502_anal_esil_get_addr_pattern2 (op, data, addrbuf, buffsize, 'x');
			r_strbuf_setf (&op->esil, "1,%s,[1],<<,C,|,%s,=[1],$c7,C,=", addrbuf, addrbuf);
		}
		_6502_anal_update_flags (op, _6502_FLAGS_NZ);
		break;
	// ROR
	case 0x6a: // ror a
	case 0x66: // ror $ff
	case 0x76: // ror $ff,x
	case 0x6e: // ror $ffff
	case 0x7e: // ror $ffff,x
		// uses N as temporary to hold C value. but in fact,
		// it is not temporary since in all ROR ops, N will have the value of C
		op->type = R_ANAL_OP_TYPE_ROR;
		if (data[0] == 0x6a) {
			r_strbuf_set (&op->esil, "C,N,=,1,a,&,C,=,1,a,>>,7,N,<<,|,a,=");
		} else {
			_6502_anal_esil_get_addr_pattern2 (op, data, addrbuf, buffsize, 'x');
			r_strbuf_setf (&op->esil, "C,N,=,1,%s,[1],&,C,=,1,%s,[1],>>,7,N,<<,|,%s,=[1]", addrbuf, addrbuf, addrbuf);
		}
		_6502_anal_update_flags (op, _6502_FLAGS_NZ);
		break;
	// INC
	case 0xe6: // inc $ff
	case 0xf6: // inc $ff,x
	case 0xee: // inc $ffff
	case 0xfe: // inc $ffff,x
		op->type = R_ANAL_OP_TYPE_STORE;
		_6502_anal_esil_get_addr_pattern2 (op, data, addrbuf, buffsize, 'x');
		r_strbuf_setf (&op->esil, "%s,++=[1]", addrbuf);
		_6502_anal_update_flags (op, _6502_FLAGS_NZ);
		break;
	// DEC
	case 0xc6: // dec $ff
	case 0xd6: // dec $ff,x
	case 0xce: // dec $ffff
	case 0xde: // dec $ffff,x
		op->type = R_ANAL_OP_TYPE_STORE;
		_6502_anal_esil_get_addr_pattern2 (op, data, addrbuf, buffsize, 'x');
		r_strbuf_setf (&op->esil, "%s,--=[1]", addrbuf);
		_6502_anal_update_flags (op, _6502_FLAGS_NZ);
		break;
	// INX, INY
	case 0xe8: // inx
	case 0xc8: // iny
		op->cycles = 2;
		op->type = R_ANAL_OP_TYPE_STORE;
		_6502_anal_esil_inc_reg (op, data[0], "+");
		break;
	// DEX, DEY
	case 0xca: // dex
	case 0x88: // dey
		op->cycles = 2;
		op->type = R_ANAL_OP_TYPE_STORE;
		_6502_anal_esil_inc_reg (op, data[0], "-");
		break;
	// CMP
	case 0xc9: // cmp #$ff
	case 0xc5: // cmp $ff
	case 0xd5: // cmp $ff,x
	case 0xcd: // cmp $ffff
	case 0xdd: // cmp $ffff,x
	case 0xd9: // cmp $ffff,y
	case 0xc1: // cmp ($ff,x)
	case 0xd1: // cmp ($ff),y
		op->type = R_ANAL_OP_TYPE_CMP;
		_6502_anal_esil_get_addr_pattern1 (op, data, addrbuf, buffsize);
		if (data[0] == 0xc9) // immediate mode
			r_strbuf_setf (&op->esil, "%s,a,==", addrbuf);
		else	r_strbuf_setf (&op->esil, "%s,[1],a,==", addrbuf);
		_6502_anal_update_flags (op, _6502_FLAGS_BNZ);
		// invert C, since C=1 when A-M >= 0
		r_strbuf_append (&op->esil, ",C,!,C,=");
		break;
	// CPX
	case 0xe0: // cpx #$ff
	case 0xe4: // cpx $ff
	case 0xec: // cpx $ffff
		op->type = R_ANAL_OP_TYPE_CMP;
		_6502_anal_esil_get_addr_pattern3 (op, data, addrbuf, buffsize, 0);
		if (data[0] == 0xe0) // immediate mode
			r_strbuf_setf (&op->esil, "%s,x,==", addrbuf);
		else	r_strbuf_setf (&op->esil, "%s,[1],x,==", addrbuf);
		_6502_anal_update_flags (op, _6502_FLAGS_BNZ);
		// invert C, since C=1 when A-M >= 0
		r_strbuf_append (&op->esil, ",C,!,C,=");
		break;
	// CPY
	case 0xc0: // cpy #$ff
	case 0xc4: // cpy $ff
	case 0xcc: // cpy $ffff
		op->type = R_ANAL_OP_TYPE_CMP;
		_6502_anal_esil_get_addr_pattern3 (op, data, addrbuf, buffsize, 0);
		if (data[0] == 0xc0) // immediate mode
			r_strbuf_setf (&op->esil, "%s,y,==", addrbuf);
		else	r_strbuf_setf (&op->esil, "%s,[1],y,==", addrbuf);
		_6502_anal_update_flags (op, _6502_FLAGS_BNZ);
		// invert C, since C=1 when A-M >= 0
		r_strbuf_append (&op->esil, ",C,!,C,=");
		break;
	// BRANCHES
	case 0x10: // bpl $ffff
	case 0x30: // bmi $ffff
	case 0x50: // bvc $ffff
	case 0x70: // bvs $ffff
	case 0x90: // bcc $ffff
	case 0xb0: // bcs $ffff
	case 0xd0: // bne $ffff
	case 0xf0: // beq $ffff
		// FIXME: Add 1 if branch occurs to same page.
		// FIXME: Add 2 if branch occurs to different page
		op->cycles = 2;
		op->failcycles = 3;
		op->type = R_ANAL_OP_TYPE_CJMP;
		if (data[1] <= 127)
			op->jump = addr + data[1] + op->size;
		else	op->jump = addr - (256 - data[1]) + op->size;
		op->fail = addr + op->size;
		// FIXME: add a type of conditional
		// op->cond = R_ANAL_COND_LE;
		_6502_anal_esil_ccall (op, data[0]);
		break;
	// JSR
	case 0x20: // jsr $ffff
		op->cycles = 6;
		op->type = R_ANAL_OP_TYPE_CALL;
		op->jump = data[1] | data[2] << 8;
		op->stackop = R_ANAL_STACK_INC;
		op->stackptr = 2;
		// JSR pushes the address-1 of the next operation on to the stack before transferring program
		// control to the following address
		// stack is on page one and sp is an 8-bit reg: operations must be done like: sp + 0x100
		r_strbuf_setf (&op->esil, "1,pc,-,0xff,sp,+,=[2],0x%04x,pc,=,2,sp,-=", op->jump);
		break;
	// JMP
	case 0x4c: // jmp $ffff
		op->cycles = 3;
		op->type = R_ANAL_OP_TYPE_JMP;
		op->jump = data[1] | data[2] << 8;
		r_strbuf_setf (&op->esil, "0x%04x,pc,=", op->jump);
		break;
	case 0x6c: // jmp ($ffff)
		op->cycles = 5;
		op->type = R_ANAL_OP_TYPE_UJMP;
		// FIXME: how to read memory?
		// op->jump = data[1] | data[2] << 8;
		r_strbuf_setf (&op->esil, "0x%04x,[2],pc,=", data[1] | data[2] << 8);
		break;
	// RTS
	case 0x60: // rts
		op->eob = 1;
		op->type = R_ANAL_OP_TYPE_RET;
		op->cycles = 6;
		op->stackop = R_ANAL_STACK_INC;
		op->stackptr = -2;
		// Operation:  PC from Stack, PC + 1 -> PC
		// stack is on page one and sp is an 8-bit reg: operations must be done like: sp + 0x100
		r_strbuf_set (&op->esil, "0x101,sp,+,[2],pc,=,pc,++=,2,sp,+=");
		break;
	// RTI
	case 0x40: // rti
		op->eob = 1;
		op->type = R_ANAL_OP_TYPE_RET;
		op->cycles = 6;
		op->stackop = R_ANAL_STACK_INC;
		op->stackptr = -3;
		// Operation: P from Stack, PC from Stack
		// stack is on page one and sp is an 8-bit reg: operations must be done like: sp + 0x100
		r_strbuf_set (&op->esil, "0x101,sp,+,[1],flags,=,0x102,sp,+,[2],pc,=,3,sp,+=");
		break;
	// NOP
	case 0xea: // nop
		op->type = R_ANAL_OP_TYPE_NOP;
		op->cycles = 2;
		break;
	// LDA
	case 0xa9: // lda #$ff
	case 0xa5: // lda $ff
	case 0xb5: // lda $ff,x
	case 0xad: // lda $ffff
	case 0xbd: // lda $ffff,x
	case 0xb9: // lda $ffff,y
	case 0xa1: // lda ($ff,x)
	case 0xb1: // lda ($ff),y
		op->type = R_ANAL_OP_TYPE_LOAD;
		_6502_anal_esil_get_addr_pattern1 (op, data, addrbuf, buffsize);
		if (data[0] == 0xa9) // immediate mode
			r_strbuf_setf (&op->esil, "%s,a,=", addrbuf);
		else	r_strbuf_setf (&op->esil, "%s,[1],a,=", addrbuf);
		_6502_anal_update_flags (op, _6502_FLAGS_NZ);
		break;
	// LDX
	case 0xa2: // ldx #$ff
	case 0xa6: // ldx $ff
	case 0xb6: // ldx $ff,y
	case 0xae: // ldx $ffff
	case 0xbe: // ldx $ffff,y
		op->type = R_ANAL_OP_TYPE_LOAD;
		_6502_anal_esil_get_addr_pattern2 (op, data, addrbuf, buffsize, 'y');
		if (data[0] == 0xa2) // immediate mode
			r_strbuf_setf (&op->esil, "%s,x,=", addrbuf);
		else	r_strbuf_setf (&op->esil, "%s,[1],x,=", addrbuf);
		_6502_anal_update_flags (op, _6502_FLAGS_NZ);
		break;
	// LDY
	case 0xa0: // ldy #$ff
	case 0xa4: // ldy $ff
	case 0xb4: // ldy $ff,x
	case 0xac: // ldy $ffff
	case 0xbc: // ldy $ffff,x
		op->type = R_ANAL_OP_TYPE_LOAD;
		_6502_anal_esil_get_addr_pattern3 (op, data, addrbuf, buffsize, 'x');
		if (data[0] == 0xa0) // immediate mode
			r_strbuf_setf (&op->esil, "%s,y,=", addrbuf);
		else	r_strbuf_setf (&op->esil, "%s,[1],y,=", addrbuf);
		_6502_anal_update_flags (op, _6502_FLAGS_NZ);
		break;
	// STA
	case 0x85: // sta $ff
	case 0x95: // sta $ff,x
	case 0x8d: // sta $ffff
	case 0x9d: // sta $ffff,x
	case 0x99: // sta $ffff,y
	case 0x81: // sta ($ff,x)
	case 0x91: // sta ($ff),y
		op->type = R_ANAL_OP_TYPE_STORE;
		_6502_anal_esil_get_addr_pattern1 (op, data, addrbuf, buffsize);
		r_strbuf_setf (&op->esil, "a,%s,=[1]", addrbuf);
		break;
	// STX
	case 0x86: // stx $ff
	case 0x96: // stx $ff,y
	case 0x8e: // stx $ffff
		op->type = R_ANAL_OP_TYPE_STORE;
		_6502_anal_esil_get_addr_pattern2 (op, data, addrbuf, buffsize, 'y');
		r_strbuf_setf (&op->esil, "x,%s,=[1]", addrbuf);
		break;
	// STY
	case 0x84: // sty $ff
	case 0x94: // sty $ff,x
	case 0x8c: // sty $ffff
		op->type = R_ANAL_OP_TYPE_STORE;
		_6502_anal_esil_get_addr_pattern3 (op, data, addrbuf, buffsize, 'x');
		r_strbuf_setf (&op->esil, "y,%s,=[1]", addrbuf);
		break;
	// PHP/PHA
	case 0x08: // php
	case 0x48: // pha
		op->type = R_ANAL_OP_TYPE_PUSH;
		op->cycles = 3;
		op->stackop = R_ANAL_STACK_INC;
		op->stackptr = 1;
		_6502_anal_esil_push (op, data[0]);
		break;
	// PLP,PLA
	case 0x28: // plp
	case 0x68: // plp
		op->type = R_ANAL_OP_TYPE_POP;
		op->cycles = 4;
		op->stackop = R_ANAL_STACK_INC;
		op->stackptr = -1;
		_6502_anal_esil_pop (op, data[0]);
		break;
	// TAX,TYA,...
	case 0xaa: // tax
	case 0x8a: // txa
	case 0xa8: // tay
	case 0x98: // tya
		op->type = R_ANAL_OP_TYPE_MOV;
		op->cycles = 2;
		_6502_anal_esil_mov (op, data[0]);
		break;
	case 0x9a: // txs
		op->type = R_ANAL_OP_TYPE_MOV;
		op->cycles = 2;
		op->stackop = R_ANAL_STACK_SET;
		// FIXME: should I get register X a place it here?
		// op->stackptr = get_register_x();
		_6502_anal_esil_mov (op, data[0]);
		break;
	case 0xba: // tsx
		op->type = R_ANAL_OP_TYPE_MOV;
		op->cycles = 2;
		op->stackop = R_ANAL_STACK_GET;
		_6502_anal_esil_mov (op, data[0]);
		break;
	}
	return op->size;
}
コード例 #29
0
ファイル: anal_8051.c プロジェクト: AitorATuin/radare2
static void analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, const char *buf_asm) {
	r_strbuf_init (&op->esil);
	r_strbuf_set (&op->esil, "");

	switch (buf[0]) {

	// Irregulars sorted by lower nibble
	case 0x00: /* nop  */ emit(","); break;
	case 0x10: /* jbc  */
		k(BIT_R "&,?{,%2$d,1,<<,255,^,%1$d,&=[1],%3$hhd,3,+,pc,+=,}"); break;
	case 0x20: /* jb   */
		k(BIT_R "&,?{,%3$hhd,3,+,pc,+=,}"); break;
	case 0x30: /* jnb  */
		k(BIT_R "&,!,?{,%3$hhd,3,+,pc,+=,}"); break;
	case 0x40: /* jc   */ emitf("C,!,?{,%hhd,2,+,pc,+=,}", buf[1]); break;
	case 0x50: /* jnc  */ emitf("C,""?{,%hhd,2,+,pc,+=,}", buf[1]); break;
	case 0x60: /* jz   */ emitf("A,!,?{,%hhd,2,+,pc,+=,}", buf[1]); break;
	case 0x70: /* jnz  */ emitf("A,""?{,%hhd,2,+,pc,+=,}", buf[1]); break;
	case 0x80: /* sjmp */ j(ESX_L1 JMP("2")); break;
	case 0x90: /* mov  */ emitf("%d,dptr,=", (buf[1]<<8) + buf[2]); break;
	case 0xA0: /* orl  */ k(BIT_R "C,|="); break;
	case 0xB0: /* anl  */ k(BIT_R "C,&="); break;
	case 0xC0: /* push */ h(XR(IB1) PUSH1); break;
	case 0xD0: /* pop  */ h(POP1 XW(IB1)); break;
	case 0xE0: /* movx */ /* TODO */ break;
	case 0xF0: /* movx */ /* TODO */ break;

	case 0x11: case 0x31: case 0x51: case 0x71:
	case 0x91: case 0xB1: case 0xD1: case 0xF1:
		emit(CALL("2")); // fall through
	case 0x01: case 0x21: case 0x41: case 0x61:
	case 0x81: case 0xA1: case 0xC1: case 0xE1:
		emitf("0x%x,pc,=", (addr & 0xF800) | ((((unsigned short)buf[0])<<3) & 0x0700) | buf[1]); break;

	case 0x02: /* ljmp  */ emitf(          "%d,pc,=", (unsigned int)((buf[1]<<8)+buf[2])); break;
	case 0x12: /* lcall */ emitf(CALL("3")",%d,pc,=", (unsigned int)((buf[1]<<8)+buf[2])); break;
	case 0x22: /* ret   */ emitf(POP2 "pc,="); break;
	case 0x32: /* reti  */ /* TODO */ break;
	case 0x72: /* orl   */ /* TODO */ break;
	case 0x82: /* anl   */ /* TODO */ break;
	case 0x92: /* mov   */ /* TODO */ break;
	case 0xA2: /* mov   */ /* TODO */ break;
	case 0xB2: /* cpl   */ k("%2$d,1,<<,%1$d,^=[1]"); break;
	case 0xC2: /* clr   */ /* TODO */ break;

	case 0x03: /* rr   */ emit("1,A,0x101,*,>>,A,="); break;
	case 0x13: /* rrc  */ /* TODO */ break;
	case 0x23: /* rl   */ emit("7,A,0x101,*,>>,A,="); break;
	case 0x33: /* rlc  */ /* TODO */ break;
	case 0x73: /* jmp  */ emit("dptr,A,+,pc,="); break;
	case 0x83: /* movc */ emit("A,dptr,+,[1],A,="); break;
	case 0x93: /* movc */ emit("A,pc,+,[1],A,="); break;
	case 0xA3: /* inc  */ h(XI(IB1, "++")); break;
	case 0xB3: /* cpl  */ emit("1," XI(C, "^")); break;
	case 0xC3: /* clr  */ emit("0,C,="); break;

	// Regulars sorted by upper nibble
	OP_GROUP_UNARY_4(0x00, "++")
	OP_GROUP_UNARY_4(0x10, "--")
	OP_GROUP_INPLACE_LHS_4(0x20, A, "+")

	case 0x34:
		h (XR(L1)  "C,+," XI(A, "+")) break;
	case 0x35:
		h (XR(IB1) "C,+," XI(A, "+")) break;

	case 0x36: case 0x37:
		j (XR(R0I) "C,+," XI(A, "+")) break;

	case 0x38: case 0x39:
	case 0x3A: case 0x3B:
	case 0x3C: case 0x3D:
	case 0x3E: case 0x3F:
		h (XR(R0)  "C,+," XI(A, "+")) break;

	OP_GROUP_INPLACE_LHS_4(0x40, A, "|")
	OP_GROUP_INPLACE_LHS_4(0x50, A, "&")
	OP_GROUP_INPLACE_LHS_4(0x60, A, "^")

	case 0x74:
		h (XR(L1) XW(A)) break;
	case 0x75:
		h (XR(L2) XW(IB1)) break;

	case 0x76: case 0x77:
		j (XR(L1) XW(R0I)) break;

	case 0x78: case 0x79:
	case 0x7A: case 0x7B:
	case 0x7C: case 0x7D:
	case 0x7E: case 0x7F:
		h (XR(L1) XW(R0)) break;

	case 0x84:
		/* div */ emit("B,!,OV,=,0,A,B,A,/=,A,B,*,-,-,B,=,0,C,="); break;
	case 0x85:
		/* mov */ h(IRAM_BASE ",%2$d,+,[1]," IRAM_BASE ",%2$d,+,=[1]"); break;

	case 0x86: case 0x87:
		j (XR(R0I) XW(IB1)) break;

	case 0x88: case 0x89:
	case 0x8A: case 0x8B:
	case 0x8C: case 0x8D:
	case 0x8E: case 0x8F:
		h (XR(R0) XW(IB1)) break;

	OP_GROUP_INPLACE_LHS_4(0x90, A, ".")

	case 0xA4:
		/* mul */ emit("8,A,B,*,DUP,>>,DUP,!,!,OV,=,B,=,A,=,0,C,="); break;
	case 0xA5: /* ??? */ emit("0,TRAP"); break;
	case 0xA6: case 0xA7:
		j (XR(IB1) XW(R0I)) break;

	case 0xA8: case 0xA9:
	case 0xAA: case 0xAB:
	case 0xAC: case 0xAD:
	case 0xAE: case 0xAF:
		h (XR(IB1) XW(R0)) break;

	case 0xB4:
		h (XR(L1)  XR(A)   "!=,?{,%3$hhd,2,+pc,+=,}") break;
	case 0xB5:
		h (XR(IB1) XR(A)   "!=,?{,%3$hhd,2,+pc,+=,}") break;

	case 0xB6: case 0xB7:
		j (XR(L1)  XR(R0I) "!=,?{,%3$hhd,2,+pc,+=,}") break;

	case 0xB8: case 0xB9:
	case 0xBA: case 0xBB:
	case 0xBC: case 0xBD:
	case 0xBE: case 0xBF:
		h (XR(L1)  XR(R0)  "!=,?{,%3$hhd,2,+pc,+=,}") break;

	case 0xC4:
		/* swap */ emit("4,A,0x101,*,>>,A,="); break;
	case 0xC5:
		/* xch  */ /* TODO */ break;

	case 0xC6: case 0xC7:
		/* xch  */ /* TODO */ break;

	case 0xC8: case 0xC9:
	case 0xCA: case 0xCB:
	case 0xCC: case 0xCD:
	case 0xCE: case 0xCF:
		/* xch  */ h (XR(A) XR(R0) XW(A) ","  XW(R0)); break;

	case 0xD2:
		/* setb */ /* TODO */ break;
	case 0xD3:
		/* setb */ /* TODO */ break;
	case 0xD4:
		/* da   */ emit("A,--="); break;
	case 0xD5:
		/* djnz */ h(XI(R0I, "--") "," XR(R0I) CJMP(L2, "2")); break;
	case 0xD6:
		/* xchd */ /* TODO */ break;
	case 0xD7:
		/* xchd */ /* TODO */ break;

	case 0xD8: case 0xD9:
	case 0xDA: case 0xDB:
	case 0xDC: case 0xDD:
	case 0xDE: case 0xDF:
		/* djnz */ h(XI(R0, "--") "," XR(R0) CJMP(L1, "2")); break;

	case 0xE2: case 0xE3:
		/* movx */ j(XRAM_BASE "r%0$d,+,[1]," XW(A)); break;

	case 0xE4:
		/* clr  */ emit("0,A,="); break;
	case 0xE5:
		/* mov  */ h (XR(IB1) XW(A)) break;

	case 0xE6: case 0xE7:
		/* mov  */ j (XR(R0I) XW(A)) break;

	case 0xE8: case 0xE9:
	case 0xEA: case 0xEB:
	case 0xEC: case 0xED:
	case 0xEE: case 0xEF:
		/* mov  */ h (XR(R0)  XW(A)) break;

	case 0xF2: case 0xF3:
		/* movx */ j(XR(A) XRAM_BASE "r%0$d,+,=[1]");

	case 0xF4:
		/* cpl  */ h ("255" XI(A, "^")) break;
	case 0xF5:
		/* mov  */ h (XR(A) XW(IB1)) break;

	case 0xF6: case 0xF7:
		/* mov  */ j (XR(A) XW(R0I)) break;

	case 0xF8: case 0xF9:
	case 0xFA: case 0xFB:
	case 0xFC: case 0xFD:
	case 0xFE: case 0xFF:
		/* mov  */ h (XR(A) XW(R0)) break;

	default: break;
	}
}
コード例 #30
0
ファイル: anal_mips_cs.c プロジェクト: commiebstrd/radare2
static int analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len, csh *handle, cs_insn *insn) {
	char str[32][32];
	r_strbuf_init (&op->esil);
	r_strbuf_set (&op->esil, "");
	if (insn)
	switch (insn->id) {
	case MIPS_INS_NOP:
		r_strbuf_setf (&op->esil, ",");
		break;
	case MIPS_INS_SW:
		r_strbuf_appendf (&op->esil, "%s,%s,=[4]",
			ARG(0), ARG(1));
		break;
	case MIPS_INS_SWC1:
	case MIPS_INS_SWC2:
		r_strbuf_setf (&op->esil, "%s,$", ARG(1));
		break;
	case MIPS_INS_SB:
		r_strbuf_appendf (&op->esil, "%s,%s,=[1]",
			ARG(0), ARG(1));
		break;
	case MIPS_INS_CMP:
	case MIPS_INS_CMPU:
	case MIPS_INS_CMPGU:
	case MIPS_INS_CMPGDU:
	case MIPS_INS_CMPI:
		r_strbuf_appendf (&op->esil, "%s,%s,==", ARG(1), ARG(0));
		break;
	case MIPS_INS_SHRAV:
	case MIPS_INS_SHRAV_R:
	case MIPS_INS_SHRA:
	case MIPS_INS_SHRA_R:
	case MIPS_INS_SRA:
		r_strbuf_appendf (&op->esil, "%s,%s,>>,31,%s,>>,?{,32,%s,-,%s,1,<<,1,-,<<,}{,0,},|,%s,=,",
				ARG(2), ARG(1), ARG(1), ARG(2), ARG(2), ARG(0));
		break;
	case MIPS_INS_SHRL:
		// suffix 'S' forces conditional flag to be updated
	case MIPS_INS_SRLV:
	case MIPS_INS_SRL:
		r_strbuf_appendf (&op->esil, "%s,%s,>>,%s,=", ARG(2), ARG(1), ARG(0));
		break;
	case MIPS_INS_SLLV:
	case MIPS_INS_SLL:
		r_strbuf_appendf (&op->esil, "%s,%s,<<,%s,=", ARG(2), ARG(1), ARG(0));
		break;
	case MIPS_INS_BAL:
	case MIPS_INS_JAL:
	case MIPS_INS_JALR:
	case MIPS_INS_JALRS:
	case MIPS_INS_JALRC:
	case MIPS_INS_BLTZAL: // Branch on less than zero and link
		r_strbuf_appendf (&op->esil, "pc,8,+,ra,=,%s,pc,=", ARG(0));
		break;
	case MIPS_INS_JR:
	case MIPS_INS_JRC:
	case MIPS_INS_J:
		// jump to address with conditional
		r_strbuf_appendf (&op->esil, "%s,pc,=", ARG(0));
		break;
	case MIPS_INS_B: // ???
	case MIPS_INS_BZ:
	case MIPS_INS_BGTZ:
	case MIPS_INS_BGTZC:
	case MIPS_INS_BGTZALC:
	case MIPS_INS_BGEZ:
	case MIPS_INS_BGEZC:
	case MIPS_INS_BGEZAL: // Branch on less than zero and link
	case MIPS_INS_BGEZALC:
		r_strbuf_appendf (&op->esil, "%s,pc,=", ARG(0));
		break;
	case MIPS_INS_BNE:  // bne $s, $t, offset 
	case MIPS_INS_BNEZ:
		r_strbuf_appendf (&op->esil, "%s,%s,==,!,?{,%s,pc,=,}",
			ARG(0), ARG(1), ARG(2));
		break;
	case MIPS_INS_BEQ:
	case MIPS_INS_BEQZ:
	case MIPS_INS_BEQZC:
	case MIPS_INS_BEQZALC:
		r_strbuf_appendf (&op->esil, "%s,%s,==,?{,%s,pc,=,}",
			ARG(0), ARG(1), ARG(2));
		break;
	case MIPS_INS_BTEQZ:
	case MIPS_INS_BTNEZ:
		r_strbuf_appendf (&op->esil, "%s,pc,=", ARG(0));
		break;
	case MIPS_INS_MOV:
	case MIPS_INS_MOVE:
	case MIPS_INS_MOVF:
	case MIPS_INS_MOVT:
	case MIPS_INS_MOVZ:
		if (REG(0)[0]!='z'){
			r_strbuf_appendf (&op->esil, "%s,%s,=", ARG(1), REG(0));
		} else {
			r_strbuf_appendf (&op->esil, ",");
		}
		break;
	case MIPS_INS_FSUB:
	case MIPS_INS_SUB:
		if (REG(0)[0]!='z'){
			r_strbuf_appendf(&op->esil, "%s,%s,>,?{,$$,}{,%s,%s,-,%s,=",ARG(2), ARG(1), ARG(1), ARG(2), ARG(0));
		} else {
			r_strbuf_appendf (&op->esil, ",");
		}
		break;
	case MIPS_INS_SUBU:
	case MIPS_INS_NEGU:
	case MIPS_INS_DSUB:
	case MIPS_INS_DSUBU:
		{
		const char *arg0 = ARG(0);
		const char *arg1 = ARG(1);
		const char *arg2 = ARG(2);
		r_strbuf_appendf (&op->esil, "%s,%s,-,%s,=",
			arg1, arg2, arg0);
		}
		break;
	/** signed -- sets overflow flag */
	case MIPS_INS_ADD:
		{
		if (REG(0)[0]!='z'){
			r_strbuf_appendf (&op->esil, "32,%s,%s,+,>>,0,>,?{,$$,}{,%s,%s,+,%s,=,}",
					ARG(2), ARG(1), ARG(2), ARG(1), ARG(0));
		} else {
			r_strbuf_appendf (&op->esil, ",");
		}
		}
		break;
	case MIPS_INS_ADDI:
		if (REG(0)[0]!='z'){
			r_strbuf_appendf (&op->esil, "32,%s,0xffffffff,&,%s,+,>>,0,>,?{,$$,}{,%s,%s,+,%s,=,}",
					ARG(2), ARG(1), ARG(2), ARG(1), ARG(0));
		} else {
			r_strbuf_appendf (&op->esil, ",");
		}
		break;
	case MIPS_INS_DADD:
	case MIPS_INS_DADDI:
	/** unsigned */
	case MIPS_INS_ADDU:
	case MIPS_INS_ADDIU:
	case MIPS_INS_DADDIU:
		{
		const char *arg0 = ARG(0);
		const char *arg1 = ARG(1);
		const char *arg2 = ARG(2);
		if (REG(0)[0]!='z'){
			r_strbuf_appendf (&op->esil, "%s,%s,+,%s,=",
					arg2, arg1, arg0);
		} else {
			r_strbuf_appendf (&op->esil, ",");
		}
		}
		break;
	case MIPS_INS_LI:
		r_strbuf_appendf (&op->esil, "0x%"PFMT64x",%s,=", IMM(1), ARG(0));
		break;
	case MIPS_INS_LUI:
		r_strbuf_appendf (&op->esil, "0x%"PFMT64x"0000,%s,=", IMM(1), ARG(0));
		break;
	case MIPS_INS_LB:
	case MIPS_INS_LBU:
		//one of these is wrong
		r_strbuf_appendf (&op->esil, "%s,[1],%s,=",
			ARG(1), REG(0));
		break;
	case MIPS_INS_LW:
	case MIPS_INS_LWC1:
	case MIPS_INS_LWC2:
	case MIPS_INS_LWL:
	case MIPS_INS_LWR:
	case MIPS_INS_LWU:
	case MIPS_INS_LWX:
	case MIPS_INS_LH:
	case MIPS_INS_LHX:
	case MIPS_INS_LL:
	case MIPS_INS_LLD:
	case MIPS_INS_LD:
	case MIPS_INS_LDI:
	case MIPS_INS_LDL:
	case MIPS_INS_LDC1:
	case MIPS_INS_LDC2:
		r_strbuf_appendf (&op->esil, "%s,[4],%s,=",
			ARG(1), REG(0));
		break;
	case MIPS_INS_AND:
	case MIPS_INS_ANDI:
		{
		const char *arg0 = ARG(0);
		const char *arg1 = ARG(1);
		const char *arg2 = ARG(2);
		r_strbuf_appendf (&op->esil, "%s,%s,&,%s,=",
			arg2, arg1, arg0);
		}
		break;
	case MIPS_INS_OR:
	case MIPS_INS_ORI:
		{
		const char *arg0 = ARG(0);
		const char *arg1 = ARG(1);
		const char *arg2 = ARG(2);
		if (REG(0)[0]!='z'){
			r_strbuf_appendf (&op->esil, "%s,%s,|,%s,=",
				arg2, arg1, arg0);
		} else {
			r_strbuf_appendf (&op->esil, ",");
		}
		}
		break;
	case MIPS_INS_XOR:
	case MIPS_INS_XORI:
		{
		const char *arg0 = ARG(0);
		const char *arg1 = ARG(1);
		const char *arg2 = ARG(2);
		if (REG(0)[0]!='z'){
			r_strbuf_appendf (&op->esil, "%s,%s,^,%s,=",
				arg2, arg1, arg0);
		} else {
			r_strbuf_appendf (&op->esil, ",");
		}
		}
		break;
	case MIPS_INS_NOR:
		{
		const char *arg0 = ARG(0);
		const char *arg1 = ARG(1);
		const char *arg2 = ARG(2);
		if (REG(0)[0]!='z'){
			r_strbuf_appendf (&op->esil, "%s,%s,|,0xffffffff,^,%s,=",
				arg2, arg1, arg0);
		} else {
			r_strbuf_appendf (&op->esil, ",");
		}
		}
		break;
	case MIPS_INS_SLTU:
		r_strbuf_appendf (&op->esil, "%s,%s,<,%s,=", ARG(1), ARG(2), ARG(0));
		break;
	case MIPS_INS_SLTIU:
		{
		r_strbuf_appendf (&op->esil, "%s,0xffffffff,&,%s,0xffffffff,<,?{%s,1,=,}{,%s,0,=,}",
					ARG(1), ARG(2), ARG(0), ARG(0));
		}
		break;
	}
	return 0;
}