Rizin
unix-like reverse engineering framework and cli tools
test_m680x.c
Go to the documentation of this file.
1 /* Capstone Disassembler Engine */
2 /* M680X Backend by Wolfgang Schwotzer <wolfgang.schwotzer@gmx.net> 2017 */
3 
4 #include <stdio.h>
5 #include <string.h>
6 
7 #include <capstone/platform.h>
8 #include <capstone/capstone.h>
9 
10 #define ARR_SIZE(a) (sizeof(a)/sizeof(a[0]))
11 
12 #define WITH_DETAILS
13 
14 struct platform {
15  cs_arch arch;
16  cs_mode mode;
17  unsigned char *code;
18  size_t size;
19  const char *comment;
20 };
21 
22 static void print_string_hex(const char *comment, unsigned char *str, size_t len)
23 {
24  unsigned char *c;
25 
26  printf("%s", comment);
27 
28  for (c = str; c < str + len; c++)
29  printf("0x%02x ", *c & 0xff);
30 
31  printf("\n");
32 }
33 
34 static void print_string_hex_short(unsigned char *str, size_t len)
35 {
36  unsigned char *c;
37 
38  for (c = str; c < str + len; c++)
39  printf("%02x", *c & 0xff);
40 }
41 
42 static const char *s_access[] = {
43  "UNCHANGED", "READ", "WRITE", "READ | WRITE",
44 };
45 
46 static void print_read_write_regs(csh handle, cs_detail *detail)
47 {
48  int i;
49 
50  if (detail->regs_read_count > 0) {
51  printf("\tRegisters read:");
52 
53  for (i = 0; i < detail->regs_read_count; ++i)
54  printf(" %s",
55  cs_reg_name(handle, detail->regs_read[i]));
56 
57  printf("\n");
58  }
59 
60  if (detail->regs_write_count > 0) {
61  printf("\tRegisters modified:");
62 
63  for (i = 0; i < detail->regs_write_count; ++i)
64  printf(" %s",
65  cs_reg_name(handle, detail->regs_write[i]));
66 
67  printf("\n");
68  }
69 }
70 
71 static void print_insn_detail(csh handle, cs_insn *insn)
72 {
73  cs_detail *detail = insn->detail;
74  cs_m680x *m680x = NULL;
75  int i;
76 
77  // detail can be NULL on "data" instruction if SKIPDATA option is turned ON
78  if (detail == NULL)
79  return;
80 
81  m680x = &detail->m680x;
82 
83  if (m680x->op_count)
84  printf("\top_count: %u\n", m680x->op_count);
85 
86  for (i = 0; i < m680x->op_count; i++) {
87  cs_m680x_op *op = &(m680x->operands[i]);
88  const char *comment;
89 
90  switch ((int)op->type) {
91  default:
92  break;
93 
94  case M680X_OP_REGISTER:
95  comment = "";
96 
97  if ((i == 0 && (m680x->flags &
99  ((i == 1 && (m680x->flags &
101  comment = " (in mnemonic)";
102 
103  printf("\t\toperands[%u].type: REGISTER = %s%s\n", i,
104  cs_reg_name(handle, op->reg), comment);
105  break;
106 
107  case M680X_OP_CONSTANT:
108  printf("\t\toperands[%u].type: CONSTANT = %u\n", i,
109  op->const_val);
110  break;
111 
112  case M680X_OP_IMMEDIATE:
113  printf("\t\toperands[%u].type: IMMEDIATE = #%d\n", i,
114  op->imm);
115  break;
116 
117  case M680X_OP_DIRECT:
118  printf("\t\toperands[%u].type: DIRECT = 0x%02x\n", i,
119  op->direct_addr);
120  break;
121 
122  case M680X_OP_EXTENDED:
123  printf("\t\toperands[%u].type: EXTENDED %s = 0x%04x\n",
124  i, op->ext.indirect ? "INDIRECT" : "",
125  op->ext.address);
126  break;
127 
128  case M680X_OP_RELATIVE:
129  printf("\t\toperands[%u].type: RELATIVE = 0x%04x\n", i,
130  op->rel.address);
131  break;
132 
133  case M680X_OP_INDEXED:
134  printf("\t\toperands[%u].type: INDEXED%s\n", i,
135  (op->idx.flags & M680X_IDX_INDIRECT) ?
136  " INDIRECT" : "");
137 
138  if (op->idx.base_reg != M680X_REG_INVALID)
139  printf("\t\t\tbase register: %s\n",
140  cs_reg_name(handle, op->idx.base_reg));
141 
142  if (op->idx.offset_reg != M680X_REG_INVALID)
143  printf("\t\t\toffset register: %s\n",
144  cs_reg_name(handle, op->idx.offset_reg));
145 
146  if ((op->idx.offset_bits != 0) &&
147  (op->idx.offset_reg == M680X_REG_INVALID) &&
148  !op->idx.inc_dec) {
149  printf("\t\t\toffset: %d\n", op->idx.offset);
150 
151  if (op->idx.base_reg == M680X_REG_PC)
152  printf("\t\t\toffset address: 0x%x\n",
153  op->idx.offset_addr);
154 
155  printf("\t\t\toffset bits: %u\n",
156  op->idx.offset_bits);
157  }
158 
159  if (op->idx.inc_dec) {
160  const char *post_pre = op->idx.flags &
161  M680X_IDX_POST_INC_DEC ? "post" : "pre";
162  const char *inc_dec = (op->idx.inc_dec > 0) ?
163  "increment" : "decrement";
164 
165  printf("\t\t\t%s %s: %d\n", post_pre, inc_dec,
166  abs(op->idx.inc_dec));
167  }
168 
169  break;
170  }
171 
172  if (op->size != 0)
173  printf("\t\t\tsize: %u\n", op->size);
174 
175  if (op->access != CS_AC_INVALID)
176  printf("\t\t\taccess: %s\n", s_access[op->access]);
177 
178  }
179 
181 
182  if (detail->groups_count) {
183  printf("\tgroups_count: %u\n", detail->groups_count);
184  }
185 
186  printf("\n");
187 }
188 
189 static bool consistency_checks()
190 {
191  return true;
192 }
193 
194 static void test()
195 {
196 #define M6800_CODE \
197  "\x01\x09\x36\x64\x7f\x74\x10\x00\x90\x10\xA4\x10\xb6\x10\x00\x39"
198 
199 #define M6801_CODE \
200  "\x04\x05\x3c\x3d\x38\x93\x10\xec\x10\xed\x10\x39"
201 
202 #define M6805_CODE \
203  "\x04\x7f\x00\x17\x22\x28\x00\x2e\x00\x40\x42\x5a\x70\x8e\x97\x9c" \
204  "\xa0\x15\xad\x00\xc3\x10\x00\xda\x12\x34\xe5\x7f\xfe"
205 
206 #define M6808_CODE \
207  "\x31\x22\x00\x35\x22\x45\x10\x00\x4b\x00\x51\x10\x52\x5e\x22\x62" \
208  "\x65\x12\x34\x72\x84\x85\x86\x87\x8a\x8b\x8c\x94\x95\xa7\x10\xaf\x10" \
209  "\x9e\x60\x7f\x9e\x6b\x7f\x00\x9e\xd6\x10\x00\x9e\xe6\x7f"
210 
211 #define HCS08_CODE \
212  "\x32\x10\x00\x9e\xae\x9e\xce\x7f\x9e\xbe\x10\x00\x9e\xfe\x7f" \
213  "\x3e\x10\x00\x9e\xf3\x7f\x96\x10\x00\x9e\xff\x7f\x82"
214 
215 #define M6811_CODE \
216  "\x02\x03\x12\x7f\x10\x00\x13\x99\x08\x00\x14\x7f\x02\x15\x7f\x01" \
217  "\x1e\x7f\x20\x00\x8f\xcf" \
218  "\x18\x08\x18\x30\x18\x3c\x18\x67\x18\x8c\x10\x00\x18\x8f" \
219  "\x18\xce\x10\x00\x18\xff\x10\x00" \
220  "\x1a\xa3\x7f\x1a\xac\x1a\xee\x7f\x1a\xef\x7f\xcd\xac\x7f"
221 
222 #define CPU12_CODE \
223  "\x00\x04\x01\x00\x0c\x00\x80\x0e\x00\x80\x00\x11\x1e\x10\x00\x80\x00" \
224  "\x3b\x4a\x10\x00\x04\x4b\x01\x04\x4f\x7f\x80\x00\x8f\x10\x00\xb7\x52" \
225  "\xb7\xb1\xa6\x67\xa6\xfe\xa6\xf7\x18\x02\xe2\x30\x39\xe2\x10\x00" \
226  "\x18\x0c\x30\x39\x10\x00\x18\x11\x18\x12\x10\x00\x18\x19\x00\x18\x1e\x00" \
227  "\x18\x3e\x18\x3f\x00"
228 
229 #define HD6301_CODE \
230  "\x6b\x10\x00\x71\x10\x00\x72\x10\x10\x39"
231 
232 #define M6809_CODE \
233  "\x06\x10\x19\x1a\x55\x1e\x01\x23\xe9\x31\x06\x34\x55\xa6\x81" \
234  "\xa7\x89\x7f\xff\xa6\x9d\x10\x00\xa7\x91\xa6\x9f\x10\x00" \
235  "\x11\xac\x99\x10\x00\x39" \
236  \
237  "\xA6\x07\xA6\x27\xA6\x47\xA6\x67\xA6\x0F\xA6\x10" \
238  "\xA6\x80\xA6\x81\xA6\x82\xA6\x83\xA6\x84\xA6\x85\xA6\x86" \
239  "\xA6\x88\x7F\xA6\x88\x80\xA6\x89\x7F\xFF\xA6\x89\x80\x00" \
240  "\xA6\x8B\xA6\x8C\x10\xA6\x8D\x10\x00" \
241  \
242  "\xA6\x91\xA6\x93\xA6\x94\xA6\x95\xA6\x96" \
243  "\xA6\x98\x7F\xA6\x98\x80\xA6\x99\x7F\xFF\xA6\x99\x80\x00" \
244  "\xA6\x9B\xA6\x9C\x10\xA6\x9D\x10\x00\xA6\x9F\x10\x00"
245 
246 
247 #define HD6309_CODE \
248  "\x01\x10\x10\x62\x10\x10\x7b\x10\x10\x00\xcd\x49\x96\x02\xd2" \
249  "\x10\x30\x23\x10\x38\x10\x3b\x10\x53\x10\x5d" \
250  "\x11\x30\x43\x10\x11\x37\x25\x10\x11\x38\x12\x11\x39\x23\x11\x3b\x34" \
251  "\x11\x8e\x10\x00\x11\xaf\x10\x11\xab\x10\x11\xf6\x80\x00"
252 
253  struct platform platforms[] = {
254  {
257  (unsigned char *)HD6301_CODE,
258  sizeof(HD6301_CODE) - 1,
259  "M680X_HD6301",
260  },
261  {
264  (unsigned char *)HD6309_CODE,
265  sizeof(HD6309_CODE) - 1,
266  "M680X_HD6309",
267  },
268  {
271  (unsigned char *)M6800_CODE,
272  sizeof(M6800_CODE) - 1,
273  "M680X_M6800",
274  },
275  {
278  (unsigned char *)M6801_CODE,
279  sizeof(M6801_CODE) - 1,
280  "M680X_M6801",
281  },
282  {
285  (unsigned char *)M6805_CODE,
286  sizeof(M6805_CODE) - 1,
287  "M680X_M68HC05",
288  },
289  {
292  (unsigned char *)M6808_CODE,
293  sizeof(M6808_CODE) - 1,
294  "M680X_M68HC08",
295  },
296  {
299  (unsigned char *)M6809_CODE,
300  sizeof(M6809_CODE) - 1,
301  "M680X_M6809",
302  },
303  {
306  (unsigned char *)M6811_CODE,
307  sizeof(M6811_CODE) - 1,
308  "M680X_M68HC11",
309  },
310  {
313  (unsigned char *)CPU12_CODE,
314  sizeof(CPU12_CODE) - 1,
315  "M680X_CPU12",
316  },
317  {
320  (unsigned char *)HCS08_CODE,
321  sizeof(HCS08_CODE) - 1,
322  "M680X_HCS08",
323  },
324  };
325 
326  uint64_t address = 0x1000;
327  csh handle;
328  cs_insn *insn;
329  int i;
330  size_t count;
331  const char *nine_spaces = " ";
332 
333  if (!consistency_checks())
334  abort();
335 
336  for (i = 0; i < sizeof(platforms) / sizeof(platforms[0]); i++) {
337  cs_err err = cs_open(platforms[i].arch, platforms[i].mode,
338  &handle);
339 
340  if (err) {
341  printf("Failed on cs_open() with error returned: %u\n",
342  err);
343  abort();
344  }
345 
346 #ifdef WITH_DETAILS
348 #endif
349 
351  address, 0, &insn);
352 
353  if (count) {
354  size_t j;
355 
356  printf("********************\n");
357  printf("Platform: %s\n", platforms[i].comment);
358  print_string_hex("Code: ", platforms[i].code,
359  platforms[i].size);
360  printf("Disasm:\n");
361 
362  for (j = 0; j < count; j++) {
363  int slen;
364  printf("0x%04x: ", (uint16_t)insn[j].address);
366  insn[j].size);
367  printf("%.*s", 1 + ((5 - insn[j].size) * 2),
368  nine_spaces);
369  printf("%s", insn[j].mnemonic);
370  slen = (int)strlen(insn[j].mnemonic);
371  printf("%.*s", 1 + (5 - slen), nine_spaces);
372  printf("%s\n", insn[j].op_str);
373 #ifdef WITH_DETAILS
374  print_insn_detail(handle, &insn[j]);
375 #endif
376  }
377 
378  // free memory allocated by cs_disasm()
379  cs_free(insn, count);
380  }
381  else {
382  printf("********************\n");
383  printf("Platform: %s\n", platforms[i].comment);
384  print_string_hex("Code:", platforms[i].code,
385  platforms[i].size);
386  printf("ERROR: Failed to disasm given code!\n");
387  abort();
388  }
389 
390  cs_close(&handle);
391  }
392 }
393 
394 int main()
395 {
396  test();
397 
398  return 0;
399 }
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
static bool err
Definition: armass.c:435
static ut8 bytes[32]
Definition: asm_arc.c:23
static mcore_handle handle
Definition: asm_mcore.c:8
cs_arch
Architecture type.
Definition: capstone.h:74
@ CS_ARCH_M680X
680X architecture
Definition: capstone.h:85
cs_mode
Mode type.
Definition: capstone.h:102
@ CS_MODE_M680X_6811
M680X Motorola/Freescale/NXP 68HC11 mode.
Definition: capstone.h:133
@ CS_MODE_M680X_6805
M680X Motorola/Freescale 6805 mode.
Definition: capstone.h:130
@ CS_MODE_M680X_HCS08
M680X Freescale/NXP HCS08 mode.
Definition: capstone.h:136
@ CS_MODE_M680X_6309
M680X Hitachi 6309 mode.
Definition: capstone.h:127
@ CS_MODE_M680X_CPU12
used on M68HC12/HCS12
Definition: capstone.h:134
@ CS_MODE_M680X_6301
M680X Hitachi 6301,6303 mode.
Definition: capstone.h:126
@ CS_MODE_M680X_6801
M680X Motorola 6801,6803 mode.
Definition: capstone.h:129
@ CS_MODE_M680X_6800
M680X Motorola 6800,6802 mode.
Definition: capstone.h:128
@ CS_MODE_M680X_6808
M680X Motorola/Freescale/NXP 68HC08 mode.
Definition: capstone.h:131
@ CS_MODE_M680X_6809
M680X Motorola 6809 mode.
Definition: capstone.h:132
@ CS_OPT_DETAIL
Break down instruction structure into details.
Definition: capstone.h:171
size_t csh
Definition: capstone.h:71
@ CS_OPT_ON
Turn ON an option (CS_OPT_DETAIL, CS_OPT_SKIPDATA).
Definition: capstone.h:183
@ CS_AC_INVALID
Uninitialized/invalid access type.
Definition: capstone.h:203
#define NULL
Definition: cris-opc.c:27
CAPSTONE_EXPORT size_t CAPSTONE_API cs_disasm(csh ud, const uint8_t *buffer, size_t size, uint64_t offset, size_t count, cs_insn **insn)
Definition: cs.c:798
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_open(cs_arch arch, cs_mode mode, csh *handle)
Definition: cs.c:453
CAPSTONE_EXPORT void CAPSTONE_API cs_free(cs_insn *insn, size_t count)
Definition: cs.c:1017
CAPSTONE_EXPORT const char *CAPSTONE_API cs_reg_name(csh ud, unsigned int reg)
Definition: cs.c:1154
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_close(csh *handle)
Definition: cs.c:501
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_option(csh ud, cs_opt_type type, size_t value)
Definition: cs.c:646
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
Definition: cs_driver.c:93
cs_arch arch
Definition: cstool.c:13
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
struct platform platforms[]
Definition: fuzz_diff.c:18
voidpf void uLong size
Definition: ioapi.h:138
const char int mode
Definition: ioapi.h:137
#define M680X_IDX_INDIRECT
Definition: m680x.h:76
#define M680X_FIRST_OP_IN_MNEM
Definition: m680x.h:159
@ M680X_REG_INVALID
Definition: m680x.h:21
@ M680X_REG_PC
M6800/1/2/3/9, M6301/9.
Definition: m680x.h:46
#define M680X_IDX_POST_INC_DEC
Definition: m680x.h:78
@ M680X_OP_EXTENDED
= Extended addressing operand.
Definition: m680x.h:60
@ M680X_OP_INDEXED
= Indexed addressing operand.
Definition: m680x.h:59
@ M680X_OP_CONSTANT
Used e.g. for a bit index or page number.
Definition: m680x.h:63
@ M680X_OP_IMMEDIATE
= Immediate operand.
Definition: m680x.h:58
@ M680X_OP_REGISTER
= Register operand.
Definition: m680x.h:57
@ M680X_OP_RELATIVE
= Relative addressing operand.
Definition: m680x.h:62
@ M680X_OP_DIRECT
= Direct addressing operand.
Definition: m680x.h:61
#define M680X_SECOND_OP_IN_MNEM
Definition: m680x.h:162
static int
Definition: sfsocketcall.h:114
unsigned short uint16_t
Definition: sftypes.h:30
unsigned long uint64_t
Definition: sftypes.h:28
#define c(i)
Definition: sha256.c:43
Definition: inftree9.h:24
Instruction operand.
Definition: m680x.h:114
The M680X instruction and it's operands.
Definition: m680x.h:165
uint8_t flags
See: M680X instruction flags.
Definition: m680x.h:166
cs_m680x_op operands[M680X_OPERAND_COUNT]
operands for this insn.
Definition: m680x.h:168
uint8_t op_count
number of operands for the instruction or 0
Definition: m680x.h:167
unsigned char * code
#define M6808_CODE
#define M6805_CODE
static void print_insn_detail(csh handle, cs_insn *insn)
Definition: test_m680x.c:71
#define HD6301_CODE
static const char * s_access[]
Definition: test_m680x.c:42
static bool consistency_checks()
Definition: test_m680x.c:189
#define M6811_CODE
static void print_string_hex(const char *comment, unsigned char *str, size_t len)
Definition: test_m680x.c:22
#define HD6309_CODE
#define M6801_CODE
#define HCS08_CODE
#define CPU12_CODE
#define M6809_CODE
#define M6800_CODE
static void test()
Definition: test_m680x.c:194
static void print_string_hex_short(unsigned char *str, size_t len)
Definition: test_m680x.c:34
static void print_read_write_regs(csh handle, cs_detail *detail)
Definition: test_m680x.c:46
int main()
Definition: test_m680x.c:394
Definition: dis.c:32
mnemonic
Definition: z80asm.h:48