1 /* radare2 - LGPL - Copyright 2017 - pancake */
2 
3 #include <r_anal.h>
4 #include <r_lib.h>
5 #include <capstone.h>
6 
7 #ifdef CAPSTONE_TMS320C64X_H
8 #define CAPSTONE_HAS_TMS320C64X 1
9 #else
10 #define CAPSTONE_HAS_TMS320C64X 0
11 #warning Cannot find capstone-tms320c64x support
12 #endif
13 
14 #if CS_API_MAJOR < 2
15 #undef CAPSONT_HAS_TMS320C64X
16 #define CAPSTONE_HAS_TMS320C64X 0
17 #endif
18 
19 
20 #if CAPSTONE_HAS_TMS320C64X
21 
22 #define INSOP(n) insn->detail->tms320c64x.operands[n]
23 #define INSCC insn->detail->tms320c64x.cc
24 
opex(RStrBuf * buf,csh handle,cs_insn * insn)25 static void opex(RStrBuf *buf, csh handle, cs_insn *insn) {
26 	int i;
27 	PJ *pj = pj_new ();
28 	if (!pj) {
29 		return;
30 	}
31 	pj_o (pj);
32 	pj_ka (pj, "operands");
33 	cs_tms320c64x *x = &insn->detail->tms320c64x;
34 	for (i = 0; i < x->op_count; i++) {
35 		cs_tms320c64x_op *op = x->operands + i;
36 		pj_o (pj);
37 		switch (op->type) {
38 		case TMS320C64X_OP_REG:
39 			pj_ks (pj, "type", "reg");
40 			pj_ks (pj, "value", cs_reg_name (handle, op->reg));
41 			break;
42 		case TMS320C64X_OP_IMM:
43 			pj_ks (pj, "type", "imm");
44 			pj_ki (pj, "value", op->imm);
45 			break;
46 		case TMS320C64X_OP_MEM:
47 			pj_ks (pj, "type", "mem");
48 			if (op->mem.base != SPARC_REG_INVALID) {
49 				pj_ks (pj, "base", cs_reg_name (handle, op->mem.base));
50 			}
51 			pj_kN (pj, "disp", (st64)op->mem.disp);
52 			break;
53 		default:
54 			pj_ks (pj, "type", "invalid");
55 			break;
56 		}
57 		pj_end (pj); /* o operand */
58 	}
59 	pj_end (pj); /* a operands */
60 	pj_end (pj);
61 
62 	r_strbuf_init (buf);
63 	r_strbuf_append (buf, pj_string (pj));
64 	pj_free (pj);
65 }
66 
tms320c64x_analop(RAnal * a,RAnalOp * op,ut64 addr,const ut8 * buf,int len,RAnalOpMask mask)67 static int tms320c64x_analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len, RAnalOpMask mask) {
68 	static csh handle = 0;
69 	static int omode;
70 	cs_insn *insn;
71 	int mode = 0, n, ret;
72 
73 	if (mode != omode) {
74 		cs_close (&handle);
75 		handle = 0;
76 		omode = mode;
77 	}
78 	if (handle == 0) {
79 		ret = cs_open (CS_ARCH_TMS320C64X, mode, &handle);
80 		if (ret != CS_ERR_OK) {
81 			return -1;
82 		}
83 		cs_option (handle, CS_OPT_DETAIL, CS_OPT_ON);
84 	}
85 	// capstone-next
86 	n = cs_disasm (handle, (const ut8*)buf, len, addr, 1, &insn);
87 	if (n < 1) {
88 		op->type = R_ANAL_OP_TYPE_ILL;
89 	} else {
90 		if (mask & R_ANAL_OP_MASK_OPEX) {
91 			opex (&op->opex, handle, insn);
92 		}
93 		op->size = insn->size;
94 		op->id = insn->id;
95 		switch (insn->id) {
96 		case TMS320C64X_INS_INVALID:
97 			op->type = R_ANAL_OP_TYPE_ILL;
98 			break;
99 		case TMS320C64X_INS_AND:
100 		case TMS320C64X_INS_ANDN:
101 			op->type = R_ANAL_OP_TYPE_AND;
102 			break;
103 		case TMS320C64X_INS_NOT:
104 			op->type = R_ANAL_OP_TYPE_NOT;
105 			break;
106 		case TMS320C64X_INS_NEG:
107 			op->type = R_ANAL_OP_TYPE_NOT;
108 			break;
109 		case TMS320C64X_INS_SWAP2:
110 		case TMS320C64X_INS_SWAP4:
111 		op->type = R_ANAL_OP_TYPE_MOV;
112 			op->type = R_ANAL_OP_TYPE_MOV;
113 			break;
114 		case TMS320C64X_INS_BNOP:
115 		case TMS320C64X_INS_NOP:
116 			op->type = R_ANAL_OP_TYPE_NOP;
117 			break;
118 		case TMS320C64X_INS_CMPEQ:
119 		case TMS320C64X_INS_CMPEQ2:
120 		case TMS320C64X_INS_CMPEQ4:
121 		case TMS320C64X_INS_CMPGT:
122 		case TMS320C64X_INS_CMPGT2:
123 		case TMS320C64X_INS_CMPGTU4:
124 		case TMS320C64X_INS_CMPLT:
125 		case TMS320C64X_INS_CMPLTU:
126 			op->type = R_ANAL_OP_TYPE_CMP;
127 			break;
128 		case TMS320C64X_INS_B:
129 			op->type = R_ANAL_OP_TYPE_JMP;
130 			// higher 32bits of the 64bit address is lost, lets clone
131 			op->jump = INSOP(0).imm + (addr & 0xFFFFFFFF00000000);
132 			break;
133 		case TMS320C64X_INS_LDB:
134 		case TMS320C64X_INS_LDBU:
135 		case TMS320C64X_INS_LDDW:
136 		case TMS320C64X_INS_LDH:
137 		case TMS320C64X_INS_LDHU:
138 		case TMS320C64X_INS_LDNDW:
139 		case TMS320C64X_INS_LDNW:
140 		case TMS320C64X_INS_LDW:
141 		case TMS320C64X_INS_LMBD:
142 			op->type = R_ANAL_OP_TYPE_LOAD;
143 			break;
144 		case TMS320C64X_INS_STB:
145 		case TMS320C64X_INS_STDW:
146 		case TMS320C64X_INS_STH:
147 		case TMS320C64X_INS_STNDW:
148 		case TMS320C64X_INS_STNW:
149 		case TMS320C64X_INS_STW:
150 			op->type = R_ANAL_OP_TYPE_STORE;
151 			break;
152 		case TMS320C64X_INS_OR:
153 			op->type = R_ANAL_OP_TYPE_OR;
154 			break;
155 		case TMS320C64X_INS_SSUB:
156 		case TMS320C64X_INS_SUB:
157 		case TMS320C64X_INS_SUB2:
158 		case TMS320C64X_INS_SUB4:
159 		case TMS320C64X_INS_SUBAB:
160 		case TMS320C64X_INS_SUBABS4:
161 		case TMS320C64X_INS_SUBAH:
162 		case TMS320C64X_INS_SUBAW:
163 		case TMS320C64X_INS_SUBC:
164 		case TMS320C64X_INS_SUBU:
165 			op->type = R_ANAL_OP_TYPE_SUB;
166 			break;
167 		case TMS320C64X_INS_ADD:
168 		case TMS320C64X_INS_ADD2:
169 		case TMS320C64X_INS_ADD4:
170 		case TMS320C64X_INS_ADDAB:
171 		case TMS320C64X_INS_ADDAD:
172 		case TMS320C64X_INS_ADDAH:
173 		case TMS320C64X_INS_ADDAW:
174 		case TMS320C64X_INS_ADDK:
175 		case TMS320C64X_INS_ADDKPC:
176 		case TMS320C64X_INS_ADDU:
177 		case TMS320C64X_INS_SADD:
178 		case TMS320C64X_INS_SADD2:
179 		case TMS320C64X_INS_SADDU4:
180 		case TMS320C64X_INS_SADDUS2:
181 			op->type = R_ANAL_OP_TYPE_ADD;
182 			break;
183 		}
184 		cs_free (insn, n);
185 	}
186 	return op->size;
187 }
188 #endif
189 
190 /*
191 
192 static int archinfo(RAnal *anal, int q) {
193 	return 4; // :D
194 }
195 
196 RAnalPlugin r_anal_plugin_tms320c64x = {
197 	.name = "tms320c64x",
198 	.desc = "Capstone TMS320C64X analysis",
199 	.license = "BSD",
200 	.arch = "tms320c64x",
201 	.bits = 32,
202 	.archinfo = archinfo,
203 	.op = &analop
204 };
205 
206 #else
207 RAnalPlugin r_anal_plugin_tms320c64x = {
208 	.name = "tms320c64x",
209 	.desc = "Capstone TMS320C64X analysis (unsupported)",
210 	.license = "BSD",
211 	.arch = "tms320c64x",
212 	.bits = 32
213 };
214 #endif
215 
216 #ifndef R2_PLUGIN_INCORE
217 R_API RLibStruct radare_plugin = {
218 	.type = R_LIB_TYPE_ANAL,
219 	.data = &r_anal_plugin_tms320c64x,
220 	.version = R2_VERSION
221 };
222 #endif
223 */
224