1 /* radare2 - LGPL - Copyright 2015-2018 - oddcoder, thestr4ng3r, courk */
2
3 #include <r_types.h>
4 #include <r_anal.h>
5 #include <r_lib.h>
6
7 #include "../../asm/arch/pic/pic_midrange.h"
8
9 typedef struct _pic_midrange_op_args_val {
10 ut16 f;
11 ut16 k;
12 ut8 d;
13 ut8 m;
14 ut8 n;
15 ut8 b;
16 } PicMidrangeOpArgsVal;
17
18 typedef void (*pic_midrange_inst_handler_t) (RAnal *anal, RAnalOp *op,
19 ut64 addr,
20 PicMidrangeOpArgsVal *args);
21
22 typedef struct _pic_midrange_op_anal_info {
23 PicMidrangeOpcode opcode;
24 PicMidrangeOpArgs args;
25 pic_midrange_inst_handler_t handler;
26 } PicMidrangeOpAnalInfo;
27
28 #define INST_HANDLER(OPCODE_NAME) \
29 static void _inst__##OPCODE_NAME (RAnal *anal, RAnalOp *op, \
30 ut64 addr, \
31 PicMidrangeOpArgsVal *args)
32 #define INST_DECL(NAME, ARGS) \
33 { \
34 PIC_MIDRANGE_OPCODE_##NAME, PIC_MIDRANGE_OP_ARGS_##ARGS, \
35 _inst__##NAME \
36 }
37
38 #define e(frag) r_strbuf_append (&op->esil, frag)
39 #define ef(frag, ...) r_strbuf_appendf (&op->esil, frag, __VA_ARGS__)
40
41 #define PIC_MIDRANGE_ESIL_SRAM_START (1 << 16)
42 #define PIC_MIDRANGE_ESIL_CSTACK_TOP ((1 << 16) + (1 << 12))
43
44 #define PIC_MIDRANGE_ESIL_BSR_ADDR "bsr,0x80,*,0x%x,+,_sram,+"
45
46 #define PIC_MIDRANGE_ESIL_OPTION_ADDR "0x95,_sram,+"
47
48 #define PIC_MIDRANGE_ESIL_UPDATE_FLAGS \
49 "$z,z,:=," \
50 "7,$c,c,:=," \
51 "4,$c,dc,:=,"
52
53 #define PIC_MIDRANGE_ESIL_LW_OP(O) \
54 "0x%x,wreg," #O "=," PIC_MIDRANGE_ESIL_UPDATE_FLAGS
55
56 #define PIC_MIDRANGE_ESIL_FWF_OP(O) \
57 "wreg," PIC_MIDRANGE_ESIL_BSR_ADDR "," #O \
58 "=[1]," PIC_MIDRANGE_ESIL_UPDATE_FLAGS
59
60 #define PIC_MIDRANGE_ESIL_WWF_OP(O) \
61 PIC_MIDRANGE_ESIL_BSR_ADDR \
62 ",[1]," \
63 "wreg," #O "=," PIC_MIDRANGE_ESIL_UPDATE_FLAGS
64
65 #define PIC_MIDRANGE_ESIL_FWF_OP_C(O) \
66 "c,wreg," \
67 "+," PIC_MIDRANGE_ESIL_BSR_ADDR "," #O \
68 "=[1]," PIC_MIDRANGE_ESIL_UPDATE_FLAGS
69
70 #define PIC_MIDRANGE_ESIL_WWF_OP_C(O) \
71 "c," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1]," #O "," \
72 "wreg," #O "=," PIC_MIDRANGE_ESIL_UPDATE_FLAGS
73
INST_HANDLER(NOP)74 INST_HANDLER (NOP) {}
75
INST_HANDLER(RETFIE)76 INST_HANDLER (RETFIE) {
77 op->type = R_ANAL_OP_TYPE_RET;
78 }
79
INST_HANDLER(OPTION)80 INST_HANDLER (OPTION) {
81 op->type = R_ANAL_OP_TYPE_STORE;
82 }
83
INST_HANDLER(TRIS)84 INST_HANDLER (TRIS) {
85 op->type = R_ANAL_OP_TYPE_STORE;
86 }
87
INST_HANDLER(RETURN)88 INST_HANDLER (RETURN) {
89 op->type = R_ANAL_OP_TYPE_RET;
90 e ("0x1f,stkptr,==,$z,?{,BREAK,},");
91 e ("_stack,stkptr,2,*,+,[2],2,*,pc,=,");
92 e ("0x01,stkptr,-=,");
93 e ("0xff,stkptr,==,$z,?{,0x1f,stkptr,=,},");
94 }
95
INST_HANDLER(CALL)96 INST_HANDLER (CALL) {
97 ut64 pclath;
98 op->type = R_ANAL_OP_TYPE_CALL;
99 r_anal_esil_reg_read (anal->esil, "pclath", &pclath, NULL);
100 op->jump = 2 * (((pclath & 0x78) << 8) + args->k);
101 ef ("8,pclath,0x78,&,<<,0x%x,+,2,*,pc,=,", args->k);
102 e ("0x1f,stkptr,==,$z,?{,0xff,stkptr,=,},");
103 e ("0x0f,stkptr,==,$z,?{,0xff,stkptr,=,},");
104 e ("0x01,stkptr,+=,");
105 ef ("0x%" PFMT64x ",_stack,stkptr,2,*,+,=[2],", (addr + 2) / 2);
106 }
107
INST_HANDLER(GOTO)108 INST_HANDLER (GOTO) {
109 ut64 pclath;
110 op->type = R_ANAL_OP_TYPE_JMP;
111 r_anal_esil_reg_read (anal->esil, "pclath", &pclath, NULL);
112 op->jump = 2 * (((pclath & 0x78) << 8) + args->k);
113 ef ("8,pclath,0x78,&,<<,0x%x,+,2,*,pc,=,", args->k);
114 }
115
INST_HANDLER(BCF)116 INST_HANDLER (BCF) {
117 ut8 mask = ~(1 << args->b);
118 ef (PIC_MIDRANGE_ESIL_BSR_ADDR
119 ",[1],0x%x,&," PIC_MIDRANGE_ESIL_BSR_ADDR ",=[1],",
120 args->f, mask, args->f);
121 }
122
INST_HANDLER(BSF)123 INST_HANDLER (BSF) {
124 ut8 mask = (1 << args->b);
125 ef (PIC_MIDRANGE_ESIL_BSR_ADDR
126 ",[1],0x%x,|," PIC_MIDRANGE_ESIL_BSR_ADDR ",=[1],",
127 args->f, mask, args->f);
128 }
129
INST_HANDLER(BTFSC)130 INST_HANDLER (BTFSC) {
131 ut8 mask = (1 << args->b);
132 op->type = R_ANAL_OP_TYPE_CJMP;
133 op->jump = addr + 4;
134 op->fail = addr + 2;
135 ef (PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],0x%x,&,!,?{,0x%" PFMT64x ",pc,=,},",
136 args->f, mask, op->jump);
137 }
138
INST_HANDLER(BTFSS)139 INST_HANDLER (BTFSS) {
140 ut8 mask = (1 << args->b);
141 op->type = R_ANAL_OP_TYPE_CJMP;
142 op->jump = addr + 4;
143 op->fail = addr + 2;
144 ef (PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],0x%x,&,?{,0x%" PFMT64x ",pc,=,},", args->f,
145 mask, op->jump);
146 }
147
INST_HANDLER(BRA)148 INST_HANDLER (BRA) {
149 st16 branch = args->k;
150 op->type = R_ANAL_OP_TYPE_JMP;
151 branch |= ((branch & 0x100) ? 0xfe00 : 0);
152 op->jump = addr + 2 * (branch + 1);
153 ef ("%s0x%x,1,+,2,*,pc,+=,", branch < 0 ? "-" : "",
154 branch < 0 ? -branch : branch);
155 }
156
INST_HANDLER(BRW)157 INST_HANDLER (BRW) {
158 ut64 wreg;
159 op->type = R_ANAL_OP_TYPE_UJMP;
160 r_anal_esil_reg_read (anal->esil, "wreg", &wreg, NULL);
161 op->jump = addr + 2 * (wreg + 1);
162 e ("wreg,1,+,2,*,pc,+=,");
163 }
164
INST_HANDLER(CLR)165 INST_HANDLER (CLR) {
166 if (args->d) {
167 ef ("0x00," PIC_MIDRANGE_ESIL_BSR_ADDR ",=[1],", args->f);
168 } else {
169 e ("0x00,wreg,=,");
170 }
171 e ("1,z,=,");
172 }
173
INST_HANDLER(SUBWF)174 INST_HANDLER (SUBWF) {
175 op->type = R_ANAL_OP_TYPE_SUB;
176 if (args->d) {
177 ef (PIC_MIDRANGE_ESIL_FWF_OP (-), args->f);
178 } else {
179 ef (PIC_MIDRANGE_ESIL_WWF_OP (-), args->f);
180 e ("wreg,0x00,-,wreg,=,c,!=,dc,!=,");
181 }
182 }
183
INST_HANDLER(DECFSZ)184 INST_HANDLER (DECFSZ) {
185 op->type = R_ANAL_OP_TYPE_CJMP;
186 op->jump = addr + 4;
187 op->fail = addr + 2;
188 if (args->d) {
189 ef ("0x01," PIC_MIDRANGE_ESIL_BSR_ADDR ",-=[1],", args->f);
190 } else {
191 ef ("0x01," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],-,wreg,=,",
192 args->f);
193 }
194 ef (PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],!,?{,0x%" PFMT64x ",pc,=,},", args->f,
195 op->jump);
196 }
197
INST_HANDLER(INCFSZ)198 INST_HANDLER (INCFSZ) {
199 op->type = R_ANAL_OP_TYPE_CJMP;
200 op->jump = addr + 4;
201 op->fail = addr + 2;
202 if (args->d) {
203 ef ("0x01," PIC_MIDRANGE_ESIL_BSR_ADDR ",+=[1],", args->f);
204 } else {
205 ef ("0x01," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],+,wreg,=,",
206 args->f);
207 }
208 ef (PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],!,?{,0x%" PFMT64x ",pc,=,},", args->f,
209 op->jump);
210 }
211
INST_HANDLER(INCF)212 INST_HANDLER (INCF) {
213 op->type = R_ANAL_OP_TYPE_ADD;
214 if (args->d) {
215 ef ("0x01," PIC_MIDRANGE_ESIL_BSR_ADDR ",+=[1],", args->f);
216 } else {
217 ef ("0x01," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],+,wreg,=,",
218 args->f);
219 }
220 e ("$z,z,:=,");
221 }
222
INST_HANDLER(DECF)223 INST_HANDLER (DECF) {
224 op->type = R_ANAL_OP_TYPE_SUB;
225 if (args->d) {
226 ef ("0x01," PIC_MIDRANGE_ESIL_BSR_ADDR ",-=[1],", args->f);
227 } else {
228 ef ("0x01," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],-,wreg,=,",
229 args->f);
230 }
231 e ("$z,z,:=,");
232 }
233
INST_HANDLER(IORWF)234 INST_HANDLER (IORWF) {
235 op->type = R_ANAL_OP_TYPE_OR;
236 if (args->d) {
237 ef (PIC_MIDRANGE_ESIL_FWF_OP (|), args->f);
238 } else {
239 ef (PIC_MIDRANGE_ESIL_WWF_OP (|), args->f);
240 }
241 }
242
INST_HANDLER(ANDWF)243 INST_HANDLER (ANDWF) {
244 op->type = R_ANAL_OP_TYPE_AND;
245 if (args->d) {
246 ef (PIC_MIDRANGE_ESIL_FWF_OP (&), args->f);
247 } else {
248 ef (PIC_MIDRANGE_ESIL_WWF_OP (&), args->f);
249 }
250 }
251
INST_HANDLER(XORWF)252 INST_HANDLER (XORWF) {
253 op->type = R_ANAL_OP_TYPE_XOR;
254 if (args->d) {
255 ef (PIC_MIDRANGE_ESIL_FWF_OP (^), args->f);
256 } else {
257 ef (PIC_MIDRANGE_ESIL_WWF_OP (^), args->f);
258 }
259 }
260
INST_HANDLER(ADDWF)261 INST_HANDLER (ADDWF) {
262 op->type = R_ANAL_OP_TYPE_ADD;
263 if (args->d) {
264 ef (PIC_MIDRANGE_ESIL_FWF_OP (+), args->f);
265 } else {
266 ef (PIC_MIDRANGE_ESIL_WWF_OP (+), args->f);
267 }
268 }
269
INST_HANDLER(SUBLW)270 INST_HANDLER (SUBLW) {
271 op->type = R_ANAL_OP_TYPE_SUB;
272 ef (PIC_MIDRANGE_ESIL_LW_OP (-), args->k);
273 }
274
INST_HANDLER(ADDLW)275 INST_HANDLER (ADDLW) {
276 op->type = R_ANAL_OP_TYPE_ADD;
277 ef (PIC_MIDRANGE_ESIL_LW_OP (+), args->k);
278 }
279
INST_HANDLER(IORLW)280 INST_HANDLER (IORLW) {
281 op->type = R_ANAL_OP_TYPE_OR;
282 ef (PIC_MIDRANGE_ESIL_LW_OP (|), args->k);
283 }
284
INST_HANDLER(ANDLW)285 INST_HANDLER (ANDLW) {
286 op->type = R_ANAL_OP_TYPE_AND;
287 ef (PIC_MIDRANGE_ESIL_LW_OP (&), args->k);
288 }
289
INST_HANDLER(XORLW)290 INST_HANDLER (XORLW) {
291 op->type = R_ANAL_OP_TYPE_XOR;
292 ef (PIC_MIDRANGE_ESIL_LW_OP (^), args->k);
293 }
294
INST_HANDLER(MOVLW)295 INST_HANDLER (MOVLW) {
296 op->type = R_ANAL_OP_TYPE_LOAD;
297 ef ("0x%x,wreg,=,", args->k);
298 }
299
INST_HANDLER(RETLW)300 INST_HANDLER (RETLW) {
301 op->type = R_ANAL_OP_TYPE_RET;
302 ef ("0x%x,wreg,=,", args->k);
303 e ("0x1f,stkptr,==,$z,?{,BREAK,},");
304 e ("_stack,stkptr,2,*,+,[2],2,*,pc,=,");
305 e ("0x01,stkptr,-=,");
306 e ("0xff,stkptr,==,$z,?{,0x1f,stkptr,=,},");
307 }
308
INST_HANDLER(MOVLP)309 INST_HANDLER (MOVLP) {
310 op->type = R_ANAL_OP_TYPE_LOAD;
311 ef ("0x%x,pclath,=,", args->f);
312 }
313
INST_HANDLER(MOVLB)314 INST_HANDLER (MOVLB) {
315 op->type = R_ANAL_OP_TYPE_LOAD;
316 ef ("0x%x,bsr,=,", args->k);
317 }
318
INST_HANDLER(CALLW)319 INST_HANDLER (CALLW) {
320 op->type = R_ANAL_OP_TYPE_UCALL;
321 e ("8,pclath,<<,0x%x,+,wreg,2,*,pc,=,");
322 e ("0x1f,stkptr,==,$z,?{,0xff,stkptr,=,},");
323 e ("0x0f,stkptr,==,$z,?{,0xff,stkptr,=,},");
324 e ("0x01,stkptr,+=,");
325 ef ("0x%" PFMT64x ",_stack,stkptr,2,*,+,=[2],", (addr + 2) / 2);
326 }
327
INST_HANDLER(MOVWF)328 INST_HANDLER (MOVWF) {
329 op->type = R_ANAL_OP_TYPE_STORE;
330 ef ("wreg," PIC_MIDRANGE_ESIL_BSR_ADDR ",=[1],", args->f);
331 }
332
INST_HANDLER(MOVF)333 INST_HANDLER (MOVF) {
334 op->type = R_ANAL_OP_TYPE_LOAD;
335 if (args->d) {
336 ef (PIC_MIDRANGE_ESIL_BSR_ADDR
337 ",[1]," PIC_MIDRANGE_ESIL_BSR_ADDR ",=[1],",
338 args->f, args->f);
339 } else {
340 ef (PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],wreg,=,", args->f);
341 }
342 e ("$z,z,:=,");
343 }
344
INST_HANDLER(SWAPF)345 INST_HANDLER (SWAPF) {
346 ef ("4," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],>>,0x0f,&,", args->f);
347 ef ("4," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],<<,0xf0,&,", args->f);
348 e ("|,");
349 ef (PIC_MIDRANGE_ESIL_BSR_ADDR ",=[1],", args->f);
350 }
351
INST_HANDLER(LSLF)352 INST_HANDLER (LSLF) {
353 op->type = R_ANAL_OP_TYPE_SHL;
354 ef ("7," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],>>,c,=,", args->f);
355 if (args->d) {
356 ef ("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",<<=[1],", args->f);
357 } else {
358 ef ("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],<<,wreg,=,",
359 args->f);
360 }
361 e ("$z,z,:=,");
362 }
363
INST_HANDLER(LSRF)364 INST_HANDLER (LSRF) {
365 op->type = R_ANAL_OP_TYPE_SHR;
366 ef ("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],&,c,=,", args->f);
367 if (args->d) {
368 ef ("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",>>=[1],", args->f);
369 } else {
370 ef ("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],>>,wreg,=,",
371 args->f);
372 }
373 e ("$z,z,:=,");
374 }
375
INST_HANDLER(ASRF)376 INST_HANDLER (ASRF) {
377 op->type = R_ANAL_OP_TYPE_SHR;
378 ef ("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],&,c,=,", args->f);
379 ef ("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],>>,", args->f);
380 ef ("0x80," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],&,", args->f);
381 if (args->d) {
382 ef ("|," PIC_MIDRANGE_ESIL_BSR_ADDR ",=[1],", args->f);
383 } else {
384 e ("|,wreg,=,");
385 }
386 e ("$z,z,:=,");
387 }
388
INST_HANDLER(RRF)389 INST_HANDLER (RRF) {
390 op->type = R_ANAL_OP_TYPE_ROR;
391 ef ("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],&,", args->f);
392 if (args->d) {
393 ef ("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",>>=[1],"
394 "c," PIC_MIDRANGE_ESIL_BSR_ADDR ",|=[1],",
395 args->f, args->f);
396 } else {
397 ef ("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],>>,wreg,=,"
398 "c,wreg,|=[1],",
399 args->f);
400 }
401 e ("c,=,");
402 }
403
INST_HANDLER(RLF)404 INST_HANDLER (RLF) {
405 op->type = R_ANAL_OP_TYPE_ROL;
406 ef ("7," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],>>,", args->f);
407 if (args->d) {
408 ef ("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",<<=[1],"
409 "c," PIC_MIDRANGE_ESIL_BSR_ADDR ",|=[1],",
410 args->f, args->f);
411 } else {
412 ef ("1," PIC_MIDRANGE_ESIL_BSR_ADDR ",[1],<<,wreg,=,"
413 "c,wreg,|=[1],",
414 args->f);
415 }
416 e ("c,=,");
417 }
418
INST_HANDLER(COMF)419 INST_HANDLER (COMF) {
420 if (args->d) {
421 ef ("0xff," PIC_MIDRANGE_ESIL_BSR_ADDR ",^=[1],", args->f);
422 } else {
423 ef ("0xff," PIC_MIDRANGE_ESIL_BSR_ADDR ",^,wreg,=,", args->f);
424 }
425 e ("$z,z,:=,");
426 }
427
INST_HANDLER(RESET)428 INST_HANDLER (RESET) {
429 op->type = R_ANAL_OP_TYPE_JMP;
430 op->jump = 0;
431 e ("0x0,pc,=,");
432 e ("0x1f,stkptr,=,");
433 }
434
INST_HANDLER(ADDFSR)435 INST_HANDLER (ADDFSR) {
436 op->type = R_ANAL_OP_TYPE_ADD;
437 if (args->n == 0) {
438 ef ("0x%x,fsr0l,+=,", args->k);
439 e ("7,$c,?{,0x01,fsr0h,+=,},");
440 } else {
441 ef ("0x%x,fsr1l,+=,", args->k);
442 e ("7,$c,?{,0x01,fsr1h,+=,},");
443 }
444 }
445
INST_HANDLER(CLRWDT)446 INST_HANDLER (CLRWDT) {
447 e ("1,to,=,");
448 e ("1,pd,=,");
449 }
450
INST_HANDLER(SLEEP)451 INST_HANDLER (SLEEP) {
452 e ("1,to,=,");
453 e ("0,pd,=,");
454 }
455
INST_HANDLER(SUBWFB)456 INST_HANDLER (SUBWFB) {
457 op->type = R_ANAL_OP_TYPE_SUB;
458 e ("c,!=,");
459 if (args->d) {
460 ef (PIC_MIDRANGE_ESIL_FWF_OP_C (-), args->f);
461 } else {
462 ef (PIC_MIDRANGE_ESIL_WWF_OP_C (-), args->f);
463 e ("wreg,0x00,-,wreg,=,c,!=,dc,!=,");
464 }
465 }
466
INST_HANDLER(ADDWFC)467 INST_HANDLER (ADDWFC) {
468 op->type = R_ANAL_OP_TYPE_ADD;
469 if (args->d) {
470 ef (PIC_MIDRANGE_ESIL_FWF_OP_C (+), args->f);
471 } else {
472 ef (PIC_MIDRANGE_ESIL_WWF_OP_C (+), args->f);
473 }
474 }
475
INST_HANDLER(MOVIW_1)476 INST_HANDLER (MOVIW_1) {
477 if (args->n == 0) {
478 if (!(args->m & 2)) {
479 ef ("1,fsr0l,%s=,", (args->m & 1) ? "-" : "+");
480 ef ("7,$c%s,fsr0h,%s,", (args->m & 1) ? ",!" : "",
481 (args->m & 1) ? "-" : "+");
482 }
483 e ("indf0,wreg,=,");
484 e ("$z,z,:=,");
485 if (args->m & 2) {
486 ef ("1,fsr0l,%s=,", (args->m & 1) ? "-" : "+");
487 ef ("7,$c%s,fsr0h,%s,", (args->m & 1) ? ",!" : "",
488 (args->m & 1) ? "-" : "+");
489 }
490 } else {
491 if (!(args->m & 2)) {
492 ef ("1,fsr1l,%s=,", (args->m & 1) ? "-" : "+");
493 ef ("7,$c%s,fsr1h,%s,", (args->m & 1) ? ",!" : "",
494 (args->m & 1) ? "-" : "+");
495 }
496 e ("indf1,wreg,=,");
497 e ("$z,z,:=,");
498 if (args->m & 2) {
499 ef ("1,fsr1l,%s=,", (args->m & 1) ? "-" : "+");
500 ef ("7,$c%s,fsr1h,%s,", (args->m & 1) ? ",!" : "",
501 (args->m & 1) ? "-" : "+");
502 }
503 }
504 }
505
INST_HANDLER(MOVWI_1)506 INST_HANDLER (MOVWI_1) {
507 if (args->n == 0) {
508 if (!(args->m & 2)) {
509 ef ("1,fsr0l,%s=,", (args->m & 1) ? "-" : "+");
510 ef ("$c7%s,fsr0h,%s,", (args->m & 1) ? ",!" : "",
511 (args->m & 1) ? "-" : "+");
512 }
513 e ("wreg,indf0=,");
514 e ("$z,z,:=,");
515 if (args->m & 2) {
516 ef ("1,fsr0l,%s=,", (args->m & 1) ? "-" : "+");
517 ef ("$c7%s,fsr0h,%s,", (args->m & 1) ? ",!" : "",
518 (args->m & 1) ? "-" : "+");
519 }
520 } else {
521 if (!(args->m & 2)) {
522 ef ("1,fsr1l,%s=,", (args->m & 1) ? "-" : "+");
523 ef ("$c7,fsr1h,%s,", (args->m & 1) ? ",!" : "");
524 }
525 e ("wreg,indf1=,");
526 e ("$z,z,:=,");
527 if (args->m & 2) {
528 ef ("1,fsr1l,%s=,", (args->m & 1) ? "-" : "+");
529 ef ("$c7%s,fsr1h,%s,", (args->m & 1) ? ",!" : "",
530 (args->m & 1) ? "-" : "+");
531 }
532 }
533 }
534
INST_HANDLER(MOVIW_2)535 INST_HANDLER (MOVIW_2) {
536 if (args->n == 0) {
537 e ("fsr0l,8,fsr0h,<<,+,");
538 } else {
539 e ("fsr1l,8,fsr1h,<<,+,");
540 }
541 ef ("0x%x,+,[1],wreg,=,", args->k);
542 }
543
INST_HANDLER(MOVWI_2)544 INST_HANDLER (MOVWI_2) {
545 e ("wreg,");
546 if (args->n == 0) {
547 e ("fsr0l,8,fsr0h,<<,+,");
548 } else {
549 e ("fsr1l,8,fsr1h,<<,+,");
550 }
551 e ("=[1],");
552 }
553
554 #define PIC_MIDRANGE_OPINFO_LEN 52
555 static const PicMidrangeOpAnalInfo pic_midrange_op_anal_info[PIC_MIDRANGE_OPINFO_LEN] = {
556 INST_DECL (NOP, NONE), INST_DECL (RETURN, NONE),
557 INST_DECL (RETFIE, NONE), INST_DECL (OPTION, NONE),
558 INST_DECL (SLEEP, NONE), INST_DECL (CLRWDT, NONE),
559 INST_DECL (TRIS, 2F), INST_DECL (MOVWF, 7F),
560 INST_DECL (CLR, 1D_7F), INST_DECL (SUBWF, 1D_7F),
561 INST_DECL (DECF, 1D_7F), INST_DECL (IORWF, 1D_7F),
562 INST_DECL (ANDWF, 1D_7F), INST_DECL (XORWF, 1D_7F),
563 INST_DECL (ADDWF, 1D_7F), INST_DECL (MOVF, 1D_7F),
564 INST_DECL (COMF, 1D_7F), INST_DECL (INCF, 1D_7F),
565 INST_DECL (DECFSZ, 1D_7F), INST_DECL (RRF, 1D_7F),
566 INST_DECL (RLF, 1D_7F), INST_DECL (SWAPF, 1D_7F),
567 INST_DECL (INCFSZ, 1D_7F), INST_DECL (BCF, 3B_7F),
568 INST_DECL (BSF, 3B_7F), INST_DECL (BTFSC, 3B_7F),
569 INST_DECL (BTFSS, 3B_7F), INST_DECL (CALL, 11K),
570 INST_DECL (GOTO, 11K), INST_DECL (MOVLW, 8K),
571 INST_DECL (RETLW, 8K), INST_DECL (IORLW, 8K),
572 INST_DECL (ANDLW, 8K), INST_DECL (XORLW, 8K),
573 INST_DECL (SUBLW, 8K), INST_DECL (ADDLW, 8K),
574 INST_DECL (RESET, NONE), INST_DECL (CALLW, NONE),
575 INST_DECL (BRW, NONE), INST_DECL (MOVIW_1, 1N_2M),
576 INST_DECL (MOVWI_1, 1N_2M), INST_DECL (MOVLB, 4K),
577 INST_DECL (LSLF, 1D_7F), INST_DECL (LSRF, 1D_7F),
578 INST_DECL (ASRF, 1D_7F), INST_DECL (SUBWFB, 1D_7F),
579 INST_DECL (ADDWFC, 1D_7F), INST_DECL (ADDFSR, 1N_6K),
580 INST_DECL (MOVLP, 7F), INST_DECL (BRA, 9K),
581 INST_DECL (MOVIW_2, 1N_6K), INST_DECL (MOVWI_2, 1N_6K)
582 };
583
anal_pic_midrange_extract_args(ut16 instr,PicMidrangeOpArgs args,PicMidrangeOpArgsVal * args_val)584 static void anal_pic_midrange_extract_args (ut16 instr,
585 PicMidrangeOpArgs args,
586 PicMidrangeOpArgsVal *args_val) {
587
588 memset (args_val, 0, sizeof (PicMidrangeOpArgsVal));
589
590 switch (args) {
591 case PIC_MIDRANGE_OP_ARGS_NONE: return;
592 case PIC_MIDRANGE_OP_ARGS_2F:
593 args_val->f = instr & PIC_MIDRANGE_OP_ARGS_2F_MASK_F;
594 return;
595 case PIC_MIDRANGE_OP_ARGS_7F:
596 args_val->f = instr & PIC_MIDRANGE_OP_ARGS_7F_MASK_F;
597 return;
598 case PIC_MIDRANGE_OP_ARGS_1D_7F:
599 args_val->f = instr & PIC_MIDRANGE_OP_ARGS_1D_7F_MASK_F;
600 args_val->d =
601 (instr & PIC_MIDRANGE_OP_ARGS_1D_7F_MASK_D) >> 7;
602 return;
603 case PIC_MIDRANGE_OP_ARGS_1N_6K:
604 args_val->n =
605 (instr & PIC_MIDRANGE_OP_ARGS_1N_6K_MASK_N) >> 6;
606 args_val->k = instr & PIC_MIDRANGE_OP_ARGS_1N_6K_MASK_K;
607 return;
608 case PIC_MIDRANGE_OP_ARGS_3B_7F:
609 args_val->b =
610 (instr & PIC_MIDRANGE_OP_ARGS_3B_7F_MASK_B) >> 7;
611 args_val->f = instr & PIC_MIDRANGE_OP_ARGS_3B_7F_MASK_F;
612 return;
613 case PIC_MIDRANGE_OP_ARGS_4K:
614 args_val->k = instr & PIC_MIDRANGE_OP_ARGS_4K_MASK_K;
615 return;
616 case PIC_MIDRANGE_OP_ARGS_8K:
617 args_val->k = instr & PIC_MIDRANGE_OP_ARGS_8K_MASK_K;
618 return;
619 case PIC_MIDRANGE_OP_ARGS_9K:
620 args_val->k = instr & PIC_MIDRANGE_OP_ARGS_9K_MASK_K;
621 return;
622 case PIC_MIDRANGE_OP_ARGS_11K:
623 args_val->k = instr & PIC_MIDRANGE_OP_ARGS_11K_MASK_K;
624 return;
625 case PIC_MIDRANGE_OP_ARGS_1N_2M:
626 args_val->n =
627 (instr & PIC_MIDRANGE_OP_ARGS_1N_2M_MASK_N) >> 2;
628 args_val->m = instr & PIC_MIDRANGE_OP_ARGS_1N_2M_MASK_M;
629 return;
630 }
631 }
632
633 static RIODesc *mem_sram = 0;
634 static RIODesc *mem_stack = 0;
635
cpu_memory_map(RIOBind * iob,RIODesc * desc,ut32 addr,ut32 size)636 static RIODesc *cpu_memory_map (RIOBind *iob, RIODesc *desc, ut32 addr,
637 ut32 size) {
638 char *mstr = r_str_newf ("malloc://%d", size);
639 if (desc && iob->fd_get_name (iob->io, desc->fd)) {
640 iob->fd_remap (iob->io, desc->fd, addr);
641 } else {
642 desc = iob->open_at (iob->io, mstr, R_PERM_RW, 0, addr);
643 }
644 free (mstr);
645 return desc;
646 }
647
pic_midrange_reg_write(RReg * reg,const char * regname,ut32 num)648 static bool pic_midrange_reg_write (RReg *reg, const char *regname, ut32 num) {
649 if (reg) {
650 RRegItem *item = r_reg_get (reg, regname, R_REG_TYPE_GPR);
651 if (item) {
652 r_reg_set_value (reg, item, num);
653 return true;
654 }
655 }
656 return false;
657 }
658
anal_pic_midrange_malloc(RAnal * anal,bool force)659 static void anal_pic_midrange_malloc (RAnal *anal, bool force) {
660 static bool init_done = false;
661
662 if (!init_done || force) {
663 // Allocate memory as needed.
664 // We assume that code is already allocated with firmware
665 // image
666 mem_sram =
667 cpu_memory_map (&anal->iob, mem_sram,
668 PIC_MIDRANGE_ESIL_SRAM_START, 0x1000);
669 mem_stack =
670 cpu_memory_map (&anal->iob, mem_stack,
671 PIC_MIDRANGE_ESIL_CSTACK_TOP, 0x20);
672
673 pic_midrange_reg_write (anal->reg, "_sram",
674 PIC_MIDRANGE_ESIL_SRAM_START);
675 pic_midrange_reg_write (anal->reg, "_stack",
676 PIC_MIDRANGE_ESIL_CSTACK_TOP);
677 pic_midrange_reg_write (anal->reg, "stkptr", 0x1f);
678
679 init_done = true;
680 }
681 }
682
anal_pic_midrange_op(RAnal * anal,RAnalOp * op,ut64 addr,const ut8 * buf,int len)683 static int anal_pic_midrange_op (RAnal *anal, RAnalOp *op, ut64 addr,
684 const ut8 *buf, int len) {
685
686 ut16 instr;
687 int i;
688
689 anal_pic_midrange_malloc (anal, false);
690
691 if (!buf || len < 2) {
692 op->type = R_ANAL_OP_TYPE_ILL;
693 return op->size;
694 }
695
696 instr = r_read_le16 (buf);
697
698 // Default op params
699 op->size = 2;
700 op->cycles = 1;
701 op->type = R_ANAL_OP_TYPE_NOP;
702
703 PicMidrangeOpcode opcode = pic_midrange_get_opcode (instr);
704 PicMidrangeOpArgsVal args_val;
705
706 for (i = 0; i < PIC_MIDRANGE_OPINFO_LEN; i++) {
707 if (pic_midrange_op_anal_info[i].opcode == opcode) {
708 anal_pic_midrange_extract_args (
709 instr, pic_midrange_op_anal_info[i].args,
710 &args_val);
711 pic_midrange_op_anal_info[i].handler (anal, op, addr,
712 &args_val);
713 break;
714 }
715 }
716
717 return op->size;
718 }
719
pic18_cond_branch(RAnalOp * op,ut64 addr,const ut8 * buf,char * flag)720 static void pic18_cond_branch (RAnalOp *op, ut64 addr, const ut8 *buf, char *flag) {
721 op->type = R_ANAL_OP_TYPE_CJMP;
722 op->jump = addr + 2 + 2 * (*(ut16 *)buf & 0xff);
723 op->fail = addr + op->size;
724 op->cycles = 2;
725 r_strbuf_setf (&op->esil, "%s,?,{,0x%" PFMT64x ",pc,=,}", flag, op->jump);
726 }
727
anal_pic_pic18_op(RAnal * anal,RAnalOp * op,ut64 addr,const ut8 * buf,int len)728 static int anal_pic_pic18_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
729 //TODO code should be refactored and broken into smaller chunks!!
730 //TODO complete the esil emitter
731 if (len < 2) {
732 op->size = len;
733 goto beach; //pancake style :P
734 }
735 op->size = 2;
736 ut16 b = *(ut16 *)buf;
737 ut32 dword_instr = 0;
738 memcpy (&dword_instr, buf, R_MIN (sizeof (dword_instr), len));
739 switch (b >> 9) {
740 case 0x76: //call
741 if (len < 4) {
742 goto beach;
743 }
744 if (dword_instr >> 28 != 0xf) {
745 goto beach;
746 }
747 op->size = 4;
748 op->type = R_ANAL_OP_TYPE_CALL;
749 return op->size;
750 };
751 switch (b >> 11) { //NEX_T
752 case 0x1b: //rcall
753 op->type = R_ANAL_OP_TYPE_CALL;
754 return op->size;
755 case 0x1a: //bra
756 op->type = R_ANAL_OP_TYPE_JMP;
757 op->cycles = 2;
758 op->jump = addr + 2 + 2 * (*(ut16 *)buf & 0x7ff);
759 r_strbuf_setf (&op->esil, "0x%" PFMT64x ",pc,=", op->jump);
760 return op->size;
761 }
762 switch (b >> 12) { //NOP,movff,BAF_T
763 case 0xf: //nop
764 op->type = R_ANAL_OP_TYPE_NOP;
765 op->cycles = 1;
766 r_strbuf_setf (&op->esil, ",");
767 return op->size;
768 case 0xc: //movff
769 if (len < 4) {
770 goto beach;
771 }
772 if (dword_instr >> 28 != 0xf) {
773 goto beach;
774 }
775 op->size = 4;
776 op->type = R_ANAL_OP_TYPE_MOV;
777 return op->size;
778 case 0xb: //btfsc
779 case 0xa: //btfss
780 op->type = R_ANAL_OP_TYPE_CJMP;
781 return op->size;
782 case 0x9: //bcf
783 case 0x8: //bsf
784 case 0x7: //btg
785 op->type = R_ANAL_OP_TYPE_UNK;
786 return op->size;
787 };
788
789 switch (b >> 8) { //GOTO_T,N_T,K_T
790 case 0xe0: //bz
791 pic18_cond_branch (op, addr, buf, "z");
792 return op->size;
793 case 0xe1: //bnz
794 pic18_cond_branch (op, addr, buf, "z,!");
795 return op->size;
796 case 0xe3: //bnc
797 pic18_cond_branch (op, addr, buf, "c,!");
798 return op->size;
799 case 0xe4: //bov
800 pic18_cond_branch (op, addr, buf, "ov");
801 return op->size;
802 case 0xe5: //bnov
803 pic18_cond_branch (op, addr, buf, "ov,!");
804 return op->size;
805 case 0xe6: //bn
806 pic18_cond_branch (op, addr, buf, "n");
807 return op->size;
808 case 0xe7: //bnn
809 pic18_cond_branch (op, addr, buf, "n,!");
810 return op->size;
811 case 0xe2: //bc
812 pic18_cond_branch (op, addr, buf, "c");
813 return op->size;
814 case 0xef: //goto
815 if (len < 4) {
816 goto beach;
817 }
818 if (dword_instr >> 28 != 0xf) {
819 goto beach;
820 }
821 op->size = 4;
822 op->cycles = 2;
823 op->jump = ((dword_instr & 0xff) | ((dword_instr & 0xfff0000) >> 8)) * 2;
824 r_strbuf_setf (&op->esil, "0x%" PFMT64x ",pc,=", op->jump);
825 op->type = R_ANAL_OP_TYPE_JMP;
826 return op->size;
827 case 0xf: //addlw
828 op->type = R_ANAL_OP_TYPE_ADD;
829 op->cycles = 1;
830 //TODO add support for dc flag
831 r_strbuf_setf (&op->esil, "0x%x,wreg,+=,$z,z,:=,7,$s,n,:=,7,$c,c,:=,7,$o,ov,:=,", *(ut16 *)buf & 0xff);
832 return op->size;
833 case 0xe: //movlw
834 op->type = R_ANAL_OP_TYPE_LOAD;
835 op->cycles = 1;
836 r_strbuf_setf (&op->esil, "0x%x,wreg,=,", *(ut16* )buf & 0xff);
837 return op->size;
838 case 0xd: //mullw
839 op->type = R_ANAL_OP_TYPE_MUL;
840 op->cycles = 1;
841 r_strbuf_setf (&op->esil, "0x%x,wreg,*,prod,=", *(ut16 *)buf & 0xff);
842 return op->size;
843 case 0xc: //retlw
844 op->type = R_ANAL_OP_TYPE_RET;
845 op->cycles = 2;
846 r_strbuf_setf (&op->esil, "0x%x,wreg,=,tos,pc,=,", *(ut16 *)buf & 0xff);
847 return op->size;
848 case 0xb: //andlw
849 op->type = R_ANAL_OP_TYPE_AND;
850 op->cycles = 1;
851 r_strbuf_setf (&op->esil, "0x%x,wreg,&=,$z,z,:=,7,$s,n,:=,", *(ut16 *)buf & 0xff);
852 return op->size;
853 case 0xa: //xorlw
854 op->type = R_ANAL_OP_TYPE_XOR;
855 op->cycles = 1;
856 r_strbuf_setf (&op->esil, "0x%x,wreg,^=,$z,z,:=,7,$s,n,:=,", *(ut16 *)buf & 0xff);
857 return op->size;
858 case 0x9: //iorlw
859 op->type = R_ANAL_OP_TYPE_OR;
860 op->cycles = 1;
861 r_strbuf_setf (&op->esil, "0x%x,wreg,^=,$z,z,:=,7,$s,n,:=,", *(ut16 *)buf & 0xff);
862 return op->size;
863 case 0x8: //sublw
864 op->type = R_ANAL_OP_TYPE_SUB;
865 op->cycles = 1;
866 //TODO add support for dc flag
867 r_strbuf_setf (&op->esil, "wreg,0x%x,-,wreg,=,$z,z,:=,7,$s,n,:=,7,$c,c,:=,7,$o,ov,:=,", *(ut16 *)buf & 0xff);
868 return op->size;
869 };
870
871 switch (b >> 6) { //LFSR
872 case 0x3b8: //lfsr
873 if (len < 4) {
874 goto beach;
875 }
876 if (dword_instr >> 28 != 0xf) {
877 goto beach;
878 }
879 op->size = 4;
880 op->type = R_ANAL_OP_TYPE_LOAD;
881 return op->size;
882 };
883 switch (b >> 10) { //DAF_T
884 case 0x17: //subwf
885 case 0x16: //subwfb
886 case 0x15: //subfwb
887 case 0x13: //dcfsnz
888 case 0xb: //decfsz
889 case 0x1: //decf
890 op->type = R_ANAL_OP_TYPE_SUB;
891 return op->size;
892 case 0x14: //movf
893 op->type = R_ANAL_OP_TYPE_MOV;
894 return op->size;
895 case 0x12: //infsnz
896 case 0xf: //incfsz
897 case 0xa: //incf
898 case 0x8: //addwfc
899 op->type = R_ANAL_OP_TYPE_ADD;
900 return op->size;
901 case 0x9: //addwf
902 op->cycles = 1;
903 op->type = R_ANAL_OP_TYPE_ADD;
904 return op->size;
905 case 0x11: //rlncf
906 case 0xd: //rlcf
907 op->type = R_ANAL_OP_TYPE_ROL;
908 return op->size;
909 case 0x10: //rrncf
910 case 0xc: //rrcf
911 op->type = R_ANAL_OP_TYPE_ROR;
912 return op->size;
913 case 0xe: //swapf
914 op->type = R_ANAL_OP_TYPE_UNK;
915 return op->size;
916 case 0x7: //comf
917 op->type = R_ANAL_OP_TYPE_CPL;
918 return op->size;
919 case 0x6: //xorwf
920 op->type = R_ANAL_OP_TYPE_XOR;
921 return op->size;
922 case 0x5: //andwf
923 op->type = R_ANAL_OP_TYPE_AND;
924 return op->size;
925 case 0x4: //iorwf
926 op->type = R_ANAL_OP_TYPE_OR;
927 return op->size;
928 };
929 switch (b >> 9) { //AF_T
930 case 0x37: //movwf
931 op->type = R_ANAL_OP_TYPE_STORE;
932 return op->size;
933 case 0x36: //negf
934 case 0x35: //clrf
935 case 0x34: //setf
936 op->type = R_ANAL_OP_TYPE_UNK;
937 return op->size;
938 case 0x33: //tstfsz
939 op->type = R_ANAL_OP_TYPE_CJMP;
940 return op->size;
941 case 0x32: //cpfsgt
942 case 0x31: //cpfseq
943 case 0x30: //cpfslt
944 op->type = R_ANAL_OP_TYPE_CMP;
945 return op->size;
946 case 0x1: //mulwf
947 op->type = R_ANAL_OP_TYPE_MUL;
948 return op->size;
949 };
950 switch (b >> 4) {
951 case 0x10: //movlb
952 op->type = R_ANAL_OP_TYPE_LOAD;
953 op->cycles = 1;
954 r_strbuf_setf (&op->esil, "0x%x,bsr,=,", *(ut16 *)buf & 0xf);
955 return op->size;
956 };
957 switch (b) {
958 case 0xff: //reset
959 case 0x7: //daw
960 case 0x4: //clwdt
961 case 0x3: //sleep
962 op->type = R_ANAL_OP_TYPE_UNK;
963 return op->size;
964 case 0x13: //return
965 op->type = R_ANAL_OP_TYPE_RET;
966 op->cycles = 2;
967 r_strbuf_setf (&op->esil, "tos,pc,=,");
968 return op->size;
969 case 0x12: //return
970 op->type = R_ANAL_OP_TYPE_RET;
971 op->cycles = 2;
972 r_strbuf_setf (&op->esil, "tos,pc,=");
973 return op->size;
974 case 0x11: //retfie
975 case 0x10: //retfie
976 op->type = R_ANAL_OP_TYPE_RET;
977 return op->size;
978 case 0xf: //tblwt
979 case 0xe: //tblwt
980 case 0xd: //tblwt
981 case 0xc: //tblwt
982 op->type = R_ANAL_OP_TYPE_LOAD;
983 return op->size;
984 case 0xb: //tblrd
985 case 0xa: //tblrd
986 case 0x9: //tblrd
987 case 0x8: //tblrd
988 op->type = R_ANAL_OP_TYPE_STORE;
989 return op->size;
990 case 0x6: //pop
991 op->type = R_ANAL_OP_TYPE_POP;
992 return op->size;
993 case 0x5: //push
994 op->type = R_ANAL_OP_TYPE_PUSH;
995 return op->size;
996 case 0x0: //nop
997 op->type = R_ANAL_OP_TYPE_NOP;
998 op->cycles = 1;
999 r_strbuf_setf (&op->esil, ",");
1000 return op->size;
1001 };
1002 beach:
1003 op->type = R_ANAL_OP_TYPE_ILL;
1004 return op->size;
1005 }
1006
anal_pic_midrange_set_reg_profile(RAnal * esil)1007 static bool anal_pic_midrange_set_reg_profile (RAnal *esil) {
1008 const char *p = \
1009 "=PC pc\n"
1010 "=SP stkptr\n"
1011 "=A0 porta\n"
1012 "=A1 portb\n"
1013 "gpr indf0 .8 0 0\n"
1014 "gpr indf1 .8 1 0\n"
1015 "gpr pcl .8 2 0\n"
1016 "gpr status .8 3 0\n"
1017 "flg c .1 3.0 0\n"
1018 "flg dc .1 3.1 0\n"
1019 "flg z .1 3.2 0\n"
1020 "flg pd .1 3.3 0\n"
1021 "flg to .1 3.4 0\n"
1022 "gpr fsr0l .8 4 0\n"
1023 "gpr fsr0h .8 5 0\n"
1024 "gpr fsr1l .8 6 0\n"
1025 "gpr fsr1h .8 7 0\n"
1026 "gpr bsr .8 8 0\n"
1027 "gpr wreg .8 9 0\n"
1028 "gpr pclath .8 10 0\n"
1029 "gpr intcon .8 11 0\n"
1030 "gpr pc .16 12 0\n"
1031 "gpr stkptr .8 14 0\n"
1032 "gpr _sram .32 15 0\n"
1033 "gpr _stack .32 19 0\n";
1034 return r_reg_set_profile_string (esil->reg, p);
1035 }
1036
anal_pic_pic18_set_reg_profile(RAnal * esil)1037 static bool anal_pic_pic18_set_reg_profile(RAnal *esil) {
1038 const char *p =
1039 "#pc lives in nowhere actually"
1040 "=PC pc\n"
1041 "=SP tos\n"
1042 "=A0 porta\n"
1043 "=A1 portb\n"
1044 "gpr pc .32 0 0\n"
1045 "gpr pcl .8 0 0\n"
1046 "gpr pclath .8 1 0\n"
1047 "gpr pclatu .8 2 0\n"
1048 "#bsr max is 0b111\n"
1049 "gpr bsr .8 4 0\n"
1050 "#tos doesn't exist\n"
1051 "#general rule of thumb any register of size >8 bits has no existence\n"
1052 "gpr tos .32 5 0\n"
1053 "gpr tosl .8 5 0\n"
1054 "gpr tosh .8 6 0\n"
1055 "gpr tosu .8 7 0\n"
1056
1057 "gpr indf0 .16 9 0\n"
1058 "gpr fsr0 .12 9 0\n"
1059 "gpr fsr0l .8 9 0\n"
1060 "gpr fsr0h .8 10 0\n"
1061 "gpr indf1 .16 11 0\n"
1062 "gpr fsr1 .12 11 0\n"
1063 "gpr fsr1l .8 11 0\n"
1064 "gpr fsr1h .8 12 0\n"
1065 "gpr indf2 .16 13 0\n"
1066 "gpr fsr2 .12 13 0\n"
1067 "gpr frs2l .8 13 0\n"
1068 "gpr fsr2h .8 14 0\n"
1069 "gpr tblptr .22 15 0\n"
1070 "gpr tblptrl .8 15 0\n"
1071 "gpr tblptrh .8 16 0\n"
1072 "gpr tblptru .8 17 0\n"
1073 "gpr rcon .8 18 0\n"
1074 "gpr memcon .8 19 0\n"
1075 "gpr intcon .8 20 0\n"
1076 "gpr intcon2 .8 21 0\n"
1077 "gpr intcon3 .8 22 0\n"
1078 "gpr pie1 .8 23 0\n"
1079 "gpr porta .7 29 0\n"
1080 "gpr trisa .8 30 0\n"
1081 "gpr portb .8 33 0\n"
1082 "gpr tisb .8 34 0\n"
1083 "gpr latb .8 35 0\n"
1084 "gpr portc .8 36 0\n"
1085 "gpr trisc .8 37 0\n"
1086 "gpr latc .8 38 0\n"
1087 "gpr portd .8 39 0\n"
1088 "gpr trisd .8 40 0\n"
1089 "gpr latd .8 41 0\n"
1090 "gpr pspcon .8 42 0\n"
1091 "gpr porte .8 43 0\n"
1092 "gpr trise .8 44 0\n"
1093 "gpr late .8 45 0\n"
1094 "gpr t0con .8 46 0\n"
1095 "gpr t1con .8 47 0\n"
1096 "gpr t2con .8 48 0\n"
1097 "gpr tmr1h .8 50 0\n"
1098 "gpr tmr0h .8 51 0\n"
1099 "gpr tmr1l .8 52 0\n"
1100 "gpr tmr2 .8 53 0\n"
1101 "gpr pr2 .8 54 0\n"
1102 "gpr ccpr1h .8 55 0\n"
1103 "gpr postinc2 .8 56 0\n"
1104 "gpr ccpr1l .8 57 0\n"
1105 "gpr postdec2 .8 58 0\n"
1106 "gpr ccp1con .8 59 0\n"
1107 "gpr preinc2 .8 60 0\n"
1108 "gpr ccpr2h .8 61 0\n"
1109 "gpr plusw2 .8 62 0\n"
1110 "gpr ccpr2l .8 63 0\n"
1111 "gpr ccp2con .8 64 0\n"
1112 "gpr status .8 65 0\n"
1113 "flg c .1 .520 0\n"
1114 "flg dc .1 .521 0\n"
1115 "flg z .1 .522 0\n"
1116 "flg ov .1 .523 0\n"
1117 "flg n .1 .524 0\n"
1118 "gpr prod .16 66 0\n"
1119 "gpr prodl .8 66 0\n"
1120 "gpr prodh .8 67 0\n"
1121 "gpr osccon .8 68 0\n"
1122 "gpr tmr3h .8 69 0\n"
1123 "gpr lvdcon .8 70 0\n"
1124 "gpr tmr3l .8 71 0\n"
1125 "gpr wdtcon .8 72 0\n"
1126 "gpr t3con .8 73 0\n"
1127 "gpr spbrg .8 74 0\n"
1128 "gpr postinc0 .8 75 0\n"
1129 "gpr rcreg .8 76 0\n"
1130 "gpr postdec0 .8 77 0\n"
1131 "gpr txreg .8 78 0\n"
1132 "gpr preinc0 .8 79 0\n"
1133 "gpr txsta .8 80 0\n"
1134 "gpr plusw0 .8 81 0\n"
1135 "gpr rcsta .8 82 0\n"
1136 "gpr sspbuf .8 83 0\n"
1137 "gpr wreg .8 84 0\n"
1138 "gpr sspadd .8 85 0\n"
1139 "gpr sspstat .8 86 0\n"
1140 "gpr postinc1 .8 87 0\n"
1141 "gpr sspcon1 .8 88 0\n"
1142 "gpr postdec1 .8 89 0\n"
1143 "gpr sspcon2 .8 90 0\n"
1144 "gpr preinc1 .8 91 0\n"
1145 "gpr adresh .8 92 0\n"
1146 "gpr plusw1 .8 93 0\n"
1147 "gpr adresl .8 94 0\n"
1148 "gpr adcon0 .8 95 0\n"
1149 "#stkprt max is 0b11111\n"
1150 "gpr stkptr .8 96 0\n"
1151 "gpr tablat .8 14 0\n";
1152
1153 return r_reg_set_profile_string (esil->reg, p);
1154 }
1155
1156
anal_pic_op(RAnal * anal,RAnalOp * op,ut64 addr,const ut8 * buf,int len,RAnalOpMask mask)1157 static int anal_pic_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len, RAnalOpMask mask) {
1158 if (anal->cpu && strcasecmp (anal->cpu, "baseline") == 0) {
1159 // TODO: implement
1160 return -1;
1161 }
1162 if (anal->cpu && strcasecmp (anal->cpu, "midrange") == 0) {
1163 return anal_pic_midrange_op (anal, op, addr, buf, len);
1164 }
1165 if (anal->cpu && strcasecmp (anal->cpu, "pic18") == 0) {
1166 return anal_pic_pic18_op (anal, op, addr, buf, len);
1167 }
1168 return -1;
1169 }
1170
anal_pic_set_reg_profile(RAnal * anal)1171 static bool anal_pic_set_reg_profile(RAnal *anal) {
1172 if (anal->cpu && strcasecmp (anal->cpu, "baseline") == 0) {
1173 // TODO: We are using the midrange profile as the baseline
1174 return anal_pic_midrange_set_reg_profile (anal);
1175 }
1176 if (anal->cpu && strcasecmp (anal->cpu, "midrange") == 0) {
1177 return anal_pic_midrange_set_reg_profile (anal);
1178 }
1179 if (anal->cpu && strcasecmp (anal->cpu, "pic18") == 0) {
1180 return anal_pic_pic18_set_reg_profile (anal);
1181 }
1182 return false;
1183 }
1184
1185 RAnalPlugin r_anal_plugin_pic = {
1186 .name = "pic",
1187 .desc = "PIC analysis plugin",
1188 .license = "LGPL3",
1189 .arch = "pic",
1190 .bits = 8,
1191 .op = &anal_pic_op,
1192 .set_reg_profile = &anal_pic_set_reg_profile,
1193 .esil = true
1194 };
1195
1196 #ifndef R2_PLUGIN_INCORE
1197 R_API RLibStruct radare_plugin = {
1198 .type = R_LIB_TYPE_ANAL,
1199 .data = &r_anal_plugin_pic,
1200 .version = R2_VERSION
1201 };
1202 #endif
1203