Rizin
unix-like reverse engineering framework and cli tools
analysis_arc.c File Reference
#include <string.h>
#include <rz_types.h>
#include <rz_lib.h>
#include <rz_asm.h>
#include <rz_analysis.h>

Go to the source code of this file.

Classes

struct  arc_fields_t
 

Macros

#define ARC_REG_ILINK1   0x1d
 
#define ARC_REG_ILINK2   0x1e
 
#define ARC_REG_BLINK   0x1f
 
#define ARC_REG_LIMM   0x3e
 
#define ARC_REG_PCL   0x3f
 
#define SIGN_EXT_S7(imm)   sign_ext(7, imm);
 
#define SIGN_EXT_S8(imm)   sign_ext(8, imm);
 
#define SIGN_EXT_S9(imm)   sign_ext(9, imm);
 
#define SIGN_EXT_S10(imm)   sign_ext(10, imm);
 
#define SIGN_EXT_S12(imm)   sign_ext(12, imm);
 
#define SIGN_EXT_S13(imm)   sign_ext(13, imm);
 
#define SIGN_EXT_S21(imm)   sign_ext(21, imm);
 
#define SIGN_EXT_S25(imm)   sign_ext(25, imm);
 

Typedefs

typedef struct arc_fields_t arc_fields
 

Functions

static ut32 rz_read_me32_arc (const void *src)
 
static int sign_ext (int bits, int imm)
 
static int map_cond2rizin (ut8 cond)
 
static void arcompact_jump (RzAnalysisOp *op, ut64 addr, ut64 jump, ut8 delay)
 
static void arcompact_jump_cond (RzAnalysisOp *op, ut64 addr, ut64 jump, ut8 delay, ut8 cond)
 
static void arcompact_branch (RzAnalysisOp *op, ut64 addr, st64 offset, ut8 delay)
 
static void map_zz2refptr (RzAnalysisOp *op, ut8 mode_zz)
 
static int arcompact_genops_jmp (RzAnalysisOp *op, ut64 addr, arc_fields *f, ut64 basic_type)
 
static int arcompact_genops (RzAnalysisOp *op, ut64 addr, ut32 words[2])
 
static int arcompact_op (RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len)
 
static int arc_op (RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len, RzAnalysisOpMask mask)
 
static int archinfo (RzAnalysis *analysis, int query)
 
static char * get_reg_profile (RzAnalysis *analysis)
 

Variables

RzAnalysisPlugin rz_analysis_plugin_arc
 
RZ_API RzLibStruct rizin_plugin
 

Macro Definition Documentation

◆ ARC_REG_BLINK

#define ARC_REG_BLINK   0x1f

Definition at line 12 of file analysis_arc.c.

◆ ARC_REG_ILINK1

#define ARC_REG_ILINK1   0x1d

Definition at line 10 of file analysis_arc.c.

◆ ARC_REG_ILINK2

#define ARC_REG_ILINK2   0x1e

Definition at line 11 of file analysis_arc.c.

◆ ARC_REG_LIMM

#define ARC_REG_LIMM   0x3e

Definition at line 13 of file analysis_arc.c.

◆ ARC_REG_PCL

#define ARC_REG_PCL   0x3f

Definition at line 14 of file analysis_arc.c.

◆ SIGN_EXT_S10

#define SIGN_EXT_S10 (   imm)    sign_ext(10, imm);

Definition at line 56 of file analysis_arc.c.

◆ SIGN_EXT_S12

#define SIGN_EXT_S12 (   imm)    sign_ext(12, imm);

Definition at line 57 of file analysis_arc.c.

◆ SIGN_EXT_S13

#define SIGN_EXT_S13 (   imm)    sign_ext(13, imm);

Definition at line 58 of file analysis_arc.c.

◆ SIGN_EXT_S21

#define SIGN_EXT_S21 (   imm)    sign_ext(21, imm);

Definition at line 59 of file analysis_arc.c.

◆ SIGN_EXT_S25

#define SIGN_EXT_S25 (   imm)    sign_ext(25, imm);

Definition at line 60 of file analysis_arc.c.

◆ SIGN_EXT_S7

#define SIGN_EXT_S7 (   imm)    sign_ext(7, imm);

Definition at line 53 of file analysis_arc.c.

◆ SIGN_EXT_S8

#define SIGN_EXT_S8 (   imm)    sign_ext(8, imm);

Definition at line 54 of file analysis_arc.c.

◆ SIGN_EXT_S9

#define SIGN_EXT_S9 (   imm)    sign_ext(9, imm);

Definition at line 55 of file analysis_arc.c.

Typedef Documentation

◆ arc_fields

typedef struct arc_fields_t arc_fields

Function Documentation

◆ arc_op()

static int arc_op ( RzAnalysis analysis,
RzAnalysisOp op,
ut64  addr,
const ut8 data,
int  len,
RzAnalysisOpMask  mask 
)
static

Definition at line 1007 of file analysis_arc.c.

1007  {
1008  const ut8 *b = (ut8 *)data;
1009 
1010  if (analysis->bits == 16) {
1011  return arcompact_op(analysis, op, addr, data, len);
1012  }
1013 
1014  /* ARCtangent A4 */
1015  op->size = 4;
1016  op->fail = addr + 4;
1017  ut8 basecode = (len > 3) ? ((b[3] & 0xf8) >> 3) : 0;
1018  switch (basecode) {
1019  case 0x04: /* Branch */
1020  case 0x05: /* Branch with Link */
1021  case 0x06: /* Loop */
1022  op->type = RZ_ANALYSIS_OP_TYPE_CJMP;
1023  op->jump = addr + 4 + ((rz_read_le32(&data[0]) & 0x07ffff80) >> (7 - 2));
1024  break;
1025  case 0x07: /* Conditional Jump and Jump with Link */
1026  op->type = RZ_ANALYSIS_OP_TYPE_CJMP;
1027  op->jump = 0;
1028  break;
1029  case 0x08:
1030  case 0x09:
1031  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
1032  break;
1033  case 0x0a:
1034  case 0x0b:
1035  op->type = RZ_ANALYSIS_OP_TYPE_SUB;
1036  break;
1037  case 0x0c:
1038  op->type = RZ_ANALYSIS_OP_TYPE_AND;
1039  break;
1040  case 0x0d:
1041  op->type = RZ_ANALYSIS_OP_TYPE_OR;
1042  break;
1043  case 0x0f:
1044  if ((b[0] == 0xff) && (b[1] == 0xff)) {
1045  op->type = RZ_ANALYSIS_OP_TYPE_NOP;
1046  break;
1047  }
1048  op->type = RZ_ANALYSIS_OP_TYPE_XOR;
1049  break;
1050  case 0x13:
1051  op->type = RZ_ANALYSIS_OP_TYPE_ROR;
1052  break;
1053  default:
1054  break;
1055  }
1056  return op->size;
1057 }
size_t len
Definition: 6502dis.c:15
static int arcompact_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len)
Definition: analysis_arc.c:441
uint8_t ut8
Definition: lh5801.h:11
@ RZ_ANALYSIS_OP_TYPE_SUB
Definition: rz_analysis.h:402
@ RZ_ANALYSIS_OP_TYPE_AND
Definition: rz_analysis.h:411
@ RZ_ANALYSIS_OP_TYPE_ROR
Definition: rz_analysis.h:419
@ RZ_ANALYSIS_OP_TYPE_ADD
Definition: rz_analysis.h:401
@ RZ_ANALYSIS_OP_TYPE_OR
Definition: rz_analysis.h:410
@ RZ_ANALYSIS_OP_TYPE_CJMP
Definition: rz_analysis.h:373
@ RZ_ANALYSIS_OP_TYPE_NOP
Definition: rz_analysis.h:389
@ RZ_ANALYSIS_OP_TYPE_XOR
Definition: rz_analysis.h:412
static ut32 rz_read_le32(const void *src)
Definition: rz_endian.h:239
#define b(i)
Definition: sha256.c:42
Definition: dis.c:32
static int addr
Definition: z80asm.c:58

References addr, arcompact_op(), b, rz_analysis_t::bits, len, RZ_ANALYSIS_OP_TYPE_ADD, RZ_ANALYSIS_OP_TYPE_AND, RZ_ANALYSIS_OP_TYPE_CJMP, RZ_ANALYSIS_OP_TYPE_NOP, RZ_ANALYSIS_OP_TYPE_OR, RZ_ANALYSIS_OP_TYPE_ROR, RZ_ANALYSIS_OP_TYPE_SUB, RZ_ANALYSIS_OP_TYPE_XOR, and rz_read_le32().

◆ archinfo()

static int archinfo ( RzAnalysis analysis,
int  query 
)
static

Definition at line 1059 of file analysis_arc.c.

1059  {
1060  if (analysis->bits != 16) {
1061  return -1;
1062  }
1063  switch (query) {
1065  return 2;
1067  /* all ops are at least 1 word long */
1068  return 2;
1070  return 8;
1071  default:
1072  return -1;
1073  }
1074 }
#define RZ_ANALYSIS_ARCHINFO_ALIGN
Definition: rz_analysis.h:100
#define RZ_ANALYSIS_ARCHINFO_MAX_OP_SIZE
Definition: rz_analysis.h:99
#define RZ_ANALYSIS_ARCHINFO_MIN_OP_SIZE
Definition: rz_analysis.h:98

References rz_analysis_t::bits, RZ_ANALYSIS_ARCHINFO_ALIGN, RZ_ANALYSIS_ARCHINFO_MAX_OP_SIZE, and RZ_ANALYSIS_ARCHINFO_MIN_OP_SIZE.

◆ arcompact_branch()

static void arcompact_branch ( RzAnalysisOp op,
ut64  addr,
st64  offset,
ut8  delay 
)
static

Definition at line 102 of file analysis_arc.c.

102  {
103  arcompact_jump(op, addr, (addr & ~3) + offset, delay);
104 }
static void arcompact_jump(RzAnalysisOp *op, ut64 addr, ut64 jump, ut8 delay)
Definition: analysis_arc.c:91
voidpf uLong offset
Definition: ioapi.h:144

References addr, and arcompact_jump().

Referenced by arcompact_op().

◆ arcompact_genops()

static int arcompact_genops ( RzAnalysisOp op,
ut64  addr,
ut32  words[2] 
)
static

Definition at line 196 of file analysis_arc.c.

196  {
197  arc_fields fields = { 0 };
198 
199  fields.format = (words[0] & 0x00c00000) >> 22;
200  fields.subopcode = (words[0] & 0x003f0000) >> 16;
201  fields.c = (words[0] & 0x00000fc0) >> 6;
202  fields.a = (words[0] & 0x0000003f);
203  fields.b = (words[0] & 0x07000000) >> 24 | (words[0] & 0x7000) >> 9;
204  fields.mode_n = 0;
205 
206  /* increase the size to cover any limm reg fields */
207  if (fields.b == ARC_REG_LIMM) {
208  op->size = 8;
209  fields.limm = words[1];
210  /* FIXME: MOV<.f> 0,x is encoded as fields.b == ARC_REG_LIMM, but no limm */
211  } else if ((fields.format == 0 || fields.format == 1) && (fields.a == ARC_REG_LIMM)) {
212  op->size = 8;
213  fields.limm = words[1];
214  } else if ((fields.format == 0) && (fields.c == ARC_REG_LIMM)) {
215  op->size = 8;
216  fields.limm = words[1];
217  } else if ((fields.format == 3) && ((fields.a & 0x20) == 0x20) && (fields.c == ARC_REG_LIMM)) {
218  op->size = 8;
219  fields.limm = words[1];
220  }
221 
222  if (fields.format == 1) {
223  /* REG_U6IMM */
224  fields.imm = fields.c;
225  } else if (fields.format == 2) {
226  /* REG_S12IMM */
227  fields.imm = SIGN_EXT_S12(fields.c | fields.a << 6);
228  }
229 
230  switch (fields.subopcode) {
231  case 0x00: /* add */
232  if ((fields.format == 1 || fields.format == 2) && fields.b == ARC_REG_PCL) {
233  /* dst = PCL + src */
234  op->ptr = (addr & ~3) + fields.imm;
235  op->refptr = 1; /* HACK! we don't actually know what size it is */
236  }
237  // fallthrough
238  case 0x01: /* add with carry */
239  case 0x14: /* add with left shift by 1 */
240  case 0x15: /* add with left shift by 2 */
241  case 0x16: /* add with left shift by 3 */
242  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
243  break;
244  case 0x02: /* subtract */
245  case 0x03: /* subtract with carry */
246  case 0x0e: /* reverse subtract */
247  case 0x17: /* subtract with left shift by 1 */
248  case 0x18: /* subtract with left shift by 2 */
249  case 0x19: /* subtract with left shift by 3 */
250  op->type = RZ_ANALYSIS_OP_TYPE_SUB;
251  break;
252  case 0x04: /* logical bitwise AND */
253  case 0x06: /* logical bitwise AND with invert */
254  case 0x10: /* bit clear */
255  case 0x13: /* bit mask */
256  op->type = RZ_ANALYSIS_OP_TYPE_AND;
257  break;
258  case 0x05: /* logical bitwise OR */
259  case 0x0f: /* bit set */
260  op->type = RZ_ANALYSIS_OP_TYPE_OR;
261  break;
262  case 0x07: /* logical bitwise exclusive-OR */
263  case 0x12: /* bit xor */
264  op->type = RZ_ANALYSIS_OP_TYPE_XOR;
265  break;
266  case 0x08: /* larger of 2 signed integers */
267  case 0x09: /* smaller of 2 signed integers */
269  break;
270  case 0x0a: /* move */
271  if (fields.format == 2) {
272  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
273  op->val = SIGN_EXT_S12(fields.a << 6 | fields.c);
274  } else if (fields.format == 3) {
275  fields.cond = fields.a & 0x1f;
276  op->cond = map_cond2rizin(fields.cond);
278  if ((fields.a & 0x20)) {
279  /* its a move from imm u6 */
280  op->val = fields.c;
281  } else if (fields.c == ARC_REG_LIMM) {
282  /* its a move from limm */
283  op->val = fields.limm;
284  }
285  }
286  break;
287  case 0x0b: /* test */
288  case 0x0c: /* compare */
289  case 0x0d: /* reverse compare */
290  case 0x11: /* bit test */
291  op->type = RZ_ANALYSIS_OP_TYPE_CMP;
292  break;
293  case 0x1a: /* 32 X 32 signed multiply */
294  case 0x1b: /* 32 X 32 signed multiply */
295  case 0x1c: /* 32 X 32 unsigned multiply */
296  case 0x1d: /* 32 X 32 unsigned multiply */
297  op->type = RZ_ANALYSIS_OP_TYPE_MUL;
298  break;
299  case 0x21: /* Jump with delay slot */
300  fields.mode_n = 1;
301  /* fall through */
302  case 0x20: /* Jump */
303  fields.mode_m = (words[0] & 0x20) >> 5;
305  break;
306  case 0x23: /* jump and link with delay slot */
307  fields.mode_n = 1;
308  /* fall through */
309  case 0x22: /* jump and link */
310  fields.mode_m = (words[0] & 0x20) >> 5;
312  break;
313  case 0x1e: /* Reserved */
314  case 0x1f: /* Reserved */
315  case 0x24: /* Reserved */
316  case 0x25: /* Reserved */
317  case 0x26: /* Reserved */
318  case 0x27: /* Reserved */
319  case 0x2c: /* Reserved */
320  case 0x2d: /* Reserved */
321  case 0x2e: /* Reserved */
322  case 0x38: /* Reserved */
323  case 0x39: /* Reserved */
324  case 0x3a: /* Reserved */
325  case 0x3b: /* Reserved */
326  case 0x3c: /* Reserved */
327  case 0x3d: /* Reserved */
328  case 0x3e: /* Reserved */
329  case 0x3f: /* Reserved */
330  op->type = RZ_ANALYSIS_OP_TYPE_ILL;
331  break;
332  case 0x28: /* loop (16-bit aligned target address) */
333  /* this is essentially a COME FROM instruction!! */
334  /* TODO: describe it to rizin better? */
335  switch (fields.format) {
336  case 2: /* Loop Set Up (Unconditional) */
337  fields.imm = SIGN_EXT_S13((fields.c | (fields.a << 6)) << 1);
338  op->jump = (addr & ~3) + fields.imm;
340  op->fail = addr + op->size;
341  break;
342  case 3: /* Loop Set Up (Conditional) */
343  fields.imm = fields.c << 1;
344  fields.cond = fields.a & 0x1f;
345  op->cond = map_cond2rizin(fields.a & 0x1f);
346  op->jump = (addr & ~3) + fields.imm;
348  op->fail = addr + op->size;
349  break;
350  default:
351  op->type = RZ_ANALYSIS_OP_TYPE_ILL;
352  break;
353  }
354  break;
355  case 0x29: /* set status flags */
356  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
357  break;
358  case 0x2a: /* load from auxiliary register. */
359  case 0x2b: /* store to auxiliary register. */
360  op->type = RZ_ANALYSIS_OP_TYPE_IO;
361  break;
362  case 0x2f: /* Single Operand Instructions, 0x04, [0x2F, 0x00 - 0x3F] */
363  switch (fields.a) {
364  case 0: /* Arithmetic shift left by one */
365  op->type = RZ_ANALYSIS_OP_TYPE_SAL;
366  break;
367  case 1: /* Arithmetic shift right by one */
368  op->type = RZ_ANALYSIS_OP_TYPE_SAR;
369  break;
370  case 2: /* Logical shift right by one */
371  op->type = RZ_ANALYSIS_OP_TYPE_SHR;
372  break;
373  case 3: /* Rotate right */
374  case 4: /* Rotate right through carry */
375  op->type = RZ_ANALYSIS_OP_TYPE_ROR;
376  break;
377  case 5: /* Sign extend byte */
378  case 6: /* Sign extend word */
379  case 7: /* Zero extend byte */
380  case 8: /* Zero extend word */
381  // op->type = RZ_ANALYSIS_OP_TYPE_UNK;
382  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
383  /* TODO: a better encoding for SIGN and ZERO EXTEND instructions */
384  break;
385  case 9: /* Absolute */
386  op->type = RZ_ANALYSIS_OP_TYPE_ABS;
387  break;
388  case 0xa: /* Logical NOT */
389  op->type = RZ_ANALYSIS_OP_TYPE_NOT;
390  break;
391  case 0xb: /* Rotate left through carry */
392  op->type = RZ_ANALYSIS_OP_TYPE_ROL;
393  break;
394  case 0xc: /* Atomic Exchange */
396  break;
397  case 0x3f: /* See Zero operand (ZOP) table */
398  switch (fields.b) {
399  case 1: /* Sleep */
400  /* TODO: a better encoding for this */
402  break;
403  case 2: /* Software interrupt */
404  op->type = RZ_ANALYSIS_OP_TYPE_SWI;
405  break;
406  case 3: /* Wait for all data-based memory transactions to complete */
407  /* TODO: a better encoding for this */
409  break;
410  case 4: /* Return from interrupt/exception */
411  op->type = RZ_ANALYSIS_OP_TYPE_RET;
412  break;
413  case 5: /* Breakpoint instruction */
415  break;
416  default:
417  op->type = RZ_ANALYSIS_OP_TYPE_ILL;
418  break;
419  }
420  break;
421  default:
422  op->type = RZ_ANALYSIS_OP_TYPE_ILL;
423  break;
424  }
425  break;
426  case 0x30:
427  case 0x31:
428  case 0x32:
429  case 0x33:
430  case 0x34:
431  case 0x35:
432  case 0x36:
433  case 0x37: /* Load Register-Register, 0x04, [0x30 - 0x37] */
434  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
435  break;
436  }
437 
438  return op->size;
439 }
const aarch64_field fields[]
Definition: aarch64-opc.c:205
#define SIGN_EXT_S12(imm)
Definition: analysis_arc.c:57
static int map_cond2rizin(ut8 cond)
Definition: analysis_arc.c:62
#define ARC_REG_PCL
Definition: analysis_arc.c:14
#define ARC_REG_LIMM
Definition: analysis_arc.c:13
static int arcompact_genops_jmp(RzAnalysisOp *op, ut64 addr, arc_fields *f, ut64 basic_type)
Definition: analysis_arc.c:117
#define SIGN_EXT_S13(imm)
Definition: analysis_arc.c:58
@ RZ_ANALYSIS_OP_TYPE_CMP
Definition: rz_analysis.h:399
@ RZ_ANALYSIS_OP_TYPE_MUL
Definition: rz_analysis.h:404
@ RZ_ANALYSIS_OP_TYPE_ROL
Definition: rz_analysis.h:420
@ RZ_ANALYSIS_OP_TYPE_JMP
Definition: rz_analysis.h:368
@ RZ_ANALYSIS_OP_TYPE_SAL
Definition: rz_analysis.h:408
@ RZ_ANALYSIS_OP_TYPE_IO
Definition: rz_analysis.h:403
@ RZ_ANALYSIS_OP_TYPE_SWI
Definition: rz_analysis.h:393
@ RZ_ANALYSIS_OP_TYPE_SAR
Definition: rz_analysis.h:409
@ RZ_ANALYSIS_OP_TYPE_ABS
Definition: rz_analysis.h:428
@ RZ_ANALYSIS_OP_TYPE_NULL
Definition: rz_analysis.h:367
@ RZ_ANALYSIS_OP_TYPE_CMOV
Definition: rz_analysis.h:391
@ RZ_ANALYSIS_OP_TYPE_TRAP
Definition: rz_analysis.h:392
@ RZ_ANALYSIS_OP_TYPE_XCHG
Definition: rz_analysis.h:421
@ RZ_ANALYSIS_OP_TYPE_CALL
Definition: rz_analysis.h:378
@ RZ_ANALYSIS_OP_TYPE_SHR
Definition: rz_analysis.h:406
@ RZ_ANALYSIS_OP_TYPE_MOV
Definition: rz_analysis.h:390
@ RZ_ANALYSIS_OP_TYPE_ILL
Definition: rz_analysis.h:387
@ RZ_ANALYSIS_OP_TYPE_NOT
Definition: rz_analysis.h:414
@ RZ_ANALYSIS_OP_TYPE_RET
Definition: rz_analysis.h:385

References addr, ARC_REG_LIMM, ARC_REG_PCL, arcompact_genops_jmp(), fields, map_cond2rizin(), RZ_ANALYSIS_OP_TYPE_ABS, RZ_ANALYSIS_OP_TYPE_ADD, RZ_ANALYSIS_OP_TYPE_AND, RZ_ANALYSIS_OP_TYPE_CALL, RZ_ANALYSIS_OP_TYPE_CJMP, RZ_ANALYSIS_OP_TYPE_CMOV, RZ_ANALYSIS_OP_TYPE_CMP, RZ_ANALYSIS_OP_TYPE_ILL, RZ_ANALYSIS_OP_TYPE_IO, RZ_ANALYSIS_OP_TYPE_JMP, RZ_ANALYSIS_OP_TYPE_MOV, RZ_ANALYSIS_OP_TYPE_MUL, RZ_ANALYSIS_OP_TYPE_NOT, RZ_ANALYSIS_OP_TYPE_NULL, RZ_ANALYSIS_OP_TYPE_OR, RZ_ANALYSIS_OP_TYPE_RET, RZ_ANALYSIS_OP_TYPE_ROL, RZ_ANALYSIS_OP_TYPE_ROR, RZ_ANALYSIS_OP_TYPE_SAL, RZ_ANALYSIS_OP_TYPE_SAR, RZ_ANALYSIS_OP_TYPE_SHR, RZ_ANALYSIS_OP_TYPE_SUB, RZ_ANALYSIS_OP_TYPE_SWI, RZ_ANALYSIS_OP_TYPE_TRAP, RZ_ANALYSIS_OP_TYPE_XCHG, RZ_ANALYSIS_OP_TYPE_XOR, SIGN_EXT_S12, and SIGN_EXT_S13.

Referenced by arcompact_op().

◆ arcompact_genops_jmp()

static int arcompact_genops_jmp ( RzAnalysisOp op,
ut64  addr,
arc_fields f,
ut64  basic_type 
)
static

Definition at line 117 of file analysis_arc.c.

117  {
118  ut64 type_ujmp;
119  ut64 type_cjmp;
120  ut64 type_ucjmp;
121 
122  switch (basic_type) {
124  type_ujmp = RZ_ANALYSIS_OP_TYPE_UJMP;
125  type_cjmp = RZ_ANALYSIS_OP_TYPE_CJMP;
126  type_ucjmp = RZ_ANALYSIS_OP_TYPE_UCJMP;
127  break;
129  type_ujmp = RZ_ANALYSIS_OP_TYPE_UCALL;
130  type_cjmp = RZ_ANALYSIS_OP_TYPE_CCALL;
131  type_ucjmp = RZ_ANALYSIS_OP_TYPE_UCCALL;
132  break;
133  default:
134  return -1; /* Should not happen */
135  }
136 
137  f->cond = f->a & 0x1f;
138 
139  switch (f->format) {
140  case 0: /* unconditional jumps via reg or long imm */
141  if (f->c == ARC_REG_LIMM) {
142  /* limm */
143  op->type = basic_type;
144  arcompact_jump(op, addr, f->limm, f->mode_n);
145  return op->size;
146  }
147  if (f->c == ARC_REG_ILINK1 || f->c == ARC_REG_ILINK2 || f->c == ARC_REG_BLINK) {
148  /* ilink1, ilink2, blink */
149  /* Note: not valid for basic_type == CALL */
150  op->type = RZ_ANALYSIS_OP_TYPE_RET;
151  op->delay = f->mode_n;
152  return op->size;
153  }
154  op->type = type_ujmp;
155  return op->size;
156  case 1: /* unconditional jumps via u6 imm */
157  op->type = basic_type;
158  arcompact_jump(op, addr, f->c, f->mode_n);
159  return op->size;
160  case 2: /* unconditional jumps via s12 imm */
161  op->type = basic_type;
162  f->imm = (f->a << 6 | f->c);
163  f->imm = SIGN_EXT_S12(f->imm);
164  arcompact_jump(op, addr, f->imm, f->mode_n);
165  return op->size;
166  case 3: /* conditional jumps */
167  if (f->mode_m == 0) {
168  if (f->c == ARC_REG_LIMM) {
169  op->type = type_cjmp;
170  arcompact_jump_cond(op, addr, f->limm, f->mode_n, f->cond);
171  return op->size;
172  }
173  if (f->c == ARC_REG_ILINK1 || f->c == ARC_REG_ILINK2 || f->c == ARC_REG_BLINK) {
174  /* ilink1, ilink2, blink */
175  /* Note: not valid for basic_type == CALL */
177  op->cond = map_cond2rizin(f->cond);
178  op->delay = f->mode_n;
179  return op->size;
180  }
181 
182  op->cond = map_cond2rizin(f->cond);
183  op->type = type_ucjmp;
184  return op->size;
185  }
186 
187  op->type = type_cjmp;
188  arcompact_jump_cond(op, addr, f->c, f->mode_n, f->cond);
189  return op->size;
190  }
191 
192  /* should not be reached */
193  return 0;
194 }
#define ARC_REG_ILINK2
Definition: analysis_arc.c:11
#define ARC_REG_BLINK
Definition: analysis_arc.c:12
#define ARC_REG_ILINK1
Definition: analysis_arc.c:10
static void arcompact_jump_cond(RzAnalysisOp *op, ut64 addr, ut64 jump, ut8 delay, ut8 cond)
Definition: analysis_arc.c:97
@ RZ_ANALYSIS_OP_TYPE_UJMP
Definition: rz_analysis.h:369
@ RZ_ANALYSIS_OP_TYPE_UCCALL
Definition: rz_analysis.h:384
@ RZ_ANALYSIS_OP_TYPE_CCALL
Definition: rz_analysis.h:383
@ RZ_ANALYSIS_OP_TYPE_CRET
Definition: rz_analysis.h:386
@ RZ_ANALYSIS_OP_TYPE_UCJMP
Definition: rz_analysis.h:377
@ RZ_ANALYSIS_OP_TYPE_UCALL
Definition: rz_analysis.h:379
#define f(i)
Definition: sha256.c:46
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References addr, ARC_REG_BLINK, ARC_REG_ILINK1, ARC_REG_ILINK2, ARC_REG_LIMM, arcompact_jump(), arcompact_jump_cond(), f, map_cond2rizin(), RZ_ANALYSIS_OP_TYPE_CALL, RZ_ANALYSIS_OP_TYPE_CCALL, RZ_ANALYSIS_OP_TYPE_CJMP, RZ_ANALYSIS_OP_TYPE_CRET, RZ_ANALYSIS_OP_TYPE_JMP, RZ_ANALYSIS_OP_TYPE_RET, RZ_ANALYSIS_OP_TYPE_UCALL, RZ_ANALYSIS_OP_TYPE_UCCALL, RZ_ANALYSIS_OP_TYPE_UCJMP, RZ_ANALYSIS_OP_TYPE_UJMP, SIGN_EXT_S12, and ut64().

Referenced by arcompact_genops().

◆ arcompact_jump()

static void arcompact_jump ( RzAnalysisOp op,
ut64  addr,
ut64  jump,
ut8  delay 
)
static

Definition at line 91 of file analysis_arc.c.

91  {
92  op->jump = jump;
93  op->fail = addr + op->size;
94  op->delay = delay;
95 }
int jump(int a, int b)
Definition: bcj_test.c:35

References addr, and jump().

Referenced by arcompact_branch(), arcompact_genops_jmp(), arcompact_jump_cond(), and arcompact_op().

◆ arcompact_jump_cond()

static void arcompact_jump_cond ( RzAnalysisOp op,
ut64  addr,
ut64  jump,
ut8  delay,
ut8  cond 
)
static

Definition at line 97 of file analysis_arc.c.

97  {
98  arcompact_jump(op, addr, jump, delay);
99  op->cond = map_cond2rizin(cond);
100 }
#define cond(bop, top, mask, flags)

References addr, arcompact_jump(), cond, jump(), and map_cond2rizin().

Referenced by arcompact_genops_jmp().

◆ arcompact_op()

static int arcompact_op ( RzAnalysis analysis,
RzAnalysisOp op,
ut64  addr,
const ut8 data,
int  len 
)
static

Definition at line 441 of file analysis_arc.c.

441  {
442  ut32 words[2]; /* storage for the de-swizled opcode data */
444 
445  /* ARCompact ISA, including */
446  /* ARCtangent-A5, ARC 600, ARC 700 */
447 
448  /* no unaligned code */
449  if (addr % 2 != 0) {
450  /* this fixes some of the reverse disassembly issues */
451  op->type = RZ_ANALYSIS_OP_TYPE_ILL;
452  return 0;
453  }
454  if (len < 8) {
455  // when rz_read_me32_arc/be32 oob read
456  return 0;
457  }
458 
459  op->type = RZ_ANALYSIS_OP_TYPE_UNK;
460  op->ptr = UT64_MAX;
461  op->val = UT64_MAX;
462  op->jump = UT64_MAX;
463  op->fail = UT64_MAX;
464  op->refptr = 0;
465  op->delay = 0;
466 
467  if (analysis->big_endian) {
468  words[0] = rz_read_be32(&data[0]);
469  words[1] = rz_read_be32(&data[4]);
470  } else {
471  words[0] = rz_read_me32_arc(&data[0]);
472  words[1] = rz_read_me32_arc(&data[4]);
473  }
474 
475  fields.opcode = (words[0] & 0xf8000000) >> 27;
476 
477  op->size = (fields.opcode >= 0x0c) ? 2 : 4;
478  op->nopcode = op->size;
479 
480  switch (fields.opcode) {
481  case 0:
482  fields.format = (words[0] & 0x00010000) >> 16;
483  fields.a = (words[0] & 0x07fe0000) >> 17;
484  fields.b = (words[0] & 0x0000ffc0) >> 6;
485  fields.c = (words[0] & 0x0000000f);
486  fields.mode_n = (words[0] & 0x20) >> 5;
487  fields.limm = fields.a << 1 | fields.b << 11;
488 
489  if (fields.format == 0) {
490  /* Branch Conditionally 0x00 [0x0] */
491  fields.limm = SIGN_EXT_S21(fields.limm);
492  fields.cond = (words[0] & 0x1f);
493  op->cond = map_cond2rizin(fields.cond);
495  } else {
496  /* Branch Unconditional Far 0x00 [0x1] */
497  fields.limm |= (fields.c & 0x0f) << 21;
498  /* the & 0xf clearly shows we don't overflow */
499  /* TODO: don't generate code to show this */
500  fields.limm = SIGN_EXT_S25(fields.limm);
501  op->type = RZ_ANALYSIS_OP_TYPE_JMP;
502  }
503  arcompact_branch(op, addr, fields.limm, fields.mode_n);
504  break;
505  case 1:
506  fields.format = (words[0] & 0x00010000) >> 16;
507  fields.mode_n = (words[0] & 0x20) >> 5;
508 
509  if (fields.format == 1) {
510  fields.format2 = (words[0] & 0x10) >> 4;
511  fields.subopcode = (words[0] & 0x0f);
512  fields.b = (words[0] & 0x07000000) >> 24 | (words[0] & 0x7000) >> 9;
513  fields.c = (words[0] & 0x00000fc0) >> 6;
514  fields.imm = SIGN_EXT_S9((words[0] & 0x00fe0000) >> 16 | (words[0] & 0x8000) >> 7);
516 
517  if (fields.format2 == 0) {
518  /* Branch on Compare Register-Register, 0x01, [0x1, 0x0] */
519  if (fields.b == ARC_REG_LIMM || fields.c == ARC_REG_LIMM) {
520  op->size = 8;
521  fields.limm = words[1];
522  }
523  /* TODO: cond codes (using the "br" mapping) */
524  } else {
525  /* Branch on Compare/Bit Test Register-Immediate, 0x01, [0x1, 0x1] */
526  /* TODO: cond codes and imm u6 (using the "br" mapping) */
527  }
528  arcompact_branch(op, addr, fields.imm, fields.mode_n);
529  } else {
530  fields.format2 = (words[0] & 0x00020000) >> 17;
531  fields.a = (words[0] & 0x07fc0000) >> 18;
532  fields.b = (words[0] & 0x0000ffc0) >> 6;
533  fields.c = (words[0] & 0x0000000f);
534  fields.imm = fields.a << 2 | fields.b << 11;
535 
536  if (fields.format2 == 0) {
537  /* Branch and Link Conditionally, 0x01, [0x0, 0x0] */
538  fields.imm = SIGN_EXT_S21(fields.imm);
539  fields.cond = (words[0] & 0x1f);
540  op->cond = map_cond2rizin(fields.cond);
542  } else {
543  /* Branch and Link Unconditional Far, 0x01, [0x0, 0x1] */
544  fields.imm |= (fields.c & 0x0f) << 21;
545  /* the & 0xf clearly shows we don't overflow */
546  /* TODO: don't generate code to show this */
547  fields.imm = SIGN_EXT_S25(fields.imm);
549  }
550  arcompact_branch(op, addr, fields.imm, fields.mode_n);
551  }
552  break;
553  case 2: /* Load Register with Offset, 0x02 */
554  fields.a = (words[0] & 0x0000003f);
555  fields.b = (words[0] & 0x07000000) >> 24 | (words[0] & 0x7000) >> 9;
556  fields.imm = SIGN_EXT_S9((words[0] & 0x00ff0000) >> 16 | (words[0] & 0x8000) >> 7);
557  /* fields.mode_aa = (words[0] & 0x600) >> 9; */
558  fields.mode_zz = (words[0] & 0x180) >> 7;
559 
561 
562  /* dst (fields.a) cannot be an extension core register */
563  if (fields.a == ARC_REG_PCL || fields.a == 61 || (fields.a >= 0x20 && fields.a <= 0x2b)) {
564  op->type = RZ_ANALYSIS_OP_TYPE_ILL;
565  }
566 
567  map_zz2refptr(op, fields.mode_zz);
568 
569  if (fields.b == ARC_REG_LIMM) {
570  op->size = 8;
571  fields.limm = words[1];
572  op->ptr = fields.limm + fields.imm;
573  /* fields.aa is reserved - and ignored with limm */
574  } else if (fields.b == ARC_REG_PCL) { /* PCL */
575  op->ptr = (addr & ~3) + fields.imm;
576  }
577  /* TODO: set op with GP,FP,SP src/dst details */
578  break;
579  case 3: /* Store Register with Offset, 0x03 */
580  fields.c = (words[0] & 0xfc0) >> 6;
581  fields.b = (words[0] & 0x07000000) >> 24 | (words[0] & 0x7000) >> 9;
582  fields.imm = SIGN_EXT_S9((words[0] & 0x00ff0000) >> 16 | (words[0] & 0x8000) >> 7);
583  /* ut8 mode_aa = (words[0] & 0x18) >> 3; */
584  fields.mode_zz = (words[0] & 0x6) >> 1;
585 
587 
588  map_zz2refptr(op, fields.mode_zz);
589 
590  if (fields.b == ARC_REG_LIMM) {
591  op->size = 8;
592  fields.limm = words[1];
593  op->ptr = fields.limm;
594  } else if (fields.c == ARC_REG_LIMM) {
595  op->size = 8;
596  fields.limm = words[1];
597  op->val = fields.limm;
598  }
599 
600  if (fields.b == ARC_REG_PCL) { /* PCL */
601  op->ptr = (addr & ~3) + fields.imm;
602  }
603  /* TODO: set op with GP,FP,SP src/dst details */
604  break;
605  case 4: /* General Operations */
606  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
607  return arcompact_genops(op, addr, words);
608  case 5:
609  case 6:
610  case 7:
611  case 8: /* 32-bit Extension Instructions, 0x05 - 0x08 */
612  fields.subopcode = (words[0] & 0x003f0000) >> 16;
613  fields.format = (words[0] & 0x00c00000) >> 22;
614  fields.c = (words[0] & 0x00000fc0) >> 6;
615  fields.a = (words[0] & 0x0000003f);
616  fields.b = (words[0] & 0x07000000) >> 24 | (words[0] & 0x7000) >> 9;
617 
618  if (fields.b == ARC_REG_LIMM) {
619  op->size = 8;
620  fields.limm = words[1];
621  } else if ((fields.format == 0 || fields.format == 1) && (fields.a == ARC_REG_LIMM)) {
622  op->size = 8;
623  fields.limm = words[1];
624  } else if ((fields.format == 0) && (fields.c == ARC_REG_LIMM)) {
625  op->size = 8;
626  fields.limm = words[1];
627  } else if ((fields.format == 3) && ((fields.a & 0x20) == 0x20) && (fields.c == ARC_REG_LIMM)) {
628  op->size = 8;
629  fields.limm = words[1];
630  }
631  /* TODO: fill in the extansion functions */
632  // op->type = RZ_ANALYSIS_OP_TYPE_UNK;
633  // op->type = RZ_ANALYSIS_OP_TYPE_SHL;
634  op->type = RZ_ANALYSIS_OP_TYPE_SHR;
635  break;
636  case 0x09:
637  case 0x0a:
638  case 0x0b: /* Market Specific Extension Instructions, 0x09 - 0x0B */
639  op->type = RZ_ANALYSIS_OP_TYPE_UNK;
640  break;
641  case 0x0c: /* Load /Add Register-Register, 0x0C, [0x00 - 0x03] */
643  fields.subopcode = (words[0] & 0x00180000) >> 19;
644  /* fields.a = (words[0] & 0x00070000) >> 16; */
645  /* fields.c = (words[0] & 0x00e00000) >> 21; */
646  /* fields.b = (words[0] & 0x07000000) >> 24; */
647 
648  switch (fields.subopcode) {
649  case 0: /* Load long word (reg.+reg.) */
650  case 1: /* Load unsigned byte (reg.+reg.) */
651  case 2: /* Load unsigned word (reg.+reg.) */
653  break;
654  case 3: /* Add */
655  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
656  break;
657  }
658  break;
659  case 0x0d: /* Add/Sub/Shift Register-Immediate, 0x0D, [0x00 - 0x03] */
660  fields.subopcode = (words[0] & 0x00180000) >> 19;
661  /* fields.imm = (words[0] & 0x00070000) >> 16; src2 u3 */
662  /* fields.c = (words[0] & 0x00e00000) >> 21; dst */
663  /* fields.b = (words[0] & 0x07000000) >> 24; src1 */
664 
665  switch (fields.subopcode) {
666  case 0: /* Add */
667  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
668  break;
669  case 1: /* Subtract */
670  op->type = RZ_ANALYSIS_OP_TYPE_SUB;
671  break;
672  case 2: /* Multiple arithmetic shift left */
673  op->type = RZ_ANALYSIS_OP_TYPE_SHL;
674  break;
675  case 3: /* Multiple arithmetic shift right */
676  op->type = RZ_ANALYSIS_OP_TYPE_SHR;
677  break;
678  }
679  break;
680  case 0x0e: /* Mov/Cmp/Add with High Register, 0x0E, [0x00 - 0x03] */
681  fields.subopcode = (words[0] & 0x00180000) >> 19;
682  /* fields.b = (words[0] & 0x07000000) >> 24; dst, src1 */
683  fields.c = (words[0] & 0x00e00000) >> 21 | (words[0] & 0x00070000) >> 13; /* src2 */
684 
685  if (fields.c == ARC_REG_LIMM) {
686  op->size = 6;
687  op->val = (words[0] & 0x0000ffff) << 16 | (words[1] & 0xffff0000) >> 16;
688  }
689 
690  switch (fields.subopcode) {
691  case 0: /* Add */
692  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
693  break;
694  case 1: /* Move */
695  case 3: /* Move */
696  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
697  break;
698  case 2: /* Compare */
699  op->type = RZ_ANALYSIS_OP_TYPE_CMP;
700  break;
701  }
702  break;
703  case 0xf: /* General Register Format Instructions, 0x0F, [0x00 - 0x1F] */
704  fields.subopcode = (words[0] & 0x001f0000) >> 16;
705  fields.c = (words[0] & 0x00e00000) >> (16 + 5);
706  fields.b = (words[0] & 0x07000000) >> (16 + 8);
707 
708  switch (fields.subopcode) {
709  case 0: /* Single Operand, Jumps and Special Format Instructions, 0x0F, [0x00, 0x00 - 0x07] */
710  switch (fields.c) {
711  case 0: /* J_S [r]*/
713  arcompact_jump(op, 0, 0, 0);
714  break;
715  case 1: /* J_S.D [r] */
717  arcompact_jump(op, 0, 0, 1);
718  break;
719  case 2: /* JL_S [r] */
721  arcompact_jump(op, 0, 0, 0);
722  break;
723  case 3: /* JL_S.D [r] */
725  arcompact_jump(op, 0, 0, 1);
726  break;
727  case 4:
728  case 5: /* Reserved - instruction error */
729  op->type = RZ_ANALYSIS_OP_TYPE_ILL;
730  break;
731  case 6: /* SUB_S.NE [b] */
732  op->cond = RZ_TYPE_COND_NE;
733  op->type = RZ_ANALYSIS_OP_TYPE_SUB;
734  break;
735  case 7: /* Zero Operand Instructions, 0x0F, [0x00, 0x07, 0x00 - 0x07] */
736  switch (fields.b) {
737  case 0: /* nop_s */
738  op->type = RZ_ANALYSIS_OP_TYPE_NOP;
739  op->size = 4;
740  break;
741  case 1:
742  case 2:
743  case 3: /* unimplemented and Reserved - instruction error */
744  op->type = RZ_ANALYSIS_OP_TYPE_ILL;
745  break;
746  case 4: /* JEQ_S [blink] */
747  op->cond = RZ_TYPE_COND_EQ;
749  break;
750  case 5: /* JNE_S [blink] */
751  op->cond = RZ_TYPE_COND_NE;
753  break;
754  case 7: /* J_S.D [blink] */
755  op->delay = 1;
756  /* fall through */
757  case 6: /* J_S [blink] */
758  op->type = RZ_ANALYSIS_OP_TYPE_RET;
759  break;
760  }
761  break;
762  }
763  break;
764  case 1:
765  case 3:
766  case 8:
767  case 9:
768  case 0xa:
769  case 0x17: /* Reserved - instruction error */
770  op->type = RZ_ANALYSIS_OP_TYPE_ILL;
771  break;
772  case 2:
773  op->type = RZ_ANALYSIS_OP_TYPE_SUB;
774  break;
775  case 4:
776  op->type = RZ_ANALYSIS_OP_TYPE_AND;
777  break;
778  case 5:
779  op->type = RZ_ANALYSIS_OP_TYPE_OR;
780  break;
781  case 6: /* Logical bitwise AND with invert */
782  /* dest = src1 AND NOT src2 */
783  op->type = RZ_ANALYSIS_OP_TYPE_AND;
784  break;
785  case 7:
786  op->type = RZ_ANALYSIS_OP_TYPE_XOR;
787  break;
788  case 0xb: /* Test */
789  /* no dst, b AND c */
790  op->type = RZ_ANALYSIS_OP_TYPE_AND;
791  break;
792  case 0xc:
793  op->type = RZ_ANALYSIS_OP_TYPE_MUL;
794  break;
795  case 0xd: /* Sign extend byte */
796  case 0xe: /* Sign extend word */
797  case 0xf: /* Zero extend byte */
798  case 0x10: /* Zero extend word */
799  case 0x13: /* Negate */
800  op->type = RZ_ANALYSIS_OP_TYPE_CPL;
801  break;
802  case 0x11:
803  op->type = RZ_ANALYSIS_OP_TYPE_ABS;
804  break;
805  case 0x12:
806  op->type = RZ_ANALYSIS_OP_TYPE_NOT;
807  break;
808  case 0x14: /* Add with left shift by 1 */
809  case 0x15: /* Add with left shift by 2 */
810  case 0x16: /* Add with left shift by 3 */
811  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
812  break;
813  case 0x18: /* Multiple arithmetic shift left */
814  op->type = RZ_ANALYSIS_OP_TYPE_SAL;
815  break;
816  case 0x19: /* Multiple logical shift right */
817  op->type = RZ_ANALYSIS_OP_TYPE_SHR;
818  break;
819  case 0x1a: /* Multiple arithmetic shift right */
820  op->type = RZ_ANALYSIS_OP_TYPE_SAR;
821  break;
822  case 0x1b: /* Arithmetic shift left by one */
823  op->type = RZ_ANALYSIS_OP_TYPE_SAL;
824  break;
825  case 0x1c: /* Arithmetic shift right by one */
826  op->type = RZ_ANALYSIS_OP_TYPE_SAR;
827  break;
828  case 0x1d: /* Logical shift right by one */
829  op->type = RZ_ANALYSIS_OP_TYPE_SHL;
830  break;
831  case 0x1e:
833  /* TODO: the description sounds more like a */
834  /* RZ_ANALYSIS_OP_TYPE_SWI, but I don't know what */
835  /* difference that would make to rizin */
836  break;
837  case 0x1f:
839  /* TODO: this should be RZ_ANALYSIS_OP_TYPE_DEBUG, */
840  /* but that type is commented out */
841  break;
842  }
843  break;
844  case 0x10: /* LD_S c,[b,u7] */
845  case 0x11: /* LDB_S c,[b,u5] */
846  case 0x12: /* LDW_S c,[b,u6] */
847  case 0x13: /* LDW_S.X c,[b,u6] */
848  /* Load/Store with Offset, 0x10 - 0x16 */
850  break;
851  case 0x14: /* ST_S c, [b, u7] */
852  case 0x15: /* STB_S c, [b, u5] */
853  case 0x16: /* STW_S c, [b, u6] */
854  /* Load/Store with Offset, 0x10 - 0x16 */
856  break;
857  case 0x17: /* Shift/Subtract/Bit Immediate, 0x17, [0x00 - 0x07] */
858  fields.subopcode = (words[0] & 0x00e00000) >> (16 + 5);
859  switch (fields.subopcode) {
860  case 0: /* Multiple arithmetic shift left */
861  op->type = RZ_ANALYSIS_OP_TYPE_SAL;
862  break;
863  case 1: /* Multiple logical shift left */
864  op->type = RZ_ANALYSIS_OP_TYPE_SHL;
865  break;
866  case 2: /* Multiple arithmetic shift right */
867  op->type = RZ_ANALYSIS_OP_TYPE_SAR;
868  break;
869  case 3: /* Subtract */
870  op->type = RZ_ANALYSIS_OP_TYPE_SUB;
871  break;
872  case 4: /* Bit set */
873  op->type = RZ_ANALYSIS_OP_TYPE_OR;
874  break;
875  case 5: /* Bit clear */
876  case 6: /* Bit mask */
877  case 7: /* Bit test */
878  op->type = RZ_ANALYSIS_OP_TYPE_AND;
879  break;
880  }
881  break;
882  case 0x18: /* Stack Pointer Based Instructions, 0x18, [0x00 - 0x07] */
883  fields.subopcode = (words[0] & 0x00e00000) >> (16 + 5);
884  switch (fields.subopcode) {
885  case 0: /* Load long word sp-rel. */
886  case 1: /* Load unsigned byte sp-rel. */
888  break;
889  case 2: /* Store long word sp-rel. */
890  case 3: /* Store unsigned byte sp-rel. */
892  break;
893  case 4: /* Add */
894  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
895  break;
896  case 5: /* Add/Subtract SP Relative, 0x18, [0x05, 0x00-0x07] */
897  fields.b = (words[0] & 0x07000000) >> (16 + 8);
898  switch (fields.b) {
899  case 0: /* Add immediate to SP */
900  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
901  break;
902  case 1: /* Subtract immediate from SP */
903  op->type = RZ_ANALYSIS_OP_TYPE_SUB;
904  break;
905  default:
906  op->type = RZ_ANALYSIS_OP_TYPE_ILL;
907  break;
908  }
909  break;
910  case 6: /* POP Register from Stack, 0x18, [0x06, 0x00-0x1F] */
911  fields.c = (words[0] & 0x001f0000) >> 16;
912  switch (fields.c) {
913  case 1: /* Pop register from stack */
914  case 0x11: /* Pop blink from stack */
915  op->type = RZ_ANALYSIS_OP_TYPE_POP;
916  break;
917  default:
918  op->type = RZ_ANALYSIS_OP_TYPE_ILL;
919  break;
920  }
921  break;
922  case 7: /* PUSH Register to Stack, 0x18, [0x07, 0x00-0x1F] */
923  fields.c = (words[0] & 0x001f0000) >> 16;
924  switch (fields.c) {
925  case 1: /* Push register to stack */
926  case 0x11: /* Push blink to stack */
928  break;
929  default:
930  op->type = RZ_ANALYSIS_OP_TYPE_ILL;
931  break;
932  }
933  break;
934  }
935  break;
936  case 0x19: /* Load/Add GP-Relative, 0x19, [0x00 - 0x03] */
937  fields.subopcode = (words[0] & 0x06000000) >> (16 + 9);
938  switch (fields.subopcode) {
939  case 0: /* Load gp-relative (32-bit aligned) to r0 */
940  case 1: /* Load unsigned byte gp-relative (8-bit aligned) to r0 */
941  case 2: /* Load unsigned word gp-relative (16-bit aligned) to r0 */
943  break;
944  case 3: /* Add gp-relative (32-bit aligned) to r0 */
945  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
946  break;
947  }
948  op->type = RZ_ANALYSIS_OP_TYPE_UNK;
949  break;
950  case 0x1a: /* Load PCL-Relative, 0x1A */
951  fields.c = (words[0] & 0x00ff0000) >> 14;
952  op->ptr = (addr & ~3) + fields.c;
953  op->refptr = 4;
955  break;
956  case 0x1b: /* Move Immediate, 0x1B */
957  op->val = (words[0] & 0x00ff0000) >> 16;
958  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
959  break;
960  case 0x1c: /* ADD/CMP Immediate, 0x1C, [0x00 - 0x01] */
961  fields.subopcode = (words[0] & 0x00800000) >> (16 + 7);
962  if (fields.subopcode == 0) {
963  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
964  } else {
965  op->type = RZ_ANALYSIS_OP_TYPE_CMP;
966  }
967  break;
968  case 0x1d: /* Branch on Compare Register with Zero, 0x1D, [0x00 - 0x01] */
969  /* fields.subopcode = (words[0] & 0x00800000) >> (16+7); */
970  fields.imm = SIGN_EXT_S8((words[0] & 0x007f0000) >> (16 - 1));
971  /* fields.subopcode? reg NE: reg EQ; */
973  arcompact_branch(op, addr, fields.imm, 0);
974  break;
975  case 0x1e: /* Branch Conditionally, 0x1E, [0x00 - 0x03] */
976  fields.subopcode = (words[0] & 0x06000000) >> (16 + 9);
977  fields.imm = SIGN_EXT_S10((words[0] & 0x01ff0000) >> (16 - 1));
978  switch (fields.subopcode) {
979  case 0: /* B_S */
980  op->type = RZ_ANALYSIS_OP_TYPE_JMP;
981  break;
982  case 1: /* BEQ_S */
983  op->cond = RZ_TYPE_COND_EQ;
985  break;
986  case 2: /* BNE_S */
987  op->cond = RZ_TYPE_COND_NE;
989  break;
990  case 3: /* Bcc_S */
992  fields.imm = SIGN_EXT_S7((words[0] & 0x003f0000) >> (16 - 1));
993  /* TODO: cond codes (looks like it is the BR table again?) */
994  break;
995  }
996  arcompact_branch(op, addr, fields.imm, 0);
997  break;
998  case 0x1f: /* Branch and Link Unconditionally, 0x1F */
999  fields.imm = SIGN_EXT_S13((words[0] & 0x07ff0000) >> (16 - 2));
1000  op->type = RZ_ANALYSIS_OP_TYPE_CALL;
1001  arcompact_branch(op, addr, fields.imm, 0);
1002  break;
1003  }
1004  return op->size;
1005 }
#define SIGN_EXT_S8(imm)
Definition: analysis_arc.c:54
static void arcompact_branch(RzAnalysisOp *op, ut64 addr, st64 offset, ut8 delay)
Definition: analysis_arc.c:102
#define SIGN_EXT_S7(imm)
Definition: analysis_arc.c:53
static int arcompact_genops(RzAnalysisOp *op, ut64 addr, ut32 words[2])
Definition: analysis_arc.c:196
#define SIGN_EXT_S21(imm)
Definition: analysis_arc.c:59
#define SIGN_EXT_S9(imm)
Definition: analysis_arc.c:55
static void map_zz2refptr(RzAnalysisOp *op, ut8 mode_zz)
Definition: analysis_arc.c:106
static ut32 rz_read_me32_arc(const void *src)
Definition: analysis_arc.c:37
#define SIGN_EXT_S10(imm)
Definition: analysis_arc.c:56
#define SIGN_EXT_S25(imm)
Definition: analysis_arc.c:60
uint32_t ut32
@ RZ_ANALYSIS_OP_TYPE_LOAD
Definition: rz_analysis.h:416
@ RZ_ANALYSIS_OP_TYPE_UNK
Definition: rz_analysis.h:388
@ RZ_ANALYSIS_OP_TYPE_STORE
Definition: rz_analysis.h:415
@ RZ_ANALYSIS_OP_TYPE_CPL
Definition: rz_analysis.h:429
@ RZ_ANALYSIS_OP_TYPE_PUSH
Definition: rz_analysis.h:397
@ RZ_ANALYSIS_OP_TYPE_POP
Definition: rz_analysis.h:398
@ RZ_ANALYSIS_OP_TYPE_SHL
Definition: rz_analysis.h:407
static ut32 rz_read_be32(const void *src)
Definition: rz_endian.h:87
@ RZ_TYPE_COND_EQ
Equal.
Definition: rz_type.h:184
@ RZ_TYPE_COND_NE
Not equal.
Definition: rz_type.h:185
#define UT64_MAX
Definition: rz_types_base.h:86

References addr, ARC_REG_LIMM, ARC_REG_PCL, arcompact_branch(), arcompact_genops(), arcompact_jump(), rz_analysis_t::big_endian, fields, len, map_cond2rizin(), map_zz2refptr(), RZ_ANALYSIS_OP_TYPE_ABS, RZ_ANALYSIS_OP_TYPE_ADD, RZ_ANALYSIS_OP_TYPE_AND, RZ_ANALYSIS_OP_TYPE_CALL, RZ_ANALYSIS_OP_TYPE_CCALL, RZ_ANALYSIS_OP_TYPE_CJMP, RZ_ANALYSIS_OP_TYPE_CMP, RZ_ANALYSIS_OP_TYPE_CPL, RZ_ANALYSIS_OP_TYPE_CRET, RZ_ANALYSIS_OP_TYPE_ILL, RZ_ANALYSIS_OP_TYPE_JMP, RZ_ANALYSIS_OP_TYPE_LOAD, RZ_ANALYSIS_OP_TYPE_MOV, RZ_ANALYSIS_OP_TYPE_MUL, RZ_ANALYSIS_OP_TYPE_NOP, RZ_ANALYSIS_OP_TYPE_NOT, RZ_ANALYSIS_OP_TYPE_OR, RZ_ANALYSIS_OP_TYPE_POP, RZ_ANALYSIS_OP_TYPE_PUSH, RZ_ANALYSIS_OP_TYPE_RET, RZ_ANALYSIS_OP_TYPE_SAL, RZ_ANALYSIS_OP_TYPE_SAR, RZ_ANALYSIS_OP_TYPE_SHL, RZ_ANALYSIS_OP_TYPE_SHR, RZ_ANALYSIS_OP_TYPE_STORE, RZ_ANALYSIS_OP_TYPE_SUB, RZ_ANALYSIS_OP_TYPE_TRAP, RZ_ANALYSIS_OP_TYPE_UCALL, RZ_ANALYSIS_OP_TYPE_UJMP, RZ_ANALYSIS_OP_TYPE_UNK, RZ_ANALYSIS_OP_TYPE_XOR, rz_read_be32(), rz_read_me32_arc(), RZ_TYPE_COND_EQ, RZ_TYPE_COND_NE, SIGN_EXT_S10, SIGN_EXT_S13, SIGN_EXT_S21, SIGN_EXT_S25, SIGN_EXT_S7, SIGN_EXT_S8, SIGN_EXT_S9, and UT64_MAX.

Referenced by arc_op().

◆ get_reg_profile()

static char* get_reg_profile ( RzAnalysis analysis)
static

Definition at line 1076 of file analysis_arc.c.

1076  {
1077  if (analysis->bits != 16) {
1078  return false;
1079  }
1080  const char *p16 =
1081  "=PC pcl\n"
1082  "=SP sp\n"
1083  "=LR blink\n"
1084  // "=BP r27\n" // ??
1085  "=A0 r0\n"
1086  "=A1 r1\n"
1087  "=A2 r2\n"
1088  "=A3 r3\n"
1089 
1090  "gpr r0 .32 0 0\n"
1091  "gpr r1 .32 4 0\n"
1092  "gpr r2 .32 8 0\n"
1093  "gpr r3 .32 12 0\n"
1094  "gpr r4 .32 16 0\n"
1095  "gpr r5 .32 20 0\n"
1096  "gpr r6 .32 24 0\n"
1097  "gpr r7 .32 28 0\n"
1098  "gpr r8 .32 32 0\n"
1099  "gpr r9 .32 36 0\n"
1100  "gpr r10 .32 40 0\n"
1101  "gpr r11 .32 44 0\n"
1102  "gpr r12 .32 48 0\n"
1103  "gpr r13 .32 52 0\n"
1104  "gpr r14 .32 56 0\n"
1105  "gpr r15 .32 60 0\n"
1106  "gpr r16 .32 64 0\n"
1107  "gpr r17 .32 68 0\n"
1108  "gpr r18 .32 72 0\n"
1109  "gpr r19 .32 76 0\n"
1110  "gpr r20 .32 80 0\n"
1111  "gpr r21 .32 84 0\n"
1112  "gpr r22 .32 88 0\n"
1113  "gpr r23 .32 92 0\n"
1114  "gpr r24 .32 96 0\n"
1115  "gpr r25 .32 100 0\n"
1116  "gpr gp .32 104 0\n"
1117  "gpr fp .32 108 0\n"
1118  "gpr sp .32 112 0\n"
1119  "gpr ilink1 .32 116 0\n"
1120  "gpr ilink2 .32 120 0\n"
1121  "gpr blink .32 124 0\n"
1122  "gpr lp_count .32 128 0\n"
1123  "gpr pcl .32 132 0\n";
1124 
1125  /* TODO: */
1126  /* Should I add the Auxiliary Register Set? */
1127  /* it contains the flag bits, amongst other things */
1128  return strdup(p16);
1129 }
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")

References rz_analysis_t::bits, and strdup().

◆ map_cond2rizin()

static int map_cond2rizin ( ut8  cond)
static

Definition at line 62 of file analysis_arc.c.

62  {
63  switch (cond) {
64  case 0: return RZ_TYPE_COND_AL;
65  case 1: return RZ_TYPE_COND_EQ;
66  case 2: return RZ_TYPE_COND_NE;
67  case 3: return RZ_TYPE_COND_PL;
68  case 4: return RZ_TYPE_COND_MI;
69  case 7: return RZ_TYPE_COND_VS;
70  case 8: return RZ_TYPE_COND_VC;
71  case 9: return RZ_TYPE_COND_GT;
72  case 0xa: return RZ_TYPE_COND_GE;
73  case 0xb: return RZ_TYPE_COND_LT;
74  case 0xc: return RZ_TYPE_COND_LE;
75  case 0xd: return RZ_TYPE_COND_HI;
76  case 0xe: return RZ_TYPE_COND_LS;
77 #if 0
78  /* TODO: */
79  /* - rizin defines RZ_TYPE_COND_LO as carry clear and _HS as carry set */
80  /* which appears different to the ARC definitions. */
81  /* Need to do some math and double check the details */
82  case 5: return RZ_TYPE_COND_?? - CS,C,LO - Carry set & LO
83  case 6: return RZ_TYPE_COND_?? - CC,NC,HS - Carry clear & HS
84  /* - Positive non-zero doesnt map to any Radare cond code. Perhaps just add it? */
85  case 0xf: return RZ_TYPE_COND_?? - PNZ - Positive non-zero
86 #endif
87  }
88  return -1;
89 }
#define C(x)
Definition: arc.h:167
#define NC
Definition: utils.h:42
@ RZ_TYPE_COND_VS
Overflow Unordered.
Definition: rz_type.h:195
@ RZ_TYPE_COND_LE
Less or equal.
Definition: rz_type.h:188
@ RZ_TYPE_COND_GE
Greater or equal.
Definition: rz_type.h:186
@ RZ_TYPE_COND_VC
No overflow Not unordered.
Definition: rz_type.h:196
@ RZ_TYPE_COND_LS
Unsigned lower or same Less than or equal.
Definition: rz_type.h:198
@ RZ_TYPE_COND_AL
Always executed (no condition)
Definition: rz_type.h:183
@ RZ_TYPE_COND_MI
Minus, negative Less than.
Definition: rz_type.h:193
@ RZ_TYPE_COND_HI
Unsigned higher Greater than, or unordered.
Definition: rz_type.h:197
@ RZ_TYPE_COND_GT
Greater than.
Definition: rz_type.h:187
@ RZ_TYPE_COND_PL
Plus, positive or zero >, ==, or unordered.
Definition: rz_type.h:194
@ RZ_TYPE_COND_LT
Less than.
Definition: rz_type.h:189

References C, cond, NC, RZ_TYPE_COND_AL, RZ_TYPE_COND_EQ, RZ_TYPE_COND_GE, RZ_TYPE_COND_GT, RZ_TYPE_COND_HI, RZ_TYPE_COND_LE, RZ_TYPE_COND_LS, RZ_TYPE_COND_LT, RZ_TYPE_COND_MI, RZ_TYPE_COND_NE, RZ_TYPE_COND_PL, RZ_TYPE_COND_VC, and RZ_TYPE_COND_VS.

Referenced by arcompact_genops(), arcompact_genops_jmp(), arcompact_jump_cond(), and arcompact_op().

◆ map_zz2refptr()

static void map_zz2refptr ( RzAnalysisOp op,
ut8  mode_zz 
)
static

Definition at line 106 of file analysis_arc.c.

106  {
107  switch (mode_zz) {
108  case 0: op->refptr = 4; break;
109  case 1: op->refptr = 1; break;
110  case 2: op->refptr = 2; break;
111  default:
112  op->type = RZ_ANALYSIS_OP_TYPE_ILL;
113  break;
114  }
115 }

References RZ_ANALYSIS_OP_TYPE_ILL.

Referenced by arcompact_op().

◆ rz_read_me32_arc()

static ut32 rz_read_me32_arc ( const void *  src)
inlinestatic

Definition at line 37 of file analysis_arc.c.

37  {
38  const ut8 *s = src;
39  return (((ut32)s[1]) << 24) | (((ut32)s[0]) << 16) | (((ut32)s[3]) << 8) | (((ut32)s[2]) << 0);
40 }
lzma_index * src
Definition: index.h:567
static RzSocket * s
Definition: rtr.c:28

References s, and src.

Referenced by arcompact_op().

◆ sign_ext()

static int sign_ext ( int  bits,
int  imm 
)
static

Definition at line 42 of file analysis_arc.c.

42  {
43  int maxsint = (1 << (bits - 1)) - 1;
44  int maxuint = (1 << (bits)) - 1;
45 
46  if (imm > maxsint) {
47  /* sign extend */
48  imm = -maxuint + imm - 1;
49  }
50  return imm;
51 }
#define imm
int bits(struct state *s, int need)
Definition: blast.c:72

References bits(), and imm.

Variable Documentation

◆ rizin_plugin

RZ_API RzLibStruct rizin_plugin
Initial value:
= {
}
RzAnalysisPlugin rz_analysis_plugin_arc
@ 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 at line 1143 of file analysis_arc.c.

◆ rz_analysis_plugin_arc

RzAnalysisPlugin rz_analysis_plugin_arc
Initial value:
= {
.name = "arc",
.arch = "arc",
.license = "LGPL3",
.bits = 16 | 32,
.desc = "ARC code analysis plugin",
.op = &arc_op,
.archinfo = archinfo,
.get_reg_profile = get_reg_profile,
}
static char * get_reg_profile(RzAnalysis *analysis)
static int arc_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len, RzAnalysisOpMask mask)
static int archinfo(RzAnalysis *analysis, int query)

Definition at line 1131 of file analysis_arc.c.