Rizin
unix-like reverse engineering framework and cli tools
analysis_h8300.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2012-2015 pancake <pancake@nopcode.org>
2 // SPDX-FileCopyrightText: 2012-2015 Fedor Sakharov <fedor.sakharov@gmail.com>
3 // SPDX-FileCopyrightText: 2012-2015 Bhootravi <ravi2809@gmail.com>
4 // SPDX-License-Identifier: LGPL-3.0-only
5 
6 #include <string.h>
7 #include <rz_types.h>
8 #include <rz_lib.h>
9 #include <rz_asm.h>
10 #include <rz_analysis.h>
11 #include <rz_util.h>
12 
13 #include <h8300_disas.h>
14 
15 #define emit(frag) rz_strbuf_appendf(&op->esil, frag)
16 #define emitf(...) rz_strbuf_appendf(&op->esil, __VA_ARGS__)
17 // setting the appropriate flags, NOTE: semicolon included
18 #define setZ rz_strbuf_appendf(&op->esil, ",$z,Z,:=") // zero flag
19 #define setN rz_strbuf_appendf(&op->esil, ",15,$s,N,=") // negative(sign) flag
20 #define setV(val) rz_strbuf_appendf(&op->esil, ",%s,V,=", val) // overflow flag
21 #define setC_B rz_strbuf_appendf(&op->esil, ",7,$c,C,:=") // carry flag for byte op
22 #define setC_W rz_strbuf_appendf(&op->esil, ",15,$c,C,:=") // carryflag for word op
23 #define setCb_B rz_strbuf_appendf(&op->esil, ",7,$b,C,:=") // borrow flag for byte
24 #define setCb_W rz_strbuf_appendf(&op->esil, ",15,$b,C,:=") // borrow flag for word
25 #define setH_B rz_strbuf_appendf(&op->esil, ",3,$c,H,:=") // half carry(byte)-bcd
26 #define setH_W rz_strbuf_appendf(&op->esil, ",11,$c,H,:=") // half carry(word)-bcd
27 #define setHb_B rz_strbuf_appendf(&op->esil, ",3,$b,H,:=") // half borrow(byte)-bcd
28 #define setHb_W rz_strbuf_appendf(&op->esil, ",11,$b,H,:=") // halfborrow(word)-bcd
29 
30 // get reg. from opcodes
31 #define rs() (buf[1] & 0x70) >> 4 // upper nibble used as source generally
32 #define rsB() (buf[1] & 0x70) >> 4, buf[1] & 0x80 ? 'l' : 'h' // msb of nibble used for l/h
33 #define rd() buf[1] & 0x07 // lower nibble used as dest generally
34 // a for compact instrs. (some instrs. have rd in 1st byte, others in 2nd byte)
35 #define rdB(a) buf[a] & 0x07, buf[a] & 0x8 ? 'l' : 'h'
36 // work around for z flag
37 // internally r=0xff on incr. stored as 0x100, which doesn't raise the z flag
38 // NOTE - use the mask and setZ at last, mask will affect other flags
39 #define mask() rz_strbuf_appendf(&op->esil, ",0xffff,r%u,&=", rd());
40 #define maskB(a) rz_strbuf_appendf(&op->esil, ",0xff,r%u%c,&=", rdB(a));
41 
42 // immediate values are always 2nd byte
43 #define imm buf[1]
44 /*
45  * Reference Manual:
46  *
47 https://www.classes.cs.uchicago.edu/archive/2006/winter/23000-1/docs/h8300.pdf
48  */
49 
50 static void h8300_analysis_jmp(RzAnalysisOp *op, ut64 addr, const ut8 *buf) {
51  ut16 ad;
52 
53  switch (buf[0]) {
54  case H8300_JMP_1:
56  break;
57  case H8300_JMP_2:
59  rz_mem_swapendian((ut8 *)&ad, buf + 2, sizeof(ut16));
60  op->jump = ad;
61  break;
62  case H8300_JMP_3:
64  op->jump = buf[1];
65  break;
66  }
67 }
68 
69 static void h8300_analysis_jsr(RzAnalysisOp *op, ut64 addr, const ut8 *buf) {
70  ut16 ad;
71 
72  switch (buf[0]) {
73  case H8300_JSR_1:
75  break;
76  case H8300_JSR_2:
78  rz_mem_swapendian((ut8 *)&ad, buf + 2, sizeof(ut16));
79  op->jump = ad;
80  op->fail = addr + 4;
81  break;
82  case H8300_JSR_3:
84  op->jump = buf[1];
85  break;
86  }
87 }
88 
89 static int analop_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf) {
90  int ret = -1;
91  ut8 opcode = buf[0];
92  if (!op) {
93  return 2;
94  }
95  rz_strbuf_init(&op->esil);
96  rz_strbuf_set(&op->esil, "");
97  switch (opcode >> 4) {
98  case H8300_CMP_4BIT:
99  // acc. to manual this is how it's done, could use == in esil
100  rz_strbuf_appendf(&op->esil, "0x%02x,r%u%c,-", imm, rdB(0));
101  // setZ
102  setV("%o");
103  setN;
104  setHb_B;
105  setCb_B;
106  maskB(0);
107  setZ;
108  return 0;
109  case H8300_OR_4BIT:
110  rz_strbuf_appendf(&op->esil, "0x%02x,r%u%c,|=", imm, rdB(0));
111  // setZ
112  setV("0");
113  setN;
114  maskB(0);
115  setZ;
116  return 0;
117  case H8300_XOR_4BIT:
118  rz_strbuf_appendf(&op->esil, "0x%02x,r%u%c,^=", imm, rdB(0));
119  // setZ
120  setN;
121  setV("0");
122  maskB(0);
123  setZ;
124  return 0;
125  case H8300_AND_4BIT:
126  rz_strbuf_appendf(&op->esil, "0x%02x,r%u%c,&=", imm, rdB(0));
127  // setZ
128  setN;
129  setV("0");
130  maskB(0);
131  setZ;
132  return 0;
133  case H8300_ADD_4BIT:
134  rz_strbuf_appendf(&op->esil, "0x%02x,r%u%c,+=", imm, rdB(0));
135  // setZ
136  setV("%o");
137  setN;
138  setH_B;
139  setC_B;
140  maskB(0);
141  setZ;
142  return 0;
143  case H8300_ADDX_4BIT:
144  rz_strbuf_appendf(&op->esil, "0x%02x,C,+,r%u%c,+= ", imm, rdB(0));
145  // setZ
146  setV("%o");
147  setN;
148  setH_B;
149  setC_B;
150  maskB(0);
151  setZ;
152  return 0;
153  case H8300_SUBX_4BIT:
154  // Rd – imm – C → Rd
155  rz_strbuf_appendf(&op->esil, "0x%02x,r%u%c,-=,C,r%u%c,-=", imm, rdB(0), rdB(0));
156  // setZ
157  setV("%o");
158  setN;
159  setHb_B;
160  setCb_B;
161  maskB(0);
162  setZ;
163  return 0;
164  case H8300_MOV_4BIT_2: /*TODO*/
165  case H8300_MOV_4BIT_3: /*TODO*/
166  case H8300_MOV_4BIT: /*TODO*/
167  return 0;
168  default:
169  break;
170  };
171 
172  switch (opcode) {
173  case H8300_NOP:
174  rz_strbuf_set(&op->esil, ",");
175  return 0;
176  case H8300_SLEEP: /* TODO */
177  return 0;
178  case H8300_STC:
179  rz_strbuf_appendf(&op->esil, "ccr,r%u%c,=", rdB(1));
180  return 0;
181  case H8300_LDC:
182  rz_strbuf_appendf(&op->esil, "r%u%c,ccr,=", rdB(1));
183  return 0;
184  case H8300_ORC:
185  rz_strbuf_appendf(&op->esil, "0x%02x,ccr,|=", imm);
186  return 0;
187  case H8300_XORC:
188  rz_strbuf_appendf(&op->esil, "0x%02x,ccr,^=", imm);
189  return 0;
190  case H8300_ANDC:
191  rz_strbuf_appendf(&op->esil, "0x%02x,ccr,&=", imm);
192  return 0;
193  case H8300_LDC_2:
194  rz_strbuf_appendf(&op->esil, "0x%02x,ccr,=", imm);
195  return 0;
196  case H8300_ADDB_DIRECT:
197  rz_strbuf_appendf(&op->esil, "r%u%c,r%u%c,+=", rsB(), rdB(1));
198  setH_B;
199  setV("%o");
200  setC_B;
201  setN;
202  // setZ;
203  maskB(1);
204  setZ;
205  return 0;
206  case H8300_ADDW_DIRECT:
207  rz_strbuf_appendf(&op->esil, "r%u,r%u,+=", rs(), rd());
208  setH_W;
209  setV("%o");
210  setC_W;
211  setN;
212  mask();
213  setZ;
214  return 0;
215  case H8300_INC:
216  rz_strbuf_appendf(&op->esil, "1,r%u%c,+=", rdB(1));
217  // setZ
218  setV("%o");
219  setN;
220  maskB(1);
221  setZ;
222  return 0;
223  case H8300_ADDS:
224  rz_strbuf_appendf(&op->esil, "%d,r%u,+=",
225  ((buf[1] & 0xf0) == 0x80) ? 2 : 1, rd());
226  return 0;
227  case H8300_MOV_1:
228  /*TODO check if flags are set internally or not*/
229  rz_strbuf_appendf(&op->esil, "r%u%c,r%u%c,=", rsB(), rdB(1));
230  // setZ
231  setN;
232  maskB(1);
233  setZ;
234  return 0;
235  case H8300_MOV_2:
236  rz_strbuf_appendf(&op->esil, "r%u,r%u,=", rs(), rd());
237  // setZ
238  setN;
239  mask();
240  setZ;
241  return 0;
242  case H8300_ADDX:
243  // Rd + (Rs) + C → Rd
244  rz_strbuf_appendf(&op->esil, "r%u%c,C,+,r%u%c,+=",
245  rsB(), rdB(1));
246  // setZ
247  setV("%o");
248  setN;
249  setH_B;
250  setC_B;
251  maskB(1);
252  setZ;
253  return 0;
254  case H8300_DAA: /*TODO*/
255  return 0;
256  case H8300_SHL: /*TODO*/
257  return 0;
258  case H8300_SHR: /*TODO*/
259  return 0;
260  case H8300_ROTL: /*TODO*/
261  return 0;
262  case H8300_ROTR: /*TODO*/
263  return 0;
264  case H8300_OR:
265  rz_strbuf_appendf(&op->esil, "r%u%c,r%u%c,|=", rsB(), rdB(1));
266  // setZ
267  setV("0");
268  setN;
269  maskB(1);
270  setZ;
271  return 0;
272  case H8300_XOR:
273  rz_strbuf_appendf(&op->esil, "r%u%c,r%u%c,^=", rsB(), rdB(1));
274  // setZ
275  setV("0");
276  setN;
277  maskB(1);
278  setZ;
279  return 0;
280  case H8300_AND:
281  rz_strbuf_appendf(&op->esil, "r%u%c,r%u%c,&=", rsB(), rdB(1));
282  // setZ
283  setV("0");
284  setN;
285  maskB(1);
286  setZ;
287  return 0;
288  case H8300_NOT_NEG:
289  if ((buf[1] & 0xf0) == 0x80) { // NEG
290  rz_strbuf_appendf(&op->esil, "r%u%c,0,-,r%u%c,=", rdB(1), rdB(1));
291  // setZ
292  setHb_B;
293  setV("%o");
294  setCb_B;
295  setN;
296  maskB(1);
297  setZ;
298  } else if ((buf[1] & 0xf0) == 0x00) { // NOT
299  rz_strbuf_appendf(&op->esil, "r%u%c,!=", rdB(1));
300  // setZ
301  setV("0");
302  setN;
303  maskB(1);
304  setZ;
305  }
306  return 0;
307  case H8300_SUB_1:
308  rz_strbuf_appendf(&op->esil, "r%u%c,r%u%c,-=", rsB(), rdB(1));
309  // setZ
310  setHb_B;
311  setV("%o");
312  setCb_B;
313  setN;
314  maskB(1);
315  setZ;
316  return 0;
317  case H8300_SUBW:
318  rz_strbuf_appendf(&op->esil, "r%u,r%u,-=", rs(), rd());
319  setHb_W;
320  setV("%o");
321  setCb_W;
322  setN;
323  mask();
324  setZ;
325  return 0;
326  case H8300_DEC:
327  rz_strbuf_appendf(&op->esil, "1,r%u%c,-=", rdB(1));
328  // setZ
329  setV("%o");
330  setN;
331  maskB(1);
332  setZ;
333  return 0;
334  case H8300_SUBS:
335  rz_strbuf_appendf(&op->esil, "%d,r%u,-=",
336  ((buf[1] & 0xf0) == 0x80) ? 2 : 1, rd());
337  return 0;
338  case H8300_CMP_1:
339  rz_strbuf_appendf(&op->esil, "r%u%c,r%u%c,-", rsB(), rdB(1));
340  // setZ
341  setHb_B;
342  setV("%o");
343  setCb_B;
344  setN;
345  maskB(1);
346  setZ;
347  return 0;
348  case H8300_CMP_2:
349  rz_strbuf_appendf(&op->esil, "r%u,r%u,-", rs(), rd());
350  // setZ
351  setHb_W;
352  setV("%o");
353  setCb_W;
354  setN;
355  mask();
356  setZ;
357  return 0;
358  case H8300_SUBX:
359  // Rd – (Rs) – C → Rd
360  rz_strbuf_appendf(&op->esil, "r%u%c,r%u%c,-=,C,r%u%c,-=",
361  rsB(), rdB(1), rdB(1));
362  // setZ
363  setHb_B;
364  setV("%o");
365  setCb_B;
366  setN;
367  maskB(1);
368  setZ;
369  return 0;
370  case H8300_DAS: /*TODO*/
371  return 0;
372  case H8300_BRA:
373  rz_strbuf_appendf(&op->esil, "0x%02x,pc,+=", buf[1]);
374  return 0;
375  case H8300_BRN:
376  rz_strbuf_appendf(&op->esil, ",");
377  return 0;
378  case H8300_BHI:
379  rz_strbuf_appendf(&op->esil, "C,Z,|,!,?{0x%02x,pc,+=}", buf[1]);
380  return 0;
381  case H8300_BLS:
382  rz_strbuf_appendf(&op->esil, "C,Z,|,?{0x%02x,pc,+=}", buf[1]);
383  return 0;
384  case H8300_BCC:
385  rz_strbuf_appendf(&op->esil, "C,!,?{0x%02x,pc,+=}", buf[1]);
386  return 0;
387  case H8300_BCS:
388  rz_strbuf_appendf(&op->esil, "C,?{0x%02x,pc,+=}", buf[1]);
389  return 0;
390  case H8300_BNE:
391  rz_strbuf_appendf(&op->esil, "Z,!,?{0x%02x,pc,+=}", buf[1]);
392  return 0;
393  case H8300_BEQ:
394  rz_strbuf_appendf(&op->esil, "Z,?{0x%02x,pc,+=}", buf[1]);
395  return 0;
396  case H8300_BVC:
397  rz_strbuf_appendf(&op->esil, "V,!,?{0x%02x,pc,+=}", buf[1]);
398  return 0;
399  case H8300_BVS:
400  rz_strbuf_appendf(&op->esil, "V,?{0x%02x,pc,+=}", buf[1]);
401  return 0;
402  case H8300_BPL:
403  rz_strbuf_appendf(&op->esil, "N,!,?{0x%02x,pc,+=}", buf[1]);
404  return 0;
405  case H8300_BMI:
406  rz_strbuf_appendf(&op->esil, "N,?{0x%02x,pc,+=}", buf[1]);
407  return 0;
408  case H8300_BGE:
409  rz_strbuf_appendf(&op->esil, "N,V,^,!,?{0x%02x,pc,+=}", buf[1]);
410  return 0;
411  case H8300_BLT:
412  rz_strbuf_appendf(&op->esil, "N,V,^,?{0x%02x,pc,+=}", buf[1]);
413  return 0;
414  case H8300_BGT:
415  rz_strbuf_appendf(&op->esil, "Z,N,V,^,|,!,?{0x%02x,pc,+=}", buf[1]);
416  return 0;
417  case H8300_BLE:
418  rz_strbuf_appendf(&op->esil, "Z,N,V,^,|,?{0x%02x,pc,+=}", buf[1]);
419  return 0;
420  case H8300_MULXU:
421  // Refer to pg. 100 of the manual linked at the beginning
422  rz_strbuf_appendf(&op->esil, "r%u%c,r%ul,*,r%u,=",
423  rsB(), rd(), rd());
424  return 0;
425  case H8300_DIVXU: /*TODO*/ return 0;
426  case H8300_RTS: /*TODO*/ return 0;
427  case H8300_BSR: /*TODO*/ return 0;
428  case H8300_RTE: /*TODO*/ return 0;
429  case H8300_JMP_1: /*TODO*/ return 0;
430  case H8300_JMP_2: /*TODO*/ return 0;
431  case H8300_JMP_3: /*TODO*/ return 0;
432  case H8300_JSR_1: /*TODO*/ return 0;
433  case H8300_JSR_2: /*TODO*/ return 0;
434  case H8300_JSR_3: /*TODO*/
435  return 0;
436  // NOTE - cases marked with TODO have mem. access also(not impl.)
437  case H8300_BSET_1: /*TODO*/
438  // set rs&0x7th bit of rd. expr.- rd|= 1<<(rs&0x07)
439  rz_strbuf_appendf(&op->esil, "0x7,r%u%c,&,1,<<,r%u%c,|=", rsB(), rdB(1));
440  return 0;
441  case H8300_BNOT_1: /*TODO*/
442  // invert rs&0x7th bit of rd. expr.- rd^= 1<<(rs&0x07)
443  rz_strbuf_appendf(&op->esil, "0x07,r%u%c,&,1,<<,r%u%c,^=", rsB(), rdB(1));
444  return 0;
445  case H8300_BCLR_R2R8: /*TODO*/
446  // clear rs&0x7th bit of rd. expr.- rd&= !(1<<(rs&0x07))
447  rz_strbuf_appendf(&op->esil, "0x7,r%u%c,&,1,<<,!,r%u%c,&=", rsB(), rdB(1));
448  return 0;
449  case H8300_BTST_R2R8: /*TODO*/
450  //¬ (<Bit No.> of <EAd>) → Z, extract bit value and shift it back
451  rz_strbuf_appendf(&op->esil, "0x7,r%u%c,&,0x7,r%u%c,&,1,<<,r%u%c,&,>>,!,Z,=",
452  rsB(), rsB(), rdB(1));
453  return 0;
454  case H8300_BST_BIST: /*TODO*/
455  if (!(buf[1] & 0x80)) { // BST
456  rz_strbuf_appendf(&op->esil, "%d,C,<<,r%u%c,|=", rs(), rdB(1));
457  } else { // BIST
458  rz_strbuf_appendf(&op->esil, "%d,C,!,<<,r%u%c,|=", rs(), rdB(1));
459  }
460  return 0;
461  case H8300_MOV_R82IND16: /*TODO*/ return 0;
462  case H8300_MOV_IND162R16: /*TODO*/ return 0;
463  case H8300_MOV_R82ABS16: /*TODO*/ return 0;
464  case H8300_MOV_ABS162R16: /*TODO*/ return 0;
465  case H8300_MOV_R82RDEC16: /*TODO*/ return 0;
466  case H8300_MOV_INDINC162R16: /*TODO*/ return 0;
467  case H8300_MOV_R82DISPR16: /*TODO*/ return 0;
468  case H8300_MOV_DISP162R16: /*TODO*/
469  return 0;
470  case H8300_BSET_2: /*TODO*/
471  // set imm bit of rd. expr.- rd|= (1<<imm)
472  rz_strbuf_appendf(&op->esil, "%d,1,<<,r%u%c,|=", rs(), rdB(1));
473  return 0;
474  case H8300_BNOT_2: /*TODO*/
475  // inv. imm bit of rd. expr.- rd^= (1<<imm)
476  rz_strbuf_appendf(&op->esil, "%d,1,<<,r%u%c,^=", rs(), rdB(1));
477  return 0;
478  case H8300_BCLR_IMM2R8:
479  // clear imm bit of rd. expr.- rd&= !(1<<imm)
480  rz_strbuf_appendf(&op->esil, "%d,1,<<,!,r%u%c,&=", rs(), rdB(1));
481  return 0;
482  case H8300_BTST: /*TODO*/
483  // see BTST above
484  rz_strbuf_appendf(&op->esil, "%d,%d,1,<<,r%u%c,&,>>,!,Z,=",
485  rs(), rs(), rdB(1));
486  return 0;
487  case H8300_BOR_BIOR: /*TODO*/
488  if (!(buf[1] & 0x80)) { // BOR
489  // C|=(rd&(1<<imm))>>imm
490  rz_strbuf_appendf(&op->esil, "%d,%d,1,<<,r%u%c,&,>>,C,|=",
491  rs(), rs(), rdB(1));
492  } else { // BIOR
493  // C|=!(rd&(1<<imm))>>imm
494  rz_strbuf_appendf(&op->esil, "%d,%d,1,<<,r%u%c,&,>>,!,C,|=",
495  rs(), rs(), rdB(1));
496  }
497  return 0;
498  case H8300_BXOR_BIXOR: /*TODO*/
499  if (!(buf[1] & 0x80)) { // BXOR
500  // C^=(rd&(1<<imm))>>imm
501  rz_strbuf_appendf(&op->esil, "%d,%d,1,<<,r%u%c,&,>>,C,^=",
502  rs(), rs(), rdB(1));
503  } else { // BIXOR
504  rz_strbuf_appendf(&op->esil, "%d,%d,1,<<,r%u%c,&,>>,!,C,^=",
505  rs(), rs(), rdB(1));
506  }
507  return 0;
508  case H8300_BAND_BIAND:
509  /*TODO check functionality*/
510  // C&=(rd&(1<<imm))>>imm
511  if (!(buf[1] & 0x80)) { // BAND
512  rz_strbuf_appendf(&op->esil, "%d,%d,1,<<,r%u%c,&,>>,C,&=",
513  rs(), rs(), rdB(1));
514  } else { // BIAND
515  rz_strbuf_appendf(&op->esil, "%d,%d,1,<<,r%u%c,&,>>,!,C,&=",
516  rs(), rs(), rdB(1));
517  }
518  return 0;
519  case H8300_BILD_IMM2R8:
520  /*TODO*/
521  if (!(buf[1] & 0x80)) { // BLD
522  rz_strbuf_appendf(&op->esil, "%d,%d,1,<<,r%u%c,&,>>,C,=",
523  rs(), rs(), rdB(1));
524  } else { // BILD
525  rz_strbuf_appendf(&op->esil, "%d,%d,1,<<,r%u%c,&,>>,!,C,=",
526  rs(), rs(), rdB(1));
527  }
528  return 0;
529  case H8300_MOV_IMM162R16: /*TODO*/ return 0;
530  case H8300_EEPMOV: /*TODO*/ return 0;
531  case H8300_BIAND_IMM2IND16: /*TODO*/ return 0;
532  case H8300_BCLR_R2IND16: /*TODO*/ return 0;
533  case H8300_BIAND_IMM2ABS8: /*TODO*/ return 0;
534  case H8300_BCLR_R2ABS8: /*TODO*/ return 0;
535  default:
536  break;
537  };
538 
539  return ret;
540 }
541 
542 static int h8300_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr,
543  const ut8 *buf, int len, RzAnalysisOpMask mask) {
544  int ret;
545  ut8 opcode = buf[0];
546  struct h8300_cmd cmd;
547 
548  if (!op) {
549  return 2;
550  }
551 
552  op->addr = addr;
553  ret = op->size = h8300_decode_command(buf, &cmd);
554 
555  if (ret < 0) {
556  return ret;
557  }
558  switch (opcode >> 4) {
559  case H8300_MOV_4BIT_2:
560  case H8300_MOV_4BIT_3:
561  case H8300_MOV_4BIT:
562  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
563  break;
564  case H8300_CMP_4BIT:
565  op->type = RZ_ANALYSIS_OP_TYPE_CMP;
566  break;
567  case H8300_XOR_4BIT:
568  op->type = RZ_ANALYSIS_OP_TYPE_XOR;
569  break;
570  case H8300_AND_4BIT:
571  op->type = RZ_ANALYSIS_OP_TYPE_AND;
572  break;
573  case H8300_ADD_4BIT:
574  case H8300_ADDX_4BIT:
575  op->type = RZ_ANALYSIS_OP_TYPE_AND;
576  break;
577  case H8300_SUBX_4BIT:
578  op->type = RZ_ANALYSIS_OP_TYPE_SUB;
579  break;
580  default:
581  op->type = RZ_ANALYSIS_OP_TYPE_UNK;
582  break;
583  };
584 
585  if (op->type != RZ_ANALYSIS_OP_TYPE_UNK) {
586  analop_esil(analysis, op, addr, buf);
587  return ret;
588  }
589  switch (opcode) {
590  case H8300_MOV_R82IND16:
591  case H8300_MOV_IND162R16:
592  case H8300_MOV_R82ABS16:
593  case H8300_MOV_ABS162R16:
594  case H8300_MOV_R82RDEC16:
598  case H8300_MOV_IMM162R16:
599  case H8300_MOV_1:
600  case H8300_MOV_2:
601  case H8300_EEPMOV:
602  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
603  break;
604  case H8300_RTS:
605  op->type = RZ_ANALYSIS_OP_TYPE_RET;
606  break;
607  case H8300_CMP_1:
608  case H8300_CMP_2:
609  case H8300_BTST_R2R8:
610  case H8300_BTST:
611  op->type = RZ_ANALYSIS_OP_TYPE_CMP;
612  break;
613  case H8300_SHL:
614  op->type = RZ_ANALYSIS_OP_TYPE_SHL;
615  break;
616  case H8300_SHR:
617  op->type = RZ_ANALYSIS_OP_TYPE_SHR;
618  break;
619  case H8300_XOR:
620  case H8300_XORC:
621  op->type = RZ_ANALYSIS_OP_TYPE_XOR;
622  break;
623  case H8300_MULXU:
624  op->type = RZ_ANALYSIS_OP_TYPE_MUL;
625  break;
626  case H8300_ANDC:
627  op->type = RZ_ANALYSIS_OP_TYPE_AND;
628  break;
629  case H8300_ADDB_DIRECT:
630  case H8300_ADDW_DIRECT:
631  case H8300_ADDS:
632  case H8300_ADDX:
633  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
634  break;
635  case H8300_SUB_1:
636  case H8300_SUBW:
637  case H8300_SUBS:
638  case H8300_SUBX:
639  op->type = RZ_ANALYSIS_OP_TYPE_SUB;
640  break;
641  case H8300_NOP:
642  op->type = RZ_ANALYSIS_OP_TYPE_NOP;
643  break;
644  case H8300_JSR_1:
645  case H8300_JSR_2:
646  case H8300_JSR_3:
648  break;
649  case H8300_JMP_1:
650  case H8300_JMP_2:
651  case H8300_JMP_3:
653  break;
654  case H8300_BRA:
655  case H8300_BRN:
656  case H8300_BHI:
657  case H8300_BLS:
658  case H8300_BCC:
659  case H8300_BCS:
660  case H8300_BNE:
661  case H8300_BEQ:
662  case H8300_BVC:
663  case H8300_BVS:
664  case H8300_BPL:
665  case H8300_BMI:
666  case H8300_BGE:
667  case H8300_BLT:
668  case H8300_BGT:
669  case H8300_BLE:
671  op->jump = addr + 2 + (st8)(buf[1]);
672  op->fail = addr + 2;
673  break;
674  default:
675  op->type = RZ_ANALYSIS_OP_TYPE_UNK;
676  break;
677  };
679  analop_esil(analysis, op, addr, buf);
680  }
681  return ret;
682 }
683 
684 static char *get_reg_profile(RzAnalysis *analysis) {
685  char *p =
686  "=PC pc\n"
687  "=SP r7\n"
688  "=A0 r0\n"
689  "gpr r0 .16 0 0\n"
690  "gpr r0h .8 0 0\n"
691  "gpr r0l .8 1 0\n"
692  "gpr r1 .16 2 0\n"
693  "gpr r1h .8 2 0\n"
694  "gpr r1l .8 3 0\n"
695  "gpr r2 .16 4 0\n"
696  "gpr r2h .8 4 0\n"
697  "gpr r2l .8 5 0\n"
698  "gpr r3 .16 6 0\n"
699  "gpr r3h .8 6 0\n"
700  "gpr r3l .8 7 0\n"
701  "gpr r4 .16 8 0\n"
702  "gpr r4h .8 8 0\n"
703  "gpr r4l .8 9 0\n"
704  "gpr r5 .16 10 0\n"
705  "gpr r5h .8 10 0\n"
706  "gpr r5l .8 11 0\n"
707  "gpr r6 .16 12 0\n"
708  "gpr r6h .8 12 0\n"
709  "gpr r6l .8 13 0\n"
710  "gpr r7 .16 14 0\n"
711  "gpr r7h .8 14 0\n"
712  "gpr r7l .8 15 0\n"
713  "gpr pc .16 16 0\n"
714  "gpr ccr .8 18 0\n"
715  "gpr I .1 .151 0\n"
716  "gpr U1 .1 .150 0\n"
717  "gpr H .1 .149 0\n"
718  "gpr U2 .1 .148 0\n"
719  "gpr N .1 .147 0\n"
720  "gpr Z .1 .146 0\n"
721  "gpr V .1 .145 0\n"
722  "gpr C .1 .144 0\n";
723  return strdup(p);
724 }
725 
727  .name = "h8300",
728  .desc = "H8300 code analysis plugin",
729  .license = "LGPL3",
730  .arch = "h8300",
731  .bits = 16,
732  .op = &h8300_op,
733  .esil = true,
734  .get_reg_profile = get_reg_profile,
735 };
736 
737 #ifndef RZ_PLUGIN_INCORE
738 struct rz_lib_struct_t rizin_plugin = {
740  .data = &rz_analysis_plugin_h8300,
742 };
743 #endif
size_t len
Definition: 6502dis.c:15
static char * get_reg_profile(RzAnalysis *analysis)
RzAnalysisPlugin rz_analysis_plugin_h8300
#define setHb_B
#define setHb_W
#define setC_W
static void h8300_analysis_jmp(RzAnalysisOp *op, ut64 addr, const ut8 *buf)
#define rdB(a)
#define rs()
#define setH_B
#define rd()
#define setH_W
#define mask()
static int h8300_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, RzAnalysisOpMask mask)
static void h8300_analysis_jsr(RzAnalysisOp *op, ut64 addr, const ut8 *buf)
#define setCb_B
#define setN
#define rsB()
#define setC_B
#define maskB(a)
#define imm
struct rz_lib_struct_t rizin_plugin
#define setCb_W
#define setZ
static int analop_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf)
#define setV(val)
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags cmd
Definition: sflib.h:79
uint16_t ut16
int h8300_decode_command(const ut8 *instr, struct h8300_cmd *cmd)
Definition: h8300_disas.c:779
@ H8300_MOV_4BIT_2
Definition: h8300_disas.h:10
@ H8300_ADDX_4BIT
Definition: h8300_disas.h:13
@ H8300_ADD_4BIT
Definition: h8300_disas.h:12
@ H8300_OR_4BIT
Definition: h8300_disas.h:16
@ H8300_AND_4BIT
Definition: h8300_disas.h:18
@ H8300_MOV_4BIT_3
Definition: h8300_disas.h:11
@ H8300_CMP_4BIT
Definition: h8300_disas.h:14
@ H8300_XOR_4BIT
Definition: h8300_disas.h:17
@ H8300_SUBX_4BIT
Definition: h8300_disas.h:15
@ H8300_MOV_4BIT
Definition: h8300_disas.h:19
@ H8300_BGE
Definition: h8300_disas.h:67
@ H8300_ORC
Definition: h8300_disas.h:27
@ H8300_SUB_1
Definition: h8300_disas.h:47
@ H8300_SLEEP
Definition: h8300_disas.h:24
@ H8300_SUBS
Definition: h8300_disas.h:50
@ H8300_BCC
Definition: h8300_disas.h:59
@ H8300_MOV_IMM162R16
Definition: h8300_disas.h:103
@ H8300_BOR_BIOR
Definition: h8300_disas.h:99
@ H8300_SUBX
Definition: h8300_disas.h:53
@ H8300_DAS
Definition: h8300_disas.h:54
@ H8300_LDC_2
Definition: h8300_disas.h:30
@ H8300_SUBW
Definition: h8300_disas.h:48
@ H8300_ADDX
Definition: h8300_disas.h:37
@ H8300_BSET_1
Definition: h8300_disas.h:82
@ H8300_SHR
Definition: h8300_disas.h:40
@ H8300_BSR
Definition: h8300_disas.h:74
@ H8300_MOV_R82IND16
Definition: h8300_disas.h:87
@ H8300_BIAND_IMM2IND16
Definition: h8300_disas.h:105
@ H8300_EEPMOV
Definition: h8300_disas.h:104
@ H8300_BNOT_1
Definition: h8300_disas.h:83
@ H8300_BRA
Definition: h8300_disas.h:55
@ H8300_ROTR
Definition: h8300_disas.h:42
@ H8300_NOT_NEG
Definition: h8300_disas.h:46
@ H8300_BNE
Definition: h8300_disas.h:61
@ H8300_RTS
Definition: h8300_disas.h:73
@ H8300_CMP_2
Definition: h8300_disas.h:52
@ H8300_JMP_2
Definition: h8300_disas.h:77
@ H8300_MOV_1
Definition: h8300_disas.h:35
@ H8300_BMI
Definition: h8300_disas.h:66
@ H8300_ADDB_DIRECT
Definition: h8300_disas.h:31
@ H8300_MOV_INDINC162R16
Definition: h8300_disas.h:92
@ H8300_BLT
Definition: h8300_disas.h:68
@ H8300_BHI
Definition: h8300_disas.h:57
@ H8300_LDC
Definition: h8300_disas.h:26
@ H8300_BLS
Definition: h8300_disas.h:58
@ H8300_BVC
Definition: h8300_disas.h:63
@ H8300_MOV_R82DISPR16
Definition: h8300_disas.h:93
@ H8300_BPL
Definition: h8300_disas.h:65
@ H8300_MOV_ABS162R16
Definition: h8300_disas.h:90
@ H8300_BCLR_R2IND16
Definition: h8300_disas.h:106
@ H8300_RTE
Definition: h8300_disas.h:75
@ H8300_DEC
Definition: h8300_disas.h:49
@ H8300_NOP
Definition: h8300_disas.h:23
@ H8300_ROTL
Definition: h8300_disas.h:41
@ H8300_CMP_1
Definition: h8300_disas.h:51
@ H8300_MOV_2
Definition: h8300_disas.h:36
@ H8300_MOV_IND162R16
Definition: h8300_disas.h:88
@ H8300_BSET_2
Definition: h8300_disas.h:95
@ H8300_BIAND_IMM2ABS8
Definition: h8300_disas.h:107
@ H8300_INC
Definition: h8300_disas.h:33
@ H8300_XOR
Definition: h8300_disas.h:44
@ H8300_MOV_R82ABS16
Definition: h8300_disas.h:89
@ H8300_XORC
Definition: h8300_disas.h:28
@ H8300_OR
Definition: h8300_disas.h:43
@ H8300_DIVXU
Definition: h8300_disas.h:72
@ H8300_MOV_R82RDEC16
Definition: h8300_disas.h:91
@ H8300_ADDW_DIRECT
Definition: h8300_disas.h:32
@ H8300_BNOT_2
Definition: h8300_disas.h:96
@ H8300_BCS
Definition: h8300_disas.h:60
@ H8300_BCLR_R2R8
Definition: h8300_disas.h:84
@ H8300_BGT
Definition: h8300_disas.h:69
@ H8300_BAND_BIAND
Definition: h8300_disas.h:101
@ H8300_JSR_2
Definition: h8300_disas.h:80
@ H8300_BILD_IMM2R8
Definition: h8300_disas.h:102
@ H8300_JMP_3
Definition: h8300_disas.h:78
@ H8300_ANDC
Definition: h8300_disas.h:29
@ H8300_BST_BIST
Definition: h8300_disas.h:86
@ H8300_ADDS
Definition: h8300_disas.h:34
@ H8300_JSR_1
Definition: h8300_disas.h:79
@ H8300_MULXU
Definition: h8300_disas.h:71
@ H8300_JMP_1
Definition: h8300_disas.h:76
@ H8300_MOV_DISP162R16
Definition: h8300_disas.h:94
@ H8300_BLE
Definition: h8300_disas.h:70
@ H8300_BVS
Definition: h8300_disas.h:64
@ H8300_SHL
Definition: h8300_disas.h:39
@ H8300_BRN
Definition: h8300_disas.h:56
@ H8300_BTST_R2R8
Definition: h8300_disas.h:85
@ H8300_BEQ
Definition: h8300_disas.h:62
@ H8300_DAA
Definition: h8300_disas.h:38
@ H8300_BXOR_BIXOR
Definition: h8300_disas.h:100
@ H8300_BTST
Definition: h8300_disas.h:98
@ H8300_BCLR_R2ABS8
Definition: h8300_disas.h:108
@ H8300_JSR_3
Definition: h8300_disas.h:81
@ H8300_BCLR_IMM2R8
Definition: h8300_disas.h:97
@ H8300_AND
Definition: h8300_disas.h:45
@ H8300_STC
Definition: h8300_disas.h:25
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
void * p
Definition: libc.cpp:67
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")
RzAnalysisOpMask
Definition: rz_analysis.h:439
@ RZ_ANALYSIS_OP_MASK_ESIL
Definition: rz_analysis.h:441
@ RZ_ANALYSIS_OP_TYPE_CMP
Definition: rz_analysis.h:399
@ RZ_ANALYSIS_OP_TYPE_SUB
Definition: rz_analysis.h:402
@ RZ_ANALYSIS_OP_TYPE_UNK
Definition: rz_analysis.h:388
@ RZ_ANALYSIS_OP_TYPE_MUL
Definition: rz_analysis.h:404
@ 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_CALL
Definition: rz_analysis.h:378
@ RZ_ANALYSIS_OP_TYPE_ADD
Definition: rz_analysis.h:401
@ RZ_ANALYSIS_OP_TYPE_SHR
Definition: rz_analysis.h:406
@ 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_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
@ RZ_LIB_TYPE_ANALYSIS
Definition: rz_lib.h:73
RZ_API void rz_mem_swapendian(ut8 *dest, const ut8 *orig, int size)
Definition: mem.c:202
RZ_API const char * rz_strbuf_set(RzStrBuf *sb, const char *s)
Definition: strbuf.c:153
RZ_API bool rz_strbuf_appendf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
RZ_API void rz_strbuf_init(RzStrBuf *sb)
Definition: strbuf.c:33
#define st8
Definition: rz_types_base.h:16
#define RZ_VERSION
Definition: rz_version.h:8
#define a(i)
Definition: sha256.c:41
const char * version
Definition: rz_analysis.h:1239
Definition: dis.c:32
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int addr
Definition: z80asm.c:58