1*9a0e4156SSadaf Ebrahimi /* Capstone Disassembler Engine */
2*9a0e4156SSadaf Ebrahimi /* By Nguyen Anh Quynh <[email protected]>, 2013> */
3*9a0e4156SSadaf Ebrahimi
4*9a0e4156SSadaf Ebrahimi #include <stdio.h> // debug
5*9a0e4156SSadaf Ebrahimi #include <string.h>
6*9a0e4156SSadaf Ebrahimi #include <caml/mlvalues.h>
7*9a0e4156SSadaf Ebrahimi #include <caml/memory.h>
8*9a0e4156SSadaf Ebrahimi #include <caml/alloc.h>
9*9a0e4156SSadaf Ebrahimi #include <caml/fail.h>
10*9a0e4156SSadaf Ebrahimi
11*9a0e4156SSadaf Ebrahimi #include "capstone/capstone.h"
12*9a0e4156SSadaf Ebrahimi
13*9a0e4156SSadaf Ebrahimi #define ARR_SIZE(a) (sizeof(a)/sizeof(a[0]))
14*9a0e4156SSadaf Ebrahimi
15*9a0e4156SSadaf Ebrahimi
16*9a0e4156SSadaf Ebrahimi // count the number of positive members in @list
list_count(uint8_t * list,unsigned int max)17*9a0e4156SSadaf Ebrahimi static unsigned int list_count(uint8_t *list, unsigned int max)
18*9a0e4156SSadaf Ebrahimi {
19*9a0e4156SSadaf Ebrahimi unsigned int i;
20*9a0e4156SSadaf Ebrahimi
21*9a0e4156SSadaf Ebrahimi for(i = 0; i < max; i++)
22*9a0e4156SSadaf Ebrahimi if (list[i] == 0)
23*9a0e4156SSadaf Ebrahimi return i;
24*9a0e4156SSadaf Ebrahimi
25*9a0e4156SSadaf Ebrahimi return max;
26*9a0e4156SSadaf Ebrahimi }
27*9a0e4156SSadaf Ebrahimi
_cs_disasm(cs_arch arch,csh handle,const uint8_t * code,size_t code_len,uint64_t addr,size_t count)28*9a0e4156SSadaf Ebrahimi CAMLprim value _cs_disasm(cs_arch arch, csh handle, const uint8_t * code, size_t code_len, uint64_t addr, size_t count)
29*9a0e4156SSadaf Ebrahimi {
30*9a0e4156SSadaf Ebrahimi CAMLparam0();
31*9a0e4156SSadaf Ebrahimi CAMLlocal5(list, cons, rec_insn, array, tmp);
32*9a0e4156SSadaf Ebrahimi CAMLlocal4(arch_info, op_info_val, tmp2, tmp3);
33*9a0e4156SSadaf Ebrahimi cs_insn *insn;
34*9a0e4156SSadaf Ebrahimi size_t c;
35*9a0e4156SSadaf Ebrahimi
36*9a0e4156SSadaf Ebrahimi list = Val_emptylist;
37*9a0e4156SSadaf Ebrahimi
38*9a0e4156SSadaf Ebrahimi c = cs_disasm(handle, code, code_len, addr, count, &insn);
39*9a0e4156SSadaf Ebrahimi if (c) {
40*9a0e4156SSadaf Ebrahimi //printf("Found %lu insn, addr: %lx\n", c, addr);
41*9a0e4156SSadaf Ebrahimi uint64_t j;
42*9a0e4156SSadaf Ebrahimi for (j = c; j > 0; j--) {
43*9a0e4156SSadaf Ebrahimi unsigned int lcount, i;
44*9a0e4156SSadaf Ebrahimi cons = caml_alloc(2, 0);
45*9a0e4156SSadaf Ebrahimi
46*9a0e4156SSadaf Ebrahimi rec_insn = caml_alloc(10, 0);
47*9a0e4156SSadaf Ebrahimi Store_field(rec_insn, 0, Val_int(insn[j-1].id));
48*9a0e4156SSadaf Ebrahimi Store_field(rec_insn, 1, Val_int(insn[j-1].address));
49*9a0e4156SSadaf Ebrahimi Store_field(rec_insn, 2, Val_int(insn[j-1].size));
50*9a0e4156SSadaf Ebrahimi
51*9a0e4156SSadaf Ebrahimi // copy raw bytes of instruction
52*9a0e4156SSadaf Ebrahimi lcount = insn[j-1].size;
53*9a0e4156SSadaf Ebrahimi if (lcount) {
54*9a0e4156SSadaf Ebrahimi array = caml_alloc(lcount, 0);
55*9a0e4156SSadaf Ebrahimi for (i = 0; i < lcount; i++) {
56*9a0e4156SSadaf Ebrahimi Store_field(array, i, Val_int(insn[j-1].bytes[i]));
57*9a0e4156SSadaf Ebrahimi }
58*9a0e4156SSadaf Ebrahimi } else
59*9a0e4156SSadaf Ebrahimi array = Atom(0); // empty list
60*9a0e4156SSadaf Ebrahimi Store_field(rec_insn, 3, array);
61*9a0e4156SSadaf Ebrahimi
62*9a0e4156SSadaf Ebrahimi Store_field(rec_insn, 4, caml_copy_string(insn[j-1].mnemonic));
63*9a0e4156SSadaf Ebrahimi Store_field(rec_insn, 5, caml_copy_string(insn[j-1].op_str));
64*9a0e4156SSadaf Ebrahimi
65*9a0e4156SSadaf Ebrahimi // copy read registers
66*9a0e4156SSadaf Ebrahimi if (insn[0].detail) {
67*9a0e4156SSadaf Ebrahimi lcount = (insn[j-1]).detail->regs_read_count;
68*9a0e4156SSadaf Ebrahimi if (lcount) {
69*9a0e4156SSadaf Ebrahimi array = caml_alloc(lcount, 0);
70*9a0e4156SSadaf Ebrahimi for (i = 0; i < lcount; i++) {
71*9a0e4156SSadaf Ebrahimi Store_field(array, i, Val_int(insn[j-1].detail->regs_read[i]));
72*9a0e4156SSadaf Ebrahimi }
73*9a0e4156SSadaf Ebrahimi } else
74*9a0e4156SSadaf Ebrahimi array = Atom(0); // empty list
75*9a0e4156SSadaf Ebrahimi } else
76*9a0e4156SSadaf Ebrahimi array = Atom(0); // empty list
77*9a0e4156SSadaf Ebrahimi Store_field(rec_insn, 6, array);
78*9a0e4156SSadaf Ebrahimi
79*9a0e4156SSadaf Ebrahimi if (insn[0].detail) {
80*9a0e4156SSadaf Ebrahimi lcount = (insn[j-1]).detail->regs_write_count;
81*9a0e4156SSadaf Ebrahimi if (lcount) {
82*9a0e4156SSadaf Ebrahimi array = caml_alloc(lcount, 0);
83*9a0e4156SSadaf Ebrahimi for (i = 0; i < lcount; i++) {
84*9a0e4156SSadaf Ebrahimi Store_field(array, i, Val_int(insn[j-1].detail->regs_write[i]));
85*9a0e4156SSadaf Ebrahimi }
86*9a0e4156SSadaf Ebrahimi } else
87*9a0e4156SSadaf Ebrahimi array = Atom(0); // empty list
88*9a0e4156SSadaf Ebrahimi } else
89*9a0e4156SSadaf Ebrahimi array = Atom(0); // empty list
90*9a0e4156SSadaf Ebrahimi Store_field(rec_insn, 7, array);
91*9a0e4156SSadaf Ebrahimi
92*9a0e4156SSadaf Ebrahimi if (insn[0].detail) {
93*9a0e4156SSadaf Ebrahimi lcount = (insn[j-1]).detail->groups_count;
94*9a0e4156SSadaf Ebrahimi if (lcount) {
95*9a0e4156SSadaf Ebrahimi array = caml_alloc(lcount, 0);
96*9a0e4156SSadaf Ebrahimi for (i = 0; i < lcount; i++) {
97*9a0e4156SSadaf Ebrahimi Store_field(array, i, Val_int(insn[j-1].detail->groups[i]));
98*9a0e4156SSadaf Ebrahimi }
99*9a0e4156SSadaf Ebrahimi } else
100*9a0e4156SSadaf Ebrahimi array = Atom(0); // empty list
101*9a0e4156SSadaf Ebrahimi } else
102*9a0e4156SSadaf Ebrahimi array = Atom(0); // empty list
103*9a0e4156SSadaf Ebrahimi Store_field(rec_insn, 8, array);
104*9a0e4156SSadaf Ebrahimi
105*9a0e4156SSadaf Ebrahimi if (insn[j-1].detail) {
106*9a0e4156SSadaf Ebrahimi switch(arch) {
107*9a0e4156SSadaf Ebrahimi case CS_ARCH_ARM:
108*9a0e4156SSadaf Ebrahimi arch_info = caml_alloc(1, 0);
109*9a0e4156SSadaf Ebrahimi
110*9a0e4156SSadaf Ebrahimi op_info_val = caml_alloc(10, 0);
111*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 0, Val_bool(insn[j-1].detail->arm.usermode));
112*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 1, Val_int(insn[j-1].detail->arm.vector_size));
113*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 2, Val_int(insn[j-1].detail->arm.vector_data));
114*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 3, Val_int(insn[j-1].detail->arm.cps_mode));
115*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 4, Val_int(insn[j-1].detail->arm.cps_flag));
116*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 5, Val_int(insn[j-1].detail->arm.cc));
117*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 6, Val_bool(insn[j-1].detail->arm.update_flags));
118*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 7, Val_bool(insn[j-1].detail->arm.writeback));
119*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 8, Val_int(insn[j-1].detail->arm.mem_barrier));
120*9a0e4156SSadaf Ebrahimi
121*9a0e4156SSadaf Ebrahimi lcount = insn[j-1].detail->arm.op_count;
122*9a0e4156SSadaf Ebrahimi if (lcount > 0) {
123*9a0e4156SSadaf Ebrahimi array = caml_alloc(lcount, 0);
124*9a0e4156SSadaf Ebrahimi for (i = 0; i < lcount; i++) {
125*9a0e4156SSadaf Ebrahimi tmp2 = caml_alloc(6, 0);
126*9a0e4156SSadaf Ebrahimi switch(insn[j-1].detail->arm.operands[i].type) {
127*9a0e4156SSadaf Ebrahimi case ARM_OP_REG:
128*9a0e4156SSadaf Ebrahimi case ARM_OP_SYSREG:
129*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 1);
130*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->arm.operands[i].reg));
131*9a0e4156SSadaf Ebrahimi break;
132*9a0e4156SSadaf Ebrahimi case ARM_OP_CIMM:
133*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 2);
134*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->arm.operands[i].imm));
135*9a0e4156SSadaf Ebrahimi break;
136*9a0e4156SSadaf Ebrahimi case ARM_OP_PIMM:
137*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 3);
138*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->arm.operands[i].imm));
139*9a0e4156SSadaf Ebrahimi break;
140*9a0e4156SSadaf Ebrahimi case ARM_OP_IMM:
141*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 4);
142*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->arm.operands[i].imm));
143*9a0e4156SSadaf Ebrahimi break;
144*9a0e4156SSadaf Ebrahimi case ARM_OP_FP:
145*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 5);
146*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, caml_copy_double(insn[j-1].detail->arm.operands[i].fp));
147*9a0e4156SSadaf Ebrahimi break;
148*9a0e4156SSadaf Ebrahimi case ARM_OP_MEM:
149*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 6);
150*9a0e4156SSadaf Ebrahimi tmp3 = caml_alloc(5, 0);
151*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 0, Val_int(insn[j-1].detail->arm.operands[i].mem.base));
152*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 1, Val_int(insn[j-1].detail->arm.operands[i].mem.index));
153*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 2, Val_int(insn[j-1].detail->arm.operands[i].mem.scale));
154*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 3, Val_int(insn[j-1].detail->arm.operands[i].mem.disp));
155*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 4, Val_int(insn[j-1].detail->arm.operands[i].mem.lshift));
156*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, tmp3);
157*9a0e4156SSadaf Ebrahimi break;
158*9a0e4156SSadaf Ebrahimi case ARM_OP_SETEND:
159*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 7);
160*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->arm.operands[i].setend));
161*9a0e4156SSadaf Ebrahimi break;
162*9a0e4156SSadaf Ebrahimi default: break;
163*9a0e4156SSadaf Ebrahimi }
164*9a0e4156SSadaf Ebrahimi tmp3 = caml_alloc(2, 0);
165*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 0, Val_int(insn[j-1].detail->arm.operands[i].shift.type));
166*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 1, Val_int(insn[j-1].detail->arm.operands[i].shift.value));
167*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 0, Val_int(insn[j-1].detail->arm.operands[i].vector_index));
168*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 1, tmp3);
169*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 2, tmp);
170*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 3, Val_bool(insn[j-1].detail->arm.operands[i].subtracted));
171*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 4, Val_int(insn[j-1].detail->arm.operands[i].access));
172*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 5, Val_int(insn[j-1].detail->arm.operands[i].neon_lane));
173*9a0e4156SSadaf Ebrahimi Store_field(array, i, tmp2);
174*9a0e4156SSadaf Ebrahimi }
175*9a0e4156SSadaf Ebrahimi } else // empty list
176*9a0e4156SSadaf Ebrahimi array = Atom(0);
177*9a0e4156SSadaf Ebrahimi
178*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 9, array);
179*9a0e4156SSadaf Ebrahimi
180*9a0e4156SSadaf Ebrahimi // finally, insert this into arch_info
181*9a0e4156SSadaf Ebrahimi Store_field(arch_info, 0, op_info_val);
182*9a0e4156SSadaf Ebrahimi
183*9a0e4156SSadaf Ebrahimi Store_field(rec_insn, 9, arch_info);
184*9a0e4156SSadaf Ebrahimi
185*9a0e4156SSadaf Ebrahimi break;
186*9a0e4156SSadaf Ebrahimi case CS_ARCH_ARM64:
187*9a0e4156SSadaf Ebrahimi arch_info = caml_alloc(1, 1);
188*9a0e4156SSadaf Ebrahimi
189*9a0e4156SSadaf Ebrahimi op_info_val = caml_alloc(4, 0);
190*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 0, Val_int(insn[j-1].detail->arm64.cc));
191*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 1, Val_bool(insn[j-1].detail->arm64.update_flags));
192*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 2, Val_bool(insn[j-1].detail->arm64.writeback));
193*9a0e4156SSadaf Ebrahimi
194*9a0e4156SSadaf Ebrahimi lcount = insn[j-1].detail->arm64.op_count;
195*9a0e4156SSadaf Ebrahimi if (lcount > 0) {
196*9a0e4156SSadaf Ebrahimi array = caml_alloc(lcount, 0);
197*9a0e4156SSadaf Ebrahimi for (i = 0; i < lcount; i++) {
198*9a0e4156SSadaf Ebrahimi tmp2 = caml_alloc(6, 0);
199*9a0e4156SSadaf Ebrahimi switch(insn[j-1].detail->arm64.operands[i].type) {
200*9a0e4156SSadaf Ebrahimi case ARM64_OP_REG:
201*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 1);
202*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->arm64.operands[i].reg));
203*9a0e4156SSadaf Ebrahimi break;
204*9a0e4156SSadaf Ebrahimi case ARM64_OP_CIMM:
205*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 2);
206*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->arm64.operands[i].imm));
207*9a0e4156SSadaf Ebrahimi break;
208*9a0e4156SSadaf Ebrahimi case ARM64_OP_IMM:
209*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 3);
210*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->arm64.operands[i].imm));
211*9a0e4156SSadaf Ebrahimi break;
212*9a0e4156SSadaf Ebrahimi case ARM64_OP_FP:
213*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 4);
214*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, caml_copy_double(insn[j-1].detail->arm64.operands[i].fp));
215*9a0e4156SSadaf Ebrahimi break;
216*9a0e4156SSadaf Ebrahimi case ARM64_OP_MEM:
217*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 5);
218*9a0e4156SSadaf Ebrahimi tmp3 = caml_alloc(3, 0);
219*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 0, Val_int(insn[j-1].detail->arm64.operands[i].mem.base));
220*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 1, Val_int(insn[j-1].detail->arm64.operands[i].mem.index));
221*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 2, Val_int(insn[j-1].detail->arm64.operands[i].mem.disp));
222*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, tmp3);
223*9a0e4156SSadaf Ebrahimi break;
224*9a0e4156SSadaf Ebrahimi case ARM64_OP_REG_MRS:
225*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 6);
226*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->arm64.operands[i].reg));
227*9a0e4156SSadaf Ebrahimi break;
228*9a0e4156SSadaf Ebrahimi case ARM64_OP_REG_MSR:
229*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 7);
230*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->arm64.operands[i].reg));
231*9a0e4156SSadaf Ebrahimi break;
232*9a0e4156SSadaf Ebrahimi case ARM64_OP_PSTATE:
233*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 8);
234*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->arm64.operands[i].pstate));
235*9a0e4156SSadaf Ebrahimi break;
236*9a0e4156SSadaf Ebrahimi case ARM64_OP_SYS:
237*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 9);
238*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->arm64.operands[i].sys));
239*9a0e4156SSadaf Ebrahimi break;
240*9a0e4156SSadaf Ebrahimi case ARM64_OP_PREFETCH:
241*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 10);
242*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->arm64.operands[i].prefetch));
243*9a0e4156SSadaf Ebrahimi break;
244*9a0e4156SSadaf Ebrahimi case ARM64_OP_BARRIER:
245*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 11);
246*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->arm64.operands[i].barrier));
247*9a0e4156SSadaf Ebrahimi break;
248*9a0e4156SSadaf Ebrahimi default: break;
249*9a0e4156SSadaf Ebrahimi }
250*9a0e4156SSadaf Ebrahimi tmp3 = caml_alloc(2, 0);
251*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 0, Val_int(insn[j-1].detail->arm64.operands[i].shift.type));
252*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 1, Val_int(insn[j-1].detail->arm64.operands[i].shift.value));
253*9a0e4156SSadaf Ebrahimi
254*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 0, Val_int(insn[j-1].detail->arm64.operands[i].vector_index));
255*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 1, Val_int(insn[j-1].detail->arm64.operands[i].vas));
256*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 2, Val_int(insn[j-1].detail->arm64.operands[i].vess));
257*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 3, tmp3);
258*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 4, Val_int(insn[j-1].detail->arm64.operands[i].ext));
259*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 5, tmp);
260*9a0e4156SSadaf Ebrahimi
261*9a0e4156SSadaf Ebrahimi Store_field(array, i, tmp2);
262*9a0e4156SSadaf Ebrahimi }
263*9a0e4156SSadaf Ebrahimi } else // empty array
264*9a0e4156SSadaf Ebrahimi array = Atom(0);
265*9a0e4156SSadaf Ebrahimi
266*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 3, array);
267*9a0e4156SSadaf Ebrahimi
268*9a0e4156SSadaf Ebrahimi // finally, insert this into arch_info
269*9a0e4156SSadaf Ebrahimi Store_field(arch_info, 0, op_info_val);
270*9a0e4156SSadaf Ebrahimi
271*9a0e4156SSadaf Ebrahimi Store_field(rec_insn, 9, arch_info);
272*9a0e4156SSadaf Ebrahimi
273*9a0e4156SSadaf Ebrahimi break;
274*9a0e4156SSadaf Ebrahimi case CS_ARCH_MIPS:
275*9a0e4156SSadaf Ebrahimi arch_info = caml_alloc(1, 2);
276*9a0e4156SSadaf Ebrahimi
277*9a0e4156SSadaf Ebrahimi op_info_val = caml_alloc(1, 0);
278*9a0e4156SSadaf Ebrahimi
279*9a0e4156SSadaf Ebrahimi lcount = insn[j-1].detail->mips.op_count;
280*9a0e4156SSadaf Ebrahimi if (lcount > 0) {
281*9a0e4156SSadaf Ebrahimi array = caml_alloc(lcount, 0);
282*9a0e4156SSadaf Ebrahimi for (i = 0; i < lcount; i++) {
283*9a0e4156SSadaf Ebrahimi tmp2 = caml_alloc(1, 0);
284*9a0e4156SSadaf Ebrahimi switch(insn[j-1].detail->mips.operands[i].type) {
285*9a0e4156SSadaf Ebrahimi case MIPS_OP_REG:
286*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 1);
287*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->mips.operands[i].reg));
288*9a0e4156SSadaf Ebrahimi break;
289*9a0e4156SSadaf Ebrahimi case MIPS_OP_IMM:
290*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 2);
291*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->mips.operands[i].imm));
292*9a0e4156SSadaf Ebrahimi break;
293*9a0e4156SSadaf Ebrahimi case MIPS_OP_MEM:
294*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 3);
295*9a0e4156SSadaf Ebrahimi tmp3 = caml_alloc(2, 0);
296*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 0, Val_int(insn[j-1].detail->mips.operands[i].mem.base));
297*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 1, Val_int(insn[j-1].detail->mips.operands[i].mem.disp));
298*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, tmp3);
299*9a0e4156SSadaf Ebrahimi break;
300*9a0e4156SSadaf Ebrahimi default: break;
301*9a0e4156SSadaf Ebrahimi }
302*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 0, tmp);
303*9a0e4156SSadaf Ebrahimi Store_field(array, i, tmp2);
304*9a0e4156SSadaf Ebrahimi }
305*9a0e4156SSadaf Ebrahimi } else // empty array
306*9a0e4156SSadaf Ebrahimi array = Atom(0);
307*9a0e4156SSadaf Ebrahimi
308*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 0, array);
309*9a0e4156SSadaf Ebrahimi
310*9a0e4156SSadaf Ebrahimi // finally, insert this into arch_info
311*9a0e4156SSadaf Ebrahimi Store_field(arch_info, 0, op_info_val);
312*9a0e4156SSadaf Ebrahimi
313*9a0e4156SSadaf Ebrahimi Store_field(rec_insn, 9, arch_info);
314*9a0e4156SSadaf Ebrahimi
315*9a0e4156SSadaf Ebrahimi break;
316*9a0e4156SSadaf Ebrahimi case CS_ARCH_X86:
317*9a0e4156SSadaf Ebrahimi arch_info = caml_alloc(1, 3);
318*9a0e4156SSadaf Ebrahimi
319*9a0e4156SSadaf Ebrahimi op_info_val = caml_alloc(17, 0);
320*9a0e4156SSadaf Ebrahimi
321*9a0e4156SSadaf Ebrahimi // fill prefix
322*9a0e4156SSadaf Ebrahimi lcount = list_count(insn[j-1].detail->x86.prefix, ARR_SIZE(insn[j-1].detail->x86.prefix));
323*9a0e4156SSadaf Ebrahimi if (lcount) {
324*9a0e4156SSadaf Ebrahimi array = caml_alloc(lcount, 0);
325*9a0e4156SSadaf Ebrahimi for (i = 0; i < lcount; i++) {
326*9a0e4156SSadaf Ebrahimi Store_field(array, i, Val_int(insn[j-1].detail->x86.prefix[i]));
327*9a0e4156SSadaf Ebrahimi }
328*9a0e4156SSadaf Ebrahimi } else
329*9a0e4156SSadaf Ebrahimi array = Atom(0);
330*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 0, array);
331*9a0e4156SSadaf Ebrahimi
332*9a0e4156SSadaf Ebrahimi // fill opcode
333*9a0e4156SSadaf Ebrahimi lcount = list_count(insn[j-1].detail->x86.opcode, ARR_SIZE(insn[j-1].detail->x86.opcode));
334*9a0e4156SSadaf Ebrahimi if (lcount) {
335*9a0e4156SSadaf Ebrahimi array = caml_alloc(lcount, 0);
336*9a0e4156SSadaf Ebrahimi for (i = 0; i < lcount; i++) {
337*9a0e4156SSadaf Ebrahimi Store_field(array, i, Val_int(insn[j-1].detail->x86.opcode[i]));
338*9a0e4156SSadaf Ebrahimi }
339*9a0e4156SSadaf Ebrahimi } else
340*9a0e4156SSadaf Ebrahimi array = Atom(0);
341*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 1, array);
342*9a0e4156SSadaf Ebrahimi
343*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 2, Val_int(insn[j-1].detail->x86.rex));
344*9a0e4156SSadaf Ebrahimi
345*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 3, Val_int(insn[j-1].detail->x86.addr_size));
346*9a0e4156SSadaf Ebrahimi
347*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 4, Val_int(insn[j-1].detail->x86.modrm));
348*9a0e4156SSadaf Ebrahimi
349*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 5, Val_int(insn[j-1].detail->x86.sib));
350*9a0e4156SSadaf Ebrahimi
351*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 6, Val_int(insn[j-1].detail->x86.disp));
352*9a0e4156SSadaf Ebrahimi
353*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 7, Val_int(insn[j-1].detail->x86.sib_index));
354*9a0e4156SSadaf Ebrahimi
355*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 8, Val_int(insn[j-1].detail->x86.sib_scale));
356*9a0e4156SSadaf Ebrahimi
357*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 9, Val_int(insn[j-1].detail->x86.sib_base));
358*9a0e4156SSadaf Ebrahimi
359*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 10, Val_int(insn[j-1].detail->x86.xop_cc));
360*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 11, Val_int(insn[j-1].detail->x86.sse_cc));
361*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 12, Val_int(insn[j-1].detail->x86.avx_cc));
362*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 13, Val_int(insn[j-1].detail->x86.avx_sae));
363*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 14, Val_int(insn[j-1].detail->x86.avx_rm));
364*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 15, Val_int(insn[j-1].detail->x86.eflags));
365*9a0e4156SSadaf Ebrahimi
366*9a0e4156SSadaf Ebrahimi lcount = insn[j-1].detail->x86.op_count;
367*9a0e4156SSadaf Ebrahimi if (lcount > 0) {
368*9a0e4156SSadaf Ebrahimi array = caml_alloc(lcount, 0);
369*9a0e4156SSadaf Ebrahimi for (i = 0; i < lcount; i++) {
370*9a0e4156SSadaf Ebrahimi switch(insn[j-1].detail->x86.operands[i].type) {
371*9a0e4156SSadaf Ebrahimi case X86_OP_REG:
372*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 1);
373*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->x86.operands[i].reg));
374*9a0e4156SSadaf Ebrahimi break;
375*9a0e4156SSadaf Ebrahimi case X86_OP_IMM:
376*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 2);
377*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->x86.operands[i].imm));
378*9a0e4156SSadaf Ebrahimi break;
379*9a0e4156SSadaf Ebrahimi case X86_OP_MEM:
380*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 3);
381*9a0e4156SSadaf Ebrahimi tmp2 = caml_alloc(5, 0);
382*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 0, Val_int(insn[j-1].detail->x86.operands[i].mem.segment));
383*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 1, Val_int(insn[j-1].detail->x86.operands[i].mem.base));
384*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 2, Val_int(insn[j-1].detail->x86.operands[i].mem.index));
385*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 3, Val_int(insn[j-1].detail->x86.operands[i].mem.scale));
386*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 4, Val_int(insn[j-1].detail->x86.operands[i].mem.disp));
387*9a0e4156SSadaf Ebrahimi
388*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, tmp2);
389*9a0e4156SSadaf Ebrahimi break;
390*9a0e4156SSadaf Ebrahimi default:
391*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 0); // X86_OP_INVALID
392*9a0e4156SSadaf Ebrahimi break;
393*9a0e4156SSadaf Ebrahimi }
394*9a0e4156SSadaf Ebrahimi
395*9a0e4156SSadaf Ebrahimi tmp2 = caml_alloc(5, 0);
396*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 0, tmp);
397*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 1, Val_int(insn[j-1].detail->x86.operands[i].size));
398*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 2, Val_int(insn[j-1].detail->x86.operands[i].access));
399*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 3, Val_int(insn[j-1].detail->x86.operands[i].avx_bcast));
400*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 4, Val_int(insn[j-1].detail->x86.operands[i].avx_zero_opmask));
401*9a0e4156SSadaf Ebrahimi Store_field(array, i, tmp2);
402*9a0e4156SSadaf Ebrahimi }
403*9a0e4156SSadaf Ebrahimi } else // empty array
404*9a0e4156SSadaf Ebrahimi array = Atom(0);
405*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 16, array);
406*9a0e4156SSadaf Ebrahimi
407*9a0e4156SSadaf Ebrahimi // finally, insert this into arch_info
408*9a0e4156SSadaf Ebrahimi Store_field(arch_info, 0, op_info_val);
409*9a0e4156SSadaf Ebrahimi
410*9a0e4156SSadaf Ebrahimi Store_field(rec_insn, 9, arch_info);
411*9a0e4156SSadaf Ebrahimi break;
412*9a0e4156SSadaf Ebrahimi
413*9a0e4156SSadaf Ebrahimi case CS_ARCH_PPC:
414*9a0e4156SSadaf Ebrahimi arch_info = caml_alloc(1, 4);
415*9a0e4156SSadaf Ebrahimi
416*9a0e4156SSadaf Ebrahimi op_info_val = caml_alloc(4, 0);
417*9a0e4156SSadaf Ebrahimi
418*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 0, Val_int(insn[j-1].detail->ppc.bc));
419*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 1, Val_int(insn[j-1].detail->ppc.bh));
420*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 2, Val_bool(insn[j-1].detail->ppc.update_cr0));
421*9a0e4156SSadaf Ebrahimi
422*9a0e4156SSadaf Ebrahimi lcount = insn[j-1].detail->ppc.op_count;
423*9a0e4156SSadaf Ebrahimi if (lcount > 0) {
424*9a0e4156SSadaf Ebrahimi array = caml_alloc(lcount, 0);
425*9a0e4156SSadaf Ebrahimi for (i = 0; i < lcount; i++) {
426*9a0e4156SSadaf Ebrahimi tmp2 = caml_alloc(1, 0);
427*9a0e4156SSadaf Ebrahimi switch(insn[j-1].detail->ppc.operands[i].type) {
428*9a0e4156SSadaf Ebrahimi case PPC_OP_REG:
429*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 1);
430*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->ppc.operands[i].reg));
431*9a0e4156SSadaf Ebrahimi break;
432*9a0e4156SSadaf Ebrahimi case PPC_OP_IMM:
433*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 2);
434*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->ppc.operands[i].imm));
435*9a0e4156SSadaf Ebrahimi break;
436*9a0e4156SSadaf Ebrahimi case PPC_OP_MEM:
437*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 3);
438*9a0e4156SSadaf Ebrahimi tmp3 = caml_alloc(2, 0);
439*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 0, Val_int(insn[j-1].detail->ppc.operands[i].mem.base));
440*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 1, Val_int(insn[j-1].detail->ppc.operands[i].mem.disp));
441*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, tmp3);
442*9a0e4156SSadaf Ebrahimi break;
443*9a0e4156SSadaf Ebrahimi case PPC_OP_CRX:
444*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 4);
445*9a0e4156SSadaf Ebrahimi tmp3 = caml_alloc(3, 0);
446*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 0, Val_int(insn[j-1].detail->ppc.operands[i].crx.scale));
447*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 1, Val_int(insn[j-1].detail->ppc.operands[i].crx.reg));
448*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 2, Val_int(insn[j-1].detail->ppc.operands[i].crx.cond));
449*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, tmp3);
450*9a0e4156SSadaf Ebrahimi break;
451*9a0e4156SSadaf Ebrahimi default: break;
452*9a0e4156SSadaf Ebrahimi }
453*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 0, tmp);
454*9a0e4156SSadaf Ebrahimi Store_field(array, i, tmp2);
455*9a0e4156SSadaf Ebrahimi }
456*9a0e4156SSadaf Ebrahimi } else // empty array
457*9a0e4156SSadaf Ebrahimi array = Atom(0);
458*9a0e4156SSadaf Ebrahimi
459*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 3, array);
460*9a0e4156SSadaf Ebrahimi
461*9a0e4156SSadaf Ebrahimi // finally, insert this into arch_info
462*9a0e4156SSadaf Ebrahimi Store_field(arch_info, 0, op_info_val);
463*9a0e4156SSadaf Ebrahimi
464*9a0e4156SSadaf Ebrahimi Store_field(rec_insn, 9, arch_info);
465*9a0e4156SSadaf Ebrahimi
466*9a0e4156SSadaf Ebrahimi break;
467*9a0e4156SSadaf Ebrahimi
468*9a0e4156SSadaf Ebrahimi case CS_ARCH_SPARC:
469*9a0e4156SSadaf Ebrahimi arch_info = caml_alloc(1, 5);
470*9a0e4156SSadaf Ebrahimi
471*9a0e4156SSadaf Ebrahimi op_info_val = caml_alloc(3, 0);
472*9a0e4156SSadaf Ebrahimi
473*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 0, Val_int(insn[j-1].detail->sparc.cc));
474*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 1, Val_int(insn[j-1].detail->sparc.hint));
475*9a0e4156SSadaf Ebrahimi
476*9a0e4156SSadaf Ebrahimi lcount = insn[j-1].detail->sparc.op_count;
477*9a0e4156SSadaf Ebrahimi if (lcount > 0) {
478*9a0e4156SSadaf Ebrahimi array = caml_alloc(lcount, 0);
479*9a0e4156SSadaf Ebrahimi for (i = 0; i < lcount; i++) {
480*9a0e4156SSadaf Ebrahimi tmp2 = caml_alloc(1, 0);
481*9a0e4156SSadaf Ebrahimi switch(insn[j-1].detail->sparc.operands[i].type) {
482*9a0e4156SSadaf Ebrahimi case SPARC_OP_REG:
483*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 1);
484*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->sparc.operands[i].reg));
485*9a0e4156SSadaf Ebrahimi break;
486*9a0e4156SSadaf Ebrahimi case SPARC_OP_IMM:
487*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 2);
488*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->sparc.operands[i].imm));
489*9a0e4156SSadaf Ebrahimi break;
490*9a0e4156SSadaf Ebrahimi case SPARC_OP_MEM:
491*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 3);
492*9a0e4156SSadaf Ebrahimi tmp3 = caml_alloc(3, 0);
493*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 0, Val_int(insn[j-1].detail->sparc.operands[i].mem.base));
494*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 1, Val_int(insn[j-1].detail->sparc.operands[i].mem.index));
495*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 2, Val_int(insn[j-1].detail->sparc.operands[i].mem.disp));
496*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, tmp3);
497*9a0e4156SSadaf Ebrahimi break;
498*9a0e4156SSadaf Ebrahimi default: break;
499*9a0e4156SSadaf Ebrahimi }
500*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 0, tmp);
501*9a0e4156SSadaf Ebrahimi Store_field(array, i, tmp2);
502*9a0e4156SSadaf Ebrahimi }
503*9a0e4156SSadaf Ebrahimi } else // empty array
504*9a0e4156SSadaf Ebrahimi array = Atom(0);
505*9a0e4156SSadaf Ebrahimi
506*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 2, array);
507*9a0e4156SSadaf Ebrahimi
508*9a0e4156SSadaf Ebrahimi // finally, insert this into arch_info
509*9a0e4156SSadaf Ebrahimi Store_field(arch_info, 0, op_info_val);
510*9a0e4156SSadaf Ebrahimi
511*9a0e4156SSadaf Ebrahimi Store_field(rec_insn, 9, arch_info);
512*9a0e4156SSadaf Ebrahimi
513*9a0e4156SSadaf Ebrahimi break;
514*9a0e4156SSadaf Ebrahimi
515*9a0e4156SSadaf Ebrahimi case CS_ARCH_SYSZ:
516*9a0e4156SSadaf Ebrahimi arch_info = caml_alloc(1, 6);
517*9a0e4156SSadaf Ebrahimi
518*9a0e4156SSadaf Ebrahimi op_info_val = caml_alloc(2, 0);
519*9a0e4156SSadaf Ebrahimi
520*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 0, Val_int(insn[j-1].detail->sysz.cc));
521*9a0e4156SSadaf Ebrahimi
522*9a0e4156SSadaf Ebrahimi lcount = insn[j-1].detail->sysz.op_count;
523*9a0e4156SSadaf Ebrahimi if (lcount > 0) {
524*9a0e4156SSadaf Ebrahimi array = caml_alloc(lcount, 0);
525*9a0e4156SSadaf Ebrahimi for (i = 0; i < lcount; i++) {
526*9a0e4156SSadaf Ebrahimi tmp2 = caml_alloc(1, 0);
527*9a0e4156SSadaf Ebrahimi switch(insn[j-1].detail->sysz.operands[i].type) {
528*9a0e4156SSadaf Ebrahimi case SYSZ_OP_REG:
529*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 1);
530*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->sysz.operands[i].reg));
531*9a0e4156SSadaf Ebrahimi break;
532*9a0e4156SSadaf Ebrahimi case SYSZ_OP_ACREG:
533*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 2);
534*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->sysz.operands[i].reg));
535*9a0e4156SSadaf Ebrahimi break;
536*9a0e4156SSadaf Ebrahimi case SYSZ_OP_IMM:
537*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 3);
538*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->sysz.operands[i].imm));
539*9a0e4156SSadaf Ebrahimi break;
540*9a0e4156SSadaf Ebrahimi case SYSZ_OP_MEM:
541*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 4);
542*9a0e4156SSadaf Ebrahimi tmp3 = caml_alloc(4, 0);
543*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 0, Val_int(insn[j-1].detail->sysz.operands[i].mem.base));
544*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 1, Val_int(insn[j-1].detail->sysz.operands[i].mem.index));
545*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 2, caml_copy_int64(insn[j-1].detail->sysz.operands[i].mem.length));
546*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 3, caml_copy_int64(insn[j-1].detail->sysz.operands[i].mem.disp));
547*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, tmp3);
548*9a0e4156SSadaf Ebrahimi break;
549*9a0e4156SSadaf Ebrahimi default: break;
550*9a0e4156SSadaf Ebrahimi }
551*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 0, tmp);
552*9a0e4156SSadaf Ebrahimi Store_field(array, i, tmp2);
553*9a0e4156SSadaf Ebrahimi }
554*9a0e4156SSadaf Ebrahimi } else // empty array
555*9a0e4156SSadaf Ebrahimi array = Atom(0);
556*9a0e4156SSadaf Ebrahimi
557*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 1, array);
558*9a0e4156SSadaf Ebrahimi
559*9a0e4156SSadaf Ebrahimi // finally, insert this into arch_info
560*9a0e4156SSadaf Ebrahimi Store_field(arch_info, 0, op_info_val);
561*9a0e4156SSadaf Ebrahimi
562*9a0e4156SSadaf Ebrahimi Store_field(rec_insn, 9, arch_info);
563*9a0e4156SSadaf Ebrahimi
564*9a0e4156SSadaf Ebrahimi break;
565*9a0e4156SSadaf Ebrahimi
566*9a0e4156SSadaf Ebrahimi case CS_ARCH_XCORE:
567*9a0e4156SSadaf Ebrahimi arch_info = caml_alloc(1, 7);
568*9a0e4156SSadaf Ebrahimi
569*9a0e4156SSadaf Ebrahimi op_info_val = caml_alloc(1, 0);
570*9a0e4156SSadaf Ebrahimi
571*9a0e4156SSadaf Ebrahimi lcount = insn[j-1].detail->xcore.op_count;
572*9a0e4156SSadaf Ebrahimi if (lcount > 0) {
573*9a0e4156SSadaf Ebrahimi array = caml_alloc(lcount, 0);
574*9a0e4156SSadaf Ebrahimi for (i = 0; i < lcount; i++) {
575*9a0e4156SSadaf Ebrahimi tmp2 = caml_alloc(1, 0);
576*9a0e4156SSadaf Ebrahimi switch(insn[j-1].detail->xcore.operands[i].type) {
577*9a0e4156SSadaf Ebrahimi case XCORE_OP_REG:
578*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 1);
579*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->xcore.operands[i].reg));
580*9a0e4156SSadaf Ebrahimi break;
581*9a0e4156SSadaf Ebrahimi case XCORE_OP_IMM:
582*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 2);
583*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->xcore.operands[i].imm));
584*9a0e4156SSadaf Ebrahimi break;
585*9a0e4156SSadaf Ebrahimi case XCORE_OP_MEM:
586*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 3);
587*9a0e4156SSadaf Ebrahimi tmp3 = caml_alloc(4, 0);
588*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 0, Val_int(insn[j-1].detail->xcore.operands[i].mem.base));
589*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 1, Val_int(insn[j-1].detail->xcore.operands[i].mem.index));
590*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 2, caml_copy_int64(insn[j-1].detail->xcore.operands[i].mem.disp));
591*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 3, caml_copy_int64(insn[j-1].detail->xcore.operands[i].mem.direct));
592*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, tmp3);
593*9a0e4156SSadaf Ebrahimi break;
594*9a0e4156SSadaf Ebrahimi default: break;
595*9a0e4156SSadaf Ebrahimi }
596*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 0, tmp);
597*9a0e4156SSadaf Ebrahimi Store_field(array, i, tmp2);
598*9a0e4156SSadaf Ebrahimi }
599*9a0e4156SSadaf Ebrahimi } else // empty array
600*9a0e4156SSadaf Ebrahimi array = Atom(0);
601*9a0e4156SSadaf Ebrahimi
602*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 0, array);
603*9a0e4156SSadaf Ebrahimi
604*9a0e4156SSadaf Ebrahimi // finally, insert this into arch_info
605*9a0e4156SSadaf Ebrahimi Store_field(arch_info, 0, op_info_val);
606*9a0e4156SSadaf Ebrahimi
607*9a0e4156SSadaf Ebrahimi Store_field(rec_insn, 9, arch_info);
608*9a0e4156SSadaf Ebrahimi
609*9a0e4156SSadaf Ebrahimi break;
610*9a0e4156SSadaf Ebrahimi
611*9a0e4156SSadaf Ebrahimi case CS_ARCH_M680X:
612*9a0e4156SSadaf Ebrahimi arch_info = caml_alloc(1, 8);
613*9a0e4156SSadaf Ebrahimi
614*9a0e4156SSadaf Ebrahimi op_info_val = caml_alloc(2, 0); // struct cs_m680x
615*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 0, Val_int(insn[j-1].detail->m680x.flags));
616*9a0e4156SSadaf Ebrahimi
617*9a0e4156SSadaf Ebrahimi lcount = insn[j-1].detail->m680x.op_count;
618*9a0e4156SSadaf Ebrahimi if (lcount > 0) {
619*9a0e4156SSadaf Ebrahimi array = caml_alloc(lcount, 0);
620*9a0e4156SSadaf Ebrahimi for (i = 0; i < lcount; i++) {
621*9a0e4156SSadaf Ebrahimi tmp2 = caml_alloc(3, 0); // m680x_op
622*9a0e4156SSadaf Ebrahimi switch(insn[j-1].detail->m680x.operands[i].type) {
623*9a0e4156SSadaf Ebrahimi case M680X_OP_IMMEDIATE:
624*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 1); // imm
625*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->m680x.operands[i].imm));
626*9a0e4156SSadaf Ebrahimi break;
627*9a0e4156SSadaf Ebrahimi case M680X_OP_REGISTER:
628*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 2); // reg
629*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->m680x.operands[i].reg));
630*9a0e4156SSadaf Ebrahimi break;
631*9a0e4156SSadaf Ebrahimi case M680X_OP_INDEXED:
632*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 3);
633*9a0e4156SSadaf Ebrahimi tmp3 = caml_alloc(7, 0); // m680x_op_idx
634*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 0, Val_int(insn[j-1].detail->m680x.operands[i].idx.base_reg));
635*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 1, Val_int(insn[j-1].detail->m680x.operands[i].idx.offset_reg));
636*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 2, Val_int(insn[j-1].detail->m680x.operands[i].idx.offset));
637*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 3, Val_int(insn[j-1].detail->m680x.operands[i].idx.offset_addr));
638*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 4, Val_int(insn[j-1].detail->m680x.operands[i].idx.offset_bits));
639*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 5, Val_int(insn[j-1].detail->m680x.operands[i].idx.inc_dec));
640*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 6, Val_int(insn[j-1].detail->m680x.operands[i].idx.flags));
641*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, tmp3);
642*9a0e4156SSadaf Ebrahimi break;
643*9a0e4156SSadaf Ebrahimi case M680X_OP_RELATIVE:
644*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 4);
645*9a0e4156SSadaf Ebrahimi tmp3 = caml_alloc(2, 0); // m680x_op_rel
646*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 0, Val_int(insn[j-1].detail->m680x.operands[i].rel.address));
647*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 1, Val_int(insn[j-1].detail->m680x.operands[i].rel.offset));
648*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, tmp3);
649*9a0e4156SSadaf Ebrahimi break;
650*9a0e4156SSadaf Ebrahimi case M680X_OP_EXTENDED:
651*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 5);
652*9a0e4156SSadaf Ebrahimi tmp3 = caml_alloc(2, 0); // m680x_op_ext
653*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 0, Val_int(insn[j-1].detail->m680x.operands[i].ext.address));
654*9a0e4156SSadaf Ebrahimi Store_field(tmp3, 1, Val_bool(insn[j-1].detail->m680x.operands[i].ext.indirect));
655*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, tmp3);
656*9a0e4156SSadaf Ebrahimi break;
657*9a0e4156SSadaf Ebrahimi case M680X_OP_DIRECT:
658*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 6); // direct_addr
659*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->m680x.operands[i].direct_addr));
660*9a0e4156SSadaf Ebrahimi break;
661*9a0e4156SSadaf Ebrahimi case M680X_OP_CONSTANT:
662*9a0e4156SSadaf Ebrahimi tmp = caml_alloc(1, 7); // const_val
663*9a0e4156SSadaf Ebrahimi Store_field(tmp, 0, Val_int(insn[j-1].detail->m680x.operands[i].const_val));
664*9a0e4156SSadaf Ebrahimi break;
665*9a0e4156SSadaf Ebrahimi default: break;
666*9a0e4156SSadaf Ebrahimi }
667*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 0, tmp); // add union
668*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 1, Val_int(insn[j-1].detail->m680x.operands[i].size));
669*9a0e4156SSadaf Ebrahimi Store_field(tmp2, 2, Val_int(insn[j-1].detail->m680x.operands[i].access));
670*9a0e4156SSadaf Ebrahimi Store_field(array, i, tmp2); // add operand to operand array
671*9a0e4156SSadaf Ebrahimi }
672*9a0e4156SSadaf Ebrahimi } else // empty list
673*9a0e4156SSadaf Ebrahimi array = Atom(0);
674*9a0e4156SSadaf Ebrahimi
675*9a0e4156SSadaf Ebrahimi Store_field(op_info_val, 1, array);
676*9a0e4156SSadaf Ebrahimi
677*9a0e4156SSadaf Ebrahimi // finally, insert this into arch_info
678*9a0e4156SSadaf Ebrahimi Store_field(arch_info, 0, op_info_val);
679*9a0e4156SSadaf Ebrahimi
680*9a0e4156SSadaf Ebrahimi Store_field(rec_insn, 9, arch_info);
681*9a0e4156SSadaf Ebrahimi
682*9a0e4156SSadaf Ebrahimi break;
683*9a0e4156SSadaf Ebrahimi
684*9a0e4156SSadaf Ebrahimi default: break;
685*9a0e4156SSadaf Ebrahimi }
686*9a0e4156SSadaf Ebrahimi }
687*9a0e4156SSadaf Ebrahimi
688*9a0e4156SSadaf Ebrahimi Store_field(cons, 0, rec_insn); // head
689*9a0e4156SSadaf Ebrahimi Store_field(cons, 1, list); // tail
690*9a0e4156SSadaf Ebrahimi list = cons;
691*9a0e4156SSadaf Ebrahimi }
692*9a0e4156SSadaf Ebrahimi cs_free(insn, count);
693*9a0e4156SSadaf Ebrahimi }
694*9a0e4156SSadaf Ebrahimi
695*9a0e4156SSadaf Ebrahimi // do not free the handle here
696*9a0e4156SSadaf Ebrahimi //cs_close(&handle);
697*9a0e4156SSadaf Ebrahimi CAMLreturn(list);
698*9a0e4156SSadaf Ebrahimi }
699*9a0e4156SSadaf Ebrahimi
ocaml_cs_disasm(value _arch,value _mode,value _code,value _addr,value _count)700*9a0e4156SSadaf Ebrahimi CAMLprim value ocaml_cs_disasm(value _arch, value _mode, value _code, value _addr, value _count)
701*9a0e4156SSadaf Ebrahimi {
702*9a0e4156SSadaf Ebrahimi CAMLparam5(_arch, _mode, _code, _addr, _count);
703*9a0e4156SSadaf Ebrahimi CAMLlocal1(head);
704*9a0e4156SSadaf Ebrahimi csh handle;
705*9a0e4156SSadaf Ebrahimi cs_arch arch;
706*9a0e4156SSadaf Ebrahimi cs_mode mode = 0;
707*9a0e4156SSadaf Ebrahimi const uint8_t *code;
708*9a0e4156SSadaf Ebrahimi uint64_t addr;
709*9a0e4156SSadaf Ebrahimi size_t count, code_len;
710*9a0e4156SSadaf Ebrahimi
711*9a0e4156SSadaf Ebrahimi switch (Int_val(_arch)) {
712*9a0e4156SSadaf Ebrahimi case 0:
713*9a0e4156SSadaf Ebrahimi arch = CS_ARCH_ARM;
714*9a0e4156SSadaf Ebrahimi break;
715*9a0e4156SSadaf Ebrahimi case 1:
716*9a0e4156SSadaf Ebrahimi arch = CS_ARCH_ARM64;
717*9a0e4156SSadaf Ebrahimi break;
718*9a0e4156SSadaf Ebrahimi case 2:
719*9a0e4156SSadaf Ebrahimi arch = CS_ARCH_MIPS;
720*9a0e4156SSadaf Ebrahimi break;
721*9a0e4156SSadaf Ebrahimi case 3:
722*9a0e4156SSadaf Ebrahimi arch = CS_ARCH_X86;
723*9a0e4156SSadaf Ebrahimi break;
724*9a0e4156SSadaf Ebrahimi case 4:
725*9a0e4156SSadaf Ebrahimi arch = CS_ARCH_PPC;
726*9a0e4156SSadaf Ebrahimi break;
727*9a0e4156SSadaf Ebrahimi case 5:
728*9a0e4156SSadaf Ebrahimi arch = CS_ARCH_SPARC;
729*9a0e4156SSadaf Ebrahimi break;
730*9a0e4156SSadaf Ebrahimi case 6:
731*9a0e4156SSadaf Ebrahimi arch = CS_ARCH_SYSZ;
732*9a0e4156SSadaf Ebrahimi break;
733*9a0e4156SSadaf Ebrahimi case 7:
734*9a0e4156SSadaf Ebrahimi arch = CS_ARCH_XCORE;
735*9a0e4156SSadaf Ebrahimi break;
736*9a0e4156SSadaf Ebrahimi case 8:
737*9a0e4156SSadaf Ebrahimi arch = CS_ARCH_M68K;
738*9a0e4156SSadaf Ebrahimi break;
739*9a0e4156SSadaf Ebrahimi case 9:
740*9a0e4156SSadaf Ebrahimi arch = CS_ARCH_TMS320C64X;
741*9a0e4156SSadaf Ebrahimi break;
742*9a0e4156SSadaf Ebrahimi case 10:
743*9a0e4156SSadaf Ebrahimi arch = CS_ARCH_M680X;
744*9a0e4156SSadaf Ebrahimi break;
745*9a0e4156SSadaf Ebrahimi default:
746*9a0e4156SSadaf Ebrahimi caml_invalid_argument("Invalid arch");
747*9a0e4156SSadaf Ebrahimi return Val_emptylist;
748*9a0e4156SSadaf Ebrahimi }
749*9a0e4156SSadaf Ebrahimi
750*9a0e4156SSadaf Ebrahimi while (_mode != Val_emptylist) {
751*9a0e4156SSadaf Ebrahimi head = Field(_mode, 0); /* accessing the head */
752*9a0e4156SSadaf Ebrahimi switch (Int_val(head)) {
753*9a0e4156SSadaf Ebrahimi case 0:
754*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_LITTLE_ENDIAN;
755*9a0e4156SSadaf Ebrahimi break;
756*9a0e4156SSadaf Ebrahimi case 1:
757*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_ARM;
758*9a0e4156SSadaf Ebrahimi break;
759*9a0e4156SSadaf Ebrahimi case 2:
760*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_16;
761*9a0e4156SSadaf Ebrahimi break;
762*9a0e4156SSadaf Ebrahimi case 3:
763*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_32;
764*9a0e4156SSadaf Ebrahimi break;
765*9a0e4156SSadaf Ebrahimi case 4:
766*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_64;
767*9a0e4156SSadaf Ebrahimi break;
768*9a0e4156SSadaf Ebrahimi case 5:
769*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_THUMB;
770*9a0e4156SSadaf Ebrahimi break;
771*9a0e4156SSadaf Ebrahimi case 6:
772*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_MCLASS;
773*9a0e4156SSadaf Ebrahimi break;
774*9a0e4156SSadaf Ebrahimi case 7:
775*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_V8;
776*9a0e4156SSadaf Ebrahimi break;
777*9a0e4156SSadaf Ebrahimi case 8:
778*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_MICRO;
779*9a0e4156SSadaf Ebrahimi break;
780*9a0e4156SSadaf Ebrahimi case 9:
781*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_MIPS3;
782*9a0e4156SSadaf Ebrahimi break;
783*9a0e4156SSadaf Ebrahimi case 10:
784*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_MIPS32R6;
785*9a0e4156SSadaf Ebrahimi break;
786*9a0e4156SSadaf Ebrahimi case 11:
787*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_MIPS2;
788*9a0e4156SSadaf Ebrahimi break;
789*9a0e4156SSadaf Ebrahimi case 12:
790*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_V9;
791*9a0e4156SSadaf Ebrahimi break;
792*9a0e4156SSadaf Ebrahimi case 13:
793*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_BIG_ENDIAN;
794*9a0e4156SSadaf Ebrahimi break;
795*9a0e4156SSadaf Ebrahimi case 14:
796*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_MIPS32;
797*9a0e4156SSadaf Ebrahimi break;
798*9a0e4156SSadaf Ebrahimi case 15:
799*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_MIPS64;
800*9a0e4156SSadaf Ebrahimi break;
801*9a0e4156SSadaf Ebrahimi case 16:
802*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_QPX;
803*9a0e4156SSadaf Ebrahimi break;
804*9a0e4156SSadaf Ebrahimi case 17:
805*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_M680X_6301;
806*9a0e4156SSadaf Ebrahimi break;
807*9a0e4156SSadaf Ebrahimi case 18:
808*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_M680X_6309;
809*9a0e4156SSadaf Ebrahimi break;
810*9a0e4156SSadaf Ebrahimi case 19:
811*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_M680X_6800;
812*9a0e4156SSadaf Ebrahimi break;
813*9a0e4156SSadaf Ebrahimi case 20:
814*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_M680X_6801;
815*9a0e4156SSadaf Ebrahimi break;
816*9a0e4156SSadaf Ebrahimi case 21:
817*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_M680X_6805;
818*9a0e4156SSadaf Ebrahimi break;
819*9a0e4156SSadaf Ebrahimi case 22:
820*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_M680X_6808;
821*9a0e4156SSadaf Ebrahimi break;
822*9a0e4156SSadaf Ebrahimi case 23:
823*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_M680X_6809;
824*9a0e4156SSadaf Ebrahimi break;
825*9a0e4156SSadaf Ebrahimi case 24:
826*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_M680X_6811;
827*9a0e4156SSadaf Ebrahimi break;
828*9a0e4156SSadaf Ebrahimi case 25:
829*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_M680X_CPU12;
830*9a0e4156SSadaf Ebrahimi break;
831*9a0e4156SSadaf Ebrahimi case 26:
832*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_M680X_HCS08;
833*9a0e4156SSadaf Ebrahimi break;
834*9a0e4156SSadaf Ebrahimi default:
835*9a0e4156SSadaf Ebrahimi caml_invalid_argument("Invalid mode");
836*9a0e4156SSadaf Ebrahimi return Val_emptylist;
837*9a0e4156SSadaf Ebrahimi }
838*9a0e4156SSadaf Ebrahimi _mode = Field(_mode, 1); /* point to the tail for next loop */
839*9a0e4156SSadaf Ebrahimi }
840*9a0e4156SSadaf Ebrahimi
841*9a0e4156SSadaf Ebrahimi cs_err ret = cs_open(arch, mode, &handle);
842*9a0e4156SSadaf Ebrahimi if (ret != CS_ERR_OK) {
843*9a0e4156SSadaf Ebrahimi return Val_emptylist;
844*9a0e4156SSadaf Ebrahimi }
845*9a0e4156SSadaf Ebrahimi
846*9a0e4156SSadaf Ebrahimi code = (uint8_t *)String_val(_code);
847*9a0e4156SSadaf Ebrahimi code_len = caml_string_length(_code);
848*9a0e4156SSadaf Ebrahimi addr = Int64_val(_addr);
849*9a0e4156SSadaf Ebrahimi count = Int64_val(_count);
850*9a0e4156SSadaf Ebrahimi
851*9a0e4156SSadaf Ebrahimi CAMLreturn(_cs_disasm(arch, handle, code, code_len, addr, count));
852*9a0e4156SSadaf Ebrahimi }
853*9a0e4156SSadaf Ebrahimi
ocaml_cs_disasm_internal(value _arch,value _handle,value _code,value _addr,value _count)854*9a0e4156SSadaf Ebrahimi CAMLprim value ocaml_cs_disasm_internal(value _arch, value _handle, value _code, value _addr, value _count)
855*9a0e4156SSadaf Ebrahimi {
856*9a0e4156SSadaf Ebrahimi CAMLparam5(_arch, _handle, _code, _addr, _count);
857*9a0e4156SSadaf Ebrahimi csh handle;
858*9a0e4156SSadaf Ebrahimi cs_arch arch;
859*9a0e4156SSadaf Ebrahimi const uint8_t *code;
860*9a0e4156SSadaf Ebrahimi uint64_t addr, count, code_len;
861*9a0e4156SSadaf Ebrahimi
862*9a0e4156SSadaf Ebrahimi handle = Int64_val(_handle);
863*9a0e4156SSadaf Ebrahimi
864*9a0e4156SSadaf Ebrahimi arch = Int_val(_arch);
865*9a0e4156SSadaf Ebrahimi code = (uint8_t *)String_val(_code);
866*9a0e4156SSadaf Ebrahimi code_len = caml_string_length(_code);
867*9a0e4156SSadaf Ebrahimi addr = Int64_val(_addr);
868*9a0e4156SSadaf Ebrahimi count = Int64_val(_count);
869*9a0e4156SSadaf Ebrahimi
870*9a0e4156SSadaf Ebrahimi CAMLreturn(_cs_disasm(arch, handle, code, code_len, addr, count));
871*9a0e4156SSadaf Ebrahimi }
872*9a0e4156SSadaf Ebrahimi
ocaml_open(value _arch,value _mode)873*9a0e4156SSadaf Ebrahimi CAMLprim value ocaml_open(value _arch, value _mode)
874*9a0e4156SSadaf Ebrahimi {
875*9a0e4156SSadaf Ebrahimi CAMLparam2(_arch, _mode);
876*9a0e4156SSadaf Ebrahimi CAMLlocal2(list, head);
877*9a0e4156SSadaf Ebrahimi csh handle;
878*9a0e4156SSadaf Ebrahimi cs_arch arch;
879*9a0e4156SSadaf Ebrahimi cs_mode mode = 0;
880*9a0e4156SSadaf Ebrahimi
881*9a0e4156SSadaf Ebrahimi list = Val_emptylist;
882*9a0e4156SSadaf Ebrahimi
883*9a0e4156SSadaf Ebrahimi switch (Int_val(_arch)) {
884*9a0e4156SSadaf Ebrahimi case 0:
885*9a0e4156SSadaf Ebrahimi arch = CS_ARCH_ARM;
886*9a0e4156SSadaf Ebrahimi break;
887*9a0e4156SSadaf Ebrahimi case 1:
888*9a0e4156SSadaf Ebrahimi arch = CS_ARCH_ARM64;
889*9a0e4156SSadaf Ebrahimi break;
890*9a0e4156SSadaf Ebrahimi case 2:
891*9a0e4156SSadaf Ebrahimi arch = CS_ARCH_MIPS;
892*9a0e4156SSadaf Ebrahimi break;
893*9a0e4156SSadaf Ebrahimi case 3:
894*9a0e4156SSadaf Ebrahimi arch = CS_ARCH_X86;
895*9a0e4156SSadaf Ebrahimi break;
896*9a0e4156SSadaf Ebrahimi case 4:
897*9a0e4156SSadaf Ebrahimi arch = CS_ARCH_PPC;
898*9a0e4156SSadaf Ebrahimi break;
899*9a0e4156SSadaf Ebrahimi case 5:
900*9a0e4156SSadaf Ebrahimi arch = CS_ARCH_SPARC;
901*9a0e4156SSadaf Ebrahimi break;
902*9a0e4156SSadaf Ebrahimi case 6:
903*9a0e4156SSadaf Ebrahimi arch = CS_ARCH_SYSZ;
904*9a0e4156SSadaf Ebrahimi break;
905*9a0e4156SSadaf Ebrahimi case 7:
906*9a0e4156SSadaf Ebrahimi arch = CS_ARCH_XCORE;
907*9a0e4156SSadaf Ebrahimi break;
908*9a0e4156SSadaf Ebrahimi case 8:
909*9a0e4156SSadaf Ebrahimi arch = CS_ARCH_M68K;
910*9a0e4156SSadaf Ebrahimi break;
911*9a0e4156SSadaf Ebrahimi case 9:
912*9a0e4156SSadaf Ebrahimi arch = CS_ARCH_TMS320C64X;
913*9a0e4156SSadaf Ebrahimi break;
914*9a0e4156SSadaf Ebrahimi case 10:
915*9a0e4156SSadaf Ebrahimi arch = CS_ARCH_M680X;
916*9a0e4156SSadaf Ebrahimi break;
917*9a0e4156SSadaf Ebrahimi default:
918*9a0e4156SSadaf Ebrahimi caml_invalid_argument("Invalid arch");
919*9a0e4156SSadaf Ebrahimi return Val_emptylist;
920*9a0e4156SSadaf Ebrahimi }
921*9a0e4156SSadaf Ebrahimi
922*9a0e4156SSadaf Ebrahimi
923*9a0e4156SSadaf Ebrahimi while (_mode != Val_emptylist) {
924*9a0e4156SSadaf Ebrahimi head = Field(_mode, 0); /* accessing the head */
925*9a0e4156SSadaf Ebrahimi switch (Int_val(head)) {
926*9a0e4156SSadaf Ebrahimi case 0:
927*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_LITTLE_ENDIAN;
928*9a0e4156SSadaf Ebrahimi break;
929*9a0e4156SSadaf Ebrahimi case 1:
930*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_ARM;
931*9a0e4156SSadaf Ebrahimi break;
932*9a0e4156SSadaf Ebrahimi case 2:
933*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_16;
934*9a0e4156SSadaf Ebrahimi break;
935*9a0e4156SSadaf Ebrahimi case 3:
936*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_32;
937*9a0e4156SSadaf Ebrahimi break;
938*9a0e4156SSadaf Ebrahimi case 4:
939*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_64;
940*9a0e4156SSadaf Ebrahimi break;
941*9a0e4156SSadaf Ebrahimi case 5:
942*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_THUMB;
943*9a0e4156SSadaf Ebrahimi break;
944*9a0e4156SSadaf Ebrahimi case 6:
945*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_MCLASS;
946*9a0e4156SSadaf Ebrahimi break;
947*9a0e4156SSadaf Ebrahimi case 7:
948*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_V8;
949*9a0e4156SSadaf Ebrahimi break;
950*9a0e4156SSadaf Ebrahimi case 8:
951*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_MICRO;
952*9a0e4156SSadaf Ebrahimi break;
953*9a0e4156SSadaf Ebrahimi case 9:
954*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_MIPS3;
955*9a0e4156SSadaf Ebrahimi break;
956*9a0e4156SSadaf Ebrahimi case 10:
957*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_MIPS32R6;
958*9a0e4156SSadaf Ebrahimi break;
959*9a0e4156SSadaf Ebrahimi case 11:
960*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_MIPS2;
961*9a0e4156SSadaf Ebrahimi break;
962*9a0e4156SSadaf Ebrahimi case 12:
963*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_V9;
964*9a0e4156SSadaf Ebrahimi break;
965*9a0e4156SSadaf Ebrahimi case 13:
966*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_BIG_ENDIAN;
967*9a0e4156SSadaf Ebrahimi break;
968*9a0e4156SSadaf Ebrahimi case 14:
969*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_MIPS32;
970*9a0e4156SSadaf Ebrahimi break;
971*9a0e4156SSadaf Ebrahimi case 15:
972*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_MIPS64;
973*9a0e4156SSadaf Ebrahimi break;
974*9a0e4156SSadaf Ebrahimi case 16:
975*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_QPX;
976*9a0e4156SSadaf Ebrahimi break;
977*9a0e4156SSadaf Ebrahimi case 17:
978*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_M680X_6301;
979*9a0e4156SSadaf Ebrahimi break;
980*9a0e4156SSadaf Ebrahimi case 18:
981*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_M680X_6309;
982*9a0e4156SSadaf Ebrahimi break;
983*9a0e4156SSadaf Ebrahimi case 19:
984*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_M680X_6800;
985*9a0e4156SSadaf Ebrahimi break;
986*9a0e4156SSadaf Ebrahimi case 20:
987*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_M680X_6801;
988*9a0e4156SSadaf Ebrahimi break;
989*9a0e4156SSadaf Ebrahimi case 21:
990*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_M680X_6805;
991*9a0e4156SSadaf Ebrahimi break;
992*9a0e4156SSadaf Ebrahimi case 22:
993*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_M680X_6808;
994*9a0e4156SSadaf Ebrahimi break;
995*9a0e4156SSadaf Ebrahimi case 23:
996*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_M680X_6809;
997*9a0e4156SSadaf Ebrahimi break;
998*9a0e4156SSadaf Ebrahimi case 24:
999*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_M680X_6811;
1000*9a0e4156SSadaf Ebrahimi break;
1001*9a0e4156SSadaf Ebrahimi case 25:
1002*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_M680X_CPU12;
1003*9a0e4156SSadaf Ebrahimi break;
1004*9a0e4156SSadaf Ebrahimi case 26:
1005*9a0e4156SSadaf Ebrahimi mode |= CS_MODE_M680X_HCS08;
1006*9a0e4156SSadaf Ebrahimi break;
1007*9a0e4156SSadaf Ebrahimi default:
1008*9a0e4156SSadaf Ebrahimi caml_invalid_argument("Invalid mode");
1009*9a0e4156SSadaf Ebrahimi return Val_emptylist;
1010*9a0e4156SSadaf Ebrahimi }
1011*9a0e4156SSadaf Ebrahimi _mode = Field(_mode, 1); /* point to the tail for next loop */
1012*9a0e4156SSadaf Ebrahimi }
1013*9a0e4156SSadaf Ebrahimi
1014*9a0e4156SSadaf Ebrahimi if (cs_open(arch, mode, &handle) != 0)
1015*9a0e4156SSadaf Ebrahimi CAMLreturn(Val_int(0));
1016*9a0e4156SSadaf Ebrahimi
1017*9a0e4156SSadaf Ebrahimi CAMLlocal1(result);
1018*9a0e4156SSadaf Ebrahimi result = caml_alloc(1, 0);
1019*9a0e4156SSadaf Ebrahimi Store_field(result, 0, caml_copy_int64(handle));
1020*9a0e4156SSadaf Ebrahimi CAMLreturn(result);
1021*9a0e4156SSadaf Ebrahimi }
1022*9a0e4156SSadaf Ebrahimi
ocaml_option(value _handle,value _opt,value _value)1023*9a0e4156SSadaf Ebrahimi CAMLprim value ocaml_option(value _handle, value _opt, value _value)
1024*9a0e4156SSadaf Ebrahimi {
1025*9a0e4156SSadaf Ebrahimi CAMLparam3(_handle, _opt, _value);
1026*9a0e4156SSadaf Ebrahimi cs_opt_type opt;
1027*9a0e4156SSadaf Ebrahimi int err;
1028*9a0e4156SSadaf Ebrahimi
1029*9a0e4156SSadaf Ebrahimi switch (Int_val(_opt)) {
1030*9a0e4156SSadaf Ebrahimi case 0:
1031*9a0e4156SSadaf Ebrahimi opt = CS_OPT_SYNTAX;
1032*9a0e4156SSadaf Ebrahimi break;
1033*9a0e4156SSadaf Ebrahimi case 1:
1034*9a0e4156SSadaf Ebrahimi opt = CS_OPT_DETAIL;
1035*9a0e4156SSadaf Ebrahimi break;
1036*9a0e4156SSadaf Ebrahimi case 2:
1037*9a0e4156SSadaf Ebrahimi opt = CS_OPT_MODE;
1038*9a0e4156SSadaf Ebrahimi break;
1039*9a0e4156SSadaf Ebrahimi case 3:
1040*9a0e4156SSadaf Ebrahimi opt = CS_OPT_MEM;
1041*9a0e4156SSadaf Ebrahimi break;
1042*9a0e4156SSadaf Ebrahimi case 4:
1043*9a0e4156SSadaf Ebrahimi opt = CS_OPT_SKIPDATA;
1044*9a0e4156SSadaf Ebrahimi break;
1045*9a0e4156SSadaf Ebrahimi case 5:
1046*9a0e4156SSadaf Ebrahimi opt = CS_OPT_SKIPDATA_SETUP;
1047*9a0e4156SSadaf Ebrahimi break;
1048*9a0e4156SSadaf Ebrahimi default:
1049*9a0e4156SSadaf Ebrahimi caml_invalid_argument("Invalid option");
1050*9a0e4156SSadaf Ebrahimi CAMLreturn(Val_int(CS_ERR_OPTION));
1051*9a0e4156SSadaf Ebrahimi }
1052*9a0e4156SSadaf Ebrahimi
1053*9a0e4156SSadaf Ebrahimi err = cs_option(Int64_val(_handle), opt, Int64_val(_value));
1054*9a0e4156SSadaf Ebrahimi
1055*9a0e4156SSadaf Ebrahimi CAMLreturn(Val_int(err));
1056*9a0e4156SSadaf Ebrahimi }
1057*9a0e4156SSadaf Ebrahimi
ocaml_register_name(value _handle,value _reg)1058*9a0e4156SSadaf Ebrahimi CAMLprim value ocaml_register_name(value _handle, value _reg)
1059*9a0e4156SSadaf Ebrahimi {
1060*9a0e4156SSadaf Ebrahimi const char *name = cs_reg_name(Int64_val(_handle), Int_val(_reg));
1061*9a0e4156SSadaf Ebrahimi if (!name) {
1062*9a0e4156SSadaf Ebrahimi caml_invalid_argument("invalid reg_id");
1063*9a0e4156SSadaf Ebrahimi name = "invalid";
1064*9a0e4156SSadaf Ebrahimi }
1065*9a0e4156SSadaf Ebrahimi
1066*9a0e4156SSadaf Ebrahimi return caml_copy_string(name);
1067*9a0e4156SSadaf Ebrahimi }
1068*9a0e4156SSadaf Ebrahimi
ocaml_instruction_name(value _handle,value _insn)1069*9a0e4156SSadaf Ebrahimi CAMLprim value ocaml_instruction_name(value _handle, value _insn)
1070*9a0e4156SSadaf Ebrahimi {
1071*9a0e4156SSadaf Ebrahimi const char *name = cs_insn_name(Int64_val(_handle), Int_val(_insn));
1072*9a0e4156SSadaf Ebrahimi if (!name) {
1073*9a0e4156SSadaf Ebrahimi caml_invalid_argument("invalid insn_id");
1074*9a0e4156SSadaf Ebrahimi name = "invalid";
1075*9a0e4156SSadaf Ebrahimi }
1076*9a0e4156SSadaf Ebrahimi
1077*9a0e4156SSadaf Ebrahimi return caml_copy_string(name);
1078*9a0e4156SSadaf Ebrahimi }
1079*9a0e4156SSadaf Ebrahimi
ocaml_group_name(value _handle,value _insn)1080*9a0e4156SSadaf Ebrahimi CAMLprim value ocaml_group_name(value _handle, value _insn)
1081*9a0e4156SSadaf Ebrahimi {
1082*9a0e4156SSadaf Ebrahimi const char *name = cs_group_name(Int64_val(_handle), Int_val(_insn));
1083*9a0e4156SSadaf Ebrahimi if (!name) {
1084*9a0e4156SSadaf Ebrahimi caml_invalid_argument("invalid insn_id");
1085*9a0e4156SSadaf Ebrahimi name = "invalid";
1086*9a0e4156SSadaf Ebrahimi }
1087*9a0e4156SSadaf Ebrahimi
1088*9a0e4156SSadaf Ebrahimi return caml_copy_string(name);
1089*9a0e4156SSadaf Ebrahimi }
1090*9a0e4156SSadaf Ebrahimi
ocaml_version(void)1091*9a0e4156SSadaf Ebrahimi CAMLprim value ocaml_version(void)
1092*9a0e4156SSadaf Ebrahimi {
1093*9a0e4156SSadaf Ebrahimi int version = cs_version(NULL, NULL);
1094*9a0e4156SSadaf Ebrahimi return Val_int(version);
1095*9a0e4156SSadaf Ebrahimi }
1096*9a0e4156SSadaf Ebrahimi
ocaml_close(value _handle)1097*9a0e4156SSadaf Ebrahimi CAMLprim value ocaml_close(value _handle)
1098*9a0e4156SSadaf Ebrahimi {
1099*9a0e4156SSadaf Ebrahimi CAMLparam1(_handle);
1100*9a0e4156SSadaf Ebrahimi csh h;
1101*9a0e4156SSadaf Ebrahimi
1102*9a0e4156SSadaf Ebrahimi h = Int64_val(_handle);
1103*9a0e4156SSadaf Ebrahimi
1104*9a0e4156SSadaf Ebrahimi CAMLreturn(Val_int(cs_close(&h)));
1105*9a0e4156SSadaf Ebrahimi }
1106