Rizin
unix-like reverse engineering framework and cli tools
SparcDisassembler.c
Go to the documentation of this file.
1 //===------ SparcDisassembler.cpp - Disassembler for PowerPC ------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 /* Capstone Disassembly Engine */
11 /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
12 
13 #ifdef CAPSTONE_HAS_SPARC
14 
15 #include <stdio.h> // DEBUG
16 #include <stdlib.h>
17 #include <string.h>
18 
19 #include "../../cs_priv.h"
20 #include "../../utils.h"
21 
22 #include "SparcDisassembler.h"
23 
24 #include "../../MCInst.h"
25 #include "../../MCInstrDesc.h"
26 #include "../../MCFixedLenDisassembler.h"
27 #include "../../MCRegisterInfo.h"
28 #include "../../MCDisassembler.h"
29 #include "../../MathExtras.h"
30 
31 
32 #define GET_REGINFO_MC_DESC
33 #define GET_REGINFO_ENUM
34 #include "SparcGenRegisterInfo.inc"
35 static const unsigned IntRegDecoderTable[] = {
36  SP_G0, SP_G1, SP_G2, SP_G3,
37  SP_G4, SP_G5, SP_G6, SP_G7,
38  SP_O0, SP_O1, SP_O2, SP_O3,
39  SP_O4, SP_O5, SP_O6, SP_O7,
40  SP_L0, SP_L1, SP_L2, SP_L3,
41  SP_L4, SP_L5, SP_L6, SP_L7,
42  SP_I0, SP_I1, SP_I2, SP_I3,
43  SP_I4, SP_I5, SP_I6, SP_I7
44 };
45 
46 static const unsigned FPRegDecoderTable[] = {
47  SP_F0, SP_F1, SP_F2, SP_F3,
48  SP_F4, SP_F5, SP_F6, SP_F7,
49  SP_F8, SP_F9, SP_F10, SP_F11,
50  SP_F12, SP_F13, SP_F14, SP_F15,
51  SP_F16, SP_F17, SP_F18, SP_F19,
52  SP_F20, SP_F21, SP_F22, SP_F23,
53  SP_F24, SP_F25, SP_F26, SP_F27,
54  SP_F28, SP_F29, SP_F30, SP_F31
55 };
56 
57 static const unsigned DFPRegDecoderTable[] = {
58  SP_D0, SP_D16, SP_D1, SP_D17,
59  SP_D2, SP_D18, SP_D3, SP_D19,
60  SP_D4, SP_D20, SP_D5, SP_D21,
61  SP_D6, SP_D22, SP_D7, SP_D23,
62  SP_D8, SP_D24, SP_D9, SP_D25,
63  SP_D10, SP_D26, SP_D11, SP_D27,
64  SP_D12, SP_D28, SP_D13, SP_D29,
65  SP_D14, SP_D30, SP_D15, SP_D31
66 };
67 
68 static const unsigned QFPRegDecoderTable[] = {
69  SP_Q0, SP_Q8, ~0U, ~0U,
70  SP_Q1, SP_Q9, ~0U, ~0U,
71  SP_Q2, SP_Q10, ~0U, ~0U,
72  SP_Q3, SP_Q11, ~0U, ~0U,
73  SP_Q4, SP_Q12, ~0U, ~0U,
74  SP_Q5, SP_Q13, ~0U, ~0U,
75  SP_Q6, SP_Q14, ~0U, ~0U,
76  SP_Q7, SP_Q15, ~0U, ~0U
77 };
78 
79 static const unsigned FCCRegDecoderTable[] = {
80  SP_FCC0, SP_FCC1, SP_FCC2, SP_FCC3
81 };
82 
83 static uint64_t getFeatureBits(int mode)
84 {
85  // support everything
86  return (uint64_t)-1;
87 }
88 
89 static DecodeStatus DecodeIntRegsRegisterClass(MCInst *Inst, unsigned RegNo,
90  uint64_t Address, const void *Decoder)
91 {
92  unsigned Reg;
93 
94  if (RegNo > 31)
95  return MCDisassembler_Fail;
96 
97  Reg = IntRegDecoderTable[RegNo];
99 
100  return MCDisassembler_Success;
101 }
102 
103 static DecodeStatus DecodeI64RegsRegisterClass(MCInst *Inst, unsigned RegNo,
104  uint64_t Address, const void *Decoder)
105 {
106  unsigned Reg;
107 
108  if (RegNo > 31)
109  return MCDisassembler_Fail;
110 
111  Reg = IntRegDecoderTable[RegNo];
112  MCOperand_CreateReg0(Inst, Reg);
113 
114  return MCDisassembler_Success;
115 }
116 
117 static DecodeStatus DecodeFPRegsRegisterClass(MCInst *Inst, unsigned RegNo,
118  uint64_t Address, const void *Decoder)
119 {
120  unsigned Reg;
121 
122  if (RegNo > 31)
123  return MCDisassembler_Fail;
124 
125  Reg = FPRegDecoderTable[RegNo];
126  MCOperand_CreateReg0(Inst, Reg);
127 
128  return MCDisassembler_Success;
129 }
130 
131 static DecodeStatus DecodeDFPRegsRegisterClass(MCInst *Inst, unsigned RegNo,
132  uint64_t Address, const void *Decoder)
133 {
134  unsigned Reg;
135 
136  if (RegNo > 31)
137  return MCDisassembler_Fail;
138 
139  Reg = DFPRegDecoderTable[RegNo];
140  MCOperand_CreateReg0(Inst, Reg);
141 
142  return MCDisassembler_Success;
143 }
144 
145 static DecodeStatus DecodeQFPRegsRegisterClass(MCInst *Inst, unsigned RegNo,
146  uint64_t Address, const void *Decoder)
147 {
148  unsigned Reg;
149 
150  if (RegNo > 31)
151  return MCDisassembler_Fail;
152 
153  Reg = QFPRegDecoderTable[RegNo];
154  if (Reg == ~0U)
155  return MCDisassembler_Fail;
156 
157  MCOperand_CreateReg0(Inst, Reg);
158 
159  return MCDisassembler_Success;
160 }
161 
162 static DecodeStatus DecodeFCCRegsRegisterClass(MCInst *Inst, unsigned RegNo,
163  uint64_t Address, const void *Decoder)
164 {
165  if (RegNo > 3)
166  return MCDisassembler_Fail;
167 
168  MCOperand_CreateReg0(Inst, FCCRegDecoderTable[RegNo]);
169 
170  return MCDisassembler_Success;
171 }
172 
173 
174 static DecodeStatus DecodeLoadInt(MCInst *Inst, unsigned insn, uint64_t Address,
175  const void *Decoder);
176 static DecodeStatus DecodeLoadFP(MCInst *Inst, unsigned insn, uint64_t Address,
177  const void *Decoder);
178 static DecodeStatus DecodeLoadDFP(MCInst *Inst, unsigned insn, uint64_t Address,
179  const void *Decoder);
180 static DecodeStatus DecodeLoadQFP(MCInst *Inst, unsigned insn, uint64_t Address,
181  const void *Decoder);
182 static DecodeStatus DecodeStoreInt(MCInst *Inst, unsigned insn,
183  uint64_t Address, const void *Decoder);
184 static DecodeStatus DecodeStoreFP(MCInst *Inst, unsigned insn,
185  uint64_t Address, const void *Decoder);
186 static DecodeStatus DecodeStoreDFP(MCInst *Inst, unsigned insn,
187  uint64_t Address, const void *Decoder);
188 static DecodeStatus DecodeStoreQFP(MCInst *Inst, unsigned insn,
189  uint64_t Address, const void *Decoder);
190 static DecodeStatus DecodeCall(MCInst *Inst, unsigned insn,
191  uint64_t Address, const void *Decoder);
192 static DecodeStatus DecodeSIMM13(MCInst *Inst, unsigned insn,
193  uint64_t Address, const void *Decoder);
194 static DecodeStatus DecodeJMPL(MCInst *Inst, unsigned insn, uint64_t Address,
195  const void *Decoder);
196 static DecodeStatus DecodeReturn(MCInst *MI, unsigned insn, uint64_t Address,
197  const void *Decoder);
198 static DecodeStatus DecodeSWAP(MCInst *Inst, unsigned insn, uint64_t Address,
199  const void *Decoder);
200 
201 
202 #define GET_SUBTARGETINFO_ENUM
203 #include "SparcGenSubtargetInfo.inc"
205 
207 static DecodeStatus readInstruction32(const uint8_t *code, size_t len, uint32_t *Insn)
208 {
209  if (len < 4)
210  // not enough data
211  return MCDisassembler_Fail;
212 
213  // Encoded as a big-endian 32-bit word in the stream.
214  *Insn = (code[3] << 0) |
215  (code[2] << 8) |
216  (code[1] << 16) |
217  ((uint32_t) code[0] << 24);
218 
219  return MCDisassembler_Success;
220 }
221 
222 bool Sparc_getInstruction(csh ud, const uint8_t *code, size_t code_len, MCInst *MI,
223  uint16_t *size, uint64_t address, void *info)
224 {
225  uint32_t Insn;
226  DecodeStatus Result;
227 
228  Result = readInstruction32(code, code_len, &Insn);
229  if (Result == MCDisassembler_Fail)
230  return false;
231 
232  if (MI->flat_insn->detail) {
233  memset(MI->flat_insn->detail, 0, offsetof(cs_detail, sparc)+sizeof(cs_sparc));
234  }
235 
236  Result = decodeInstruction_4(DecoderTableSparc32, MI, Insn, address,
237  (MCRegisterInfo *)info, 0);
238  if (Result != MCDisassembler_Fail) {
239  *size = 4;
240  return true;
241  }
242 
243  return false;
244 }
245 
246 typedef DecodeStatus (*DecodeFunc)(MCInst *MI, unsigned insn, uint64_t Address,
247  const void *Decoder);
248 
249 static DecodeStatus DecodeMem(MCInst *MI, unsigned insn, uint64_t Address,
250  const void *Decoder,
251  bool isLoad, DecodeFunc DecodeRD)
252 {
254  unsigned rd = fieldFromInstruction_4(insn, 25, 5);
255  unsigned rs1 = fieldFromInstruction_4(insn, 14, 5);
256  bool isImm = fieldFromInstruction_4(insn, 13, 1) != 0;
257  unsigned rs2 = 0;
258  unsigned simm13 = 0;
259 
260  if (isImm)
261  simm13 = SignExtend32(fieldFromInstruction_4(insn, 0, 13), 13);
262  else
263  rs2 = fieldFromInstruction_4(insn, 0, 5);
264 
265  if (isLoad) {
266  status = DecodeRD(MI, rd, Address, Decoder);
268  return status;
269  }
270 
271  // Decode rs1.
272  status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
274  return status;
275 
276  // Decode imm|rs2.
277  if (isImm)
278  MCOperand_CreateImm0(MI, simm13);
279  else {
280  status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
282  return status;
283  }
284 
285  if (!isLoad) {
286  status = DecodeRD(MI, rd, Address, Decoder);
288  return status;
289  }
290 
291  return MCDisassembler_Success;
292 }
293 
294 static DecodeStatus DecodeLoadInt(MCInst *Inst, unsigned insn, uint64_t Address,
295  const void *Decoder)
296 {
297  return DecodeMem(Inst, insn, Address, Decoder, true,
298  DecodeIntRegsRegisterClass);
299 }
300 
301 static DecodeStatus DecodeLoadFP(MCInst *Inst, unsigned insn, uint64_t Address,
302  const void *Decoder)
303 {
304  return DecodeMem(Inst, insn, Address, Decoder, true,
305  DecodeFPRegsRegisterClass);
306 }
307 
308 static DecodeStatus DecodeLoadDFP(MCInst *Inst, unsigned insn, uint64_t Address,
309  const void *Decoder)
310 {
311  return DecodeMem(Inst, insn, Address, Decoder, true,
312  DecodeDFPRegsRegisterClass);
313 }
314 
315 static DecodeStatus DecodeLoadQFP(MCInst *Inst, unsigned insn, uint64_t Address,
316  const void *Decoder)
317 {
318  return DecodeMem(Inst, insn, Address, Decoder, true,
319  DecodeQFPRegsRegisterClass);
320 }
321 
322 static DecodeStatus DecodeStoreInt(MCInst *Inst, unsigned insn,
323  uint64_t Address, const void *Decoder)
324 {
325  return DecodeMem(Inst, insn, Address, Decoder, false,
326  DecodeIntRegsRegisterClass);
327 }
328 
329 static DecodeStatus DecodeStoreFP(MCInst *Inst, unsigned insn, uint64_t Address,
330  const void *Decoder)
331 {
332  return DecodeMem(Inst, insn, Address, Decoder, false,
333  DecodeFPRegsRegisterClass);
334 }
335 
336 static DecodeStatus DecodeStoreDFP(MCInst *Inst, unsigned insn,
337  uint64_t Address, const void *Decoder)
338 {
339  return DecodeMem(Inst, insn, Address, Decoder, false,
340  DecodeDFPRegsRegisterClass);
341 }
342 
343 static DecodeStatus DecodeStoreQFP(MCInst *Inst, unsigned insn,
344  uint64_t Address, const void *Decoder)
345 {
346  return DecodeMem(Inst, insn, Address, Decoder, false,
347  DecodeQFPRegsRegisterClass);
348 }
349 
350 static DecodeStatus DecodeCall(MCInst *MI, unsigned insn,
351  uint64_t Address, const void *Decoder)
352 {
353  unsigned tgt = fieldFromInstruction_4(insn, 0, 30);
354  tgt <<= 2;
355 
356  MCOperand_CreateImm0(MI, tgt);
357 
358  return MCDisassembler_Success;
359 }
360 
361 static DecodeStatus DecodeSIMM13(MCInst *MI, unsigned insn,
362  uint64_t Address, const void *Decoder)
363 {
364  unsigned tgt = SignExtend32(fieldFromInstruction_4(insn, 0, 13), 13);
365 
366  MCOperand_CreateImm0(MI, tgt);
367 
368  return MCDisassembler_Success;
369 }
370 
371 static DecodeStatus DecodeJMPL(MCInst *MI, unsigned insn, uint64_t Address,
372  const void *Decoder)
373 {
375  unsigned rd = fieldFromInstruction_4(insn, 25, 5);
376  unsigned rs1 = fieldFromInstruction_4(insn, 14, 5);
377  unsigned isImm = fieldFromInstruction_4(insn, 13, 1);
378  unsigned rs2 = 0;
379  unsigned simm13 = 0;
380 
381  if (isImm)
382  simm13 = SignExtend32(fieldFromInstruction_4(insn, 0, 13), 13);
383  else
384  rs2 = fieldFromInstruction_4(insn, 0, 5);
385 
386  // Decode RD.
387  status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder);
389  return status;
390 
391  // Decode RS1.
392  status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
394  return status;
395 
396  // Decode RS1 | SIMM13.
397  if (isImm)
398  MCOperand_CreateImm0(MI, simm13);
399  else {
400  status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
402  return status;
403  }
404 
405  return MCDisassembler_Success;
406 }
407 
408 static DecodeStatus DecodeReturn(MCInst *MI, unsigned insn, uint64_t Address,
409  const void *Decoder)
410 {
412  unsigned rs1 = fieldFromInstruction_4(insn, 14, 5);
413  unsigned isImm = fieldFromInstruction_4(insn, 13, 1);
414  unsigned rs2 = 0;
415  unsigned simm13 = 0;
416  if (isImm)
417  simm13 = SignExtend32(fieldFromInstruction_4(insn, 0, 13), 13);
418  else
419  rs2 = fieldFromInstruction_4(insn, 0, 5);
420 
421  // Decode RS1.
422  status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
424  return status;
425 
426  // Decode RS2 | SIMM13.
427  if (isImm)
428  MCOperand_CreateImm0(MI, simm13);
429  else {
430  status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
432  return status;
433  }
434 
435  return MCDisassembler_Success;
436 }
437 
438 static DecodeStatus DecodeSWAP(MCInst *MI, unsigned insn, uint64_t Address,
439  const void *Decoder)
440 {
442  unsigned rd = fieldFromInstruction_4(insn, 25, 5);
443  unsigned rs1 = fieldFromInstruction_4(insn, 14, 5);
444  unsigned isImm = fieldFromInstruction_4(insn, 13, 1);
445  unsigned rs2 = 0;
446  unsigned simm13 = 0;
447 
448  if (isImm)
449  simm13 = SignExtend32(fieldFromInstruction_4(insn, 0, 13), 13);
450  else
451  rs2 = fieldFromInstruction_4(insn, 0, 5);
452 
453  // Decode RD.
454  status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder);
456  return status;
457 
458  // Decode RS1.
459  status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
461  return status;
462 
463  // Decode RS1 | SIMM13.
464  if (isImm)
465  MCOperand_CreateImm0(MI, simm13);
466  else {
467  status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
469  return status;
470  }
471 
472  return MCDisassembler_Success;
473 }
474 
475 void Sparc_init(MCRegisterInfo *MRI)
476 {
477  /*
478  InitMCRegisterInfo(SparcRegDesc, 119, RA, PC,
479  SparcMCRegisterClasses, 8,
480  SparcRegUnitRoots,
481  86,
482  SparcRegDiffLists,
483  SparcRegStrings,
484  SparcSubRegIdxLists,
485  7,
486  SparcSubRegIdxRanges,
487  SparcRegEncodingTable);
488  */
489 
490  MCRegisterInfo_InitMCRegisterInfo(MRI, SparcRegDesc, 119,
491  0, 0,
492  SparcMCRegisterClasses, 8,
493  0, 0,
494  SparcRegDiffLists,
495  0,
496  SparcSubRegIdxLists, 7,
497  0);
498 }
499 
500 #endif
size_t len
Definition: 6502dis.c:15
DecodeStatus
Definition: MCDisassembler.h:7
@ MCDisassembler_Success
@ MCDisassembler_Fail
Definition: MCDisassembler.h:8
void MCOperand_CreateReg0(MCInst *mcInst, unsigned Reg)
Definition: MCInst.c:158
void MCOperand_CreateImm0(MCInst *mcInst, int64_t Val)
Definition: MCInst.c:177
void MCRegisterInfo_InitMCRegisterInfo(MCRegisterInfo *RI, const MCRegisterDesc *D, unsigned NR, unsigned RA, unsigned PC, const MCRegisterClass *C, unsigned NC, uint16_t(*RURoots)[2], unsigned NRU, const MCPhysReg *DL, const char *Strings, const uint16_t *SubIndices, unsigned NumIndices, const uint16_t *RET)
static int32_t SignExtend32(uint32_t X, unsigned B)
Sign extend number in the bottom B bits of X to a 32-bit int. Requires 0 < B <= 32.
Definition: MathExtras.h:407
bool Sparc_getInstruction(csh ud, const uint8_t *code, size_t code_len, MCInst *instr, uint16_t *size, uint64_t address, void *info)
void Sparc_init(MCRegisterInfo *MRI)
#define rd()
RzBinInfo * info(RzBinFile *bf)
Definition: bin_ne.c:86
size_t csh
Definition: capstone.h:71
voidpf void uLong size
Definition: ioapi.h:138
const char int mode
Definition: ioapi.h:137
#define offsetof(type, member)
return memset(p, 0, total)
static const char struct stat static buf struct stat static buf static vhangup int status
Definition: sflib.h:145
unsigned short uint16_t
Definition: sftypes.h:30
unsigned int uint32_t
Definition: sftypes.h:29
unsigned long uint64_t
Definition: sftypes.h:28
unsigned char uint8_t
Definition: sftypes.h:31
Definition: MCInst.h:88
cs_insn * flat_insn
Definition: MCInst.h:95
Definition: inftree9.h:24
Instruction structure.
Definition: sparc.h:199