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

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

Powered by Google App Engine
This is Rietveld 408576698