1 /* radare - LGPL - Copyright 2010-2015 - pancake */
2
3 #include <string.h>
4 #include <r_types.h>
5 #include <r_lib.h>
6 #include <r_asm.h>
7 #include <r_anal.h>
8
9
10 static ut64 t9_pre = UT64_MAX;
11 #define REG_BUF_MAX 32
12 // ESIL macros:
13
14 // put the sign bit on the stack
15 #define ES_IS_NEGATIVE(arg) "1,"arg",<<<,1,&"
16
17 #define ES_B(x) "0xff,"x",&"
18 #define ES_H(x) "0xffff,"x",&"
19 #define ES_W(x) "0xffffffff,"x",&"
20 // call with delay slot
21 #define ES_CALL_DR(ra, addr) "pc,4,+,"ra",=,"ES_J(addr)
22 #define ES_CALL_D(addr) ES_CALL_DR("ra", addr)
23
24 // call without delay slot
25 #define ES_CALL_NDR(ra, addr) "pc,"ra",=,"ES_J(addr)
26 #define ES_CALL_ND(addr) ES_CALL_NDR("ra", addr)
27
28 #define USE_DS 0
29 #if USE_DS
30 // emit ERR trap if executed in a delay slot
31 #define ES_TRAP_DS() "$ds,!,!,?{,$$,1,TRAP,BREAK,},"
32 // jump to address
33 #define ES_J(addr) addr",SETJT,1,SETD"
34 #else
35 #define ES_TRAP_DS() ""
36 #define ES_J(addr) addr",pc,="
37 #endif
38
39 #define ES_SIGN32_64(arg) es_sign_n_64 (a, op, arg, 32)
40 #define ES_SIGN16_64(arg) es_sign_n_64 (a, op, arg, 16)
41
42 #define ES_ADD_CK32_OVERF(x, y, z) es_add_ck (op, x, y, z, 32)
43 #define ES_ADD_CK64_OVERF(x, y, z) es_add_ck (op, x, y, z, 64)
44
es_sign_n_64(RAnal * a,RAnalOp * op,const char * arg,int bit)45 static inline void es_sign_n_64(RAnal *a, RAnalOp *op, const char *arg, int bit)
46 {
47 if (a->bits == 64) {
48 r_strbuf_appendf (&op->esil, ",%d,%s,~,%s,=,", bit, arg, arg);
49 } else {
50 r_strbuf_append (&op->esil,",");
51 }
52 }
53
es_add_ck(RAnalOp * op,const char * a1,const char * a2,const char * re,int bit)54 static inline void es_add_ck(RAnalOp *op, const char *a1, const char *a2, const char *re, int bit)
55 {
56 ut64 mask = 1ULL << (bit-1);
57 r_strbuf_appendf (&op->esil,
58 "%d,0x%" PFMT64x ",%s,%s,^,&,>>,%d,0x%" PFMT64x ",%s,%s,+,&,>>,|,1,==,$z,?{,$$,1,TRAP,}{,%s,%s,+,%s,=,}",
59 bit-2, mask, a1, a2, bit-1, mask, a1, a2, a1, a2, re);
60 }
61 // MIPS instruction
62 typedef enum mips_insn {
63 MIPS_INS_INVALID = 0,
64
65 MIPS_INS_ABSQ_S,
66 MIPS_INS_ADD,
67 MIPS_INS_ADDIUPC,
68 MIPS_INS_ADDIUR1SP,
69 MIPS_INS_ADDIUR2,
70 MIPS_INS_ADDIUS5,
71 MIPS_INS_ADDIUSP,
72 MIPS_INS_ADDQH,
73 MIPS_INS_ADDQH_R,
74 MIPS_INS_ADDQ,
75 MIPS_INS_ADDQ_S,
76 MIPS_INS_ADDSC,
77 MIPS_INS_ADDS_A,
78 MIPS_INS_ADDS_S,
79 MIPS_INS_ADDS_U,
80 MIPS_INS_ADDU16,
81 MIPS_INS_ADDUH,
82 MIPS_INS_ADDUH_R,
83 MIPS_INS_ADDU,
84 MIPS_INS_ADDU_S,
85 MIPS_INS_ADDVI,
86 MIPS_INS_ADDV,
87 MIPS_INS_ADDWC,
88 MIPS_INS_ADD_A,
89 MIPS_INS_ADDI,
90 MIPS_INS_ADDIU,
91 MIPS_INS_ALIGN,
92 MIPS_INS_ALUIPC,
93 MIPS_INS_AND,
94 MIPS_INS_AND16,
95 MIPS_INS_ANDI16,
96 MIPS_INS_ANDI,
97 MIPS_INS_APPEND,
98 MIPS_INS_ASUB_S,
99 MIPS_INS_ASUB_U,
100 MIPS_INS_AUI,
101 MIPS_INS_AUIPC,
102 MIPS_INS_AVER_S,
103 MIPS_INS_AVER_U,
104 MIPS_INS_AVE_S,
105 MIPS_INS_AVE_U,
106 MIPS_INS_B16,
107 MIPS_INS_BADDU,
108 MIPS_INS_BAL,
109 MIPS_INS_BALC,
110 MIPS_INS_BALIGN,
111 MIPS_INS_BBIT0,
112 MIPS_INS_BBIT032,
113 MIPS_INS_BBIT1,
114 MIPS_INS_BBIT132,
115 MIPS_INS_BC,
116 MIPS_INS_BC0F,
117 MIPS_INS_BC0FL,
118 MIPS_INS_BC0T,
119 MIPS_INS_BC0TL,
120 MIPS_INS_BC1EQZ,
121 MIPS_INS_BC1F,
122 MIPS_INS_BC1FL,
123 MIPS_INS_BC1NEZ,
124 MIPS_INS_BC1T,
125 MIPS_INS_BC1TL,
126 MIPS_INS_BC2EQZ,
127 MIPS_INS_BC2F,
128 MIPS_INS_BC2FL,
129 MIPS_INS_BC2NEZ,
130 MIPS_INS_BC2T,
131 MIPS_INS_BC2TL,
132 MIPS_INS_BC3F,
133 MIPS_INS_BC3FL,
134 MIPS_INS_BC3T,
135 MIPS_INS_BC3TL,
136 MIPS_INS_BCLRI,
137 MIPS_INS_BCLR,
138 MIPS_INS_BEQ,
139 MIPS_INS_BEQC,
140 MIPS_INS_BEQL,
141 MIPS_INS_BEQZ16,
142 MIPS_INS_BEQZALC,
143 MIPS_INS_BEQZC,
144 MIPS_INS_BGEC,
145 MIPS_INS_BGEUC,
146 MIPS_INS_BGEZ,
147 MIPS_INS_BGEZAL,
148 MIPS_INS_BGEZALC,
149 MIPS_INS_BGEZALL,
150 MIPS_INS_BGEZALS,
151 MIPS_INS_BGEZC,
152 MIPS_INS_BGEZL,
153 MIPS_INS_BGTZ,
154 MIPS_INS_BGTZALC,
155 MIPS_INS_BGTZC,
156 MIPS_INS_BGTZL,
157 MIPS_INS_BINSLI,
158 MIPS_INS_BINSL,
159 MIPS_INS_BINSRI,
160 MIPS_INS_BINSR,
161 MIPS_INS_BITREV,
162 MIPS_INS_BITSWAP,
163 MIPS_INS_BLEZ,
164 MIPS_INS_BLEZALC,
165 MIPS_INS_BLEZC,
166 MIPS_INS_BLEZL,
167 MIPS_INS_BLTC,
168 MIPS_INS_BLTUC,
169 MIPS_INS_BLTZ,
170 MIPS_INS_BLTZAL,
171 MIPS_INS_BLTZALC,
172 MIPS_INS_BLTZALL,
173 MIPS_INS_BLTZALS,
174 MIPS_INS_BLTZC,
175 MIPS_INS_BLTZL,
176 MIPS_INS_BMNZI,
177 MIPS_INS_BMNZ,
178 MIPS_INS_BMZI,
179 MIPS_INS_BMZ,
180 MIPS_INS_BNE,
181 MIPS_INS_BNEC,
182 MIPS_INS_BNEGI,
183 MIPS_INS_BNEG,
184 MIPS_INS_BNEL,
185 MIPS_INS_BNEZ16,
186 MIPS_INS_BNEZALC,
187 MIPS_INS_BNEZC,
188 MIPS_INS_BNVC,
189 MIPS_INS_BNZ,
190 MIPS_INS_BOVC,
191 MIPS_INS_BPOSGE32,
192 MIPS_INS_BREAK,
193 MIPS_INS_BREAK16,
194 MIPS_INS_BSELI,
195 MIPS_INS_BSEL,
196 MIPS_INS_BSETI,
197 MIPS_INS_BSET,
198 MIPS_INS_BZ,
199 MIPS_INS_BEQZ,
200 MIPS_INS_B,
201 MIPS_INS_BNEZ,
202 MIPS_INS_BTEQZ,
203 MIPS_INS_BTNEZ,
204 MIPS_INS_CACHE,
205 MIPS_INS_CEIL,
206 MIPS_INS_CEQI,
207 MIPS_INS_CEQ,
208 MIPS_INS_CFC1,
209 MIPS_INS_CFCMSA,
210 MIPS_INS_CINS,
211 MIPS_INS_CINS32,
212 MIPS_INS_CLASS,
213 MIPS_INS_CLEI_S,
214 MIPS_INS_CLEI_U,
215 MIPS_INS_CLE_S,
216 MIPS_INS_CLE_U,
217 MIPS_INS_CLO,
218 MIPS_INS_CLTI_S,
219 MIPS_INS_CLTI_U,
220 MIPS_INS_CLT_S,
221 MIPS_INS_CLT_U,
222 MIPS_INS_CLZ,
223 MIPS_INS_CMPGDU,
224 MIPS_INS_CMPGU,
225 MIPS_INS_CMPU,
226 MIPS_INS_CMP,
227 MIPS_INS_COPY_S,
228 MIPS_INS_COPY_U,
229 MIPS_INS_CTC1,
230 MIPS_INS_CTCMSA,
231 MIPS_INS_CVT,
232 MIPS_INS_C,
233 MIPS_INS_CMPI,
234 MIPS_INS_DADD,
235 MIPS_INS_DADDI,
236 MIPS_INS_DADDIU,
237 MIPS_INS_DADDU,
238 MIPS_INS_DAHI,
239 MIPS_INS_DALIGN,
240 MIPS_INS_DATI,
241 MIPS_INS_DAUI,
242 MIPS_INS_DBITSWAP,
243 MIPS_INS_DCLO,
244 MIPS_INS_DCLZ,
245 MIPS_INS_DDIV,
246 MIPS_INS_DDIVU,
247 MIPS_INS_DERET,
248 MIPS_INS_DEXT,
249 MIPS_INS_DEXTM,
250 MIPS_INS_DEXTU,
251 MIPS_INS_DI,
252 MIPS_INS_DINS,
253 MIPS_INS_DINSM,
254 MIPS_INS_DINSU,
255 MIPS_INS_DIV,
256 MIPS_INS_DIVU,
257 MIPS_INS_DIV_S,
258 MIPS_INS_DIV_U,
259 MIPS_INS_DLSA,
260 MIPS_INS_DMFC0,
261 MIPS_INS_DMFC1,
262 MIPS_INS_DMFC2,
263 MIPS_INS_DMOD,
264 MIPS_INS_DMODU,
265 MIPS_INS_DMTC0,
266 MIPS_INS_DMTC1,
267 MIPS_INS_DMTC2,
268 MIPS_INS_DMUH,
269 MIPS_INS_DMUHU,
270 MIPS_INS_DMUL,
271 MIPS_INS_DMULT,
272 MIPS_INS_DMULTU,
273 MIPS_INS_DMULU,
274 MIPS_INS_DOTP_S,
275 MIPS_INS_DOTP_U,
276 MIPS_INS_DPADD_S,
277 MIPS_INS_DPADD_U,
278 MIPS_INS_DPAQX_SA,
279 MIPS_INS_DPAQX_S,
280 MIPS_INS_DPAQ_SA,
281 MIPS_INS_DPAQ_S,
282 MIPS_INS_DPAU,
283 MIPS_INS_DPAX,
284 MIPS_INS_DPA,
285 MIPS_INS_DPOP,
286 MIPS_INS_DPSQX_SA,
287 MIPS_INS_DPSQX_S,
288 MIPS_INS_DPSQ_SA,
289 MIPS_INS_DPSQ_S,
290 MIPS_INS_DPSUB_S,
291 MIPS_INS_DPSUB_U,
292 MIPS_INS_DPSU,
293 MIPS_INS_DPSX,
294 MIPS_INS_DPS,
295 MIPS_INS_DROTR,
296 MIPS_INS_DROTR32,
297 MIPS_INS_DROTRV,
298 MIPS_INS_DSBH,
299 MIPS_INS_DSHD,
300 MIPS_INS_DSLL,
301 MIPS_INS_DSLL32,
302 MIPS_INS_DSLLV,
303 MIPS_INS_DSRA,
304 MIPS_INS_DSRA32,
305 MIPS_INS_DSRAV,
306 MIPS_INS_DSRL,
307 MIPS_INS_DSRL32,
308 MIPS_INS_DSRLV,
309 MIPS_INS_DSUB,
310 MIPS_INS_DSUBU,
311 MIPS_INS_EHB,
312 MIPS_INS_EI,
313 MIPS_INS_ERET,
314 MIPS_INS_EXT,
315 MIPS_INS_EXTP,
316 MIPS_INS_EXTPDP,
317 MIPS_INS_EXTPDPV,
318 MIPS_INS_EXTPV,
319 MIPS_INS_EXTRV_RS,
320 MIPS_INS_EXTRV_R,
321 MIPS_INS_EXTRV_S,
322 MIPS_INS_EXTRV,
323 MIPS_INS_EXTR_RS,
324 MIPS_INS_EXTR_R,
325 MIPS_INS_EXTR_S,
326 MIPS_INS_EXTR,
327 MIPS_INS_EXTS,
328 MIPS_INS_EXTS32,
329 MIPS_INS_ABS,
330 MIPS_INS_FADD,
331 MIPS_INS_FCAF,
332 MIPS_INS_FCEQ,
333 MIPS_INS_FCLASS,
334 MIPS_INS_FCLE,
335 MIPS_INS_FCLT,
336 MIPS_INS_FCNE,
337 MIPS_INS_FCOR,
338 MIPS_INS_FCUEQ,
339 MIPS_INS_FCULE,
340 MIPS_INS_FCULT,
341 MIPS_INS_FCUNE,
342 MIPS_INS_FCUN,
343 MIPS_INS_FDIV,
344 MIPS_INS_FEXDO,
345 MIPS_INS_FEXP2,
346 MIPS_INS_FEXUPL,
347 MIPS_INS_FEXUPR,
348 MIPS_INS_FFINT_S,
349 MIPS_INS_FFINT_U,
350 MIPS_INS_FFQL,
351 MIPS_INS_FFQR,
352 MIPS_INS_FILL,
353 MIPS_INS_FLOG2,
354 MIPS_INS_FLOOR,
355 MIPS_INS_FMADD,
356 MIPS_INS_FMAX_A,
357 MIPS_INS_FMAX,
358 MIPS_INS_FMIN_A,
359 MIPS_INS_FMIN,
360 MIPS_INS_MOV,
361 MIPS_INS_FMSUB,
362 MIPS_INS_FMUL,
363 MIPS_INS_MUL,
364 MIPS_INS_NEG,
365 MIPS_INS_FRCP,
366 MIPS_INS_FRINT,
367 MIPS_INS_FRSQRT,
368 MIPS_INS_FSAF,
369 MIPS_INS_FSEQ,
370 MIPS_INS_FSLE,
371 MIPS_INS_FSLT,
372 MIPS_INS_FSNE,
373 MIPS_INS_FSOR,
374 MIPS_INS_FSQRT,
375 MIPS_INS_SQRT,
376 MIPS_INS_FSUB,
377 MIPS_INS_SUB,
378 MIPS_INS_FSUEQ,
379 MIPS_INS_FSULE,
380 MIPS_INS_FSULT,
381 MIPS_INS_FSUNE,
382 MIPS_INS_FSUN,
383 MIPS_INS_FTINT_S,
384 MIPS_INS_FTINT_U,
385 MIPS_INS_FTQ,
386 MIPS_INS_FTRUNC_S,
387 MIPS_INS_FTRUNC_U,
388 MIPS_INS_HADD_S,
389 MIPS_INS_HADD_U,
390 MIPS_INS_HSUB_S,
391 MIPS_INS_HSUB_U,
392 MIPS_INS_ILVEV,
393 MIPS_INS_ILVL,
394 MIPS_INS_ILVOD,
395 MIPS_INS_ILVR,
396 MIPS_INS_INS,
397 MIPS_INS_INSERT,
398 MIPS_INS_INSV,
399 MIPS_INS_INSVE,
400 MIPS_INS_J,
401 MIPS_INS_JAL,
402 MIPS_INS_JALR,
403 MIPS_INS_JALRS16,
404 MIPS_INS_JALRS,
405 MIPS_INS_JALS,
406 MIPS_INS_JALX,
407 MIPS_INS_JIALC,
408 MIPS_INS_JIC,
409 MIPS_INS_JR,
410 MIPS_INS_JR16,
411 MIPS_INS_JRADDIUSP,
412 MIPS_INS_JRC,
413 MIPS_INS_JALRC,
414 MIPS_INS_LB,
415 MIPS_INS_LBU16,
416 MIPS_INS_LBUX,
417 MIPS_INS_LBU,
418 MIPS_INS_LD,
419 MIPS_INS_LDC1,
420 MIPS_INS_LDC2,
421 MIPS_INS_LDC3,
422 MIPS_INS_LDI,
423 MIPS_INS_LDL,
424 MIPS_INS_LDPC,
425 MIPS_INS_LDR,
426 MIPS_INS_LDXC1,
427 MIPS_INS_LH,
428 MIPS_INS_LHU16,
429 MIPS_INS_LHX,
430 MIPS_INS_LHU,
431 MIPS_INS_LI16,
432 MIPS_INS_LL,
433 MIPS_INS_LLD,
434 MIPS_INS_LSA,
435 MIPS_INS_LUXC1,
436 MIPS_INS_LUI,
437 MIPS_INS_LW,
438 MIPS_INS_LW16,
439 MIPS_INS_LWC1,
440 MIPS_INS_LWC2,
441 MIPS_INS_LWC3,
442 MIPS_INS_LWL,
443 MIPS_INS_LWM16,
444 MIPS_INS_LWM32,
445 MIPS_INS_LWPC,
446 MIPS_INS_LWP,
447 MIPS_INS_LWR,
448 MIPS_INS_LWUPC,
449 MIPS_INS_LWU,
450 MIPS_INS_LWX,
451 MIPS_INS_LWXC1,
452 MIPS_INS_LWXS,
453 MIPS_INS_LI,
454 MIPS_INS_MADD,
455 MIPS_INS_MADDF,
456 MIPS_INS_MADDR_Q,
457 MIPS_INS_MADDU,
458 MIPS_INS_MADDV,
459 MIPS_INS_MADD_Q,
460 MIPS_INS_MAQ_SA,
461 MIPS_INS_MAQ_S,
462 MIPS_INS_MAXA,
463 MIPS_INS_MAXI_S,
464 MIPS_INS_MAXI_U,
465 MIPS_INS_MAX_A,
466 MIPS_INS_MAX,
467 MIPS_INS_MAX_S,
468 MIPS_INS_MAX_U,
469 MIPS_INS_MFC0,
470 MIPS_INS_MFC1,
471 MIPS_INS_MFC2,
472 MIPS_INS_MFHC1,
473 MIPS_INS_MFHI,
474 MIPS_INS_MFLO,
475 MIPS_INS_MINA,
476 MIPS_INS_MINI_S,
477 MIPS_INS_MINI_U,
478 MIPS_INS_MIN_A,
479 MIPS_INS_MIN,
480 MIPS_INS_MIN_S,
481 MIPS_INS_MIN_U,
482 MIPS_INS_MOD,
483 MIPS_INS_MODSUB,
484 MIPS_INS_MODU,
485 MIPS_INS_MOD_S,
486 MIPS_INS_MOD_U,
487 MIPS_INS_MOVE,
488 MIPS_INS_MOVEP,
489 MIPS_INS_MOVF,
490 MIPS_INS_MOVN,
491 MIPS_INS_MOVT,
492 MIPS_INS_MOVZ,
493 MIPS_INS_MSUB,
494 MIPS_INS_MSUBF,
495 MIPS_INS_MSUBR_Q,
496 MIPS_INS_MSUBU,
497 MIPS_INS_MSUBV,
498 MIPS_INS_MSUB_Q,
499 MIPS_INS_MTC0,
500 MIPS_INS_MTC1,
501 MIPS_INS_MTC2,
502 MIPS_INS_MTHC1,
503 MIPS_INS_MTHI,
504 MIPS_INS_MTHLIP,
505 MIPS_INS_MTLO,
506 MIPS_INS_MTM0,
507 MIPS_INS_MTM1,
508 MIPS_INS_MTM2,
509 MIPS_INS_MTP0,
510 MIPS_INS_MTP1,
511 MIPS_INS_MTP2,
512 MIPS_INS_MUH,
513 MIPS_INS_MUHU,
514 MIPS_INS_MULEQ_S,
515 MIPS_INS_MULEU_S,
516 MIPS_INS_MULQ_RS,
517 MIPS_INS_MULQ_S,
518 MIPS_INS_MULR_Q,
519 MIPS_INS_MULSAQ_S,
520 MIPS_INS_MULSA,
521 MIPS_INS_MULT,
522 MIPS_INS_MULTU,
523 MIPS_INS_MULU,
524 MIPS_INS_MULV,
525 MIPS_INS_MUL_Q,
526 MIPS_INS_MUL_S,
527 MIPS_INS_NLOC,
528 MIPS_INS_NLZC,
529 MIPS_INS_NMADD,
530 MIPS_INS_NMSUB,
531 MIPS_INS_NOR,
532 MIPS_INS_NORI,
533 MIPS_INS_NOT16,
534 MIPS_INS_NOT,
535 MIPS_INS_OR,
536 MIPS_INS_OR16,
537 MIPS_INS_ORI,
538 MIPS_INS_PACKRL,
539 MIPS_INS_PAUSE,
540 MIPS_INS_PCKEV,
541 MIPS_INS_PCKOD,
542 MIPS_INS_PCNT,
543 MIPS_INS_PICK,
544 MIPS_INS_POP,
545 MIPS_INS_PRECEQU,
546 MIPS_INS_PRECEQ,
547 MIPS_INS_PRECEU,
548 MIPS_INS_PRECRQU_S,
549 MIPS_INS_PRECRQ,
550 MIPS_INS_PRECRQ_RS,
551 MIPS_INS_PRECR,
552 MIPS_INS_PRECR_SRA,
553 MIPS_INS_PRECR_SRA_R,
554 MIPS_INS_PREF,
555 MIPS_INS_PREPEND,
556 MIPS_INS_RADDU,
557 MIPS_INS_RDDSP,
558 MIPS_INS_RDHWR,
559 MIPS_INS_REPLV,
560 MIPS_INS_REPL,
561 MIPS_INS_RINT,
562 MIPS_INS_ROTR,
563 MIPS_INS_ROTRV,
564 MIPS_INS_ROUND,
565 MIPS_INS_SAT_S,
566 MIPS_INS_SAT_U,
567 MIPS_INS_SB,
568 MIPS_INS_SB16,
569 MIPS_INS_SC,
570 MIPS_INS_SCD,
571 MIPS_INS_SD,
572 MIPS_INS_SDBBP,
573 MIPS_INS_SDBBP16,
574 MIPS_INS_SDC1,
575 MIPS_INS_SDC2,
576 MIPS_INS_SDC3,
577 MIPS_INS_SDL,
578 MIPS_INS_SDR,
579 MIPS_INS_SDXC1,
580 MIPS_INS_SEB,
581 MIPS_INS_SEH,
582 MIPS_INS_SELEQZ,
583 MIPS_INS_SELNEZ,
584 MIPS_INS_SEL,
585 MIPS_INS_SEQ,
586 MIPS_INS_SEQI,
587 MIPS_INS_SH,
588 MIPS_INS_SH16,
589 MIPS_INS_SHF,
590 MIPS_INS_SHILO,
591 MIPS_INS_SHILOV,
592 MIPS_INS_SHLLV,
593 MIPS_INS_SHLLV_S,
594 MIPS_INS_SHLL,
595 MIPS_INS_SHLL_S,
596 MIPS_INS_SHRAV,
597 MIPS_INS_SHRAV_R,
598 MIPS_INS_SHRA,
599 MIPS_INS_SHRA_R,
600 MIPS_INS_SHRLV,
601 MIPS_INS_SHRL,
602 MIPS_INS_SLDI,
603 MIPS_INS_SLD,
604 MIPS_INS_SLL,
605 MIPS_INS_SLL16,
606 MIPS_INS_SLLI,
607 MIPS_INS_SLLV,
608 MIPS_INS_SLT,
609 MIPS_INS_SLTI,
610 MIPS_INS_SLTIU,
611 MIPS_INS_SLTU,
612 MIPS_INS_SNE,
613 MIPS_INS_SNEI,
614 MIPS_INS_SPLATI,
615 MIPS_INS_SPLAT,
616 MIPS_INS_SRA,
617 MIPS_INS_SRAI,
618 MIPS_INS_SRARI,
619 MIPS_INS_SRAR,
620 MIPS_INS_SRAV,
621 MIPS_INS_SRL,
622 MIPS_INS_SRL16,
623 MIPS_INS_SRLI,
624 MIPS_INS_SRLRI,
625 MIPS_INS_SRLR,
626 MIPS_INS_SRLV,
627 MIPS_INS_SSNOP,
628 MIPS_INS_ST,
629 MIPS_INS_SUBQH,
630 MIPS_INS_SUBQH_R,
631 MIPS_INS_SUBQ,
632 MIPS_INS_SUBQ_S,
633 MIPS_INS_SUBSUS_U,
634 MIPS_INS_SUBSUU_S,
635 MIPS_INS_SUBS_S,
636 MIPS_INS_SUBS_U,
637 MIPS_INS_SUBU16,
638 MIPS_INS_SUBUH,
639 MIPS_INS_SUBUH_R,
640 MIPS_INS_SUBU,
641 MIPS_INS_SUBU_S,
642 MIPS_INS_SUBVI,
643 MIPS_INS_SUBV,
644 MIPS_INS_SUXC1,
645 MIPS_INS_SW,
646 MIPS_INS_SW16,
647 MIPS_INS_SWC1,
648 MIPS_INS_SWC2,
649 MIPS_INS_SWC3,
650 MIPS_INS_SWL,
651 MIPS_INS_SWM16,
652 MIPS_INS_SWM32,
653 MIPS_INS_SWP,
654 MIPS_INS_SWR,
655 MIPS_INS_SWXC1,
656 MIPS_INS_SYNC,
657 MIPS_INS_SYNCI,
658 MIPS_INS_SYSCALL,
659 MIPS_INS_TEQ,
660 MIPS_INS_TEQI,
661 MIPS_INS_TGE,
662 MIPS_INS_TGEI,
663 MIPS_INS_TGEIU,
664 MIPS_INS_TGEU,
665 MIPS_INS_TLBP,
666 MIPS_INS_TLBR,
667 MIPS_INS_TLBWI,
668 MIPS_INS_TLBWR,
669 MIPS_INS_TLT,
670 MIPS_INS_TLTI,
671 MIPS_INS_TLTIU,
672 MIPS_INS_TLTU,
673 MIPS_INS_TNE,
674 MIPS_INS_TNEI,
675 MIPS_INS_TRUNC,
676 MIPS_INS_V3MULU,
677 MIPS_INS_VMM0,
678 MIPS_INS_VMULU,
679 MIPS_INS_VSHF,
680 MIPS_INS_WAIT,
681 MIPS_INS_WRDSP,
682 MIPS_INS_WSBH,
683 MIPS_INS_XOR,
684 MIPS_INS_XOR16,
685 MIPS_INS_XORI,
686
687 //> some alias instructions
688 MIPS_INS_NOP,
689 MIPS_INS_NEGU,
690
691 //> special instructions
692 MIPS_INS_JALR_HB, // jump and link with Hazard Barrier
693 MIPS_INS_JR_HB, // jump register with Hazard Barrier
694
695 MIPS_INS_ENDING,
696 } mips_insn;
697
698
699 struct gnu_rreg {
700 const char *rs;
701 const char *rt;
702 const char *rd;
703 ut8 sa[REG_BUF_MAX];
704 };
705
706 struct gnu_jreg {
707 ut8 jump[REG_BUF_MAX];
708 };
709
710 struct gnu_ireg {
711 const char *rs;
712 const char *rt;
713 union {
714 ut8 imm[REG_BUF_MAX];
715 ut8 jump[REG_BUF_MAX];
716 };
717 };
718
719 typedef struct gnu_insn {
720 ut8 optype;
721 ut32 id;
722 union {
723 struct gnu_rreg r_reg;
724 struct gnu_ireg i_reg;
725 struct gnu_jreg j_reg;
726 };
727 } gnu_insn;
728
729
730 #define R_REG(x) ((const char *)insn->r_reg.x)
731 #define I_REG(x) ((const char *)insn->i_reg.x)
732 #define J_REG(x) ((const char *)insn->j_reg.x)
733
734
735 /* Return a mapping from the register number i.e. $0 .. $31 to string name */
mips_reg_decode(ut32 reg_num)736 static const char* mips_reg_decode(ut32 reg_num) {
737 /* See page 36 of "See Mips Run Linux, 2e, D. Sweetman, 2007"*/
738 static const char *REGISTERS[32] = {
739 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
740 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
741 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
742 "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra"
743 };
744 if (reg_num < 32) {
745 return REGISTERS[reg_num];
746 }
747 return NULL;
748 }
749
analop_esil(RAnal * a,RAnalOp * op,ut64 addr,gnu_insn * insn)750 static int analop_esil(RAnal *a, RAnalOp *op, ut64 addr, gnu_insn*insn) {
751
752 switch (insn->id) {
753 case MIPS_INS_NOP:
754 r_strbuf_setf (&op->esil, ",");
755 break;
756 case MIPS_INS_BREAK:
757 //r_strbuf_setf (&op->esil, "%d,%d,TRAP", IMM (0), IMM (0));
758 break;
759 case MIPS_INS_SD:
760 r_strbuf_appendf (&op->esil, "%s,%s,%s,+,=[8]",
761 I_REG (rt), I_REG (imm), I_REG (rs));
762 break;
763 case MIPS_INS_SW:
764 case MIPS_INS_SWL:
765 case MIPS_INS_SWR:
766 r_strbuf_appendf (&op->esil, "%s,%s,%s,+,=[4]",
767 I_REG (rt),I_REG (imm), I_REG (rs));
768 break;
769 case MIPS_INS_SH:
770 r_strbuf_appendf (&op->esil, "%s,%s,%s,+,=[2]",
771 I_REG (rt),I_REG (imm), I_REG (rs));
772 break;
773 case MIPS_INS_SWC1:
774 case MIPS_INS_SWC2:
775 break;
776 case MIPS_INS_SB:
777 r_strbuf_appendf (&op->esil, "%s,%s,%s,+,=[1]",
778 I_REG (rt),I_REG (imm), I_REG (rs));
779 break;
780 case MIPS_INS_CMP:
781 case MIPS_INS_CMPU:
782 case MIPS_INS_CMPGU:
783 case MIPS_INS_CMPGDU:
784 case MIPS_INS_CMPI:
785 break;
786 case MIPS_INS_SHRAV:
787 case MIPS_INS_SHRAV_R:
788 case MIPS_INS_SHRA:
789 case MIPS_INS_SHRA_R:
790 break;
791 case MIPS_INS_SRA:
792 r_strbuf_appendf (&op->esil,
793 ES_W ("%s,%s")",>>,31,%s,>>,?{,%s,32,-,0xffffffff,<<,0xffffffff,&,}{,0,},|,%s,=",
794 R_REG (sa), R_REG (rt), R_REG (rt), R_REG (sa), R_REG (rd));
795 break;
796 case MIPS_INS_DSRA:
797 r_strbuf_appendf (&op->esil,
798 "%s,%s,>>,31,%s,>>,?{,32,%s,32,-,0xffffffff,<<,0xffffffff,&,<<,}{,0,},|,%s,=",
799 R_REG (sa), R_REG (rt), R_REG (rt), R_REG (sa), R_REG (rd));
800 break;
801 case MIPS_INS_SHRL:
802 // suffix 'S' forces conditional flag to be updated
803 break;
804 case MIPS_INS_SRLV:
805 case MIPS_INS_SRL:
806 r_strbuf_appendf (&op->esil, "%s,%s,>>,%s,=", \
807 R_REG (rs)?R_REG (rs):R_REG (sa), R_REG (rt),R_REG (rd) );
808 break;
809 case MIPS_INS_SLLV:
810 case MIPS_INS_SLL:
811 r_strbuf_appendf (&op->esil, "%s,%s,<<,%s,=", \
812 R_REG (rs)?R_REG (rs):R_REG (sa),R_REG (rt),R_REG (rd) );
813 break;
814 case MIPS_INS_BAL:
815 case MIPS_INS_JAL:
816 r_strbuf_appendf (&op->esil, ES_TRAP_DS () "" ES_CALL_D ("%s"), I_REG (jump));
817 break;
818 case MIPS_INS_JALR:
819 case MIPS_INS_JALRS:
820 if (strcmp(R_REG(rd), "rd")==0) {
821 r_strbuf_appendf (&op->esil, ES_TRAP_DS () "" ES_CALL_D ("%s"), R_REG (rs));
822 } else {
823 r_strbuf_appendf (&op->esil, ES_TRAP_DS () "" ES_CALL_DR ("%s", "%s"), R_REG (rd), R_REG (rs));
824 }
825 break;
826 case MIPS_INS_JR:
827 case MIPS_INS_JRC:
828 r_strbuf_appendf (&op->esil, ES_TRAP_DS () "" ES_J ("%s"), R_REG (rs));
829 break;
830 case MIPS_INS_J:
831 r_strbuf_appendf (&op->esil, ES_TRAP_DS () "" ES_J ("%s"), J_REG (jump));
832 case MIPS_INS_B:
833 // jump to address with conditional
834 r_strbuf_appendf (&op->esil, ES_TRAP_DS () "" ES_J ("%s"), I_REG (jump));
835 break;
836 case MIPS_INS_BNE: // bne $s, $t, offset
837 case MIPS_INS_BNEL:
838 r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,%s,==,$z,!,?{," ES_J ("%s") ",}",
839 I_REG (rs), I_REG (rt), I_REG (jump));
840 break;
841 case MIPS_INS_BEQ:
842 case MIPS_INS_BEQL:
843 r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,%s,==,$z,?{," ES_J ("%s") ",}",
844 I_REG (rs), I_REG (rt), I_REG (jump));
845 break;
846 case MIPS_INS_BZ:
847 case MIPS_INS_BEQZ:
848 case MIPS_INS_BEQZC:
849 r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,0,==,$z,?{," ES_J ("%s") ",}",
850 I_REG (rs), I_REG (jump));
851 break;
852 case MIPS_INS_BNEZ:
853 r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,0,==,$z,!,?{," ES_J ("%s") ",}",
854 I_REG (rs), I_REG (jump));
855 break;
856 case MIPS_INS_BLEZ:
857 case MIPS_INS_BLEZC:
858 case MIPS_INS_BLEZL:
859 r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0,%s,==,$z,?{," ES_J ("%s") ",BREAK,},",
860 I_REG (rs), I_REG (jump));
861 r_strbuf_appendf (&op->esil, ES_TRAP_DS () "1," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J ("%s") ",}",
862 I_REG (rs), I_REG (jump));
863 break;
864 case MIPS_INS_BGEZ:
865 case MIPS_INS_BGEZC:
866 case MIPS_INS_BGEZL:
867 r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J ("%s") ",}",
868 I_REG (rs), I_REG (jump));
869 break;
870 case MIPS_INS_BGEZAL:
871 r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_CALL_D ("%s") ",}",
872 I_REG (rs), I_REG (jump));
873 break;
874 case MIPS_INS_BLTZAL:
875 r_strbuf_appendf (&op->esil, ES_TRAP_DS () "1," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_CALL_D ("%s") ",}",
876 I_REG (rs), I_REG (jump));
877 break;
878 case MIPS_INS_BLTZ:
879 case MIPS_INS_BLTZC:
880 case MIPS_INS_BLTZL:
881 r_strbuf_appendf (&op->esil, ES_TRAP_DS () "1," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J ("%s") ",}",
882 I_REG (rs), I_REG (jump));
883 break;
884 case MIPS_INS_BGTZ:
885 case MIPS_INS_BGTZC:
886 case MIPS_INS_BGTZL:
887 r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0,%s,==,$z,?{,BREAK,},", I_REG (rs));
888 r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J ("%s") ",}",
889 I_REG (rs), I_REG (jump));
890 break;
891 case MIPS_INS_BTEQZ:
892 break;
893 case MIPS_INS_BTNEZ:
894 break;
895 case MIPS_INS_MOV:
896 case MIPS_INS_MOVE:
897 r_strbuf_appendf (&op->esil, "%s,%s,=", R_REG (rs), R_REG (rd));
898 break;
899 case MIPS_INS_MOVZ:
900 case MIPS_INS_MOVF:
901 r_strbuf_appendf (&op->esil, "0,%s,==,$z,?{,%s,%s,=,}",
902 R_REG (rt), R_REG (rs), R_REG (rd));
903 break;
904 case MIPS_INS_MOVT:
905 r_strbuf_appendf (&op->esil, "1,%s,==,$z,?{,%s,%s,=,}",
906 R_REG (rt), R_REG (rs), R_REG (rd));
907 break;
908 case MIPS_INS_FSUB:
909 case MIPS_INS_SUB:
910 case MIPS_INS_SUBU:
911 case MIPS_INS_DSUB:
912 case MIPS_INS_DSUBU:
913 r_strbuf_appendf (&op->esil, "%s,%s,-,%s,=",
914 R_REG (rt), R_REG (rs), R_REG (rd));
915 break;
916 case MIPS_INS_NEG:
917 case MIPS_INS_NEGU:
918 break;
919 /** signed -- sets overflow flag */
920 case MIPS_INS_ADD:
921 ES_ADD_CK32_OVERF(R_REG (rs), R_REG (rt), R_REG (rd));
922 break;
923 case MIPS_INS_ADDI:
924 ES_ADD_CK32_OVERF(I_REG (imm), I_REG (rs), I_REG (rt));
925 break;
926 case MIPS_INS_DADD:
927 ES_ADD_CK64_OVERF(R_REG (rs), R_REG (rt), R_REG (rd));
928 break;
929 case MIPS_INS_DADDU:
930 case MIPS_INS_ADDU:
931 r_strbuf_appendf (&op->esil, "%s,%s,+,%s,=",\
932 R_REG (rt), R_REG (rs), R_REG (rd));
933 break;
934 case MIPS_INS_DADDI:
935 ES_ADD_CK64_OVERF(I_REG (imm), I_REG (rs), I_REG (rt));
936 break;
937 case MIPS_INS_ADDIU:
938 case MIPS_INS_DADDIU:
939 r_strbuf_appendf (&op->esil, "%s,%s,+,%s,=",
940 I_REG (imm), I_REG (rs), I_REG (rt));
941 ES_SIGN32_64 (I_REG (rt));
942 break;
943 case MIPS_INS_LI:
944 case MIPS_INS_LDI:
945 r_strbuf_appendf (&op->esil, "%s,%s,=", I_REG (imm), I_REG (rt));
946 break;
947 case MIPS_INS_LUI:
948 r_strbuf_appendf (&op->esil, "%s0000,%s,=",I_REG (imm), I_REG (rt));
949 break;
950 case MIPS_INS_LB:
951 op->sign = true; //To load a byte from memory as a signed value
952 /* fallthrough */
953 case MIPS_INS_LBU:
954 //one of these is wrong
955 r_strbuf_appendf (&op->esil, "%s,%s,+,[1],%s,=",\
956 I_REG (imm), I_REG (rs), I_REG (rt));\
957 break;
958 case MIPS_INS_LW:
959 case MIPS_INS_LWC1:
960 case MIPS_INS_LWC2:
961 case MIPS_INS_LWL:
962 case MIPS_INS_LWR:
963 case MIPS_INS_LWU:
964 case MIPS_INS_LL:
965 r_strbuf_appendf (&op->esil, "%s,%s,+,[4],%s,=",\
966 I_REG (imm), I_REG (rs), I_REG (rt));\
967 break;
968 case MIPS_INS_LDL:
969 case MIPS_INS_LDC1:
970 case MIPS_INS_LDC2:
971 case MIPS_INS_LLD:
972 case MIPS_INS_LD:
973 r_strbuf_appendf (&op->esil, "%s,%s,+,[8],%s,=",\
974 I_REG (imm), I_REG (rs), I_REG (rt));\
975 break;
976 case MIPS_INS_LH:
977 op->sign = true; //To load a byte from memory as a signed value
978 /* fallthrough */
979 case MIPS_INS_LHU:
980 r_strbuf_appendf (&op->esil, "%s,%s,+,[2],%s,=",\
981 I_REG (imm), I_REG (rs), I_REG (rt));\
982 break;
983 case MIPS_INS_LHX:
984 case MIPS_INS_LWX:
985 break;
986 case MIPS_INS_AND:
987 r_strbuf_appendf (&op->esil, "%s,%s,&,%s,=", R_REG (rt), R_REG (rs), R_REG (rd));
988 break;
989 case MIPS_INS_ANDI:
990 r_strbuf_appendf (&op->esil, "%s,%s,&,%s,=", I_REG (imm), I_REG (rs), I_REG (rt));
991 break;
992 case MIPS_INS_OR:
993 r_strbuf_appendf (&op->esil, "%s,%s,|,%s,=", R_REG (rt), R_REG (rs), R_REG (rd));
994 break;
995 case MIPS_INS_ORI:
996 r_strbuf_appendf (&op->esil, "%s,%s,|,%s,=", I_REG (imm), I_REG (rs), I_REG (rt));
997 break;
998 case MIPS_INS_XOR:
999 r_strbuf_appendf (&op->esil, "%s,%s,^,%s,=", R_REG (rt), R_REG (rs), R_REG (rd));
1000 break;
1001 case MIPS_INS_XORI:
1002 r_strbuf_appendf (&op->esil, "%s,%s,^,%s,=", I_REG (imm), I_REG (rs), I_REG (rt));
1003 break;
1004 case MIPS_INS_NOR:
1005 r_strbuf_appendf (&op->esil, "%s,%s,|,0xffffffff,^,%s,=",R_REG (rs), R_REG (rt), R_REG (rd));
1006 break;
1007 case MIPS_INS_SLT:
1008 r_strbuf_appendf (&op->esil, "%s,%s,<,t,=", R_REG (rs), R_REG (rt));
1009 break;
1010 case MIPS_INS_SLTI:
1011 r_strbuf_appendf (&op->esil, "%s,%s,<,%s,=", I_REG (imm), I_REG (rs), I_REG (rt));
1012 break;
1013 case MIPS_INS_SLTU:
1014 r_strbuf_appendf (&op->esil, "%s,0xffffffff,&,%s,0xffffffff,&,<,t,=",
1015 R_REG (rs), R_REG (rt));
1016 break;
1017 case MIPS_INS_SLTIU:
1018 r_strbuf_appendf (&op->esil, "%s,0xffffffff,&,%s,0xffffffff,&,<,%s,=",
1019 I_REG (imm), I_REG (rs), I_REG (rt));
1020 break;
1021 case MIPS_INS_MUL:
1022 r_strbuf_appendf (&op->esil, ES_W("%s,%s,*")",%s,=", R_REG (rs), R_REG (rt), R_REG (rd));
1023 ES_SIGN32_64 (R_REG (rd));
1024 break;
1025 case MIPS_INS_MULT:
1026 case MIPS_INS_MULTU:
1027 r_strbuf_appendf (&op->esil, ES_W("%s,%s,*")",lo,=", R_REG (rs), R_REG (rt));
1028 ES_SIGN32_64 ("lo");
1029 r_strbuf_appendf (&op->esil, ES_W("32,%s,%s,*,>>")",hi,=", R_REG (rs), R_REG (rt));
1030 ES_SIGN32_64 ("hi");
1031 break;
1032 case MIPS_INS_MFLO:
1033 r_strbuf_appendf (&op->esil, "lo,%s,=", R_REG (rd));
1034 break;
1035 case MIPS_INS_MFHI:
1036 r_strbuf_appendf (&op->esil, "hi,%s,=", R_REG (rd));
1037 break;
1038 case MIPS_INS_MTLO:
1039 r_strbuf_appendf (&op->esil, "%s,lo,=,", R_REG (rs));
1040 ES_SIGN32_64 ("lo");
1041 break;
1042 case MIPS_INS_MTHI:
1043 r_strbuf_appendf (&op->esil, "%s,hi,=,", R_REG (rs));
1044 ES_SIGN32_64 ("hi");
1045 break;
1046 default:
1047 return -1;
1048 }
1049
1050 return 0;
1051 }
1052
1053
mips_op(RAnal * anal,RAnalOp * op,ut64 addr,const ut8 * b,int len,RAnalOpMask mask)1054 static int mips_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int len, RAnalOpMask mask) {
1055 ut32 opcode;
1056 // WIP char buf[10]; int reg; int family;
1057 int optype, oplen = (anal->bits==16)?2:4;
1058 const ut8 * buf;
1059 gnu_insn insn;
1060
1061 if (!op) {
1062 return oplen;
1063 }
1064
1065 op->type = R_ANAL_OP_TYPE_UNK;
1066 op->size = oplen;
1067 op->addr = addr;
1068 // Be endian aware
1069 opcode = r_read_ble32 (b, anal->big_endian);
1070
1071 // eprintf ("MIPS: %02x %02x %02x %02x (after endian: big=%d)\n", buf[0], buf[1], buf[2], buf[3], anal->big_endian);
1072 if (opcode == 0) {
1073 op->type = R_ANAL_OP_TYPE_NOP;
1074 return oplen;
1075 }
1076
1077 opcode = r_swap_ut32(opcode);
1078 buf = (ut8 *) & opcode;
1079
1080 optype = (buf[0]>>2);
1081 insn.optype = optype;
1082 insn.id = 0;
1083
1084 if (optype == 0) {
1085 /*
1086 R-TYPE
1087 ======
1088 opcode (6) rs (5) rt (5) rd (5) sa (5) function (6)
1089 rs = register source
1090 rt = register target
1091 rd = register destination
1092 sa =
1093 fu =
1094 |--[0]--| |--[1]--| |--[2]--| |--[3]--|
1095 1111 1111 1111 1111 1111 1111 1111 1111
1096 \_op__/\_rs__/\_rt_/ \_rd_/\_sa__/\_fun_/
1097 | | | | | |
1098 buf[0]>>2 | (buf[1]&31) | | buf[3]&63
1099 | (buf[2]>>3) |
1100 (buf[0]&3)<<3)+(buf[1]>>5) (buf[2]&7)+(buf[3]>>6)
1101 */
1102 int rs = ((buf[0]&3)<<3) + (buf[1]>>5);
1103 int rt = buf[1]&31;
1104 int rd = buf[2]>>3;
1105 int sa = ((buf[2]&7)<<2)+(buf[3]>>6);
1106 int fun = buf[3]&63;
1107
1108 insn.r_reg.rs = mips_reg_decode (rs);
1109 insn.r_reg.rd = mips_reg_decode (rd);
1110 insn.r_reg.rt = mips_reg_decode (rt);
1111 snprintf ((char *)insn.r_reg.sa, REG_BUF_MAX, "%"PFMT32d, sa);
1112
1113 switch (fun) {
1114 case 0: // sll
1115 insn.id = MIPS_INS_SLL;
1116 insn.r_reg.rs = NULL;
1117 op->val = sa;
1118 case 4: // sllv
1119 insn.id = MIPS_INS_SLLV;
1120 op->type = R_ANAL_OP_TYPE_SHL;
1121 break;
1122 case 2: // srl
1123 insn.id = MIPS_INS_SRL;
1124 insn.r_reg.rs = NULL;
1125 op->val = sa;
1126 case 6: // srlv
1127 insn.id = MIPS_INS_SRLV;
1128 op->type = R_ANAL_OP_TYPE_SHR;
1129 break;
1130 case 3: // sra
1131 insn.id = MIPS_INS_SRA;
1132 op->type = R_ANAL_OP_TYPE_SAR;
1133 break;
1134 case 7: // srav
1135 insn.id = MIPS_INS_SRAV;
1136 op->type = R_ANAL_OP_TYPE_SAR;
1137 break;
1138 case 59: // dsra
1139 insn.id = MIPS_INS_DSRA; //TODO double
1140 op->type = R_ANAL_OP_TYPE_SAR;
1141 break;
1142 case 63: // dsra32
1143 insn.id = MIPS_INS_DSRA32;
1144 op->type = R_ANAL_OP_TYPE_SAR;
1145 break;
1146 case 8: // jr
1147 //eprintf ("%llx jr\n", addr);
1148 // TODO: check return value or gtfo
1149 op->delay = 1;
1150 insn.id = MIPS_INS_JR;
1151 if (rs == 31) {
1152 op->type = R_ANAL_OP_TYPE_RET;
1153 } else if (rs == 25) {
1154 op->type = R_ANAL_OP_TYPE_RJMP;
1155 op->jump = t9_pre;
1156 break;
1157
1158 } else {
1159 op->type = R_ANAL_OP_TYPE_RJMP;
1160 }
1161 break;
1162 case 9: // jalr
1163 //eprintf ("%llx jalr\n", addr);
1164 op->delay = 1;
1165 insn.id = MIPS_INS_JALR;
1166 if (rs == 25){
1167 op->type = R_ANAL_OP_TYPE_RCALL;
1168 op->jump = t9_pre;
1169 break;
1170 }
1171 op->type = R_ANAL_OP_TYPE_UCALL;
1172 break;
1173 case 10: //movz
1174 insn.id = MIPS_INS_MOVZ;
1175 break;
1176 case 12: // syscall
1177 op->type = R_ANAL_OP_TYPE_SWI;
1178 break;
1179 case 13: // break
1180 op->type = R_ANAL_OP_TYPE_TRAP;
1181 break;
1182 case 16: // mfhi
1183 insn.id = MIPS_INS_MFHI;
1184 break;
1185 case 18: // mflo
1186 insn.id = MIPS_INS_MFLO;
1187 break;
1188 case 17: // mthi
1189 insn.id = MIPS_INS_MTHI;
1190 break;
1191 case 19: // mtlo
1192 insn.id = MIPS_INS_MTLO;
1193 op->type = R_ANAL_OP_TYPE_MOV;
1194 break;
1195 case 24: // mult
1196 insn.id = MIPS_INS_MULT;
1197 case 25: // multu
1198 insn.id = MIPS_INS_MULTU;
1199 op->type = R_ANAL_OP_TYPE_MUL;
1200 break;
1201 case 26: // div
1202 case 27: // divu
1203 op->type = R_ANAL_OP_TYPE_DIV;
1204 insn.id = MIPS_INS_DIV;
1205 break;
1206 case 32: // add
1207 insn.id = MIPS_INS_ADD;
1208 case 33: // addu //TODO:表明位数
1209 insn.id = MIPS_INS_ADDU;
1210 op->type = R_ANAL_OP_TYPE_ADD;
1211 break;
1212 case 44: //dadd
1213 insn.id = MIPS_INS_DADD;
1214 op->type = R_ANAL_OP_TYPE_ADD;
1215 break;
1216 case 45: //daddu move
1217 if(rt == 0) {
1218 op->type = R_ANAL_OP_TYPE_MOV;
1219 insn.id = MIPS_INS_MOV;
1220 break;
1221 }
1222 op->type = R_ANAL_OP_TYPE_ADD;
1223 insn.id = MIPS_INS_DADDU;
1224 break;
1225 case 34: // sub
1226 case 35: // subu
1227 insn.id = MIPS_INS_SUB;
1228 op->type = R_ANAL_OP_TYPE_SUB;
1229 break;
1230 case 46: //dsub
1231 insn.id = MIPS_INS_SUB;
1232 op->type = R_ANAL_OP_TYPE_SUB;
1233 break;
1234 case 47: //dsubu
1235 insn.id = MIPS_INS_SUB;
1236 op->type = R_ANAL_OP_TYPE_SUB;
1237 break;
1238 case 36: // and
1239 insn.id = MIPS_INS_AND;
1240 op->type = R_ANAL_OP_TYPE_AND;
1241 break;
1242 case 37: // or
1243 insn.id = MIPS_INS_OR;
1244 op->type = R_ANAL_OP_TYPE_OR;
1245 break;
1246 case 38: // xor
1247 insn.id = MIPS_INS_XOR;
1248 op->type = R_ANAL_OP_TYPE_XOR;
1249 break;
1250 case 39: // nor
1251 insn.id = MIPS_INS_NOR;
1252 op->type = R_ANAL_OP_TYPE_NOR;
1253 break;
1254 case 42: // slt
1255 insn.id = MIPS_INS_SLT;
1256 break;
1257 case 43: // sltu
1258 insn.id = MIPS_INS_SLTU;
1259 break;
1260 default:
1261 // eprintf ("%llx %d\n", addr, optype);
1262 break;
1263 }
1264 //family = 'R';
1265 } else
1266 if ((optype & 0x3e) == 2) {
1267 /*
1268 // J-TYPE
1269 |--[0]--| |--[1]--| |--[2]--| |--[3]--|
1270 1111 1111 1111 1111 1111 1111 1111 1111
1271 \_op__/\______address____________________/
1272 | |
1273 (buf[0]>>2) ((buf[0]&3)<<24)+(buf[1]<<16)+(buf[2]<<8)+buf[3]
1274 */
1275 // FIXME: what happens when addr is using a virtual map?
1276 // ANS: address will be E 0x000000..0x0ffffffc
1277 // but addr could be anywhere
1278 // so address needs to be adjusted for that, somehow...
1279 // MIPS is strange. For example, the same code memory may be
1280 // mapped simultaneously to 0x00600000 and 0x80600000. The program is
1281 // executing at 0x80600000 if we are operating in 'KSEG0' space
1282 // (unmapped cached mode) vs 0x00600000 (KUSEG or user space)
1283 // An immediate jump can only reach within 2^28 bits.
1284 // HACK: if the user specified a mapping for the program
1285 // then assume that they know which MIPS segment they
1286 // are analysing in, and use the high order bits of addr
1287 // to be add to the jump.
1288 // WARNING: it is possible that this may not be the case
1289 // in all situations!
1290 // Maybe better solution: use a cfg. variable to do
1291 // the offset... but I dont yet know how to get to that
1292 // from this static function
1293 int address = (((buf[0]&3)<<24)+(buf[1]<<16)+(buf[2]<<8)+buf[3]) << 2;
1294 ut64 page_hack = addr & 0xf0000000;
1295
1296 switch (optype) {
1297 case 2: // j
1298 insn.id = MIPS_INS_J;
1299 op->type = R_ANAL_OP_TYPE_JMP;
1300 op->jump = page_hack + address;
1301 op->delay = 1;
1302 snprintf ((char *)insn.j_reg.jump, REG_BUF_MAX, "0x%"PFMT64x, op->jump);
1303 break;
1304 case 3: // jal
1305 insn.id = MIPS_INS_JAL;
1306 op->type = R_ANAL_OP_TYPE_CALL;
1307 op->jump = page_hack + address;
1308 op->fail = addr + 8;
1309 op->delay = 1;
1310 snprintf ((char *)insn.j_reg.jump, REG_BUF_MAX, "0x%"PFMT64x, op->jump);
1311 break;
1312 }
1313 //family = 'J';
1314 } else if ((optype & 0x3c) == 0x10) {
1315 /*
1316 C-TYPE
1317 ======
1318 opcode (6) format (5) ft (5) fs (5) fd (5) function (6)
1319
1320 |--[0]--| |--[1]--| |--[2]--| |--[3]--|
1321 1111 1111 1111 1111 1111 1111 1111 1111
1322 \_op__/\_fmt_/\_ft_/ \_fs_/\_fd__/\_fun_/
1323 | | | | | |
1324 buf[0]>>2 | (buf[1]&31) | | buf[3]&63
1325 | (buf[2]>>3) |
1326 (buf[0]&3)<<3)+(buf[1]>>5) (buf[2]&7)+(buf[3]>>6)
1327 */
1328 #if WIP
1329 int fmt = ((buf[0]&3)<<3) + (buf[1]>>5);
1330 int ft = (buf[1]&31);
1331 int fs = (buf[2]>>3);
1332 int fd = (buf[2]&7)+(buf[3]>>6);
1333 #endif
1334 int fun = (buf[3]&63);
1335 //family = 'C';
1336 switch (fun) {
1337 case 0: // mtc1
1338 break;
1339 case 1: // sub.s
1340 break;
1341 case 2: // mul.s
1342 break;
1343 case 3: // div.s
1344 break;
1345 // ....
1346 }
1347 } else {
1348 /*
1349 I-TYPE
1350 ======
1351 all opcodes but 000000 000001x and 0100xx
1352 opcode (6) rs (5) rt (5) immediate (16)
1353
1354 |--[0]--| |--[1]--| |--[2]--| |--[3]--|
1355 1111 1111 1111 1111 1111 1111 1111 1111
1356 \_op__/\_rs__/\_rt_/ \_______imm________/
1357 | | | |
1358 buf[0]>>2 | (buf[1]&31) |
1359 | |
1360 ((buf[0]&3)<<3)+(buf[1]>>5) (buf[2]<<8)+buf[3]
1361 */
1362 op->refptr = 0;
1363 int rs = ((buf[0] & 3) << 3) + (buf[1] >> 5);
1364 int rt = buf[1] & 31;
1365 int imm = (buf[2] << 8) + buf[3];
1366 if (((optype >> 2) ^ 0x3) && (imm & 0x8000)) {
1367 imm = 0 - (0x10000 - imm);
1368 }
1369
1370 insn.i_reg.rs = mips_reg_decode (rs);
1371 insn.i_reg.rt = mips_reg_decode (rt);
1372 snprintf ((char *)insn.i_reg.imm, REG_BUF_MAX, "%"PFMT32d, imm);
1373
1374 switch (optype) {
1375 case 1:
1376 switch (rt) {
1377 case 0: //bltz
1378 insn.id = MIPS_INS_BLTZ;
1379 break;
1380 case 1: //bgez
1381 insn.id = MIPS_INS_BGEZ;
1382 break;
1383 case 17: //bal bgezal
1384 if (rs==0) {
1385 op->jump = addr+(imm<<2)+4;
1386 snprintf ((char *)insn.i_reg.jump, REG_BUF_MAX, "0x%"PFMT64x, op->jump) ;
1387 insn.id = MIPS_INS_BAL;
1388 } else {
1389 op->fail = addr+8;
1390 insn.id = MIPS_INS_BGEZAL;
1391 }
1392 op->delay = 1;
1393 op->type = R_ANAL_OP_TYPE_CALL;
1394 break;
1395 default:
1396 op->delay = 1;
1397 op->fail = addr+8;
1398 break;
1399 }
1400 break;
1401 case 4: // beq
1402 if (!insn.id) {
1403 insn.id = MIPS_INS_BEQ;
1404 if(rt == 0) {
1405 insn.id = MIPS_INS_BEQZ ;
1406 }
1407 }
1408 case 5: // bne // also bnez
1409 if (!insn.id) {
1410 insn.id = MIPS_INS_BNE;
1411 if(rt == 0) {
1412 insn.id = MIPS_INS_BNEZ;
1413 }
1414 }
1415 case 6: // blez
1416 if (!insn.id) {
1417 insn.id = MIPS_INS_BLEZ;
1418 }
1419 case 7: // bgtz
1420 // XXX: use imm here
1421 if (!insn.id) {
1422 insn.id = MIPS_INS_BGTZ;
1423 }
1424 op->type = R_ANAL_OP_TYPE_CJMP;
1425 op->jump = addr + (imm << 2) + 4;
1426 op->fail = addr + 8;
1427 op->delay = 1;
1428
1429 snprintf ((char *)insn.i_reg.jump, REG_BUF_MAX, "0x%"PFMT64x, op->jump);
1430 break;
1431 // The following idiom is very common in mips 32 bit:
1432 //
1433 // lui a0,0x8123
1434 // ; maybe other opcodes
1435 // ; maybe even a jump with branch delay
1436 // addui a0,a0,-12345
1437 //
1438 // Here, a0 might typically be any a0 or s0 register, and -12345 is a signed 16-bit number
1439 // This is used to address const or static data in a 64kb page
1440 // 0x8123 is the upper 16 bits of the register
1441 // The net result: a0 := 0x8122cfc7
1442 // The cases vary, so for now leave the smarts in a human generated macro to decide
1443 // but the macro needs the opcode values as input
1444 //
1445 // TODO: this is a stop-gap. Really we need some smarts in here to tie this into the
1446 // flags directly, as suggested here: https://github.com/radareorg/radare2/issues/949#issuecomment-43654922
1447 case 15: // lui
1448 insn.id = MIPS_INS_LUI;
1449 snprintf ((char *)insn.i_reg.imm, REG_BUF_MAX, "0x%"PFMT32x, imm);
1450 op->dst = r_anal_value_new ();
1451 op->dst->reg = r_reg_get (anal->reg, mips_reg_decode (rt), R_REG_TYPE_GPR);
1452 // TODO: currently there is no way for the macro to get access to this register
1453 op->val = imm;
1454 break;
1455 case 9: // addiu
1456 insn.id = MIPS_INS_ADDIU;
1457 op->type = R_ANAL_OP_TYPE_ADD;
1458 op->dst = r_anal_value_new ();
1459 op->dst->reg = r_reg_get (anal->reg, mips_reg_decode(rt), R_REG_TYPE_GPR);
1460 // TODO: currently there is no way for the macro to get access to this register
1461 op->src[0] = r_anal_value_new ();
1462 op->src[0]->reg = r_reg_get (anal->reg, mips_reg_decode(rs), R_REG_TYPE_GPR);
1463 op->val = imm; // Beware: this one is signed... use `?vi $v`
1464 if (rs == 0) {
1465 insn.id = MIPS_INS_LI;
1466 snprintf ((char *)insn.i_reg.imm, REG_BUF_MAX, "0x%"PFMT32x, imm);
1467 }
1468 break;
1469 case 8: // addi
1470 insn.id = MIPS_INS_ADDI;
1471 op->type = R_ANAL_OP_TYPE_ADD;
1472 break;
1473 case 10: // slti
1474 insn.id = MIPS_INS_SLTI;
1475 break;
1476 case 11: // sltiu
1477 insn.id = MIPS_INS_SLTIU;
1478 break;
1479 case 12: // andi
1480 insn.id = MIPS_INS_ANDI;
1481 op->type = R_ANAL_OP_TYPE_AND;
1482 break;
1483 case 13: // ori
1484 insn.id = MIPS_INS_ORI;
1485 op->type = R_ANAL_OP_TYPE_OR;
1486 break;
1487 case 14: // xori
1488 insn.id = MIPS_INS_XORI;
1489 op->type = R_ANAL_OP_TYPE_XOR;
1490 break;
1491 case 24: // daddi
1492 insn.id = MIPS_INS_DADDI;
1493 op->type = R_ANAL_OP_TYPE_ADD;
1494 break;
1495 case 25: // daddiu
1496 insn.id = MIPS_INS_DADDIU;
1497 op->type = R_ANAL_OP_TYPE_ADD;
1498 if (rs == 0) {
1499 insn.id = MIPS_INS_LDI;
1500 snprintf ((char *)insn.i_reg.imm, REG_BUF_MAX, "0x%"PFMT32x, imm);
1501 }
1502 break;
1503 case 32: // lb
1504 op->refptr = 1;
1505 insn.id = MIPS_INS_LB;
1506 /* fallthrough */
1507 case 33: // lh
1508 if (!op->refptr) {
1509 op->refptr = 2;
1510 insn.id = MIPS_INS_LB;
1511 }
1512 /* fallthrough */
1513 case 35: // lw
1514 if (!op->refptr) {
1515 op->refptr = 4;
1516 insn.id = MIPS_INS_LW;
1517 }
1518 /* fallthrough */
1519 case 55: // ld
1520 if (!op->refptr) {
1521 op->refptr = 8;
1522 insn.id = MIPS_INS_LD;
1523 }
1524
1525 if (rs == 28) {
1526 op->ptr = anal->gp + imm;
1527 } else {
1528 op->ptr = imm;
1529 }
1530 if (rt == 25) {
1531 t9_pre = op->ptr;
1532 }
1533 op->type = R_ANAL_OP_TYPE_LOAD;
1534 break;
1535 case 36: // lbu
1536 insn.id = MIPS_INS_LBU;
1537 op->type = R_ANAL_OP_TYPE_LOAD;
1538 break;
1539 case 37: // lhu
1540 insn.id = MIPS_INS_LHU;
1541 op->type = R_ANAL_OP_TYPE_LOAD;
1542 break;
1543 case 40: // sb
1544 insn.id = MIPS_INS_SB;
1545 op->type = R_ANAL_OP_TYPE_STORE;
1546 break;
1547 case 41: // sh
1548 insn.id = MIPS_INS_SH;
1549 op->type = R_ANAL_OP_TYPE_STORE;
1550 break;
1551 case 43: // sw
1552 insn.id = MIPS_INS_SW;
1553 op->type = R_ANAL_OP_TYPE_STORE;
1554 break;
1555 case 63: //sd
1556 insn.id = MIPS_INS_SD;
1557 op->type = R_ANAL_OP_TYPE_STORE;
1558 break;
1559 case 49: // lwc1
1560 case 57: // swc1
1561 break;
1562 case 29: // jalx
1563 insn.id = MIPS_INS_JALX;
1564 op->type = R_ANAL_OP_TYPE_CALL;
1565 op->jump = addr + 4*((buf[3] | buf[2]<<8 | buf[1]<<16));
1566 op->fail = addr + 8;
1567 op->delay = 1;
1568 snprintf ((char *)insn.i_reg.jump, REG_BUF_MAX, "0x%"PFMT64x, op->jump);
1569
1570 break;
1571 }
1572 //family = 'I';
1573 }
1574
1575 if (mask & R_ANAL_OP_MASK_ESIL) {
1576 if (analop_esil (anal, op, addr, &insn)) {
1577 r_strbuf_fini (&op->esil);
1578 }
1579 }
1580 if (mask & R_ANAL_OP_MASK_VAL) {
1581 //TODO: add op_fillval (anal, op, &insn);
1582 }
1583 return oplen;
1584 /*
1585 R - all instructions that only take registers as arguments (jalr, jr)
1586 opcode 000000
1587 opcode (6) rs (5) rt (5) rd (5) sa (5) function (6)
1588 add rd, rs, rt 100000
1589 addu rd, rs, rt 100001
1590 and rd, rs, rt 100100
1591 break 001101
1592 div rs, rt 011010
1593 divu rs, rt 011011
1594 jalr rd, rs 001001
1595 jr rs 001000
1596
1597 mfhi rd 010000
1598 mflo rd 010010
1599 mthi rs 010001
1600 mtlo rs 010011
1601 mult rs, rt 011000
1602 multu rs, rt 011001
1603
1604 nor rd, rs, rt 100111
1605 or rd, rs, rt 100101
1606 sll rd, rt, sa 000000
1607 sllv rd, rt, rs 000100
1608 slt rd, rs, rt 101010
1609 sltu rd, rs, rt 101011
1610
1611 sra rd, rt, sa 000011
1612 srav rd, rt, rs 000111
1613
1614 srl rd, rt, sa 000010
1615 srlv rd, rt, rs 000110
1616
1617 sub rd, rs, rt 100010
1618 subu rd, rs, rt 100011
1619 syscall 001100
1620 xor rd, rs, rt 100110
1621 I - instructions with immediate operand, load/store/..
1622 all opcodes but 000000 000001x and 0100xx
1623 opcode (6) rs (5) rt (5) immediate (16)
1624 addi rt, rs, immediate 001000
1625 addiu rt, rs, immediate 001001
1626 andi rt, rs, immediate 001100
1627 beq rs, rt, label 000100
1628
1629 bgez rs, label 000001 rt = 00001
1630
1631 bgtz rs, label 000111 rt = 00000
1632 blez rs, label 000110 rt = 00000
1633
1634 bltz rs, label 000001 rt = 00000
1635 bne rs, rt, label 000101
1636 lb rt, immediate(rs) 100000
1637 lbu rt, immediate(rs) 100100
1638
1639 lh rt, immediate(rs) 100001
1640 lhu rt, immediate(rs) 100101
1641
1642 lui rt, immediate 001111
1643
1644 lw rt, immediate(rs) 100011
1645 lwc1 rt, immediate(rs) 110001
1646
1647 ori rt, rs, immediate 001101
1648 sb rt, immediate(rs) 101000
1649
1650 slti rt, rs, immediate 001010
1651 sltiu rt, rs, immediate 001011
1652 sh rt, immediate(rs) 101001
1653 sw rt, immediate(rs) 101011
1654 swc1 rt, immediate(rs) 111001
1655 xori rt, rs, immediate 001110
1656 J - require memory address like j, jal
1657 00001x
1658 opcode (6) target (26)
1659 j label 000010 coded address of label
1660 jal label 000011 coded address of label
1661 C - coprocessor insutrctions that use cp0, cp1, ..
1662 0100xx
1663 opcode (6) format (5) ft (5) fs (5) fd (5) function (6)
1664 add.s fd, fs, ft 000000 10000
1665 cvt.s.w fd, fs, ft 100000 10100
1666 cvt.w.s fd, fs, ft 100100 10000
1667 div.s fd, fs, ft 000011 10000
1668 mfc1 ft, fs 000000 00000
1669 mov.s fd, fs 000110 10000
1670 mtc1 ft, fs 000000 00100
1671 mul.s fd, fs, ft 000010 10000
1672 sub.s fd, fs, ft 000001 10000
1673 */
1674 return op->size;
1675 }
1676 /* Set the profile register */
mips_set_reg_profile(RAnal * anal)1677 static bool mips_set_reg_profile(RAnal* anal){
1678 const char *p =
1679 #if 0
1680 "=PC pc\n"
1681 "=SP sp\n"
1682 "=A0 a0\n"
1683 "=A1 a1\n"
1684 "=A2 a2\n"
1685 "=A3 a3\n"
1686 "gpr zero .32 0 0\n"
1687 "gpr at .32 4 0\n"
1688 "gpr v0 .32 8 0\n"
1689 "gpr v1 .32 12 0\n"
1690 "gpr a0 .32 16 0\n"
1691 "gpr a1 .32 20 0\n"
1692 "gpr a2 .32 24 0\n"
1693 "gpr a3 .32 28 0\n"
1694 "gpr t0 .32 32 0\n"
1695 "gpr t1 .32 36 0\n"
1696 "gpr t2 .32 40 0\n"
1697 "gpr t3 .32 44 0\n"
1698 "gpr t4 .32 48 0\n"
1699 "gpr t5 .32 52 0\n"
1700 "gpr t6 .32 56 0\n"
1701 "gpr t7 .32 60 0\n"
1702 "gpr s0 .32 64 0\n"
1703 "gpr s1 .32 68 0\n"
1704 "gpr s2 .32 72 0\n"
1705 "gpr s3 .32 76 0\n"
1706 "gpr s4 .32 80 0\n"
1707 "gpr s5 .32 84 0\n"
1708 "gpr s6 .32 88 0\n"
1709 "gpr s7 .32 92 0\n"
1710 "gpr t8 .32 96 0\n"
1711 "gpr t9 .32 100 0\n"
1712 "gpr k0 .32 104 0\n"
1713 "gpr k1 .32 108 0\n"
1714 "gpr gp .32 112 0\n"
1715 "gpr sp .32 116 0\n"
1716 "gpr fp .32 120 0\n"
1717 "gpr ra .32 124 0\n"
1718 "gpr pc .32 128 0\n";
1719 #else
1720 // take the one from the debugger //
1721 "=PC pc\n"
1722 "=SP sp\n"
1723 "=BP fp\n"
1724 "=A0 a0\n"
1725 "=A1 a1\n"
1726 "=A2 a2\n"
1727 "=A3 a3\n"
1728 "gpr zero .64 0 0\n"
1729 // XXX DUPPED CAUSES FAILURE "gpr at .32 8 0\n"
1730 "gpr at .64 8 0\n"
1731 "gpr v0 .64 16 0\n"
1732 "gpr v1 .64 24 0\n"
1733 /* args */
1734 "gpr a0 .64 32 0\n"
1735 "gpr a1 .64 40 0\n"
1736 "gpr a2 .64 48 0\n"
1737 "gpr a3 .64 56 0\n"
1738 /* tmp */
1739 "gpr t0 .64 64 0\n"
1740 "gpr t1 .64 72 0\n"
1741 "gpr t2 .64 80 0\n"
1742 "gpr t3 .64 88 0\n"
1743 "gpr t4 .64 96 0\n"
1744 "gpr t5 .64 104 0\n"
1745 "gpr t6 .64 112 0\n"
1746 "gpr t7 .64 120 0\n"
1747 /* saved */
1748 "gpr s0 .64 128 0\n"
1749 "gpr s1 .64 136 0\n"
1750 "gpr s2 .64 144 0\n"
1751 "gpr s3 .64 152 0\n"
1752 "gpr s4 .64 160 0\n"
1753 "gpr s5 .64 168 0\n"
1754 "gpr s6 .64 176 0\n"
1755 "gpr s7 .64 184 0\n"
1756 "gpr t8 .64 192 0\n"
1757 "gpr t9 .64 200 0\n"
1758 /* special */
1759 "gpr k0 .64 208 0\n"
1760 "gpr k1 .64 216 0\n"
1761 "gpr gp .64 224 0\n"
1762 "gpr sp .64 232 0\n"
1763 "gpr fp .64 240 0\n"
1764 "gpr ra .64 248 0\n"
1765 /* extra */
1766 "gpr pc .64 272 0\n"
1767 ;
1768 #endif
1769 return r_reg_set_profile_string (anal->reg, p);
1770 }
1771
archinfo(RAnal * anal,int q)1772 static int archinfo(RAnal *anal, int q) {
1773 return 4;
1774 }
1775
1776 RAnalPlugin r_anal_plugin_mips_gnu = {
1777 .name = "mips.gnu",
1778 .desc = "MIPS code analysis plugin",
1779 .license = "LGPL3",
1780 .arch = "mips",
1781 .bits = 32,
1782 .esil = true,
1783 .archinfo = archinfo,
1784 .op = &mips_op,
1785 .set_reg_profile = mips_set_reg_profile,
1786 };
1787
1788 #ifndef R2_PLUGIN_INCORE
1789 R_API RLibStruct radare_plugin = {
1790 .type = R_LIB_TYPE_ANAL,
1791 .data = &r_anal_plugin_mips_gnu
1792 };
1793 #endif
1794