Rizin
unix-like reverse engineering framework and cli tools
XCoreInstPrinter.c
Go to the documentation of this file.
1 //===-- XCoreInstPrinter.cpp - Convert XCore MCInst to assembly syntax --------===//
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 // This class prints an XCore MCInst to a .s file.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 /* Capstone Disassembly Engine */
15 /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
16 
17 #ifdef CAPSTONE_HAS_XCORE
18 
19 #if defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64)
20 #pragma warning(disable : 4996) // disable MSVC's warning on strcpy()
21 #pragma warning(disable : 28719) // disable MSVC's warning on strcpy()
22 #endif
23 
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <capstone/platform.h>
28 
29 #include "XCoreInstPrinter.h"
30 #include "../../MCInst.h"
31 #include "../../utils.h"
32 #include "../../SStream.h"
33 #include "../../MCRegisterInfo.h"
34 #include "../../MathExtras.h"
35 #include "XCoreMapping.h"
36 
37 static const char *getRegisterName(unsigned RegNo);
38 
39 void XCore_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci)
40 {
41  /*
42  if (((cs_struct *)ud)->detail != CS_OPT_ON)
43  return;
44  */
45 }
46 
47 // stw sed, sp[3]
48 void XCore_insn_extract(MCInst *MI, const char *code)
49 {
50  int id;
51  char *p, *p2;
52  char tmp[128];
53 
54  strcpy(tmp, code); // safe because code is way shorter than 128 bytes
55 
56  // find the first space
57  p = strchr(tmp, ' ');
58  if (p) {
59  p++;
60  // find the next ','
61  p2 = strchr(p, ',');
62  if (p2) {
63  *p2 = '\0';
64  id = XCore_reg_id(p);
65  if (id) {
66  // register
67  if (MI->csh->detail) {
68  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].type = XCORE_OP_REG;
69  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].reg = id;
70  MI->flat_insn->detail->xcore.op_count++;
71  }
72  }
73  // next should be register, or memory?
74  // skip space
75  p2++;
76  while(*p2 && *p2 == ' ')
77  p2++;
78  if (*p2) {
79  // find '['
80  p = p2;
81  while(*p && *p != '[')
82  p++;
83  if (*p) {
84  // this is '['
85  *p = '\0';
86  id = XCore_reg_id(p2);
87  if (id) {
88  // base register
89  if (MI->csh->detail) {
90  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].type = XCORE_OP_MEM;
91  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.base = (uint8_t)id;
92  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.index = XCORE_REG_INVALID;
93  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.disp = 0;
94  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.direct = 1;
95  }
96 
97  p++;
98  p2 = p;
99  // until ']'
100  while(*p && *p != ']')
101  p++;
102  if (*p) {
103  *p = '\0';
104  // p2 is either index, or disp
105  id = XCore_reg_id(p2);
106  if (id) {
107  // index register
108  if (MI->csh->detail) {
109  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.index = (uint8_t)id;
110  }
111  } else {
112  // a number means disp
113  if (MI->csh->detail) {
114  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.disp = atoi(p2);
115  }
116  }
117  }
118 
119  if (MI->csh->detail) {
120  MI->flat_insn->detail->xcore.op_count++;
121  }
122  }
123  } else {
124  // a register?
125  id = XCore_reg_id(p2);
126  if (id) {
127  // register
128  if (MI->csh->detail) {
129  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].type = XCORE_OP_REG;
130  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].reg = id;
131  MI->flat_insn->detail->xcore.op_count++;
132  }
133  }
134  }
135  }
136  } else {
137  id = XCore_reg_id(p);
138  if (id) {
139  // register
140  if (MI->csh->detail) {
141  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].type = XCORE_OP_REG;
142  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].reg = id;
143  MI->flat_insn->detail->xcore.op_count++;
144  }
145  }
146  }
147  }
148 }
149 
150 static void set_mem_access(MCInst *MI, bool status, int reg)
151 {
152  if (MI->csh->detail != CS_OPT_ON)
153  return;
154 
155  MI->csh->doing_mem = status;
156  if (status) {
157  if (reg != 0xffff && reg != -0xffff) {
158  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].type = XCORE_OP_MEM;
159  if (reg) {
160  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.base = (uint8_t)reg;
161  } else {
162  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.base = XCORE_REG_INVALID;
163  }
164  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.index = XCORE_REG_INVALID;
165  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.disp = 0;
166  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.direct = 1;
167  } else {
168  // the last op should be the memory base
169  MI->flat_insn->detail->xcore.op_count--;
170  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].type = XCORE_OP_MEM;
171  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.base = (uint8_t)MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].reg;
172  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.index = XCORE_REG_INVALID;
173  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.disp = 0;
174  if (reg > 0)
175  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.direct = 1;
176  else
177  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.direct = -1;
178  }
179  } else {
180  if (reg) {
181  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.index = (uint8_t)reg;
182  // done, create the next operand slot
183  MI->flat_insn->detail->xcore.op_count++;
184  }
185  }
186 }
187 
188 static void _printOperand(MCInst *MI, MCOperand *MO, SStream *O)
189 {
190  if (MCOperand_isReg(MO)) {
191  unsigned reg;
192 
193  reg = MCOperand_getReg(MO);
194  SStream_concat0(O, getRegisterName(reg));
195 
196  if (MI->csh->detail) {
197  if (MI->csh->doing_mem) {
198  if (MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.base == ARM_REG_INVALID)
199  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.base = (uint8_t)reg;
200  else
201  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.index = (uint8_t)reg;
202  } else {
203  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].type = XCORE_OP_REG;
204  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].reg = reg;
205  MI->flat_insn->detail->xcore.op_count++;
206  }
207  }
208  } else if (MCOperand_isImm(MO)) {
209  int32_t Imm = (int32_t)MCOperand_getImm(MO);
210 
211  printInt32(O, Imm);
212 
213  if (MI->csh->detail) {
214  if (MI->csh->doing_mem) {
215  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].mem.disp = Imm;
216  } else {
217  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].type = XCORE_OP_IMM;
218  MI->flat_insn->detail->xcore.operands[MI->flat_insn->detail->xcore.op_count].imm = Imm;
219  MI->flat_insn->detail->xcore.op_count++;
220  }
221  }
222  }
223 }
224 
225 static void printOperand(MCInst *MI, int OpNum, SStream *O)
226 {
227  if (OpNum >= MI->size)
228  return;
229 
230  _printOperand(MI, MCInst_getOperand(MI, OpNum), O);
231 }
232 
233 static void printInlineJT(MCInst *MI, int OpNum, SStream *O)
234 {
235 }
236 
237 static void printInlineJT32(MCInst *MI, int OpNum, SStream *O)
238 {
239 }
240 
241 #define PRINT_ALIAS_INSTR
242 #include "XCoreGenAsmWriter.inc"
243 
244 void XCore_printInst(MCInst *MI, SStream *O, void *Info)
245 {
246  printInstruction(MI, O, Info);
247  set_mem_access(MI, false, 0);
248 }
249 
250 #endif
MCOperand * MCInst_getOperand(MCInst *inst, unsigned i)
Definition: MCInst.c:78
bool MCOperand_isReg(const MCOperand *op)
Definition: MCInst.c:101
int64_t MCOperand_getImm(MCOperand *op)
Definition: MCInst.c:128
unsigned MCOperand_getReg(const MCOperand *op)
getReg - Returns the register number.
Definition: MCInst.c:117
bool MCOperand_isImm(const MCOperand *op)
Definition: MCInst.c:106
void SStream_concat0(SStream *ss, const char *s)
Definition: SStream.c:31
void printInt32(SStream *O, int32_t val)
Definition: SStream.c:137
void XCore_insn_extract(MCInst *MI, const char *code)
void XCore_printInst(MCInst *MI, SStream *O, void *Info)
void XCore_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci)
xcore_reg XCore_reg_id(char *name)
@ ARM_REG_INVALID
Definition: arm.h:253
size_t csh
Definition: capstone.h:71
@ CS_OPT_ON
Turn ON an option (CS_OPT_DETAIL, CS_OPT_SKIPDATA).
Definition: capstone.h:183
@ XCORE_REG_INVALID
Definition: xcore.h:27
@ XCORE_OP_REG
= CS_OP_REG (Register operand).
Definition: xcore.h:20
@ XCORE_OP_IMM
= CS_OP_IMM (Immediate operand).
Definition: xcore.h:21
@ XCORE_OP_MEM
= CS_OP_MEM (Memory operand).
Definition: xcore.h:22
#define reg(n)
void * p
Definition: libc.cpp:67
static const char struct stat static buf struct stat static buf static vhangup int status
Definition: sflib.h:145
int id
Definition: op.c:540
#define O
Definition: rcond.c:14
int int32_t
Definition: sftypes.h:33
unsigned char uint8_t
Definition: sftypes.h:31
Definition: MCInst.h:88
cs_insn * flat_insn
Definition: MCInst.h:95
uint8_t size
Definition: MCInst.h:90
cs_struct * csh
Definition: MCInst.h:97
Definition: SStream.h:9
Definition: inftree9.h:24
bool doing_mem
Definition: cs_priv.h:70
cs_opt_value detail
Definition: cs_priv.h:68
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4