OLD | NEW |
| (Empty) |
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_protec
t.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 } | |
OLD | NEW |