Upstream version 11.39.266.0
[platform/framework/web/crosswalk.git] / src / native_client / src / trusted / validator_x86 / ncenuminsts_x86_64.c
1 /*
2  * Copyright (c) 2012 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 #ifndef NACL_TRUSTED_BUT_NOT_TCB
8 #error("This file is not meant for use in the TCB")
9 #endif
10
11 #include "native_client/src/trusted/validator_x86/ncenuminsts.h"
12
13 #include "native_client/src/shared/platform/nacl_log.h"
14 #include "native_client/src/trusted/validator/ncvalidate.h"
15 #include "native_client/src/trusted/validator/x86/decoder/ncop_exps.h"
16 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_iter.h"
17 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_state.h"
18 #include "native_client/src/trusted/validator_x86/ncdis_decode_tables.h"
19 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncvalidate_iter.h"
20 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncvalidate_iter_internal.h"
21 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/nc_illegal.h"
22 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/nc_memory_protect.h"
23 #include "native_client/src/trusted/validator/x86/nc_segment.h"
24
25 /* To turn on debugging of instruction decoding, change value of
26  * DEBUGGING to 1.
27  */
28 #define DEBUGGING 0
29
30 #include "native_client/src/shared/utils/debugging.h"
31
32 NaClInstStruct *NaClParseInst(uint8_t* ibytes, size_t isize,
33                              const NaClPcAddress vbase) {
34
35   /* WARNING: This version of the code uses a global to return the
36    * decoded instruction, forcing the use to be in a single thread.
37    * The following two (static) locals are used to hold the decoded
38    * instruction until the next call to the function.
39    */
40   static NaClInstIter* ND_iterator = NULL;
41   static NaClSegment ND_segment;
42
43   NaClSegmentInitialize(ibytes, vbase, isize, &ND_segment);
44   if (ND_iterator != NULL) {
45     NaClInstIterDestroy(ND_iterator);
46   }
47   ND_iterator = NaClInstIterCreate(kNaClDecoderTables, &ND_segment);
48   return NaClInstIterGetState(ND_iterator);
49 }
50
51 uint8_t NaClInstLength(NaClInstStruct *inst) {
52   return NaClInstStateLength(inst);
53 }
54
55 char *NaClInstToStr(NaClInstStruct *inst) {
56   return NaClInstStateInstructionToString(inst);
57 }
58
59 const char *NaClOpcodeName(NaClInstStruct *inst) {
60   const struct NaClInst *nacl_opcode = NaClInstStateInst(inst);
61   return NaClMnemonicName(nacl_opcode->name);
62 }
63
64 Bool NaClInstDecodesCorrectly(NaClInstStruct *inst) {
65   return NaClInstStateIsValid(inst);
66 }
67
68 Bool NaClInstValidates(uint8_t* mbase,
69                        uint8_t size,
70                        NaClPcAddress vbase,
71                        NaClInstStruct* inst) {
72   NaClSegment segment;
73   NaClValidatorState* state;
74   Bool validates = FALSE;
75   NaClCPUFeaturesX86 cpu_features;
76
77   NaClGetCurrentCPUFeaturesX86((NaClCPUFeatures *) &cpu_features);
78   NACL_FLAGS_unsafe_single_inst_mode = TRUE;
79   state = NaClValidatorStateCreate(vbase, (NaClMemorySize) size, RegR15, FALSE,
80                                    &cpu_features);
81   do {
82     NaClSegmentInitialize(mbase, vbase, (NaClMemorySize) size, &segment);
83     NaClBaseRegisterMemoryInitialize(state);
84     state->cur_iter = NaClInstIterCreate(kNaClDecoderTables, &segment);
85     if (NULL == state->cur_iter) break;
86     state->cur_inst_state = NaClInstIterGetState(state->cur_iter);
87     state->cur_inst = NaClInstStateInst(state->cur_inst_state);
88     state->cur_inst_vector = NaClInstStateExpVector(state->cur_inst_state);
89     NaClValidateInstructionLegal(state);
90     NaClBaseRegisterValidator(state);
91     /* induce call to NaClMaybeReportPreviousBad() */
92     NaClBaseRegisterSummarize(state);
93     NaClMemoryReferenceValidator(state);
94     NaClJumpValidator(state);
95     validates = NaClValidatesOk(state);
96     NaClInstIterDestroy(state->cur_iter);
97     state->cur_iter = NULL;
98     state->cur_inst_state = NULL;
99     state->cur_inst = NULL;
100     state->cur_inst_vector = NULL;
101   } while(0);
102   NaClValidatorStateDestroy(state);
103   /* Strictly speaking this shouldn't be necessary, as the mode */
104   /* should only be used from tests. Disabling it here as a     */
105   /* defensive tactic. */
106   NACL_FLAGS_unsafe_single_inst_mode = FALSE;
107   return validates;
108 }
109
110 Bool NaClSegmentValidates(uint8_t* mbase,
111                           size_t size,
112                           NaClPcAddress vbase) {
113   NaClCPUFeaturesX86 cpu_features;
114   NaClValidationStatus status;
115   /* TODO(pasko): Validator initialization can be slow, make it run only once.
116    */
117   const struct NaClValidatorInterface *validator = NaClCreateValidator();
118
119   /* check if NaCl thinks the given code segment is valid. */
120   validator->SetAllCPUFeatures((NaClCPUFeatures *) &cpu_features);
121   status = validator->Validate(
122       vbase, mbase, size,
123       /* stubout_mode= */ FALSE, /* readonly_text= */ FALSE,
124       (NaClCPUFeatures *) &cpu_features, NULL, NULL);
125   switch (status) {
126     case NaClValidationSucceeded:
127       return TRUE;
128     default:
129       return FALSE;
130   }
131 }