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

Side by Side Diff: src/trusted/validator_ragel/validator_internal.h

Issue 11000033: Move validator_x86_XX.rl out of unreviewed. (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client/
Patch Set: Created 8 years, 2 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
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. 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 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 * This file contains common parts of x86-32 and x86-64 internals (inline 8 * This file contains common parts of x86-32 and x86-64 internals (inline
9 * functions and defines). 9 * functions and defines).
10 */ 10 */
11 11
12 #ifndef NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_VALIDATOR_INTERNAL_H_ 12 #ifndef NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_VALIDATOR_INTERNAL_H_
13 #define NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_VALIDATOR_INTERNAL_H_ 13 #define NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_VALIDATOR_INTERNAL_H_
14 14
15 #include "native_client/src/shared/platform/nacl_check.h" 15 #include "native_client/src/shared/platform/nacl_check.h"
16 #include "native_client/src/shared/utils/types.h" 16 #include "native_client/src/shared/utils/types.h"
17 #include "native_client/src/trusted/validator_ragel/unreviewed/decoding.h" 17 #include "native_client/src/trusted/validator_ragel/decoding.h"
18 #include "native_client/src/trusted/validator_ragel/unreviewed/validator.h" 18 #include "native_client/src/trusted/validator_ragel/unreviewed/validator.h"
19 19
20 /* Maximum set of R-DFA allowable CPUID features. */ 20 /* Maximum set of R-DFA allowable CPUID features. */
21 extern const NaClCPUFeaturesX86 validator_cpuid_features; 21 extern const NaClCPUFeaturesX86 kValidatorCPUIDFeatures;
22 22
23 /* Macroses to suppport CPUID handling. */ 23 /* Macroses to suppport CPUID handling. */
24 #define SET_CPU_FEATURE(F) \ 24 #define SET_CPU_FEATURE(F) \
25 if (!(F##_Allowed)) { \ 25 if (!(F##_Allowed)) { \
26 instruction_info_collected |= UNRECOGNIZED_INSTRUCTION; \ 26 instruction_info_collected |= UNRECOGNIZED_INSTRUCTION; \
27 } \ 27 } \
28 if (!(F)) { \ 28 if (!(F)) { \
29 instruction_info_collected |= CPUID_UNSUPPORTED_INSTRUCTION; \ 29 instruction_info_collected |= CPUID_UNSUPPORTED_INSTRUCTION; \
30 } 30 }
31 #define CPUFeature_3DNOW cpu_features->data[NaClCPUFeature_3DNOW] 31 #define CPUFeature_3DNOW cpu_features->data[NaClCPUFeature_3DNOW]
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 #define CPUFeature_TSC cpu_features->data[NaClCPUFeature_TSC] 78 #define CPUFeature_TSC cpu_features->data[NaClCPUFeature_TSC]
79 /* 79 /*
80 * We allow tzcnt unconditionally 80 * We allow tzcnt unconditionally
81 * See http://code.google.com/p/nativeclient/issues/detail?id=2869 81 * See http://code.google.com/p/nativeclient/issues/detail?id=2869
82 */ 82 */
83 #define CPUFeature_TZCNT TRUE 83 #define CPUFeature_TZCNT TRUE
84 #define CPUFeature_x87 cpu_features->data[NaClCPUFeature_x87] 84 #define CPUFeature_x87 cpu_features->data[NaClCPUFeature_x87]
85 #define CPUFeature_XOP cpu_features->data[NaClCPUFeature_XOP] 85 #define CPUFeature_XOP cpu_features->data[NaClCPUFeature_XOP]
86 86
87 #define CPUFeature_3DNOW_Allowed \ 87 #define CPUFeature_3DNOW_Allowed \
88 validator_cpuid_features.data[NaClCPUFeature_3DNOW] 88 kValidatorCPUIDFeatures.data[NaClCPUFeature_3DNOW]
89 /* 89 /*
90 * AMD documentation claims it's always available if CPUFeature_LM is present, 90 * AMD documentation claims it's always available if CPUFeature_LM is present,
91 * But Intel documentation does not even mention it! 91 * But Intel documentation does not even mention it!
92 * Keep it as 3DNow! instruction. 92 * Keep it as 3DNow! instruction.
93 */ 93 */
94 #define CPUFeature_3DPRFTCH_Allowed \ 94 #define CPUFeature_3DPRFTCH_Allowed \
95 CPUFeature_3DNOW_Allowed || CPUFeature_PRE_Allowed 95 CPUFeature_3DNOW_Allowed || CPUFeature_PRE_Allowed
96 #define CPUFeature_AES_Allowed \ 96 #define CPUFeature_AES_Allowed \
97 validator_cpuid_features.data[NaClCPUFeature_AES] 97 kValidatorCPUIDFeatures.data[NaClCPUFeature_AES]
98 #define CPUFeature_AESAVX_Allowed \ 98 #define CPUFeature_AESAVX_Allowed \
99 CPUFeature_AES_Allowed && CPUFeature_AVX_Allowed 99 CPUFeature_AES_Allowed && CPUFeature_AVX_Allowed
100 #define CPUFeature_AVX_Allowed \ 100 #define CPUFeature_AVX_Allowed \
101 validator_cpuid_features.data[NaClCPUFeature_AVX] 101 kValidatorCPUIDFeatures.data[NaClCPUFeature_AVX]
102 #define CPUFeature_BMI1_Allowed \ 102 #define CPUFeature_BMI1_Allowed \
103 validator_cpuid_features.data[NaClCPUFeature_BMI1] 103 kValidatorCPUIDFeatures.data[NaClCPUFeature_BMI1]
104 #define CPUFeature_CLFLUSH_Allowed \ 104 #define CPUFeature_CLFLUSH_Allowed \
105 validator_cpuid_features.data[NaClCPUFeature_CLFLUSH] 105 kValidatorCPUIDFeatures.data[NaClCPUFeature_CLFLUSH]
106 #define CPUFeature_CLMUL_Allowed \ 106 #define CPUFeature_CLMUL_Allowed \
107 validator_cpuid_features.data[NaClCPUFeature_CLMUL] 107 kValidatorCPUIDFeatures.data[NaClCPUFeature_CLMUL]
108 #define CPUFeature_CLMULAVX_Allowed \ 108 #define CPUFeature_CLMULAVX_Allowed \
109 CPUFeature_CLMUL_Allowed && CPUFeature_AVX_Allowed 109 CPUFeature_CLMUL_Allowed && CPUFeature_AVX_Allowed
110 #define CPUFeature_CMOV_Allowed \ 110 #define CPUFeature_CMOV_Allowed \
111 validator_cpuid_features.data[NaClCPUFeature_CMOV] 111 kValidatorCPUIDFeatures.data[NaClCPUFeature_CMOV]
112 #define CPUFeature_CMOVx87_Allowed \ 112 #define CPUFeature_CMOVx87_Allowed \
113 CPUFeature_CMOV_Allowed && CPUFeature_x87_Allowed 113 CPUFeature_CMOV_Allowed && CPUFeature_x87_Allowed
114 #define CPUFeature_CX16_Allowed \ 114 #define CPUFeature_CX16_Allowed \
115 validator_cpuid_features.data[NaClCPUFeature_CX16] 115 kValidatorCPUIDFeatures.data[NaClCPUFeature_CX16]
116 #define CPUFeature_CX8_Allowed \ 116 #define CPUFeature_CX8_Allowed \
117 validator_cpuid_features.data[NaClCPUFeature_CX8] 117 kValidatorCPUIDFeatures.data[NaClCPUFeature_CX8]
118 #define CPUFeature_E3DNOW_Allowed \ 118 #define CPUFeature_E3DNOW_Allowed \
119 validator_cpuid_features.data[NaClCPUFeature_E3DNOW] 119 kValidatorCPUIDFeatures.data[NaClCPUFeature_E3DNOW]
120 #define CPUFeature_EMMX_Allowed \ 120 #define CPUFeature_EMMX_Allowed \
121 validator_cpuid_features.data[NaClCPUFeature_EMMX] 121 kValidatorCPUIDFeatures.data[NaClCPUFeature_EMMX]
122 #define CPUFeature_EMMXSSE_Allowed \ 122 #define CPUFeature_EMMXSSE_Allowed \
123 CPUFeature_EMMX_Allowed || CPUFeature_SSE_Allowed 123 CPUFeature_EMMX_Allowed || CPUFeature_SSE_Allowed
124 #define CPUFeature_F16C_Allowed \ 124 #define CPUFeature_F16C_Allowed \
125 validator_cpuid_features.data[NaClCPUFeature_F16C] 125 kValidatorCPUIDFeatures.data[NaClCPUFeature_F16C]
126 #define CPUFeature_FMA_Allowed \ 126 #define CPUFeature_FMA_Allowed \
127 validator_cpuid_features.data[NaClCPUFeature_FMA] 127 kValidatorCPUIDFeatures.data[NaClCPUFeature_FMA]
128 #define CPUFeature_FMA4_Allowed \ 128 #define CPUFeature_FMA4_Allowed \
129 validator_cpuid_features.data[NaClCPUFeature_FMA4] 129 kValidatorCPUIDFeatures.data[NaClCPUFeature_FMA4]
130 #define CPUFeature_FXSR_Allowed \ 130 #define CPUFeature_FXSR_Allowed \
131 validator_cpuid_features.data[NaClCPUFeature_FXSR] 131 kValidatorCPUIDFeatures.data[NaClCPUFeature_FXSR]
132 #define CPUFeature_LAHF_Allowed \ 132 #define CPUFeature_LAHF_Allowed \
133 validator_cpuid_features.data[NaClCPUFeature_LAHF] 133 kValidatorCPUIDFeatures.data[NaClCPUFeature_LAHF]
134 #define CPUFeature_LM_Allowed \ 134 #define CPUFeature_LM_Allowed \
135 validator_cpuid_features.data[NaClCPUFeature_LM] 135 kValidatorCPUIDFeatures.data[NaClCPUFeature_LM]
136 #define CPUFeature_LWP_Allowed \ 136 #define CPUFeature_LWP_Allowed \
137 validator_cpuid_features.data[NaClCPUFeature_LWP] 137 kValidatorCPUIDFeatures.data[NaClCPUFeature_LWP]
138 /* 138 /*
139 * We allow lzcnt unconditionally 139 * We allow lzcnt unconditionally
140 * See http://code.google.com/p/nativeclient/issues/detail?id=2869 140 * See http://code.google.com/p/nativeclient/issues/detail?id=2869
141 */ 141 */
142 #define CPUFeature_LZCNT_Allowed TRUE 142 #define CPUFeature_LZCNT_Allowed TRUE
143 #define CPUFeature_MMX_Allowed \ 143 #define CPUFeature_MMX_Allowed \
144 validator_cpuid_features.data[NaClCPUFeature_MMX] 144 kValidatorCPUIDFeatures.data[NaClCPUFeature_MMX]
145 #define CPUFeature_MON_Allowed \ 145 #define CPUFeature_MON_Allowed \
146 validator_cpuid_features.data[NaClCPUFeature_MON] 146 kValidatorCPUIDFeatures.data[NaClCPUFeature_MON]
147 #define CPUFeature_MOVBE_Allowed \ 147 #define CPUFeature_MOVBE_Allowed \
148 validator_cpuid_features.data[NaClCPUFeature_MOVBE] 148 kValidatorCPUIDFeatures.data[NaClCPUFeature_MOVBE]
149 #define CPUFeature_OSXSAVE_Allowed \ 149 #define CPUFeature_OSXSAVE_Allowed \
150 validator_cpuid_features.data[NaClCPUFeature_OSXSAVE] 150 kValidatorCPUIDFeatures.data[NaClCPUFeature_OSXSAVE]
151 #define CPUFeature_POPCNT_Allowed \ 151 #define CPUFeature_POPCNT_Allowed \
152 validator_cpuid_features.data[NaClCPUFeature_POPCNT] 152 kValidatorCPUIDFeatures.data[NaClCPUFeature_POPCNT]
153 #define CPUFeature_PRE_Allowed \ 153 #define CPUFeature_PRE_Allowed \
154 validator_cpuid_features.data[NaClCPUFeature_PRE] 154 kValidatorCPUIDFeatures.data[NaClCPUFeature_PRE]
155 #define CPUFeature_SSE_Allowed \ 155 #define CPUFeature_SSE_Allowed \
156 validator_cpuid_features.data[NaClCPUFeature_SSE] 156 kValidatorCPUIDFeatures.data[NaClCPUFeature_SSE]
157 #define CPUFeature_SSE2_Allowed \ 157 #define CPUFeature_SSE2_Allowed \
158 validator_cpuid_features.data[NaClCPUFeature_SSE2] 158 kValidatorCPUIDFeatures.data[NaClCPUFeature_SSE2]
159 #define CPUFeature_SSE3_Allowed \ 159 #define CPUFeature_SSE3_Allowed \
160 validator_cpuid_features.data[NaClCPUFeature_SSE3] 160 kValidatorCPUIDFeatures.data[NaClCPUFeature_SSE3]
161 #define CPUFeature_SSE41_Allowed \ 161 #define CPUFeature_SSE41_Allowed \
162 validator_cpuid_features.data[NaClCPUFeature_SSE41] 162 kValidatorCPUIDFeatures.data[NaClCPUFeature_SSE41]
163 #define CPUFeature_SSE42_Allowed \ 163 #define CPUFeature_SSE42_Allowed \
164 validator_cpuid_features.data[NaClCPUFeature_SSE42] 164 kValidatorCPUIDFeatures.data[NaClCPUFeature_SSE42]
165 #define CPUFeature_SSE4A_Allowed \ 165 #define CPUFeature_SSE4A_Allowed \
166 validator_cpuid_features.data[NaClCPUFeature_SSE4A] 166 kValidatorCPUIDFeatures.data[NaClCPUFeature_SSE4A]
167 #define CPUFeature_SSSE3_Allowed \ 167 #define CPUFeature_SSSE3_Allowed \
168 validator_cpuid_features.data[NaClCPUFeature_SSSE3] 168 kValidatorCPUIDFeatures.data[NaClCPUFeature_SSSE3]
169 #define CPUFeature_TBM_Allowed \ 169 #define CPUFeature_TBM_Allowed \
170 validator_cpuid_features.data[NaClCPUFeature_TBM] 170 kValidatorCPUIDFeatures.data[NaClCPUFeature_TBM]
171 #define CPUFeature_TSC_Allowed \ 171 #define CPUFeature_TSC_Allowed \
172 validator_cpuid_features.data[NaClCPUFeature_TSC] 172 kValidatorCPUIDFeatures.data[NaClCPUFeature_TSC]
173 /* 173 /*
174 * We allow tzcnt unconditionally 174 * We allow tzcnt unconditionally
175 * See http://code.google.com/p/nativeclient/issues/detail?id=2869 175 * See http://code.google.com/p/nativeclient/issues/detail?id=2869
176 */ 176 */
177 #define CPUFeature_TZCNT_Allowed TRUE 177 #define CPUFeature_TZCNT_Allowed TRUE
178 #define CPUFeature_x87_Allowed \ 178 #define CPUFeature_x87_Allowed \
179 validator_cpuid_features.data[NaClCPUFeature_x87] 179 kValidatorCPUIDFeatures.data[NaClCPUFeature_x87]
180 #define CPUFeature_XOP_Allowed \ 180 #define CPUFeature_XOP_Allowed \
181 validator_cpuid_features.data[NaClCPUFeature_XOP] 181 kValidatorCPUIDFeatures.data[NaClCPUFeature_XOP]
182 182
183 /* Remember some information about instruction for further processing. */ 183 /* Remember some information about instruction for further processing. */
184 #define GET_REX_PREFIX() rex_prefix 184 #define GET_REX_PREFIX() rex_prefix
185 #define SET_REX_PREFIX(P) rex_prefix = (P) 185 #define SET_REX_PREFIX(P) rex_prefix = (P)
186 #define GET_VEX_PREFIX2() vex_prefix2 186 #define GET_VEX_PREFIX2() vex_prefix2
187 #define SET_VEX_PREFIX2(P) vex_prefix2 = (P) 187 #define SET_VEX_PREFIX2(P) vex_prefix2 = (P)
188 #define GET_VEX_PREFIX3() vex_prefix3 188 #define GET_VEX_PREFIX3() vex_prefix3
189 #define SET_VEX_PREFIX3(P) vex_prefix3 = (P) 189 #define SET_VEX_PREFIX3(P) vex_prefix3 = (P)
190 #define SET_MODRM_BASE(N) base = (N) 190 #define SET_MODRM_BASE(N) base = (N)
191 #define SET_MODRM_INDEX(N) index = (N) 191 #define SET_MODRM_INDEX(N) index = (N)
(...skipping 14 matching lines...) Expand all
206 * 8bit operands must be distinguished from other types because the REX prefix 206 * 8bit operands must be distinguished from other types because the REX prefix
207 * regulates the choice between %ah and %spl, as well as %ch and %bpl. 207 * regulates the choice between %ah and %spl, as well as %ch and %bpl.
208 */ 208 */
209 OperandSandbox8bit, 209 OperandSandbox8bit,
210 OperandSandboxRestricted, 210 OperandSandboxRestricted,
211 OperandSandboxUnrestricted 211 OperandSandboxUnrestricted
212 }; 212 };
213 213
214 #define SET_OPERAND_NAME(N, S) operand_states |= ((S) << ((N) << 3)) 214 #define SET_OPERAND_NAME(N, S) operand_states |= ((S) << ((N) << 3))
215 #define SET_OPERAND_TYPE(N, T) SET_OPERAND_TYPE_ ## T(N) 215 #define SET_OPERAND_TYPE(N, T) SET_OPERAND_TYPE_ ## T(N)
216 #define SET_OPERAND_TYPE_OPERAND_SIZE_8_BIT(N) \ 216 #define SET_OPERAND_TYPE_OPERAND_TYPE_8_BIT(N) \
217 operand_states |= OperandSandbox8bit << (5 + ((N) << 3)) 217 operand_states |= OperandSandbox8bit << (5 + ((N) << 3))
218 #define SET_OPERAND_TYPE_OPERAND_SIZE_16_BIT(N) \ 218 #define SET_OPERAND_TYPE_OPERAND_TYPE_16_BIT(N) \
219 operand_states |= OperandSandboxUnrestricted << (5 + ((N) << 3)) 219 operand_states |= OperandSandboxUnrestricted << (5 + ((N) << 3))
220 #define SET_OPERAND_TYPE_OPERAND_SIZE_32_BIT(N) \ 220 #define SET_OPERAND_TYPE_OPERAND_TYPE_32_BIT(N) \
221 operand_states |= OperandSandboxRestricted << (5 + ((N) << 3)) 221 operand_states |= OperandSandboxRestricted << (5 + ((N) << 3))
222 #define SET_OPERAND_TYPE_OPERAND_SIZE_64_BIT(N) \ 222 #define SET_OPERAND_TYPE_OPERAND_TYPE_64_BIT(N) \
223 operand_states |= OperandSandboxUnrestricted << (5 + ((N) << 3)) 223 operand_states |= OperandSandboxUnrestricted << (5 + ((N) << 3))
224 #define CHECK_OPERAND(N, S, T) \ 224 #define CHECK_OPERAND(N, S, T) \
225 ((operand_states & (0xff << ((N) << 3))) == ((S | (T << 5)) << ((N) << 3))) 225 ((operand_states & (0xff << ((N) << 3))) == ((S | (T << 5)) << ((N) << 3)))
226 226
227 /* Ignore this information for now. */ 227 /* Ignore this information for now. */
228 #define SET_DATA16_PREFIX(S) 228 #define SET_DATA16_PREFIX(S)
229 #define SET_LOCK_PREFIX(S) 229 #define SET_LOCK_PREFIX(S)
230 #define SET_REPZ_PREFIX(S) 230 #define SET_REPZ_PREFIX(S)
231 #define SET_REPNZ_PREFIX(S) 231 #define SET_REPNZ_PREFIX(S)
232 #define SET_BRANCH_TAKEN(S) 232 #define SET_BRANCH_TAKEN(S)
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 (((((bitmap_word)1) << bits) - 1) << (index % NACL_HOST_WORDSIZE))) != 0; 297 (((((bitmap_word)1) << bits) - 1) << (index % NACL_HOST_WORDSIZE))) != 0;
298 } 298 }
299 299
300 /* All the bits must be in a single 32-bit bundle. */ 300 /* All the bits must be in a single 32-bit bundle. */
301 static FORCEINLINE void BitmapSetBits(bitmap_word *bitmap, 301 static FORCEINLINE void BitmapSetBits(bitmap_word *bitmap,
302 size_t index, size_t bits) { 302 size_t index, size_t bits) {
303 bitmap[index / NACL_HOST_WORDSIZE] |= 303 bitmap[index / NACL_HOST_WORDSIZE] |=
304 ((((bitmap_word)1) << bits) - 1) << (index % NACL_HOST_WORDSIZE); 304 ((((bitmap_word)1) << bits) - 1) << (index % NACL_HOST_WORDSIZE);
305 } 305 }
306 306
307 /* Mark the destination of a jump instruction and make an early validity check: 307 /*
308 * Mark the destination of a jump instruction and make an early validity check:
308 * to jump outside given code region, the target address must be aligned. 309 * to jump outside given code region, the target address must be aligned.
309 * 310 *
310 * Returns TRUE iff the jump passes the early validity check. 311 * Returns TRUE iff the jump passes the early validity check.
311 */ 312 */
312 static FORCEINLINE int MarkJumpTarget(size_t jump_dest, 313 static FORCEINLINE int MarkJumpTarget(size_t jump_dest,
313 bitmap_word *jump_dests, 314 bitmap_word *jump_dests,
314 size_t size) { 315 size_t size) {
315 if ((jump_dest & kBundleMask) == 0) { 316 if ((jump_dest & kBundleMask) == 0) {
316 return TRUE; 317 return TRUE;
317 } 318 }
318 if (jump_dest >= size) { 319 if (jump_dest >= size) {
319 return FALSE; 320 return FALSE;
320 } 321 }
321 BitmapSetBit(jump_dests, jump_dest); 322 BitmapSetBit(jump_dests, jump_dest);
322 return TRUE; 323 return TRUE;
323 } 324 }
324 325
326 /*
327 * Mark the gived address as valid jump target address.
Brad Chen 2012/10/05 16:47:21 "given"?
khim 2012/10/15 16:38:57 Done.
328 */
329 static FORCEINLINE void MakeJumpTargetValid(size_t address,
330 bitmap_word *valid_targets) {
331 BitmapSetBit(valid_targets, address);
332 }
333
334 /*
335 * Mark the gived address as invalid jump target address.
Brad Chen 2012/10/05 16:47:21 "given"?
khim 2012/10/15 16:38:57 Done.
336 */
337 static FORCEINLINE void MakeInvalidJumpTarget(size_t address,
338 bitmap_word *valid_targets) {
339 BitmapClearBit(valid_targets, address);
340 }
325 341
326 static INLINE Bool ProcessInvalidJumpTargets( 342 static INLINE Bool ProcessInvalidJumpTargets(
327 const uint8_t *data, 343 const uint8_t *data,
328 size_t size, 344 size_t size,
329 bitmap_word *valid_targets, 345 bitmap_word *valid_targets,
330 bitmap_word *jump_dests, 346 bitmap_word *jump_dests,
331 validation_callback_func user_callback, 347 ValidationCallbackFunc user_callback,
332 void *callback_data) { 348 void *callback_data) {
333 size_t elements = (size + NACL_HOST_WORDSIZE - 1) / NACL_HOST_WORDSIZE; 349 size_t elements = (size + NACL_HOST_WORDSIZE - 1) / NACL_HOST_WORDSIZE;
334 size_t i, j; 350 size_t i, j;
335 Bool result = TRUE; 351 Bool result = TRUE;
336 352
337 for (i = 0; i < elements ; i++) { 353 for (i = 0; i < elements ; i++) {
338 bitmap_word jump_dest_mask = jump_dests[i]; 354 bitmap_word jump_dest_mask = jump_dests[i];
339 bitmap_word valid_target_mask = valid_targets[i]; 355 bitmap_word valid_target_mask = valid_targets[i];
340 if ((jump_dest_mask & ~valid_target_mask) != 0) { 356 if ((jump_dest_mask & ~valid_target_mask) != 0) {
341 for (j = i * NACL_HOST_WORDSIZE; j < (i + 1) * NACL_HOST_WORDSIZE; j++) 357 for (j = i * NACL_HOST_WORDSIZE; j < (i + 1) * NACL_HOST_WORDSIZE; j++)
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 rip[-2] + 256U * ((uint32_t) rip[-1])))); 402 rip[-2] + 256U * ((uint32_t) rip[-1]))));
387 size_t jump_dest = offset + (rip - codeblock_start); 403 size_t jump_dest = offset + (rip - codeblock_start);
388 404
389 if (MarkJumpTarget(jump_dest, jump_dests, jumpdests_size)) 405 if (MarkJumpTarget(jump_dest, jump_dests, jumpdests_size))
390 *instruction_info_collected |= RELATIVE_32BIT; 406 *instruction_info_collected |= RELATIVE_32BIT;
391 else 407 else
392 *instruction_info_collected |= RELATIVE_32BIT | DIRECT_JUMP_OUT_OF_RANGE; 408 *instruction_info_collected |= RELATIVE_32BIT | DIRECT_JUMP_OUT_OF_RANGE;
393 } 409 }
394 410
395 static INLINE void check_access(ptrdiff_t instruction_start, 411 static INLINE void check_access(ptrdiff_t instruction_start,
396 enum register_name base, 412 enum OperandName base,
397 enum register_name index, 413 enum OperandName index,
398 uint8_t restricted_register, 414 uint8_t restricted_register,
399 bitmap_word *valid_targets, 415 bitmap_word *valid_targets,
400 uint32_t *instruction_info_collected) { 416 uint32_t *instruction_info_collected) {
401 if ((base == REG_RIP) || (base == REG_R15) || 417 if ((base == REG_RIP) || (base == REG_R15) ||
402 (base == REG_RSP) || (base == REG_RBP)) { 418 (base == REG_RSP) || (base == REG_RBP)) {
403 if ((index == NO_REG) || (index == REG_RIZ)) 419 if ((index == NO_REG) || (index == REG_RIZ))
404 { /* do nothing. */ } 420 { /* do nothing. */ }
405 else if (index == restricted_register) 421 else if (index == restricted_register)
406 BitmapClearBit(valid_targets, instruction_start), 422 BitmapClearBit(valid_targets, instruction_start),
407 *instruction_info_collected |= RESTRICTED_REGISTER_USED; 423 *instruction_info_collected |= RESTRICTED_REGISTER_USED;
408 else 424 else
409 *instruction_info_collected |= UNRESTRICTED_INDEX_REGISTER; 425 *instruction_info_collected |= UNRESTRICTED_INDEX_REGISTER;
410 } else { 426 } else {
411 *instruction_info_collected |= FORBIDDEN_BASE_REGISTER; 427 *instruction_info_collected |= FORBIDDEN_BASE_REGISTER;
412 } 428 }
413 } 429 }
414 430
415 431
416 static INLINE void process_0_operands(enum register_name *restricted_register, 432 static INLINE void process_0_operands(enum OperandName *restricted_register,
417 uint32_t *instruction_info_collected) { 433 uint32_t *instruction_info_collected) {
418 /* Restricted %rsp or %rbp must be processed by appropriate nacl-special 434 /* Restricted %rsp or %rbp must be processed by appropriate nacl-special
419 * instruction, not with regular instruction. */ 435 * instruction, not with regular instruction. */
420 if (*restricted_register == REG_RSP) { 436 if (*restricted_register == REG_RSP) {
421 *instruction_info_collected |= RESTRICTED_RSP_UNPROCESSED; 437 *instruction_info_collected |= RESTRICTED_RSP_UNPROCESSED;
422 } else if (*restricted_register == REG_RBP) { 438 } else if (*restricted_register == REG_RBP) {
423 *instruction_info_collected |= RESTRICTED_RBP_UNPROCESSED; 439 *instruction_info_collected |= RESTRICTED_RBP_UNPROCESSED;
424 } 440 }
425 *restricted_register = NO_REG; 441 *restricted_register = NO_REG;
426 } 442 }
427 443
428 static INLINE void process_1_operand(enum register_name *restricted_register, 444 static INLINE void process_1_operand(enum OperandName *restricted_register,
429 uint32_t *instruction_info_collected, 445 uint32_t *instruction_info_collected,
430 uint8_t rex_prefix, 446 uint8_t rex_prefix,
431 uint32_t operand_states) { 447 uint32_t operand_states) {
432 /* Restricted %rsp or %rbp must be processed by appropriate nacl-special 448 /* Restricted %rsp or %rbp must be processed by appropriate nacl-special
433 * instruction, not with regular instruction. */ 449 * instruction, not with regular instruction. */
434 if (*restricted_register == REG_RSP) { 450 if (*restricted_register == REG_RSP) {
435 *instruction_info_collected |= RESTRICTED_RSP_UNPROCESSED; 451 *instruction_info_collected |= RESTRICTED_RSP_UNPROCESSED;
436 } else if (*restricted_register == REG_RBP) { 452 } else if (*restricted_register == REG_RBP) {
437 *instruction_info_collected |= RESTRICTED_RBP_UNPROCESSED; 453 *instruction_info_collected |= RESTRICTED_RBP_UNPROCESSED;
438 } 454 }
439 *restricted_register = NO_REG; 455 *restricted_register = NO_REG;
440 if (CHECK_OPERAND(0, REG_R15, OperandSandbox8bit) || 456 if (CHECK_OPERAND(0, REG_R15, OperandSandbox8bit) ||
441 CHECK_OPERAND(0, REG_R15, OperandSandboxRestricted) || 457 CHECK_OPERAND(0, REG_R15, OperandSandboxRestricted) ||
442 CHECK_OPERAND(0, REG_R15, OperandSandboxUnrestricted)) { 458 CHECK_OPERAND(0, REG_R15, OperandSandboxUnrestricted)) {
443 *instruction_info_collected |= R15_MODIFIED; 459 *instruction_info_collected |= R15_MODIFIED;
444 } else if ((CHECK_OPERAND(0, REG_RBP, OperandSandbox8bit) && rex_prefix) || 460 } else if ((CHECK_OPERAND(0, REG_RBP, OperandSandbox8bit) && rex_prefix) ||
445 CHECK_OPERAND(0, REG_RBP, OperandSandboxRestricted) || 461 CHECK_OPERAND(0, REG_RBP, OperandSandboxRestricted) ||
446 CHECK_OPERAND(0, REG_RBP, OperandSandboxUnrestricted)) { 462 CHECK_OPERAND(0, REG_RBP, OperandSandboxUnrestricted)) {
447 *instruction_info_collected |= BPL_MODIFIED; 463 *instruction_info_collected |= BPL_MODIFIED;
448 } else if ((CHECK_OPERAND(0, REG_RSP, OperandSandbox8bit) && rex_prefix) || 464 } else if ((CHECK_OPERAND(0, REG_RSP, OperandSandbox8bit) && rex_prefix) ||
449 CHECK_OPERAND(0, REG_RSP, OperandSandboxRestricted) || 465 CHECK_OPERAND(0, REG_RSP, OperandSandboxRestricted) ||
450 CHECK_OPERAND(0, REG_RSP, OperandSandboxUnrestricted)) { 466 CHECK_OPERAND(0, REG_RSP, OperandSandboxUnrestricted)) {
451 *instruction_info_collected |= SPL_MODIFIED; 467 *instruction_info_collected |= SPL_MODIFIED;
452 } 468 }
453 } 469 }
454 470
455 static INLINE void process_1_operand_zero_extends( 471 static INLINE void process_1_operand_zero_extends(
456 enum register_name *restricted_register, 472 enum OperandName *restricted_register,
457 uint32_t *instruction_info_collected, uint8_t rex_prefix, 473 uint32_t *instruction_info_collected, uint8_t rex_prefix,
458 uint32_t operand_states) { 474 uint32_t operand_states) {
459 /* Restricted %rsp or %rbp must be processed by appropriate nacl-special 475 /* Restricted %rsp or %rbp must be processed by appropriate nacl-special
460 * instruction, not with regular instruction. */ 476 * instruction, not with regular instruction. */
461 if (*restricted_register == REG_RSP) { 477 if (*restricted_register == REG_RSP) {
462 *instruction_info_collected |= RESTRICTED_RSP_UNPROCESSED; 478 *instruction_info_collected |= RESTRICTED_RSP_UNPROCESSED;
463 } else if (*restricted_register == REG_RBP) { 479 } else if (*restricted_register == REG_RBP) {
464 *instruction_info_collected |= RESTRICTED_RBP_UNPROCESSED; 480 *instruction_info_collected |= RESTRICTED_RBP_UNPROCESSED;
465 } 481 }
466 *restricted_register = NO_REG; 482 *restricted_register = NO_REG;
467 if (CHECK_OPERAND(0, REG_R15, OperandSandbox8bit) || 483 if (CHECK_OPERAND(0, REG_R15, OperandSandbox8bit) ||
468 CHECK_OPERAND(0, REG_R15, OperandSandboxRestricted) || 484 CHECK_OPERAND(0, REG_R15, OperandSandboxRestricted) ||
469 CHECK_OPERAND(0, REG_R15, OperandSandboxUnrestricted)) { 485 CHECK_OPERAND(0, REG_R15, OperandSandboxUnrestricted)) {
470 *instruction_info_collected |= R15_MODIFIED; 486 *instruction_info_collected |= R15_MODIFIED;
471 } else if ((CHECK_OPERAND(0, REG_RBP, OperandSandbox8bit) && rex_prefix) || 487 } else if ((CHECK_OPERAND(0, REG_RBP, OperandSandbox8bit) && rex_prefix) ||
472 CHECK_OPERAND(0, REG_RBP, OperandSandboxUnrestricted)) { 488 CHECK_OPERAND(0, REG_RBP, OperandSandboxUnrestricted)) {
473 *instruction_info_collected |= BPL_MODIFIED; 489 *instruction_info_collected |= BPL_MODIFIED;
474 } else if ((CHECK_OPERAND(0, REG_RSP, OperandSandbox8bit) && rex_prefix) || 490 } else if ((CHECK_OPERAND(0, REG_RSP, OperandSandbox8bit) && rex_prefix) ||
475 CHECK_OPERAND(0, REG_RSP, OperandSandboxUnrestricted)) { 491 CHECK_OPERAND(0, REG_RSP, OperandSandboxUnrestricted)) {
476 *instruction_info_collected |= SPL_MODIFIED; 492 *instruction_info_collected |= SPL_MODIFIED;
477 /* Take 2 bits of operand type from operand_states as *restricted_register, 493 /* Take 2 bits of operand type from operand_states as *restricted_register,
478 * make sure operand_states denotes a register (4th bit == 0). */ 494 * make sure operand_states denotes a register (4th bit == 0). */
479 } else if ((operand_states & 0x70) == (OperandSandboxRestricted << 5)) { 495 } else if ((operand_states & 0x70) == (OperandSandboxRestricted << 5)) {
480 *restricted_register = operand_states & 0x0f; 496 *restricted_register = operand_states & 0x0f;
481 } 497 }
482 } 498 }
483 499
484 static INLINE void process_2_operands(enum register_name *restricted_register, 500 static INLINE void process_2_operands(enum OperandName *restricted_register,
485 uint32_t *instruction_info_collected, 501 uint32_t *instruction_info_collected,
486 uint8_t rex_prefix, 502 uint8_t rex_prefix,
487 uint32_t operand_states) { 503 uint32_t operand_states) {
488 /* Restricted %rsp or %rbp must be processed by appropriate nacl-special 504 /* Restricted %rsp or %rbp must be processed by appropriate nacl-special
489 * instruction, not with regular instruction. */ 505 * instruction, not with regular instruction. */
490 if (*restricted_register == REG_RSP) { 506 if (*restricted_register == REG_RSP) {
491 *instruction_info_collected |= RESTRICTED_RSP_UNPROCESSED; 507 *instruction_info_collected |= RESTRICTED_RSP_UNPROCESSED;
492 } else if (*restricted_register == REG_RBP) { 508 } else if (*restricted_register == REG_RBP) {
493 *instruction_info_collected |= RESTRICTED_RBP_UNPROCESSED; 509 *instruction_info_collected |= RESTRICTED_RBP_UNPROCESSED;
494 } 510 }
(...skipping 15 matching lines...) Expand all
510 } else if ((CHECK_OPERAND(0, REG_RSP, OperandSandbox8bit) && rex_prefix) || 526 } else if ((CHECK_OPERAND(0, REG_RSP, OperandSandbox8bit) && rex_prefix) ||
511 CHECK_OPERAND(0, REG_RSP, OperandSandboxRestricted) || 527 CHECK_OPERAND(0, REG_RSP, OperandSandboxRestricted) ||
512 CHECK_OPERAND(0, REG_RSP, OperandSandboxUnrestricted) || 528 CHECK_OPERAND(0, REG_RSP, OperandSandboxUnrestricted) ||
513 (CHECK_OPERAND(1, REG_RSP, OperandSandbox8bit) && rex_prefix) || 529 (CHECK_OPERAND(1, REG_RSP, OperandSandbox8bit) && rex_prefix) ||
514 CHECK_OPERAND(1, REG_RSP, OperandSandboxRestricted) || 530 CHECK_OPERAND(1, REG_RSP, OperandSandboxRestricted) ||
515 CHECK_OPERAND(1, REG_RSP, OperandSandboxUnrestricted)) { 531 CHECK_OPERAND(1, REG_RSP, OperandSandboxUnrestricted)) {
516 *instruction_info_collected |= SPL_MODIFIED; 532 *instruction_info_collected |= SPL_MODIFIED;
517 } 533 }
518 } 534 }
519 535
520 static INLINE void process_2_operands_zero_extends( 536 static INLINE void process_2_operands_zero_extends(
Brad Chen 2012/10/05 16:47:21 All these non-standard procedure names need to be
khim 2012/10/15 16:38:57 Done.
521 enum register_name *restricted_register, 537 enum OperandName *restricted_register,
522 uint32_t *instruction_info_collected, 538 uint32_t *instruction_info_collected,
523 uint8_t rex_prefix, uint32_t operand_states) { 539 uint8_t rex_prefix, uint32_t operand_states) {
524 /* Restricted %rsp or %rbp must be processed by appropriate nacl-special 540 /* Restricted %rsp or %rbp must be processed by appropriate nacl-special
525 * instruction, not with regular instruction. */ 541 * instruction, not with regular instruction. */
526 if (*restricted_register == REG_RSP) { 542 if (*restricted_register == REG_RSP) {
527 *instruction_info_collected |= RESTRICTED_RSP_UNPROCESSED; 543 *instruction_info_collected |= RESTRICTED_RSP_UNPROCESSED;
528 } else if (*restricted_register == REG_RBP) { 544 } else if (*restricted_register == REG_RBP) {
529 *instruction_info_collected |= RESTRICTED_RBP_UNPROCESSED; 545 *instruction_info_collected |= RESTRICTED_RBP_UNPROCESSED;
530 } 546 }
531 *restricted_register = NO_REG; 547 *restricted_register = NO_REG;
(...skipping 23 matching lines...) Expand all
555 } else if (CHECK_OPERAND(1, REG_RBP, OperandSandboxRestricted)) { 571 } else if (CHECK_OPERAND(1, REG_RBP, OperandSandboxRestricted)) {
556 *instruction_info_collected |= RESTRICTED_RBP_UNPROCESSED; 572 *instruction_info_collected |= RESTRICTED_RBP_UNPROCESSED;
557 } 573 }
558 /* Take 2 bits of operand type from operand_states as *restricted_register, 574 /* Take 2 bits of operand type from operand_states as *restricted_register,
559 * make sure operand_states denotes a register (12th bit == 0). */ 575 * make sure operand_states denotes a register (12th bit == 0). */
560 } else if ((operand_states & 0x7000) == (OperandSandboxRestricted << 13)) { 576 } else if ((operand_states & 0x7000) == (OperandSandboxRestricted << 13)) {
561 *restricted_register = (operand_states & 0x0f00) >> 8; 577 *restricted_register = (operand_states & 0x0f00) >> 8;
562 } 578 }
563 } 579 }
564 580
581 /*
582 * This action redefines the range of the superinstruction to include the
583 * preceding sandboxing sequence then invalidates jump targets on the
584 * interior of the superinstructions and finally clears “the restricted
585 * register” variable.
586 */
587 static INLINE void ProcessNaclCallOrNaclJmp(
Brad Chen 2012/10/05 16:47:21 This is a big improvement. Now it's much easier to
khim 2012/10/15 16:38:57 Done.
588 uint32_t *instruction_info_collected, const uint8_t **instruction_start,
589 const uint8_t *current_position, const uint8_t *data,
590 bitmap_word *valid_targets, Bool and_have_rex, Bool add_stores_to_reg) {
591 /* Expand the range. Only expand by 6 bytes: this covers “add” (second
592 * instruction) and “and” WITHOUT it's REX prefix.
593 */
594 *instruction_start -= 6;
595 /* Compare registers used by “and”, “add”, and “call” or “jmp”. */
596 if (RMFromModRM((*instruction_start)[1]) !=
597 (add_stores_to_reg ? RegFromModRM((*instruction_start)[5]) :
598 RMFromModRM((*instruction_start)[5])) ||
599 RMFromModRM((*instruction_start)[1]) != RMFromModRM(current_position[0]))
600 *instruction_info_collected |= UNRECOGNIZED_INSTRUCTION;
601 /* Make start of the second and third instruction not valid targets. */
602 MakeInvalidJumpTarget((*instruction_start - data) + 3, valid_targets);
603 MakeInvalidJumpTarget((*instruction_start - data) + 6, valid_targets);
604 /* Expand the range again. This time to cover REX prefix (if any). */
605 if (and_have_rex) --*instruction_start;
606 }
607
608 /*
609 * This action redefines the range of the superinstruction to include the
610 * preceding sandboxing sequence then invalidates jump targets on the interior
611 * of the superinstruction.
612 */
613 static INLINE void SandboxRsiOrRdiMakeInteriorInvalidJumpTargets(
614 const uint8_t **instruction_start, const uint8_t *data,
615 bitmap_word *valid_targets, Bool mov_have_rex) {
616 /* Expand the range. Only expand by 6 bytes: this covers “lea” (second
617 * instruction) and “mov” WITHOUT it's REX prefix.
618 */
619 *instruction_start -= 6;
620 MakeInvalidJumpTarget((*instruction_start - data) + 2, valid_targets);
621 MakeInvalidJumpTarget((*instruction_start - data) + 6, valid_targets);
622 /* Expand the range again. This time to cover REX prefix (if any). */
623 if (mov_have_rex) --*instruction_start;
624 }
625
565 #endif /* NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_VALIDATOR_INTERNAL_H_ */ 626 #endif /* NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_VALIDATOR_INTERNAL_H_ */
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698