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

Side by Side Diff: src/trusted/validator/x86/ncval_reg_sfi/nc_protect_base.c

Issue 7980021: Speed up x86-64 validator by inlining heavily called routines. Speeds up (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client/
Patch Set: '' Created 9 years, 3 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) 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 /* nc_protect_base.h - For 64-bit mode, verifies that no instruction 7 /* nc_protect_base.h - For 64-bit mode, verifies that no instruction
8 * changes the value of the base register, that the invariant between 8 * changes the value of the base register, that the invariant between
9 * RSP and RBP is maintained, and that segment registers are not set. 9 * RSP and RBP is maintained, and that segment registers are not set.
10 */ 10 */
11 #include <assert.h> 11 #include <assert.h>
12 12
13 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/nc_protect_base. h" 13 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/nc_protect_base. h"
14 14
15 #include "native_client/src/shared/platform/nacl_log.h" 15 #include "native_client/src/shared/platform/nacl_log.h"
16 #include "native_client/src/trusted/validator/x86/decoder/ncop_exps.h"
17 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_iter.h"
18 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_state_internal .h" 16 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_state_internal .h"
19 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_trans.h" 17 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_trans.h"
20 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncvalidate_iter. h" 18 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncvalidate_iter. h"
21 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncvalidate_iter_ internal.h" 19 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncvalidate_iter_ internal.h"
22 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncvalidate_utils .h" 20 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncvalidate_utils .h"
23 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/nc_jumps.h" 21 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/nc_jumps.h"
24 22
25 /* To turn on debugging of instruction decoding, change value of 23 /* To turn on debugging of instruction decoding, change value of
26 * DEBUGGING to 1. 24 * DEBUGGING to 1.
27 */ 25 */
28 #define DEBUGGING 0 26 #define DEBUGGING 0
29 27
30 #include "native_client/src/shared/utils/debugging.h" 28 #include "native_client/src/shared/utils/debugging.h"
31 29
30 #include "native_client/src/trusted/validator/x86/decoder/ncopcode_desc_inl.c"
31 #include "native_client/src/trusted/validator/x86/decoder/ncop_exps_inl.c"
32 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_iter_inl.c"
33
32 /* Defines locals used by the NaClBaseRegisterValidator to 34 /* Defines locals used by the NaClBaseRegisterValidator to
33 * record registers set in the current instruction, that are 35 * record registers set in the current instruction, that are
34 * a problem if not used correctly in the next instruction. 36 * a problem if not used correctly in the next instruction.
35 */ 37 */
36 typedef struct NaClRegisterLocals { 38 typedef struct NaClRegisterLocals {
37 /* Points to an instruction that contains an assignment to register ESP, 39 /* Points to an instruction that contains an assignment to register ESP,
38 * or NULL if the instruction doesn't set ESP. This is done so that we 40 * or NULL if the instruction doesn't set ESP. This is done so that we
39 * can check if the next instruction uses the value of ESP to update RSP 41 * can check if the next instruction uses the value of ESP to update RSP
40 * (if not, we need to report that ESP is incorrectly assigned). 42 * (if not, we need to report that ESP is incorrectly assigned).
41 */ 43 */
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 } 136 }
135 137
136 /* Returns true if the instruction is of the form 138 /* Returns true if the instruction is of the form
137 * OP %esp, C 139 * OP %esp, C
138 * where OP in { add , sub } and C is a 32 bit constant. 140 * where OP in { add , sub } and C is a 32 bit constant.
139 */ 141 */
140 static Bool NaClIsAddOrSubBoundedConstFromEsp(NaClInstState* state) { 142 static Bool NaClIsAddOrSubBoundedConstFromEsp(NaClInstState* state) {
141 const NaClInst* inst = NaClInstStateInst(state); 143 const NaClInst* inst = NaClInstStateInst(state);
142 NaClExpVector* vector = NaClInstStateExpVector(state); 144 NaClExpVector* vector = NaClInstStateExpVector(state);
143 return (InstAdd == inst->name || InstSub == inst->name) && 145 return (InstAdd == inst->name || InstSub == inst->name) &&
144 2 == NaClGetInstNumberOperands(inst) && 146 2 == NaClGetInstNumberOperandsInline(inst) &&
145 /* Note: Since the vector contains a list of operand expressions, the 147 /* Note: Since the vector contains a list of operand expressions, the
146 * first operand reference is always at index zero, and its first child 148 * first operand reference is always at index zero, and its first child
147 * (where the register would be defined) is at index 1. 149 * (where the register would be defined) is at index 1.
148 */ 150 */
149 ExprRegister == vector->node[1].kind && 151 ExprRegister == vector->node[1].kind &&
150 RegESP == NaClGetExpRegister(&vector->node[1]) && 152 RegESP == NaClGetExpRegisterInline(&vector->node[1]) &&
151 /* Note: Since the first subtree is a register operand, it uses 153 /* Note: Since the first subtree is a register operand, it uses
152 * nodes 0 and 1 in the vector (node 0 is the operand reference, and 154 * nodes 0 and 1 in the vector (node 0 is the operand reference, and
153 * node 1 is its child defining a register value). The second operand 155 * node 1 is its child defining a register value). The second operand
154 * reference therefore lies at node 2, and if the operand is defined by 156 * reference therefore lies at node 2, and if the operand is defined by
155 * a 32 bit constant, it is the first kid of node 2, which is node 3. 157 * a 32 bit constant, it is the first kid of node 2, which is node 3.
156 */ 158 */
157 ExprConstant == vector->node[3].kind; 159 ExprConstant == vector->node[3].kind;
158 } 160 }
159 161
160 /* Returns true iff the instruction of form "lea _, [%reg+%rbase*1]" */ 162 /* Returns true iff the instruction of form "lea _, [%reg+%rbase*1]" */
161 static Bool NaClIsLeaAddressRegPlusRbase(NaClValidatorState* state, 163 static Bool NaClIsLeaAddressRegPlusRbase(NaClValidatorState* state,
162 NaClInstState* inst_state, 164 NaClInstState* inst_state,
163 NaClOpKind reg) { 165 NaClOpKind reg) {
164 const NaClInst* inst = NaClInstStateInst(inst_state); 166 const NaClInst* inst = NaClInstStateInst(inst_state);
165 assert((RegRSP == reg) || (RegRBP == reg)); 167 assert((RegRSP == reg) || (RegRBP == reg));
166 if (InstLea == inst->name && 168 if (InstLea == inst->name &&
167 2 == NaClGetInstNumberOperands(inst)) { 169 2 == NaClGetInstNumberOperandsInline(inst)) {
168 NaClExpVector* vector = NaClInstStateExpVector(inst_state); 170 NaClExpVector* vector = NaClInstStateExpVector(inst_state);
169 int op2_index = 171 int op2_index =
170 NaClGetExpKidIndex(vector, 172 NaClGetExpKidIndex(vector,
171 NaClGetNthExpKind(vector, OperandReference, 2), 173 NaClGetNthExpKind(vector, OperandReference, 2),
172 0); 174 0);
173 NaClExp* op2 = &(vector->node[op2_index]); 175 NaClExp* op2 = &(vector->node[op2_index]);
174 /* Only allow memory offset nodes with address size 64. */ 176 /* Only allow memory offset nodes with address size 64. */
175 if (ExprMemOffset == op2->kind && 177 if (ExprMemOffset == op2->kind &&
176 NACL_EMPTY_EFLAGS != (op2->flags & NACL_EFLAG(ExprSize64))) { 178 NACL_EMPTY_EFLAGS != (op2->flags & NACL_EFLAG(ExprSize64))) {
177 int base_reg_index = op2_index + 1; 179 int base_reg_index = op2_index + 1;
(...skipping 30 matching lines...) Expand all
208 * the corresponding 32-bit retister. 210 * the corresponding 32-bit retister.
209 */ 211 */
210 212
211 static Bool NaClAcceptRegMoveLea32To64(struct NaClValidatorState* state, 213 static Bool NaClAcceptRegMoveLea32To64(struct NaClValidatorState* state,
212 struct NaClInstIter* iter, 214 struct NaClInstIter* iter,
213 const NaClInst* inst, 215 const NaClInst* inst,
214 NaClOpKind reg) { 216 NaClOpKind reg) {
215 NaClInstState* inst_state = state->cur_inst_state; 217 NaClInstState* inst_state = state->cur_inst_state;
216 assert((RegRSP == reg) || (RegRBP == reg)); 218 assert((RegRSP == reg) || (RegRBP == reg));
217 if (NaClOperandOneIsRegisterSet(inst_state, reg) && 219 if (NaClOperandOneIsRegisterSet(inst_state, reg) &&
218 NaClInstIterHasLookbackState(iter, 1)) { 220 NaClInstIterHasLookbackStateInline(iter, 1)) {
219 NaClInstState* prev_inst = NaClInstIterGetLookbackState(iter, 1); 221 NaClInstState* prev_inst = NaClInstIterGetLookbackStateInline(iter, 1);
220 if (NaClAssignsRegisterWithZeroExtends( 222 if (NaClAssignsRegisterWithZeroExtends(
221 prev_inst, NaClGet32For64BitReg(reg)) && 223 prev_inst, NaClGet32For64BitReg(reg)) &&
222 NaClIsLeaAddressRegPlusRbase(state, inst_state, reg)) { 224 NaClIsLeaAddressRegPlusRbase(state, inst_state, reg)) {
223 DEBUG(const char* reg_name = NaClOpKindName(reg); 225 DEBUG(const char* reg_name = NaClOpKindName(reg);
224 printf("nc protect base for 'lea %s. [%s, rbase]'\n", 226 printf("nc protect base for 'lea %s. [%s, rbase]'\n",
225 reg_name, reg_name)); 227 reg_name, reg_name));
226 NaClMarkInstructionJumpIllegal(state, inst_state); 228 NaClMarkInstructionJumpIllegal(state, inst_state);
227 return TRUE; 229 return TRUE;
228 } 230 }
229 } 231 }
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 if (i == 3) return; 318 if (i == 3) return;
317 break; 319 break;
318 case InstOr: 320 case InstOr:
319 case InstAdd: 321 case InstAdd:
320 { 322 {
321 /* case 2/4 (depending on instruction name). */ 323 /* case 2/4 (depending on instruction name). */
322 if (NaClIsBinarySetUsingRegisters( 324 if (NaClIsBinarySetUsingRegisters(
323 state->decoder_tables, 325 state->decoder_tables,
324 inst, inst_name, vector, RegRSP, 326 inst, inst_name, vector, RegRSP,
325 state->base_register) && 327 state->base_register) &&
326 NaClInstIterHasLookbackState(iter, 1)) { 328 NaClInstIterHasLookbackStateInline(iter, 1)) {
327 NaClInstState* prev_inst = 329 NaClInstState* prev_inst =
328 NaClInstIterGetLookbackState(iter, 1); 330 NaClInstIterGetLookbackStateInline(iter, 1);
329 if (NaClAssignsRegisterWithZeroExtends(prev_inst, RegESP) 331 if (NaClAssignsRegisterWithZeroExtends(prev_inst, RegESP)
330 || (inst_name == InstAdd && 332 || (inst_name == InstAdd &&
331 NaClIsAddOrSubBoundedConstFromEsp(prev_inst))) { 333 NaClIsAddOrSubBoundedConstFromEsp(prev_inst))) {
332 /* Found that the assignment to ESP in previous instruction 334 /* Found that the assignment to ESP in previous instruction
333 * is legal, so long as the two instructions are atomic. 335 * is legal, so long as the two instructions are atomic.
334 */ 336 */
335 DEBUG(printf("nc protect esp for zero extend, or or/add " 337 DEBUG(printf("nc protect esp for zero extend, or or/add "
336 "constant\n")); 338 "constant\n"));
337 NaClMarkInstructionJumpIllegal(state, inst_state); 339 NaClMarkInstructionJumpIllegal(state, inst_state);
338 locals->buffer[locals->previous_index].esp_set_inst = NULL; 340 locals->buffer[locals->previous_index].esp_set_inst = NULL;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 * 416 *
415 * Note: We require the scale to be 1, and rbase be in 417 * Note: We require the scale to be 1, and rbase be in
416 * the index position. 418 * the index position.
417 */ 419 */
418 NaClInstState* inst_state = state->cur_inst_state; 420 NaClInstState* inst_state = state->cur_inst_state;
419 const NaClInst* inst = state->cur_inst; 421 const NaClInst* inst = state->cur_inst;
420 NaClMnemonic inst_name = inst->name; 422 NaClMnemonic inst_name = inst->name;
421 NaClExpVector* vector = state->cur_inst_vector; 423 NaClExpVector* vector = state->cur_inst_vector;
422 switch (inst_name) { 424 switch (inst_name) {
423 case InstAdd: 425 case InstAdd:
424 if (NaClInstIterHasLookbackState(iter, 1)) { 426 if (NaClInstIterHasLookbackStateInline(iter, 1)) {
425 NaClInstState* prev_state = 427 NaClInstState* prev_state =
426 NaClInstIterGetLookbackState(iter, 1); 428 NaClInstIterGetLookbackStateInline(iter, 1);
427 if (NaClIsBinarySetUsingRegisters( 429 if (NaClIsBinarySetUsingRegisters(
428 state->decoder_tables, 430 state->decoder_tables,
429 inst, InstAdd, vector, 431 inst, InstAdd, vector,
430 RegRBP, state->base_register) && 432 RegRBP, state->base_register) &&
431 NaClAssignsRegisterWithZeroExtends( 433 NaClAssignsRegisterWithZeroExtends(
432 prev_state, RegEBP)) { 434 prev_state, RegEBP)) {
433 /* case 2. */ 435 /* case 2. */
434 NaClMarkInstructionJumpIllegal(state, inst_state); 436 NaClMarkInstructionJumpIllegal(state, inst_state);
435 locals->buffer[locals->previous_index].ebp_set_inst = NULL; 437 locals->buffer[locals->previous_index].ebp_set_inst = NULL;
436 return; 438 return;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 NaClExpVector* vector = state->cur_inst_vector; 495 NaClExpVector* vector = state->cur_inst_vector;
494 496
495 DEBUG(NaClValidatorInstMessage( 497 DEBUG(NaClValidatorInstMessage(
496 LOG_INFO, state, inst_state, "Checking base registers...\n")); 498 LOG_INFO, state, inst_state, "Checking base registers...\n"));
497 499
498 /* Look for assignments to registers. */ 500 /* Look for assignments to registers. */
499 for (i = 0; i < vector->number_expr_nodes; ++i) { 501 for (i = 0; i < vector->number_expr_nodes; ++i) {
500 NaClExp* node = &vector->node[i]; 502 NaClExp* node = &vector->node[i];
501 if (ExprRegister == node->kind) { 503 if (ExprRegister == node->kind) {
502 if (node->flags & NACL_EFLAG(ExprSet)) { 504 if (node->flags & NACL_EFLAG(ExprSet)) {
503 NaClOpKind reg_name = NaClGetExpRegister(node); 505 NaClOpKind reg_name = NaClGetExpRegisterInline(node);
504 506
505 /* If reached, found an assignment to a register. 507 /* If reached, found an assignment to a register.
506 * Check if its one that we care about (i.e. 508 * Check if its one that we care about (i.e.
507 * the base register (RBASE), RSP, RBP, or segment register). 509 * the base register (RBASE), RSP, RBP, or segment register).
508 */ 510 */
509 if (reg_name == state->base_register) { 511 if (reg_name == state->base_register) {
510 NaClValidatorInstMessage( 512 NaClValidatorInstMessage(
511 LOG_ERROR, state, inst_state, 513 LOG_ERROR, state, inst_state,
512 "Illegal to change the value of register %s\n", 514 "Illegal to change the value of register %s\n",
513 NaClOpKindName(state->base_register)); 515 NaClOpKindName(state->base_register));
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 */ 557 */
556 NaClMaybeReportPreviousBad(state, locals); 558 NaClMaybeReportPreviousBad(state, locals);
557 } 559 }
558 560
559 void NaClBaseRegisterSummarize(struct NaClValidatorState* state, 561 void NaClBaseRegisterSummarize(struct NaClValidatorState* state,
560 struct NaClInstIter* iter, 562 struct NaClInstIter* iter,
561 struct NaClBaseRegisterLocals* locals) { 563 struct NaClBaseRegisterLocals* locals) {
562 /* Check if problems in last instruction of segment. */ 564 /* Check if problems in last instruction of segment. */
563 NaClMaybeReportPreviousBad(state, locals); 565 NaClMaybeReportPreviousBad(state, locals);
564 } 566 }
OLDNEW
« no previous file with comments | « src/trusted/validator/x86/ncval_reg_sfi/nc_memory_protect.c ('k') | src/trusted/validator/x86/ncval_reg_sfi/ncvalidate_iter.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698