1 /* radare - LGPL - Copyright 2012-2013 - pancake
2 	2014 - Fedor Sakharov <fedor.sakharov@gmail.com> */
3 
4 #include <string.h>
5 #include <r_types.h>
6 #include <r_lib.h>
7 #include <r_asm.h>
8 #include <r_anal.h>
9 #include <r_util.h>
10 
11 #include <cr16_disas.h>
12 
cr16_op(RAnal * anal,RAnalOp * op,ut64 addr,const ut8 * buf,int len,RAnalOpMask mask)13 static int cr16_op(RAnal *anal, RAnalOp *op, ut64 addr,
14 		const ut8 *buf, int len, RAnalOpMask mask)
15 {
16 	int ret;
17 	struct cr16_cmd cmd;
18 
19 	memset(&cmd, 0, sizeof (cmd));
20 
21 	ret = op->size = cr16_decode_command(buf, &cmd, len);
22 
23 	if (ret <= 0) {
24 		return ret;
25 	}
26 
27 	op->addr = addr;
28 
29 	switch (cmd.type) {
30 	case CR16_TYPE_MOV:
31 		op->type = R_ANAL_OP_TYPE_MOV;
32 		break;
33 	case CR16_TYPE_ADD:
34 		op->type = R_ANAL_OP_TYPE_ADD;
35 		break;
36 	case CR16_TYPE_MUL:
37 		op->type = R_ANAL_OP_TYPE_MUL;
38 		break;
39 	case CR16_TYPE_SUB:
40 		op->type = R_ANAL_OP_TYPE_SUB;
41 		break;
42 	case CR16_TYPE_CMP:
43 		op->type = R_ANAL_OP_TYPE_CMP;
44 		break;
45 	case CR16_TYPE_BE:
46 	case CR16_TYPE_BNE:
47 		op->type = R_ANAL_OP_TYPE_CJMP;
48 		break;
49 	case CR16_TYPE_AND:
50 		op->type = R_ANAL_OP_TYPE_AND;
51 		break;
52 	case CR16_TYPE_OR:
53 		op->type = R_ANAL_OP_TYPE_OR;
54 		break;
55 	case CR16_TYPE_SCOND:
56 		break;
57 	case CR16_TYPE_XOR:
58 		op->type = R_ANAL_OP_TYPE_XOR;
59 		break;
60 	case CR16_TYPE_SHIFT:
61 		op->type = R_ANAL_OP_TYPE_SHR;
62 		break;
63 	case CR16_TYPE_BIT:
64 		op->type = R_ANAL_OP_TYPE_MOV;
65 		break;
66 	case CR16_TYPE_SLPR:
67 		op->type = R_ANAL_OP_TYPE_MOV;
68 		break;
69 	case CR16_TYPE_BCOND:
70 		if (cmd.reladdr) {
71 			op->jump = addr + cmd.reladdr;
72 			op->fail = addr + 2;
73 		}
74 		op->type = R_ANAL_OP_TYPE_CJMP;
75 		break;
76 	case CR16_TYPE_BR:
77 	case CR16_TYPE_BAL:
78 		op->type = R_ANAL_OP_TYPE_UJMP;
79 		break;
80 	case CR16_TYPE_EXCP:
81 		op->type = R_ANAL_OP_TYPE_SWI;
82 		break;
83 	case CR16_TYPE_JCOND:
84 	case CR16_TYPE_JAL:
85 	case CR16_TYPE_JUMP:
86 	case CR16_TYPE_JUMP_UNK:
87 		if (cmd.reladdr) {
88 			op->jump = addr + cmd.reladdr;
89 			op->fail = addr + 2;
90 		}
91 		op->type = R_ANAL_OP_TYPE_JMP;
92 		break;
93 	case CR16_TYPE_RETX:
94 		op->type = R_ANAL_OP_TYPE_RET;
95 		break;
96 	case CR16_TYPE_PUSH:
97 		op->type = R_ANAL_OP_TYPE_PUSH;
98 		break;
99 	case CR16_TYPE_POP:
100 		op->type = R_ANAL_OP_TYPE_POP;
101 		break;
102 	case CR16_TYPE_LOAD:
103 	case CR16_TYPE_DI:
104 	case CR16_TYPE_EI:
105 	case CR16_TYPE_STOR:
106 		op->type = R_ANAL_OP_TYPE_MOV;
107 		break;
108 	case CR16_TYPE_NOP:
109 		op->type = R_ANAL_OP_TYPE_NOP;
110 		break;
111 	case CR16_TYPE_WAIT:
112 	case CR16_TYPE_EWAIT:
113 		op->type = R_ANAL_OP_TYPE_SWI;
114 		break;
115 	default:
116 		op->type = R_ANAL_OP_TYPE_UNK;
117 	}
118 
119 	return ret;
120 }
121 
122 RAnalPlugin r_anal_plugin_cr16 = {
123 	.name = "cr16",
124 	.desc = "CR16 code analysis plugin",
125 	.license = "LGPL3",
126 	.arch = "cr16",
127 	.bits = 16,
128 	.op = cr16_op,
129 };
130 
131 #ifndef R2_PLUGIN_INCORE
132 R_API RLibStruct radare_plugin = {
133 	.type = R_LIB_TYPE_ANAL,
134 	.data = &r_anal_plugin_cr16,
135 	.version = R2_VERSION
136 };
137 #endif
138