Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(305)

Side by Side Diff: src/trusted/validator_ragel/decoder-test.c

Issue 9348082: Move unreviewed files to unreviewed subdirectory (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client/
Patch Set: Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/trusted/validator_ragel/decoder.h ('k') | src/trusted/validator_ragel/decoder-x86_32.rl » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2011 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
6
7 #include <assert.h>
8 #include <elf.h>
9 #include <inttypes.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include "decoder.h"
14
15 #undef TRUE
16 #define TRUE 1
17
18 #undef FALSE
19 #define FALSE 0
20
21 static void CheckBounds(unsigned char *data, size_t data_size,
22 void *ptr, size_t inside_size) {
23 assert(data <= (unsigned char *) ptr);
24 assert((unsigned char *) ptr + inside_size <= data + data_size);
25 }
26
27 void ReadFile(const char *filename, uint8_t **result, size_t *result_size) {
28 FILE *fp;
29 uint8_t *data;
30 size_t file_size;
31 size_t got;
32
33 fp = fopen(filename, "rb");
34 if (fp == NULL) {
35 fprintf(stderr, "Failed to open input file: %s\n", filename);
36 exit(1);
37 }
38 /* Find the file size. */
39 fseek(fp, 0, SEEK_END);
40 file_size = ftell(fp);
41 data = malloc(file_size);
42 if (data == NULL) {
43 fprintf(stderr, "Unable to create memory image of input file: %s\n",
44 filename);
45 exit(1);
46 }
47 fseek(fp, 0, SEEK_SET);
48 got = fread(data, 1, file_size, fp);
49 if (got != file_size) {
50 fprintf(stderr, "Unable to read data from input file: %s\n",
51 filename);
52 exit(1);
53 }
54 fclose(fp);
55
56 *result = data;
57 *result_size = file_size;
58 }
59
60 struct DecodeState {
61 uint8_t width;
62 const uint8_t *fwait; /* Set to true if fwait is detetected. */
63 const uint8_t *offset;
64 int ia32_mode;
65 };
66
67 void ProcessInstruction(const uint8_t *begin, const uint8_t *end,
68 struct instruction *instruction, void *userdata) {
69 const char *instruction_name;
70 unsigned char operands_count;
71 const uint8_t *p;
72 char delimeter = ' ';
73 int print_rip = FALSE;
74 int rex_bits = 0;
75 int maybe_rex_bits = 0;
76 int show_name_suffix = FALSE;
77 #define print_name(x) (printf((x)), shown_name += strlen((x)))
78 int shown_name = 0;
79 int i, operand_type;
80
81 /* "fwait" is nasty: any number of them will be included in other X87
82 instructions ("fclex", "finit", "fstcw", "fstsw", "fsave" have two
83 names, other instructions are unchanged) - but if after them we see
84 regular instruction then we must print all them. This convoluted
85 logic is not needed when we don't print anything so decoder does
86 not include it. */
87 if ((end == begin + 1) && (begin[0] == 0x9b)) {
88 if (!(((struct DecodeState *)userdata)->fwait)) {
89 ((struct DecodeState *)userdata)->fwait = begin;
90 }
91 return;
92 } else if (((struct DecodeState *)userdata)->fwait) {
93 if ((begin[0] < 0xd8) || (begin[0] > 0xdf)) {
94 while ((((struct DecodeState *)userdata)->fwait) < begin) {
95 printf("%*zx:\t \tfwait\n",
96 ((struct DecodeState *)userdata)->width,
97 ((((struct DecodeState *)userdata)->fwait++) -
98 (((struct DecodeState *)userdata)->offset)));
99 }
100 } else {
101 begin = ((struct DecodeState *)userdata)->fwait;
102 }
103 ((struct DecodeState *)userdata)->fwait = FALSE;
104 }
105 printf("%*zx:\t", ((struct DecodeState *)userdata)->width,
106 (begin - (((struct DecodeState *)userdata)->offset)));
107 for (p = begin; p < begin + 7; ++p) {
108 if (p >= end) {
109 printf(" ");
110 } else {
111 printf("%02x ", *p);
112 }
113 }
114 printf("\t");
115 instruction_name = instruction->name;
116 operands_count = instruction->operands_count;
117 /* "cmppd" has two-operand mnemonic names for "imm8" equal to 0x0, ...0x7. */
118 if (!strcmp(instruction_name, "cmppd")) {
119 if (instruction->imm[0] < 0x08) {
120 switch (instruction->imm[0]) {
121 case 0x00: instruction_name = "cmpeqpd"; break;
122 case 0x01: instruction_name = "cmpltpd"; break;
123 case 0x02: instruction_name = "cmplepd"; break;
124 case 0x03: instruction_name = "cmpunordpd"; break;
125 case 0x04: instruction_name = "cmpneqpd"; break;
126 case 0x05: instruction_name = "cmpnltpd"; break;
127 case 0x06: instruction_name = "cmpnlepd"; break;
128 case 0x07: instruction_name = "cmpordpd"; break;
129 }
130 --operands_count;
131 }
132 }
133 /* "vcmppd" has two-operand mnemonic names for "imm8"
134 * equal to 0x0, ... 0x1f. */
135 if (!strcmp(instruction_name, "vcmppd")) {
136 if (instruction->imm[0] < 0x20) {
137 switch (instruction->imm[0]) {
138 case 0x00: instruction_name = "vcmpeqpd"; break;
139 case 0x01: instruction_name = "vcmpltpd"; break;
140 case 0x02: instruction_name = "vcmplepd"; break;
141 case 0x03: instruction_name = "vcmpunordpd"; break;
142 case 0x04: instruction_name = "vcmpneqpd"; break;
143 case 0x05: instruction_name = "vcmpnltpd"; break;
144 case 0x06: instruction_name = "vcmpnlepd"; break;
145 case 0x07: instruction_name = "vcmpordpd"; break;
146 case 0x08: instruction_name = "vcmpeq_uqpd"; break;
147 case 0x09: instruction_name = "vcmpngepd"; break;
148 case 0x0a: instruction_name = "vcmpngtpd"; break;
149 case 0x0b: instruction_name = "vcmpfalsepd"; break;
150 case 0x0c: instruction_name = "vcmpneq_oqpd"; break;
151 case 0x0d: instruction_name = "vcmpgepd"; break;
152 case 0x0e: instruction_name = "vcmpgtpd"; break;
153 case 0x0f: instruction_name = "vcmptruepd"; break;
154 case 0x10: instruction_name = "vcmpeq_ospd"; break;
155 case 0x11: instruction_name = "vcmplt_oqpd"; break;
156 case 0x12: instruction_name = "vcmple_oqpd"; break;
157 case 0x13: instruction_name = "vcmpunord_spd"; break;
158 case 0x14: instruction_name = "vcmpneq_uspd"; break;
159 case 0x15: instruction_name = "vcmpnlt_uqpd"; break;
160 case 0x16: instruction_name = "vcmpnle_uqpd"; break;
161 case 0x17: instruction_name = "vcmpord_spd"; break;
162 case 0x18: instruction_name = "vcmpeq_uspd"; break;
163 case 0x19: instruction_name = "vcmpnge_uqpd"; break;
164 case 0x1a: instruction_name = "vcmpngt_uqpd"; break;
165 case 0x1b: instruction_name = "vcmpfalse_ospd"; break;
166 case 0x1c: instruction_name = "vcmpneq_ospd"; break;
167 case 0x1d: instruction_name = "vcmpge_oqpd"; break;
168 case 0x1e: instruction_name = "vcmpgt_oqpd"; break;
169 case 0x1f: instruction_name = "vcmptrue_uspd"; break;
170 }
171 --operands_count;
172 }
173 }
174 /* "cmpps" has two-operand mnemonic names for "imm8" equal to 0x0, ... 0x7. */
175 if (!strcmp(instruction_name, "cmpps")) {
176 if (instruction->imm[0] < 0x08) {
177 switch (instruction->imm[0]) {
178 case 0x00: instruction_name = "cmpeqps"; break;
179 case 0x01: instruction_name = "cmpltps"; break;
180 case 0x02: instruction_name = "cmpleps"; break;
181 case 0x03: instruction_name = "cmpunordps"; break;
182 case 0x04: instruction_name = "cmpneqps"; break;
183 case 0x05: instruction_name = "cmpnltps"; break;
184 case 0x06: instruction_name = "cmpnleps"; break;
185 case 0x07: instruction_name = "cmpordps"; break;
186 }
187 --operands_count;
188 }
189 }
190 /* "vcmpps" has two-operand mnemonic names for "imm8" equal to 0x0, ...0x1f. * /
191 if (!strcmp(instruction_name, "vcmpps")) {
192 if (instruction->imm[0] < 0x20) {
193 switch (instruction->imm[0]) {
194 case 0x00: instruction_name = "vcmpeqps"; break;
195 case 0x01: instruction_name = "vcmpltps"; break;
196 case 0x02: instruction_name = "vcmpleps"; break;
197 case 0x03: instruction_name = "vcmpunordps"; break;
198 case 0x04: instruction_name = "vcmpneqps"; break;
199 case 0x05: instruction_name = "vcmpnltps"; break;
200 case 0x06: instruction_name = "vcmpnleps"; break;
201 case 0x07: instruction_name = "vcmpordps"; break;
202 case 0x08: instruction_name = "vcmpeq_uqps"; break;
203 case 0x09: instruction_name = "vcmpngeps"; break;
204 case 0x0a: instruction_name = "vcmpngtps"; break;
205 case 0x0b: instruction_name = "vcmpfalseps"; break;
206 case 0x0c: instruction_name = "vcmpneq_oqps"; break;
207 case 0x0d: instruction_name = "vcmpgeps"; break;
208 case 0x0e: instruction_name = "vcmpgtps"; break;
209 case 0x0f: instruction_name = "vcmptrueps"; break;
210 case 0x10: instruction_name = "vcmpeq_osps"; break;
211 case 0x11: instruction_name = "vcmplt_oqps"; break;
212 case 0x12: instruction_name = "vcmple_oqps"; break;
213 case 0x13: instruction_name = "vcmpunord_sps"; break;
214 case 0x14: instruction_name = "vcmpneq_usps"; break;
215 case 0x15: instruction_name = "vcmpnlt_uqps"; break;
216 case 0x16: instruction_name = "vcmpnle_uqps"; break;
217 case 0x17: instruction_name = "vcmpord_sps"; break;
218 case 0x18: instruction_name = "vcmpeq_usps"; break;
219 case 0x19: instruction_name = "vcmpnge_uqps"; break;
220 case 0x1a: instruction_name = "vcmpngt_uqps"; break;
221 case 0x1b: instruction_name = "vcmpfalse_osps"; break;
222 case 0x1c: instruction_name = "vcmpneq_osps"; break;
223 case 0x1d: instruction_name = "vcmpge_oqps"; break;
224 case 0x1e: instruction_name = "vcmpgt_oqps"; break;
225 case 0x1f: instruction_name = "vcmptrue_usps"; break;
226 }
227 --operands_count;
228 }
229 }
230 /* "cmpsd" has two-operand mnemonic names for "imm8" equal to 0x0, ...0x7. */
231 if (!strcmp(instruction_name, "cmpsd")) {
232 if (instruction->imm[0] < 0x08) {
233 switch (instruction->imm[0]) {
234 case 0x00: instruction_name = "cmpeqsd"; break;
235 case 0x01: instruction_name = "cmpltsd"; break;
236 case 0x02: instruction_name = "cmplesd"; break;
237 case 0x03: instruction_name = "cmpunordsd"; break;
238 case 0x04: instruction_name = "cmpneqsd"; break;
239 case 0x05: instruction_name = "cmpnltsd"; break;
240 case 0x06: instruction_name = "cmpnlesd"; break;
241 case 0x07: instruction_name = "cmpordsd"; break;
242 }
243 --operands_count;
244 }
245 }
246 /* "vcmpsd" has two-operand mnemonic names for "imm8" equal to 0x0, ...0x1f. * /
247 if (!strcmp(instruction_name, "vcmpsd")) {
248 if (instruction->imm[0] < 0x20) {
249 switch (instruction->imm[0]) {
250 case 0x00: instruction_name = "vcmpeqsd"; break;
251 case 0x01: instruction_name = "vcmpltsd"; break;
252 case 0x02: instruction_name = "vcmplesd"; break;
253 case 0x03: instruction_name = "vcmpunordsd"; break;
254 case 0x04: instruction_name = "vcmpneqsd"; break;
255 case 0x05: instruction_name = "vcmpnltsd"; break;
256 case 0x06: instruction_name = "vcmpnlesd"; break;
257 case 0x07: instruction_name = "vcmpordsd"; break;
258 case 0x08: instruction_name = "vcmpeq_uqsd"; break;
259 case 0x09: instruction_name = "vcmpngesd"; break;
260 case 0x0a: instruction_name = "vcmpngtsd"; break;
261 case 0x0b: instruction_name = "vcmpfalsesd"; break;
262 case 0x0c: instruction_name = "vcmpneq_oqsd"; break;
263 case 0x0d: instruction_name = "vcmpgesd"; break;
264 case 0x0e: instruction_name = "vcmpgtsd"; break;
265 case 0x0f: instruction_name = "vcmptruesd"; break;
266 case 0x10: instruction_name = "vcmpeq_ossd"; break;
267 case 0x11: instruction_name = "vcmplt_oqsd"; break;
268 case 0x12: instruction_name = "vcmple_oqsd"; break;
269 case 0x13: instruction_name = "vcmpunord_ssd"; break;
270 case 0x14: instruction_name = "vcmpneq_ussd"; break;
271 case 0x15: instruction_name = "vcmpnlt_uqsd"; break;
272 case 0x16: instruction_name = "vcmpnle_uqsd"; break;
273 case 0x17: instruction_name = "vcmpord_ssd"; break;
274 case 0x18: instruction_name = "vcmpeq_ussd"; break;
275 case 0x19: instruction_name = "vcmpnge_uqsd"; break;
276 case 0x1a: instruction_name = "vcmpngt_uqsd"; break;
277 case 0x1b: instruction_name = "vcmpfalse_ossd"; break;
278 case 0x1c: instruction_name = "vcmpneq_ossd"; break;
279 case 0x1d: instruction_name = "vcmpge_oqsd"; break;
280 case 0x1e: instruction_name = "vcmpgt_oqsd"; break;
281 case 0x1f: instruction_name = "vcmptrue_ussd"; break;
282 }
283 --operands_count;
284 }
285 }
286 /* "cmpss" has two-operand mnemonic names for "imm8" equal to 0x0, ... 0x7. */
287 if (!strcmp(instruction_name, "cmpss")) {
288 if (instruction->imm[0] < 0x08) {
289 switch (instruction->imm[0]) {
290 case 0x00: instruction_name = "cmpeqss"; break;
291 case 0x01: instruction_name = "cmpltss"; break;
292 case 0x02: instruction_name = "cmpless"; break;
293 case 0x03: instruction_name = "cmpunordss"; break;
294 case 0x04: instruction_name = "cmpneqss"; break;
295 case 0x05: instruction_name = "cmpnltss"; break;
296 case 0x06: instruction_name = "cmpnless"; break;
297 case 0x07: instruction_name = "cmpordss"; break;
298 }
299 --operands_count;
300 }
301 }
302 /* "vcmpss" has two-operand mnemonic names for "imm8" equal to 0x0, ...0x1f. * /
303 if (!strcmp(instruction_name, "vcmpss")) {
304 if (instruction->imm[0] < 0x20) {
305 switch (instruction->imm[0]) {
306 case 0x00: instruction_name = "vcmpeqss"; break;
307 case 0x01: instruction_name = "vcmpltss"; break;
308 case 0x02: instruction_name = "vcmpless"; break;
309 case 0x03: instruction_name = "vcmpunordss"; break;
310 case 0x04: instruction_name = "vcmpneqss"; break;
311 case 0x05: instruction_name = "vcmpnltss"; break;
312 case 0x06: instruction_name = "vcmpnless"; break;
313 case 0x07: instruction_name = "vcmpordss"; break;
314 case 0x08: instruction_name = "vcmpeq_uqss"; break;
315 case 0x09: instruction_name = "vcmpngess"; break;
316 case 0x0a: instruction_name = "vcmpngtss"; break;
317 case 0x0b: instruction_name = "vcmpfalsess"; break;
318 case 0x0c: instruction_name = "vcmpneq_oqss"; break;
319 case 0x0d: instruction_name = "vcmpgess"; break;
320 case 0x0e: instruction_name = "vcmpgtss"; break;
321 case 0x0f: instruction_name = "vcmptruess"; break;
322 case 0x10: instruction_name = "vcmpeq_osss"; break;
323 case 0x11: instruction_name = "vcmplt_oqss"; break;
324 case 0x12: instruction_name = "vcmple_oqss"; break;
325 case 0x13: instruction_name = "vcmpunord_sss"; break;
326 case 0x14: instruction_name = "vcmpneq_usss"; break;
327 case 0x15: instruction_name = "vcmpnlt_uqss"; break;
328 case 0x16: instruction_name = "vcmpnle_uqss"; break;
329 case 0x17: instruction_name = "vcmpord_sss"; break;
330 case 0x18: instruction_name = "vcmpeq_usss"; break;
331 case 0x19: instruction_name = "vcmpnge_uqss"; break;
332 case 0x1a: instruction_name = "vcmpngt_uqss"; break;
333 case 0x1b: instruction_name = "vcmpfalse_osss"; break;
334 case 0x1c: instruction_name = "vcmpneq_osss"; break;
335 case 0x1d: instruction_name = "vcmpge_oqss"; break;
336 case 0x1e: instruction_name = "vcmpgt_oqss"; break;
337 case 0x1f: instruction_name = "vcmptrue_usss"; break;
338 }
339 --operands_count;
340 }
341 }
342 /* "pclmulqdq" has two-operand mnemonic names for "imm8"
343 * equal to 0x0, ... 0x3. */
344 if (!strcmp(instruction_name, "pclmulqdq")) {
345 if (instruction->imm[0] < 0x04) {
346 switch (instruction->imm[0]) {
347 case 0x00: instruction_name = "pclmullqlqdq"; break;
348 case 0x01: instruction_name = "pclmulhqlqdq"; break;
349 case 0x02: instruction_name = "pclmullqhqdq"; break;
350 case 0x03: instruction_name = "pclmulhqhqdq"; break;
351 }
352 --operands_count;
353 }
354 }
355 /* "vpclmulqdq" has two-operand mnemonic names for "imm8"
356 * equal to 0x0, ... 0x3. */
357 if (!strcmp(instruction_name, "vpclmulqdq")) {
358 if (instruction->imm[0] < 0x04) {
359 switch (instruction->imm[0]) {
360 case 0x00: instruction_name = "vpclmullqlqdq"; break;
361 case 0x01: instruction_name = "vpclmulhqlqdq"; break;
362 case 0x02: instruction_name = "vpclmullqhqdq"; break;
363 case 0x03: instruction_name = "vpclmulhqhqdq"; break;
364 }
365 --operands_count;
366 }
367 }
368 if (operands_count > 0) {
369 show_name_suffix = TRUE;
370 for (i=operands_count-1; i>=0; --i) {
371 if (instruction->operands[i].name == JMP_TO) {
372 /* Most control flow instructions never use suffixes, but "call" and
373 "jmp" do... unless byte offset is used. */
374 if ((!strcmp(instruction_name, "call")) ||
375 (!strcmp(instruction_name, "jmp"))) {
376 switch (instruction->operands[i].type) {
377 case OperandSize8bit: show_name_suffix = FALSE; break;
378 case OperandSize16bit: show_name_suffix = 'w'; break;
379 case OperandSize32bit:
380 if (((struct DecodeState *)userdata)->ia32_mode) {
381 show_name_suffix = FALSE;
382 } else {
383 show_name_suffix = 'q';
384 }
385 break;
386 case OperandSize2bit:
387 case OperandSize64bit:
388 case OperandSize128bit:
389 case OperandSize256bit:
390 case OperandFloatSize16bit:
391 case OperandFloatSize32bit:
392 case OperandFloatSize64bit:
393 case OperandFloatSize80bit:
394 case OperandX87Size16bit:
395 case OperandX87Size32bit:
396 case OperandX87Size64bit:
397 case OperandX87BCD:
398 case OperandX87ENV:
399 case OperandX87STATE:
400 case OperandX87MMXXMMSTATE:
401 case OperandST:
402 case OperandSelector:
403 case OperandFarPtr:
404 case OperandSegmentRegister:
405 case OperandControlRegister:
406 case OperandDebugRegister:
407 case OperandMMX:
408 case OperandXMM:
409 case OperandYMM:
410 assert(FALSE);
411 }
412 } else {
413 show_name_suffix = FALSE;
414 }
415 } else if ((instruction->operands[i].name == REG_IMM) ||
416 (instruction->operands[i].name == REG_IMM2) ||
417 (instruction->operands[i].name == REG_RM) ||
418 (instruction->operands[i].name == REG_PORT_DX) ||
419 (instruction->operands[i].name == REG_ES_RDI) ||
420 (instruction->operands[i].name == REG_DS_RSI)) {
421 if (show_name_suffix) {
422 switch (instruction->operands[i].type) {
423 case OperandSize8bit: show_name_suffix = 'b'; break;
424 case OperandSize16bit: show_name_suffix = 'w'; break;
425 case OperandSize32bit: show_name_suffix = 'l'; break;
426 case OperandSize64bit: show_name_suffix = 'q'; break;
427 case OperandFloatSize32bit: show_name_suffix = 's'; break;
428 case OperandFloatSize64bit: show_name_suffix = 'l'; break;
429 case OperandFloatSize80bit:show_name_suffix = 't'; break;
430 case OperandX87Size32bit: show_name_suffix = 'l'; break;
431 case OperandX87Size64bit: show_name_suffix = 'L'; break;
432 case OperandSize2bit:
433 case OperandX87Size16bit:
434 case OperandX87BCD:
435 case OperandX87ENV:
436 case OperandX87STATE:
437 case OperandX87MMXXMMSTATE:
438 case OperandSize128bit:
439 case OperandSize256bit:
440 case OperandFarPtr:
441 case OperandMMX:
442 case OperandXMM:
443 case OperandYMM:
444 case OperandSelector: show_name_suffix = FALSE; break;
445 case OperandFloatSize16bit:
446 case OperandST:
447 case OperandSegmentRegister:
448 case OperandControlRegister:
449 case OperandDebugRegister:
450 assert(FALSE);
451 }
452 }
453 } else {
454 /* First argument of "rcl"/"rcr"/"rol"/"ror"/"sar/""shl"/"shr"
455 can not be used to determine size of command. */
456 if (((i != 1) || (strcmp(instruction_name, "rcl") &&
457 strcmp(instruction_name, "rcr") &&
458 strcmp(instruction_name, "rol") &&
459 strcmp(instruction_name, "ror") &&
460 strcmp(instruction_name, "sal") &&
461 strcmp(instruction_name, "sar") &&
462 strcmp(instruction_name, "shl") &&
463 strcmp(instruction_name, "shr"))) &&
464 /* Second argument of "crc32" can not be used to determine size of
465 command. */
466 ((i != 0) || strcmp(instruction_name, "crc32"))) {
467 show_name_suffix = FALSE;
468 }
469 /* First argument of "crc32" can be used for that but objdump uses
470 suffix anyway. */
471 if ((i == 1) && (!strcmp(instruction_name, "crc32"))) {
472 switch (instruction->operands[i].type) {
473 case OperandSize8bit: show_name_suffix = 'b'; break;
474 case OperandSize16bit: show_name_suffix = 'w'; break;
475 case OperandSize32bit: show_name_suffix = 'l'; break;
476 case OperandSize64bit: show_name_suffix = 'q'; break;
477 case OperandSize2bit:
478 case OperandSize128bit:
479 case OperandSize256bit:
480 case OperandFloatSize16bit:
481 case OperandFloatSize32bit:
482 case OperandFloatSize64bit:
483 case OperandFloatSize80bit:
484 case OperandX87Size16bit:
485 case OperandX87Size32bit:
486 case OperandX87Size64bit:
487 case OperandX87BCD:
488 case OperandX87ENV:
489 case OperandX87STATE:
490 case OperandX87MMXXMMSTATE:
491 case OperandST:
492 case OperandSelector:
493 case OperandFarPtr:
494 case OperandSegmentRegister:
495 case OperandControlRegister:
496 case OperandDebugRegister:
497 case OperandMMX:
498 case OperandXMM:
499 case OperandYMM:
500 assert(FALSE);
501 }
502 }
503 }
504 if ((instruction->operands[i].name >= REG_R8) &&
505 (instruction->operands[i].name <= REG_R15) &&
506 (instruction->operands[i].type != OperandMMX)) {
507 if (!((struct DecodeState *)userdata)->ia32_mode) {
508 ++rex_bits;
509 /* HACK: objdump mistakenly allows "lock" with "mov %crX,%rXX" only in
510 32bit mode. It's perfectly valid in 64bit mode, too, so instead of
511 changing the decoder we fix it here. */
512 if (instruction->operands[i].type == OperandControlRegister) {
513 if ((*begin == 0xf0) && !(instruction->prefix.lock)) {
514 print_name("lock ");
515 if (!(instruction->prefix.rex & 0x04)) {
516 instruction->operands[i].name -= 8;
517 --rex_bits;
518 }
519 }
520 }
521 }
522 } else if (instruction->operands[i].name == REG_RM) {
523 if ((instruction->rm.base >= REG_R8) &&
524 (instruction->rm.base <= REG_R15)) {
525 ++rex_bits;
526 } else if ((instruction->rm.base == REG_NONE) ||
527 (instruction->rm.base == REG_RIP)) {
528 ++maybe_rex_bits;
529 }
530 if ((instruction->rm.index >= REG_R8) &&
531 (instruction->rm.index <= REG_R15)) {
532 ++rex_bits;
533 }
534 }
535 }
536 }
537 if ((!strcmp(instruction_name, "cvtsi2sd") ||
538 !strcmp(instruction_name, "cvtsi2ss")) &&
539 instruction->operands[1].name == REG_RM) {
540 if (instruction->operands[1].type == OperandSize32bit) {
541 show_name_suffix = 'l';
542 } else {
543 show_name_suffix = 'q';
544 }
545 }
546 if ((!strcmp(instruction_name, "vcvtpd2dq") ||
547 !strcmp(instruction_name, "vcvtpd2ps") ||
548 !strcmp(instruction_name, "vcvttpd2dq") ||
549 !strcmp(instruction_name, "vcvttpd2ps")) &&
550 instruction->operands[1].name == REG_RM) {
551 if (instruction->operands[1].type == OperandXMM) {
552 show_name_suffix = 'x';
553 } else {
554 show_name_suffix = 'y';
555 }
556 }
557 if ((!strcmp(instruction_name, "vcvtsi2sd") ||
558 !strcmp(instruction_name, "vcvtsi2ss")) &&
559 instruction->operands[2].name == REG_RM) {
560 if (instruction->operands[2].type == OperandSize32bit) {
561 show_name_suffix = 'l';
562 } else {
563 show_name_suffix = 'q';
564 }
565 }
566 if (instruction->prefix.lock) {
567 print_name("lock ");
568 }
569 if (instruction->prefix.repnz) {
570 print_name("repnz ");
571 }
572 if (instruction->prefix.repz) {
573 /* This prefix is "rep" for "ins", "movs", and "outs", "repz" otherwise. */
574 if ((!strcmp(instruction_name, "ins")) ||
575 (!strcmp(instruction_name, "movs")) ||
576 (!strcmp(instruction_name, "outs")) ||
577 (!strcmp(instruction_name, "stos"))) {
578 print_name("rep ");
579 } else {
580 print_name("repz ");
581 }
582 }
583 if (instruction->prefix.rex == 0x40) {
584 /* First argument of "crc32"/"rcl"/"rcr"/"rol"/"ror"/"sar"/"shl"/"shr"
585 confuses objdump: it does not show it in this case. */
586 if ((show_name_suffix ||
587 !strcmp(instruction_name, "movsbl") ||
588 !strcmp(instruction_name, "movsbw") ||
589 !strcmp(instruction_name, "movzbl") ||
590 !strcmp(instruction_name, "movzbw") ||
591 !strcmp(instruction_name, "pextrb") ||
592 !strcmp(instruction_name, "pinsrb")) &&
593 ((strcmp(instruction_name, "crc32") &&
594 strcmp(instruction_name, "movsbl") &&
595 strcmp(instruction_name, "movsbw") &&
596 strcmp(instruction_name, "movzbl") &&
597 strcmp(instruction_name, "movzbw") &&
598 strcmp(instruction_name, "rcl") &&
599 strcmp(instruction_name, "rcr") &&
600 strcmp(instruction_name, "rol") &&
601 strcmp(instruction_name, "ror") &&
602 strcmp(instruction_name, "sal") &&
603 strcmp(instruction_name, "sar") &&
604 strcmp(instruction_name, "shl") &&
605 strcmp(instruction_name, "shr")) ||
606 (instruction->operands[1].name > REG_R15))) {
607 print_name("rex ");
608 }
609 }
610 if ((instruction->prefix.rex & 0x08) == 0x08) {
611 /* rex.W is ignored by "in"/"out", and "pop"/"push" commands. */
612 if ((!strcmp(instruction_name, "in")) ||
613 (!strcmp(instruction_name, "ins")) ||
614 (!strcmp(instruction_name, "out")) ||
615 (!strcmp(instruction_name, "outs")) ||
616 (!strcmp(instruction_name, "pop")) ||
617 (!strcmp(instruction_name, "push"))) {
618 rex_bits = -1;
619 }
620 }
621 if (show_name_suffix == 'b') {
622 /* "cflush", "int", "invlpg", "prefetch*", and "setcc" never use suffix. */
623 if ((!strcmp(instruction_name, "clflush")) ||
624 (!strcmp(instruction_name, "int")) ||
625 (!strcmp(instruction_name, "invlpg")) ||
626 (!strcmp(instruction_name, "prefetch")) ||
627 (!strcmp(instruction_name, "prefetchnta")) ||
628 (!strcmp(instruction_name, "prefetcht0")) ||
629 (!strcmp(instruction_name, "prefetcht1")) ||
630 (!strcmp(instruction_name, "prefetcht2")) ||
631 (!strcmp(instruction_name, "prefetchw")) ||
632 (!strcmp(instruction_name, "seta")) ||
633 (!strcmp(instruction_name, "setae")) ||
634 (!strcmp(instruction_name, "setbe")) ||
635 (!strcmp(instruction_name, "setb")) ||
636 (!strcmp(instruction_name, "sete")) ||
637 (!strcmp(instruction_name, "setg")) ||
638 (!strcmp(instruction_name, "setge")) ||
639 (!strcmp(instruction_name, "setle")) ||
640 (!strcmp(instruction_name, "setl")) ||
641 (!strcmp(instruction_name, "setne")) ||
642 (!strcmp(instruction_name, "setno")) ||
643 (!strcmp(instruction_name, "setnp")) ||
644 (!strcmp(instruction_name, "setns")) ||
645 (!strcmp(instruction_name, "seto")) ||
646 (!strcmp(instruction_name, "setp")) ||
647 (!strcmp(instruction_name, "sets"))) {
648 show_name_suffix = FALSE;
649 /* Instruction enter accepts two immediates: word and byte. But
650 objdump always uses suffix "q". This is supremely strange, but
651 we want to match objdump exactly, so... here goes. */
652 } else if (!strcmp(instruction_name, "enter")) {
653 if (((struct DecodeState *)userdata)->ia32_mode) {
654 show_name_suffix = FALSE;
655 } else {
656 show_name_suffix = 'q';
657 }
658 }
659 }
660 if ((show_name_suffix == 'b') || (show_name_suffix == 'l')) {
661 /* objdump always shows "6a 01" as "pushq $1", "66 68 01 00" as
662 "pushw $1" yet "68 01 00 00 00" as "pushq $1" again. This makes no
663 sense whatsoever so we'll just hack around here to make sure we
664 produce objdump-compatible output. */
665 if (!strcmp(instruction_name, "push")) {
666 if (((struct DecodeState *)userdata)->ia32_mode) {
667 if (instruction->operands[0].name != REG_RM) {
668 show_name_suffix = FALSE;
669 }
670 } else {
671 show_name_suffix = 'q';
672 }
673 }
674 }
675 if (show_name_suffix == 'w') {
676 /* "lldt", "[ls]msw", "lret", "ltr", and "ver[rw]" newer use suffixes at
677 all. */
678 if ((!strcmp(instruction_name, "lldt")) ||
679 (!strcmp(instruction_name, "lmsw")) ||
680 (!strcmp(instruction_name, "lret")) ||
681 (!strcmp(instruction_name, "ltr")) ||
682 (!strcmp(instruction_name, "smsw")) ||
683 (!strcmp(instruction_name, "verr")) ||
684 (!strcmp(instruction_name, "verw"))) {
685 show_name_suffix = FALSE;
686 /* "callw"/"jmpw" already includes suffix in the nanme. */
687 } else if ((!strcmp(instruction_name, "callw")) ||
688 (!strcmp(instruction_name, "jmpw"))) {
689 show_name_suffix = FALSE;
690 /* "ret" always uses suffix "q" no matter what. */
691 } else if (!strcmp(instruction_name, "ret")) {
692 if (((struct DecodeState *)userdata)->ia32_mode) {
693 show_name_suffix = FALSE;
694 } else {
695 show_name_suffix = 'q';
696 }
697 }
698 }
699 if ((show_name_suffix == 'w') || (show_name_suffix == 'l')) {
700 /* "sldt" and "str" newer uses suffixes at all. */
701 if ((!strcmp(instruction_name, "sldt")) ||
702 (!strcmp(instruction_name, "str"))) {
703 show_name_suffix = FALSE;
704 }
705 }
706 if (show_name_suffix == 'l') {
707 /* “calll”/“jmpl” do not exist, only “call” do. */
708 if (((struct DecodeState *)userdata)->ia32_mode &&
709 (!strcmp(instruction_name, "call") ||
710 !strcmp(instruction_name, "jmp"))) {
711 show_name_suffix = FALSE;
712 /* “popl” does not exist, only “popq” do. */
713 } else if (!((struct DecodeState *)userdata)->ia32_mode &&
714 !strcmp(instruction_name, "pop")) {
715 show_name_suffix = 'q';
716 } else if (!strcmp(instruction_name, "ldmxcsr") ||
717 !strcmp(instruction_name, "stmxcsr") ||
718 !strcmp(instruction_name, "vldmxcsr") ||
719 !strcmp(instruction_name, "vstmxcsr")) {
720 show_name_suffix = FALSE;
721 }
722 }
723 if (show_name_suffix == 'q') {
724 /* "callq","cmpxchg8b"/"jmpq" already include suffix in the nanme. */
725 if ((!strcmp(instruction_name, "callq")) ||
726 (!strcmp(instruction_name, "cmpxchg8b")) ||
727 (!strcmp(instruction_name, "jmpq"))) {
728 show_name_suffix = FALSE;
729 }
730 }
731 i = (instruction->prefix.rex & 0x01) +
732 ((instruction->prefix.rex & 0x02) >> 1) +
733 ((instruction->prefix.rex & 0x04) >> 2);
734 if (instruction->prefix.rex &&
735 !((i == rex_bits) ||
736 (maybe_rex_bits &&
737 (instruction->prefix.rex & 0x01) && (i == rex_bits + 1)))) {
738 print_name("rex.");
739 if (instruction->prefix.rex & 0x08) {
740 print_name("W");
741 }
742 if (instruction->prefix.rex & 0x04) {
743 print_name("R");
744 }
745 if (instruction->prefix.rex & 0x02) {
746 print_name("X");
747 }
748 if (instruction->prefix.rex & 0x01) {
749 print_name("B");
750 }
751 print_name(" ");
752 }
753 printf("%s", instruction_name);
754 shown_name += strlen(instruction_name);
755 if (show_name_suffix) {
756 if (show_name_suffix == 'L') {
757 print_name("ll");
758 } else {
759 printf("%c", show_name_suffix);
760 ++shown_name;
761 }
762 }
763 if (!strcmp(instruction_name, "mov")) {
764 if ((instruction->operands[1].name == REG_IMM) &&
765 (instruction->operands[1].type == OperandSize64bit)) {
766 print_name("abs");
767 }
768 }
769 #undef print_name
770 if ((strcmp(instruction_name, "nop") || operands_count != 0) &&
771 strcmp(instruction_name, "fwait") &&
772 strcmp(instruction_name, "pop %fs") &&
773 strcmp(instruction_name, "pop %gs") &&
774 strcmp(instruction_name, "popq %fs") &&
775 strcmp(instruction_name, "popq %gs") &&
776 strcmp(instruction_name, "push %fs") &&
777 strcmp(instruction_name, "push %gs") &&
778 strcmp(instruction_name, "pushq %fs") &&
779 strcmp(instruction_name, "pushq %gs")) {
780 while (shown_name < 6) {
781 printf(" ");
782 ++shown_name;
783 }
784 if (operands_count == 0) {
785 printf(" ");
786 }
787 }
788 for (i=operands_count-1; i>=0; --i) {
789 printf("%c", delimeter);
790 if ((!strcmp(instruction_name, "call")) ||
791 (!strcmp(instruction_name, "jmp")) ||
792 (!strcmp(instruction_name, "lcall")) ||
793 (!strcmp(instruction_name, "ljmp"))) {
794 if (instruction->operands[i].name != JMP_TO) {
795 printf("*");
796 }
797 } else if ((!strcmp(instruction_name, "callw")) ||
798 (!strcmp(instruction_name, "callq")) ||
799 (!strcmp(instruction_name, "jmpw")) ||
800 (!strcmp(instruction_name, "jmpq")) ||
801 (!strcmp(instruction_name, "ljmpw")) ||
802 (!strcmp(instruction_name, "ljmpq")) ||
803 (!strcmp(instruction_name, "lcallw")) ||
804 (!strcmp(instruction_name, "lcallq"))) {
805 printf("*");
806 }
807 /* Dirty hack: both AMD manual and Intel manual agree that mov from general
808 purpose register to segment register has signature "mov Ew Sw", but
809 objdump insist on 32bit. This is clearly error in objdump so we fix it
810 here and not in decoder. */
811 if (((begin[0] == 0x8e) ||
812 ((begin[0] >= 0x40) && (begin[0] <= 0x4f) && (begin[1] == 0x8e))) &&
813 (instruction->operands[i].type == OperandSize16bit)) {
814 operand_type = OperandSize32bit;
815 } else {
816 operand_type = instruction->operands[i].type;
817 }
818 switch (instruction->operands[i].name) {
819 case REG_RAX: switch (operand_type) {
820 case OperandSize8bit: printf("%%al"); break;
821 case OperandSize16bit: printf("%%ax"); break;
822 case OperandSize32bit: printf("%%eax"); break;
823 case OperandSize64bit: printf("%%rax"); break;
824 case OperandST: printf("%%st(0)"); break;
825 case OperandMMX: printf("%%mm0"); break;
826 case OperandFloatSize32bit:
827 case OperandFloatSize64bit:
828 case OperandSize128bit:
829 case OperandXMM: printf("%%xmm0"); break;
830 case OperandSize256bit:
831 case OperandYMM: printf("%%ymm0"); break;
832 case OperandSegmentRegister: printf("%%es"); break;
833 case OperandControlRegister: printf("%%cr0"); break;
834 case OperandDebugRegister: printf("%%db0"); break;
835 default: assert(FALSE);
836 }
837 break;
838 case REG_RCX: switch (operand_type) {
839 case OperandSize8bit: printf("%%cl"); break;
840 case OperandSize16bit: printf("%%cx"); break;
841 case OperandSize32bit: printf("%%ecx"); break;
842 case OperandSize64bit: printf("%%rcx"); break;
843 case OperandST: printf("%%st(1)"); break;
844 case OperandMMX: printf("%%mm1"); break;
845 case OperandFloatSize32bit:
846 case OperandFloatSize64bit:
847 case OperandSize128bit:
848 case OperandXMM: printf("%%xmm1"); break;
849 case OperandSize256bit:
850 case OperandYMM: printf("%%ymm1"); break;
851 case OperandSegmentRegister: printf("%%cs"); break;
852 case OperandControlRegister: printf("%%cr1"); break;
853 case OperandDebugRegister: printf("%%db1"); break;
854 default: assert(FALSE);
855 }
856 break;
857 case REG_RDX: switch (operand_type) {
858 case OperandSize8bit: printf("%%dl"); break;
859 case OperandSize16bit: printf("%%dx"); break;
860 case OperandSize32bit: printf("%%edx"); break;
861 case OperandSize64bit: printf("%%rdx"); break;
862 case OperandST: printf("%%st(2)"); break;
863 case OperandMMX: printf("%%mm2"); break;
864 case OperandFloatSize32bit:
865 case OperandFloatSize64bit:
866 case OperandSize128bit:
867 case OperandXMM: printf("%%xmm2"); break;
868 case OperandSize256bit:
869 case OperandYMM: printf("%%ymm2"); break;
870 case OperandSegmentRegister: printf("%%ss"); break;
871 case OperandControlRegister: printf("%%cr2"); break;
872 case OperandDebugRegister: printf("%%db2"); break;
873 default: assert(FALSE);
874 }
875 break;
876 case REG_RBX: switch (operand_type) {
877 case OperandSize8bit: printf("%%bl"); break;
878 case OperandSize16bit: printf("%%bx"); break;
879 case OperandSize32bit: printf("%%ebx"); break;
880 case OperandSize64bit: printf("%%rbx"); break;
881 case OperandST: printf("%%st(3)"); break;
882 case OperandMMX: printf("%%mm3"); break;
883 case OperandFloatSize32bit:
884 case OperandFloatSize64bit:
885 case OperandSize128bit:
886 case OperandXMM: printf("%%xmm3"); break;
887 case OperandSize256bit:
888 case OperandYMM: printf("%%ymm3"); break;
889 case OperandSegmentRegister: printf("%%ds"); break;
890 case OperandControlRegister: printf("%%cr3"); break;
891 case OperandDebugRegister: printf("%%db3"); break;
892 default: assert(FALSE);
893 }
894 break;
895 case REG_RSP: switch (operand_type) {
896 case OperandSize8bit: if (instruction->prefix.rex)
897 printf("%%spl");
898 else
899 printf("%%ah");
900 break;
901 case OperandSize16bit: printf("%%sp"); break;
902 case OperandSize32bit: printf("%%esp"); break;
903 case OperandSize64bit: printf("%%rsp"); break;
904 case OperandST: printf("%%st(4)"); break;
905 case OperandMMX: printf("%%mm4"); break;
906 case OperandFloatSize32bit:
907 case OperandFloatSize64bit:
908 case OperandSize128bit:
909 case OperandXMM: printf("%%xmm4"); break;
910 case OperandSize256bit:
911 case OperandYMM: printf("%%ymm4"); break;
912 case OperandSegmentRegister: printf("%%fs"); break;
913 case OperandControlRegister: printf("%%cr4"); break;
914 case OperandDebugRegister: printf("%%db4"); break;
915 default: assert(FALSE);
916 }
917 break;
918 case REG_RBP: switch (operand_type) {
919 case OperandSize8bit: if (instruction->prefix.rex)
920 printf("%%bpl");
921 else
922 printf("%%ch");
923 break;
924 case OperandSize16bit: printf("%%bp"); break;
925 case OperandSize32bit: printf("%%ebp"); break;
926 case OperandSize64bit: printf("%%rbp"); break;
927 case OperandST: printf("%%st(5)"); break;
928 case OperandMMX: printf("%%mm5"); break;
929 case OperandFloatSize32bit:
930 case OperandFloatSize64bit:
931 case OperandSize128bit:
932 case OperandXMM: printf("%%xmm5"); break;
933 case OperandSize256bit:
934 case OperandYMM: printf("%%ymm5"); break;
935 case OperandSegmentRegister: printf("%%gs"); break;
936 case OperandControlRegister: printf("%%cr5"); break;
937 case OperandDebugRegister: printf("%%db5"); break;
938 default: assert(FALSE);
939 }
940 break;
941 case REG_RSI: switch (operand_type) {
942 case OperandSize8bit: if (instruction->prefix.rex)
943 printf("%%sil");
944 else
945 printf("%%dh");
946 break;
947 case OperandSize16bit: printf("%%si"); break;
948 case OperandSize32bit: printf("%%esi"); break;
949 case OperandSize64bit: printf("%%rsi"); break;
950 case OperandST: printf("%%st(6)"); break;
951 case OperandMMX: printf("%%mm6"); break;
952 case OperandFloatSize32bit:
953 case OperandFloatSize64bit:
954 case OperandSize128bit:
955 case OperandXMM: printf("%%xmm6"); break;
956 case OperandSize256bit:
957 case OperandYMM: printf("%%ymm6"); break;
958 case OperandControlRegister: printf("%%cr6"); break;
959 case OperandDebugRegister: printf("%%db6"); break;
960 default: assert(FALSE);
961 }
962 break;
963 case REG_RDI: switch (operand_type) {
964 case OperandSize8bit: if (instruction->prefix.rex)
965 printf("%%dil");
966 else
967 printf("%%bh");
968 break;
969 case OperandSize16bit: printf("%%di"); break;
970 case OperandSize32bit: printf("%%edi"); break;
971 case OperandSize64bit: printf("%%rdi"); break;
972 case OperandST: printf("%%st(7)"); break;
973 case OperandMMX: printf("%%mm7"); break;
974 case OperandFloatSize32bit:
975 case OperandFloatSize64bit:
976 case OperandSize128bit:
977 case OperandXMM: printf("%%xmm7"); break;
978 case OperandSize256bit:
979 case OperandYMM: printf("%%ymm7"); break;
980 case OperandControlRegister: printf("%%cr7"); break;
981 case OperandDebugRegister: printf("%%db7"); break;
982 default: assert(FALSE);
983 }
984 break;
985 case REG_R8: switch (operand_type) {
986 case OperandSize8bit: printf("%%r8b"); break;
987 case OperandSize16bit: printf("%%r8w"); break;
988 case OperandSize32bit: printf("%%r8d"); break;
989 case OperandSize64bit: printf("%%r8"); break;
990 case OperandMMX: printf("%%mm0"); break;
991 case OperandFloatSize32bit:
992 case OperandFloatSize64bit:
993 case OperandSize128bit:
994 case OperandXMM: printf("%%xmm8"); break;
995 case OperandSize256bit:
996 case OperandYMM: printf("%%ymm8"); break;
997 case OperandControlRegister: printf("%%cr8"); break;
998 default: assert(FALSE);
999 }
1000 break;
1001 case REG_R9: switch (operand_type) {
1002 case OperandSize8bit: printf("%%r9b"); break;
1003 case OperandSize16bit: printf("%%r9w"); break;
1004 case OperandSize32bit: printf("%%r9d"); break;
1005 case OperandSize64bit: printf("%%r9"); break;
1006 case OperandMMX: printf("%%mm1"); break;
1007 case OperandFloatSize32bit:
1008 case OperandFloatSize64bit:
1009 case OperandSize128bit:
1010 case OperandXMM: printf("%%xmm9"); break;
1011 case OperandSize256bit:
1012 case OperandYMM: printf("%%ymm9"); break;
1013 case OperandControlRegister: printf("%%cr9"); break;
1014 default: assert(FALSE);
1015 }
1016 break;
1017 case REG_R10: switch (operand_type) {
1018 case OperandSize8bit: printf("%%r10b"); break;
1019 case OperandSize16bit: printf("%%r10w"); break;
1020 case OperandSize32bit: printf("%%r10d"); break;
1021 case OperandSize64bit: printf("%%r10"); break;
1022 case OperandMMX: printf("%%mm2"); break;
1023 case OperandFloatSize32bit:
1024 case OperandFloatSize64bit:
1025 case OperandSize128bit:
1026 case OperandXMM: printf("%%xmm10"); break;
1027 case OperandSize256bit:
1028 case OperandYMM: printf("%%ymm10"); break;
1029 case OperandControlRegister: printf("%%cr10"); break;
1030 default: assert(FALSE);
1031 }
1032 break;
1033 case REG_R11: switch (operand_type) {
1034 case OperandSize8bit: printf("%%r11b"); break;
1035 case OperandSize16bit: printf("%%r11w"); break;
1036 case OperandSize32bit: printf("%%r11d"); break;
1037 case OperandSize64bit: printf("%%r11"); break;
1038 case OperandMMX: printf("%%mm3"); break;
1039 case OperandFloatSize32bit:
1040 case OperandFloatSize64bit:
1041 case OperandSize128bit:
1042 case OperandXMM: printf("%%xmm11"); break;
1043 case OperandSize256bit:
1044 case OperandYMM: printf("%%ymm11"); break;
1045 case OperandControlRegister: printf("%%cr11"); break;
1046 default: assert(FALSE);
1047 }
1048 break;
1049 case REG_R12: switch (operand_type) {
1050 case OperandSize8bit: printf("%%r12b"); break;
1051 case OperandSize16bit: printf("%%r12w"); break;
1052 case OperandSize32bit: printf("%%r12d"); break;
1053 case OperandSize64bit: printf("%%r12"); break;
1054 case OperandMMX: printf("%%mm4"); break;
1055 case OperandFloatSize32bit:
1056 case OperandFloatSize64bit:
1057 case OperandSize128bit:
1058 case OperandXMM: printf("%%xmm12"); break;
1059 case OperandSize256bit:
1060 case OperandYMM: printf("%%ymm12"); break;
1061 case OperandControlRegister: printf("%%cr12"); break;
1062 default: assert(FALSE);
1063 }
1064 break;
1065 case REG_R13: switch (operand_type) {
1066 case OperandSize8bit: printf("%%r13b"); break;
1067 case OperandSize16bit: printf("%%r13w"); break;
1068 case OperandSize32bit: printf("%%r13d"); break;
1069 case OperandSize64bit: printf("%%r13"); break;
1070 case OperandMMX: printf("%%mm5"); break;
1071 case OperandFloatSize32bit:
1072 case OperandFloatSize64bit:
1073 case OperandSize128bit:
1074 case OperandXMM: printf("%%xmm13"); break;
1075 case OperandSize256bit:
1076 case OperandYMM: printf("%%ymm13"); break;
1077 case OperandControlRegister: printf("%%cr13"); break;
1078 default: assert(FALSE);
1079 }
1080 break;
1081 case REG_R14: switch (operand_type) {
1082 case OperandSize8bit: printf("%%r14b"); break;
1083 case OperandSize16bit: printf("%%r14w"); break;
1084 case OperandSize32bit: printf("%%r14d"); break;
1085 case OperandSize64bit: printf("%%r14"); break;
1086 case OperandMMX: printf("%%mm6"); break;
1087 case OperandFloatSize32bit:
1088 case OperandFloatSize64bit:
1089 case OperandSize128bit:
1090 case OperandXMM: printf("%%xmm14"); break;
1091 case OperandSize256bit:
1092 case OperandYMM: printf("%%ymm14"); break;
1093 case OperandControlRegister: printf("%%cr14"); break;
1094 default: assert(FALSE);
1095 }
1096 break;
1097 case REG_R15: switch (operand_type) {
1098 case OperandSize8bit: printf("%%r15b"); break;
1099 case OperandSize16bit: printf("%%r15w"); break;
1100 case OperandSize32bit: printf("%%r15d"); break;
1101 case OperandSize64bit: printf("%%r15"); break;
1102 case OperandMMX: printf("%%mm7"); break;
1103 case OperandFloatSize32bit:
1104 case OperandFloatSize64bit:
1105 case OperandSize128bit:
1106 case OperandXMM: printf("%%xmm15"); break;
1107 case OperandSize256bit:
1108 case OperandYMM: printf("%%ymm15"); break;
1109 case OperandControlRegister: printf("%%cr15"); break;
1110 default: assert(FALSE);
1111 }
1112 break;
1113 case REG_ST:
1114 assert(operand_type == OperandST);
1115 printf("%%st");
1116 break;
1117 case REG_RM: {
1118 if (instruction->rm.offset) {
1119 printf("0x%"PRIx64, instruction->rm.offset);
1120 }
1121 if (((struct DecodeState *)userdata)->ia32_mode) {
1122 if ((instruction->rm.base != REG_NONE) ||
1123 (instruction->rm.index != REG_NONE) ||
1124 (instruction->rm.scale != 0)) {
1125 printf("(");
1126 }
1127 switch (instruction->rm.base) {
1128 case REG_RAX: printf("%%eax"); break;
1129 case REG_RCX: printf("%%ecx"); break;
1130 case REG_RDX: printf("%%edx"); break;
1131 case REG_RBX: printf("%%ebx"); break;
1132 case REG_RSP: printf("%%esp"); break;
1133 case REG_RBP: printf("%%ebp"); break;
1134 case REG_RSI: printf("%%esi"); break;
1135 case REG_RDI: printf("%%edi"); break;
1136 case REG_NONE: break;
1137 case REG_R8:
1138 case REG_R9:
1139 case REG_R10:
1140 case REG_R11:
1141 case REG_R12:
1142 case REG_R13:
1143 case REG_R14:
1144 case REG_R15:
1145 case REG_RIP:
1146 case REG_RM:
1147 case REG_RIZ:
1148 case REG_IMM:
1149 case REG_IMM2:
1150 case REG_DS_RBX:
1151 case REG_ES_RDI:
1152 case REG_DS_RSI:
1153 case REG_PORT_DX:
1154 case REG_ST:
1155 case JMP_TO:
1156 assert(FALSE);
1157 }
1158 switch (instruction->rm.index) {
1159 case REG_RAX: printf(",%%eax,%d",1<<instruction->rm.scale); break;
1160 case REG_RCX: printf(",%%ecx,%d",1<<instruction->rm.scale); break;
1161 case REG_RDX: printf(",%%edx,%d",1<<instruction->rm.scale); break;
1162 case REG_RBX: printf(",%%ebx,%d",1<<instruction->rm.scale); break;
1163 case REG_RSP: printf(",%%esp,%d",1<<instruction->rm.scale); break;
1164 case REG_RBP: printf(",%%ebp,%d",1<<instruction->rm.scale); break;
1165 case REG_RSI: printf(",%%esi,%d",1<<instruction->rm.scale); break;
1166 case REG_RDI: printf(",%%edi,%d",1<<instruction->rm.scale); break;
1167 case REG_RIZ: if ((instruction->rm.base != REG_RSP) ||
1168 (instruction->rm.scale != 0))
1169 printf(",%%eiz,%d",1<<instruction->rm.scale);
1170 break;
1171 case REG_NONE: break;
1172 case REG_R8:
1173 case REG_R9:
1174 case REG_R10:
1175 case REG_R11:
1176 case REG_R12:
1177 case REG_R13:
1178 case REG_R14:
1179 case REG_R15:
1180 case REG_RM:
1181 case REG_RIP:
1182 case REG_IMM:
1183 case REG_IMM2:
1184 case REG_DS_RBX:
1185 case REG_ES_RDI:
1186 case REG_DS_RSI:
1187 case REG_PORT_DX:
1188 case REG_ST:
1189 case JMP_TO:
1190 assert(FALSE);
1191 }
1192 if ((instruction->rm.base != REG_NONE) ||
1193 (instruction->rm.index != REG_NONE) ||
1194 (instruction->rm.scale != 0)) {
1195 printf(")");
1196 }
1197 } else {
1198 if ((instruction->rm.base != REG_NONE) ||
1199 (instruction->rm.index != REG_RIZ) ||
1200 (instruction->rm.scale != 0)) {
1201 printf("(");
1202 }
1203 switch (instruction->rm.base) {
1204 case REG_RAX: printf("%%rax"); break;
1205 case REG_RCX: printf("%%rcx"); break;
1206 case REG_RDX: printf("%%rdx"); break;
1207 case REG_RBX: printf("%%rbx"); break;
1208 case REG_RSP: printf("%%rsp"); break;
1209 case REG_RBP: printf("%%rbp"); break;
1210 case REG_RSI: printf("%%rsi"); break;
1211 case REG_RDI: printf("%%rdi"); break;
1212 case REG_R8: printf("%%r8"); break;
1213 case REG_R9: printf("%%r9"); break;
1214 case REG_R10: printf("%%r10"); break;
1215 case REG_R11: printf("%%r11"); break;
1216 case REG_R12: printf("%%r12"); break;
1217 case REG_R13: printf("%%r13"); break;
1218 case REG_R14: printf("%%r14"); break;
1219 case REG_R15: printf("%%r15"); break;
1220 case REG_RIP: printf("%%rip"); print_rip = TRUE; break;
1221 case REG_NONE: break;
1222 case REG_RM:
1223 case REG_RIZ:
1224 case REG_IMM:
1225 case REG_IMM2:
1226 case REG_DS_RBX:
1227 case REG_ES_RDI:
1228 case REG_DS_RSI:
1229 case REG_PORT_DX:
1230 case REG_ST:
1231 case JMP_TO:
1232 assert(FALSE);
1233 }
1234 switch (instruction->rm.index) {
1235 case REG_RAX: printf(",%%rax,%d",1<<instruction->rm.scale); break;
1236 case REG_RCX: printf(",%%rcx,%d",1<<instruction->rm.scale); break;
1237 case REG_RDX: printf(",%%rdx,%d",1<<instruction->rm.scale); break;
1238 case REG_RBX: printf(",%%rbx,%d",1<<instruction->rm.scale); break;
1239 case REG_RSP: printf(",%%rsp,%d",1<<instruction->rm.scale); break;
1240 case REG_RBP: printf(",%%rbp,%d",1<<instruction->rm.scale); break;
1241 case REG_RSI: printf(",%%rsi,%d",1<<instruction->rm.scale); break;
1242 case REG_RDI: printf(",%%rdi,%d",1<<instruction->rm.scale); break;
1243 case REG_R8: printf(",%%r8,%d",1<<instruction->rm.scale); break;
1244 case REG_R9: printf(",%%r9,%d",1<<instruction->rm.scale); break;
1245 case REG_R10: printf(",%%r10,%d",1<<instruction->rm.scale); break;
1246 case REG_R11: printf(",%%r11,%d",1<<instruction->rm.scale); break;
1247 case REG_R12: printf(",%%r12,%d",1<<instruction->rm.scale); break;
1248 case REG_R13: printf(",%%r13,%d",1<<instruction->rm.scale); break;
1249 case REG_R14: printf(",%%r14,%d",1<<instruction->rm.scale); break;
1250 case REG_R15: printf(",%%r15,%d",1<<instruction->rm.scale); break;
1251 case REG_RIZ: if (((instruction->rm.base != REG_NONE) &&
1252 (instruction->rm.base != REG_RSP) &&
1253 (instruction->rm.base != REG_R12)) ||
1254 (instruction->rm.scale != 0))
1255 printf(",%%riz,%d",1<<instruction->rm.scale);
1256 break;
1257 case REG_NONE: break;
1258 case REG_RM:
1259 case REG_RIP:
1260 case REG_IMM:
1261 case REG_IMM2:
1262 case REG_DS_RBX:
1263 case REG_ES_RDI:
1264 case REG_DS_RSI:
1265 case REG_PORT_DX:
1266 case REG_ST:
1267 case JMP_TO:
1268 assert(FALSE);
1269 }
1270 if ((instruction->rm.base != REG_NONE) ||
1271 (instruction->rm.index != REG_RIZ) ||
1272 (instruction->rm.scale != 0)) {
1273 printf(")");
1274 }
1275 }
1276 }
1277 break;
1278 case REG_IMM: {
1279 printf("$0x%"PRIx64,instruction->imm[0]);
1280 break;
1281 }
1282 case REG_IMM2: {
1283 printf("$0x%"PRIx64,instruction->imm[1]);
1284 break;
1285 }
1286 case REG_PORT_DX: printf("(%%dx)"); break;
1287 case REG_DS_RBX: if (((struct DecodeState *)userdata)->ia32_mode) {
1288 printf("%%ds:(%%ebx)");
1289 } else {
1290 printf("%%ds:(%%rbx)");
1291 }
1292 break;
1293 case REG_ES_RDI: if (((struct DecodeState *)userdata)->ia32_mode) {
1294 printf("%%es:(%%edi)");
1295 } else {
1296 printf("%%es:(%%rdi)");
1297 }
1298 break;
1299 case REG_DS_RSI: if (((struct DecodeState *)userdata)->ia32_mode) {
1300 printf("%%ds:(%%esi)");
1301 } else {
1302 printf("%%ds:(%%rsi)");
1303 }
1304 break;
1305 case JMP_TO: if (instruction->operands[0].type == OperandSize16bit)
1306 printf("0x%zx", ((end + instruction->rm.offset -
1307 (((struct DecodeState *)userdata)->offset)) & 0xffff));
1308 else
1309 printf("0x%zx", (end + instruction->rm.offset -
1310 (((struct DecodeState *)userdata)->offset)));
1311 break;
1312 case REG_RIP:
1313 case REG_RIZ:
1314 case REG_NONE:
1315 assert(FALSE);
1316 }
1317 delimeter = ',';
1318 }
1319 if (print_rip) {
1320 printf(" # 0x%8"PRIx64,
1321 (uint64_t) (end + instruction->rm.offset -
1322 (((struct DecodeState *)userdata)->offset)));
1323 }
1324 printf("\n");
1325 begin += 7;
1326 while (begin < end) {
1327 printf("%*"PRIx64":\t", ((struct DecodeState *)userdata)->width,
1328 (uint64_t) (begin - (((struct DecodeState *)userdata)->offset)));
1329 for (p = begin; p < begin + 7; ++p) {
1330 if (p >= end) {
1331 printf("\n");
1332 return;
1333 } else {
1334 printf("%02x ", *p);
1335 }
1336 }
1337 if (p >= end) {
1338 printf("\n");
1339 return;
1340 }
1341 begin += 7;
1342 }
1343 }
1344
1345 void ProcessError (const uint8_t *ptr, void *userdata) {
1346 printf("rejected at %"PRIx64" (byte 0x%02"PRIx32")\n",
1347 (uint64_t) (ptr - (((struct DecodeState *)userdata)->offset)),
1348 *ptr);
1349 }
1350
1351 int DecodeFile(const char *filename, int repeat_count) {
1352 size_t data_size;
1353 uint8_t *data;
1354 int count;
1355
1356 ReadFile(filename, &data, &data_size);
1357 if (data[4] == 1) {
1358 for (count = 0; count < repeat_count; ++count) {
1359 Elf32_Ehdr *header;
1360 int index;
1361
1362 header = (Elf32_Ehdr *) data;
1363 CheckBounds(data, data_size, header, sizeof(*header));
1364 assert(memcmp(header->e_ident, ELFMAG, strlen(ELFMAG)) == 0);
1365
1366 for (index = 0; index < header->e_shnum; ++index) {
1367 Elf32_Shdr *section = (Elf32_Shdr *) (data + header->e_shoff +
1368 header->e_shentsize * index);
1369 CheckBounds(data, data_size, section, sizeof(*section));
1370
1371 if ((section->sh_flags & SHF_EXECINSTR) != 0) {
1372 struct DecodeState state;
1373 int res;
1374
1375 state.ia32_mode = TRUE;
1376 state.fwait = FALSE;
1377 state.offset = data + section->sh_offset - section->sh_addr;
1378 if (section->sh_size <= 0xfff) {
1379 state.width = 4;
1380 } else if (section->sh_size <= 0xfffffff) {
1381 state.width = 8;
1382 } else {
1383 state.width = 12;
1384 }
1385 CheckBounds(data, data_size,
1386 data + section->sh_offset, section->sh_size);
1387 res = DecodeChunkIA32(data + section->sh_offset, section->sh_size,
1388 ProcessInstruction, ProcessError, &state);
1389 if (res != 0) {
1390 return res;
1391 } else if (state.fwait) {
1392 while (state.fwait < data + section->sh_offset + section->sh_size) {
1393 printf("%*zx:\t9b \tfwait\n",
1394 state.width, (state.fwait++ - state.offset));
1395 }
1396 }
1397 }
1398 }
1399 }
1400 } else if (data[4] == 2) {
1401 for (count = 0; count < repeat_count; ++count) {
1402 Elf64_Ehdr *header;
1403 int index;
1404
1405 header = (Elf64_Ehdr *) data;
1406 CheckBounds(data, data_size, header, sizeof(*header));
1407 assert(memcmp(header->e_ident, ELFMAG, strlen(ELFMAG)) == 0);
1408
1409 for (index = 0; index < header->e_shnum; ++index) {
1410 Elf64_Shdr *section = (Elf64_Shdr *) (data + header->e_shoff +
1411 header->e_shentsize * index);
1412 CheckBounds(data, data_size, section, sizeof(*section));
1413
1414 if ((section->sh_flags & SHF_EXECINSTR) != 0) {
1415 struct DecodeState state;
1416 int res;
1417
1418 state.ia32_mode = FALSE;
1419 state.fwait = FALSE;
1420 state.offset = data + section->sh_offset - section->sh_addr;
1421 if (section->sh_size <= 0xfff) {
1422 state.width = 4;
1423 } else if (section->sh_size <= 0xfffffff) {
1424 state.width = 8;
1425 } else if (section->sh_size <= 0xfffffffffffLL) {
1426 state.width = 12;
1427 } else {
1428 state.width = 16;
1429 }
1430 CheckBounds(data, data_size,
1431 data + section->sh_offset, section->sh_size);
1432 res = DecodeChunkAMD64(data + section->sh_offset, section->sh_size,
1433 ProcessInstruction, ProcessError, &state);
1434 if (res != 0) {
1435 return res;
1436 } else if (state.fwait) {
1437 while (state.fwait < data + section->sh_offset + section->sh_size) {
1438 printf("%*zx:\t9b \tfwait\n",
1439 state.width, (state.fwait++ - state.offset));
1440 }
1441 }
1442 }
1443 }
1444 }
1445 } else {
1446 printf("Unknown ELF class: %s\n", filename);
1447 exit(1);
1448 }
1449 return 0;
1450 }
1451
1452 int main(int argc, char **argv) {
1453 int index, initial_index = 1, repeat_count = 1;
1454 if (argc == 1) {
1455 printf("%s: no input files\n", argv[0]);
1456 exit(1);
1457 }
1458 if (!strcmp(argv[1],"--repeat"))
1459 repeat_count = atoi(argv[2]),
1460 initial_index += 2;
1461 for (index = initial_index; index < argc; ++index) {
1462 const char *filename = argv[index];
1463 int rc = DecodeFile(filename, repeat_count);
1464 if (rc != 0) {
1465 printf("file '%s' can not be fully decoded\n", filename);
1466 return 1;
1467 }
1468 }
1469 return 0;
1470 }
OLDNEW
« no previous file with comments | « src/trusted/validator_ragel/decoder.h ('k') | src/trusted/validator_ragel/decoder-x86_32.rl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698