OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. | 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 | 3 * Use of this source code is governed by a BSD-style license that can be |
4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
5 */ | 5 */ |
6 | 6 |
7 /* | 7 /* |
8 * ncdis.c - disassemble using NaCl decoder. | 8 * ncdis.c - disassemble using NaCl decoder. |
9 * Mostly for testing. | 9 * Mostly for testing. |
10 */ | 10 */ |
11 | 11 |
12 | 12 |
13 #ifndef NACL_TRUSTED_BUT_NOT_TCB | 13 #ifndef NACL_TRUSTED_BUT_NOT_TCB |
14 #error("This file is not meant for use in the TCB") | 14 #error("This file is not meant for use in the TCB") |
15 #endif | 15 #endif |
16 | 16 |
17 #include <stdio.h> | 17 #include <stdio.h> |
18 #include <stdlib.h> | 18 #include <stdlib.h> |
19 #include <string.h> | 19 #include <string.h> |
20 | 20 |
21 #include "native_client/src/trusted/validator_x86/ncdecode.h" | 21 #include "native_client/src/trusted/validator_x86/ncdecode.h" |
22 #include "gen/native_client/src/trusted/validator_x86/ncdisasmtab.h" | 22 #include "gen/native_client/src/trusted/validator_x86/ncdisasmtab.h" |
23 | 23 #include "native_client/src/trusted/validator_x86/RexPrefixes.h" |
24 | 24 |
25 /* To turn on debugging of instruction decoding, change value of | 25 /* To turn on debugging of instruction decoding, change value of |
26 * DEBUGGING to 1. | 26 * DEBUGGING to 1. |
27 */ | 27 */ |
28 #define DEBUGGING 0 | 28 #define DEBUGGING 0 |
29 | 29 |
30 #include "native_client/src/shared/utils/debugging.h" | 30 #include "native_client/src/shared/utils/debugging.h" |
31 | 31 |
32 /* The following are conditionally added since they only have meaning | 32 /* The following are conditionally added since they only have meaning |
33 * if we are processing 64-bit instructions. | 33 * if we are processing 64-bit instructions. |
34 */ | 34 */ |
35 #if NACL_TARGET_SUBARCH == 64 | 35 #if NACL_TARGET_SUBARCH == 64 |
36 | 36 |
37 /* Returns if the decoded instruction contains a REX prefix byte. */ | 37 /* Returns if the decoded instruction contains a REX prefix byte. */ |
38 static INLINE uint8_t HasRexPrefix(const NCDecoderInst* dinst) { | 38 static INLINE uint8_t HasRexPrefix(const NCDecoderInst* dinst) { |
39 /* Note: we could check the prefix mask of the recognized instruction to | 39 /* Note: we could check the prefix mask of the recognized instruction to |
40 * see if bit kPrefixREX is set. However, the field rexprefix is | 40 * see if bit kPrefixREX is set. However, the field rexprefix is |
41 * initialized to zero (during decoding) and only set if an actual | 41 * initialized to zero (during decoding) and only set if an actual |
42 * REX prefix is found (which must be values between 0x40 and 0x4f) | 42 * REX prefix is found (which must be values between 0x40 and 0x4f) |
43 */ | 43 */ |
44 return 0 != dinst->inst.rexprefix; | 44 return 0 != dinst->inst.rexprefix; |
45 } | 45 } |
46 | 46 |
47 /* Returns true if REX.W is defined in the REX prefix byte. */ | 47 /* Returns true if REX.W is defined in the REX prefix byte. */ |
48 static INLINE uint8_t GetRexPrefixW(const NCDecoderInst* dinst) { | 48 static INLINE uint8_t GetRexPrefixW(const NCDecoderInst* dinst) { |
49 /* Note: the field rexprefix is non-zero only if a rexprefix was found. */ | 49 /* Note: the field rexprefix is non-zero only if a rexprefix was found. */ |
50 return 0 != (dinst->inst.rexprefix & 0x8); | 50 return 0 != NaClRexW(dinst->inst.rexprefix); |
51 } | 51 } |
52 | 52 |
53 /* Returns true if REX.R is defined in the REX prefix byte. */ | 53 /* Returns true if REX.R is defined in the REX prefix byte. */ |
54 static INLINE uint8_t GetRexPrefixR(const NCDecoderInst* dinst) { | 54 static INLINE uint8_t GetRexPrefixR(const NCDecoderInst* dinst) { |
55 /* Note: the field rexprefix is non-zero only if a rexprefix was found. */ | 55 /* Note: the field rexprefix is non-zero only if a rexprefix was found. */ |
56 return 0 != (dinst->inst.rexprefix & 0x4); | 56 return 0 != NaClRexR(dinst->inst.rexprefix); |
57 } | 57 } |
58 | 58 |
59 /* Returns true if REX.X is defined in the REX prefix byte. */ | 59 /* Returns true if REX.X is defined in the REX prefix byte. */ |
60 static INLINE uint8_t GetRexPrefixX(const NCDecoderInst* dinst) { | 60 static INLINE uint8_t GetRexPrefixX(const NCDecoderInst* dinst) { |
61 /* Note: the field rexprefix is non-zero only if a rexprefix was found. */ | 61 /* Note: the field rexprefix is non-zero only if a rexprefix was found. */ |
62 return 0 != (dinst->inst.rexprefix & 0x2); | 62 return 0 != NaClRexX(dinst->inst.rexprefix); |
63 } | 63 } |
64 | 64 |
65 /* Returns true if REX.B is defined in the REX prefix byte. */ | 65 /* Returns true if REX.B is defined in the REX prefix byte. */ |
66 static INLINE uint8_t GetRexPrefixB(const NCDecoderInst* dinst) { | 66 static INLINE uint8_t GetRexPrefixB(const NCDecoderInst* dinst) { |
67 /* Note: the field rexprefix is non-zero only if a rexprefix was found. */ | 67 /* Note: the field rexprefix is non-zero only if a rexprefix was found. */ |
68 return 0 != (dinst->inst.rexprefix & 0x1); | 68 return 0 != NaClRexB(dinst ->inst.rexprefix); |
69 } | 69 } |
| 70 |
70 #endif | 71 #endif |
71 | 72 |
72 /* Returns the index into the general purpose registers based on the | 73 /* Returns the index into the general purpose registers based on the |
73 * value in the modrm.rm field of the instruction (taking into account | 74 * value in the modrm.rm field of the instruction (taking into account |
74 * the REX prefix if it appears). | 75 * the REX prefix if it appears). |
75 */ | 76 */ |
76 static INLINE uint32_t state_modrm_reg(const NCDecoderInst* dinst) { | 77 static INLINE uint32_t state_modrm_reg(const NCDecoderInst* dinst) { |
77 /* TODO(karl) This is no where near close to being correct. Currently, | 78 /* TODO(karl) This is no where near close to being correct. Currently, |
78 * It only models r/m64 entry for instructions in the Intel documentation, | 79 * It only models r/m64 entry for instructions in the Intel documentation, |
79 * which requires the W bit to be set (r/m32 entries do not use REX.w, | 80 * which requires the W bit to be set (r/m32 entries do not use REX.w, |
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
577 for (i = dinst->inst.bytes.length; i < 7; i++) fprintf(fp, " "); | 578 for (i = dinst->inst.bytes.length; i < 7; i++) fprintf(fp, " "); |
578 fprintf(fp, "\t"); | 579 fprintf(fp, "\t"); |
579 InstFormat(DisFmt(dinst), dinst, fp); | 580 InstFormat(DisFmt(dinst), dinst, fp); |
580 fprintf(fp, "\n"); | 581 fprintf(fp, "\n"); |
581 } | 582 } |
582 | 583 |
583 | 584 |
584 void PrintInstStdout(const NCDecoderInst *dinst) { | 585 void PrintInstStdout(const NCDecoderInst *dinst) { |
585 PrintInst(dinst, stdout); | 586 PrintInst(dinst, stdout); |
586 } | 587 } |
OLD | NEW |