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