1*9a0e4156SSadaf Ebrahimi
2*9a0e4156SSadaf Ebrahimi #include <stdio.h>
3*9a0e4156SSadaf Ebrahimi #include <stdlib.h>
4*9a0e4156SSadaf Ebrahimi #include <inttypes.h>
5*9a0e4156SSadaf Ebrahimi #include <assert.h>
6*9a0e4156SSadaf Ebrahimi
7*9a0e4156SSadaf Ebrahimi #include <capstone/capstone.h>
8*9a0e4156SSadaf Ebrahimi
9*9a0e4156SSadaf Ebrahimi
10*9a0e4156SSadaf Ebrahimi struct platform {
11*9a0e4156SSadaf Ebrahimi cs_arch arch;
12*9a0e4156SSadaf Ebrahimi cs_mode mode;
13*9a0e4156SSadaf Ebrahimi char *comment;
14*9a0e4156SSadaf Ebrahimi };
15*9a0e4156SSadaf Ebrahimi
16*9a0e4156SSadaf Ebrahimi FILE * outfile = NULL;
17*9a0e4156SSadaf Ebrahimi
18*9a0e4156SSadaf Ebrahimi struct platform platforms[] = {
19*9a0e4156SSadaf Ebrahimi {
20*9a0e4156SSadaf Ebrahimi // item 0
21*9a0e4156SSadaf Ebrahimi CS_ARCH_X86,
22*9a0e4156SSadaf Ebrahimi CS_MODE_32,
23*9a0e4156SSadaf Ebrahimi "X86 32 (Intel syntax)"
24*9a0e4156SSadaf Ebrahimi },
25*9a0e4156SSadaf Ebrahimi {
26*9a0e4156SSadaf Ebrahimi // item 1
27*9a0e4156SSadaf Ebrahimi CS_ARCH_X86,
28*9a0e4156SSadaf Ebrahimi CS_MODE_64,
29*9a0e4156SSadaf Ebrahimi "X86 64 (Intel syntax)"
30*9a0e4156SSadaf Ebrahimi },
31*9a0e4156SSadaf Ebrahimi {
32*9a0e4156SSadaf Ebrahimi // item 2
33*9a0e4156SSadaf Ebrahimi CS_ARCH_ARM,
34*9a0e4156SSadaf Ebrahimi CS_MODE_ARM,
35*9a0e4156SSadaf Ebrahimi "ARM"
36*9a0e4156SSadaf Ebrahimi },
37*9a0e4156SSadaf Ebrahimi {
38*9a0e4156SSadaf Ebrahimi // item 3
39*9a0e4156SSadaf Ebrahimi CS_ARCH_ARM,
40*9a0e4156SSadaf Ebrahimi CS_MODE_THUMB,
41*9a0e4156SSadaf Ebrahimi "THUMB"
42*9a0e4156SSadaf Ebrahimi },
43*9a0e4156SSadaf Ebrahimi {
44*9a0e4156SSadaf Ebrahimi // item 4
45*9a0e4156SSadaf Ebrahimi CS_ARCH_ARM,
46*9a0e4156SSadaf Ebrahimi (cs_mode)(CS_MODE_ARM + CS_MODE_V8),
47*9a0e4156SSadaf Ebrahimi "Arm-V8"
48*9a0e4156SSadaf Ebrahimi },
49*9a0e4156SSadaf Ebrahimi {
50*9a0e4156SSadaf Ebrahimi // item 5
51*9a0e4156SSadaf Ebrahimi CS_ARCH_ARM,
52*9a0e4156SSadaf Ebrahimi (cs_mode)(CS_MODE_THUMB+CS_MODE_V8),
53*9a0e4156SSadaf Ebrahimi "THUMB+V8"
54*9a0e4156SSadaf Ebrahimi },
55*9a0e4156SSadaf Ebrahimi {
56*9a0e4156SSadaf Ebrahimi // item 6
57*9a0e4156SSadaf Ebrahimi CS_ARCH_ARM,
58*9a0e4156SSadaf Ebrahimi (cs_mode)(CS_MODE_THUMB + CS_MODE_MCLASS),
59*9a0e4156SSadaf Ebrahimi "Thumb-MClass"
60*9a0e4156SSadaf Ebrahimi },
61*9a0e4156SSadaf Ebrahimi {
62*9a0e4156SSadaf Ebrahimi // item 7
63*9a0e4156SSadaf Ebrahimi CS_ARCH_ARM64,
64*9a0e4156SSadaf Ebrahimi (cs_mode)0,
65*9a0e4156SSadaf Ebrahimi "ARM-64"
66*9a0e4156SSadaf Ebrahimi },
67*9a0e4156SSadaf Ebrahimi {
68*9a0e4156SSadaf Ebrahimi // item 8
69*9a0e4156SSadaf Ebrahimi CS_ARCH_MIPS,
70*9a0e4156SSadaf Ebrahimi (cs_mode)(CS_MODE_MIPS32 + CS_MODE_BIG_ENDIAN),
71*9a0e4156SSadaf Ebrahimi "MIPS-32 (Big-endian)"
72*9a0e4156SSadaf Ebrahimi },
73*9a0e4156SSadaf Ebrahimi {
74*9a0e4156SSadaf Ebrahimi // item 9
75*9a0e4156SSadaf Ebrahimi CS_ARCH_MIPS,
76*9a0e4156SSadaf Ebrahimi (cs_mode)(CS_MODE_MIPS32 + CS_MODE_MICRO),
77*9a0e4156SSadaf Ebrahimi "MIPS-32 (micro)"
78*9a0e4156SSadaf Ebrahimi },
79*9a0e4156SSadaf Ebrahimi {
80*9a0e4156SSadaf Ebrahimi //item 10
81*9a0e4156SSadaf Ebrahimi CS_ARCH_MIPS,
82*9a0e4156SSadaf Ebrahimi CS_MODE_MIPS64,
83*9a0e4156SSadaf Ebrahimi "MIPS-64-EL (Little-endian)"
84*9a0e4156SSadaf Ebrahimi },
85*9a0e4156SSadaf Ebrahimi {
86*9a0e4156SSadaf Ebrahimi //item 11
87*9a0e4156SSadaf Ebrahimi CS_ARCH_MIPS,
88*9a0e4156SSadaf Ebrahimi CS_MODE_MIPS32,
89*9a0e4156SSadaf Ebrahimi "MIPS-32-EL (Little-endian)"
90*9a0e4156SSadaf Ebrahimi },
91*9a0e4156SSadaf Ebrahimi {
92*9a0e4156SSadaf Ebrahimi //item 12
93*9a0e4156SSadaf Ebrahimi CS_ARCH_MIPS,
94*9a0e4156SSadaf Ebrahimi (cs_mode)(CS_MODE_MIPS64 + CS_MODE_BIG_ENDIAN),
95*9a0e4156SSadaf Ebrahimi "MIPS-64 (Big-endian)"
96*9a0e4156SSadaf Ebrahimi },
97*9a0e4156SSadaf Ebrahimi {
98*9a0e4156SSadaf Ebrahimi //item 13
99*9a0e4156SSadaf Ebrahimi CS_ARCH_MIPS,
100*9a0e4156SSadaf Ebrahimi (cs_mode)(CS_MODE_MIPS32 + CS_MODE_MICRO + CS_MODE_BIG_ENDIAN),
101*9a0e4156SSadaf Ebrahimi "MIPS-32 | Micro (Big-endian)"
102*9a0e4156SSadaf Ebrahimi },
103*9a0e4156SSadaf Ebrahimi {
104*9a0e4156SSadaf Ebrahimi //item 14
105*9a0e4156SSadaf Ebrahimi CS_ARCH_PPC,
106*9a0e4156SSadaf Ebrahimi CS_MODE_BIG_ENDIAN,
107*9a0e4156SSadaf Ebrahimi "PPC-64"
108*9a0e4156SSadaf Ebrahimi },
109*9a0e4156SSadaf Ebrahimi {
110*9a0e4156SSadaf Ebrahimi //item 15
111*9a0e4156SSadaf Ebrahimi CS_ARCH_SPARC,
112*9a0e4156SSadaf Ebrahimi CS_MODE_BIG_ENDIAN,
113*9a0e4156SSadaf Ebrahimi "Sparc"
114*9a0e4156SSadaf Ebrahimi },
115*9a0e4156SSadaf Ebrahimi {
116*9a0e4156SSadaf Ebrahimi //item 16
117*9a0e4156SSadaf Ebrahimi CS_ARCH_SPARC,
118*9a0e4156SSadaf Ebrahimi (cs_mode)(CS_MODE_BIG_ENDIAN + CS_MODE_V9),
119*9a0e4156SSadaf Ebrahimi "SparcV9"
120*9a0e4156SSadaf Ebrahimi },
121*9a0e4156SSadaf Ebrahimi {
122*9a0e4156SSadaf Ebrahimi //item 17
123*9a0e4156SSadaf Ebrahimi CS_ARCH_SYSZ,
124*9a0e4156SSadaf Ebrahimi (cs_mode)0,
125*9a0e4156SSadaf Ebrahimi "SystemZ"
126*9a0e4156SSadaf Ebrahimi },
127*9a0e4156SSadaf Ebrahimi {
128*9a0e4156SSadaf Ebrahimi //item 18
129*9a0e4156SSadaf Ebrahimi CS_ARCH_XCORE,
130*9a0e4156SSadaf Ebrahimi (cs_mode)0,
131*9a0e4156SSadaf Ebrahimi "XCore"
132*9a0e4156SSadaf Ebrahimi },
133*9a0e4156SSadaf Ebrahimi {
134*9a0e4156SSadaf Ebrahimi //item 19
135*9a0e4156SSadaf Ebrahimi CS_ARCH_MIPS,
136*9a0e4156SSadaf Ebrahimi (cs_mode)(CS_MODE_MIPS32R6 + CS_MODE_BIG_ENDIAN),
137*9a0e4156SSadaf Ebrahimi "MIPS-32R6 (Big-endian)"
138*9a0e4156SSadaf Ebrahimi },
139*9a0e4156SSadaf Ebrahimi {
140*9a0e4156SSadaf Ebrahimi //item 20
141*9a0e4156SSadaf Ebrahimi CS_ARCH_MIPS,
142*9a0e4156SSadaf Ebrahimi (cs_mode)(CS_MODE_MIPS32R6 + CS_MODE_MICRO + CS_MODE_BIG_ENDIAN),
143*9a0e4156SSadaf Ebrahimi "MIPS-32R6 (Micro+Big-endian)"
144*9a0e4156SSadaf Ebrahimi },
145*9a0e4156SSadaf Ebrahimi {
146*9a0e4156SSadaf Ebrahimi //item 21
147*9a0e4156SSadaf Ebrahimi CS_ARCH_MIPS,
148*9a0e4156SSadaf Ebrahimi CS_MODE_MIPS32R6,
149*9a0e4156SSadaf Ebrahimi "MIPS-32R6 (Little-endian)"
150*9a0e4156SSadaf Ebrahimi },
151*9a0e4156SSadaf Ebrahimi {
152*9a0e4156SSadaf Ebrahimi //item 22
153*9a0e4156SSadaf Ebrahimi CS_ARCH_MIPS,
154*9a0e4156SSadaf Ebrahimi (cs_mode)(CS_MODE_MIPS32R6 + CS_MODE_MICRO),
155*9a0e4156SSadaf Ebrahimi "MIPS-32R6 (Micro+Little-endian)"
156*9a0e4156SSadaf Ebrahimi },
157*9a0e4156SSadaf Ebrahimi {
158*9a0e4156SSadaf Ebrahimi //item 23
159*9a0e4156SSadaf Ebrahimi CS_ARCH_M68K,
160*9a0e4156SSadaf Ebrahimi (cs_mode)0,
161*9a0e4156SSadaf Ebrahimi "M68K"
162*9a0e4156SSadaf Ebrahimi },
163*9a0e4156SSadaf Ebrahimi {
164*9a0e4156SSadaf Ebrahimi //item 24
165*9a0e4156SSadaf Ebrahimi CS_ARCH_M680X,
166*9a0e4156SSadaf Ebrahimi (cs_mode)CS_MODE_M680X_6809,
167*9a0e4156SSadaf Ebrahimi "M680X_M6809"
168*9a0e4156SSadaf Ebrahimi },
169*9a0e4156SSadaf Ebrahimi {
170*9a0e4156SSadaf Ebrahimi //item 25
171*9a0e4156SSadaf Ebrahimi CS_ARCH_EVM,
172*9a0e4156SSadaf Ebrahimi (cs_mode)0,
173*9a0e4156SSadaf Ebrahimi "EVM"
174*9a0e4156SSadaf Ebrahimi },
175*9a0e4156SSadaf Ebrahimi };
176*9a0e4156SSadaf Ebrahimi
177*9a0e4156SSadaf Ebrahimi void LLVMFuzzerInit();
178*9a0e4156SSadaf Ebrahimi int LLVMFuzzerReturnOneInput(const uint8_t *Data, size_t Size, char * AssemblyText);
179*9a0e4156SSadaf Ebrahimi
LLVMFuzzerTestOneInput(const uint8_t * Data,size_t Size)180*9a0e4156SSadaf Ebrahimi int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
181*9a0e4156SSadaf Ebrahimi csh handle;
182*9a0e4156SSadaf Ebrahimi cs_insn *insn;
183*9a0e4156SSadaf Ebrahimi cs_err err;
184*9a0e4156SSadaf Ebrahimi const uint8_t **Datap = &Data;
185*9a0e4156SSadaf Ebrahimi size_t * Sizep = &Size;
186*9a0e4156SSadaf Ebrahimi uint64_t address = 0x1000;
187*9a0e4156SSadaf Ebrahimi char LLVMAssemblyText[80];
188*9a0e4156SSadaf Ebrahimi char CapstoneAssemblyText[80];
189*9a0e4156SSadaf Ebrahimi
190*9a0e4156SSadaf Ebrahimi if (Size < 1) {
191*9a0e4156SSadaf Ebrahimi // 1 byte for arch choice
192*9a0e4156SSadaf Ebrahimi return 0;
193*9a0e4156SSadaf Ebrahimi } else if (Size > 0x1000) {
194*9a0e4156SSadaf Ebrahimi //limit input to 4kb
195*9a0e4156SSadaf Ebrahimi Size = 0x1000;
196*9a0e4156SSadaf Ebrahimi }
197*9a0e4156SSadaf Ebrahimi if (outfile == NULL) {
198*9a0e4156SSadaf Ebrahimi // we compute the output
199*9a0e4156SSadaf Ebrahimi outfile = fopen("/dev/null", "w");
200*9a0e4156SSadaf Ebrahimi if (outfile == NULL) {
201*9a0e4156SSadaf Ebrahimi return 0;
202*9a0e4156SSadaf Ebrahimi }
203*9a0e4156SSadaf Ebrahimi LLVMFuzzerInit();
204*9a0e4156SSadaf Ebrahimi }
205*9a0e4156SSadaf Ebrahimi
206*9a0e4156SSadaf Ebrahimi if (Data[0] >= sizeof(platforms)/sizeof(platforms[0])) {
207*9a0e4156SSadaf Ebrahimi return 0;
208*9a0e4156SSadaf Ebrahimi }
209*9a0e4156SSadaf Ebrahimi
210*9a0e4156SSadaf Ebrahimi if (LLVMFuzzerReturnOneInput(Data, Size, LLVMAssemblyText) == 1) {
211*9a0e4156SSadaf Ebrahimi return 0;
212*9a0e4156SSadaf Ebrahimi }
213*9a0e4156SSadaf Ebrahimi
214*9a0e4156SSadaf Ebrahimi err = cs_open(platforms[Data[0]].arch, platforms[Data[0]].mode, &handle);
215*9a0e4156SSadaf Ebrahimi if (err) {
216*9a0e4156SSadaf Ebrahimi return 0;
217*9a0e4156SSadaf Ebrahimi }
218*9a0e4156SSadaf Ebrahimi
219*9a0e4156SSadaf Ebrahimi insn = cs_malloc(handle);
220*9a0e4156SSadaf Ebrahimi Data++;
221*9a0e4156SSadaf Ebrahimi Size--;
222*9a0e4156SSadaf Ebrahimi assert(insn);
223*9a0e4156SSadaf Ebrahimi if (cs_disasm_iter(handle, Datap, Sizep, &address, insn)) {
224*9a0e4156SSadaf Ebrahimi snprintf(CapstoneAssemblyText, 80, "\t%s\t%s", insn->mnemonic, insn->op_str);
225*9a0e4156SSadaf Ebrahimi if (strcmp(CapstoneAssemblyText, LLVMAssemblyText) != 0) {
226*9a0e4156SSadaf Ebrahimi printf("capstone %s != llvm %s", CapstoneAssemblyText, LLVMAssemblyText);
227*9a0e4156SSadaf Ebrahimi abort();
228*9a0e4156SSadaf Ebrahimi }
229*9a0e4156SSadaf Ebrahimi } else {
230*9a0e4156SSadaf Ebrahimi printf("capstone failed with llvm %s", LLVMAssemblyText);
231*9a0e4156SSadaf Ebrahimi abort();
232*9a0e4156SSadaf Ebrahimi }
233*9a0e4156SSadaf Ebrahimi cs_free(insn, 1);
234*9a0e4156SSadaf Ebrahimi cs_close(&handle);
235*9a0e4156SSadaf Ebrahimi
236*9a0e4156SSadaf Ebrahimi return 0;
237*9a0e4156SSadaf Ebrahimi }
238