Rizin
unix-like reverse engineering framework and cli tools
dis.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <stdarg.h>
#include <stdint.h>
#include "dis.h"
#include <rz_types.h>
#include <rz_util/rz_assert.h>

Go to the source code of this file.

Functions

static struct stateget_state (void)
 
static uint16_t i2u16 (struct instruction *in)
 
static void decode_unknown (struct state *s, struct directive *d)
 
static int decode_fixed (struct state *s, struct directive *d)
 
static char * regname (int reg)
 
static int get_num (int num, int shift)
 
static int get_operand (struct state *s, struct directive *d)
 
static int decode_known (struct state *s, struct directive *d)
 
static void xap_decode (struct state *s, struct directive *d)
 
static int read_bin (struct state *s, struct directive *d)
 
static struct directivenext_inst (struct state *s)
 

Variables

static struct state _state
 

Function Documentation

◆ decode_fixed()

static int decode_fixed ( struct state s,
struct directive d 
)
static

Definition at line 47 of file dis.c.

47  {
48  *d->d_asm = '\0';
49  switch (i2u16(&d->d_inst)) {
50  case INST_NOP:
51  if (s->s_prefix) {
52  return 0;
53  }
54  s->s_nop++;
55  strcpy(d->d_asm, "nop");
56  break;
57  case INST_BRK: strcpy(d->d_asm, "brk"); break;
58  case INST_SLEEP: strcpy(d->d_asm, "sleep"); break;
59  case INST_SIF: strcpy(d->d_asm, "sif"); break;
60  case INST_BC: strcpy(d->d_asm, "bc"); break;
61  case INST_BRXL: strcpy(d->d_asm, "brxl"); break;
62  case INST_U:
63  strcpy(d->d_asm, "");
64  s->s_u = 1;
65  break;
66  case INST_RTS: strcpy(d->d_asm, "rts"); break;
67  }
68  return d->d_asm[0] != 0;
69 }
#define INST_SLEEP
Definition: dis.h:70
#define INST_SIF
Definition: dis.h:72
#define INST_BRK
Definition: dis.h:69
#define INST_RTS
Definition: dis.h:73
#define INST_NOP
Definition: dis.h:68
#define INST_U
Definition: dis.h:71
#define INST_BC
Definition: dis.h:75
#define INST_BRXL
Definition: dis.h:74
static RzSocket * s
Definition: rtr.c:28
#define d(i)
Definition: sha256.c:44
static uint16_t i2u16(struct instruction *in)
Definition: dis.c:23

References d, i2u16(), INST_BC, INST_BRK, INST_BRXL, INST_NOP, INST_RTS, INST_SIF, INST_SLEEP, INST_U, and s.

Referenced by xap_decode().

◆ decode_known()

static int decode_known ( struct state s,
struct directive d 
)
static

Definition at line 95 of file dis.c.

95  {
96  char *op = NULL;
97  char *regn = NULL;
98  int reg = 0;
99  int ptr = 1;
100  int idx = 1;
101  int imm = 0;
102  int rel = 0;
103  char fmt[16];
104  char tmp[128];
105  int fmtsz;
106  int branch = 0;
107  struct instruction *in = &d->d_inst;
108  // int operand;
109  char *sign = "";
110  int rti = 0;
111 
112  switch (in->in_opcode) {
113  case 0:
114  if (in->in_reg == 0 && in->in_mode == 0) {
115  if (s->s_prefix == 0)
116  s->s_prefix_val = 0;
117  s->s_prefix++;
118 
119  if (s->s_prefix == 2)
120  s->s_prefix_val <<= 8;
121 #if 0
122  /* XXX we need to look ahead more to see if we're
123  * getting a branch instruction */
124  if (s->s_nopd && in->in_operand == 0x80)
125  strcpy(s->s_nopd->d_asm, "");
126 #endif
127  s->s_prefix_val |= in->in_operand << 8;
128 
129  strcpy(d->d_asm, "");
130  return 1;
131  }
132 
133  switch (i2u16(in) & 0xf) {
134  case 1:
135  op = "st";
136  regn = "FLAGS";
137  break;
138  case 2:
139  op = "st";
140  regn = "UX";
141  break;
142  case 3:
143  op = "st";
144  regn = "UY";
145  break;
146  case 5:
147  op = "ld";
148  regn = "FLAGS";
149  break;
150  case 6:
151  op = "ld";
152  regn = "UX";
153  break;
154  case 7:
155  op = "ld";
156  regn = "UY";
157  break;
158  case 0xa:
159  op = "st";
160  regn = "XH";
161  break;
162  case 0xd:
163  op = "rti";
164  regn = "";
165  rti = 1;
166  break;
167  case 0xe:
168  op = "ld";
169  regn = "XH";
170  break;
171  }
172  break;
173 
174  case 1:
175  op = "ld";
176  reg = 1;
177  ptr = 1;
178  idx = 1;
179  imm = 1;
180  break;
181  case 2:
182  if (in->in_mode == DATA_MODE_IMMEDIATE) {
183  op = "print";
184  imm = 1;
185  reg = 1;
186  } else {
187  op = "st";
188  reg = 1;
189  ptr = 1;
190  idx = 1;
191  }
192  break;
193  case 3:
194  op = "add";
195  reg = 1;
196  ptr = 1;
197  idx = 1;
198  imm = 1;
199  break;
200  case 4:
201  op = "addc";
202  reg = 1;
203  ptr = 1;
204  idx = 1;
205  imm = 1;
206  break;
207  case 5:
208  op = "sub";
209  reg = 1;
210  ptr = 1;
211  idx = 1;
212  imm = 1;
213  break;
214  case 6:
215  op = "subc";
216  reg = 1;
217  ptr = 1;
218  idx = 1;
219  imm = 1;
220  break;
221  case 7:
222  op = "nadd";
223  reg = 1;
224  ptr = 1;
225  idx = 1;
226  imm = 1;
227  break;
228  case 8:
229  op = "cmp";
230  reg = 1;
231  ptr = 1;
232  idx = 1;
233  imm = 1;
234  break;
235  case 0x9:
236  switch (in->in_reg) {
237  case 0:
238  if (s->s_u)
239  op = "umult";
240  else
241  op = "smult";
242  imm = 1;
243  s->s_u = 0;
244  idx = 1;
245  ptr = 1;
246  break;
247  case 1:
248  if (s->s_u)
249  op = "udiv";
250  else
251  op = "sdiv";
252  s->s_u = 0;
253  imm = 1;
254  break;
255  case 2:
256  op = "tst";
257  imm = 1;
258  ptr = 1;
259  idx = 1;
260  break;
261  case 3:
262  branch = 1;
263  op = "bsr";
264  ptr = 1;
265  idx = 1;
266  if (in->in_mode == ADDR_MODE_RELATIVE)
267  rel = 1;
268  break;
269  }
270  break;
271  case 0xa:
272  switch (in->in_reg) {
273  case 0:
274  op = "asl";
275  imm = 1;
276  break;
277  case 1:
278  if (s->s_u)
279  op = "lsr";
280  else
281  op = "asr";
282  s->s_u = 0;
283  imm = 1;
284  idx = 1;
285  ptr = 1;
286  break;
287  case 2:
288  op = "rol";
289  imm = 1;
290  break;
291  case 3:
292  op = "ror";
293  imm = 1;
294  break;
295  }
296  break;
297 
298  case 0xb:
299  op = "or";
300  reg = 1;
301  ptr = 1;
302  idx = 1;
303  imm = 1;
304  break;
305  case 0xc:
306  op = "and";
307  reg = 1;
308  ptr = 1;
309  idx = 1;
310  imm = 1;
311  break;
312  case 0xd:
313  op = "xor";
314  reg = 1;
315  ptr = 1;
316  idx = 1;
317  imm = 1;
318  break;
319  case 0xe:
320  branch = 1;
321  if (in->in_mode == ADDR_MODE_RELATIVE)
322  rel = 1;
323  switch (in->in_reg) {
324  case 0:
325  op = "bra";
326  ptr = 1;
327  idx = 1;
328 #if 0
329  if (s->s_nopd) {
330  op = "bra2"; /* XXX need bra3 support */
331  strcpy(s->s_nopd->d_asm, "");
332  }
333 #endif
334  break;
335 
336  case 1:
337  op = "blt"; /* yummy */
338  break;
339  case 2:
340  op = "bpl";
341  break;
342  case 3:
343  op = "bmi";
344  break;
345  }
346  break;
347  case 0xf:
348  branch = 1;
349  if (in->in_mode == ADDR_MODE_RELATIVE)
350  rel = 1;
351  switch (in->in_reg) {
352  case 0: op = "bne"; break;
353  case 1: op = "beq"; break;
354  case 2: op = "bcc"; break;
355  case 3: op = "bcs"; break;
356  }
357  break;
358  }
359 
360  if (!op)
361  return 0;
362 
363  if (ptr && in->in_mode == DATA_MODE_IMMEDIATE)
364  ptr = 0;
365 
366  if (branch && in->in_mode == ADDR_MODE_X_RELATIVE)
367  ptr = 0;
368 
369  if (idx && (!(in->in_mode & 2)))
370  idx = 0;
371 
372  if (regn) {
373  ptr = 1;
374  idx = 1;
375  reg = 1;
376  }
377 
378  sprintf(d->d_asm, "%s ", op);
379  if (reg) {
380  char *r = regn;
381  if (!r) {
382  r = regname(in->in_reg);
383  }
384  if (r && !rti) {
385  if ((strlen(r) + 4 + strlen(d->d_asm)) < sizeof(d->d_asm)) {
386  strcat(d->d_asm, r);
387  strcat(d->d_asm, ", ");
388  }
389  }
390  }
391  if (ptr) {
392  strcat(d->d_asm, "@");
393  rel = 0;
394  } else if (imm) {
395  strcat(d->d_asm, "#");
396  }
397  if (idx && ptr) {
398  strcat(d->d_asm, "(");
399  }
400 
401  d->d_prefix = s->s_prefix;
402 // d->d_operand = get_operand(s, d);
403 #if 1
404  if ((branch && idx) || rti) {
405  d->d_operand = get_operand(s, d);
406  if (d->d_operand < 0) {
407  d->d_operand *= -1;
408  sign = "-";
409  }
410  } else {
411  d->d_operand = s->s_prefix_val | in->in_operand;
412  if (d->d_operand & 0x80) {
413  if (d->d_prefix) {
414  if (!rel)
415  d->d_operand -= 0x100;
416  } else
417  d->d_operand |= 0xff00;
418  }
419  }
420 #endif
421 #if 0
422  operand = d->d_operand;
423  if (operand < 0)
424  operand *= -1;
425 #endif
426  fmtsz = 4;
427  if (d->d_operand & 0xff0000)
428  fmtsz += 2;
429 
430  // can be cleaned, no need to fmtsz
431  snprintf(fmt, sizeof(fmt), "%s0x%%.%dX", sign, fmtsz);
432  snprintf(tmp, sizeof(tmp), fmt, d->d_operand);
433  strcat(d->d_asm, tmp);
434 
435  if (idx) {
436  char *r = in->in_mode == DATA_MODE_INDEXED_X ? "X" : "Y";
437  if (regn)
438  r = "Y";
439  snprintf(tmp, sizeof(tmp), ", %s", r);
440  strcat(d->d_asm, tmp);
441  if (ptr)
442  strcat(d->d_asm, ")");
443  }
444 
445  return 1;
446 }
#define imm
operand
Definition: arc-opc.c:39
const lzma_allocator const uint8_t * in
Definition: block.h:527
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
#define ADDR_MODE_RELATIVE
Definition: dis.h:87
#define ADDR_MODE_X_RELATIVE
Definition: dis.h:88
#define DATA_MODE_INDEXED_X
Definition: dis.h:84
#define DATA_MODE_IMMEDIATE
Definition: dis.h:82
snprintf
Definition: kernel.h:364
sprintf
Definition: kernel.h:365
#define reg(n)
int idx
Definition: setup.py:197
Definition: dis.c:32
static char * regname(int reg)
Definition: dis.c:71
static int get_operand(struct state *s, struct directive *d)
Definition: dis.c:86

References ADDR_MODE_RELATIVE, ADDR_MODE_X_RELATIVE, test-lz4-speed::branch, d, DATA_MODE_IMMEDIATE, DATA_MODE_INDEXED_X, get_operand(), i2u16(), setup::idx, imm, in, NULL, r, reg, regname(), s, snprintf, sprintf, and autogen_x86imm::tmp.

Referenced by xap_decode().

◆ decode_unknown()

static void decode_unknown ( struct state s,
struct directive d 
)
static

Definition at line 39 of file dis.c.

39  {
40 #if 0
41  printf("Opcode 0x%x reg %d mode %d operand 0x%x",
42  in->in_opcode, in->in_reg, in->in_mode, in->in_operand);
43 #endif
44  sprintf(d->d_asm, "DC 0x%4x", i2u16(&d->d_inst));
45 }
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
Definition: cs_driver.c:93

References d, i2u16(), in, printf(), and sprintf.

Referenced by xap_decode().

◆ get_num()

static int get_num ( int  num,
int  shift 
)
static

Definition at line 81 of file dis.c.

81  {
82  char x = (char)((num >> shift) & 0xff);
83  return (int)(x << shift);
84 }
static RZ_NULLABLE RzILOpBitVector * shift(RzILOpBitVector *val, RZ_NULLABLE RzILOpBool **carry_out, arm_shifter type, RZ_OWN RzILOpBitVector *dist)
Definition: arm_il32.c:190
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char static mode static oldfd struct tms static buf static getgid static geteuid const char static filename static arg static mask struct ustat static ubuf static getppid static setsid static egid sigset_t static set struct timeval struct timezone static tz fd_set fd_set fd_set struct timeval static timeout const char char static bufsiz const char static swapflags void static offset const char static length static mode static who const char struct statfs static buf unsigned unsigned num
Definition: sflib.h:126
int x
Definition: mipsasm.c:20

References num, shift(), and x.

Referenced by get_operand().

◆ get_operand()

static int get_operand ( struct state s,
struct directive d 
)
static

Definition at line 86 of file dis.c.

86  {
87  int total = get_num(d->d_inst.in_operand, 0);
88  if (s->s_prefix)
89  total += get_num(s->s_prefix_val, 8);
90  if (s->s_prefix == 2)
91  total += get_num(s->s_prefix_val, 16);
92  return total;
93 }
static int get_num(int num, int shift)
Definition: dis.c:81

References d, get_num(), and s.

Referenced by decode_known(), and xap_op().

◆ get_state()

static struct state* get_state ( void  )
inlinestatic

Definition at line 18 of file dis.c.

18  {
19  memset(&_state, 0, sizeof(struct state));
20  return &_state;
21 }
return memset(p, 0, total)
Definition: dis.h:43
static struct state _state
Definition: dis.c:13

References _state, and memset().

Referenced by arch_xap_disasm().

◆ i2u16()

static uint16_t i2u16 ( struct instruction in)
static

Definition at line 23 of file dis.c.

23  {
24  return *((uint16_t *)in);
25 }
unsigned short uint16_t
Definition: sftypes.h:30

References in.

Referenced by arch_xap_disasm(), decode_fixed(), decode_known(), and decode_unknown().

◆ next_inst()

static struct directive* next_inst ( struct state s)
inlinestatic

Definition at line 463 of file dis.c.

463  {
464  int rd;
465  struct directive *d = malloc(sizeof(*d));
466  if (!d) {
467  perror("malloc()");
468  return NULL;
469  }
470  memset(d, 0, sizeof(*d));
471 #if 0
472  if (s->s_format)
473  rd = read_text(s, d);
474  else
475 #endif
476  rd = read_bin(s, d);
477  if (!rd) {
478  free(d);
479  return NULL;
480  }
481 
482  return d;
483 }
#define rd()
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
void * malloc(size_t size)
Definition: malloc.c:123
Definition: dis.h:26
static int read_bin(struct state *s, struct directive *d)
Definition: dis.c:457

References d, free(), malloc(), memset(), NULL, rd, read_bin(), and s.

Referenced by arch_xap_disasm().

◆ read_bin()

static int read_bin ( struct state s,
struct directive d 
)
static

Definition at line 457 of file dis.c.

457  {
458  memcpy(&d->d_inst, s->s_buf, sizeof(d->d_inst));
459  d->d_off = s->s_off++;
460  return 1;
461 }
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))

References d, memcpy(), and s.

Referenced by next_inst().

◆ regname()

◆ xap_decode()

static void xap_decode ( struct state s,
struct directive d 
)
static

Definition at line 448 of file dis.c.

448  {
449  int prefix = s->s_prefix;
450  if (!decode_fixed(s, d))
451  if (!decode_known(s, d))
452  decode_unknown(s, d);
453  if (s->s_prefix == prefix)
454  s->s_prefix_val = s->s_prefix = 0;
455 }
unsigned short prefix[65536]
Definition: gun.c:163
static void decode_unknown(struct state *s, struct directive *d)
Definition: dis.c:39
static int decode_fixed(struct state *s, struct directive *d)
Definition: dis.c:47
static int decode_known(struct state *s, struct directive *d)
Definition: dis.c:95

References d, decode_fixed(), decode_known(), decode_unknown(), prefix, and s.

Referenced by arch_xap_disasm(), and xap_op().

Variable Documentation

◆ _state

struct state _state
static

Definition at line 1 of file dis.c.

Referenced by get_state().