test_arm64.c
Go to the documentation of this file.
1 /* Capstone Disassembler Engine */
2 /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013 */
3 
4 #include <stdio.h>
5 #include <stdlib.h>
6 
7 #include <capstone/platform.h>
8 #include <capstone/capstone.h>
9 
10 static csh handle;
11 
12 struct platform {
13  cs_arch arch;
14  cs_mode mode;
15  unsigned char *code;
16  size_t size;
17  const char *comment;
18 };
19 
20 static void print_string_hex(const char *comment, unsigned char *str, size_t len)
21 {
22  unsigned char *c;
23 
24  printf("%s", comment);
25  for (c = str; c < str + len; c++) {
26  printf("0x%02x ", *c & 0xff);
27  }
28 
29  printf("\n");
30 }
31 
32 static void print_insn_detail(cs_insn *ins)
33 {
34  cs_arm64 *arm64;
35  int i;
36  cs_regs regs_read, regs_write;
37  unsigned char regs_read_count, regs_write_count;
38  unsigned char access;
39 
40  // detail can be NULL if SKIPDATA option is turned ON
41  if (ins->detail == NULL)
42  return;
43 
44  arm64 = &(ins->detail->arm64);
45  if (arm64->op_count)
46  printf("\top_count: %u\n", arm64->op_count);
47 
48  for (i = 0; i < arm64->op_count; i++) {
49  cs_arm64_op *op = &(arm64->operands[i]);
50  switch(op->type) {
51  default:
52  break;
53  case ARM64_OP_REG:
54  printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg));
55  break;
56  case ARM64_OP_IMM:
57  printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 "\n", i, op->imm);
58  break;
59  case ARM64_OP_FP:
60 #if defined(_KERNEL_MODE)
61  // Issue #681: Windows kernel does not support formatting float point
62  printf("\t\toperands[%u].type: FP = <float_point_unsupported>\n", i);
63 #else
64  printf("\t\toperands[%u].type: FP = %f\n", i, op->fp);
65 #endif
66  break;
67  case ARM64_OP_MEM:
68  printf("\t\toperands[%u].type: MEM\n", i);
69  if (op->mem.base != ARM64_REG_INVALID)
70  printf("\t\t\toperands[%u].mem.base: REG = %s\n", i, cs_reg_name(handle, op->mem.base));
71  if (op->mem.index != ARM64_REG_INVALID)
72  printf("\t\t\toperands[%u].mem.index: REG = %s\n", i, cs_reg_name(handle, op->mem.index));
73  if (op->mem.disp != 0)
74  printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i, op->mem.disp);
75 
76  break;
77  case ARM64_OP_CIMM:
78  printf("\t\toperands[%u].type: C-IMM = %u\n", i, (int)op->imm);
79  break;
80  case ARM64_OP_REG_MRS:
81  printf("\t\toperands[%u].type: REG_MRS = 0x%x\n", i, op->reg);
82  break;
83  case ARM64_OP_REG_MSR:
84  printf("\t\toperands[%u].type: REG_MSR = 0x%x\n", i, op->reg);
85  break;
86  case ARM64_OP_PSTATE:
87  printf("\t\toperands[%u].type: PSTATE = 0x%x\n", i, op->pstate);
88  break;
89  case ARM64_OP_SYS:
90  printf("\t\toperands[%u].type: SYS = 0x%x\n", i, op->sys);
91  break;
92  case ARM64_OP_PREFETCH:
93  printf("\t\toperands[%u].type: PREFETCH = 0x%x\n", i, op->prefetch);
94  break;
95  case ARM64_OP_BARRIER:
96  printf("\t\toperands[%u].type: BARRIER = 0x%x\n", i, op->barrier);
97  break;
98  }
99 
100  access = op->access;
101  switch(access) {
102  default:
103  break;
104  case CS_AC_READ:
105  printf("\t\toperands[%u].access: READ\n", i);
106  break;
107  case CS_AC_WRITE:
108  printf("\t\toperands[%u].access: WRITE\n", i);
109  break;
110  case CS_AC_READ | CS_AC_WRITE:
111  printf("\t\toperands[%u].access: READ | WRITE\n", i);
112  break;
113  }
114 
115  if (op->shift.type != ARM64_SFT_INVALID &&
116  op->shift.value)
117  printf("\t\t\tShift: type = %u, value = %u\n",
118  op->shift.type, op->shift.value);
119 
120  if (op->ext != ARM64_EXT_INVALID)
121  printf("\t\t\tExt: %u\n", op->ext);
122 
123  if (op->vas != ARM64_VAS_INVALID)
124  printf("\t\t\tVector Arrangement Specifier: 0x%x\n", op->vas);
125 
126  if (op->vess != ARM64_VESS_INVALID)
127  printf("\t\t\tVector Element Size Specifier: %u\n", op->vess);
128 
129  if (op->vector_index != -1)
130  printf("\t\t\tVector Index: %u\n", op->vector_index);
131  }
132 
133  if (arm64->update_flags)
134  printf("\tUpdate-flags: True\n");
135 
136  if (arm64->writeback)
137  printf("\tWrite-back: True\n");
138 
139  if (arm64->cc)
140  printf("\tCode-condition: %u\n", arm64->cc);
141 
142  // Print out all registers accessed by this instruction (either implicit or explicit)
143  if (!cs_regs_access(handle, ins,
144  regs_read, &regs_read_count,
145  regs_write, &regs_write_count)) {
146  if (regs_read_count) {
147  printf("\tRegisters read:");
148  for(i = 0; i < regs_read_count; i++) {
149  printf(" %s", cs_reg_name(handle, regs_read[i]));
150  }
151  printf("\n");
152  }
153 
154  if (regs_write_count) {
155  printf("\tRegisters modified:");
156  for(i = 0; i < regs_write_count; i++) {
157  printf(" %s", cs_reg_name(handle, regs_write[i]));
158  }
159  printf("\n");
160  }
161  }
162 
163  printf("\n");
164 }
165 
166 static void test()
167 {
168 //#define ARM64_CODE "\xe1\x0b\x40\xb9" // ldr w1, [sp, #0x8]
169 //#define ARM64_CODE "\x21\x7c\x00\x53" // lsr w1, w1, #0x0
170 //#define ARM64_CODE "\x21\x7c\x02\x9b"
171 //#define ARM64_CODE "\x20\x04\x81\xda" // csneg x0, x1, x1, eq | cneg x0, x1, ne
172 //#define ARM64_CODE "\x20\x08\x02\x8b" // add x0, x1, x2, lsl #2
173 
174 //#define ARM64_CODE "\x20\xcc\x20\x8b"
175 //#define ARM64_CODE "\xe2\x8f\x40\xa9" // ldp x2, x3, [sp, #8]
176 //#define ARM64_CODE "\x20\x40\x60\x1e" // fmov d0, d1
177 //#define ARM64_CODE "\x20\x7c\x7d\x93" // sbfiz x0, x1, #3, #32
178 
179 //#define ARM64_CODE "\x20\x88\x43\xb3" // bfxil x0, x1, #3, #32
180 //#define ARM64_CODE "\x01\x71\x08\xd5" // sys #0, c7, c1, #0, x1
181 //#define ARM64_CODE "\x00\x71\x28\xd5" // sysl x0, #0, c7, c1, #0
182 
183 //#define ARM64_CODE "\x20\xf4\x18\x9e" // fcvtzs x0, s1, #3
184 //#define ARM64_CODE "\x20\x74\x0b\xd5" // dc zva, x0: FIXME: handle as "sys" insn
185 //#define ARM64_CODE "\x00\x90\x24\x1e" // fmov s0, ##10.00000000
186 //#define ARM64_CODE "\xe1\x0b\x40\xb9" // ldr w1, [sp, #0x8]
187 //#define ARM64_CODE "\x20\x78\x62\xf8" // ldr x0, [x1, x2, lsl #3]
188 //#define ARM64_CODE "\x41\x14\x44\xb3" // bfm x1, x2, #4, #5
189 //#define ARM64_CODE "\x80\x23\x29\xd5" // sysl x0, #1, c2, c3, #4
190 //#define ARM64_CODE "\x20\x00\x24\x1e" // fcvtas w0, s1
191 //#define ARM64_CODE "\x41\x04\x40\xd2" // eor x1, x2, #0x3
192 //#define ARM64_CODE "\x9f\x33\x03\xd5" // dsb osh
193 //#define ARM64_CODE "\x41\x10\x23\x8a" // bic x1, x2, x3, lsl #4
194 //#define ARM64_CODE "\x16\x41\x3c\xd5" // mrs x22, sp_el1
195 //#define ARM64_CODE "\x41\x1c\x63\x0e" // bic v1.8b, v2.8b, v3.8b
196 //#define ARM64_CODE "\x41\xd4\xe3\x6e" // fabd v1.2d, v2.2d, v3.2d
197 //#define ARM64_CODE "\x20\x8c\x62\x2e" // cmeq v0.4h, v1.4h, v2.4h
198 //#define ARM64_CODE "\x20\x98\x20\x4e" // cmeq v0.16b, v1.16b, #0
199 //#define ARM64_CODE "\x20\x2c\x05\x4e" // smov x0, v1.b[2]
200 //#define ARM64_CODE "\x21\xe4\x00\x2f" // movi d1, #0xff
201 //#define ARM64_CODE "\x60\x78\x08\xd5" // at s1e0w, x0 // FIXME: same problem with dc ZVA
202 //#define ARM64_CODE "\x20\x00\xa0\xf2" // movk x0, #1, lsl #16
203 //#define ARM64_CODE "\x20\x08\x00\xb1" // adds x0, x1, #0x2
204 //#define ARM64_CODE "\x41\x04\x00\x0f" // movi v1.2s, #0x2
205 //#define ARM64_CODE "\x06\x00\x00\x14" // b 0x44
206 //#define ARM64_CODE "\x00\x90\x24\x1e" // fmov s0, ##10.00000000
207 //#define ARM64_CODE "\x5f\x3f\x03\xd5" // clrex
208 //#define ARM64_CODE "\x5f\x3e\x03\xd5" // clrex #14
209 //#define ARM64_CODE "\x20\x00\x02\xab" // adds x0, x1, x2 (alias of adds x0, x1, x2, lsl #0)
210 //#define ARM64_CODE "\x20\xf4\x18\x9e" // fcvtzs x0, s1, #3
211 //#define ARM64_CODE "\x20\xfc\x02\x9b" // mneg x0, x1, x2
212 //#define ARM64_CODE "\xd0\xb6\x1e\xd5" // msr s3_6_c11_c6_6, x16
213 
214 //#define ARM64_CODE "\x21\x7c\x02\x9b\x21\x7c\x00\x53\x00\x40\x21\x4b\xe1\x0b\x40\xb9\x20\x04\x81\xda\x20\x08\x02\x8b"
215 
216 //#define ARM64_CODE "\x09\x00\x38\xd5" // DBarrier
217 //#define ARM64_CODE "\x20\xe4\x3d\x0f\xa2\x00\xae\x9e"
218 //#define ARM64_CODE "\x9f\x37\x03\xd5\xbf\x33\x03\xd5\xdf\x3f\x03\xd5" // DBarrier
219 //#define ARM64_CODE "\x10\x5b\xe8\x3c"
220 //#define ARM64_CODE "\x00\x18\xa0\x5f\xa2\x00\xae\x9e"
221 
222 #define ARM64_CODE "\x09\x00\x38\xd5\xbf\x40\x00\xd5\x0c\x05\x13\xd5\x20\x50\x02\x0e\x20\xe4\x3d\x0f\x00\x18\xa0\x5f\xa2\x00\xae\x9e\x9f\x37\x03\xd5\xbf\x33\x03\xd5\xdf\x3f\x03\xd5\x21\x7c\x02\x9b\x21\x7c\x00\x53\x00\x40\x21\x4b\xe1\x0b\x40\xb9\x20\x04\x81\xda\x20\x08\x02\x8b\x10\x5b\xe8\x3c"
223 
224  struct platform platforms[] = {
225  {
227  CS_MODE_ARM,
228  (unsigned char *)ARM64_CODE,
229  sizeof(ARM64_CODE) - 1,
230  "ARM-64"
231  },
232  };
233 
234  uint64_t address = 0x2c;
235  cs_insn *insn;
236  int i;
237  size_t count;
238 
239  for (i = 0; i < sizeof(platforms)/sizeof(platforms[0]); i++) {
240  cs_err err = cs_open(platforms[i].arch, platforms[i].mode, &handle);
241  if (err) {
242  printf("Failed on cs_open() with error returned: %u\n", err);
243  abort();
244  }
245 
247 
248  count = cs_disasm(handle, platforms[i].code, platforms[i].size, address, 0, &insn);
249  if (count) {
250  size_t j;
251 
252  printf("****************\n");
253  printf("Platform: %s\n", platforms[i].comment);
255  printf("Disasm:\n");
256 
257  for (j = 0; j < count; j++) {
258  printf("0x%" PRIx64 ":\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str);
259  print_insn_detail(&insn[j]);
260  }
261  printf("0x%" PRIx64 ":\n", insn[j-1].address + insn[j-1].size);
262 
263  // free memory allocated by cs_disasm()
264  cs_free(insn, count);
265  } else {
266  printf("****************\n");
267  printf("Platform: %s\n", platforms[i].comment);
269  printf("ERROR: Failed to disasm given code!\n");
270  abort();
271  }
272 
273  printf("\n");
274 
275  cs_close(&handle);
276  }
277 }
278 
279 int main()
280 {
281  test();
282 
283  return 0;
284 }
285 
xds_interop_client.str
str
Definition: xds_interop_client.py:487
ARM64_OP_FP
@ ARM64_OP_FP
= CS_OP_FP (Floating-Point operand).
Definition: arm64.h:238
cs_close
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_close(csh *handle)
Definition: cs.c:522
test
static void test()
Definition: test_arm64.c:166
ARM64_OP_PREFETCH
@ ARM64_OP_PREFETCH
Prefetch operand (PRFM).
Definition: arm64.h:244
print_string_hex
static void print_string_hex(const char *comment, unsigned char *str, size_t len)
Definition: test_arm64.c:20
ARM64_OP_REG_MRS
@ ARM64_OP_REG_MRS
MRS register operand.
Definition: arm64.h:240
cs_arm64_op
Instruction operand.
Definition: arm64.h:630
platform::code
unsigned char * code
Definition: test_arm_regression.c:21
CS_MODE_ARM
@ CS_MODE_ARM
32-bit ARM
Definition: capstone.h:105
cs_disasm
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:822
printf
_Use_decl_annotations_ int __cdecl printf(const char *_Format,...)
Definition: cs_driver.c:91
error_ref_leak.err
err
Definition: error_ref_leak.py:35
cs_open
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_open(cs_arch arch, cs_mode mode, csh *handle)
Definition: cs.c:474
platform::mode
cs_mode mode
Definition: test_arm_regression.c:20
cs_arch
cs_arch
Architecture type.
Definition: capstone.h:74
mode
const char int mode
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:135
CS_OPT_DETAIL
@ CS_OPT_DETAIL
Break down instruction structure into details.
Definition: capstone.h:172
ARM64_OP_REG
@ ARM64_OP_REG
= CS_OP_REG (Register operand).
Definition: arm64.h:235
ARM64_VESS_INVALID
@ ARM64_VESS_INVALID
Definition: arm64.h:208
ARM64_OP_SYS
@ ARM64_OP_SYS
SYS operand for IC/DC/AT/TLBI instructions.
Definition: arm64.h:243
CS_AC_READ
@ CS_AC_READ
Operand read from memory or register.
Definition: capstone.h:205
main
int main()
Definition: test_arm64.c:279
cs_regs_access
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_regs_access(csh ud, const cs_insn *insn, cs_regs regs_read, uint8_t *regs_read_count, cs_regs regs_write, uint8_t *regs_write_count)
Definition: cs.c:1539
ARM64_VAS_INVALID
@ ARM64_VAS_INVALID
Definition: arm64.h:194
cs_option
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_option(csh ud, cs_opt_type type, size_t value)
Definition: cs.c:670
ARM64_OP_REG_MSR
@ ARM64_OP_REG_MSR
MSR register operand.
Definition: arm64.h:241
ARM64_OP_PSTATE
@ ARM64_OP_PSTATE
PState operand.
Definition: arm64.h:242
cs_mode
cs_mode
Mode type.
Definition: capstone.h:103
capstone.h
c
void c(T a)
Definition: miscompile_with_no_unique_address_test.cc:40
cs_reg_name
const CAPSTONE_EXPORT char *CAPSTONE_API cs_reg_name(csh ud, unsigned int reg)
Definition: cs.c:1176
platform.h
uint64_t
unsigned __int64 uint64_t
Definition: stdint-msvc2008.h:90
CS_OPT_ON
@ CS_OPT_ON
Turn ON an option (CS_OPT_DETAIL, CS_OPT_SKIPDATA).
Definition: capstone.h:184
platform::comment
char * comment
Definition: test_arm_regression.c:23
arch
cs_arch arch
Definition: cstool.c:13
platform::arch
cs_arch arch
Definition: test_arm_regression.c:19
ARM64_CODE
#define ARM64_CODE
arm64
Definition: test_winkernel.cpp:59
csh
size_t csh
Definition: capstone.h:71
ARM64_OP_CIMM
@ ARM64_OP_CIMM
C-Immediate.
Definition: arm64.h:239
ARM64_SFT_INVALID
@ ARM64_SFT_INVALID
Definition: arm64.h:19
count
int * count
Definition: bloaty/third_party/googletest/googlemock/test/gmock_stress_test.cc:96
ARM64_OP_BARRIER
@ ARM64_OP_BARRIER
Memory barrier operand (ISB/DMB/DSB instructions).
Definition: arm64.h:245
print_insn_detail
static void print_insn_detail(cs_insn *ins)
Definition: test_arm64.c:32
ARM64_EXT_INVALID
@ ARM64_EXT_INVALID
Definition: arm64.h:29
ARM64_OP_IMM
@ ARM64_OP_IMM
= CS_OP_IMM (Immediate operand).
Definition: arm64.h:236
cs_free
CAPSTONE_EXPORT void CAPSTONE_API cs_free(cs_insn *insn, size_t count)
Definition: cs.c:1039
ARM64_OP_MEM
@ ARM64_OP_MEM
= CS_OP_MEM (Memory operand).
Definition: arm64.h:237
CS_ARCH_ARM64
@ CS_ARCH_ARM64
ARM-64, also called AArch64.
Definition: capstone.h:76
code
Definition: bloaty/third_party/zlib/contrib/infback9/inftree9.h:24
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
platforms
struct platform platforms[]
Definition: fuzz_diff.c:18
size
voidpf void uLong size
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
access
Definition: bloaty/third_party/zlib/examples/zran.c:75
ARM64_REG_INVALID
@ ARM64_REG_INVALID
Definition: arm64.h:348
op
static grpc_op * op
Definition: test/core/fling/client.cc:47
platform
Definition: test_arm_regression.c:18
platform::size
size_t size
Definition: test_arm_regression.c:22
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
CS_AC_WRITE
@ CS_AC_WRITE
Operand write to memory or register.
Definition: capstone.h:206
handle
static csh handle
Definition: test_arm64.c:10
cs_arm64
Instruction structure.
Definition: arm64.h:658


grpc
Author(s):
autogenerated on Fri May 16 2025 03:00:27