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 : /* Descriptors to model instructions, opcodes, and instruction operands. */
8 :
9 : #include "native_client/src/trusted/validator/x86/decoder/ncopcode_desc.h"
10 :
11 : #include <assert.h>
12 : #include <string.h>
13 :
14 : #include "native_client/src/shared/utils/types.h"
15 : #include "native_client/src/trusted/validator/x86/decoder/gen/ncopcode_prefix_impl.h"
16 : #include "native_client/src/trusted/validator/x86/decoder/gen/ncopcode_insts_impl.h"
17 : #include "native_client/src/trusted/validator/x86/decoder/gen/ncopcode_opcode_flags_impl.h"
18 : #include "native_client/src/trusted/validator/x86/decoder/gen/ncopcode_operand_kind_impl.h"
19 : #include "native_client/src/trusted/validator/x86/decoder/gen/ncopcode_operand_flag_impl.h"
20 : #include "native_client/src/trusted/validator/x86/decoder/nc_decode_tables.h"
21 :
22 : #include "native_client/src/trusted/validator/x86/decoder/ncopcode_desc_inl.c"
23 :
24 2 : uint8_t NaClGetOpcodeInModRm(uint8_t opcode_ext) {
25 2 : return opcode_ext & 0x0F;
26 2 : }
27 :
28 1 : uint8_t NaClGetOpcodeInModRmRm(uint8_t opcode_ext) {
29 1 : return (opcode_ext >> 4) & 0x0F;
30 1 : }
31 :
32 2 : uint8_t NaClGetOpcodePlusR(uint8_t opcode_ext) {
33 2 : return opcode_ext & 0x0F;
34 2 : }
35 :
36 0 : uint8_t NaClGetInstNumberOperands(const NaClInst* inst) {
37 0 : return NaClGetInstNumberOperandsInline(inst);
38 0 : }
39 :
40 : const NaClOp* NaClGetInstOperand(const NaClDecodeTables* tables,
41 1 : const NaClInst* inst, uint8_t index) {
42 1 : return NaClGetInstOperandInline(tables, inst, index);
43 1 : }
44 :
45 : /* Print out the opcode operand flags in a simplified (i.e. more human readable)
46 : * form.
47 : */
48 2 : void NaClOpFlagsPrint(struct Gio* f, NaClOpFlags flags) {
49 : NaClOpFlag i;
50 2 : Bool first = TRUE;
51 2 : for (i = 0; i < NaClOpFlagEnumSize; ++i) {
52 2 : if (flags & NACL_OPFLAG(i)) {
53 2 : if (first) {
54 2 : first = FALSE;
55 2 : } else {
56 2 : gprintf(f, " ");
57 : }
58 2 : gprintf(f, "%s", NaClOpFlagName(i));
59 : }
60 2 : }
61 2 : }
62 :
63 : /* Print out the opcode operand in a simplified (i.e. more human readable)
64 : * form.
65 : */
66 2 : void NaClOpPrint(struct Gio* f, const NaClOp* operand) {
67 2 : gprintf(f, "%s", NaClOpKindName(operand->kind));
68 2 : if (operand->flags) {
69 : size_t i;
70 2 : for (i = strlen(NaClOpKindName(operand->kind)); i < 24; ++i) {
71 2 : gprintf(f, " ");
72 2 : }
73 2 : NaClOpFlagsPrint(f, operand->flags);
74 : }
75 2 : gprintf(f, "\n");
76 2 : }
77 :
78 : /* Print instruction flags using a simplified (i.e. more human readable) form */
79 2 : void NaClIFlagsPrint(struct Gio* f, NaClIFlags flags) {
80 : int i;
81 2 : Bool first = TRUE;
82 2 : for (i = 0; i < NaClIFlagEnumSize; ++i) {
83 2 : if (flags & NACL_IFLAG(i)) {
84 2 : if (first) {
85 2 : first = FALSE;
86 2 : } else {
87 2 : gprintf(f, " ");
88 : }
89 2 : gprintf(f, "%s", NaClIFlagName(i));
90 : }
91 2 : }
92 2 : }
93 :
94 : /* Returns a string defining bytes of the given prefix that are considered
95 : * prefix bytes, independent of the opcode.
96 : */
97 1 : const char* OpcodePrefixBytes(NaClInstPrefix prefix) {
98 1 : switch(prefix) {
99 : case NoPrefix:
100 : case Prefix0F:
101 : case Prefix0F0F:
102 : case Prefix0F38:
103 : case Prefix0F3A:
104 : case PrefixD8:
105 : case PrefixD9:
106 : case PrefixDA:
107 : case PrefixDB:
108 : case PrefixDC:
109 : case PrefixDD:
110 : case PrefixDE:
111 : case PrefixDF:
112 : default: /* This shouldn't happen, but be safe. */
113 1 : return "";
114 : case PrefixF20F:
115 : case PrefixF20F38:
116 1 : return "f2";
117 : case PrefixF30F:
118 1 : return "f3";
119 : case Prefix660F:
120 : case Prefix660F38:
121 : case Prefix660F3A:
122 1 : return "66";
123 : }
124 1 : }
|