xref: /aosp_15_r20/external/capstone/tests/test_x86.c (revision 9a0e4156d50a75a99ec4f1653a0e9602a5d45c18)
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>
5*9a0e4156SSadaf Ebrahimi #include <stdlib.h>
6*9a0e4156SSadaf Ebrahimi 
7*9a0e4156SSadaf Ebrahimi #include <capstone/platform.h>
8*9a0e4156SSadaf Ebrahimi #include <capstone/capstone.h>
9*9a0e4156SSadaf Ebrahimi 
10*9a0e4156SSadaf Ebrahimi static csh handle;
11*9a0e4156SSadaf Ebrahimi 
12*9a0e4156SSadaf Ebrahimi struct platform {
13*9a0e4156SSadaf Ebrahimi 	cs_arch arch;
14*9a0e4156SSadaf Ebrahimi 	cs_mode mode;
15*9a0e4156SSadaf Ebrahimi 	unsigned char *code;
16*9a0e4156SSadaf Ebrahimi 	size_t size;
17*9a0e4156SSadaf Ebrahimi 	const char *comment;
18*9a0e4156SSadaf Ebrahimi 	cs_opt_type opt_type;
19*9a0e4156SSadaf Ebrahimi 	cs_opt_value opt_value;
20*9a0e4156SSadaf Ebrahimi };
21*9a0e4156SSadaf Ebrahimi 
print_string_hex(const char * comment,unsigned char * str,size_t len)22*9a0e4156SSadaf Ebrahimi static void print_string_hex(const char *comment, unsigned char *str, size_t len)
23*9a0e4156SSadaf Ebrahimi {
24*9a0e4156SSadaf Ebrahimi 	unsigned char *c;
25*9a0e4156SSadaf Ebrahimi 
26*9a0e4156SSadaf Ebrahimi 	printf("%s", comment);
27*9a0e4156SSadaf Ebrahimi 	for (c = str; c < str + len; c++) {
28*9a0e4156SSadaf Ebrahimi 		printf("0x%02x ", *c & 0xff);
29*9a0e4156SSadaf Ebrahimi 	}
30*9a0e4156SSadaf Ebrahimi 
31*9a0e4156SSadaf Ebrahimi 	printf("\n");
32*9a0e4156SSadaf Ebrahimi }
33*9a0e4156SSadaf Ebrahimi 
get_eflag_name(uint64_t flag)34*9a0e4156SSadaf Ebrahimi static const char *get_eflag_name(uint64_t flag)
35*9a0e4156SSadaf Ebrahimi {
36*9a0e4156SSadaf Ebrahimi 	switch(flag) {
37*9a0e4156SSadaf Ebrahimi 		default:
38*9a0e4156SSadaf Ebrahimi 			return NULL;
39*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_UNDEFINED_OF:
40*9a0e4156SSadaf Ebrahimi 			return "UNDEF_OF";
41*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_UNDEFINED_SF:
42*9a0e4156SSadaf Ebrahimi 			return "UNDEF_SF";
43*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_UNDEFINED_ZF:
44*9a0e4156SSadaf Ebrahimi 			return "UNDEF_ZF";
45*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_MODIFY_AF:
46*9a0e4156SSadaf Ebrahimi 			return "MOD_AF";
47*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_UNDEFINED_PF:
48*9a0e4156SSadaf Ebrahimi 			return "UNDEF_PF";
49*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_MODIFY_CF:
50*9a0e4156SSadaf Ebrahimi 			return "MOD_CF";
51*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_MODIFY_SF:
52*9a0e4156SSadaf Ebrahimi 			return "MOD_SF";
53*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_MODIFY_ZF:
54*9a0e4156SSadaf Ebrahimi 			return "MOD_ZF";
55*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_UNDEFINED_AF:
56*9a0e4156SSadaf Ebrahimi 			return "UNDEF_AF";
57*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_MODIFY_PF:
58*9a0e4156SSadaf Ebrahimi 			return "MOD_PF";
59*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_UNDEFINED_CF:
60*9a0e4156SSadaf Ebrahimi 			return "UNDEF_CF";
61*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_MODIFY_OF:
62*9a0e4156SSadaf Ebrahimi 			return "MOD_OF";
63*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_RESET_OF:
64*9a0e4156SSadaf Ebrahimi 			return "RESET_OF";
65*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_RESET_CF:
66*9a0e4156SSadaf Ebrahimi 			return "RESET_CF";
67*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_RESET_DF:
68*9a0e4156SSadaf Ebrahimi 			return "RESET_DF";
69*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_RESET_IF:
70*9a0e4156SSadaf Ebrahimi 			return "RESET_IF";
71*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_TEST_OF:
72*9a0e4156SSadaf Ebrahimi 			return "TEST_OF";
73*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_TEST_SF:
74*9a0e4156SSadaf Ebrahimi 			return "TEST_SF";
75*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_TEST_ZF:
76*9a0e4156SSadaf Ebrahimi 			return "TEST_ZF";
77*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_TEST_PF:
78*9a0e4156SSadaf Ebrahimi 			return "TEST_PF";
79*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_TEST_CF:
80*9a0e4156SSadaf Ebrahimi 			return "TEST_CF";
81*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_RESET_SF:
82*9a0e4156SSadaf Ebrahimi 			return "RESET_SF";
83*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_RESET_AF:
84*9a0e4156SSadaf Ebrahimi 			return "RESET_AF";
85*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_RESET_TF:
86*9a0e4156SSadaf Ebrahimi 			return "RESET_TF";
87*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_RESET_NT:
88*9a0e4156SSadaf Ebrahimi 			return "RESET_NT";
89*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_PRIOR_OF:
90*9a0e4156SSadaf Ebrahimi 			return "PRIOR_OF";
91*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_PRIOR_SF:
92*9a0e4156SSadaf Ebrahimi 			return "PRIOR_SF";
93*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_PRIOR_ZF:
94*9a0e4156SSadaf Ebrahimi 			return "PRIOR_ZF";
95*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_PRIOR_AF:
96*9a0e4156SSadaf Ebrahimi 			return "PRIOR_AF";
97*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_PRIOR_PF:
98*9a0e4156SSadaf Ebrahimi 			return "PRIOR_PF";
99*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_PRIOR_CF:
100*9a0e4156SSadaf Ebrahimi 			return "PRIOR_CF";
101*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_PRIOR_TF:
102*9a0e4156SSadaf Ebrahimi 			return "PRIOR_TF";
103*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_PRIOR_IF:
104*9a0e4156SSadaf Ebrahimi 			return "PRIOR_IF";
105*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_PRIOR_DF:
106*9a0e4156SSadaf Ebrahimi 			return "PRIOR_DF";
107*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_TEST_NT:
108*9a0e4156SSadaf Ebrahimi 			return "TEST_NT";
109*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_TEST_DF:
110*9a0e4156SSadaf Ebrahimi 			return "TEST_DF";
111*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_RESET_PF:
112*9a0e4156SSadaf Ebrahimi 			return "RESET_PF";
113*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_PRIOR_NT:
114*9a0e4156SSadaf Ebrahimi 			return "PRIOR_NT";
115*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_MODIFY_TF:
116*9a0e4156SSadaf Ebrahimi 			return "MOD_TF";
117*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_MODIFY_IF:
118*9a0e4156SSadaf Ebrahimi 			return "MOD_IF";
119*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_MODIFY_DF:
120*9a0e4156SSadaf Ebrahimi 			return "MOD_DF";
121*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_MODIFY_NT:
122*9a0e4156SSadaf Ebrahimi 			return "MOD_NT";
123*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_MODIFY_RF:
124*9a0e4156SSadaf Ebrahimi 			return "MOD_RF";
125*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_SET_CF:
126*9a0e4156SSadaf Ebrahimi 			return "SET_CF";
127*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_SET_DF:
128*9a0e4156SSadaf Ebrahimi 			return "SET_DF";
129*9a0e4156SSadaf Ebrahimi 		case X86_EFLAGS_SET_IF:
130*9a0e4156SSadaf Ebrahimi 			return "SET_IF";
131*9a0e4156SSadaf Ebrahimi 	}
132*9a0e4156SSadaf Ebrahimi }
133*9a0e4156SSadaf Ebrahimi 
get_fpu_flag_name(uint64_t flag)134*9a0e4156SSadaf Ebrahimi static const char *get_fpu_flag_name(uint64_t flag)
135*9a0e4156SSadaf Ebrahimi {
136*9a0e4156SSadaf Ebrahimi 	switch (flag) {
137*9a0e4156SSadaf Ebrahimi 		default:
138*9a0e4156SSadaf Ebrahimi 			return NULL;
139*9a0e4156SSadaf Ebrahimi 		case X86_FPU_FLAGS_MODIFY_C0:
140*9a0e4156SSadaf Ebrahimi 			return "MOD_C0";
141*9a0e4156SSadaf Ebrahimi 		case X86_FPU_FLAGS_MODIFY_C1:
142*9a0e4156SSadaf Ebrahimi 			return "MOD_C1";
143*9a0e4156SSadaf Ebrahimi 		case X86_FPU_FLAGS_MODIFY_C2:
144*9a0e4156SSadaf Ebrahimi 			return "MOD_C2";
145*9a0e4156SSadaf Ebrahimi 		case X86_FPU_FLAGS_MODIFY_C3:
146*9a0e4156SSadaf Ebrahimi 			return "MOD_C3";
147*9a0e4156SSadaf Ebrahimi 		case X86_FPU_FLAGS_RESET_C0:
148*9a0e4156SSadaf Ebrahimi 			return "RESET_C0";
149*9a0e4156SSadaf Ebrahimi 		case X86_FPU_FLAGS_RESET_C1:
150*9a0e4156SSadaf Ebrahimi 			return "RESET_C1";
151*9a0e4156SSadaf Ebrahimi 		case X86_FPU_FLAGS_RESET_C2:
152*9a0e4156SSadaf Ebrahimi 			return "RESET_C2";
153*9a0e4156SSadaf Ebrahimi 		case X86_FPU_FLAGS_RESET_C3:
154*9a0e4156SSadaf Ebrahimi 			return "RESET_C3";
155*9a0e4156SSadaf Ebrahimi 		case X86_FPU_FLAGS_SET_C0:
156*9a0e4156SSadaf Ebrahimi 			return "SET_C0";
157*9a0e4156SSadaf Ebrahimi 		case X86_FPU_FLAGS_SET_C1:
158*9a0e4156SSadaf Ebrahimi 			return "SET_C1";
159*9a0e4156SSadaf Ebrahimi 		case X86_FPU_FLAGS_SET_C2:
160*9a0e4156SSadaf Ebrahimi 			return "SET_C2";
161*9a0e4156SSadaf Ebrahimi 		case X86_FPU_FLAGS_SET_C3:
162*9a0e4156SSadaf Ebrahimi 			return "SET_C3";
163*9a0e4156SSadaf Ebrahimi 		case X86_FPU_FLAGS_UNDEFINED_C0:
164*9a0e4156SSadaf Ebrahimi 			return "UNDEF_C0";
165*9a0e4156SSadaf Ebrahimi 		case X86_FPU_FLAGS_UNDEFINED_C1:
166*9a0e4156SSadaf Ebrahimi 			return "UNDEF_C1";
167*9a0e4156SSadaf Ebrahimi 		case X86_FPU_FLAGS_UNDEFINED_C2:
168*9a0e4156SSadaf Ebrahimi 			return "UNDEF_C2";
169*9a0e4156SSadaf Ebrahimi 		case X86_FPU_FLAGS_UNDEFINED_C3:
170*9a0e4156SSadaf Ebrahimi 			return "UNDEF_C3";
171*9a0e4156SSadaf Ebrahimi 		case X86_FPU_FLAGS_TEST_C0:
172*9a0e4156SSadaf Ebrahimi 			return "TEST_C0";
173*9a0e4156SSadaf Ebrahimi 		case X86_FPU_FLAGS_TEST_C1:
174*9a0e4156SSadaf Ebrahimi 			return "TEST_C1";
175*9a0e4156SSadaf Ebrahimi 		case X86_FPU_FLAGS_TEST_C2:
176*9a0e4156SSadaf Ebrahimi 			return "TEST_C2";
177*9a0e4156SSadaf Ebrahimi 		case X86_FPU_FLAGS_TEST_C3:
178*9a0e4156SSadaf Ebrahimi 			return "TEST_C3";
179*9a0e4156SSadaf Ebrahimi 	}
180*9a0e4156SSadaf Ebrahimi }
181*9a0e4156SSadaf Ebrahimi 
print_insn_detail(csh ud,cs_mode mode,cs_insn * ins)182*9a0e4156SSadaf Ebrahimi static void print_insn_detail(csh ud, cs_mode mode, cs_insn *ins)
183*9a0e4156SSadaf Ebrahimi {
184*9a0e4156SSadaf Ebrahimi 	int count, i;
185*9a0e4156SSadaf Ebrahimi 	cs_x86 *x86;
186*9a0e4156SSadaf Ebrahimi 	cs_regs regs_read, regs_write;
187*9a0e4156SSadaf Ebrahimi 	uint8_t regs_read_count, regs_write_count;
188*9a0e4156SSadaf Ebrahimi 
189*9a0e4156SSadaf Ebrahimi 	// detail can be NULL on "data" instruction if SKIPDATA option is turned ON
190*9a0e4156SSadaf Ebrahimi 	if (ins->detail == NULL)
191*9a0e4156SSadaf Ebrahimi 		return;
192*9a0e4156SSadaf Ebrahimi 
193*9a0e4156SSadaf Ebrahimi 	x86 = &(ins->detail->x86);
194*9a0e4156SSadaf Ebrahimi 
195*9a0e4156SSadaf Ebrahimi 	print_string_hex("\tPrefix:", x86->prefix, 4);
196*9a0e4156SSadaf Ebrahimi 
197*9a0e4156SSadaf Ebrahimi 	print_string_hex("\tOpcode:", x86->opcode, 4);
198*9a0e4156SSadaf Ebrahimi 
199*9a0e4156SSadaf Ebrahimi 	printf("\trex: 0x%x\n", x86->rex);
200*9a0e4156SSadaf Ebrahimi 
201*9a0e4156SSadaf Ebrahimi 	printf("\taddr_size: %u\n", x86->addr_size);
202*9a0e4156SSadaf Ebrahimi 	printf("\tmodrm: 0x%x\n", x86->modrm);
203*9a0e4156SSadaf Ebrahimi 	if (x86->encoding.modrm_offset != 0) {
204*9a0e4156SSadaf Ebrahimi 		printf("\tmodrm_offset: 0x%x\n", x86->encoding.modrm_offset);
205*9a0e4156SSadaf Ebrahimi 	}
206*9a0e4156SSadaf Ebrahimi 
207*9a0e4156SSadaf Ebrahimi 	printf("\tdisp: 0x%" PRIx64 "\n", x86->disp);
208*9a0e4156SSadaf Ebrahimi 	if (x86->encoding.disp_offset != 0) {
209*9a0e4156SSadaf Ebrahimi 		printf("\tdisp_offset: 0x%x\n", x86->encoding.disp_offset);
210*9a0e4156SSadaf Ebrahimi 	}
211*9a0e4156SSadaf Ebrahimi 
212*9a0e4156SSadaf Ebrahimi 	if (x86->encoding.disp_size != 0) {
213*9a0e4156SSadaf Ebrahimi 		printf("\tdisp_size: 0x%x\n", x86->encoding.disp_size);
214*9a0e4156SSadaf Ebrahimi 	}
215*9a0e4156SSadaf Ebrahimi 
216*9a0e4156SSadaf Ebrahimi 	// SIB is not available in 16-bit mode
217*9a0e4156SSadaf Ebrahimi 	if ((mode & CS_MODE_16) == 0) {
218*9a0e4156SSadaf Ebrahimi 		printf("\tsib: 0x%x\n", x86->sib);
219*9a0e4156SSadaf Ebrahimi 		if (x86->sib_base != X86_REG_INVALID)
220*9a0e4156SSadaf Ebrahimi 			printf("\t\tsib_base: %s\n", cs_reg_name(handle, x86->sib_base));
221*9a0e4156SSadaf Ebrahimi 		if (x86->sib_index != X86_REG_INVALID)
222*9a0e4156SSadaf Ebrahimi 			printf("\t\tsib_index: %s\n", cs_reg_name(handle, x86->sib_index));
223*9a0e4156SSadaf Ebrahimi 		if (x86->sib_scale != 0)
224*9a0e4156SSadaf Ebrahimi 			printf("\t\tsib_scale: %d\n", x86->sib_scale);
225*9a0e4156SSadaf Ebrahimi 	}
226*9a0e4156SSadaf Ebrahimi 
227*9a0e4156SSadaf Ebrahimi 	// XOP code condition
228*9a0e4156SSadaf Ebrahimi 	if (x86->xop_cc != X86_XOP_CC_INVALID) {
229*9a0e4156SSadaf Ebrahimi 		printf("\txop_cc: %u\n", x86->xop_cc);
230*9a0e4156SSadaf Ebrahimi 	}
231*9a0e4156SSadaf Ebrahimi 
232*9a0e4156SSadaf Ebrahimi 	// SSE code condition
233*9a0e4156SSadaf Ebrahimi 	if (x86->sse_cc != X86_SSE_CC_INVALID) {
234*9a0e4156SSadaf Ebrahimi 		printf("\tsse_cc: %u\n", x86->sse_cc);
235*9a0e4156SSadaf Ebrahimi 	}
236*9a0e4156SSadaf Ebrahimi 
237*9a0e4156SSadaf Ebrahimi 	// AVX code condition
238*9a0e4156SSadaf Ebrahimi 	if (x86->avx_cc != X86_AVX_CC_INVALID) {
239*9a0e4156SSadaf Ebrahimi 		printf("\tavx_cc: %u\n", x86->avx_cc);
240*9a0e4156SSadaf Ebrahimi 	}
241*9a0e4156SSadaf Ebrahimi 
242*9a0e4156SSadaf Ebrahimi 	// AVX Suppress All Exception
243*9a0e4156SSadaf Ebrahimi 	if (x86->avx_sae) {
244*9a0e4156SSadaf Ebrahimi 		printf("\tavx_sae: %u\n", x86->avx_sae);
245*9a0e4156SSadaf Ebrahimi 	}
246*9a0e4156SSadaf Ebrahimi 
247*9a0e4156SSadaf Ebrahimi 	// AVX Rounding Mode
248*9a0e4156SSadaf Ebrahimi 	if (x86->avx_rm != X86_AVX_RM_INVALID) {
249*9a0e4156SSadaf Ebrahimi 		printf("\tavx_rm: %u\n", x86->avx_rm);
250*9a0e4156SSadaf Ebrahimi 	}
251*9a0e4156SSadaf Ebrahimi 
252*9a0e4156SSadaf Ebrahimi 	// Print out all immediate operands
253*9a0e4156SSadaf Ebrahimi 	count = cs_op_count(ud, ins, X86_OP_IMM);
254*9a0e4156SSadaf Ebrahimi 	if (count) {
255*9a0e4156SSadaf Ebrahimi 		printf("\timm_count: %u\n", count);
256*9a0e4156SSadaf Ebrahimi 		for (i = 1; i < count + 1; i++) {
257*9a0e4156SSadaf Ebrahimi 			int index = cs_op_index(ud, ins, X86_OP_IMM, i);
258*9a0e4156SSadaf Ebrahimi 			printf("\t\timms[%u]: 0x%" PRIx64 "\n", i, x86->operands[index].imm);
259*9a0e4156SSadaf Ebrahimi 			if (x86->encoding.imm_offset != 0) {
260*9a0e4156SSadaf Ebrahimi 				printf("\timm_offset: 0x%x\n", x86->encoding.imm_offset);
261*9a0e4156SSadaf Ebrahimi 			}
262*9a0e4156SSadaf Ebrahimi 
263*9a0e4156SSadaf Ebrahimi 			if (x86->encoding.imm_size != 0) {
264*9a0e4156SSadaf Ebrahimi 				printf("\timm_size: 0x%x\n", x86->encoding.imm_size);
265*9a0e4156SSadaf Ebrahimi 			}
266*9a0e4156SSadaf Ebrahimi 		}
267*9a0e4156SSadaf Ebrahimi 	}
268*9a0e4156SSadaf Ebrahimi 
269*9a0e4156SSadaf Ebrahimi 	if (x86->op_count)
270*9a0e4156SSadaf Ebrahimi 		printf("\top_count: %u\n", x86->op_count);
271*9a0e4156SSadaf Ebrahimi 
272*9a0e4156SSadaf Ebrahimi 	// Print out all operands
273*9a0e4156SSadaf Ebrahimi 	for (i = 0; i < x86->op_count; i++) {
274*9a0e4156SSadaf Ebrahimi 		cs_x86_op *op = &(x86->operands[i]);
275*9a0e4156SSadaf Ebrahimi 
276*9a0e4156SSadaf Ebrahimi 		switch((int)op->type) {
277*9a0e4156SSadaf Ebrahimi 			case X86_OP_REG:
278*9a0e4156SSadaf Ebrahimi 				printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg));
279*9a0e4156SSadaf Ebrahimi 				break;
280*9a0e4156SSadaf Ebrahimi 			case X86_OP_IMM:
281*9a0e4156SSadaf Ebrahimi 				printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 "\n", i, op->imm);
282*9a0e4156SSadaf Ebrahimi 				break;
283*9a0e4156SSadaf Ebrahimi 			case X86_OP_MEM:
284*9a0e4156SSadaf Ebrahimi 				printf("\t\toperands[%u].type: MEM\n", i);
285*9a0e4156SSadaf Ebrahimi 				if (op->mem.segment != X86_REG_INVALID)
286*9a0e4156SSadaf Ebrahimi 					printf("\t\t\toperands[%u].mem.segment: REG = %s\n", i, cs_reg_name(handle, op->mem.segment));
287*9a0e4156SSadaf Ebrahimi 				if (op->mem.base != X86_REG_INVALID)
288*9a0e4156SSadaf Ebrahimi 					printf("\t\t\toperands[%u].mem.base: REG = %s\n", i, cs_reg_name(handle, op->mem.base));
289*9a0e4156SSadaf Ebrahimi 				if (op->mem.index != X86_REG_INVALID)
290*9a0e4156SSadaf Ebrahimi 					printf("\t\t\toperands[%u].mem.index: REG = %s\n", i, cs_reg_name(handle, op->mem.index));
291*9a0e4156SSadaf Ebrahimi 				if (op->mem.scale != 1)
292*9a0e4156SSadaf Ebrahimi 					printf("\t\t\toperands[%u].mem.scale: %u\n", i, op->mem.scale);
293*9a0e4156SSadaf Ebrahimi 				if (op->mem.disp != 0)
294*9a0e4156SSadaf Ebrahimi 					printf("\t\t\toperands[%u].mem.disp: 0x%" PRIx64 "\n", i, op->mem.disp);
295*9a0e4156SSadaf Ebrahimi 				break;
296*9a0e4156SSadaf Ebrahimi 			default:
297*9a0e4156SSadaf Ebrahimi 				break;
298*9a0e4156SSadaf Ebrahimi 		}
299*9a0e4156SSadaf Ebrahimi 
300*9a0e4156SSadaf Ebrahimi 		// AVX broadcast type
301*9a0e4156SSadaf Ebrahimi 		if (op->avx_bcast != X86_AVX_BCAST_INVALID)
302*9a0e4156SSadaf Ebrahimi 			printf("\t\toperands[%u].avx_bcast: %u\n", i, op->avx_bcast);
303*9a0e4156SSadaf Ebrahimi 
304*9a0e4156SSadaf Ebrahimi 		// AVX zero opmask {z}
305*9a0e4156SSadaf Ebrahimi 		if (op->avx_zero_opmask != false)
306*9a0e4156SSadaf Ebrahimi 			printf("\t\toperands[%u].avx_zero_opmask: TRUE\n", i);
307*9a0e4156SSadaf Ebrahimi 
308*9a0e4156SSadaf Ebrahimi 		printf("\t\toperands[%u].size: %u\n", i, op->size);
309*9a0e4156SSadaf Ebrahimi 
310*9a0e4156SSadaf Ebrahimi 		switch(op->access) {
311*9a0e4156SSadaf Ebrahimi 			default:
312*9a0e4156SSadaf Ebrahimi 				break;
313*9a0e4156SSadaf Ebrahimi 			case CS_AC_READ:
314*9a0e4156SSadaf Ebrahimi 				printf("\t\toperands[%u].access: READ\n", i);
315*9a0e4156SSadaf Ebrahimi 				break;
316*9a0e4156SSadaf Ebrahimi 			case CS_AC_WRITE:
317*9a0e4156SSadaf Ebrahimi 				printf("\t\toperands[%u].access: WRITE\n", i);
318*9a0e4156SSadaf Ebrahimi 				break;
319*9a0e4156SSadaf Ebrahimi 			case CS_AC_READ | CS_AC_WRITE:
320*9a0e4156SSadaf Ebrahimi 				printf("\t\toperands[%u].access: READ | WRITE\n", i);
321*9a0e4156SSadaf Ebrahimi 				break;
322*9a0e4156SSadaf Ebrahimi 		}
323*9a0e4156SSadaf Ebrahimi 	}
324*9a0e4156SSadaf Ebrahimi 
325*9a0e4156SSadaf Ebrahimi 	// Print out all registers accessed by this instruction (either implicit or explicit)
326*9a0e4156SSadaf Ebrahimi 	if (!cs_regs_access(ud, ins,
327*9a0e4156SSadaf Ebrahimi 				regs_read, &regs_read_count,
328*9a0e4156SSadaf Ebrahimi 				regs_write, &regs_write_count)) {
329*9a0e4156SSadaf Ebrahimi 		if (regs_read_count) {
330*9a0e4156SSadaf Ebrahimi 			printf("\tRegisters read:");
331*9a0e4156SSadaf Ebrahimi 			for(i = 0; i < regs_read_count; i++) {
332*9a0e4156SSadaf Ebrahimi 				printf(" %s", cs_reg_name(handle, regs_read[i]));
333*9a0e4156SSadaf Ebrahimi 			}
334*9a0e4156SSadaf Ebrahimi 			printf("\n");
335*9a0e4156SSadaf Ebrahimi 		}
336*9a0e4156SSadaf Ebrahimi 
337*9a0e4156SSadaf Ebrahimi 		if (regs_write_count) {
338*9a0e4156SSadaf Ebrahimi 			printf("\tRegisters modified:");
339*9a0e4156SSadaf Ebrahimi 			for(i = 0; i < regs_write_count; i++) {
340*9a0e4156SSadaf Ebrahimi 				printf(" %s", cs_reg_name(handle, regs_write[i]));
341*9a0e4156SSadaf Ebrahimi 			}
342*9a0e4156SSadaf Ebrahimi 			printf("\n");
343*9a0e4156SSadaf Ebrahimi 		}
344*9a0e4156SSadaf Ebrahimi 	}
345*9a0e4156SSadaf Ebrahimi 
346*9a0e4156SSadaf Ebrahimi 	if (x86->eflags || x86->fpu_flags) {
347*9a0e4156SSadaf Ebrahimi 		for(i = 0; i < ins->detail->groups_count; i++) {
348*9a0e4156SSadaf Ebrahimi 			if (ins->detail->groups[i] == X86_GRP_FPU) {
349*9a0e4156SSadaf Ebrahimi 				printf("\tFPU_FLAGS:");
350*9a0e4156SSadaf Ebrahimi 				for(i = 0; i <= 63; i++)
351*9a0e4156SSadaf Ebrahimi 					if (x86->fpu_flags & ((uint64_t)1 << i)) {
352*9a0e4156SSadaf Ebrahimi 						printf(" %s", get_fpu_flag_name((uint64_t)1 << i));
353*9a0e4156SSadaf Ebrahimi 					}
354*9a0e4156SSadaf Ebrahimi 				printf("\n");
355*9a0e4156SSadaf Ebrahimi 				break;
356*9a0e4156SSadaf Ebrahimi 			}
357*9a0e4156SSadaf Ebrahimi 		}
358*9a0e4156SSadaf Ebrahimi 
359*9a0e4156SSadaf Ebrahimi 		if (i == ins->detail->groups_count) {
360*9a0e4156SSadaf Ebrahimi 			printf("\tEFLAGS:");
361*9a0e4156SSadaf Ebrahimi 			for(i = 0; i <= 63; i++)
362*9a0e4156SSadaf Ebrahimi 				if (x86->eflags & ((uint64_t)1 << i)) {
363*9a0e4156SSadaf Ebrahimi 					printf(" %s", get_eflag_name((uint64_t)1 << i));
364*9a0e4156SSadaf Ebrahimi 				}
365*9a0e4156SSadaf Ebrahimi 			printf("\n");
366*9a0e4156SSadaf Ebrahimi 		}
367*9a0e4156SSadaf Ebrahimi 	}
368*9a0e4156SSadaf Ebrahimi 
369*9a0e4156SSadaf Ebrahimi 	printf("\n");
370*9a0e4156SSadaf Ebrahimi }
371*9a0e4156SSadaf Ebrahimi 
test()372*9a0e4156SSadaf Ebrahimi static void test()
373*9a0e4156SSadaf Ebrahimi {
374*9a0e4156SSadaf Ebrahimi //#define X86_CODE32 "\x01\xd8\x81\xc6\x34\x12\x00\x00\x05\x78\x56\x00\x00"
375*9a0e4156SSadaf Ebrahimi //#define X86_CODE32 "\x05\x78\x56\x00\x00"
376*9a0e4156SSadaf Ebrahimi //#define X86_CODE32 "\x01\xd8"
377*9a0e4156SSadaf Ebrahimi //#define X86_CODE32 "\x05\x23\x01\x00\x00"
378*9a0e4156SSadaf Ebrahimi //#define X86_CODE32 "\x8d\x87\x89\x67\x00\x00"
379*9a0e4156SSadaf Ebrahimi //#define X86_CODE32 "\xa1\x13\x48\x6d\x3a\x8b\x81\x23\x01\x00\x00\x8b\x84\x39\x23\x01\x00\x00"
380*9a0e4156SSadaf Ebrahimi //#define X86_CODE32 "\xb4\xc6"	// mov	ah, 0x6c
381*9a0e4156SSadaf Ebrahimi //#define X86_CODE32 "\x77\x04"	// ja +6
382*9a0e4156SSadaf Ebrahimi #define X86_CODE64 "\x55\x48\x8b\x05\xb8\x13\x00\x00\xe9\xea\xbe\xad\xde\xff\x25\x23\x01\x00\x00\xe8\xdf\xbe\xad\xde\x74\xff"
383*9a0e4156SSadaf Ebrahimi //#define X86_CODE64 "\xe9\x79\xff\xff\xff"	// jmp 0xf7e
384*9a0e4156SSadaf Ebrahimi 
385*9a0e4156SSadaf Ebrahimi #define X86_CODE16 "\x8d\x4c\x32\x08\x01\xd8\x81\xc6\x34\x12\x00\x00\x05\x23\x01\x00\x00\x36\x8b\x84\x91\x23\x01\x00\x00\x41\x8d\x84\x39\x89\x67\x00\x00\x8d\x87\x89\x67\x00\x00\xb4\xc6\x66\xe9\xb8\x00\x00\x00\x67\xff\xa0\x23\x01\x00\x00\x66\xe8\xcb\x00\x00\x00\x74\xfc"
386*9a0e4156SSadaf Ebrahimi #define X86_CODE32 "\x8d\x4c\x32\x08\x01\xd8\x81\xc6\x34\x12\x00\x00\x05\x23\x01\x00\x00\x36\x8b\x84\x91\x23\x01\x00\x00\x41\x8d\x84\x39\x89\x67\x00\x00\x8d\x87\x89\x67\x00\x00\xb4\xc6\xe9\xea\xbe\xad\xde\xff\xa0\x23\x01\x00\x00\xe8\xdf\xbe\xad\xde\x74\xff"
387*9a0e4156SSadaf Ebrahimi //#define X86_CODE32 "\x05\x23\x01\x00\x00\x0f\x01\xda"
388*9a0e4156SSadaf Ebrahimi //#define X86_CODE32 "\x0f\xa7\xc0"	// xstorerng
389*9a0e4156SSadaf Ebrahimi //#define X86_CODE32 "\x64\xa1\x18\x00\x00\x00"	// mov eax, dword ptr fs:[18]
390*9a0e4156SSadaf Ebrahimi //#define X86_CODE32 "\x64\xa3\x00\x00\x00\x00"	// mov [fs:0x0], eax
391*9a0e4156SSadaf Ebrahimi //#define X86_CODE32 "\xd1\xe1"	// shl ecx, 1
392*9a0e4156SSadaf Ebrahimi //#define X86_CODE32 "\xd1\xc8"	// ror eax, 1
393*9a0e4156SSadaf Ebrahimi //#define X86_CODE32 "\x83\xC0\x80"	// add	eax, -x80
394*9a0e4156SSadaf Ebrahimi //#define X86_CODE32 "\xe8\x26\xfe\xff\xff"		// call	0xe2b
395*9a0e4156SSadaf Ebrahimi //#define X86_CODE32 "\xcd\x80"		// int 0x80
396*9a0e4156SSadaf Ebrahimi //#define X86_CODE32 "\x24\xb8"		// and    $0xb8,%al
397*9a0e4156SSadaf Ebrahimi //#define X86_CODE32 "\xf0\x01\xd8"   // lock add eax,ebx
398*9a0e4156SSadaf Ebrahimi //#define X86_CODE32 "\xf3\xaa"		// rep stosb
399*9a0e4156SSadaf Ebrahimi //#define X86_CODE32 "\x81\xc6\x23\x01\x00\x00"
400*9a0e4156SSadaf Ebrahimi 
401*9a0e4156SSadaf Ebrahimi 	struct platform platforms[] = {
402*9a0e4156SSadaf Ebrahimi 		{
403*9a0e4156SSadaf Ebrahimi 			CS_ARCH_X86,
404*9a0e4156SSadaf Ebrahimi 			CS_MODE_16,
405*9a0e4156SSadaf Ebrahimi 			(unsigned char *)X86_CODE16,
406*9a0e4156SSadaf Ebrahimi 			sizeof(X86_CODE16) - 1,
407*9a0e4156SSadaf Ebrahimi 			"X86 16bit (Intel syntax)"
408*9a0e4156SSadaf Ebrahimi 		},
409*9a0e4156SSadaf Ebrahimi 		{
410*9a0e4156SSadaf Ebrahimi 			CS_ARCH_X86,
411*9a0e4156SSadaf Ebrahimi 			CS_MODE_32,
412*9a0e4156SSadaf Ebrahimi 			(unsigned char *)X86_CODE32,
413*9a0e4156SSadaf Ebrahimi 			sizeof(X86_CODE32) - 1,
414*9a0e4156SSadaf Ebrahimi 			"X86 32 (AT&T syntax)",
415*9a0e4156SSadaf Ebrahimi 			CS_OPT_SYNTAX,
416*9a0e4156SSadaf Ebrahimi 			CS_OPT_SYNTAX_ATT,
417*9a0e4156SSadaf Ebrahimi 		},
418*9a0e4156SSadaf Ebrahimi 		{
419*9a0e4156SSadaf Ebrahimi 			CS_ARCH_X86,
420*9a0e4156SSadaf Ebrahimi 			CS_MODE_32,
421*9a0e4156SSadaf Ebrahimi 			(unsigned char *)X86_CODE32,
422*9a0e4156SSadaf Ebrahimi 			sizeof(X86_CODE32) - 1,
423*9a0e4156SSadaf Ebrahimi 			"X86 32 (Intel syntax)"
424*9a0e4156SSadaf Ebrahimi 		},
425*9a0e4156SSadaf Ebrahimi 		{
426*9a0e4156SSadaf Ebrahimi 			CS_ARCH_X86,
427*9a0e4156SSadaf Ebrahimi 			CS_MODE_64,
428*9a0e4156SSadaf Ebrahimi 			(unsigned char *)X86_CODE64,
429*9a0e4156SSadaf Ebrahimi 			sizeof(X86_CODE64) - 1,
430*9a0e4156SSadaf Ebrahimi 			"X86 64 (Intel syntax)"
431*9a0e4156SSadaf Ebrahimi 		},
432*9a0e4156SSadaf Ebrahimi 	};
433*9a0e4156SSadaf Ebrahimi 
434*9a0e4156SSadaf Ebrahimi 	uint64_t address = 0x1000;
435*9a0e4156SSadaf Ebrahimi 	cs_insn *insn;
436*9a0e4156SSadaf Ebrahimi 	int i;
437*9a0e4156SSadaf Ebrahimi 	size_t count;
438*9a0e4156SSadaf Ebrahimi 
439*9a0e4156SSadaf Ebrahimi 	for (i = 0; i < sizeof(platforms)/sizeof(platforms[0]); i++) {
440*9a0e4156SSadaf Ebrahimi 		cs_err err = cs_open(platforms[i].arch, platforms[i].mode, &handle);
441*9a0e4156SSadaf Ebrahimi 		if (err) {
442*9a0e4156SSadaf Ebrahimi 			printf("Failed on cs_open() with error returned: %u\n", err);
443*9a0e4156SSadaf Ebrahimi 			abort();
444*9a0e4156SSadaf Ebrahimi 		}
445*9a0e4156SSadaf Ebrahimi 
446*9a0e4156SSadaf Ebrahimi 		if (platforms[i].opt_type)
447*9a0e4156SSadaf Ebrahimi 			cs_option(handle, platforms[i].opt_type, platforms[i].opt_value);
448*9a0e4156SSadaf Ebrahimi 
449*9a0e4156SSadaf Ebrahimi 		cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
450*9a0e4156SSadaf Ebrahimi 
451*9a0e4156SSadaf Ebrahimi 		count = cs_disasm(handle, platforms[i].code, platforms[i].size, address, 0, &insn);
452*9a0e4156SSadaf Ebrahimi 		if (count) {
453*9a0e4156SSadaf Ebrahimi 			size_t j;
454*9a0e4156SSadaf Ebrahimi 
455*9a0e4156SSadaf Ebrahimi 			printf("****************\n");
456*9a0e4156SSadaf Ebrahimi 			printf("Platform: %s\n", platforms[i].comment);
457*9a0e4156SSadaf Ebrahimi 			print_string_hex("Code:", platforms[i].code, platforms[i].size);
458*9a0e4156SSadaf Ebrahimi 			printf("Disasm:\n");
459*9a0e4156SSadaf Ebrahimi 
460*9a0e4156SSadaf Ebrahimi 			for (j = 0; j < count; j++) {
461*9a0e4156SSadaf Ebrahimi 				printf("0x%" PRIx64 ":\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str);
462*9a0e4156SSadaf Ebrahimi 				print_insn_detail(handle, platforms[i].mode, &insn[j]);
463*9a0e4156SSadaf Ebrahimi 			}
464*9a0e4156SSadaf Ebrahimi 			printf("0x%" PRIx64 ":\n", insn[j-1].address + insn[j-1].size);
465*9a0e4156SSadaf Ebrahimi 
466*9a0e4156SSadaf Ebrahimi 			// free memory allocated by cs_disasm()
467*9a0e4156SSadaf Ebrahimi 			cs_free(insn, count);
468*9a0e4156SSadaf Ebrahimi 		} else {
469*9a0e4156SSadaf Ebrahimi 			printf("****************\n");
470*9a0e4156SSadaf Ebrahimi 			printf("Platform: %s\n", platforms[i].comment);
471*9a0e4156SSadaf Ebrahimi 			print_string_hex("Code:", platforms[i].code, platforms[i].size);
472*9a0e4156SSadaf Ebrahimi 			printf("ERROR: Failed to disasm given code!\n");
473*9a0e4156SSadaf Ebrahimi 			abort();
474*9a0e4156SSadaf Ebrahimi 		}
475*9a0e4156SSadaf Ebrahimi 
476*9a0e4156SSadaf Ebrahimi 		printf("\n");
477*9a0e4156SSadaf Ebrahimi 
478*9a0e4156SSadaf Ebrahimi 		cs_close(&handle);
479*9a0e4156SSadaf Ebrahimi 	}
480*9a0e4156SSadaf Ebrahimi }
481*9a0e4156SSadaf Ebrahimi 
main()482*9a0e4156SSadaf Ebrahimi int main()
483*9a0e4156SSadaf Ebrahimi {
484*9a0e4156SSadaf Ebrahimi 	test();
485*9a0e4156SSadaf Ebrahimi 
486*9a0e4156SSadaf Ebrahimi 	return 0;
487*9a0e4156SSadaf Ebrahimi }
488