Rizin
unix-like reverse engineering framework and cli tools
analysis_sparc_gnu.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2011-2015 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <string.h>
5 
6 #include <rz_types.h>
7 #include <rz_lib.h>
8 #include <rz_asm.h>
9 #include <rz_analysis.h>
10 
11 enum {
12  GPR_G0 = 0,
13  GPR_G1 = 1,
14  GPR_G2 = 2,
15  GPR_G3 = 3,
16  GPR_G4 = 4,
17  GPR_G5 = 5,
18  GPR_G6 = 6,
19  GPR_G7 = 7,
20  GPR_O0 = 8,
21  GPR_O1 = 9,
22  GPR_O2 = 10,
23  GPR_O3 = 11,
24  GPR_O4 = 12,
25  GPR_O5 = 13,
26  GPR_O6 = 14,
27  GPR_O7 = 15,
28  GPR_L0 = 16,
29  GPR_L1 = 17,
30  GPR_L2 = 18,
31  GPR_L3 = 19,
32  GPR_L4 = 20,
33  GPR_L5 = 21,
34  GPR_L6 = 22,
35  GPR_L7 = 23,
36  GPR_I0 = 24,
37  GPR_I1 = 25,
38  GPR_I2 = 26,
39  GPR_I3 = 27,
40  GPR_I4 = 28,
41  GPR_I5 = 29,
42  GPR_I6 = 30,
43  GPR_I7 = 31,
44 };
45 
46 const char *gpr_regs[] = { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
47  "o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7",
48  "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
49  "i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7" };
50 
51 enum {
52  ICC_A = 0x8,
53  ICC_CC = 0xd,
54  ICC_CS = 0x5,
55  ICC_E = 0x1,
56  ICC_G = 0xa,
57  ICC_GE = 0xb,
58  ICC_GU = 0xc,
59  ICC_L = 0x3,
60  ICC_LE = 0x2,
61  ICC_LEU = 0x4,
62  ICC_N = 0x0,
63  ICC_NE = 0x9,
64  ICC_NEG = 0x6,
65  ICC_POS = 0xe,
66  ICC_VC = 0xf,
67  ICC_VS = 0x7,
68 };
69 
70 enum {
71  FCC_A = 0x8,
72  FCC_E = 0x9,
73  FCC_G = 0x6,
74  FCC_GE = 0xb,
75  FCC_L = 0x4,
76  FCC_LE = 0xd,
77  FCC_LG = 0x2,
78  FCC_N = 0x0,
79  FCC_NE = 0x1,
80  FCC_O = 0xf,
81  FCC_U = 0x7,
82  FCC_UE = 0xa,
83  FCC_UG = 0x5,
84  FCC_UGE = 0xc,
85  FCC_UL = 0x3,
86  FCC_ULE = 0xe,
87 };
88 /* Define some additional conditions that are nor mappable to
89  the existing RZ_TYPE_COND* ones and need to be handled in a
90  special way. */
91 enum {
95 };
96 
97 static int icc_to_r_cond(const int cond) {
98  /* we treat signed and unsigned the same here */
99  switch (cond) {
100  case ICC_A: return RZ_TYPE_COND_ALWAYS;
101  case ICC_CC: return RZ_TYPE_COND_GE;
102  case ICC_CS: return RZ_TYPE_COND_LT;
103  case ICC_E: return RZ_TYPE_COND_EQ;
104  case ICC_G: return RZ_TYPE_COND_GT;
105  case ICC_GE: return RZ_TYPE_COND_GE;
106  case ICC_GU: return RZ_TYPE_COND_GT;
107  case ICC_L: return RZ_TYPE_COND_LT;
108  case ICC_LE: return RZ_TYPE_COND_LE;
109  case ICC_LEU: return RZ_TYPE_COND_LE;
110  case ICC_N: return RZ_TYPE_COND_NEVER;
111  case ICC_NE: return RZ_TYPE_COND_NE;
112  case ICC_NEG:
113  case ICC_POS:
114  case ICC_VC:
115  case ICC_VS:
116  default: return RZ_TYPE_COND_UNKNOWN;
117  }
118 }
119 
120 static int fcc_to_r_cond(const int cond) {
121  switch (cond) {
122  case FCC_A: return RZ_TYPE_COND_ALWAYS;
123  case FCC_E: return RZ_TYPE_COND_EQ;
124  case FCC_G: return RZ_TYPE_COND_GT;
125  case FCC_GE: return RZ_TYPE_COND_GE;
126  case FCC_L: return RZ_TYPE_COND_LT;
127  case FCC_LE: return RZ_TYPE_COND_LE;
128  case FCC_LG: return RZ_TYPE_COND_NE;
129  case FCC_N: return RZ_TYPE_COND_NEVER;
130  case FCC_NE: return RZ_TYPE_COND_NE;
131  case FCC_O:
132  case FCC_U:
133  case FCC_UE:
134  case FCC_UG:
135  case FCC_UGE:
136  case FCC_UL:
137  case FCC_ULE:
138  default:
139  return RZ_TYPE_COND_UNKNOWN;
140  }
141 }
142 
143 #define X_OP(i) (((i) >> 30) & 0x3)
144 #define X_OP2(i) (((i) >> 22) & 0x7)
145 #define X_OP3(i) (((i) >> 19) & 0x3f)
146 #define X_COND(i) (((i) >> 25) & 0x1f)
147 
148 #define X_RD(i) (((i) >> 25) & 0x1f)
149 #define X_RS1(i) (((i) >> 14) & 0x1f)
150 #define X_LDST_I(i) (((i) >> 13) & 1)
151 #define X_ASI(i) (((i) >> 5) & 0xff)
152 #define X_RS2(i) (((i) >> 0) & 0x1f)
153 #define X_IMM(i, n) (((i) >> 0) & ((1 << (n)) - 1))
154 #define X_SIMM(i, n) SIGN_EXT(X_IMM((i), (n)), (n))
155 #define X_DISP22(i) (((i) >> 0) & 0x3fffff)
156 #define X_IMM22(i) X_DISP22(i)
157 #define X_DISP30(i) (((i) >> 0) & 0x3fffffff)
158 
159 /* These are for v9. */
160 #define X_DISP16(i) (((((i) >> 20) & 3) << 14) | (((i) >> 0) & 0x3fff))
161 #define X_DISP19(i) (((i) >> 0) & 0x7ffff)
162 #define X_MEMBAR(i) ((i)&0x7f)
163 
164 enum {
165  OP_0 = 0,
166  OP_1 = 1,
167  OP_2 = 2,
168  OP_3 = 3,
169 };
170 
171 enum {
173  OP2_BPcc = 1,
174  OP2_Bicc = 2,
175  OP2_BPr = 3,
179  OP2_INV = 7,
180 };
181 
182 enum {
183  OP32_ADD = 0x00,
184  OP32_ADDcc = 0x10,
185  OP32_TADDcc = 0x20,
186  OP32_WRY = 0x30, /* or WRCCR WRASI WRASR WRFPRS SIR */
187  OP32_AND = 0x01,
188  OP32_ANDcc = 0x11,
189  OP32_TSUBcc = 0x21,
190  OP32_SAVED = 0x31, /* or RESTORED */
191  OP32_OR = 0x02,
192  OP32_ORcc = 0x12,
194  OP32_WRPR = 0x32,
195  OP32_XOR = 0x03,
196  OP32_XORcc = 0x13,
198  OP32_SUB = 0x04,
199  OP32_SUBcc = 0x14,
200  OP32_MULSccD = 0x24,
201  OP32_FPop1 = 0x34,
202  OP32_ANDN = 0x05,
203  OP32_ANDNcc = 0x15,
204  OP32_SLL = 0x25, /* or SLLX */
205  OP32_FPop2 = 0x35,
206  OP32_ORN = 0x06,
207  OP32_ORNcc = 0x16,
208  OP32_SRL = 0x26, /* or SLRX */
209  OP32_XNOR = 0x07,
210  OP32_XNORcc = 0x17,
211  OP32_SRA = 0x27, /* or SRAX */
212  OP32_ADDC = 0x08,
213  OP32_ADDCcc = 0x18,
214  OP32_RDY = 0x28, /* or RDCCR RDASI RDTICK RDPC RDFPRS RDASR
215  MEMBAR STBAR */
216  OP32_JMPL = 0x38,
217  OP32_MULX = 0x09,
218  OP32_RETURN = 0x39,
219  OP32_UMUL = 0x0a,
220  OP32_UMULcc = 0x1a,
221  OP32_RDPR = 0x2a,
222  OP32_Tcc = 0x3a,
223  OP32_SMULD = 0x0b,
224  OP32_SMULcc = 0x1b,
225  OP32_FLUSHW = 0x2b,
226  OP32_FLUSH = 0x3b,
227  OP32_SUBC = 0x0c,
228  OP32_SUBCcc = 0x1c,
229  OP32_MOVcc = 0x2c,
230  OP32_SAVE = 0x3c,
231  OP32_UDIVX = 0x0d,
232  OP32_SDIVX = 0x2d,
233  OP32_RESTORE = 0x3d,
234  OP32_UDIV = 0x0e,
235  OP32_UDIVcc = 0x1e,
236  OP32_POPC = 0x2e,
237  OP32_DONE = 0x3e, /* or RETRY */
238  OP32_SDIV = 0x0f,
239  OP32_SDIVcc = 0x1f,
240  OP32_MOVr = 0x2f,
241  /* always invalid */
242  OP32_INV1 = 0x33,
243  OP32_INV2 = 0x19,
244  OP32_INV3 = 0x29,
245  OP32_INV4 = 0x1d,
246  OP32_INV5 = 0x3f,
247  /* invalid under certain conditions */
251 };
252 
253 enum {
254  OP33_INV1 = 0x31,
255  OP33_INV2 = 0x35,
256  OP33_INV3 = 0x28,
257  OP33_INV4 = 0x38,
258  OP33_INV5 = 0x29,
259  OP33_INV6 = 0x39,
260  OP33_INV7 = 0x2a,
261  OP33_INV8 = 0x3a,
262  OP33_INV9 = 0x2b,
263  OP33_INV10 = 0x3b,
264  OP33_INV11 = 0x0c,
265  OP33_INV12 = 0x1c,
266  OP33_INV13 = 0x2c,
267  OP33_INV14 = 0x2e,
268  OP33_INV15 = 0x2f,
269  OP33_INV16 = 0x3f,
270 };
271 
272 static st64 get_immed_sgnext(const ut64 insn, const ut8 nbit) {
273  const ut64 mask = ~(((ut64)1 << (nbit + 1)) - 1);
274  return (st64)((insn & ~mask) | (((insn & ((ut64)1 << nbit)) >> nbit) * mask));
275 }
276 
279  val->base = addr + disp;
280  return val;
281 }
282 
283 static RzAnalysisValue *value_fill_addr_reg_regdelta(RzAnalysis const *const analysis, const int ireg, const int iregdelta) {
285  val->reg = rz_reg_get(analysis->reg, gpr_regs[ireg], RZ_REG_TYPE_GPR);
286  val->reg = rz_reg_get(analysis->reg, gpr_regs[iregdelta], RZ_REG_TYPE_GPR);
287  return val;
288 }
289 
290 static RzAnalysisValue *value_fill_addr_reg_disp(RzAnalysis const *const analysis, const int ireg, const st64 disp) {
292  val->reg = rz_reg_get(analysis->reg, gpr_regs[ireg], RZ_REG_TYPE_GPR);
293  val->delta = disp;
294  return val;
295 }
296 
297 static void analysis_call(RzAnalysisOp *op, const ut32 insn, const ut64 addr) {
298  const st64 disp = (get_immed_sgnext(insn, 29) * 4);
300  op->dst = value_fill_addr_pc_disp(addr, disp);
301  op->jump = addr + disp;
302  op->fail = addr + 4;
303 }
304 
305 static void analysis_jmpl(RzAnalysis const *const analysis, RzAnalysisOp *op, const ut32 insn, const ut64 addr) {
306  st64 disp = 0;
307  if (X_LDST_I(insn)) {
308  disp = get_immed_sgnext(insn, 12);
309  }
310 
311  if (X_RD(insn) == GPR_O7) {
313  op->fail = addr + 4;
314  } else if (X_RD(insn) == GPR_G0 && X_LDST_I(insn) == 1 && (X_RS1(insn) == GPR_I7 || X_RS1(insn) == GPR_O7) && disp == 8) {
315  op->type = RZ_ANALYSIS_OP_TYPE_RET;
316  op->eob = true;
317  return;
318  } else {
320  op->eob = true;
321  }
322 
323  if (X_LDST_I(insn)) {
324  op->dst = value_fill_addr_reg_disp(analysis, X_RS1(insn), disp);
325  } else {
326  op->dst = value_fill_addr_reg_regdelta(analysis, X_RS1(insn), X_RS2(insn));
327  }
328 }
329 
330 static void analysis_branch(RzAnalysisOp *op, const ut32 insn, const ut64 addr) {
331  st64 disp = 0;
332  int rz_cond = 0;
333  op->eob = true;
334 
335  /* handle the conditions */
336  if (X_OP2(insn) == OP2_Bicc || X_OP2(insn) == OP2_BPcc) {
337  rz_cond = icc_to_r_cond(X_COND(insn));
338  } else if (X_OP2(insn) == OP2_FBfcc || X_OP2(insn) == OP2_FBPfcc) {
339  rz_cond = fcc_to_r_cond(X_COND(insn));
340  } else if (X_OP2(insn) == OP2_BPr) {
341  rz_cond = RZ_TYPE_COND_UNKNOWN;
342  }
343 
344  if (rz_cond == RZ_TYPE_COND_ALWAYS) {
345  op->type = RZ_ANALYSIS_OP_TYPE_JMP;
346  } else if (rz_cond == RZ_TYPE_COND_NEVER) {
347  op->type = RZ_ANALYSIS_OP_TYPE_NOP;
348  return;
349  } else {
351  op->fail = addr + 4;
352  }
353 
354  /* handle displacement */
355  if (X_OP2(insn) == OP2_Bicc || X_OP2(insn) == OP2_FBfcc) {
356  disp = get_immed_sgnext(insn, 21) * 4;
357  } else if (X_OP2(insn) == OP2_BPcc || X_OP2(insn) == OP2_FBPfcc) {
358  disp = get_immed_sgnext(insn, 18) * 4;
359  } else if (X_OP2(insn) == OP2_BPr) {
360  disp = get_immed_sgnext(X_DISP16(insn), 15) * 4;
361  }
362  op->dst = value_fill_addr_pc_disp(addr, disp);
363  op->jump = addr + disp;
364 }
365 
366 // TODO: this implementation is just a fast hack. needs to be rewritten and completed
367 static int sparc_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len, RzAnalysisOpMask mask) {
368  int sz = 4;
369  ut32 insn;
370 
371  op->family = RZ_ANALYSIS_OP_FAMILY_CPU;
372  op->addr = addr;
373  op->size = sz;
374 
375  if (!analysis->big_endian) {
376  ((char *)&insn)[0] = data[3];
377  ((char *)&insn)[1] = data[2];
378  ((char *)&insn)[2] = data[1];
379  ((char *)&insn)[3] = data[0];
380  } else {
381  memcpy(&insn, data, sz);
382  }
383 
384  if (X_OP(insn) == OP_0) {
385  switch (X_OP2(insn)) {
386  case OP2_ILLTRAP:
387  case OP2_INV:
388  op->type = RZ_ANALYSIS_OP_TYPE_ILL;
389  sz = 0; /* make rz_core_analysis_bb stop */
390  break;
391  case OP2_BPcc:
392  case OP2_Bicc:
393  case OP2_BPr:
394  case OP2_FBPfcc:
395  case OP2_FBfcc:
396  analysis_branch(op, insn, addr);
397  break;
398  }
399  } else if (X_OP(insn) == OP_1) {
400  analysis_call(op, insn, addr);
401  } else if (X_OP(insn) == OP_2) {
402  switch (X_OP3(insn)) {
403  case OP32_INV1:
404  case OP32_INV2:
405  case OP32_INV3:
406  case OP32_INV4:
407  case OP32_INV5:
408  op->type = RZ_ANALYSIS_OP_TYPE_ILL;
409  sz = 0; /* make rz_core_analysis_bb stop */
410  break;
411  case OP32_CONDINV1:
412  if (X_RD(insn) == 1) {
413  op->type = RZ_ANALYSIS_OP_TYPE_ILL;
414  sz = 0; /* make rz_core_analysis_bb stop */
415  }
416  break;
417  case OP32_CONDINV2:
418  if (X_RS1(insn) == 1) {
419  op->type = RZ_ANALYSIS_OP_TYPE_ILL;
420  sz = 0; /* make rz_core_analysis_bb stop */
421  }
422  break;
423  case OP32_CONDINV3:
424  if (X_RS1(insn) != 0) {
425  op->type = RZ_ANALYSIS_OP_TYPE_ILL;
426  sz = 0; /* make rz_core_analysis_bb stop */
427  }
428  break;
429 
430  case OP32_JMPL:
431  analysis_jmpl(analysis, op, insn, addr);
432  break;
433  }
434  } else if (X_OP(insn) == OP_3) {
435  switch (X_OP3(insn)) {
436  case OP33_INV1:
437  case OP33_INV2:
438  case OP33_INV3:
439  case OP33_INV4:
440  case OP33_INV5:
441  case OP33_INV6:
442  case OP33_INV7:
443  case OP33_INV8:
444  case OP33_INV9:
445  case OP33_INV10:
446  case OP33_INV11:
447  case OP33_INV12:
448  case OP33_INV13:
449  case OP33_INV14:
450  case OP33_INV15:
451  case OP33_INV16:
452  op->type = RZ_ANALYSIS_OP_TYPE_ILL;
453  sz = 0; /* make rz_core_analysis_bb stop */
454  break;
455  }
456  }
457 
458  return sz;
459 }
460 
461 static char *get_reg_profile(RzAnalysis *analysis) {
462  /* As far as I can see, sparc v9 register and instruction set
463  don't depened on bits of the running application.
464  But: They depend on the bits of the consuming application,
465  that is the bits rizin had been compiled with.
466  See sys/procfs_isa.h on a Solaris10 Sparc machine and
467  'man 4 core' for reference.
468  */
469  const char *p =
470  "=PC pc\n"
471  "=SP o6\n"
472  "=BP i6\n"
473  "=A0 g0\n"
474  "=A1 g1\n"
475  /* prgregset_t for _LP64 */
476  "gpr g0 .64 0 0\n"
477  "gpr g1 .64 8 0\n"
478  "gpr g2 .64 16 0\n"
479  "gpr g3 .64 24 0\n"
480  "gpr g4 .64 32 0\n"
481  "gpr g5 .64 40 0\n"
482  "gpr g6 .64 48 0\n"
483  "gpr g7 .64 56 0\n"
484  "gpr o0 .64 64 0\n"
485  "gpr o1 .64 72 0\n"
486  "gpr o2 .64 80 0\n"
487  "gpr o3 .64 88 0\n"
488  "gpr o4 .64 96 0\n"
489  "gpr o5 .64 104 0\n"
490  "gpr o6 .64 112 0\n"
491  "gpr o7 .64 120 0\n"
492  "gpr l0 .64 128 0\n"
493  "gpr l1 .64 136 0\n"
494  "gpr l2 .64 144 0\n"
495  "gpr l3 .64 152 0\n"
496  "gpr l4 .64 160 0\n"
497  "gpr l5 .64 168 0\n"
498  "gpr l6 .64 176 0\n"
499  "gpr l7 .64 184 0\n"
500  "gpr i0 .64 192 0\n"
501  "gpr i1 .64 200 0\n"
502  "gpr i2 .64 208 0\n"
503  "gpr i3 .64 216 0\n"
504  "gpr i4 .64 224 0\n"
505  "gpr i5 .64 232 0\n"
506  "gpr i6 .64 240 0\n"
507  "gpr i7 .64 248 0\n"
508  "gpr ccr .64 256 0\n"
509  "gpr pc .64 264 0\n"
510  "gpr ncp .64 272 0\n"
511  "gpr y .64 280 0\n"
512  "gpr asi .64 288 0\n"
513  "gpr fprs .64 296 0\n"
514  /* beginning of prfpregset_t for __sparcv9 */
515  "fpu sf0 .32 304 0\n"
516  "fpu sf1 .32 308 0\n"
517  "fpu sf2 .32 312 0\n"
518  "fpu sf3 .32 316 0\n"
519  "fpu sf4 .32 320 0\n"
520  "fpu sf5 .32 324 0\n"
521  "fpu sf6 .32 328 0\n"
522  "fpu sf7 .32 332 0\n"
523  "fpu sf8 .32 336 0\n"
524  "fpu sf9 .32 340 0\n"
525  "fpu sf10 .32 344 0\n"
526  "fpu sf11 .32 348 0\n"
527  "fpu sf12 .32 352 0\n"
528  "fpu sf13 .32 356 0\n"
529  "fpu sf14 .32 360 0\n"
530  "fpu sf15 .32 364 0\n"
531  "fpu sf16 .32 368 0\n"
532  "fpu sf17 .32 372 0\n"
533  "fpu sf18 .32 376 0\n"
534  "fpu sf19 .32 380 0\n"
535  "fpu sf20 .32 384 0\n"
536  "fpu sf21 .32 388 0\n"
537  "fpu sf22 .32 392 0\n"
538  "fpu sf23 .32 396 0\n"
539  "fpu sf24 .32 400 0\n"
540  "fpu sf25 .32 404 0\n"
541  "fpu sf26 .32 408 0\n"
542  "fpu sf27 .32 412 0\n"
543  "fpu sf28 .32 416 0\n"
544  "fpu sf29 .32 420 0\n"
545  "fpu sf30 .32 424 0\n"
546  "fpu sf31 .32 428 0\n"
547  "fpu df0 .64 304 0\n" /* sf0 sf1 */
548  "fpu df2 .64 312 0\n" /* sf2 sf3 */
549  "fpu df4 .64 320 0\n" /* sf4 sf5 */
550  "fpu df6 .64 328 0\n" /* sf6 sf7 */
551  "fpu df8 .64 336 0\n" /* sf8 sf9 */
552  "fpu df10 .64 344 0\n" /* sf10 sf11 */
553  "fpu df12 .64 352 0\n" /* sf12 sf13 */
554  "fpu df14 .64 360 0\n" /* sf14 sf15 */
555  "fpu df16 .64 368 0\n" /* sf16 sf17 */
556  "fpu df18 .64 376 0\n" /* sf18 sf19 */
557  "fpu df20 .64 384 0\n" /* sf20 sf21 */
558  "fpu df22 .64 392 0\n" /* sf22 sf23 */
559  "fpu df24 .64 400 0\n" /* sf24 sf25 */
560  "fpu df26 .64 408 0\n" /* sf26 sf27 */
561  "fpu df28 .64 416 0\n" /* sf28 sf29 */
562  "fpu df30 .64 424 0\n" /* sf30 sf31 */
563  "fpu df32 .64 432 0\n"
564  "fpu df34 .64 440 0\n"
565  "fpu df36 .64 448 0\n"
566  "fpu df38 .64 456 0\n"
567  "fpu df40 .64 464 0\n"
568  "fpu df42 .64 472 0\n"
569  "fpu df44 .64 480 0\n"
570  "fpu df46 .64 488 0\n"
571  "fpu df48 .64 496 0\n"
572  "fpu df50 .64 504 0\n"
573  "fpu df52 .64 512 0\n"
574  "fpu df54 .64 520 0\n"
575  "fpu df56 .64 528 0\n"
576  "fpu df58 .64 536 0\n"
577  "fpu df60 .64 544 0\n"
578  "fpu df62 .64 552 0\n"
579  "fpu qf0 .128 304 0\n" /* sf0 sf1 sf2 sf3 */
580  "fpu qf4 .128 320 0\n" /* sf4 sf5 sf6 sf7 */
581  "fpu qf8 .128 336 0\n" /* sf8 sf9 sf10 sf11 */
582  "fpu qf12 .128 352 0\n" /* sf12 sf13 sf14 sf15 */
583  "fpu qf16 .128 368 0\n" /* sf16 sf17 sf18 sf19 */
584  "fpu qf20 .128 384 0\n" /* sf20 sf21 sf22 sf23 */
585  "fpu qf24 .128 400 0\n" /* sf24 sf25 sf26 sf27 */
586  "fpu qf28 .128 416 0\n" /* sf28 sf29 sf30 sf31 */
587  "fpu qf32 .128 432 0\n" /* df32 df34 */
588  "fpu qf36 .128 448 0\n" /* df36 df38 */
589  "fpu qf40 .128 464 0\n" /* df40 df42 */
590  "fpu qf44 .128 480 0\n" /* df44 df46 */
591  "fpu qf48 .128 496 0\n" /* df48 df50 */
592  "fpu qf52 .128 512 0\n" /* df52 df54 */
593  "fpu qf56 .128 528 0\n" /* df56 df68 */
594  "fpu qf60 .128 544 0\n" /* df60 df62 */
595  "gpr fsr .64 560 0\n"; /* note that
596  we've left out the filler */
597  return strdup(p);
598 }
599 
600 static int archinfo(RzAnalysis *analysis, int q) {
601  return 4; /* :D */
602 }
603 
605  .name = "sparc.gnu",
606  .desc = "SPARC analysis plugin",
607  .license = "LGPL3",
608  .arch = "sparc",
609  .bits = 32 | 64,
610  .op = &sparc_op,
611  .archinfo = archinfo,
612  .get_reg_profile = get_reg_profile,
613 };
614 
615 #ifndef RZ_PLUGIN_INCORE
620 };
621 #endif
size_t len
Definition: 6502dis.c:15
RZ_API RzAnalysisValue * rz_analysis_value_new(void)
Definition: value.c:6
#define mask()
@ GPR_O1
@ GPR_I6
@ GPR_G5
@ GPR_G2
@ GPR_I3
@ GPR_L0
@ GPR_L6
@ GPR_L4
@ GPR_I7
@ GPR_O5
@ GPR_L1
@ GPR_O4
@ GPR_I5
@ GPR_O3
@ GPR_L7
@ GPR_G0
@ GPR_G1
@ GPR_L3
@ GPR_I4
@ GPR_G7
@ GPR_O6
@ GPR_L5
@ GPR_I2
@ GPR_G3
@ GPR_O2
@ GPR_L2
@ GPR_G4
@ GPR_O7
@ GPR_I1
@ GPR_G6
@ GPR_I0
@ GPR_O0
@ ICC_GU
@ ICC_A
@ ICC_VC
@ ICC_NE
@ ICC_CC
@ ICC_E
@ ICC_LE
@ ICC_N
@ ICC_GE
@ ICC_VS
@ ICC_NEG
@ ICC_CS
@ ICC_POS
@ ICC_G
@ ICC_LEU
@ ICC_L
RzAnalysisPlugin rz_analysis_plugin_sparc_gnu
static char * get_reg_profile(RzAnalysis *analysis)
#define X_OP3(i)
static int fcc_to_r_cond(const int cond)
static st64 get_immed_sgnext(const ut64 insn, const ut8 nbit)
#define X_OP2(i)
const char * gpr_regs[]
#define X_RS2(i)
#define X_OP(i)
static RzAnalysisValue * value_fill_addr_reg_regdelta(RzAnalysis const *const analysis, const int ireg, const int iregdelta)
@ OP2_INV
@ OP2_BPcc
@ OP2_FBPfcc
@ OP2_FBfcc
@ OP2_BPr
@ OP2_SETHI
@ OP2_Bicc
@ OP2_ILLTRAP
static RzAnalysisValue * value_fill_addr_pc_disp(const ut64 addr, const st64 disp)
RZ_API RzLibStruct rizin_plugin
#define X_DISP16(i)
#define X_RD(i)
static int icc_to_r_cond(const int cond)
#define X_LDST_I(i)
static void analysis_jmpl(RzAnalysis const *const analysis, RzAnalysisOp *op, const ut32 insn, const ut64 addr)
#define X_RS1(i)
@ RZ_TYPE_COND_NEVER
@ RZ_TYPE_COND_UNKNOWN
@ RZ_TYPE_COND_ALWAYS
static RzAnalysisValue * value_fill_addr_reg_disp(RzAnalysis const *const analysis, const int ireg, const st64 disp)
@ FCC_E
@ FCC_UGE
@ FCC_LG
@ FCC_GE
@ FCC_N
@ FCC_L
@ FCC_U
@ FCC_ULE
@ FCC_UL
@ FCC_G
@ FCC_LE
@ FCC_NE
@ FCC_A
@ FCC_UG
@ FCC_O
@ FCC_UE
#define X_COND(i)
static int archinfo(RzAnalysis *analysis, int q)
static void analysis_call(RzAnalysisOp *op, const ut32 insn, const ut64 addr)
@ OP33_INV13
@ OP33_INV3
@ OP33_INV4
@ OP33_INV2
@ OP33_INV16
@ OP33_INV5
@ OP33_INV10
@ OP33_INV14
@ OP33_INV1
@ OP33_INV8
@ OP33_INV6
@ OP33_INV12
@ OP33_INV7
@ OP33_INV9
@ OP33_INV11
@ OP33_INV15
static int sparc_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len, RzAnalysisOpMask mask)
static void analysis_branch(RzAnalysisOp *op, const ut32 insn, const ut64 addr)
@ OP32_SDIVcc
@ OP32_INV3
@ OP32_INV4
@ OP32_XNOR
@ OP32_SRL
@ OP32_MOVr
@ OP32_ADDCcc
@ OP32_Tcc
@ OP32_FPop2
@ OP32_SUBC
@ OP32_ORcc
@ OP32_RESTORE
@ OP32_ADDC
@ OP32_SLL
@ OP32_RETURN
@ OP32_WRY
@ OP32_TSUBccTV
@ OP32_TSUBcc
@ OP32_ADD
@ OP32_AND
@ OP32_ORNcc
@ OP32_SMULD
@ OP32_FPop1
@ OP32_ANDN
@ OP32_SUBCcc
@ OP32_MOVcc
@ OP32_CONDINV2
@ OP32_INV1
@ OP32_XNORcc
@ OP32_CONDINV1
@ OP32_UMULcc
@ OP32_SAVE
@ OP32_ORN
@ OP32_SUB
@ OP32_TADDccTV
@ OP32_UDIV
@ OP32_TADDcc
@ OP32_POPC
@ OP32_XOR
@ OP32_UDIVcc
@ OP32_ANDcc
@ OP32_WRPR
@ OP32_SAVED
@ OP32_CONDINV3
@ OP32_XORcc
@ OP32_INV5
@ OP32_DONE
@ OP32_MULX
@ OP32_SDIVX
@ OP32_FLUSHW
@ OP32_SRA
@ OP32_RDPR
@ OP32_ANDNcc
@ OP32_OR
@ OP32_MULSccD
@ OP32_UMUL
@ OP32_FLUSH
@ OP32_SDIV
@ OP32_JMPL
@ OP32_SMULcc
@ OP32_ADDcc
@ OP32_RDY
@ OP32_INV2
@ OP32_SUBcc
@ OP32_UDIVX
ut16 val
Definition: armass64_const.h:6
#define RZ_API
uint32_t ut32
uint8_t ut8
Definition: lh5801.h:11
void * p
Definition: libc.cpp:67
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
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")
RZ_API RzRegItem * rz_reg_get(RzReg *reg, const char *name, int type)
Definition: reg.c:344
@ RZ_ANALYSIS_OP_FAMILY_CPU
Definition: rz_analysis.h:312
RzAnalysisOpMask
Definition: rz_analysis.h:439
@ RZ_ANALYSIS_OP_TYPE_JMP
Definition: rz_analysis.h:368
@ RZ_ANALYSIS_OP_TYPE_UJMP
Definition: rz_analysis.h:369
@ RZ_ANALYSIS_OP_TYPE_CALL
Definition: rz_analysis.h:378
@ RZ_ANALYSIS_OP_TYPE_CJMP
Definition: rz_analysis.h:373
@ RZ_ANALYSIS_OP_TYPE_ILL
Definition: rz_analysis.h:387
@ RZ_ANALYSIS_OP_TYPE_UCALL
Definition: rz_analysis.h:379
@ RZ_ANALYSIS_OP_TYPE_RET
Definition: rz_analysis.h:385
@ RZ_ANALYSIS_OP_TYPE_NOP
Definition: rz_analysis.h:389
@ RZ_LIB_TYPE_ANALYSIS
Definition: rz_lib.h:73
@ RZ_REG_TYPE_GPR
Definition: rz_reg.h:21
@ 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_EQ
Equal.
Definition: rz_type.h:184
@ RZ_TYPE_COND_NE
Not equal.
Definition: rz_type.h:185
@ RZ_TYPE_COND_GT
Greater than.
Definition: rz_type.h:187
@ RZ_TYPE_COND_LT
Less than.
Definition: rz_type.h:189
#define st64
Definition: rz_types_base.h:10
#define RZ_VERSION
Definition: rz_version.h:8
#define cond(bop, top, mask, flags)
const char * version
Definition: rz_analysis.h:1239
Definition: dis.c:32
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int addr
Definition: z80asm.c:58