xref: /aosp_15_r20/external/capstone/cstool/cstool.c (revision 9a0e4156d50a75a99ec4f1653a0e9602a5d45c18)
1*9a0e4156SSadaf Ebrahimi /* Tang Yuhang <[email protected]> 2016 */
2*9a0e4156SSadaf Ebrahimi /* pancake <[email protected]> 2017 */
3*9a0e4156SSadaf Ebrahimi 
4*9a0e4156SSadaf Ebrahimi #include <string.h>
5*9a0e4156SSadaf Ebrahimi #include <ctype.h>
6*9a0e4156SSadaf Ebrahimi #include <errno.h>
7*9a0e4156SSadaf Ebrahimi #include "getopt.h"
8*9a0e4156SSadaf Ebrahimi 
9*9a0e4156SSadaf Ebrahimi #include <capstone/capstone.h>
10*9a0e4156SSadaf Ebrahimi 
11*9a0e4156SSadaf Ebrahimi static struct {
12*9a0e4156SSadaf Ebrahimi 	const char *name;
13*9a0e4156SSadaf Ebrahimi 	cs_arch arch;
14*9a0e4156SSadaf Ebrahimi 	cs_mode mode;
15*9a0e4156SSadaf Ebrahimi } all_archs[] = {
16*9a0e4156SSadaf Ebrahimi 	{ "arm", CS_ARCH_ARM, CS_MODE_ARM },
17*9a0e4156SSadaf Ebrahimi 	{ "armb", CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_BIG_ENDIAN },
18*9a0e4156SSadaf Ebrahimi 	{ "armbe", CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_BIG_ENDIAN },
19*9a0e4156SSadaf Ebrahimi 	{ "arml", CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_LITTLE_ENDIAN },
20*9a0e4156SSadaf Ebrahimi 	{ "armle", CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_LITTLE_ENDIAN },
21*9a0e4156SSadaf Ebrahimi 	{ "cortexm", CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_THUMB | CS_MODE_MCLASS },
22*9a0e4156SSadaf Ebrahimi 	{ "thumb", CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_THUMB },
23*9a0e4156SSadaf Ebrahimi 	{ "thumbbe", CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_THUMB | CS_MODE_BIG_ENDIAN },
24*9a0e4156SSadaf Ebrahimi 	{ "thumble", CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_THUMB | CS_MODE_LITTLE_ENDIAN },
25*9a0e4156SSadaf Ebrahimi 	{ "arm64", CS_ARCH_ARM64, CS_MODE_LITTLE_ENDIAN },
26*9a0e4156SSadaf Ebrahimi 	{ "arm64be", CS_ARCH_ARM64, CS_MODE_BIG_ENDIAN },
27*9a0e4156SSadaf Ebrahimi 	{ "mips", CS_ARCH_MIPS, CS_MODE_MIPS32 | CS_MODE_LITTLE_ENDIAN },
28*9a0e4156SSadaf Ebrahimi 	{ "mipsbe", CS_ARCH_MIPS, CS_MODE_MIPS32 | CS_MODE_BIG_ENDIAN },
29*9a0e4156SSadaf Ebrahimi 	{ "mips64", CS_ARCH_MIPS, CS_MODE_MIPS64 | CS_MODE_LITTLE_ENDIAN },
30*9a0e4156SSadaf Ebrahimi 	{ "mips64be", CS_ARCH_MIPS, CS_MODE_MIPS64 | CS_MODE_BIG_ENDIAN },
31*9a0e4156SSadaf Ebrahimi 	{ "x16", CS_ARCH_X86, CS_MODE_16 }, // CS_MODE_16
32*9a0e4156SSadaf Ebrahimi 	{ "x16att", CS_ARCH_X86, CS_MODE_16 }, // CS_MODE_16 , CS_OPT_SYNTAX_ATT
33*9a0e4156SSadaf Ebrahimi 	{ "x32", CS_ARCH_X86, CS_MODE_32 }, // CS_MODE_32
34*9a0e4156SSadaf Ebrahimi 	{ "x32att", CS_ARCH_X86, CS_MODE_32 }, // CS_MODE_32, CS_OPT_SYNTAX_ATT
35*9a0e4156SSadaf Ebrahimi 	{ "x64", CS_ARCH_X86, CS_MODE_64 }, // CS_MODE_64
36*9a0e4156SSadaf Ebrahimi 	{ "x64att", CS_ARCH_X86, CS_MODE_64 }, // CS_MODE_64, CS_OPT_SYNTAX_ATT
37*9a0e4156SSadaf Ebrahimi 	{ "ppc64", CS_ARCH_PPC, CS_MODE_64 | CS_MODE_LITTLE_ENDIAN },
38*9a0e4156SSadaf Ebrahimi 	{ "ppc64be", CS_ARCH_PPC, CS_MODE_64 | CS_MODE_BIG_ENDIAN },
39*9a0e4156SSadaf Ebrahimi 	{ "sparc", CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN },
40*9a0e4156SSadaf Ebrahimi 	{ "systemz", CS_ARCH_SYSZ, CS_MODE_BIG_ENDIAN },
41*9a0e4156SSadaf Ebrahimi 	{ "sysz", CS_ARCH_SYSZ, CS_MODE_BIG_ENDIAN },
42*9a0e4156SSadaf Ebrahimi 	{ "s390x", CS_ARCH_SYSZ, CS_MODE_BIG_ENDIAN },
43*9a0e4156SSadaf Ebrahimi 	{ "xcore", CS_ARCH_XCORE, CS_MODE_BIG_ENDIAN },
44*9a0e4156SSadaf Ebrahimi 	{ "m68k", CS_ARCH_M68K, CS_MODE_BIG_ENDIAN },
45*9a0e4156SSadaf Ebrahimi 	{ "m68k40", CS_ARCH_M68K, CS_MODE_M68K_040 },
46*9a0e4156SSadaf Ebrahimi 	{ "tms320c64x", CS_ARCH_TMS320C64X, CS_MODE_BIG_ENDIAN },
47*9a0e4156SSadaf Ebrahimi 	{ "tms320c64x", CS_ARCH_TMS320C64X, CS_MODE_BIG_ENDIAN },
48*9a0e4156SSadaf Ebrahimi 	{ "m6800", CS_ARCH_M680X, CS_MODE_M680X_6800 },
49*9a0e4156SSadaf Ebrahimi 	{ "m6801", CS_ARCH_M680X, CS_MODE_M680X_6801 },
50*9a0e4156SSadaf Ebrahimi 	{ "m6805", CS_ARCH_M680X, CS_MODE_M680X_6805 },
51*9a0e4156SSadaf Ebrahimi 	{ "m6808", CS_ARCH_M680X, CS_MODE_M680X_6808 },
52*9a0e4156SSadaf Ebrahimi 	{ "m6809", CS_ARCH_M680X, CS_MODE_M680X_6809 },
53*9a0e4156SSadaf Ebrahimi 	{ "m6811", CS_ARCH_M680X, CS_MODE_M680X_6811 },
54*9a0e4156SSadaf Ebrahimi 	{ "cpu12", CS_ARCH_M680X, CS_MODE_M680X_CPU12 },
55*9a0e4156SSadaf Ebrahimi 	{ "hd6301", CS_ARCH_M680X, CS_MODE_M680X_6301 },
56*9a0e4156SSadaf Ebrahimi 	{ "hd6309", CS_ARCH_M680X, CS_MODE_M680X_6309 },
57*9a0e4156SSadaf Ebrahimi 	{ "hcs08", CS_ARCH_M680X, CS_MODE_M680X_HCS08 },
58*9a0e4156SSadaf Ebrahimi 	{ "evm", CS_ARCH_EVM, 0 },
59*9a0e4156SSadaf Ebrahimi 	{ "mos65xx", CS_ARCH_MOS65XX, 0 },
60*9a0e4156SSadaf Ebrahimi 	{ NULL }
61*9a0e4156SSadaf Ebrahimi };
62*9a0e4156SSadaf Ebrahimi 
63*9a0e4156SSadaf Ebrahimi void print_insn_detail_x86(csh ud, cs_mode mode, cs_insn *ins);
64*9a0e4156SSadaf Ebrahimi void print_insn_detail_arm(csh handle, cs_insn *ins);
65*9a0e4156SSadaf Ebrahimi void print_insn_detail_arm64(csh handle, cs_insn *ins);
66*9a0e4156SSadaf Ebrahimi void print_insn_detail_mips(csh handle, cs_insn *ins);
67*9a0e4156SSadaf Ebrahimi void print_insn_detail_ppc(csh handle, cs_insn *ins);
68*9a0e4156SSadaf Ebrahimi void print_insn_detail_sparc(csh handle, cs_insn *ins);
69*9a0e4156SSadaf Ebrahimi void print_insn_detail_sysz(csh handle, cs_insn *ins);
70*9a0e4156SSadaf Ebrahimi void print_insn_detail_xcore(csh handle, cs_insn *ins);
71*9a0e4156SSadaf Ebrahimi void print_insn_detail_m68k(csh handle, cs_insn *ins);
72*9a0e4156SSadaf Ebrahimi void print_insn_detail_tms320c64x(csh handle, cs_insn *ins);
73*9a0e4156SSadaf Ebrahimi void print_insn_detail_m680x(csh handle, cs_insn *ins);
74*9a0e4156SSadaf Ebrahimi void print_insn_detail_evm(csh handle, cs_insn *ins);
75*9a0e4156SSadaf Ebrahimi void print_insn_detail_mos65xx(csh handle, cs_insn *ins);
76*9a0e4156SSadaf Ebrahimi 
77*9a0e4156SSadaf Ebrahimi static void print_details(csh handle, cs_arch arch, cs_mode md, cs_insn *ins);
78*9a0e4156SSadaf Ebrahimi 
print_string_hex(const char * comment,unsigned char * str,size_t len)79*9a0e4156SSadaf Ebrahimi void print_string_hex(const char *comment, unsigned char *str, size_t len)
80*9a0e4156SSadaf Ebrahimi {
81*9a0e4156SSadaf Ebrahimi 	unsigned char *c;
82*9a0e4156SSadaf Ebrahimi 
83*9a0e4156SSadaf Ebrahimi 	printf("%s", comment);
84*9a0e4156SSadaf Ebrahimi 	for (c = str; c < str + len; c++) {
85*9a0e4156SSadaf Ebrahimi 		printf("0x%02x ", *c & 0xff);
86*9a0e4156SSadaf Ebrahimi 	}
87*9a0e4156SSadaf Ebrahimi 
88*9a0e4156SSadaf Ebrahimi 	printf("\n");
89*9a0e4156SSadaf Ebrahimi }
90*9a0e4156SSadaf Ebrahimi 
91*9a0e4156SSadaf Ebrahimi // convert hexchar to hexnum
char_to_hexnum(char c)92*9a0e4156SSadaf Ebrahimi static uint8_t char_to_hexnum(char c)
93*9a0e4156SSadaf Ebrahimi {
94*9a0e4156SSadaf Ebrahimi 	if (c >= '0' && c <= '9') {
95*9a0e4156SSadaf Ebrahimi 		return (uint8_t)(c - '0');
96*9a0e4156SSadaf Ebrahimi 	}
97*9a0e4156SSadaf Ebrahimi 
98*9a0e4156SSadaf Ebrahimi 	if (c >= 'a' && c <= 'f') {
99*9a0e4156SSadaf Ebrahimi 		return (uint8_t)(10 + c - 'a');
100*9a0e4156SSadaf Ebrahimi 	}
101*9a0e4156SSadaf Ebrahimi 
102*9a0e4156SSadaf Ebrahimi 	//  c >= 'A' && c <= 'F'
103*9a0e4156SSadaf Ebrahimi 	return (uint8_t)(10 + c - 'A');
104*9a0e4156SSadaf Ebrahimi }
105*9a0e4156SSadaf Ebrahimi 
106*9a0e4156SSadaf Ebrahimi // convert user input (char[]) to uint8_t[], each element of which is
107*9a0e4156SSadaf Ebrahimi // valid hexadecimal, and return actual length of uint8_t[] in @size.
preprocess(char * code,size_t * size)108*9a0e4156SSadaf Ebrahimi static uint8_t *preprocess(char *code, size_t *size)
109*9a0e4156SSadaf Ebrahimi {
110*9a0e4156SSadaf Ebrahimi 	size_t i = 0, j = 0;
111*9a0e4156SSadaf Ebrahimi 	uint8_t high, low;
112*9a0e4156SSadaf Ebrahimi 	uint8_t *result;
113*9a0e4156SSadaf Ebrahimi 
114*9a0e4156SSadaf Ebrahimi 	if (strlen(code) == 0)
115*9a0e4156SSadaf Ebrahimi 		return NULL;
116*9a0e4156SSadaf Ebrahimi 
117*9a0e4156SSadaf Ebrahimi 	result = (uint8_t *)malloc(strlen(code));
118*9a0e4156SSadaf Ebrahimi 	if (result != NULL) {
119*9a0e4156SSadaf Ebrahimi 		while (code[i] != '\0') {
120*9a0e4156SSadaf Ebrahimi 			if (isxdigit(code[i]) && isxdigit(code[i+1])) {
121*9a0e4156SSadaf Ebrahimi 				high = 16 * char_to_hexnum(code[i]);
122*9a0e4156SSadaf Ebrahimi 				low = char_to_hexnum(code[i+1]);
123*9a0e4156SSadaf Ebrahimi 				result[j] = high + low;
124*9a0e4156SSadaf Ebrahimi 				i++;
125*9a0e4156SSadaf Ebrahimi 				j++;
126*9a0e4156SSadaf Ebrahimi 			}
127*9a0e4156SSadaf Ebrahimi 			i++;
128*9a0e4156SSadaf Ebrahimi 		}
129*9a0e4156SSadaf Ebrahimi 		*size = j;
130*9a0e4156SSadaf Ebrahimi 	}
131*9a0e4156SSadaf Ebrahimi 
132*9a0e4156SSadaf Ebrahimi 	return result;
133*9a0e4156SSadaf Ebrahimi }
134*9a0e4156SSadaf Ebrahimi 
usage(char * prog)135*9a0e4156SSadaf Ebrahimi static void usage(char *prog)
136*9a0e4156SSadaf Ebrahimi {
137*9a0e4156SSadaf Ebrahimi 	printf("Cstool for Capstone Disassembler Engine v%u.%u.%u\n\n", CS_VERSION_MAJOR, CS_VERSION_MINOR, CS_VERSION_EXTRA);
138*9a0e4156SSadaf Ebrahimi 	printf("Syntax: %s [-u|-d|-s|-v] <arch+mode> <assembly-hexstring> [start-address-in-hex-format]\n", prog);
139*9a0e4156SSadaf Ebrahimi 	printf("\nThe following <arch+mode> options are supported:\n");
140*9a0e4156SSadaf Ebrahimi 
141*9a0e4156SSadaf Ebrahimi 	if (cs_support(CS_ARCH_X86)) {
142*9a0e4156SSadaf Ebrahimi 		printf("        x16         16-bit mode (X86)\n");
143*9a0e4156SSadaf Ebrahimi 		printf("        x32         32-bit mode (X86)\n");
144*9a0e4156SSadaf Ebrahimi 		printf("        x64         64-bit mode (X86)\n");
145*9a0e4156SSadaf Ebrahimi 		printf("        x16att      16-bit mode (X86), syntax AT&T\n");
146*9a0e4156SSadaf Ebrahimi 		printf("        x32att      32-bit mode (X86), syntax AT&T\n");
147*9a0e4156SSadaf Ebrahimi 		printf("        x64att      64-bit mode (X86), syntax AT&T\n");
148*9a0e4156SSadaf Ebrahimi 	}
149*9a0e4156SSadaf Ebrahimi 
150*9a0e4156SSadaf Ebrahimi 	if (cs_support(CS_ARCH_ARM)) {
151*9a0e4156SSadaf Ebrahimi 		printf("        arm         arm\n");
152*9a0e4156SSadaf Ebrahimi 		printf("        armbe       arm + big endian\n");
153*9a0e4156SSadaf Ebrahimi 		printf("        thumb       thumb mode\n");
154*9a0e4156SSadaf Ebrahimi 		printf("        thumbbe     thumb + big endian\n");
155*9a0e4156SSadaf Ebrahimi 		printf("        cortexm     thumb + cortex-m extensions\n");
156*9a0e4156SSadaf Ebrahimi 	}
157*9a0e4156SSadaf Ebrahimi 
158*9a0e4156SSadaf Ebrahimi 	if (cs_support(CS_ARCH_ARM64)) {
159*9a0e4156SSadaf Ebrahimi 		printf("        arm64       aarch64 mode\n");
160*9a0e4156SSadaf Ebrahimi 		printf("        arm64be     aarch64 + big endian\n");
161*9a0e4156SSadaf Ebrahimi 	}
162*9a0e4156SSadaf Ebrahimi 
163*9a0e4156SSadaf Ebrahimi 	if (cs_support(CS_ARCH_MIPS)) {
164*9a0e4156SSadaf Ebrahimi 		printf("        mips        mips32 + little endian\n");
165*9a0e4156SSadaf Ebrahimi 		printf("        mipsbe      mips32 + big endian\n");
166*9a0e4156SSadaf Ebrahimi 		printf("        mips64      mips64 + little endian\n");
167*9a0e4156SSadaf Ebrahimi 		printf("        mips64be    mips64 + big endian\n");
168*9a0e4156SSadaf Ebrahimi 	}
169*9a0e4156SSadaf Ebrahimi 
170*9a0e4156SSadaf Ebrahimi 	if (cs_support(CS_ARCH_PPC)) {
171*9a0e4156SSadaf Ebrahimi 		printf("        ppc64       ppc64 + little endian\n");
172*9a0e4156SSadaf Ebrahimi 		printf("        ppc64be     ppc64 + big endian\n");
173*9a0e4156SSadaf Ebrahimi 	}
174*9a0e4156SSadaf Ebrahimi 
175*9a0e4156SSadaf Ebrahimi 	if (cs_support(CS_ARCH_SPARC)) {
176*9a0e4156SSadaf Ebrahimi 		printf("        sparc       sparc\n");
177*9a0e4156SSadaf Ebrahimi 	}
178*9a0e4156SSadaf Ebrahimi 
179*9a0e4156SSadaf Ebrahimi 	if (cs_support(CS_ARCH_SYSZ)) {
180*9a0e4156SSadaf Ebrahimi 		printf("        systemz     systemz (s390x)\n");
181*9a0e4156SSadaf Ebrahimi 	}
182*9a0e4156SSadaf Ebrahimi 
183*9a0e4156SSadaf Ebrahimi 	if (cs_support(CS_ARCH_XCORE)) {
184*9a0e4156SSadaf Ebrahimi 		printf("        xcore       xcore\n");
185*9a0e4156SSadaf Ebrahimi 	}
186*9a0e4156SSadaf Ebrahimi 
187*9a0e4156SSadaf Ebrahimi 	if (cs_support(CS_ARCH_M68K)) {
188*9a0e4156SSadaf Ebrahimi 		printf("        m68k        m68k + big endian\n");
189*9a0e4156SSadaf Ebrahimi 		printf("        m68k40      m68k_040\n");
190*9a0e4156SSadaf Ebrahimi 	}
191*9a0e4156SSadaf Ebrahimi 
192*9a0e4156SSadaf Ebrahimi 	if (cs_support(CS_ARCH_TMS320C64X)) {
193*9a0e4156SSadaf Ebrahimi 		printf("        tms320c64x  TMS320C64x\n");
194*9a0e4156SSadaf Ebrahimi 	}
195*9a0e4156SSadaf Ebrahimi 
196*9a0e4156SSadaf Ebrahimi 	if (cs_support(CS_ARCH_M680X)) {
197*9a0e4156SSadaf Ebrahimi 		printf("        m6800       M6800/2\n");
198*9a0e4156SSadaf Ebrahimi 		printf("        m6801       M6801/3\n");
199*9a0e4156SSadaf Ebrahimi 		printf("        m6805       M6805\n");
200*9a0e4156SSadaf Ebrahimi 		printf("        m6808       M68HC08\n");
201*9a0e4156SSadaf Ebrahimi 		printf("        m6809       M6809\n");
202*9a0e4156SSadaf Ebrahimi 		printf("        m6811       M68HC11\n");
203*9a0e4156SSadaf Ebrahimi 		printf("        cpu12       M68HC12/HCS12\n");
204*9a0e4156SSadaf Ebrahimi 		printf("        hd6301      HD6301/3\n");
205*9a0e4156SSadaf Ebrahimi 		printf("        hd6309      HD6309\n");
206*9a0e4156SSadaf Ebrahimi 		printf("        hcs08       HCS08\n");
207*9a0e4156SSadaf Ebrahimi 	}
208*9a0e4156SSadaf Ebrahimi 
209*9a0e4156SSadaf Ebrahimi 	if (cs_support(CS_ARCH_EVM)) {
210*9a0e4156SSadaf Ebrahimi 		printf("        evm         Ethereum Virtual Machine\n");
211*9a0e4156SSadaf Ebrahimi 	}
212*9a0e4156SSadaf Ebrahimi 
213*9a0e4156SSadaf Ebrahimi 	if (cs_support(CS_ARCH_MOS65XX)) {
214*9a0e4156SSadaf Ebrahimi 		printf("        mos65xx     MOS65XX family\n");
215*9a0e4156SSadaf Ebrahimi 	}
216*9a0e4156SSadaf Ebrahimi 
217*9a0e4156SSadaf Ebrahimi 	printf("\nExtra options:\n");
218*9a0e4156SSadaf Ebrahimi 	printf("        -d show detailed information of the instructions\n");
219*9a0e4156SSadaf Ebrahimi 	printf("        -u show immediates as unsigned\n");
220*9a0e4156SSadaf Ebrahimi 	printf("        -s decode in SKIPDATA mode\n");
221*9a0e4156SSadaf Ebrahimi 	printf("        -v show version & Capstone core build info\n\n");
222*9a0e4156SSadaf Ebrahimi }
223*9a0e4156SSadaf Ebrahimi 
print_details(csh handle,cs_arch arch,cs_mode md,cs_insn * ins)224*9a0e4156SSadaf Ebrahimi static void print_details(csh handle, cs_arch arch, cs_mode md, cs_insn *ins)
225*9a0e4156SSadaf Ebrahimi {
226*9a0e4156SSadaf Ebrahimi 	switch(arch) {
227*9a0e4156SSadaf Ebrahimi 		case CS_ARCH_X86:
228*9a0e4156SSadaf Ebrahimi 			print_insn_detail_x86(handle, md, ins);
229*9a0e4156SSadaf Ebrahimi 			break;
230*9a0e4156SSadaf Ebrahimi 		case CS_ARCH_ARM:
231*9a0e4156SSadaf Ebrahimi 			print_insn_detail_arm(handle, ins);
232*9a0e4156SSadaf Ebrahimi 			break;
233*9a0e4156SSadaf Ebrahimi 		case CS_ARCH_ARM64:
234*9a0e4156SSadaf Ebrahimi 			print_insn_detail_arm64(handle, ins);
235*9a0e4156SSadaf Ebrahimi 			break;
236*9a0e4156SSadaf Ebrahimi 		case CS_ARCH_MIPS:
237*9a0e4156SSadaf Ebrahimi 			print_insn_detail_mips(handle, ins);
238*9a0e4156SSadaf Ebrahimi 			break;
239*9a0e4156SSadaf Ebrahimi 		case CS_ARCH_PPC:
240*9a0e4156SSadaf Ebrahimi 			print_insn_detail_ppc(handle, ins);
241*9a0e4156SSadaf Ebrahimi 			break;
242*9a0e4156SSadaf Ebrahimi 		case CS_ARCH_SPARC:
243*9a0e4156SSadaf Ebrahimi 			print_insn_detail_sparc(handle, ins);
244*9a0e4156SSadaf Ebrahimi 			break;
245*9a0e4156SSadaf Ebrahimi 		case CS_ARCH_SYSZ:
246*9a0e4156SSadaf Ebrahimi 			print_insn_detail_sysz(handle, ins);
247*9a0e4156SSadaf Ebrahimi 			break;
248*9a0e4156SSadaf Ebrahimi 		case CS_ARCH_XCORE:
249*9a0e4156SSadaf Ebrahimi 			print_insn_detail_xcore(handle, ins);
250*9a0e4156SSadaf Ebrahimi 			break;
251*9a0e4156SSadaf Ebrahimi 		case CS_ARCH_M68K:
252*9a0e4156SSadaf Ebrahimi 			print_insn_detail_m68k(handle, ins);
253*9a0e4156SSadaf Ebrahimi 			break;
254*9a0e4156SSadaf Ebrahimi 		case CS_ARCH_TMS320C64X:
255*9a0e4156SSadaf Ebrahimi 			print_insn_detail_tms320c64x(handle, ins);
256*9a0e4156SSadaf Ebrahimi 			break;
257*9a0e4156SSadaf Ebrahimi 		case CS_ARCH_M680X:
258*9a0e4156SSadaf Ebrahimi 			print_insn_detail_m680x(handle, ins);
259*9a0e4156SSadaf Ebrahimi 			break;
260*9a0e4156SSadaf Ebrahimi 		case CS_ARCH_EVM:
261*9a0e4156SSadaf Ebrahimi 			print_insn_detail_evm(handle, ins);
262*9a0e4156SSadaf Ebrahimi 			break;
263*9a0e4156SSadaf Ebrahimi 		case CS_ARCH_MOS65XX:
264*9a0e4156SSadaf Ebrahimi 			print_insn_detail_mos65xx(handle, ins);
265*9a0e4156SSadaf Ebrahimi 			break;
266*9a0e4156SSadaf Ebrahimi 		default: break;
267*9a0e4156SSadaf Ebrahimi 	}
268*9a0e4156SSadaf Ebrahimi 
269*9a0e4156SSadaf Ebrahimi 	if (ins->detail->groups_count) {
270*9a0e4156SSadaf Ebrahimi 		int j;
271*9a0e4156SSadaf Ebrahimi 
272*9a0e4156SSadaf Ebrahimi 		printf("\tGroups: ");
273*9a0e4156SSadaf Ebrahimi 		for(j = 0; j < ins->detail->groups_count; j++) {
274*9a0e4156SSadaf Ebrahimi 			printf("%s ", cs_group_name(handle, ins->detail->groups[j]));
275*9a0e4156SSadaf Ebrahimi 		}
276*9a0e4156SSadaf Ebrahimi 		printf("\n");
277*9a0e4156SSadaf Ebrahimi 	}
278*9a0e4156SSadaf Ebrahimi 
279*9a0e4156SSadaf Ebrahimi 	printf("\n");
280*9a0e4156SSadaf Ebrahimi }
281*9a0e4156SSadaf Ebrahimi 
main(int argc,char ** argv)282*9a0e4156SSadaf Ebrahimi int main(int argc, char **argv)
283*9a0e4156SSadaf Ebrahimi {
284*9a0e4156SSadaf Ebrahimi 	int i, c;
285*9a0e4156SSadaf Ebrahimi 	csh handle;
286*9a0e4156SSadaf Ebrahimi 	char *mode;
287*9a0e4156SSadaf Ebrahimi 	uint8_t *assembly;
288*9a0e4156SSadaf Ebrahimi 	size_t count, size;
289*9a0e4156SSadaf Ebrahimi 	uint64_t address = 0LL;
290*9a0e4156SSadaf Ebrahimi 	cs_insn *insn;
291*9a0e4156SSadaf Ebrahimi 	cs_err err;
292*9a0e4156SSadaf Ebrahimi 	cs_mode md;
293*9a0e4156SSadaf Ebrahimi 	cs_arch arch = CS_ARCH_ALL;
294*9a0e4156SSadaf Ebrahimi 	bool detail_flag = false;
295*9a0e4156SSadaf Ebrahimi 	bool unsigned_flag = false;
296*9a0e4156SSadaf Ebrahimi 	bool skipdata = false;
297*9a0e4156SSadaf Ebrahimi 	int args_left;
298*9a0e4156SSadaf Ebrahimi 
299*9a0e4156SSadaf Ebrahimi 	while ((c = getopt (argc, argv, "sudhv")) != -1) {
300*9a0e4156SSadaf Ebrahimi 		switch (c) {
301*9a0e4156SSadaf Ebrahimi 			case 's':
302*9a0e4156SSadaf Ebrahimi 				skipdata = true;
303*9a0e4156SSadaf Ebrahimi 				break;
304*9a0e4156SSadaf Ebrahimi 			case 'u':
305*9a0e4156SSadaf Ebrahimi 				unsigned_flag = true;
306*9a0e4156SSadaf Ebrahimi 				break;
307*9a0e4156SSadaf Ebrahimi 			case 'd':
308*9a0e4156SSadaf Ebrahimi 				detail_flag = true;
309*9a0e4156SSadaf Ebrahimi 				break;
310*9a0e4156SSadaf Ebrahimi 			case 'v':
311*9a0e4156SSadaf Ebrahimi 				printf("cstool for Capstone Disassembler, v%u.%u.%u\n", CS_VERSION_MAJOR, CS_VERSION_MINOR, CS_VERSION_EXTRA);
312*9a0e4156SSadaf Ebrahimi 
313*9a0e4156SSadaf Ebrahimi 				printf("Capstone build: ");
314*9a0e4156SSadaf Ebrahimi 				if (cs_support(CS_ARCH_X86)) {
315*9a0e4156SSadaf Ebrahimi 					printf("x86=1 ");
316*9a0e4156SSadaf Ebrahimi 				}
317*9a0e4156SSadaf Ebrahimi 
318*9a0e4156SSadaf Ebrahimi 				if (cs_support(CS_ARCH_ARM)) {
319*9a0e4156SSadaf Ebrahimi 					printf("arm=1 ");
320*9a0e4156SSadaf Ebrahimi 				}
321*9a0e4156SSadaf Ebrahimi 
322*9a0e4156SSadaf Ebrahimi 				if (cs_support(CS_ARCH_ARM64)) {
323*9a0e4156SSadaf Ebrahimi 					printf("arm64=1 ");
324*9a0e4156SSadaf Ebrahimi 				}
325*9a0e4156SSadaf Ebrahimi 
326*9a0e4156SSadaf Ebrahimi 				if (cs_support(CS_ARCH_MIPS)) {
327*9a0e4156SSadaf Ebrahimi 					printf("mips=1 ");
328*9a0e4156SSadaf Ebrahimi 				}
329*9a0e4156SSadaf Ebrahimi 
330*9a0e4156SSadaf Ebrahimi 				if (cs_support(CS_ARCH_PPC)) {
331*9a0e4156SSadaf Ebrahimi 					printf("ppc=1 ");
332*9a0e4156SSadaf Ebrahimi 				}
333*9a0e4156SSadaf Ebrahimi 
334*9a0e4156SSadaf Ebrahimi 				if (cs_support(CS_ARCH_SPARC)) {
335*9a0e4156SSadaf Ebrahimi 					printf("sparc=1 ");
336*9a0e4156SSadaf Ebrahimi 				}
337*9a0e4156SSadaf Ebrahimi 
338*9a0e4156SSadaf Ebrahimi 				if (cs_support(CS_ARCH_SYSZ)) {
339*9a0e4156SSadaf Ebrahimi 					printf("sysz=1 ");
340*9a0e4156SSadaf Ebrahimi 				}
341*9a0e4156SSadaf Ebrahimi 
342*9a0e4156SSadaf Ebrahimi 				if (cs_support(CS_ARCH_XCORE)) {
343*9a0e4156SSadaf Ebrahimi 					printf("xcore=1 ");
344*9a0e4156SSadaf Ebrahimi 				}
345*9a0e4156SSadaf Ebrahimi 
346*9a0e4156SSadaf Ebrahimi 				if (cs_support(CS_ARCH_M68K)) {
347*9a0e4156SSadaf Ebrahimi 					printf("m68k=1 ");
348*9a0e4156SSadaf Ebrahimi 				}
349*9a0e4156SSadaf Ebrahimi 
350*9a0e4156SSadaf Ebrahimi 				if (cs_support(CS_ARCH_TMS320C64X)) {
351*9a0e4156SSadaf Ebrahimi 					printf("tms320c64x=1 ");
352*9a0e4156SSadaf Ebrahimi 				}
353*9a0e4156SSadaf Ebrahimi 
354*9a0e4156SSadaf Ebrahimi 				if (cs_support(CS_ARCH_M680X)) {
355*9a0e4156SSadaf Ebrahimi 					printf("m680x=1 ");
356*9a0e4156SSadaf Ebrahimi 				}
357*9a0e4156SSadaf Ebrahimi 
358*9a0e4156SSadaf Ebrahimi 				if (cs_support(CS_ARCH_EVM)) {
359*9a0e4156SSadaf Ebrahimi 					printf("evm=1 ");
360*9a0e4156SSadaf Ebrahimi 				}
361*9a0e4156SSadaf Ebrahimi 
362*9a0e4156SSadaf Ebrahimi 				if (cs_support(CS_ARCH_MOS65XX)) {
363*9a0e4156SSadaf Ebrahimi 					printf("mos65xx=1 ");
364*9a0e4156SSadaf Ebrahimi 				}
365*9a0e4156SSadaf Ebrahimi 
366*9a0e4156SSadaf Ebrahimi 				if (cs_support(CS_SUPPORT_DIET)) {
367*9a0e4156SSadaf Ebrahimi 					printf("diet=1 ");
368*9a0e4156SSadaf Ebrahimi 				}
369*9a0e4156SSadaf Ebrahimi 
370*9a0e4156SSadaf Ebrahimi 				if (cs_support(CS_SUPPORT_X86_REDUCE)) {
371*9a0e4156SSadaf Ebrahimi 					printf("x86_reduce=1 ");
372*9a0e4156SSadaf Ebrahimi 				}
373*9a0e4156SSadaf Ebrahimi 
374*9a0e4156SSadaf Ebrahimi 				printf("\n");
375*9a0e4156SSadaf Ebrahimi 				return 0;
376*9a0e4156SSadaf Ebrahimi 			case 'h':
377*9a0e4156SSadaf Ebrahimi 				usage(argv[0]);
378*9a0e4156SSadaf Ebrahimi 				return 0;
379*9a0e4156SSadaf Ebrahimi 			default:
380*9a0e4156SSadaf Ebrahimi 				usage(argv[0]);
381*9a0e4156SSadaf Ebrahimi 				return -1;
382*9a0e4156SSadaf Ebrahimi 		}
383*9a0e4156SSadaf Ebrahimi 	}
384*9a0e4156SSadaf Ebrahimi 
385*9a0e4156SSadaf Ebrahimi 	args_left = argc - optind;
386*9a0e4156SSadaf Ebrahimi 	if (args_left < 2 || args_left > 3) {
387*9a0e4156SSadaf Ebrahimi 		usage(argv[0]);
388*9a0e4156SSadaf Ebrahimi 		return -1;
389*9a0e4156SSadaf Ebrahimi 	}
390*9a0e4156SSadaf Ebrahimi 
391*9a0e4156SSadaf Ebrahimi 	mode = argv[optind];
392*9a0e4156SSadaf Ebrahimi 	assembly = preprocess(argv[optind + 1], &size);
393*9a0e4156SSadaf Ebrahimi 	if (!assembly) {
394*9a0e4156SSadaf Ebrahimi 		usage(argv[0]);
395*9a0e4156SSadaf Ebrahimi 		return -1;
396*9a0e4156SSadaf Ebrahimi 	}
397*9a0e4156SSadaf Ebrahimi 
398*9a0e4156SSadaf Ebrahimi 	if (args_left == 3) {
399*9a0e4156SSadaf Ebrahimi 		char *temp, *src = argv[optind + 2];
400*9a0e4156SSadaf Ebrahimi 		address = strtoull(src, &temp, 16);
401*9a0e4156SSadaf Ebrahimi 		if (temp == src || *temp != '\0' || errno == ERANGE) {
402*9a0e4156SSadaf Ebrahimi 			printf("ERROR: invalid address argument, quit!\n");
403*9a0e4156SSadaf Ebrahimi 			return -2;
404*9a0e4156SSadaf Ebrahimi 		}
405*9a0e4156SSadaf Ebrahimi 	}
406*9a0e4156SSadaf Ebrahimi 
407*9a0e4156SSadaf Ebrahimi 	for (i = 0; all_archs[i].name; i++) {
408*9a0e4156SSadaf Ebrahimi 		if (!strcmp(all_archs[i].name, mode)) {
409*9a0e4156SSadaf Ebrahimi 			arch = all_archs[i].arch;
410*9a0e4156SSadaf Ebrahimi 			err = cs_open(all_archs[i].arch, all_archs[i].mode, &handle);
411*9a0e4156SSadaf Ebrahimi 			if (!err) {
412*9a0e4156SSadaf Ebrahimi 				md = all_archs[i].mode;
413*9a0e4156SSadaf Ebrahimi 				if (strstr (mode, "att")) {
414*9a0e4156SSadaf Ebrahimi 					cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
415*9a0e4156SSadaf Ebrahimi 				}
416*9a0e4156SSadaf Ebrahimi 
417*9a0e4156SSadaf Ebrahimi 				// turn on SKIPDATA mode
418*9a0e4156SSadaf Ebrahimi 				if (skipdata)
419*9a0e4156SSadaf Ebrahimi 					cs_option(handle, CS_OPT_SKIPDATA, CS_OPT_ON);
420*9a0e4156SSadaf Ebrahimi 			}
421*9a0e4156SSadaf Ebrahimi 			break;
422*9a0e4156SSadaf Ebrahimi 		}
423*9a0e4156SSadaf Ebrahimi 	}
424*9a0e4156SSadaf Ebrahimi 
425*9a0e4156SSadaf Ebrahimi 	if (arch == CS_ARCH_ALL) {
426*9a0e4156SSadaf Ebrahimi 		printf("ERROR: Invalid <arch+mode>: \"%s\", quit!\n", mode);
427*9a0e4156SSadaf Ebrahimi 		usage(argv[0]);
428*9a0e4156SSadaf Ebrahimi 		return -1;
429*9a0e4156SSadaf Ebrahimi 	}
430*9a0e4156SSadaf Ebrahimi 
431*9a0e4156SSadaf Ebrahimi 	if (err) {
432*9a0e4156SSadaf Ebrahimi 		printf("ERROR: Failed on cs_open(), quit!\n");
433*9a0e4156SSadaf Ebrahimi 		usage(argv[0]);
434*9a0e4156SSadaf Ebrahimi 		return -1;
435*9a0e4156SSadaf Ebrahimi 	}
436*9a0e4156SSadaf Ebrahimi 
437*9a0e4156SSadaf Ebrahimi 	if (detail_flag) {
438*9a0e4156SSadaf Ebrahimi 		cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
439*9a0e4156SSadaf Ebrahimi 	}
440*9a0e4156SSadaf Ebrahimi 
441*9a0e4156SSadaf Ebrahimi 	if (unsigned_flag) {
442*9a0e4156SSadaf Ebrahimi 		cs_option(handle, CS_OPT_UNSIGNED, CS_OPT_ON);
443*9a0e4156SSadaf Ebrahimi 	}
444*9a0e4156SSadaf Ebrahimi 
445*9a0e4156SSadaf Ebrahimi 	count = cs_disasm(handle, assembly, size, address, 0, &insn);
446*9a0e4156SSadaf Ebrahimi 	if (count > 0) {
447*9a0e4156SSadaf Ebrahimi 		size_t i;
448*9a0e4156SSadaf Ebrahimi 
449*9a0e4156SSadaf Ebrahimi 		for (i = 0; i < count; i++) {
450*9a0e4156SSadaf Ebrahimi 			int j;
451*9a0e4156SSadaf Ebrahimi 
452*9a0e4156SSadaf Ebrahimi 			printf("%2"PRIx64"  ", insn[i].address);
453*9a0e4156SSadaf Ebrahimi 			for (j = 0; j < insn[i].size; j++) {
454*9a0e4156SSadaf Ebrahimi 				if (j > 0)
455*9a0e4156SSadaf Ebrahimi 					putchar(' ');
456*9a0e4156SSadaf Ebrahimi 				printf("%02x", insn[i].bytes[j]);
457*9a0e4156SSadaf Ebrahimi 			}
458*9a0e4156SSadaf Ebrahimi 			// X86 and s390 instruction sizes are variable.
459*9a0e4156SSadaf Ebrahimi 			// align assembly instruction after the opcode
460*9a0e4156SSadaf Ebrahimi 			if (arch == CS_ARCH_X86) {
461*9a0e4156SSadaf Ebrahimi 				for (; j < 16; j++) {
462*9a0e4156SSadaf Ebrahimi 					printf("   ");
463*9a0e4156SSadaf Ebrahimi 				}
464*9a0e4156SSadaf Ebrahimi 			} else if (arch == CS_ARCH_SYSZ) {
465*9a0e4156SSadaf Ebrahimi 				for (; j < 6; j++) {
466*9a0e4156SSadaf Ebrahimi 					printf("   ");
467*9a0e4156SSadaf Ebrahimi 				}
468*9a0e4156SSadaf Ebrahimi 			}
469*9a0e4156SSadaf Ebrahimi 
470*9a0e4156SSadaf Ebrahimi 			printf("  %s\t%s\n", insn[i].mnemonic, insn[i].op_str);
471*9a0e4156SSadaf Ebrahimi 
472*9a0e4156SSadaf Ebrahimi 			if (detail_flag) {
473*9a0e4156SSadaf Ebrahimi 				print_details(handle, arch, md, &insn[i]);
474*9a0e4156SSadaf Ebrahimi 			}
475*9a0e4156SSadaf Ebrahimi 		}
476*9a0e4156SSadaf Ebrahimi 
477*9a0e4156SSadaf Ebrahimi 		cs_free(insn, count);
478*9a0e4156SSadaf Ebrahimi 	} else {
479*9a0e4156SSadaf Ebrahimi 		printf("ERROR: invalid assembly code\n");
480*9a0e4156SSadaf Ebrahimi 		return(-4);
481*9a0e4156SSadaf Ebrahimi 	}
482*9a0e4156SSadaf Ebrahimi 
483*9a0e4156SSadaf Ebrahimi 	cs_close(&handle);
484*9a0e4156SSadaf Ebrahimi 	free(assembly);
485*9a0e4156SSadaf Ebrahimi 
486*9a0e4156SSadaf Ebrahimi 	return 0;
487*9a0e4156SSadaf Ebrahimi }
488