Rizin
unix-like reverse engineering framework and cli tools
analysis_i4004.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2016-2020 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <string.h>
5 #include <rz_types.h>
6 #include <rz_util.h>
7 #include <rz_lib.h>
8 #include <rz_asm.h>
9 #include <rz_analysis.h>
10 
11 #define AVR_SOFTCAST(x, y) ((x) + ((y)*0x100))
12 
13 static char *get_reg_profile(RzAnalysis *analysis) {
14  const char *p =
15  "=PC PC\n"
16  /* syntax not yet supported */
17  // "=SP &PC1\n"
18  "=A0 r0\n"
19  "=A1 r1\n"
20  "=A2 r2\n"
21  "=A3 r3\n"
22  "=R0 r0\n"
23  "gpr r0 .4 0 0\n"
24  "gpr r1 .4 1 0\n"
25  "gpr r2 .4 2 0\n"
26  "gpr r3 .4 3 0\n"
27  "gpr r4 .4 4 0\n"
28  "gpr r5 .4 5 0\n"
29  "gpr r6 .4 6 0\n"
30  "gpr r7 .4 7 0\n"
31  "gpr r8 .4 8 0\n"
32  "gpr r9 .4 9 0\n"
33  "gpr r10 .4 10 0\n"
34  "gpr r11 .4 11 0\n"
35  "gpr r12 .4 12 0\n"
36  "gpr r13 .4 13 0\n"
37  "gpr r14 .4 14 0\n"
38  "gpr r15 .4 15 0\n"
39  "gpr PC .64 32 0\n"
40  /* stack */
41  "gpr PC1 .64 34 0\n"
42  "gpr PC2 .64 34 0\n"
43  "gpr PC3 .64 34 0\n";
44  return strdup(p);
45 }
46 
47 /* That 3 is a hack */
48 static const int i4004_ins_len[16] = {
49  1, 2, 3, 1, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1
50 };
51 
52 static const char *i4004_e[16] = {
53  "wrm",
54  "wmp",
55  "wrr",
56  "wpm",
57  "wr0",
58  "wr1",
59  "wr2",
60  "wr3",
61  "sbm",
62  "rdm",
63  "rdr",
64  "adm",
65  "rd0",
66  "rd1",
67  "rd2",
68  "rd3"
69 };
70 
71 static const char *i4004_f[16] = {
72  "clb",
73  "clc",
74  "iac",
75  "cmc",
76  "cma",
77  "ral",
78  "rar",
79  "tcc",
80  "dac", // decrement
81  "tcs",
82  "stc",
83  "daa",
84  "kbp",
85  "dcl",
86  "invalid",
87  "invalid"
88 };
89 
90 static int i4004_get_ins_len(ut8 hex) {
91  ut8 high = (hex & 0xf0) >> 4;
92  int ret = i4004_ins_len[high];
93  if (ret == 3) {
94  ret = (hex & 1) ? 1 : 2;
95  }
96  return ret;
97 }
98 
99 static int i4004_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, RzAnalysisOpMask mask) {
100  char basm[128];
101  const size_t basz = sizeof(basm) - 1;
102  int rlen = i4004_get_ins_len(*buf);
103  if (!op) {
104  return 2;
105  }
106  ut8 high = (*buf & 0xf0) >> 4;
107  ut8 low = (*buf & 0xf);
108  basm[0] = 0;
109 
110  if (rlen > len) {
111  return op->size = 0;
112  }
113  switch (high) {
114  case 0:
115  if (low) {
116  op->type = RZ_ANALYSIS_OP_TYPE_ILL;
117  } else {
118  op->type = RZ_ANALYSIS_OP_TYPE_NOP;
119  }
120  break;
121  case 1: // snprintf (basm, basz, "jcn %d 0x%02x", low, buf[1]); break;
123  op->jump = (addr & (~0xFF)) + buf[1];
124  op->fail = addr + rlen;
125  break;
126  case 2:
127  if (rlen == 1) {
128  snprintf(basm, basz, "scr r%d", (low & 0xe));
129  } else {
130  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
131  op->val = buf[1];
132  snprintf(basm, basz, "fim r%d, 0x%02x", (low & 0xe), buf[1]);
133  }
134  break;
135  case 3:
136  if (low & 1) {
138  } else {
139  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
140  snprintf(basm, basz, "fin r%d", (low & 0xe));
141  }
142  break;
143  case 4:
144  op->type = RZ_ANALYSIS_OP_TYPE_JMP;
145  op->jump = (ut16)(low << 8) | buf[1];
146  break;
147  case 5: // snprintf (basm, basz, "jms 0x%03x", ((ut16)(low<<8) | buf[1])); break;
149  op->jump = (ut16)(low << 8) | buf[1];
150  op->fail = addr + rlen;
151  break;
152  case 6: // snprintf (basm, basz, "inc r%d", low); break;
153  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
154  break;
155  case 7: // snprintf (basm, basz, "isz r%d, 0x%02x", low, buf[1]);
157  op->fail = (addr & (~0xFF)) + buf[1];
158  op->jump = addr + rlen;
159  break;
160  case 8:
161  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
162  // snprintf (basm, basz, "add r%d", low); break;
163  break;
164  case 9:
165  op->type = RZ_ANALYSIS_OP_TYPE_SUB;
166  // snprintf (basm, basz, "sub r%d", low); break;
167  break;
168  case 10: // snprintf (basm, basz, "ld r%d", low); break;
169  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
170  break;
171  case 11: // snprintf (basm, basz, "xch r%d", low); break;
173  break;
174  case 12: // snprintf (basm, basz, "bbl %d", low); break;
175  op->type = RZ_ANALYSIS_OP_TYPE_RET;
176  break;
177  case 13:
179  // snprintf (basm, basz, "ldm %d", low); break;
180  break;
181  case 14:
182  strncpy(basm, i4004_e[low], basz);
183  basm[basz] = '\0';
184  break;
185  case 15:
186  strncpy(basm, i4004_f[low], basz);
187  basm[basz] = '\0';
188  if (!strcmp(basm, "dac")) {
189  op->type = RZ_ANALYSIS_OP_TYPE_SUB;
190  }
191  break;
192  }
193  if (!strcmp(basm, "invalid")) {
194  op->type = RZ_ANALYSIS_OP_TYPE_ILL;
195  } else if (!strcmp(basm, "ral")) {
196  op->type = RZ_ANALYSIS_OP_TYPE_SHL;
197  } else if (!strcmp(basm, "rar")) {
198  op->type = RZ_ANALYSIS_OP_TYPE_SHR;
199  }
200  return op->size = rlen;
201 }
202 
204  .name = "i4004",
205  .desc = "i4004 code analysis plugin",
206  .license = "LGPL3",
207  .arch = "i4004",
208  .esil = false,
209  .bits = 8,
210  .op = &i4004_op,
211  .get_reg_profile = &get_reg_profile
212 };
213 
214 #ifndef RZ_PLUGIN_INCORE
217  .data = &rz_analysis_plugin_i4004,
219 };
220 #endif
size_t len
Definition: 6502dis.c:15
#define mask()
static char * get_reg_profile(RzAnalysis *analysis)
static const char * i4004_f[16]
static int i4004_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, RzAnalysisOpMask mask)
static int i4004_get_ins_len(ut8 hex)
RZ_API RzLibStruct rizin_plugin
static const char * i4004_e[16]
RzAnalysisPlugin rz_analysis_plugin_i4004
static const int i4004_ins_len[16]
#define RZ_API
uint16_t ut16
voidpf void * buf
Definition: ioapi.h:138
snprintf
Definition: kernel.h:364
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")
static const char hex[16]
Definition: print.c:21
RzAnalysisOpMask
Definition: rz_analysis.h:439
@ RZ_ANALYSIS_OP_TYPE_SUB
Definition: rz_analysis.h:402
@ RZ_ANALYSIS_OP_TYPE_LOAD
Definition: rz_analysis.h:416
@ RZ_ANALYSIS_OP_TYPE_JMP
Definition: rz_analysis.h:368
@ RZ_ANALYSIS_OP_TYPE_XCHG
Definition: rz_analysis.h:421
@ 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_RJMP
Definition: rz_analysis.h:370
@ 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_RET
Definition: rz_analysis.h:385
@ RZ_ANALYSIS_OP_TYPE_NOP
Definition: rz_analysis.h:389
@ RZ_LIB_TYPE_ANALYSIS
Definition: rz_lib.h:73
#define RZ_VERSION
Definition: rz_version.h:8
const char * version
Definition: rz_analysis.h:1239
Definition: dis.c:32
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int addr
Definition: z80asm.c:58