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

Side by Side Diff: src/trusted/validator_ragel/unreviewed/validator-x86_64.rl

Issue 10392066: validator_ragel: Use different actions for different types of commands (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client/
Patch Set: Created 8 years, 7 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
« no previous file with comments | « src/trusted/validator_ragel/unreviewed/gen-dfa.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #include <assert.h> 7 #include <assert.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <stdio.h> 9 #include <stdio.h>
10 #include <stdlib.h> 10 #include <stdlib.h>
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 action rel16_operand { 81 action rel16_operand {
82 assert(FALSE); 82 assert(FALSE);
83 } 83 }
84 action rel32_operand { 84 action rel32_operand {
85 int32_t offset = 85 int32_t offset =
86 (uint32_t) (p[-3] + 256U * (p[-2] + 256U * (p[-1] + 256U * (p[0])))); 86 (uint32_t) (p[-3] + 256U * (p[-2] + 256U * (p[-1] + 256U * (p[0]))));
87 size_t jump_dest = offset + (p - data); 87 size_t jump_dest = offset + (p - data);
88 check_jump_dest; 88 check_jump_dest;
89 } 89 }
90 90
91 include decode_x86_64 "validator-x86_64-instruction.rl"; 91 action process_0_operands {
92
93 action process_normal_instruction {
94 /* Restricted %rsp or %rbp must be processed by appropriate nacl-special 92 /* Restricted %rsp or %rbp must be processed by appropriate nacl-special
95 instruction, not with regular instruction. */ 93 * instruction, not with regular instruction. */
96 if (restricted_register == REG_RSP) { 94 if (restricted_register == REG_RSP) {
97 PrintError("Incorrectly modified register %%rsp\n", begin - data); 95 PrintError("Incorrectly modified register %%rsp\n", begin - data);
98 result = 1; 96 result = 1;
97 goto error_detected;
98 } else if (restricted_register == REG_RBP) {
99 PrintError("Incorrectly modified register %%rbp\n", begin - data);
100 result = 1;
101 goto error_detected;
102 }
103 restricted_register = kNoRestrictedReg;
104 }
105
106 action process_1_operands {
107 /* Restricted %rsp or %rbp must be processed by appropriate nacl-special
108 * instruction, not with regular instruction. */
109 if (restricted_register == REG_RSP) {
110 PrintError("Incorrectly modified register %%rsp\n", begin - data);
111 result = 1;
99 goto error_detected; 112 goto error_detected;
100 } else if (restricted_register == REG_RBP) { 113 } else if (restricted_register == REG_RBP) {
101 PrintError("Incorrectly modified register %%rbp\n", begin - data); 114 PrintError("Incorrectly modified register %%rbp\n", begin - data);
102 result = 1; 115 result = 1;
103 goto error_detected; 116 goto error_detected;
104 } 117 }
105 /* If Sandboxed Rsi is destroyed then we must note that. */ 118 /* If Sandboxed Rsi is destroyed then we must detect that. */
119 if (restricted_register == kSandboxedRsi) {
120 if (CHECK_OPERAND(0, REG_RSI, OperandSandboxRestricted) ||
121 CHECK_OPERAND(0, REG_RSI, OperandSandboxUnrestricted)) {
122 restricted_register = kNoRestrictedReg;
123 }
124 }
125 if (restricted_register == kSandboxedRsi) {
126 if (CHECK_OPERAND(0, REG_RDI, OperandSandboxRestricted)) {
127 sandboxed_rsi_restricted_rdi = begin;
128 restricted_register = kSandboxedRsiRestrictedRdi;
129 }
130 }
131 if (restricted_register != kSandboxedRsiRestrictedRdi) {
132 restricted_register = kNoRestrictedReg;
133 if (CHECK_OPERAND(0, REG_R15, OperandSandbox8bit) ||
134 CHECK_OPERAND(0, REG_R15, OperandSandboxRestricted) ||
135 CHECK_OPERAND(0, REG_R15, OperandSandboxUnrestricted)) {
136 PrintError("Incorrectly modified register %%r15\n", begin - data);
137 result = 1;
138 goto error_detected;
139 } else if ((CHECK_OPERAND(0, REG_RBP, OperandSandbox8bit) &&
140 GET_REX_PREFIX()) ||
141 CHECK_OPERAND(0, REG_RBP, OperandSandboxUnrestricted)) {
142 PrintError("Incorrectly modified register %%rbp\n", begin - data);
143 result = 1;
144 goto error_detected;
145 } else if ((CHECK_OPERAND(0, REG_RSP, OperandSandbox8bit) &&
146 GET_REX_PREFIX()) ||
147 CHECK_OPERAND(0, REG_RSP, OperandSandboxUnrestricted)) {
148 PrintError("Incorrectly modified register %%rsp\n", begin - data);
149 result = 1;
150 goto error_detected;
151 /* Take 2 bits of operand type from operand_states as restricted_register,
152 * make sure operand_states denotes a register (4th bit == 0). */
153 } else if ((operand_states & 0x70) == (OperandSandboxRestricted << 5)) {
154 restricted_register = operand_states & 0x0f;
155 }
156 }
157 }
158
159 action process_2_operands {
160 /* Restricted %rsp or %rbp must be processed by appropriate nacl-special
161 * instruction, not with regular instruction. */
162 if (restricted_register == REG_RSP) {
163 PrintError("Incorrectly modified register %%rsp\n", begin - data);
164 result = 1;
165 goto error_detected;
166 } else if (restricted_register == REG_RBP) {
167 PrintError("Incorrectly modified register %%rbp\n", begin - data);
168 result = 1;
169 goto error_detected;
170 }
171 /* If Sandboxed Rsi is destroyed then we must detect that. */
106 if (restricted_register == kSandboxedRsi) { 172 if (restricted_register == kSandboxedRsi) {
107 if (CHECK_OPERAND(0, REG_RSI, OperandSandboxRestricted) || 173 if (CHECK_OPERAND(0, REG_RSI, OperandSandboxRestricted) ||
108 CHECK_OPERAND(0, REG_RSI, OperandSandboxUnrestricted) || 174 CHECK_OPERAND(0, REG_RSI, OperandSandboxUnrestricted) ||
109 CHECK_OPERAND(1, REG_RSI, OperandSandboxRestricted) || 175 CHECK_OPERAND(1, REG_RSI, OperandSandboxRestricted) ||
110 CHECK_OPERAND(1, REG_RSI, OperandSandboxUnrestricted)) { 176 CHECK_OPERAND(1, REG_RSI, OperandSandboxUnrestricted)) {
111 restricted_register = kNoRestrictedReg; 177 restricted_register = kNoRestrictedReg;
112 } 178 }
113 } 179 }
114 if (restricted_register == kSandboxedRsi) { 180 if (restricted_register == kSandboxedRsi) {
115 if (CHECK_OPERAND(0, REG_RDI, OperandSandboxRestricted) || 181 if (CHECK_OPERAND(0, REG_RDI, OperandSandboxRestricted) ||
(...skipping 24 matching lines...) Expand all
140 goto error_detected; 206 goto error_detected;
141 } else if ((CHECK_OPERAND(0, REG_RSP, OperandSandbox8bit) && 207 } else if ((CHECK_OPERAND(0, REG_RSP, OperandSandbox8bit) &&
142 GET_REX_PREFIX()) || 208 GET_REX_PREFIX()) ||
143 CHECK_OPERAND(0, REG_RSP, OperandSandboxUnrestricted) || 209 CHECK_OPERAND(0, REG_RSP, OperandSandboxUnrestricted) ||
144 (CHECK_OPERAND(1, REG_RSP, OperandSandbox8bit) && 210 (CHECK_OPERAND(1, REG_RSP, OperandSandbox8bit) &&
145 GET_REX_PREFIX()) || 211 GET_REX_PREFIX()) ||
146 CHECK_OPERAND(1, REG_RSP, OperandSandboxUnrestricted)) { 212 CHECK_OPERAND(1, REG_RSP, OperandSandboxUnrestricted)) {
147 PrintError("Incorrectly modified register %%rsp\n", begin - data); 213 PrintError("Incorrectly modified register %%rsp\n", begin - data);
148 result = 1; 214 result = 1;
149 goto error_detected; 215 goto error_detected;
216 /* Take 2 bits of operand type from operand_states as restricted_register,
217 * make sure operand_states denotes a register (4th bit == 0). */
150 } else if ((operand_states & 0x70) == (OperandSandboxRestricted << 5)) { 218 } else if ((operand_states & 0x70) == (OperandSandboxRestricted << 5)) {
151 restricted_register = operand_states & 0x0f; 219 restricted_register = operand_states & 0x0f;
220 /* Take 2 bits of operand type from operand_states as restricted_register,
221 * make sure operand_states denotes a register (12th bit == 0). */
152 } else if ((operand_states & 0x7000) == 222 } else if ((operand_states & 0x7000) ==
153 (OperandSandboxRestricted << (5 + 8))) { 223 (OperandSandboxRestricted << (5 + 8))) {
154 restricted_register = (operand_states & 0x0f00) >> 8; 224 restricted_register = (operand_states & 0x0f00) >> 8;
155 } 225 }
156 } 226 }
157 } 227 }
158 228
229 include decode_x86_64 "validator-x86_64-instruction.rl";
230
159 # Remove special instructions which are only allowed in special cases. 231 # Remove special instructions which are only allowed in special cases.
160 normal_instruction = (one_instruction - ( 232 normal_instruction = one_instruction - (
161 (0x48 0x89 0xe5) | # mov %rsp,%rbp 233 (0x48 0x89 0xe5) | # mov %rsp,%rbp
162 (0x48 0x89 0xec) | # mov %rbp,%rsp 234 (0x48 0x89 0xec) | # mov %rbp,%rsp
163 (0x48 0x81 0xe4 any{4}) | # and $XXX,%rsp 235 (0x48 0x81 0xe4 any{4}) | # and $XXX,%rsp
164 (0x48 0x83 0xe4 any) | # and $XXX,%rsp 236 (0x48 0x83 0xe4 any) | # and $XXX,%rsp
165 (0x4c 0x01 0xfd) | # add %r15,%rbp 237 (0x4c 0x01 0xfd) | # add %r15,%rbp
166 (0x49 0x8d 0x2c 0x2f) | # lea (%r15,%rbp,1),%rbp 238 (0x49 0x8d 0x2c 0x2f) | # lea (%r15,%rbp,1),%rbp
167 (0x4a 0x8d 0x6c 0x3d any) | # lea 0x0(%rbp,%r15,1),%rbp 239 (0x4a 0x8d 0x6c 0x3d any) | # lea 0x0(%rbp,%r15,1),%rbp
168 (0x48 0x81 0xe5 any{4}) | # and $XXX,%rsp 240 (0x48 0x81 0xe5 any{4}) | # and $XXX,%rsp
169 (0x48 0x83 0xe5 any) | # and $XXX,%rsp 241 (0x48 0x83 0xe5 any) | # and $XXX,%rsp
170 (0x4c 0x01 0xfc) | # add %r15,%rsp 242 (0x4c 0x01 0xfc) | # add %r15,%rsp
171 (0x4a 0x8d 0x24 0x3c) | # lea (%rsp,%r15,1),%rsp 243 (0x4a 0x8d 0x24 0x3c) | # lea (%rsp,%r15,1),%rsp
172 (0x49 0x8d 0x34 0x37) | # lea (%r15,%rsi,1),%rsi 244 (0x49 0x8d 0x34 0x37) | # lea (%r15,%rsi,1),%rsi
173 (0x49 0x8d 0x3c 0x3f) # lea (%r15,%rdi,1),%rdi 245 (0x49 0x8d 0x3c 0x3f) # lea (%r15,%rdi,1),%rdi
174 )) @process_normal_instruction; 246 );
175 247
176 data16condrep = (data16 | condrep data16 | data16 condrep); 248 data16condrep = (data16 | condrep data16 | data16 condrep);
177 data16rep = (data16 | rep data16 | data16 rep); 249 data16rep = (data16 | rep data16 | data16 rep);
178 250
179 special_instruction = 251 special_instruction =
180 (0x48 0x89 0xe5) | # mov %rsp,%rbp 252 (0x48 0x89 0xe5) | # mov %rsp,%rbp
181 (0x48 0x81 0xe4 any{3} (0x80 .. 0xff)) | # and $XXX,%rsp 253 (0x48 0x81 0xe4 any{3} (0x80 .. 0xff)) | # and $XXX,%rsp
182 (0x48 0x83 0xe4 (0x80 .. 0xff)) # and $XXX,%rsp 254 (0x48 0x83 0xe4 (0x80 .. 0xff)) # and $XXX,%rsp
183 @{ if (restricted_register == REG_RSP) { 255 @{ if (restricted_register == REG_RSP) {
184 PrintError("Incorrectly modified register %%rsp\n", begin - data); 256 PrintError("Incorrectly modified register %%rsp\n", begin - data);
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 * OperandSandboxUnrestricted to match the behavior of the old validator. 444 * OperandSandboxUnrestricted to match the behavior of the old validator.
373 * 445 *
374 * 8bit operands must be distinguished from other types because the REX prefix 446 * 8bit operands must be distinguished from other types because the REX prefix
375 * regulates the choice between %ah and %spl, as well as %ch and %bpl. 447 * regulates the choice between %ah and %spl, as well as %ch and %bpl.
376 */ 448 */
377 OperandSandbox8bit, 449 OperandSandbox8bit,
378 OperandSandboxRestricted, 450 OperandSandboxRestricted,
379 OperandSandboxUnrestricted 451 OperandSandboxUnrestricted
380 }; 452 };
381 453
382 /* Define SET_OPERAND_NAME as SET_OPERAND_NAME_0, SET_OPERAND_NAME_1 to detect 454 #define SET_OPERAND_NAME(N, S) operand_states |= ((S) << ((N) << 3))
383 * cases where more than two general purpose registers are affected. This will
384 * produce a compile-time error if an operand with unexpected number is
385 * encountered. */
386 #define SET_OPERAND_NAME(N, S) SET_OPERAND_NAME_ ## N(S)
387 #define SET_OPERAND_NAME_0(S) operand_states |= (S)
388 #define SET_OPERAND_NAME_1(S) operand_states |= ((S) << 8)
389 #define SET_OPERAND_TYPE(N, T) SET_OPERAND_TYPE_ ## T(N) 455 #define SET_OPERAND_TYPE(N, T) SET_OPERAND_TYPE_ ## T(N)
390 #define SET_OPERAND_TYPE_OperandSize8bit(N) \ 456 #define SET_OPERAND_TYPE_OperandSize8bit(N) \
391 operand_states |= OperandSandbox8bit << (5 + ((N) << 3)) 457 operand_states |= OperandSandbox8bit << (5 + ((N) << 3))
392 #define SET_OPERAND_TYPE_OperandSize16bit(N) \ 458 #define SET_OPERAND_TYPE_OperandSize16bit(N) \
393 operand_states |= OperandSandboxUnrestricted << (5 + ((N) << 3)) 459 operand_states |= OperandSandboxUnrestricted << (5 + ((N) << 3))
394 #define SET_OPERAND_TYPE_OperandSize32bit(N) \ 460 #define SET_OPERAND_TYPE_OperandSize32bit(N) \
395 operand_states |= OperandSandboxRestricted << (5 + ((N) << 3)) 461 operand_states |= OperandSandboxRestricted << (5 + ((N) << 3))
396 #define SET_OPERAND_TYPE_OperandSize64bit(N) \ 462 #define SET_OPERAND_TYPE_OperandSize64bit(N) \
397 operand_states |= OperandSandboxUnrestricted << (5 + ((N) << 3)) 463 operand_states |= OperandSandboxUnrestricted << (5 + ((N) << 3))
398 #define CHECK_OPERAND(N, S, T) \ 464 #define CHECK_OPERAND(N, S, T) \
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 uint8_t rex_prefix = FALSE; 585 uint8_t rex_prefix = FALSE;
520 uint8_t vex_prefix2 = 0xe0; 586 uint8_t vex_prefix2 = 0xe0;
521 uint8_t vex_prefix3 = 0x00; 587 uint8_t vex_prefix3 = 0x00;
522 /* Keeps one byte of information per operand in the current instruction: 588 /* Keeps one byte of information per operand in the current instruction:
523 * 2 bits for register kinds, 589 * 2 bits for register kinds,
524 * 5 bits for register numbers (16 regs plus RIZ). */ 590 * 5 bits for register numbers (16 regs plus RIZ). */
525 int operand_states = 0; 591 int operand_states = 0;
526 enum register_name base = NO_REG; 592 enum register_name base = NO_REG;
527 enum register_name index = NO_REG; 593 enum register_name index = NO_REG;
528 int result = 0; 594 int result = 0;
529 /* 595 /* These are borders of the appropriate instructions. Initialize them to make
530 * These are borders of the appropriate instructions. Initialize them to make
531 * compiler happy: they are never used uninitialized even without explicit 596 * compiler happy: they are never used uninitialized even without explicit
532 * initialization but GCC is not sophysicated enough to prove that. 597 * initialization but GCC is not sophysicated enough to prove that. */
533 */
534 const uint8_t *sandboxed_rsi = 0; 598 const uint8_t *sandboxed_rsi = 0;
535 const uint8_t *sandboxed_rsi_restricted_rdi = 0; 599 const uint8_t *sandboxed_rsi_restricted_rdi = 0;
536 const uint8_t *sandboxed_rdi = 0; 600 const uint8_t *sandboxed_rdi = 0;
537 601
538 assert(size % bundle_size == 0); 602 assert(size % bundle_size == 0);
539 603
540 while (p < data + size) { 604 while (p < data + size) {
541 const uint8_t *pe = p + bundle_size; 605 const uint8_t *pe = p + bundle_size;
542 const uint8_t *eof = pe; 606 const uint8_t *eof = pe;
543 int cs; 607 int cs;
544 enum { 608 enum {
545 kNoRestrictedReg = 32, 609 kNoRestrictedReg = 32,
546 kSandboxedRsi, 610 kSandboxedRsi,
547 kSandboxedRdi, 611 kSandboxedRdi,
548 kSandboxedRsiRestrictedRdi, 612 kSandboxedRsiRestrictedRdi,
549 kSandboxedRsiSandboxedRdi 613 kSandboxedRsiSandboxedRdi
550 }; uint8_t restricted_register = kNoRestrictedReg; 614 }; uint8_t restricted_register = kNoRestrictedReg;
551 615
552 %% write init; 616 %% write init;
553 /* Ragel-generated code stores a difference between pointers into an "int" 617 /* Ragel-generated code stores a difference between pointers into an "int"
554 variable. This produces C4244 warning on Windows x64. */ 618 * variable. This produces C4244 warning on Windows x64. */
555 #ifdef _MSC_VER 619 #ifdef _MSC_VER
556 #pragma warning(push) 620 #pragma warning(push)
557 #pragma warning(disable: 4244) // possible loss of data 621 #pragma warning(disable: 4244) // possible loss of data
558 #endif 622 #endif
559 %% write exec; 623 %% write exec;
560 #ifdef _MSC_VER 624 #ifdef _MSC_VER
561 #pragma warning(pop) 625 #pragma warning(pop)
562 #endif 626 #endif
563 627
564 if (restricted_register == REG_RBP) { 628 if (restricted_register == REG_RBP) {
565 PrintError("Incorrectly sandboxed %%rbp\n", begin - data); 629 PrintError("Incorrectly sandboxed %%rbp\n", begin - data);
566 result = 1; 630 result = 1;
567 goto error_detected; 631 goto error_detected;
568 } else if (restricted_register == REG_RSP) { 632 } else if (restricted_register == REG_RSP) {
569 PrintError("Incorrectly sandboxed %%rsp\n", begin - data); 633 PrintError("Incorrectly sandboxed %%rsp\n", begin - data);
570 result = 1; 634 result = 1;
571 goto error_detected; 635 goto error_detected;
572 } 636 }
573 } 637 }
574 638
575 if (CheckJumpTargets(valid_targets, jump_dests, size)) { 639 if (CheckJumpTargets(valid_targets, jump_dests, size)) {
576 return 1; 640 return 1;
577 } 641 }
578 642
579 error_detected: 643 error_detected:
580 return result; 644 return result;
581 } 645 }
OLDNEW
« no previous file with comments | « src/trusted/validator_ragel/unreviewed/gen-dfa.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698