Rizin
unix-like reverse engineering framework and cli tools
c55plus_decode.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2013-2021 th0rpe <josediazfer@yahoo.es>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <stdio.h>
5 #include <string.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <rz_types.h>
9 #include <rz_util.h>
10 
11 #include "ins.h"
12 #include "decode.h"
13 #include "utils.h"
14 #include "hashtable.h"
15 #include "decode_funcs.h"
16 
17 extern char *ins_str[];
18 extern ut32 ins_buff_len;
19 
20 static ut32 get_q_bits(ut32 val, char *ins, ut32 ins_len, int *err_code) {
21  ut32 res = 0;
22 
23  if (!rz_str_ncasecmp(ins, "q_MMAP", 6)) {
24  res = val & 1;
25  } else if (!rz_str_ncasecmp(ins, "q_LOCK", 6)) {
26  res = val & 1;
27  } else if (!rz_str_ncasecmp(ins, "q_LINR", 6)) {
28  res = (val >> 2) & 1;
29  } else if (!rz_str_ncasecmp(ins, "q_CIRC", 6)) {
30  res = (val >> 3) & 1;
31  } else if (!rz_str_ncasecmp(ins, "q_PORT_READ", 11)) {
32  res = (val >> 4) & 1;
33  } else if (!rz_str_ncasecmp(ins, "q_PORT_WRITE", 12)) {
34  res = (val >> 5) & 1;
35  } else if (!rz_str_ncasecmp(ins, "q_XPORT_READ", 12)) {
36  res = (val >> 6) & 1;
37  } else if (!rz_str_ncasecmp(ins, "q_XPORT_WRITE", 13)) {
38  res = (val >> 7) & 1;
39  } else if (!rz_str_ncasecmp(ins, "q_SAT", 5)) {
40  res = (val >> 8) & 1;
41  } else if (!rz_str_ncasecmp(ins, "q_XC0", 5)) {
42  res = (val >> 9) & 1;
43  } else if (!rz_str_ncasecmp(ins, "q_XC1", 5)) {
44  res = (val >> 10) & 1;
45  } else {
46  /* INVALID CONDITION */
47  fprintf(stderr, "Invalid token %s\n", ins);
48  *err_code = -1;
49  }
50  return res;
51 }
52 
53 /*
54  a2 = 0x223;
55  0x800 = valor que se crea en sub_40BAE0<) con and 0xfffff800
56 */
57 static ut32 get_ins_bits(ut32 hash_code, ut32 ins_pos, char *ins,
58  ut32 ins_len, ut32 magic_value, int *err_code) {
59  ut32 res = 0;
60  ut8 op_b;
61  ut32 len, x, i;
62  char *op_str, *aux;
63 
64  if (ins[0] == 'q') {
65  return get_q_bits(magic_value, ins, ins_len, err_code);
66  }
67 
68  op_str = ins_str[1 + hash_code * 4];
69  // printf("OPSTR => %s %d\n", ins, ins_len);
70 
71  x = 0;
72  for (i = 0; i < ins_len; i++) {
73  aux = strchr(&op_str[x], ins[i]);
74  if (!aux) {
75  aux = strchr(op_str, ins[i]);
76  if (!aux) {
77  fprintf(stderr, "Invalid token %s\n", ins);
78  *err_code = -1;
79  return 0;
80  }
81  }
82 
83  len = (unsigned int)(aux - op_str);
84  // printf("INS_POS: %d POS: %d\n", ins_pos, len / 8);
85  op_b = get_ins_part(ins_pos + len / 8, 1);
86  // printf("OPP: %x\n", op_b);
87 
88  x = len + 1;
89  res = (res * 2) | ((op_b >> ((1023 - len) % 8)) & 1);
90  if (!op_str[x]) {
91  x = 0;
92  }
93  }
94 
95  if (C55PLUS_DEBUG) {
96  printf("INS_BITS => 0x%x\n", res);
97  getchar();
98  }
99 
100  return res;
101 }
102 
103 static bool check_arg(ut32 ins_bits, int *err_code) {
104  bool res = false;
105 
106  if ((ins_bits <= 31) | (ins_bits >= 128 && ins_bits < 160)) {
107  res = true;
108  } else if (ins_bits >= 32 && ins_bits <= 252) {
109  res = false;
110  } else {
111  fprintf(stderr, "Invalid arg: %u\n", ins_bits);
112  *err_code = -1;
113  }
114 
115  return res;
116 }
117 
118 static char *decode_regis(char *reg_arg, st32 hash_code, ut32 ins_bits,
119  ut32 *ret_ins_bits, int *err_code) {
120  char reg_type;
121  char *res;
122 
123  reg_type = *reg_arg;
124  res = NULL;
125 
126  // printf("REG_TYPE %d %d\n", reg_type, ins_bits);
127 
128  switch (reg_type) {
129  case 33:
130  res = get_reg_name_1((ins_bits >> 1) |
131  ((ins_bits & 1) << 6));
132  break;
133  case 100:
134  if (rz_str_ncasecmp(reg_arg, "d(ALLx", 6)) {
135  fprintf(stderr, "invalid register! %s\n", reg_arg);
136  *err_code = -1;
137  return NULL;
138  }
139  res = (check_arg(ins_bits, err_code) != 0 && *err_code == 0) ? strdup("dbl(") : NULL;
140  if (*err_code < 0) {
141  return NULL;
142  }
143  break;
144  case 41:
145  if (rz_str_ncasecmp(reg_arg, ")ALLx", 5)) {
146  fprintf(stderr, "invalid register! %s\n", reg_arg);
147  *err_code = -1;
148  return NULL;
149  }
150  res = (check_arg(ins_bits, err_code) && *err_code == 0) ? strdup(")") : NULL;
151  if (*err_code < 0) {
152  return NULL;
153  }
154  break;
155  case 65:
156  if (!rz_str_ncasecmp(reg_arg, "ACLH", 4)) {
157  res = get_reg_name_1(ins_bits + 64);
158  } else if (!rz_str_ncasecmp(reg_arg, "ACxP", 4)) {
159  res = get_reg_name_1(ins_bits + 1);
160  } else if (!rz_str_ncasecmp(reg_arg, "ACx", 3) ||
161  !rz_str_ncasecmp(reg_arg, "ADR", 3) ||
162  !rz_str_ncasecmp(reg_arg, "ALL", 3) /* 430ADC */
163  ) {
164  res = get_reg_name_1(ins_bits);
165  }
166  if (hash_code == 0xDF || hash_code == 0xE0) {
167  *ret_ins_bits = ins_bits;
168  }
169  break;
170  case 68:
171  res = get_reg_name_1(ins_bits + 32);
172  break;
173  case 77:
174  if (!rz_str_ncasecmp(reg_arg, "MA", 2) || !rz_str_ncasecmp(reg_arg, "MR", 2)) {
175  res = get_reg_name_1(ins_bits);
176  } else {
177  res = get_reg_name_2(ins_bits);
178  }
179  break;
180  case 83:
181  res = get_reg_name_1(ins_bits);
182  break;
183  case 82:
184  if (!rz_str_ncasecmp(reg_arg, "RA", 2) || !rz_str_ncasecmp(reg_arg, "RL", 2)) {
185  res = get_reg_name_1(ins_bits);
186  } else if (!rz_str_ncasecmp(reg_arg, "RLP", 3) || !rz_str_ncasecmp(reg_arg, "RxP", 3)) {
187  res = get_reg_name_1(ins_bits + 1);
188  } else if (!rz_str_ncasecmp(reg_arg, "RX", 2)) {
189  res = get_reg_name_1(ins_bits);
190  } else {
191  res = get_reg_name_2(ins_bits);
192  }
193  break;
194  case 84:
195  res = get_reg_name_1(ins_bits + 48);
196  break;
197  case 87:
198  if (!rz_str_ncasecmp(reg_arg, "WD", 2)) {
199  res = get_reg_name_2(ins_bits);
200  } else if (!rz_str_ncasecmp(reg_arg, "WA", 2)) {
201  res = get_reg_name_1(ins_bits);
202  } else {
203  res = NULL;
204  }
205  break;
206  case 88:
207  if (!rz_str_ncasecmp(reg_arg, "XR", 2)) {
208  res = get_reg_name_3(ins_bits);
209  } else if (!rz_str_ncasecmp(reg_arg, "XD", 2)) {
210  res = get_reg_name_2(ins_bits + 32);
211  } else {
212  res = NULL;
213  }
214  break;
215  default:
216  res = NULL;
217  break;
218  }
219 
220  return res;
221 }
222 
223 static char *decode_ins(st32 hash_code, ut32 ins_pos, ut32 ins_off, ut32 *ins_len_dec,
224  ut32 *reg_len_dec, ut32 *ret_ins_bits, ut32 magic_value, ut8 two_ins, int *err_code) {
225  ut32 ins_len;
226  char *ins, *pos;
227  char token_aux[80];
228  ut32 i, len;
229  char *reg = NULL;
230  char *res_decode = NULL;
231  char *aux = NULL;
232 
233  // get instruction length
234  ins_len = get_ins_len(get_ins_part(ins_pos + ins_off, 1));
235  // get pseudo instruction
236  ins = ins_str[1 + 2 + hash_code * 4];
237  if (!ins /*|| ins_str[4 * hash_code] == 0*/) {
238  fprintf(stderr, "Invalid instruction hash %x\n", hash_code);
239  *err_code = -1;
240  return NULL;
241  }
242  if (hash_code == 0x19C) {
243  res_decode = get_token_decoded(hash_code, "MMMMxxxxmm", 10, NULL, ret_ins_bits,
244  reg_len_dec, magic_value, ins_pos + ins_off, ins_len, two_ins, err_code);
245  if (*err_code < 0) {
246  return NULL;
247  }
248  }
249 
250  if (C55PLUS_DEBUG) {
251  printf("PSEUDO INS %s\n", ins);
252  }
253 
254  pos = ins;
255  // instruction length
256  *ins_len_dec = ins_len;
257 
258  while (*pos) {
259  if (*pos == '`') {
260  pos++;
261  aux = strchr(pos, '`');
262  if (!aux || pos == aux) {
263  fprintf(stderr, "Invalid instruction %s\n", ins);
264  free(res_decode);
265  *err_code = -1;
266  return NULL;
267  }
268  len = (ut32)(size_t)(aux - pos);
269  if (len >= 80) {
270  fprintf(stderr, "Invalid length token %d\n", len);
271  free(res_decode);
272  *err_code = -1;
273  return NULL;
274  }
275 
276  memcpy(token_aux, pos, len);
277  token_aux[len] = '\0';
278  pos = aux;
279 
280  if (C55PLUS_DEBUG) {
281  printf("TOKEN AUX: %s\n", token_aux);
282  }
283 
284  reg = NULL;
285  for (i = 0; i < len; i++) {
286  if (token_aux[i] == ',') {
287  len = (unsigned int)(size_t)(&token_aux[i] - token_aux);
288  reg = &token_aux[i + 1];
289 
290  if (C55PLUS_DEBUG) {
291  printf("REG : %s\n", reg);
292  }
293  break;
294  }
295  }
296 
297  aux = get_token_decoded(hash_code, token_aux, len, reg, ret_ins_bits,
298  reg_len_dec, magic_value, ins_pos + ins_off, ins_len, two_ins, err_code);
299  if (*err_code < 0) {
300  return NULL;
301  }
302  res_decode = strcat_dup(res_decode, aux, 3);
303  if (C55PLUS_DEBUG) {
304  printf("RET TOKEN %s\n", res_decode);
305  }
306  } else {
307  token_aux[0] = *pos;
308  token_aux[1] = '\0';
309  res_decode = strcat_dup(res_decode, token_aux, 1);
310  }
311  pos++;
312  }
313 
314  if (C55PLUS_DEBUG) {
315  printf("RESULT DECODE: %s\n", res_decode);
316  }
317 
318  return res_decode;
319 }
320 
321 static bool is_hash(st32 hash_code) {
322  bool ret;
323 
324  switch (hash_code) {
325  case 0xE8:
326  case 0xE9:
327  case 0xEA:
328  case 0xEC:
329  case 0x1A8:
330  case 0x1DC:
331  case 0x1E1:
332  case 0x1E2:
333  case 0x1E3:
334  case 0x1E4:
335  ret = 1;
336  break;
337  default:
338  ret = 0;
339  }
340 
341  return ret;
342 }
343 
344 void set_magic_value(ut32 *magic_value, st32 hash_code, int *err_code) {
345  switch (hash_code) {
346  case 232:
347  *magic_value |= 1;
348  break;
349  case 424:
350  *magic_value |= 2;
351  break;
352  case 236:
353  *magic_value |= 4;
354  break;
355  case 233:
356  *magic_value |= 0x10;
357  break;
358  case 234:
359  *magic_value |= 0x20;
360  break;
361  case 483:
362  *magic_value |= 0x40;
363  break;
364  case 484:
365  *magic_value |= 0x80;
366  break;
367  case 476:
368  *magic_value |= 0x100;
369  break;
370  case 481:
371  *magic_value |= 0x200;
372  break;
373  case 482:
374  *magic_value |= 0x400;
375  break;
376  default:
377  fprintf(stderr, "invalid hash code 0x%x for magic value 0x%x\n", hash_code, *magic_value);
378  *err_code = -1;
379  }
380 }
381 
382 static char *do_decode(ut32 ins_off, ut32 ins_pos, ut32 two_ins, ut32 *next_ins_pos,
383  st32 *ins_hash_code, int *err_code) {
384  st32 hash_code, hash_aux;
385  ut32 reg_len_dec, ins_len_dec, ret_ins_bits;
386  char *ins_res = NULL, *ins_aux = NULL;
387  ut32 magic_value = 0x800;
388 
389  *next_ins_pos = 0;
390 
391  reg_len_dec = 0;
392  ret_ins_bits = 0;
393  ins_len_dec = 0;
394 
395  hash_code = get_hash_code(ins_pos + ins_off);
396  if (is_hash(hash_code)) {
397  hash_aux = hash_code;
398  ins_off++;
399  set_magic_value(&magic_value, hash_code, err_code);
400  if (*err_code < 0) {
401  return NULL;
402  }
403  hash_code = get_hash_code(ins_pos + ins_off);
404  *next_ins_pos = 1;
405  } else {
406  hash_aux = 0x223;
407  }
408 
409  if (ins_hash_code != NULL) {
410  *ins_hash_code = hash_code;
411  }
412 
413  if (C55PLUS_DEBUG) {
414  printf("MAGIC VALUE 0x%x\n", 0x800);
415  }
416 
417  if (hash_aux == 0x1E1 || hash_aux == 0x1E2) {
418  ins_aux = decode_ins(hash_aux, ins_pos, ins_off, &ins_len_dec, &reg_len_dec,
419  &ret_ins_bits, magic_value, two_ins, err_code);
420  if (*err_code < 0) {
421  return NULL;
422  }
423  ins_aux = strcat_dup(ins_aux, " ", 1);
424  }
425 
426  if (hash_code == 0x223) {
427  ins_res = strcat_dup(ins_aux, ".byte 0x", 1);
428  ins_aux = get_hex_str(get_ins_part(ins_pos, 1));
429  ins_res = strcat_dup(ins_res, ins_aux, 2);
430  *next_ins_pos = *next_ins_pos + 1;
431  } else {
432  free(ins_aux);
433  ins_aux = decode_ins(hash_code, ins_pos, ins_off, &ins_len_dec,
434  &reg_len_dec, &ret_ins_bits, magic_value, two_ins, err_code);
435  if (*err_code < 0) {
436  free(ins_aux);
437  return NULL;
438  }
439  ins_res = strcat_dup(ins_aux, ins_res, 1);
440  // printf("NEXT POS %d %d\n", ins_len_dec, reg_len_dec);
441  // getchar();
442  *next_ins_pos += ins_len_dec; // reg_len_dec;
443  }
444 
445  return ins_res;
446 }
447 
448 char *c55plus_decode(ut32 ins_pos, ut32 *next_ins_pos) {
449  ut8 opcode, two_ins = 0;
450  ut32 next_ins1_pos, next_ins2_pos;
451  st32 hash_code;
452  char *ins1, *ins2, *aux, *ins_res;
453  int err_code;
454 
455  if (ins_pos >= ins_buff_len) {
456  return NULL;
457  }
458  ins_res = NULL;
459  err_code = 0;
460 
461  opcode = get_ins_part(ins_pos, 1);
462  if ((opcode & 0xF0) == 0x30) {
463  two_ins = opcode & 0x0F;
464  if (two_ins < 4) {
465  two_ins += 0xF;
466  }
467  } else {
468  two_ins = 0;
469  }
470 
471  // two instruction execution?
472  if (two_ins) {
473  ins1 = do_decode(1, ins_pos, two_ins, &next_ins1_pos, &hash_code, &err_code);
474  if (err_code < 0) {
475  free(ins1);
476  return NULL;
477  }
478  ins2 = do_decode(next_ins1_pos + 1, ins_pos, two_ins, &next_ins2_pos, NULL, &err_code);
479  if (err_code < 0) {
480  free(ins1);
481  free(ins2);
482  return NULL;
483  }
484  *next_ins_pos = next_ins2_pos;
485 
486  if (hash_code == 0xF0 || hash_code == 0xF1) {
487  aux = strcat_dup(ins2, " || ", 1);
488  ins_res = strcat_dup(aux, ins1, 1);
489  free(ins1);
490  } else {
491  aux = strcat_dup(ins1, " || ", 1);
492  ins_res = strcat_dup(aux, ins2, 1);
493  free(ins2);
494  }
495  *next_ins_pos = next_ins1_pos + next_ins2_pos + 1;
496  if (*next_ins_pos != two_ins) {
497  // ins_res = strcat_dup(ins_res, " P-tag problem", 1);
498  err_code = -1;
499  free(ins_res);
500  return NULL;
501  }
502  } else {
503  ins_res = do_decode(0, ins_pos, two_ins, &next_ins1_pos, &hash_code, &err_code);
504  if (err_code < 0) {
505  free(ins_res);
506  return NULL;
507  }
508  *next_ins_pos = next_ins1_pos;
509  }
510 
511  return ins_res;
512 }
513 
514 static bool is_linear_circular(ut32 ins_bits) {
515  ut8 op, op2, op3;
516  op = (ins_bits >> 6) | 16 * (ins_bits & 3);
517  op2 = (ins_bits >> 2) & 0xF;
518  op3 = op2 & 0xF;
519  return (op == 26 || op == 30 || (op3 > 7 && op3 != 15));
520 }
521 
522 static char *get_token_decoded(st32 hash_code, char *ins_token, ut32 ins_token_len,
523  char *reg_arg, ut32 *ret_ins_bits, ut32 *ret_reg_len, ut32 magic_value,
524  ut32 ins_pos, ut32 ins_len, ut8 two_ins, int *err_code) {
525  ut32 tok_op, ins_bits;
526  char *res = NULL;
527  char buff_aux[512];
528  char *aux = NULL;
529  ut32 ret_len = 0, flag;
530 
531  *ret_ins_bits = 0;
532  *ret_reg_len = 0;
533 
534  ins_bits = get_ins_bits(hash_code, ins_pos, ins_token, ins_token_len, magic_value, err_code);
535  if (*err_code < 0) {
536  return NULL;
537  }
538  tok_op = *ins_token - 0x23;
539 
540  if (C55PLUS_DEBUG) {
541  printf("WAY ins_bits: OP = %d 0x%x %s %d %d\n", tok_op, ins_bits, ins_token, ins_token_len, ins_pos);
542  getchar();
543  }
544 
545  switch (tok_op) {
546  case 30:
547  case 31:
548  case 32:
549  case 33:
550  case 43:
551  case 62:
552  case 63:
553  case 64:
554  case 65:
555  if (!reg_arg || *reg_arg == '\0') {
556  res = strdup("<register>");
557  goto ret_decode;
558  }
559  res = decode_regis(reg_arg, hash_code, ins_bits, ret_ins_bits, err_code);
560  if (*err_code < 0) {
561  return NULL;
562  }
563  break;
564  case 35: res = ins_bits ? strdup(" || far()") : NULL; break;
565  case 36: res = ins_bits ? strdup(" || local()") : NULL; break;
566  case 37: res = get_opers(ins_bits); break;
567  case 38:
568  res = ins_bits ? "lo" : "hi";
569  res = strdup(res);
570  break;
571  case 39: res = get_cmp_op(ins_bits); break;
572  case 40:
573  case 48:
574  sprintf(buff_aux, "#0x%x", (ins_bits << (32 - ins_token_len) >> (32 - ins_token_len)));
575  res = strdup(buff_aux);
576  break;
577  case 70:
578  case 72:
579  case 80:
580  if (reg_arg) {
581  if (*reg_arg == '!') {
582  res = get_reg_pair(ins_bits);
583  break;
584  } else if (!rz_str_ncasecmp(reg_arg, "ST", 2)) {
585  res = get_status_regs_and_bits(reg_arg, ins_bits);
586  break;
587  }
588  }
589  if (hash_code == 0xDF || hash_code == 0xE0) {
590  *ret_ins_bits = ins_bits;
591  }
592  if (!reg_arg || *reg_arg != '-') {
593  sprintf(buff_aux, "#0x%lx", (long unsigned int)ins_bits);
594  } else {
595  sprintf(buff_aux, "-#0x%lx", (long unsigned int)ins_bits);
596  }
597  res = strdup(buff_aux);
598  if (!reg_arg || *reg_arg != 'm') {
599  break;
600  }
601 
602  res = strcat_dup(res, ")", 1);
603  res = strcat_dup("*(", res, 2);
604 
605  if (magic_value & 0xC0) {
606  res = strcat_dup(res, ")", 1);
607  res = strcat_dup("volatile(", res, 2);
608  } else if (magic_value & 0x30) {
609  res = strcat_dup(res, ")", 1);
610  res = strcat_dup("port(", res, 2);
611  }
612  break;
613  case 41:
614  case 73:
615  if ((reg_arg && *reg_arg == 'L') || hash_code == 105 || hash_code == 7) {
616  if (C55PLUS_DEBUG) {
617  fprintf(stderr, "Ooops!!! look up address in sections!! %d", hash_code);
618  }
619  }
620  if (reg_arg && *reg_arg == 'L') {
621  ins_bits = ins_bits << (32 - ins_token_len) >> (32 - ins_token_len);
622  }
623  if (reg_arg && *reg_arg == 'i') {
624  res = strdup("");
625  } else {
626  sprintf(buff_aux, "#0x%06lx", (long unsigned int)ins_bits);
627  res = strdup(buff_aux);
628  }
629  break;
630  case 42:
631  flag = 0;
632  if (reg_arg && *reg_arg == '3') {
633  flag = ins_bits & 1;
634  ins_bits = ins_bits >> 1;
635  reg_arg++;
636  }
637  if (magic_value & 1) {
638  aux = get_sim_reg(reg_arg, ins_bits);
639  } else if (reg_arg) {
640  switch (*reg_arg) {
641  case 'b':
642  case 'd':
643  reg_arg++;
644  break;
645  case '!':
646  // strncpy(buff_aux, reg_arg + 1, 8);
647  reg_arg += 10;
648  // ins_bits2 = get_ins_bits(hash_code, ins_pos, buff_aux, 8);
649  break;
650  }
651  aux = get_AR_regs_class2(ins_bits, &ret_len, ins_len + ins_pos, 1);
652  }
653  if (magic_value & 1) {
654  aux = strcat_dup(aux, ")", 1);
655  aux = strcat_dup("mmap(", aux, 2);
656  } else if ((magic_value & 4) && is_linear_circular(ins_bits)) {
657  aux = strcat_dup(aux, ")", 1);
658  aux = strcat_dup("linear(", aux, 2);
659  } else if ((magic_value & 8) && is_linear_circular(ins_bits)) {
660  aux = strcat_dup(aux, ")", 1);
661  aux = strcat_dup("circular(", aux, 2);
662  } else if (magic_value & 2) {
663  aux = strcat_dup(aux, ")", 1);
664  aux = strcat_dup("lock(", aux, 2);
665  } else if (reg_arg) {
666  if (((magic_value & 0x10) && strchr(reg_arg, 'r')) ||
667  ((magic_value & 0x20) && strchr(reg_arg, 'w'))) {
668 
669  aux = strcat_dup(aux, ")", 1);
670  aux = strcat_dup("port(", aux, 2);
671  } else if (
672  ((magic_value & 0x40) && strchr(reg_arg, 'r')) ||
673  ((magic_value & 0x80000000) && strchr(reg_arg, 'w'))) {
674 
675  aux = strcat_dup(aux, ")", 1);
676  aux = strcat_dup("volatile(", aux, 2);
677  }
678  }
679 
680  if (flag) {
681  res = strcat_dup("t3 = ", aux, 2);
682  } else {
683  res = aux;
684  *ret_reg_len = ret_len;
685  }
686  break;
687  case 79:
688  res = get_trans_reg(ins_bits);
689  if (!res) {
690  *err_code = -1;
691  }
692  break;
693  case 49:
694  if (reg_arg) {
695  if (*reg_arg == '1') {
696  res = get_tc2_tc1(ins_bits >> 1);
697  } else if (*reg_arg == '2') {
698  res = get_tc2_tc1(ins_bits & 1);
699  }
700  } else {
701  res = get_tc2_tc1(ins_bits);
702  }
703  if (!res) {
704  *err_code = -1;
705  return NULL;
706  }
707  break;
708  case 52:
709  if (ins_bits == 0) {
710  break;
711  }
712  if (reg_arg) {
713  if (*reg_arg == 'H') {
714  res = "hi(";
715  } else if (*reg_arg == 'L') {
716  res = "lo(";
717  } else if (*reg_arg == 'd') {
718  res = "dbl(";
719  } else if (*reg_arg == ')') {
720  res = ")";
721  } else {
722  res = "<W>";
723  }
724  } else {
725  res = "<W !flags>";
726  }
727  res = strdup(res);
728  break;
729  case 53:
730  case 54:
731  case 55:
732  flag = 0;
733  if (reg_arg && *reg_arg == '3') {
734  flag = ins_bits & 1;
735  ins_bits = ins_bits >> 1;
736  reg_arg++;
737  }
738  aux = get_AR_regs_class1(ins_bits);
739  tok_op = ins_bits & 0xF;
740  if (magic_value & 4) {
741  if (tok_op <= 7 || tok_op == 0xF) {
742  aux = strcat_dup(aux, ")", 1);
743  aux = strcat_dup("linear(", aux, 2);
744  }
745  } else if (magic_value & 8) {
746  if (tok_op <= 7 || tok_op == 0xF) {
747  aux = strcat_dup(aux, ")", 1);
748  aux = strcat_dup("circular(", aux, 2);
749  }
750  } else if (magic_value & 2) {
751  aux = strcat_dup(aux, ")", 1);
752  aux = strcat_dup("lock(", aux, 2);
753  } else if (reg_arg) {
754  if (
755  ((magic_value & 0x10) && *ins_token == 'X' && strchr(reg_arg, 'r')) ||
756  ((magic_value & 0x20) && *ins_token == 'Y' && strchr(reg_arg, 'w'))) {
757 
758  aux = strcat_dup(aux, ")", 1);
759  aux = strcat_dup("port(", aux, 2);
760  } else if (
761  ((magic_value & 0x40) && *ins_token == 'X' && strchr(reg_arg, 'r')) ||
762  ((magic_value & 0x80000000) && *ins_token == 'Y' && strchr(reg_arg, 'w'))
763 
764  ) {
765  aux = strcat_dup(aux, ")", 1);
766  aux = strcat_dup("volatile(", aux, 2);
767  }
768  }
769  res = flag ? strcat_dup("t3 = ", aux, 2) : aux;
770  break;
771  case 0:
772  case 1:
773  if (!ins_bits) {
774  break;
775  }
776  if (!reg_arg) {
777  res = "U";
778  } else {
779  if (*reg_arg == '(') {
780  res = "uns(";
781  } else if (*reg_arg == ')') {
782  res = ")";
783  } else {
784  res = "<$/#>";
785  }
786  }
787  res = strdup(res);
788  break;
789  case 2:
790  if (!ins_bits) {
791  break;
792  }
793  if (!reg_arg) {
794  res = "R";
795  } else {
796  if (*reg_arg == '(') {
797  res = "rnd(";
798  } else if (*reg_arg == ')') {
799  res = ")";
800  } else {
801  res = "<%>";
802  }
803  }
804  res = strdup(res);
805  break;
806  case 12:
807  if (!ins_bits) {
808  break;
809  }
810  if (!reg_arg) {
811  res = "F";
812  } else {
813  if (*reg_arg == '(') {
814  res = "frct(";
815  } else if (*reg_arg == ')') {
816  res = ")";
817  } else if (*reg_arg == 'a') {
818  res = "<%>";
819  } else {
820  res = "</>";
821  }
822  }
823  res = strdup(res);
824  break;
825  case 29:
826  if (!ins_bits) {
827  break;
828  }
829  if (!reg_arg) {
830  res = "saturate";
831  } else {
832  if (*reg_arg == '(') {
833  res = "saturate(";
834  } else if (*reg_arg == ')') {
835  res = ")";
836  } else {
837  res = "<saturate>";
838  }
839  }
840  res = strdup(res);
841  break;
842  case 16:
843  res = (ins_bits != 0) ? strdup("t3 = ") : NULL;
844  break;
845  case 17:
846  if (!ins_bits) {
847  break;
848  }
849  if (!reg_arg) {
850  res = "40";
851  } else {
852  if (*reg_arg == '(') {
853  res = "m40(";
854  } else if (*reg_arg == ')') {
855  res = ")";
856  } else {
857  res = "<4>";
858  }
859  }
860  res = strdup(res);
861  break;
862  case 78:
863  if (!rz_str_ncasecmp(ins_token, "q_SAT", 5)) {
864  res = ins_bits ? "s" : NULL;
865  } else if (!rz_str_ncasecmp(ins_token, "q_CIRC", 6)) {
866  res = ins_bits ? ".cr" : NULL;
867  } else if (!rz_str_ncasecmp(ins_token, "q_LINR", 6)) {
868  res = ins_bits ? ".lr" : NULL;
869  } else {
870  fprintf(stderr, "Invalid instruction %s\n!", ins_token);
871  *err_code = -1;
872  return NULL;
873  }
874  if (res != NULL) {
875  if (C55PLUS_DEBUG) {
876  printf("OP(78): TOKEN=%s\n", res);
877  }
878  res = strdup(res);
879  }
880  break;
881  }
882 
883 ret_decode:
884  if (C55PLUS_DEBUG) {
885  printf("RES = %s\n", (res) ? res : "NULL");
886  }
887  return res;
888 }
size_t len
Definition: 6502dis.c:15
ut8 op
Definition: 6502dis.c:13
ut32 get_ins_len(ut8 opcode)
Definition: ins.c:11
lzma_index ** i
Definition: index.h:629
ut16 val
Definition: armass64_const.h:6
static bool is_hash(st32 hash_code)
static char * decode_ins(st32 hash_code, ut32 ins_pos, ut32 ins_off, ut32 *ins_len_dec, ut32 *reg_len_dec, ut32 *ret_ins_bits, ut32 magic_value, ut8 two_ins, int *err_code)
static char * do_decode(ut32 ins_off, ut32 ins_pos, ut32 two_ins, ut32 *next_ins_pos, st32 *ins_hash_code, int *err_code)
static bool check_arg(ut32 ins_bits, int *err_code)
ut32 ins_buff_len
Definition: ins.c:7
void set_magic_value(ut32 *magic_value, st32 hash_code, int *err_code)
static ut32 get_ins_bits(ut32 hash_code, ut32 ins_pos, char *ins, ut32 ins_len, ut32 magic_value, int *err_code)
char * c55plus_decode(ut32 ins_pos, ut32 *next_ins_pos)
char * ins_str[]
Definition: ins.c:76
static bool is_linear_circular(ut32 ins_bits)
static char * decode_regis(char *reg_arg, st32 hash_code, ut32 ins_bits, ut32 *ret_ins_bits, int *err_code)
static ut32 get_q_bits(ut32 val, char *ins, ut32 ins_len, int *err_code)
static char * get_token_decoded(st32 hash_code, char *ins_token, ut32 ins_token_len, char *reg_arg, ut32 *ret_ins_bits, ut32 *ret_reg_len, ut32 magic_value, ut32 ins_pos, ut32 ins_len, ut8 two_ins, int *err_code)
#define NULL
Definition: cris-opc.c:27
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
Definition: cs_driver.c:93
char * get_opers(ut8 oper_byte)
Definition: decode_funcs.c:951
char * get_reg_name_2(ut32 idx)
Definition: decode_funcs.c:333
char * get_AR_regs_class1(ut32 ins_bits)
Definition: decode_funcs.c:58
char * get_sim_reg(char *reg_arg, ut32 ins_bits)
char * get_cmp_op(ut32 idx)
char * get_tc2_tc1(ut32 ins_bits)
Definition: decode_funcs.c:11
char * get_trans_reg(ut32 ins_bits)
Definition: decode_funcs.c:23
char * get_reg_pair(ut32 idx)
Definition: decode_funcs.c:238
char * get_status_regs_and_bits(char *reg_arg, int reg_bit)
Definition: decode_funcs.c:644
char * get_AR_regs_class2(ut32 ins_bits, ut32 *ret_len, ut32 ins_pos, ut32 idx)
Definition: decode_funcs.c:93
char * get_reg_name_1(ut32 idx)
Definition: decode_funcs.c:389
char * get_reg_name_3(ut32 idx)
Definition: decode_funcs.c:269
uint32_t ut32
st32 get_hash_code(ut32 ins_pos)
Definition: hashtable.c:2801
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
ut32 get_ins_part(ut32 pos, ut32 len)
Definition: ins.c:51
sprintf
Definition: kernel.h:365
#define reg(n)
uint8_t ut8
Definition: lh5801.h:11
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
char * strcat_dup(char *s1, char *s2, st32 n_free)
Definition: utils.c:12
char * get_hex_str(ut32 hex_num)
Definition: utils.c:38
#define C55PLUS_DEBUG
Definition: utils.h:8
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 x
Definition: mipsasm.c:20
RZ_API int rz_str_ncasecmp(const char *dst, const char *orig, size_t n)
Definition: str.c:129
#define st32
Definition: rz_types_base.h:12
static int
Definition: sfsocketcall.h:114
int pos
Definition: main.c:11
Definition: dis.c:32