Rizin
unix-like reverse engineering framework and cli tools
ebc_disas.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2013-2015 Fedor Sakharov <fedor.sakharov@gmail.com>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include "ebc_disas.h"
5 #include <rz_types.h>
6 
7 #define CHK_SNPRINTF(dst, sz, fmt, ...) \
8  do { \
9  int len_chk_snprintf_ = snprintf(dst, sz, fmt, __VA_ARGS__); \
10  if (len_chk_snprintf_ >= sz) { \
11  return -1; \
12  } \
13  } while (0)
14 
15 static const char *instr_names[] = {
16  "break",
17  "jmp",
18  "jmp8",
19  "call",
20  "ret",
21  "cmp",
22  "cmp",
23  "cmp",
24  "cmp",
25  "cmp",
26  "not",
27  "neg",
28  "add",
29  "sub",
30  "mul",
31  "mulu",
32  "div",
33  "divu",
34  "mod",
35  "modu",
36  "and",
37  "or",
38  "xor",
39  "shl",
40  "shr",
41  "ashr",
42  "extndb",
43  "extndw",
44  "extndd",
45  "movbw",
46  "movww",
47  "movdw",
48  "movqw",
49  "movbd",
50  "movwd",
51  "movdd",
52  "movqd",
53  "movsnw",
54  "movsnd",
55  "",
56  "movqq",
57  "loadsp",
58  "storesp",
59  "push",
60  "pop",
61  "cmpi",
62  "cmpi",
63  "cmpi",
64  "cmpi",
65  "cmpi",
66  "movnw",
67  "movnd",
68  "",
69  "pushn",
70  "popn",
71  "movi",
72  "movin",
73  "movrel"
74 };
75 
76 /* Dedicated registers names */
77 static const char *dedic_regs[] = {
78  "FLAGS",
79  "IP",
80  "DR_RESERVED1",
81  "DR_RESERVED2",
82  "DR_RESERVED3",
83  "DR_RESERVED4",
84  "DR_RESERVED5",
85  "DR_RESERVED6"
86 };
87 
88 typedef int (*decode)(const ut8 *, ebc_command_t *cmd);
89 
90 typedef struct ebc_index {
91  enum { EBC_INDEX16,
94  enum { EBC_INDEX_PLUS = 0,
100 
101 static int decode_index16(const ut8 *data, ebc_index_t *index) {
102  ut16 tmp = *(ut16 *)data;
103  index->type = EBC_INDEX16;
104  index->sign = tmp & 0x8000 ? EBC_INDEX_PLUS : EBC_INDEX_MINUS;
105  index->a_width = ((tmp >> 12) & EBC_N_BIT_MASK(2)) * 2;
106  index->n = tmp & EBC_N_BIT_MASK(index->a_width);
107  index->c = (tmp >> index->a_width) & EBC_N_BIT_MASK(12 - index->a_width);
108  return 0;
109 }
110 
111 static int decode_index32(const ut8 *data, ebc_index_t *index) {
112  ut32 tmp = *(ut32 *)data;
113  index->type = EBC_INDEX32;
114  index->sign = tmp & EBC_NTH_BIT(31) ? EBC_INDEX_PLUS : EBC_INDEX_MINUS;
115  index->a_width = ((tmp >> 28) & EBC_N_BIT_MASK(2)) * 4;
116  index->n = tmp & EBC_N_BIT_MASK(index->a_width);
117  index->c = (tmp >> index->a_width) & EBC_N_BIT_MASK(28 - index->a_width);
118  return 0;
119 }
120 
121 static int decode_index64(const ut8 *data, ebc_index_t *index) {
122  ut64 tmp = *(ut64 *)data;
123  index->type = EBC_INDEX64;
124  index->sign = tmp & EBC_NTH_BIT(63) ? EBC_INDEX_PLUS : EBC_INDEX_MINUS;
125  index->a_width = ((tmp >> 60) & EBC_N_BIT_MASK(2)) * 8;
126  index->n = tmp & EBC_N_BIT_MASK(index->a_width);
127  index->c = (tmp >> index->a_width) & EBC_N_BIT_MASK(60 - index->a_width);
128  return 0;
129 }
130 
131 static int decode_break(const ut8 *bytes, ebc_command_t *cmd) {
133  snprintf(cmd->operands, EBC_OPERANDS_MAXLEN, "%d", bytes[1]);
134  return 2;
135 }
136 
137 // TODO: what is the difference between relative and absolute jump in disas?
138 static int decode_jmp(const ut8 *bytes, ebc_command_t *cmd) {
139  int ret;
140  int bits = 32;
141  char op1[32] = { 0 };
142  int32_t immed32;
143  ebc_index_t idx32;
144  char sign;
145  unsigned long immed;
146 
147  snprintf(cmd->instr, EBC_INSTR_MAXLEN, "%s%d%s", instr_names[EBC_JMP], bits,
148  TEST_BIT(bytes[1], 7) ? TEST_BIT(bytes[1], 6) ? "cs" : "cc" : "");
149 
150  if (TEST_BIT(bytes[0], 6)) {
151  immed = *(ut64 *)(bytes + 2);
152  ret = 10;
153  snprintf(cmd->operands, EBC_OPERANDS_MAXLEN, "0x%lx", immed);
154  } else {
155  if ((bytes[1] & 0x7) != 0) {
156  {
157  snprintf(op1, sizeof(op1), "%sr%u ",
158  TEST_BIT(bytes[1], 3) ? "@" : "", bytes[1] & 0x7);
159  }
160  }
161  if (TEST_BIT(bytes[0], 7)) {
162  if (TEST_BIT(bytes[1], 3)) {
163  decode_index32(bytes + 2, &idx32);
164  sign = idx32.sign ? '+' : '-';
165 
167  "%s(%c%u, %c%u)",
168  op1, sign, idx32.n, sign, idx32.c);
169  } else {
170  immed32 = *(int32_t *)(bytes + 2);
172  "%s0x%x", op1, immed32);
173  }
174  ret = 6;
175  } else {
176  snprintf(cmd->operands, EBC_OPERANDS_MAXLEN, "%s", op1);
177  ret = 2;
178  }
179  }
180 
181  return ret;
182 }
183 
184 static int decode_jmp8(const ut8 *bytes, ebc_command_t *cmd) {
185  char suff[3] = { 0 };
186  if (TEST_BIT(bytes[0], 7)) {
187  const char *str = (TEST_BIT(bytes[0], 6)) ? "cs" : "cc";
188  snprintf(suff, 3, "%s", str);
189  }
190  snprintf(cmd->instr, EBC_INSTR_MAXLEN, "%s%s",
191  instr_names[bytes[0] & EBC_OPCODE_MASK], suff);
192  snprintf(cmd->operands, EBC_OPERANDS_MAXLEN, "0x%x", bytes[1]);
193  return 2;
194 }
195 
196 static int decode_call(const ut8 *bytes, ebc_command_t *cmd) {
197  int ret;
198  short bits = 32;
199  ut8 op1 = bytes[1] & 0x7;
200  ut32 i1;
201  unsigned long i2;
202  ebc_index_t idx32;
203  char sign;
204 
205  if (!TEST_BIT(bytes[0], 6)) {
206  // CALL32
207  bits = 32;
208  ret = 2;
209  if (TEST_BIT(bytes[1], 3)) {
210  // operand 1 indirect
211  if (TEST_BIT(bytes[0], 7)) {
212  // immediate data is present
213  decode_index32(bytes + 2, &idx32);
214  sign = idx32.sign ? '+' : '-';
215 
217  "@r%d(%c%u, %c%u)",
218  op1, sign, idx32.n, sign, idx32.c);
219  ret = 6;
220  } else {
221  snprintf(cmd->operands, EBC_OPERANDS_MAXLEN,
222  "@r%d", op1);
223  }
224  } else {
225  // operand 1 direct
226  if (TEST_BIT(bytes[0], 7)) {
227  // immediate data present
228  i1 = *(ut32 *)(bytes + 2);
230  "r%d(0x%x)", op1, i1);
231  ret = 6;
232  } else {
233  // no immediate data present
235  "r%d", op1);
236  }
237  }
238  } else {
239  bits = 64;
240  ret = 10;
241  i2 = *(ut64 *)&bytes[2];
242  CHK_SNPRINTF(cmd->operands, EBC_OPERANDS_MAXLEN, "0x%lx", i2);
243  }
244  CHK_SNPRINTF(cmd->instr, EBC_INSTR_MAXLEN, "%s%d%s%s",
246  TEST_BIT(bytes[1], 5) ? "ex" : "",
247  TEST_BIT(bytes[1], 4) ? "" : "a");
248  return ret;
249 }
250 
251 static int decode_ret(const ut8 *bytes, ebc_command_t *cmd) {
252  int ret = 2;
254  cmd->operands[0] = '\0';
255  return ret;
256 }
257 
258 static int decode_cmp(const ut8 *bytes, ebc_command_t *cmd) {
259  int ret = 2;
260  int op1, op2;
261  char sign;
262  ut16 immed;
264 
265  op1 = bytes[1] & 0x07;
266  op2 = (bytes[1] >> 4) & 0x07;
267 
268  if (TEST_BIT(bytes[0], 7)) {
269  ret += 2;
270  if (TEST_BIT(bytes[1], 7)) {
271  decode_index16(bytes + 2, &idx);
272  sign = idx.sign ? '+' : '-';
274  "r%d, @r%d (%c%d, %c%d)",
275  op1, op2, sign, idx.n, sign, idx.c);
276  } else {
277  immed = *(ut16 *)&bytes[2];
279  "r%d, r%d %d", op1, op2, immed);
280  }
281  } else {
283  "r%d, r%d", op1, op2);
284  }
285 
286  return ret;
287 }
288 
289 static int decode_cmpeq(const ut8 *bytes, ebc_command_t *cmd) {
290  unsigned bits = TEST_BIT(bytes[0], 6) ? 64 : 32;
291  snprintf(cmd->instr, EBC_INSTR_MAXLEN, "%s%deq",
293  return decode_cmp(bytes, cmd);
294 }
295 
296 static int decode_cmplte(const ut8 *bytes, ebc_command_t *cmd) {
297  unsigned bits = TEST_BIT(bytes[0], 6) ? 64 : 32;
298  snprintf(cmd->instr, EBC_INSTR_MAXLEN, "%s%dlte",
300  return decode_cmp(bytes, cmd);
301 }
302 
303 static int decode_cmpgte(const ut8 *bytes, ebc_command_t *cmd) {
304  unsigned bits = TEST_BIT(bytes[0], 6) ? 64 : 32;
305  snprintf(cmd->instr, EBC_INSTR_MAXLEN, "%s%dgte",
307  return decode_cmp(bytes, cmd);
308 }
309 
310 static int decode_cmpulte(const ut8 *bytes, ebc_command_t *cmd) {
311  unsigned bits = TEST_BIT(bytes[0], 6) ? 64 : 32;
312  snprintf(cmd->instr, EBC_INSTR_MAXLEN, "%s%dulte",
314  return decode_cmp(bytes, cmd);
315 }
316 
317 static int decode_cmpugte(const ut8 *bytes, ebc_command_t *cmd) {
318  unsigned bits = TEST_BIT(bytes[0], 6) ? 64 : 32;
319  snprintf(cmd->instr, EBC_INSTR_MAXLEN, "%s%dugte",
321  return decode_cmp(bytes, cmd);
322 }
323 
324 static int decode_not(const ut8 *bytes, ebc_command_t *cmd) {
325  int ret = 2;
326  unsigned bits = TEST_BIT(bytes[0], 6) ? 64 : 32;
327  unsigned op1, op2;
328  char index[32] = { 0 };
329  ut16 immed;
330 
331  snprintf(cmd->instr, EBC_INSTR_MAXLEN, "%s%u", instr_names[EBC_NOT],
332  bits);
333 
334  op1 = bytes[1] & 0x07;
335  op2 = (bytes[1] >> 4) & 0x07;
336 
337  if (TEST_BIT(bytes[0], 7)) {
338  // immediate/index present
339  ret = 4;
340  if (TEST_BIT(bytes[1], 7)) {
342  decode_index16(bytes + 2, &idx);
343  snprintf(index, 32, " (%c%d, %c%d)",
344  idx.sign ? '+' : '-', idx.n,
345  idx.sign ? '+' : '-', idx.c);
346  } else {
347  immed = *(ut16 *)&bytes[2];
348  snprintf(index, 32, "(%u)", immed);
349  }
350  }
351 
352  CHK_SNPRINTF(cmd->operands, EBC_OPERANDS_MAXLEN, "%sr%d, %sr%d%s",
353  TEST_BIT(bytes[1], 3) ? "@" : "", op1,
354  TEST_BIT(bytes[1], 7) ? "@" : "", op2, index);
355  return ret;
356 }
357 
358 static int decode_neg(const ut8 *bytes, ebc_command_t *cmd) {
359  int ret = decode_not(bytes, cmd);
360  cmd->instr[1] = 'e';
361  cmd->instr[2] = 'g';
362  return ret;
363 }
364 
365 static int decode_add(const ut8 *bytes, ebc_command_t *cmd) {
366  char sign;
367  int ret = 2;
368  unsigned bits = TEST_BIT(bytes[0], 6) ? 64 : 32;
369  unsigned op1, op2;
370  char index[32] = { 0 };
371  ut16 immed;
372 
373  snprintf(cmd->instr, EBC_INSTR_MAXLEN, "%s%u", instr_names[EBC_ADD],
374  bits);
375 
376  op1 = bytes[1] & 0x07;
377  op2 = (bytes[1] >> 4) & 0x07;
378 
379  if (TEST_BIT(bytes[0], 7)) {
380  ret = 4;
381  if (TEST_BIT(bytes[1], 7)) {
383  decode_index16(bytes + 2, &idx);
384  sign = idx.sign ? '+' : '-';
385  snprintf(index, sizeof(index),
386  " (%c%d, %c%d)", sign, idx.n, sign, idx.c);
387  } else {
388  immed = *(ut16 *)&bytes[2];
389  snprintf(index, sizeof(index), "(%u)", immed);
390  }
391  }
392 
393  CHK_SNPRINTF(cmd->operands, EBC_OPERANDS_MAXLEN, "%sr%d, %sr%d%s",
394  TEST_BIT(bytes[1], 3) ? "@" : "", op1,
395  TEST_BIT(bytes[1], 7) ? "@" : "", op2, index);
396  return ret;
397 }
398 
399 static int decode_sub(const ut8 *bytes, ebc_command_t *cmd) {
400  int ret = decode_add(bytes, cmd);
401  unsigned bits = TEST_BIT(bytes[0], 6) ? 64 : 32;
402  snprintf(cmd->instr, EBC_INSTR_MAXLEN, "%s%u",
404  return ret;
405 }
406 
407 static int decode_mul(const ut8 *bytes, ebc_command_t *cmd) {
408  int ret = decode_add(bytes, cmd);
409  unsigned bits = TEST_BIT(bytes[0], 6) ? 64 : 32;
410  snprintf(cmd->instr, EBC_INSTR_MAXLEN, "%s%u",
412  return ret;
413 }
414 
415 static int decode_mulu(const ut8 *bytes, ebc_command_t *cmd) {
416  int ret = decode_add(bytes, cmd);
417  unsigned bits = TEST_BIT(bytes[0], 6) ? 64 : 32;
418 
419  snprintf(cmd->instr, EBC_INSTR_MAXLEN, "%s%u",
421  return ret;
422 }
423 
424 static int decode_div(const ut8 *bytes, ebc_command_t *cmd) {
425  int ret = decode_add(bytes, cmd);
426  unsigned bits = TEST_BIT(bytes[0], 6) ? 64 : 32;
427  snprintf(cmd->instr, EBC_INSTR_MAXLEN, "%s%u",
429  return ret;
430 }
431 
432 static int decode_divu(const ut8 *bytes, ebc_command_t *cmd) {
433  int ret = decode_add(bytes, cmd);
434  unsigned bits = TEST_BIT(bytes[0], 6) ? 64 : 32;
435  snprintf(cmd->instr, EBC_INSTR_MAXLEN, "%s%u",
437  return ret;
438 }
439 
440 static int decode_arith(const ut8 *bytes, ebc_command_t *cmd) {
441  int ret = decode_add(bytes, cmd);
442  unsigned bits = TEST_BIT(bytes[0], 6) ? 64 : 32;
443  snprintf(cmd->instr, EBC_INSTR_MAXLEN, "%s%u",
445  return ret;
446 }
447 
448 static int decode_mov_args(const ut8 *bytes, ebc_command_t *cmd) {
449  int ret = 2;
450  unsigned op1, op2;
451  char op1c[32], op2c[32];
452  char ind1[32] = { 0 }, ind2[32] = { 0 };
454  char sign;
455 
456  op1 = bytes[1] & 0x07;
457  op2 = (bytes[1] >> 4) & 0x07;
458 
459  snprintf(op1c, 32, "%sr%u", TEST_BIT(bytes[1], 3) ? "@" : "", op1);
460  snprintf(op2c, 32, "%sr%u", TEST_BIT(bytes[1], 7) ? "@" : "", op2);
461 
462  switch (bytes[0] & EBC_OPCODE_MASK) {
463  case EBC_MOVBW:
464  case EBC_MOVWW:
465  case EBC_MOVDW:
466  case EBC_MOVQW:
467  if (TEST_BIT(bytes[0], 7)) {
468  decode_index16(bytes + ret, &idx);
469  sign = idx.sign ? '+' : '-';
470  snprintf(ind1, 32, "(%c%u, %c%u)", sign,
471  idx.n, sign, idx.c);
472  ret += 2;
473  }
474  if (TEST_BIT(bytes[0], 6)) {
475  decode_index16(bytes + ret, &idx);
476  sign = idx.sign ? '+' : '-';
477  snprintf(ind2, 32, "(%c%u, %c%u)", sign,
478  idx.n, sign, idx.c);
479  ret += 2;
480  }
481  break;
482  case EBC_MOVBD:
483  case EBC_MOVWD:
484  case EBC_MOVDD:
485  case EBC_MOVQD:
486  if (TEST_BIT(bytes[0], 7)) {
487  decode_index32(bytes + ret, &idx);
488  sign = idx.sign ? '+' : '-';
489  snprintf(ind1, 32, "(%c%u, %c%u)", sign,
490  idx.n, sign, idx.c);
491  ret += 4;
492  }
493  if (TEST_BIT(bytes[0], 6)) {
494  decode_index32(bytes + ret, &idx);
495  sign = idx.sign ? '+' : '-';
496  snprintf(ind2, 32, "(%c%u, %c%u)", sign,
497  idx.n, sign, idx.c);
498  ret += 4;
499  }
500  break;
501  case EBC_MOVQQ:
502  if (TEST_BIT(bytes[0], 7)) {
503  decode_index64(bytes + ret, &idx);
504  sign = idx.sign ? '+' : '-';
505  snprintf(ind1, 32, "(%c%u, %c%u)", sign,
506  idx.n, sign, idx.c);
507  ret += 8;
508  }
509  if (TEST_BIT(bytes[0], 6)) {
510  decode_index64(bytes + ret, &idx);
511  sign = idx.sign ? '+' : '-';
512  snprintf(ind1, 32, "(%c%u, %c%u)", sign,
513  idx.n, sign, idx.c);
514  ret += 8;
515  }
516  break;
517  }
518 
519  CHK_SNPRINTF(cmd->operands, EBC_OPERANDS_MAXLEN, "%s%s, %s%s",
520  op1c, ind1, op2c, ind2);
521 
522  return ret;
523 }
524 
525 static int decode_mov(const ut8 *bytes, ebc_command_t *cmd) {
526  snprintf(cmd->instr, EBC_INSTR_MAXLEN, "%s",
528  return decode_mov_args(bytes, cmd);
529 }
530 
532  int ret = 2;
533  unsigned op1, op2;
534  char op1c[32], op2c[32], sign;
535  char ind1[32] = { 0 }, ind2[32] = { 0 };
536 
537  op1 = bytes[1] & 0x07;
538  op2 = (bytes[1] >> 4) & 0x07;
539 
540  snprintf(op1c, 32, "%sr%u", TEST_BIT(bytes[1], 3) ? "@" : "", op1);
541  snprintf(op2c, 32, "%sr%u", TEST_BIT(bytes[1], 7) ? "@" : "", op2);
542 
543  switch (bytes[0] & EBC_OPCODE_MASK) {
544  case EBC_MOVSNW:
545  if (TEST_BIT(bytes[0], 7)) {
547  ret += 2;
548  decode_index16(bytes + 2, &idx);
549  sign = idx.sign ? '+' : '-';
550  snprintf(ind1, 32, "(%c%u, %c%u)",
551  sign, idx.n, sign, idx.c);
552  }
553  if (TEST_BIT(bytes[0], 6)) {
555  decode_index16(bytes + ret, &idx);
556  sign = idx.sign ? '+' : '-';
557  snprintf(ind2, 32, "(%c%u, %c%u)",
558  sign, idx.n, sign, idx.c);
559  ret += 2;
560  }
561  break;
562  case EBC_MOVSND:
563  break;
564  }
565  CHK_SNPRINTF(cmd->operands, EBC_OPERANDS_MAXLEN, "%s%s, %s%s",
566  op1c, ind1, op2c, ind2);
567  return ret;
568 }
569 
570 static int decode_movsn(const ut8 *bytes, ebc_command_t *cmd) {
571  snprintf(cmd->instr, EBC_INSTR_MAXLEN, "%s",
573  return decode_movsn_args(bytes, cmd);
574 }
575 
576 static int decode_loadsp(const ut8 *bytes, ebc_command_t *cmd) {
577  int ret = 2;
578  snprintf(cmd->instr, EBC_INSTR_MAXLEN, "%s",
580  snprintf(cmd->operands, EBC_OPERANDS_MAXLEN, "%s, r%u",
581  dedic_regs[bytes[1] & 0x7],
582  (bytes[1] >> 4) & 0x7);
583  return ret;
584 }
585 
586 static int decode_storesp(const ut8 *bytes, ebc_command_t *cmd) {
587  int ret = 2;
588  unsigned op2 = (bytes[1] >> 4) & 0x07;
589  snprintf(cmd->instr, EBC_INSTR_MAXLEN, "%s",
591  CHK_SNPRINTF(cmd->operands, EBC_OPERANDS_MAXLEN, "r%u, %s",
592  bytes[1] & 0x7,
593  op2 < 2 ? dedic_regs[op2] : "RESERVED_DEDICATED_REG");
594  return ret;
595 }
596 
597 static int decode_push_pop(const ut8 *bytes, ebc_command_t *cmd) {
598  int ret = 2;
599  unsigned op1 = bytes[1] & 0x07;
600  char op1c[32];
601 
602  snprintf(cmd->instr, EBC_INSTR_MAXLEN, "%s%u",
604  TEST_BIT(bytes[0], 6) ? 64 : 32);
605 
606  snprintf(op1c, sizeof(op1c), "%sr%d",
607  TEST_BIT(bytes[1], 3) ? "@" : "", op1);
608 
609  if (TEST_BIT(bytes[0], 7)) {
610  ret += 2;
611  if (TEST_BIT(bytes[1], 3)) {
613  char sign;
614  decode_index16(bytes + 2, &idx);
615 
616  sign = idx.sign ? '+' : '-';
617 
618  CHK_SNPRINTF(cmd->operands, EBC_OPERANDS_MAXLEN, "%s (%c%d, %c%d)",
619  op1c, sign, idx.n, sign, idx.c);
620  } else {
621  ut16 immed = *(ut16 *)(bytes + 2);
622 
623  CHK_SNPRINTF(cmd->operands, EBC_OPERANDS_MAXLEN, "%s %u",
624  op1c, immed);
625  }
626  } else {
627  CHK_SNPRINTF(cmd->operands, EBC_OPERANDS_MAXLEN, "%s", op1c);
628  }
629 
630  return ret;
631 }
632 
633 static int decode_cmpi(const ut8 *bytes, ebc_command_t *cmd) {
634  int ret = 2;
635  unsigned op1 = bytes[1] & 0x07;
636  char op1c[32];
637  char indx[32] = { 0 };
638  char immed[32] = { 0 };
639  char *suff[] = { "eq", "lte", "gte", "ulte", "ugte" };
640 
641  snprintf(op1c, sizeof(op1c) - 1, "%sr%u",
642  TEST_BIT(bytes[1], 3) ? "@" : "", op1);
643 
644  snprintf(cmd->instr, EBC_INSTR_MAXLEN, "%s%u%c%s",
646  TEST_BIT(bytes[0], 6) ? 64 : 32,
647  TEST_BIT(bytes[0], 7) ? 'd' : 'w',
648  suff[(bytes[0] & EBC_OPCODE_MASK) - EBC_CMPIEQ]);
649 
650  if (TEST_BIT(bytes[1], 4)) {
651  char sign;
653 
654  decode_index16(bytes + 2, &idx);
655 
656  sign = idx.sign ? '+' : '-';
657 
658  snprintf(indx, sizeof(indx), " (%c%u, %c%u)", sign, idx.n, sign, idx.c);
659 
660  ret += 2;
661  }
662 
663  if (TEST_BIT(bytes[0], 7)) {
664  ut32 im = *(ut32 *)(bytes + ret);
665  snprintf(immed, sizeof(immed), "%u", im);
666  ret += 4;
667  } else {
668  ut16 im = *(ut16 *)(bytes + ret);
669  snprintf(immed, sizeof(immed), "%u", im);
670  ret += 2;
671  }
672 
673  CHK_SNPRINTF(cmd->operands, EBC_OPERANDS_MAXLEN, "%s%s, %s", op1c, indx, immed);
674  return ret;
675 }
676 
677 static int decode_movn(const ut8 *bytes, ebc_command_t *cmd) {
678  int ret = 2;
679  unsigned op1 = bytes[1] & 0x07;
680  unsigned op2 = (bytes[1] >> 4) & 0x07;
681  char op1c[32], op2c[32];
682  char indx1[32] = { 0 };
683  char indx2[32] = { 0 };
684  char sign;
686 
687  snprintf(cmd->instr, EBC_INSTR_MAXLEN, "%s",
689 
690  snprintf(op1c, 32, "%sr%u", TEST_BIT(bytes[1], 3) ? "@" : "", op1);
691  snprintf(op2c, 32, "%sr%u", TEST_BIT(bytes[1], 7) ? "@" : "", op2);
692 
693  if ((bytes[0] & EBC_OPCODE_MASK) == EBC_MOVNW) {
694  if (TEST_BIT(bytes[0], 7)) {
695  decode_index16(bytes + ret, &idx);
696  sign = idx.sign ? '+' : '-';
697  snprintf(indx1, 32, "(%c%u, %c%u)", sign, idx.n, sign, idx.c);
698  ret += 2;
699  }
700  if (TEST_BIT(bytes[0], 6)) {
701  decode_index16(bytes + ret, &idx);
702  sign = idx.sign ? '+' : '-';
703  snprintf(indx2, 32, "(%c%u, %c%u)", sign, idx.n, sign, idx.c);
704  ret += 2;
705  }
706  } else {
707  if (TEST_BIT(bytes[0], 7)) {
708  decode_index32(bytes + ret, &idx);
709  sign = idx.sign ? '+' : '-';
710  snprintf(indx1, 32, "(%c%u, %c%u)", sign, idx.n, sign, idx.c);
711  ret += 4;
712  }
713  if (TEST_BIT(bytes[0], 6)) {
714  decode_index32(bytes + ret, &idx);
715  sign = idx.sign ? '+' : '-';
716  snprintf(indx2, 32, "(%c%u, %c%u)", sign, idx.n, sign, idx.c);
717  ret += 4;
718  }
719  }
720 
721  CHK_SNPRINTF(cmd->operands, EBC_OPERANDS_MAXLEN, "%s%s, %s%s", op1c, indx1, op2c, indx2);
722  return ret;
723 }
724 
725 static int decode_movi(const ut8 *bytes, ebc_command_t *cmd) {
726  int ret = 2;
727  char p1 = 0, p2 = 0;
728  char indx[32] = { 0 };
729  char op1[32];
730  unsigned long immed = 0;
731 
732  switch (bytes[0] >> 6) {
733  case 0: ret = -1; break;
734  case 1: p2 = 'w'; break;
735  case 2: p2 = 'd'; break;
736  case 3: p2 = 'q'; break;
737  }
738 
739  if (ret < 0) {
740  return ret;
741  }
742 
743  switch ((bytes[1] >> 4) & 0x3) {
744  case 0: p1 = 'b'; break;
745  case 1: p1 = 'w'; break;
746  case 2: p1 = 'd'; break;
747  case 3: p1 = 'q'; break;
748  }
749 
750  snprintf(cmd->instr, EBC_INSTR_MAXLEN, "%s%c%c",
751  instr_names[bytes[0] & EBC_OPCODE_MASK], p1, p2);
752 
753  if (TEST_BIT(bytes[1], 6)) {
754  char sign;
756 
757  decode_index16(bytes + 2, &idx);
758  sign = idx.sign ? '+' : '-';
759 
760  snprintf(indx, 32, "(%c%u, %c%u)", sign, idx.n, sign, idx.c);
761 
762  ret += 2;
763  }
764 
765  switch (p2) {
766  ut16 i1;
767  ut32 i2;
768  ut64 i3;
769  case 'w':
770  i1 = *(ut16 *)(bytes + ret);
771  immed = (unsigned long)i1;
772  ret += 2;
773  break;
774  case 'd':
775  i2 = *(ut32 *)(bytes + ret);
776  immed = (unsigned long)i2;
777  ret += 4;
778  break;
779  case 'q':
780  i3 = *(ut64 *)(bytes + ret);
781  immed = i3;
782  ret += 8;
783  break;
784  }
785 
786  snprintf(op1, 32, "%sr%u", TEST_BIT(bytes[1], 3) ? "@" : "", bytes[1] & 0x7);
787  CHK_SNPRINTF(cmd->operands, EBC_OPERANDS_MAXLEN, "%s%s, %lu", op1, indx, immed);
788  return ret;
789 }
790 
791 static int decode_movin(const ut8 *bytes, ebc_command_t *cmd) {
792  int ret = 2;
793  char p1 = 0;
794  char indx1[32] = { 0 };
795  char indx2[32] = { 0 };
796  char op1[32];
797  char sign;
798  ebc_index_t idx = { 0 };
799 
800  switch (bytes[0] >> 6) {
801  case 0: ret = -1; break;
802  case 1: p1 = 'w'; break;
803  case 2: p1 = 'd'; break;
804  case 3: p1 = 'q'; break;
805  }
806 
807  if (ret < 0) {
808  return ret;
809  }
810 
811  snprintf(cmd->instr, EBC_INSTR_MAXLEN, "%s%c",
812  instr_names[bytes[0] & EBC_OPCODE_MASK], p1);
813 
814  if (TEST_BIT(bytes[1], 6)) {
815  decode_index16(bytes + 2, &idx);
816 
817  sign = idx.sign ? '+' : '-';
818 
819  snprintf(indx1, 32, "(%c%u, %c%u)", sign,
820  idx.n, sign, idx.c);
821 
822  ret += 2;
823  }
824 
825  switch (p1) {
826  case 'w':
827  decode_index16(bytes + ret, &idx);
828  ret += 2;
829  break;
830  case 'd':
831  decode_index32(bytes + ret, &idx);
832  ret += 4;
833  break;
834  case 'q':
835  decode_index64(bytes + ret, &idx);
836  ret += 8;
837  break;
838  }
839 
840  sign = idx.sign ? '+' : '-';
841 
842  snprintf(indx2, 32, "(%c%u, %c%u)", sign, idx.n, sign, idx.c);
843 
844  snprintf(op1, 32, "%sr%u", TEST_BIT(bytes[1], 3) ? "@" : "", bytes[1] & 0x7);
845  CHK_SNPRINTF(cmd->operands, EBC_OPERANDS_MAXLEN, "%s%s, %s", op1, indx1, indx2);
846  return ret;
847 }
848 
849 static int decode_movrel(const ut8 *bytes, ebc_command_t *cmd) {
850  int ret = 2;
851  char p1 = 0;
852  char op1[32];
853  char indx[32] = { 0 };
854  unsigned long immed = 0;
855  unsigned formathex = 0;
856 
857  switch (bytes[0] >> 6) {
858  case 0:
859  ret = -1;
860  break;
861  case 1:
862  p1 = 'w';
863  formathex = 4;
864  break;
865  case 2:
866  p1 = 'd';
867  formathex = 8;
868  break;
869  case 3:
870  p1 = 'q';
871  formathex = 16;
872  break;
873  }
874 
875  if (ret < 0) {
876  return ret;
877  }
878 
879  snprintf(cmd->instr, EBC_INSTR_MAXLEN, "%s%c",
880  instr_names[bytes[0] & EBC_OPCODE_MASK], p1);
881  snprintf(op1, 32, "%sr%u", TEST_BIT(bytes[1], 3) ? "@" : "", bytes[1] & 0x7);
882 
883  if (TEST_BIT(bytes[1], 6)) {
885  char sign;
886 
887  decode_index16(bytes + 2, &idx);
888  sign = idx.sign ? '+' : '-';
889 
890  snprintf(indx, 32, "(%c%u, %c%u)", sign, idx.n, sign, idx.c);
891 
892  ret += 2;
893  }
894 
895  ut16 v16;
896  ut32 v32;
897  ut64 v64;
898  switch (p1) {
899  case 'w':
900  v16 = *(ut16 *)(bytes + 2);
901  immed = v16;
902  ret += 2;
903  break;
904  case 'd':
905  v32 = *(ut32 *)(bytes + 2);
906  immed = v32;
907  ret += 4;
908  break;
909  case 'q':
910  v64 = *(ut64 *)(bytes + 2);
911  immed = v64;
912  ret += 8;
913  break;
914  }
915 
916  CHK_SNPRINTF(cmd->operands, EBC_OPERANDS_MAXLEN, "%s%s, 0x%0*lx",
917  op1, indx, formathex, immed);
918  return ret;
919 }
920 
921 static int decode_invalid(const ut8 *bytes, ebc_command_t *cmd) {
922  return -1;
923 }
924 
926  decode_break,
927  decode_jmp,
928  decode_jmp8,
929  decode_call,
930  decode_ret,
931  decode_cmpeq,
936  decode_not,
937  decode_neg,
938  decode_add,
939  decode_sub,
940  decode_mul,
941  decode_mulu,
942  decode_div,
943  decode_divu,
944  decode_arith,
945  decode_arith,
946  decode_arith,
947  decode_arith,
948  decode_arith,
949  decode_arith,
950  decode_arith,
951  decode_arith,
952  decode_arith,
953  decode_arith,
954  decode_arith,
955  decode_mov,
956  decode_mov,
957  decode_mov,
958  decode_mov,
959  decode_mov,
960  decode_mov,
961  decode_mov,
962  decode_mov,
963  decode_movsn,
964  decode_movsn,
966  decode_mov,
971  decode_cmpi,
972  decode_cmpi,
973  decode_cmpi,
974  decode_cmpi,
975  decode_cmpi,
976  decode_movn,
977  decode_movn,
981  decode_movi,
982  decode_movin,
984 };
985 
987  if ((instr[0] & EBC_OPCODE_MASK) > 0x39) {
988  {
989  return -1;
990  }
991  }
992  return decodes[instr[0] & EBC_OPCODE_MASK](instr, cmd);
993 }
static ut8 bytes[32]
Definition: asm_arc.c:23
int bits(struct state *s, int need)
Definition: blast.c:72
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
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 long
Definition: sflib.h:79
uint16_t ut16
uint32_t ut32
static int decode_sub(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:399
static int decode_movrel(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:849
static int decode_cmpulte(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:310
static int decode_break(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:131
static int decode_jmp(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:138
static int decode_call(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:196
static int decode_cmpugte(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:317
static int decode_storesp(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:586
static int decode_index64(const ut8 *data, ebc_index_t *index)
Definition: ebc_disas.c:121
static int decode_div(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:424
struct ebc_index ebc_index_t
static int decode_mov_args(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:448
static int decode_cmpgte(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:303
static const char * dedic_regs[]
Definition: ebc_disas.c:77
static int decode_movi(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:725
static int decode_jmp8(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:184
static int decode_movsn(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:570
#define CHK_SNPRINTF(dst, sz, fmt,...)
Definition: ebc_disas.c:7
static int decode_movin(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:791
static int decode_cmplte(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:296
static int decode_mov(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:525
static int decode_mulu(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:415
static int decode_add(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:365
static int decode_cmpeq(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:289
static int decode_neg(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:358
static int decode_movn(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:677
static const char * instr_names[]
Definition: ebc_disas.c:15
static int decode_mul(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:407
static int decode_index32(const ut8 *data, ebc_index_t *index)
Definition: ebc_disas.c:111
static int decode_push_pop(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:597
static int decode_index16(const ut8 *data, ebc_index_t *index)
Definition: ebc_disas.c:101
int ebc_decode_command(const ut8 *instr, ebc_command_t *cmd)
Definition: ebc_disas.c:986
static int decode_ret(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:251
static int decode_cmp(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:258
static int decode_divu(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:432
int(* decode)(const ut8 *, ebc_command_t *cmd)
Definition: ebc_disas.c:88
static int decode_arith(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:440
static int decode_not(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:324
static int decode_cmpi(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:633
static int decode_movsn_args(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:531
static int decode_invalid(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:921
static int decode_loadsp(const ut8 *bytes, ebc_command_t *cmd)
Definition: ebc_disas.c:576
static decode decodes[EBC_COMMAND_NUM]
Definition: ebc_disas.c:925
#define EBC_N_BIT_MASK(n)
Definition: ebc_disas.h:24
#define EBC_OPCODE_MASK
Definition: ebc_disas.h:9
#define EBC_INSTR_MAXLEN
Definition: ebc_disas.h:20
#define EBC_OPERANDS_MAXLEN
Definition: ebc_disas.h:21
@ EBC_NOT
Definition: ebc_disas.h:40
@ EBC_ADD
Definition: ebc_disas.h:42
@ EBC_MOVDD
Definition: ebc_disas.h:65
@ EBC_MUL
Definition: ebc_disas.h:44
@ EBC_MULU
Definition: ebc_disas.h:45
@ EBC_DIV
Definition: ebc_disas.h:46
@ EBC_SUB
Definition: ebc_disas.h:43
@ EBC_CMPULTE
Definition: ebc_disas.h:38
@ EBC_MOVDW
Definition: ebc_disas.h:61
@ EBC_COMMAND_NUM
Definition: ebc_disas.h:88
@ EBC_CMPLTE
Definition: ebc_disas.h:36
@ EBC_RET
Definition: ebc_disas.h:34
@ EBC_CALL
Definition: ebc_disas.h:33
@ EBC_MOVQQ
Definition: ebc_disas.h:70
@ EBC_MOVQW
Definition: ebc_disas.h:62
@ EBC_MOVQD
Definition: ebc_disas.h:66
@ EBC_CMPGTE
Definition: ebc_disas.h:37
@ EBC_MOVSNW
Definition: ebc_disas.h:67
@ EBC_DIVU
Definition: ebc_disas.h:47
@ EBC_CMPUGTE
Definition: ebc_disas.h:39
@ EBC_JMP
Definition: ebc_disas.h:31
@ EBC_MOVWW
Definition: ebc_disas.h:60
@ EBC_MOVBW
Definition: ebc_disas.h:59
@ EBC_BREAK
Definition: ebc_disas.h:30
@ EBC_MOVSND
Definition: ebc_disas.h:68
@ EBC_MOVBD
Definition: ebc_disas.h:63
@ EBC_MOVWD
Definition: ebc_disas.h:64
@ EBC_CMPIEQ
Definition: ebc_disas.h:75
@ EBC_MOVNW
Definition: ebc_disas.h:80
#define TEST_BIT(x, n)
Definition: ebc_disas.h:27
#define EBC_NTH_BIT(n)
Definition: ebc_disas.h:23
snprintf
Definition: kernel.h:364
uint8_t ut8
Definition: lh5801.h:11
int idx
Definition: setup.py:197
static int
Definition: sfsocketcall.h:114
int int32_t
Definition: sftypes.h:33
ut32 c
Definition: ebc_disas.c:97
enum ebc_index::@64 type
@ EBC_INDEX_MINUS
Definition: ebc_disas.c:95
@ EBC_INDEX_PLUS
Definition: ebc_disas.c:94
ut8 a_width
Definition: ebc_disas.c:96
@ EBC_INDEX64
Definition: ebc_disas.c:93
@ EBC_INDEX16
Definition: ebc_disas.c:91
@ EBC_INDEX32
Definition: ebc_disas.c:92
enum ebc_index::@65 sign
ut32 n
Definition: ebc_disas.c:98
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int indx(const char **ptr, const char **list, int error, const char **expr)
Definition: z80asm.c:154