Rizin
unix-like reverse engineering framework and cli tools
SystemZDisassembler.c
Go to the documentation of this file.
1 //===------ SystemZDisassembler.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_SYSZ
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 "SystemZDisassembler.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 #include "SystemZMCTargetDesc.h"
32 
33 static uint64_t getFeatureBits(int mode)
34 {
35  // support everything
36  return (uint64_t)-1;
37 }
38 
39 static DecodeStatus decodeRegisterClass(MCInst *Inst, uint64_t RegNo, const unsigned *Regs)
40 {
41  //assert(RegNo < 16 && "Invalid register");
42  RegNo = Regs[RegNo];
43  if (RegNo == 0)
44  return MCDisassembler_Fail;
45 
46  MCOperand_CreateReg0(Inst, (unsigned)RegNo);
48 }
49 
50 static DecodeStatus DecodeGR32BitRegisterClass(MCInst *Inst, uint64_t RegNo,
51  uint64_t Address, const void *Decoder)
52 {
53  return decodeRegisterClass(Inst, RegNo, SystemZMC_GR32Regs);
54 }
55 
56 static DecodeStatus DecodeGRH32BitRegisterClass(MCInst *Inst, uint64_t RegNo,
57  uint64_t Address, const void *Decoder)
58 {
59  return decodeRegisterClass(Inst, RegNo, SystemZMC_GRH32Regs);
60 }
61 
62 static DecodeStatus DecodeGR64BitRegisterClass(MCInst *Inst, uint64_t RegNo,
63  uint64_t Address, const void *Decoder)
64 {
65  return decodeRegisterClass(Inst, RegNo, SystemZMC_GR64Regs);
66 }
67 
68 static DecodeStatus DecodeGR128BitRegisterClass(MCInst *Inst, uint64_t RegNo,
69  uint64_t Address, const void *Decoder)
70 {
71  return decodeRegisterClass(Inst, RegNo, SystemZMC_GR128Regs);
72 }
73 
74 static DecodeStatus DecodeADDR64BitRegisterClass(MCInst *Inst, uint64_t RegNo,
75  uint64_t Address, const void *Decoder)
76 {
77  return decodeRegisterClass(Inst, RegNo, SystemZMC_GR64Regs);
78 }
79 
80 static DecodeStatus DecodeFP32BitRegisterClass(MCInst *Inst, uint64_t RegNo,
81  uint64_t Address, const void *Decoder)
82 {
83  return decodeRegisterClass(Inst, RegNo, SystemZMC_FP32Regs);
84 }
85 
86 static DecodeStatus DecodeFP64BitRegisterClass(MCInst *Inst, uint64_t RegNo,
87  uint64_t Address, const void *Decoder)
88 {
89  return decodeRegisterClass(Inst, RegNo, SystemZMC_FP64Regs);
90 }
91 
92 static DecodeStatus DecodeFP128BitRegisterClass(MCInst *Inst, uint64_t RegNo,
93  uint64_t Address, const void *Decoder)
94 {
95  return decodeRegisterClass(Inst, RegNo, SystemZMC_FP128Regs);
96 }
97 
98 static DecodeStatus decodeUImmOperand(MCInst *Inst, uint64_t Imm)
99 {
100  //assert(isUInt<N>(Imm) && "Invalid immediate");
101  MCOperand_CreateImm0(Inst, Imm);
102  return MCDisassembler_Success;
103 }
104 
105 static DecodeStatus decodeSImmOperand(MCInst *Inst, uint64_t Imm, unsigned N)
106 {
107  //assert(isUInt<N>(Imm) && "Invalid immediate");
108  MCOperand_CreateImm0(Inst, SignExtend64(Imm, N));
109  return MCDisassembler_Success;
110 }
111 
112 static DecodeStatus decodeAccessRegOperand(MCInst *Inst, uint64_t Imm,
113  uint64_t Address, const void *Decoder)
114 {
115  return decodeUImmOperand(Inst, Imm);
116 }
117 
118 static DecodeStatus decodeU4ImmOperand(MCInst *Inst, uint64_t Imm,
119  uint64_t Address, const void *Decoder)
120 {
121  return decodeUImmOperand(Inst, Imm);
122 }
123 
124 static DecodeStatus decodeU6ImmOperand(MCInst *Inst, uint64_t Imm,
125  uint64_t Address, const void *Decoder)
126 {
127  return decodeUImmOperand(Inst, Imm);
128 }
129 
130 static DecodeStatus decodeU8ImmOperand(MCInst *Inst, uint64_t Imm,
131  uint64_t Address, const void *Decoder)
132 {
133  return decodeUImmOperand(Inst, Imm);
134 }
135 
136 static DecodeStatus decodeU16ImmOperand(MCInst *Inst, uint64_t Imm,
137  uint64_t Address, const void *Decoder)
138 {
139  return decodeUImmOperand(Inst, Imm);
140 }
141 
142 static DecodeStatus decodeU32ImmOperand(MCInst *Inst, uint64_t Imm,
143  uint64_t Address, const void *Decoder)
144 {
145  return decodeUImmOperand(Inst, Imm);
146 }
147 
148 static DecodeStatus decodeS8ImmOperand(MCInst *Inst, uint64_t Imm,
149  uint64_t Address, const void *Decoder)
150 {
151  return decodeSImmOperand(Inst, Imm, 8);
152 }
153 
154 static DecodeStatus decodeS16ImmOperand(MCInst *Inst, uint64_t Imm,
155  uint64_t Address, const void *Decoder)
156 {
157  return decodeSImmOperand(Inst, Imm, 16);
158 }
159 
160 static DecodeStatus decodeS32ImmOperand(MCInst *Inst, uint64_t Imm,
161  uint64_t Address, const void *Decoder)
162 {
163  return decodeSImmOperand(Inst, Imm, 32);
164 }
165 
166 static DecodeStatus decodePCDBLOperand(MCInst *Inst, uint64_t Imm,
167  uint64_t Address, unsigned N)
168 {
169  //assert(isUInt<N>(Imm) && "Invalid PC-relative offset");
170  MCOperand_CreateImm0(Inst, SignExtend64(Imm, N) * 2 + Address);
171  return MCDisassembler_Success;
172 }
173 
174 static DecodeStatus decodePC16DBLOperand(MCInst *Inst, uint64_t Imm,
175  uint64_t Address, const void *Decoder)
176 {
177  return decodePCDBLOperand(Inst, Imm, Address, 16);
178 }
179 
180 static DecodeStatus decodePC32DBLOperand(MCInst *Inst, uint64_t Imm,
181  uint64_t Address,
182  const void *Decoder)
183 {
184  return decodePCDBLOperand(Inst, Imm, Address, 32);
185 }
186 
187 static DecodeStatus decodeBDAddr12Operand(MCInst *Inst, uint64_t Field,
188  const unsigned *Regs)
189 {
190  uint64_t Base = Field >> 12;
191  uint64_t Disp = Field & 0xfff;
192  //assert(Base < 16 && "Invalid BDAddr12");
193 
194  MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]);
195  MCOperand_CreateImm0(Inst, Disp);
196 
197  return MCDisassembler_Success;
198 }
199 
200 static DecodeStatus decodeBDAddr20Operand(MCInst *Inst, uint64_t Field,
201  const unsigned *Regs)
202 {
203  uint64_t Base = Field >> 20;
204  uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff);
205  //assert(Base < 16 && "Invalid BDAddr20");
206 
207  MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]);
208  MCOperand_CreateImm0(Inst, SignExtend64(Disp, 20));
209  return MCDisassembler_Success;
210 }
211 
212 static DecodeStatus decodeBDXAddr12Operand(MCInst *Inst, uint64_t Field,
213  const unsigned *Regs)
214 {
215  uint64_t Index = Field >> 16;
216  uint64_t Base = (Field >> 12) & 0xf;
217  uint64_t Disp = Field & 0xfff;
218 
219  //assert(Index < 16 && "Invalid BDXAddr12");
220  MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]);
221  MCOperand_CreateImm0(Inst, Disp);
222  MCOperand_CreateReg0(Inst, Index == 0 ? 0 : Regs[Index]);
223 
224  return MCDisassembler_Success;
225 }
226 
227 static DecodeStatus decodeBDXAddr20Operand(MCInst *Inst, uint64_t Field,
228  const unsigned *Regs)
229 {
230  uint64_t Index = Field >> 24;
231  uint64_t Base = (Field >> 20) & 0xf;
232  uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12);
233 
234  //assert(Index < 16 && "Invalid BDXAddr20");
235  MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]);
236  MCOperand_CreateImm0(Inst, SignExtend64(Disp, 20));
237  MCOperand_CreateReg0(Inst, Index == 0 ? 0 : Regs[Index]);
238 
239  return MCDisassembler_Success;
240 }
241 
242 static DecodeStatus decodeBDLAddr12Len8Operand(MCInst *Inst, uint64_t Field,
243  const unsigned *Regs)
244 {
245  uint64_t Length = Field >> 16;
246  uint64_t Base = (Field >> 12) & 0xf;
247  uint64_t Disp = Field & 0xfff;
248  //assert(Length < 256 && "Invalid BDLAddr12Len8");
249 
250  MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]);
251  MCOperand_CreateImm0(Inst, Disp);
252  MCOperand_CreateImm0(Inst, Length + 1);
253 
254  return MCDisassembler_Success;
255 }
256 
257 static DecodeStatus decodeBDAddr32Disp12Operand(MCInst *Inst, uint64_t Field,
258  uint64_t Address, const void *Decoder)
259 {
260  return decodeBDAddr12Operand(Inst, Field, SystemZMC_GR32Regs);
261 }
262 
263 static DecodeStatus decodeBDAddr32Disp20Operand(MCInst *Inst, uint64_t Field,
264  uint64_t Address, const void *Decoder)
265 {
266  return decodeBDAddr20Operand(Inst, Field, SystemZMC_GR32Regs);
267 }
268 
269 static DecodeStatus decodeBDAddr64Disp12Operand(MCInst *Inst, uint64_t Field,
270  uint64_t Address, const void *Decoder)
271 {
272  return decodeBDAddr12Operand(Inst, Field, SystemZMC_GR64Regs);
273 }
274 
275 static DecodeStatus decodeBDAddr64Disp20Operand(MCInst *Inst, uint64_t Field,
276  uint64_t Address, const void *Decoder)
277 {
278  return decodeBDAddr20Operand(Inst, Field, SystemZMC_GR64Regs);
279 }
280 
281 static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst *Inst, uint64_t Field,
282  uint64_t Address, const void *Decoder)
283 {
284  return decodeBDXAddr12Operand(Inst, Field, SystemZMC_GR64Regs);
285 }
286 
287 static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst *Inst, uint64_t Field,
288  uint64_t Address, const void *Decoder)
289 {
290  return decodeBDXAddr20Operand(Inst, Field, SystemZMC_GR64Regs);
291 }
292 
293 static DecodeStatus decodeBDLAddr64Disp12Len8Operand(MCInst *Inst, uint64_t Field,
294  uint64_t Address, const void *Decoder)
295 {
296  return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC_GR64Regs);
297 }
298 
299 #define GET_SUBTARGETINFO_ENUM
302 bool SystemZ_getInstruction(csh ud, const uint8_t *code, size_t code_len, MCInst *MI,
303  uint16_t *size, uint64_t address, void *info)
304 {
305  uint64_t Inst;
306  const uint8_t *Table;
307  uint16_t I;
308 
309  // The top 2 bits of the first byte specify the size.
310  if (*code < 0x40) {
311  *size = 2;
312  Table = DecoderTable16;
313  } else if (*code < 0xc0) {
314  *size = 4;
315  Table = DecoderTable32;
316  } else {
317  *size = 6;
318  Table = DecoderTable48;
319  }
320 
321  if (code_len < *size)
322  // short of input data
323  return false;
324 
325  if (MI->flat_insn->detail) {
326  memset(MI->flat_insn->detail, 0, offsetof(cs_detail, sysz)+sizeof(cs_sysz));
327  }
328 
329  // Construct the instruction.
330  Inst = 0;
331  for (I = 0; I < *size; ++I)
332  Inst = (Inst << 8) | code[I];
333 
334  return decodeInstruction(Table, MI, Inst, address, info, 0);
335 }
336 
337 #define GET_REGINFO_ENUM
338 #define GET_REGINFO_MC_DESC
340 void SystemZ_init(MCRegisterInfo *MRI)
341 {
342  /*
343  InitMCRegisterInfo(SystemZRegDesc, 98, RA, PC,
344  SystemZMCRegisterClasses, 12,
345  SystemZRegUnitRoots,
346  49,
347  SystemZRegDiffLists,
348  SystemZRegStrings,
349  SystemZSubRegIdxLists,
350  7,
351  SystemZSubRegIdxRanges,
352  SystemZRegEncodingTable);
353  */
354 
355  MCRegisterInfo_InitMCRegisterInfo(MRI, SystemZRegDesc, 98,
356  0, 0,
357  SystemZMCRegisterClasses, 12,
358  0, 0,
359  SystemZRegDiffLists,
360  0,
361  SystemZSubRegIdxLists, 7,
362  0);
363 }
364 
365 #endif
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 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
void SystemZ_init(MCRegisterInfo *MRI)
bool SystemZ_getInstruction(csh ud, const uint8_t *code, size_t code_len, MCInst *instr, uint16_t *size, uint64_t address, void *info)
const unsigned SystemZMC_GRH32Regs[16]
const unsigned SystemZMC_GR128Regs[16]
const unsigned SystemZMC_FP128Regs[16]
const unsigned SystemZMC_FP64Regs[16]
const unsigned SystemZMC_GR32Regs[16]
const unsigned SystemZMC_FP32Regs[16]
const unsigned SystemZMC_GR64Regs[16]
int decodeInstruction(struct InternalInstruction *insn, byteReader_t reader, const void *readerArg, uint64_t startLoc, DisassemblerMode mode)
#define I(x)
Definition: arc.h:164
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)
unsigned short uint16_t
Definition: sftypes.h:30
unsigned long uint64_t
Definition: sftypes.h:28
unsigned char uint8_t
Definition: sftypes.h:31
Definition: length.h:9
Definition: MCInst.h:88
cs_insn * flat_insn
Definition: MCInst.h:95
Definition: inftree9.h:24
#define N
Definition: zip_err_str.c:8