Rizin
unix-like reverse engineering framework and cli tools
PPCDisassembler.c
Go to the documentation of this file.
1 //===------ PPCDisassembler.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_POWERPC
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 "PPCDisassembler.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 #define GET_REGINFO_ENUM
32 #include "PPCGenRegisterInfo.inc"
33 
34 
35 // FIXME: These can be generated by TableGen from the existing register
36 // encoding values!
37 
38 static const unsigned CRRegs[] = {
39  PPC_CR0, PPC_CR1, PPC_CR2, PPC_CR3,
40  PPC_CR4, PPC_CR5, PPC_CR6, PPC_CR7
41 };
42 
43 static const unsigned CRBITRegs[] = {
44  PPC_CR0LT, PPC_CR0GT, PPC_CR0EQ, PPC_CR0UN,
45  PPC_CR1LT, PPC_CR1GT, PPC_CR1EQ, PPC_CR1UN,
46  PPC_CR2LT, PPC_CR2GT, PPC_CR2EQ, PPC_CR2UN,
47  PPC_CR3LT, PPC_CR3GT, PPC_CR3EQ, PPC_CR3UN,
48  PPC_CR4LT, PPC_CR4GT, PPC_CR4EQ, PPC_CR4UN,
49  PPC_CR5LT, PPC_CR5GT, PPC_CR5EQ, PPC_CR5UN,
50  PPC_CR6LT, PPC_CR6GT, PPC_CR6EQ, PPC_CR6UN,
51  PPC_CR7LT, PPC_CR7GT, PPC_CR7EQ, PPC_CR7UN
52 };
53 
54 static const unsigned FRegs[] = {
55  PPC_F0, PPC_F1, PPC_F2, PPC_F3,
56  PPC_F4, PPC_F5, PPC_F6, PPC_F7,
57  PPC_F8, PPC_F9, PPC_F10, PPC_F11,
58  PPC_F12, PPC_F13, PPC_F14, PPC_F15,
59  PPC_F16, PPC_F17, PPC_F18, PPC_F19,
60  PPC_F20, PPC_F21, PPC_F22, PPC_F23,
61  PPC_F24, PPC_F25, PPC_F26, PPC_F27,
62  PPC_F28, PPC_F29, PPC_F30, PPC_F31
63 };
64 
65 static const unsigned VRegs[] = {
66  PPC_V0, PPC_V1, PPC_V2, PPC_V3,
67  PPC_V4, PPC_V5, PPC_V6, PPC_V7,
68  PPC_V8, PPC_V9, PPC_V10, PPC_V11,
69  PPC_V12, PPC_V13, PPC_V14, PPC_V15,
70  PPC_V16, PPC_V17, PPC_V18, PPC_V19,
71  PPC_V20, PPC_V21, PPC_V22, PPC_V23,
72  PPC_V24, PPC_V25, PPC_V26, PPC_V27,
73  PPC_V28, PPC_V29, PPC_V30, PPC_V31
74 };
75 
76 static const unsigned VSRegs[] = {
77  PPC_VSL0, PPC_VSL1, PPC_VSL2, PPC_VSL3,
78  PPC_VSL4, PPC_VSL5, PPC_VSL6, PPC_VSL7,
79  PPC_VSL8, PPC_VSL9, PPC_VSL10, PPC_VSL11,
80  PPC_VSL12, PPC_VSL13, PPC_VSL14, PPC_VSL15,
81  PPC_VSL16, PPC_VSL17, PPC_VSL18, PPC_VSL19,
82  PPC_VSL20, PPC_VSL21, PPC_VSL22, PPC_VSL23,
83  PPC_VSL24, PPC_VSL25, PPC_VSL26, PPC_VSL27,
84  PPC_VSL28, PPC_VSL29, PPC_VSL30, PPC_VSL31,
85 
86  PPC_VSH0, PPC_VSH1, PPC_VSH2, PPC_VSH3,
87  PPC_VSH4, PPC_VSH5, PPC_VSH6, PPC_VSH7,
88  PPC_VSH8, PPC_VSH9, PPC_VSH10, PPC_VSH11,
89  PPC_VSH12, PPC_VSH13, PPC_VSH14, PPC_VSH15,
90  PPC_VSH16, PPC_VSH17, PPC_VSH18, PPC_VSH19,
91  PPC_VSH20, PPC_VSH21, PPC_VSH22, PPC_VSH23,
92  PPC_VSH24, PPC_VSH25, PPC_VSH26, PPC_VSH27,
93  PPC_VSH28, PPC_VSH29, PPC_VSH30, PPC_VSH31
94 };
95 
96 static const unsigned VSFRegs[] = {
97  PPC_F0, PPC_F1, PPC_F2, PPC_F3,
98  PPC_F4, PPC_F5, PPC_F6, PPC_F7,
99  PPC_F8, PPC_F9, PPC_F10, PPC_F11,
100  PPC_F12, PPC_F13, PPC_F14, PPC_F15,
101  PPC_F16, PPC_F17, PPC_F18, PPC_F19,
102  PPC_F20, PPC_F21, PPC_F22, PPC_F23,
103  PPC_F24, PPC_F25, PPC_F26, PPC_F27,
104  PPC_F28, PPC_F29, PPC_F30, PPC_F31,
105 
106  PPC_VF0, PPC_VF1, PPC_VF2, PPC_VF3,
107  PPC_VF4, PPC_VF5, PPC_VF6, PPC_VF7,
108  PPC_VF8, PPC_VF9, PPC_VF10, PPC_VF11,
109  PPC_VF12, PPC_VF13, PPC_VF14, PPC_VF15,
110  PPC_VF16, PPC_VF17, PPC_VF18, PPC_VF19,
111  PPC_VF20, PPC_VF21, PPC_VF22, PPC_VF23,
112  PPC_VF24, PPC_VF25, PPC_VF26, PPC_VF27,
113  PPC_VF28, PPC_VF29, PPC_VF30, PPC_VF31
114 };
115 
116 static const unsigned GPRegs[] = {
117  PPC_R0, PPC_R1, PPC_R2, PPC_R3,
118  PPC_R4, PPC_R5, PPC_R6, PPC_R7,
119  PPC_R8, PPC_R9, PPC_R10, PPC_R11,
120  PPC_R12, PPC_R13, PPC_R14, PPC_R15,
121  PPC_R16, PPC_R17, PPC_R18, PPC_R19,
122  PPC_R20, PPC_R21, PPC_R22, PPC_R23,
123  PPC_R24, PPC_R25, PPC_R26, PPC_R27,
124  PPC_R28, PPC_R29, PPC_R30, PPC_R31
125 };
126 
127 static const unsigned GP0Regs[] = {
128  PPC_ZERO, PPC_R1, PPC_R2, PPC_R3,
129  PPC_R4, PPC_R5, PPC_R6, PPC_R7,
130  PPC_R8, PPC_R9, PPC_R10, PPC_R11,
131  PPC_R12, PPC_R13, PPC_R14, PPC_R15,
132  PPC_R16, PPC_R17, PPC_R18, PPC_R19,
133  PPC_R20, PPC_R21, PPC_R22, PPC_R23,
134  PPC_R24, PPC_R25, PPC_R26, PPC_R27,
135  PPC_R28, PPC_R29, PPC_R30, PPC_R31
136 };
137 
138 static const unsigned G8Regs[] = {
139  PPC_X0, PPC_X1, PPC_X2, PPC_X3,
140  PPC_X4, PPC_X5, PPC_X6, PPC_X7,
141  PPC_X8, PPC_X9, PPC_X10, PPC_X11,
142  PPC_X12, PPC_X13, PPC_X14, PPC_X15,
143  PPC_X16, PPC_X17, PPC_X18, PPC_X19,
144  PPC_X20, PPC_X21, PPC_X22, PPC_X23,
145  PPC_X24, PPC_X25, PPC_X26, PPC_X27,
146  PPC_X28, PPC_X29, PPC_X30, PPC_X31
147 };
148 
149 static const unsigned QFRegs[] = {
150  PPC_QF0, PPC_QF1, PPC_QF2, PPC_QF3,
151  PPC_QF4, PPC_QF5, PPC_QF6, PPC_QF7,
152  PPC_QF8, PPC_QF9, PPC_QF10, PPC_QF11,
153  PPC_QF12, PPC_QF13, PPC_QF14, PPC_QF15,
154  PPC_QF16, PPC_QF17, PPC_QF18, PPC_QF19,
155  PPC_QF20, PPC_QF21, PPC_QF22, PPC_QF23,
156  PPC_QF24, PPC_QF25, PPC_QF26, PPC_QF27,
157  PPC_QF28, PPC_QF29, PPC_QF30, PPC_QF31
158 };
159 
160 static uint64_t getFeatureBits(int feature)
161 {
162  // enable all features
163  return (uint64_t)-1;
164 }
165 
166 static DecodeStatus decodeRegisterClass(MCInst *Inst, uint64_t RegNo,
167  const unsigned *Regs)
168 {
169  // assert(RegNo < N && "Invalid register number");
170  MCOperand_CreateReg0(Inst, Regs[RegNo]);
171  return MCDisassembler_Success;
172 }
173 
174 static DecodeStatus DecodeCRRCRegisterClass(MCInst *Inst, uint64_t RegNo,
175  uint64_t Address,
176  const void *Decoder)
177 {
178  return decodeRegisterClass(Inst, RegNo, CRRegs);
179 }
180 
181 static DecodeStatus DecodeCRBITRCRegisterClass(MCInst *Inst, uint64_t RegNo,
182  uint64_t Address,
183  const void *Decoder)
184 {
185  return decodeRegisterClass(Inst, RegNo, CRBITRegs);
186 }
187 
188 static DecodeStatus DecodeF4RCRegisterClass(MCInst *Inst, uint64_t RegNo,
189  uint64_t Address,
190  const void *Decoder)
191 {
192  return decodeRegisterClass(Inst, RegNo, FRegs);
193 }
194 
195 static DecodeStatus DecodeF8RCRegisterClass(MCInst *Inst, uint64_t RegNo,
196  uint64_t Address,
197  const void *Decoder)
198 {
199  return decodeRegisterClass(Inst, RegNo, FRegs);
200 }
201 
202 static DecodeStatus DecodeVRRCRegisterClass(MCInst *Inst, uint64_t RegNo,
203  uint64_t Address,
204  const void *Decoder)
205 {
206  return decodeRegisterClass(Inst, RegNo, VRegs);
207 }
208 
209 static DecodeStatus DecodeVSRCRegisterClass(MCInst *Inst, uint64_t RegNo,
210  uint64_t Address,
211  const void *Decoder)
212 {
213  return decodeRegisterClass(Inst, RegNo, VSRegs);
214 }
215 
216 static DecodeStatus DecodeVSFRCRegisterClass(MCInst *Inst, uint64_t RegNo,
217  uint64_t Address,
218  const void *Decoder)
219 {
220  return decodeRegisterClass(Inst, RegNo, VSFRegs);
221 }
222 
223 static DecodeStatus DecodeGPRCRegisterClass(MCInst *Inst, uint64_t RegNo,
224  uint64_t Address,
225  const void *Decoder)
226 {
227  return decodeRegisterClass(Inst, RegNo, GPRegs);
228 }
229 
230 static DecodeStatus DecodeGPRC_NOR0RegisterClass(MCInst *Inst, uint64_t RegNo,
231  uint64_t Address,
232  const void *Decoder)
233 {
234  return decodeRegisterClass(Inst, RegNo, GP0Regs);
235 }
236 
237 static DecodeStatus DecodeG8RCRegisterClass(MCInst *Inst, uint64_t RegNo,
238  uint64_t Address,
239  const void *Decoder)
240 {
241  return decodeRegisterClass(Inst, RegNo, G8Regs);
242 }
243 
244 #define DecodePointerLikeRegClass0 DecodeGPRCRegisterClass
245 #define DecodePointerLikeRegClass1 DecodeGPRC_NOR0RegisterClass
246 
247 static DecodeStatus DecodeQFRCRegisterClass(MCInst *Inst, uint64_t RegNo,
248  uint64_t Address,
249  const void *Decoder)
250 {
251  return decodeRegisterClass(Inst, RegNo, QFRegs);
252 }
253 
254 #define DecodeQSRCRegisterClass DecodeQFRCRegisterClass
255 #define DecodeQBRCRegisterClass DecodeQFRCRegisterClass
256 
257 static DecodeStatus decodeUImmOperand(MCInst *Inst, uint64_t Imm,
258  int64_t Address, const void *Decoder, unsigned N)
259 {
260  //assert(isUInt<N>(Imm) && "Invalid immediate");
261  MCOperand_CreateImm0(Inst, Imm);
262  return MCDisassembler_Success;
263 }
264 
265 static DecodeStatus decodeSImmOperand(MCInst *Inst, uint64_t Imm,
266  int64_t Address, const void *Decoder, unsigned N)
267 {
268  // assert(isUInt<N>(Imm) && "Invalid immediate");
269  MCOperand_CreateImm0(Inst, SignExtend64(Imm, N));
270  return MCDisassembler_Success;
271 }
272 
273 
274 #define GET_INSTRINFO_ENUM
275 #include "PPCGenInstrInfo.inc"
276 
277 static DecodeStatus decodeMemRIOperands(MCInst *Inst, uint64_t Imm,
278  int64_t Address, const void *Decoder)
279 {
280  // Decode the memri field (imm, reg), which has the low 16-bits as the
281  // displacement and the next 5 bits as the register #.
282 
283  uint64_t Base = Imm >> 16;
284  uint64_t Disp = Imm & 0xFFFF;
285 
286  // assert(Base < 32 && "Invalid base register");
287  if (Base >= 32)
288  return MCDisassembler_Fail;
289 
290  switch (MCInst_getOpcode(Inst)) {
291  default: break;
292  case PPC_LBZU:
293  case PPC_LHAU:
294  case PPC_LHZU:
295  case PPC_LWZU:
296  case PPC_LFSU:
297  case PPC_LFDU:
298  // Add the tied output operand.
299  MCOperand_CreateReg0(Inst, GP0Regs[Base]);
300  break;
301  case PPC_STBU:
302  case PPC_STHU:
303  case PPC_STWU:
304  case PPC_STFSU:
305  case PPC_STFDU:
306  MCInst_insert0(Inst, 0, MCOperand_CreateReg1(Inst, GP0Regs[Base]));
307  break;
308  }
309 
310  MCOperand_CreateImm0(Inst, SignExtend64(Disp, 16));
311  MCOperand_CreateReg0(Inst, GP0Regs[Base]);
312  return MCDisassembler_Success;
313 }
314 
315 static DecodeStatus decodeMemRIXOperands(MCInst *Inst, uint64_t Imm,
316  int64_t Address, const void *Decoder)
317 {
318  // Decode the memrix field (imm, reg), which has the low 14-bits as the
319  // displacement and the next 5 bits as the register #.
320 
321  uint64_t Base = Imm >> 14;
322  uint64_t Disp = Imm & 0x3FFF;
323 
324  // assert(Base < 32 && "Invalid base register");
325 
326  if (MCInst_getOpcode(Inst) == PPC_LDU)
327  // Add the tied output operand.
328  MCOperand_CreateReg0(Inst, GP0Regs[Base]);
329  else if (MCInst_getOpcode(Inst) == PPC_STDU)
330  MCInst_insert0(Inst, 0, MCOperand_CreateReg1(Inst, GP0Regs[Base]));
331 
332  MCOperand_CreateImm0(Inst, SignExtend64(Disp << 2, 16));
333  MCOperand_CreateReg0(Inst, GP0Regs[Base]);
334  return MCDisassembler_Success;
335 }
336 
337 static DecodeStatus decodeCRBitMOperand(MCInst *Inst, uint64_t Imm,
338  int64_t Address, const void *Decoder)
339 {
340  // The cr bit encoding is 0x80 >> cr_reg_num.
341 
342  unsigned Zeros = CountTrailingZeros_64(Imm);
343  // assert(Zeros < 8 && "Invalid CR bit value");
344  if (Zeros >=8)
345  return MCDisassembler_Fail;
346 
347  MCOperand_CreateReg0(Inst, CRRegs[7 - Zeros]);
348  return MCDisassembler_Success;
349 }
350 
352 
354  const uint8_t *code, size_t code_len,
355  uint16_t *Size,
356  uint64_t Address, MCRegisterInfo *MRI)
357 {
358  uint32_t insn;
359  DecodeStatus result;
360  // Get the four bytes of the instruction.
361  if (code_len < 4) {
362  // not enough data
363  *Size = 0;
364  return MCDisassembler_Fail;
365  }
366 
367  // The instruction is big-endian encoded.
368  if (MODE_IS_BIG_ENDIAN(MI->csh->mode))
369  insn = ((uint32_t) code[0] << 24) | (code[1] << 16) |
370  (code[2] << 8) | (code[3] << 0);
371  else
372  insn = ((uint32_t) code[3] << 24) | (code[2] << 16) |
373  (code[1] << 8) | (code[0] << 0);
374 
375  if (MI->flat_insn->detail) {
376  memset(MI->flat_insn->detail, 0, offsetof(cs_detail, ppc)+sizeof(cs_ppc));
377  }
378 
379  if (MI->csh->mode & CS_MODE_QPX) {
380  result = decodeInstruction_4(DecoderTableQPX32, MI, insn, Address, 4);
381  if (result != MCDisassembler_Fail) {
382  *Size = 4;
383  return result;
384  }
385 
386  MCInst_clear(MI);
387  }
388 
389  result = decodeInstruction_4(DecoderTable32, MI, insn, Address, 4);
390  if (result != MCDisassembler_Fail) {
391  *Size = 4;
392  return result;
393  }
394 
395  // report error
396  MCInst_clear(MI);
397  *Size = 0;
398  return MCDisassembler_Fail;
399 }
400 
401 bool PPC_getInstruction(csh ud, const uint8_t *code, size_t code_len,
402  MCInst *instr, uint16_t *size, uint64_t address, void *info)
403 {
405  code, code_len,
406  size,
407  address, (MCRegisterInfo *)info);
408 
409  return status == MCDisassembler_Success;
410 }
411 
412 #define GET_REGINFO_MC_DESC
413 #include "PPCGenRegisterInfo.inc"
414 void PPC_init(MCRegisterInfo *MRI)
415 {
416  /*
417  InitMCRegisterInfo(PPCRegDesc, 310, RA, PC,
418  PPCMCRegisterClasses, 23,
419  PPCRegUnitRoots,
420  138,
421  PPCRegDiffLists,
422  PPCLaneMaskLists,
423  PPCRegStrings,
424  PPCRegClassStrings,
425  PPCSubRegIdxLists,
426  8,
427  PPCSubRegIdxRanges,
428  PPCRegEncodingTable);
429  */
430 
431 
432  MCRegisterInfo_InitMCRegisterInfo(MRI, PPCRegDesc, 310,
433  0, 0,
434  PPCMCRegisterClasses, 23,
435  0, 0,
436  PPCRegDiffLists,
437  0,
438  PPCSubRegIdxLists, 8,
439  0);
440 }
441 
442 #endif
DecodeStatus
Definition: MCDisassembler.h:7
@ MCDisassembler_Success
@ MCDisassembler_Fail
Definition: MCDisassembler.h:8
MCOperand * MCOperand_CreateReg1(MCInst *mcInst, unsigned Reg)
Definition: MCInst.c:148
unsigned MCInst_getOpcode(const MCInst *inst)
Definition: MCInst.c:68
void MCInst_clear(MCInst *inst)
Definition: MCInst.c:40
void MCInst_insert0(MCInst *inst, int index, MCOperand *Op)
Definition: MCInst.c:46
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 int64_t SignExtend64(uint64_t X, unsigned B)
Sign extend number in the bottom B bits of X to a 64-bit int. Requires 0 < B <= 64.
Definition: MathExtras.h:413
static unsigned CountTrailingZeros_64(uint64_t Value)
Definition: MathExtras.h:218
void PPC_init(MCRegisterInfo *MRI)
bool PPC_getInstruction(csh ud, const uint8_t *code, size_t code_len, MCInst *instr, uint16_t *size, uint64_t address, void *info)
RzBinInfo * info(RzBinFile *bf)
Definition: bin_ne.c:86
@ CS_MODE_QPX
Quad Processing eXtensions mode (PPC)
Definition: capstone.h:116
size_t csh
Definition: capstone.h:71
#define MODE_IS_BIG_ENDIAN(mode)
Definition: cs_priv.h:84
voidpf void uLong size
Definition: ioapi.h:138
#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
long int64_t
Definition: sftypes.h:32
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
cs_struct * csh
Definition: MCInst.h:97
Definition: inftree9.h:24
Instruction structure.
Definition: ppc.h:294
cs_mode mode
Definition: cs_priv.h:56
void __stdcall getInstruction(cs_insn *insn, uint32_t index, void *curInst, uint32_t bufSize)
Definition: vbCapstone.cpp:60
#define N
Definition: zip_err_str.c:8