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

Side by Side Diff: src/trusted/validator_ragel/validator_x86_64.rl

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 7 years, 9 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 is the core of amd64-mode validator. Please note that this file 8 * This is the core of amd64-mode validator. Please note that this file
9 * combines ragel machine description and C language actions. Please read 9 * combines ragel machine description and C language actions. Please read
10 * validator_internals.html first to understand how the whole thing is built: 10 * validator_internals.html first to understand how the whole thing is built:
11 * it explains how the byte sequences are constructed, what constructs like 11 * it explains how the byte sequences are constructed, what constructs like
12 * "@{}" or "REX_WRX?" mean, etc. 12 * "@{}" or "REX_WRX?" mean, etc.
13 */ 13 */
14 14
15 #include <assert.h> 15 #include <assert.h>
16 #include <errno.h> 16 #include <errno.h>
17 #include <stddef.h> 17 #include <stddef.h>
18 #include <stdio.h> 18 #include <stdio.h>
19 #include <stdlib.h> 19 #include <stdlib.h>
20 #include <string.h> 20 #include <string.h>
21 21
22 #include "native_client/src/trusted/validator_ragel/bitmap.h" 22 #include "native_client/src/trusted/validator_ragel/bitmap.h"
23 #include "native_client/src/trusted/validator_ragel/unreviewed/validator_interna l.h" 23 #include "native_client/src/trusted/validator_ragel/validator_internal.h"
24 24
25 %%{ 25 %%{
26 machine x86_64_validator; 26 machine x86_64_validator;
27 alphtype unsigned char; 27 alphtype unsigned char;
28 variable p current_position; 28 variable p current_position;
29 variable pe end_of_bundle; 29 variable pe end_of_bundle;
30 variable eof end_of_bundle; 30 variable eof end_of_bundle;
31 variable cs current_state; 31 variable cs current_state;
32 32
33 include byte_machine "byte_machines.rl"; 33 include byte_machine "byte_machines.rl";
(...skipping 30 matching lines...) Expand all
64 "native_client/src/trusted/validator_ragel/unreviewed/parse_instruction.rl"; 64 "native_client/src/trusted/validator_ragel/unreviewed/parse_instruction.rl";
65 include cpuid_actions 65 include cpuid_actions
66 "native_client/src/trusted/validator_ragel/unreviewed/parse_instruction.rl"; 66 "native_client/src/trusted/validator_ragel/unreviewed/parse_instruction.rl";
67 67
68 action check_access { 68 action check_access {
69 CheckAccess(instruction_begin - data, base, index, restricted_register, 69 CheckAccess(instruction_begin - data, base, index, restricted_register,
70 valid_targets, &instruction_info_collected); 70 valid_targets, &instruction_info_collected);
71 } 71 }
72 72
73 # Action which marks last byte as not immediate. Most 3DNow! instructions, 73 # Action which marks last byte as not immediate. Most 3DNow! instructions,
74 # some AVX and XOP instructions have this proerty. It's referenced by 74 # some AVX and XOP instructions have this property.
75 # decode_x86_32 machine in [autogenerated] "validator_x86_32_instruction.rl" 75 #
76 # file. 76 # This action is referenced by decode_x86_32 ragel machine in [autogenerated]
77 # "validator_x86_64_instruction.rl" file.
77 action last_byte_is_not_immediate { 78 action last_byte_is_not_immediate {
78 instruction_info_collected |= LAST_BYTE_IS_NOT_IMMEDIATE; 79 instruction_info_collected |= LAST_BYTE_IS_NOT_IMMEDIATE;
79 } 80 }
80 81
81 action modifiable_instruction { 82 action modifiable_instruction {
82 instruction_info_collected |= MODIFIABLE_INSTRUCTION; 83 instruction_info_collected |= MODIFIABLE_INSTRUCTION;
83 } 84 }
84 85
85 action process_0_operands { 86 action process_0_operands {
86 Process0Operands(&restricted_register, &instruction_info_collected); 87 Process0Operands(&restricted_register, &instruction_info_collected);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 # instruction (it gets assembled as 'lea 0x00(%rbp,%r15,1),%rbp'). 132 # instruction (it gets assembled as 'lea 0x00(%rbp,%r15,1),%rbp').
132 0x4a 0x8d 0x6c 0x3d 0x00 | # lea 0x00(%rbp,%r15,1),%rbp 133 0x4a 0x8d 0x6c 0x3d 0x00 | # lea 0x00(%rbp,%r15,1),%rbp
133 0x4a 0x8d 0xac 0x3d 0x00 0x00 0x00 0x00) # lea 0x00000000(%rbp,%r15,1),%rbp 134 0x4a 0x8d 0xac 0x3d 0x00 0x00 0x00 0x00) # lea 0x00000000(%rbp,%r15,1),%rbp
134 # Note: restricted_register keeps the restricted register as explained in 135 # Note: restricted_register keeps the restricted register as explained in
135 # http://www.chromium.org/nativeclient/design-documents/nacl-sfi-model-on-x8 6-64-systems 136 # http://www.chromium.org/nativeclient/design-documents/nacl-sfi-model-on-x8 6-64-systems
136 # 137 #
137 # "Normal" instructions can not be used in a place where %rbp is restricted. 138 # "Normal" instructions can not be used in a place where %rbp is restricted.
138 # But since these instructions are "second half" of the %rbp sandboxing they 139 # But since these instructions are "second half" of the %rbp sandboxing they
139 # can be used *only* when %rbp is restricted. 140 # can be used *only* when %rbp is restricted.
140 # 141 #
141 # That is (normal instruction): 142 # Compare:
142 # mov %eax,%ebp 143 # mov %eax,%ebp
143 # mov %esi,%edi <- Error: %ebp is restricted 144 # mov %esi,%edi <- Error: %ebp is restricted
144 # vs 145 # vs
145 # mov %esi,%edi 146 # mov %esi,%edi
146 # add %r15,%rbp <- Error: %ebp is *not* restricted 147 # add %r15,%rbp <- Error: %ebp is *not* restricted
147 # vs 148 # vs
148 # mov %eax,%ebp 149 # mov %eax,%ebp
149 # add %r15,%rbp <- Ok: %rbp is restricted as it should be 150 # add %r15,%rbp <- Ok: %rbp is restricted as it should be
150 # 151 #
151 # Check this precondition and mark the beginning of the instruction as 152 # Check this precondition and mark the beginning of the instruction as
152 # invalid jump for target. 153 # invalid jump for target.
153 @{ if (restricted_register == REG_RBP) 154 @{ if (restricted_register == REG_RBP)
155 /* RESTRICTED_REGISTER_USED is informational flag used in tests. */
154 instruction_info_collected |= RESTRICTED_REGISTER_USED; 156 instruction_info_collected |= RESTRICTED_REGISTER_USED;
155 else 157 else
158 /* UNRESTRICTED_RSP_PROCESSED is error flag used in production. */
156 instruction_info_collected |= UNRESTRICTED_RBP_PROCESSED; 159 instruction_info_collected |= UNRESTRICTED_RBP_PROCESSED;
157 restricted_register = NO_REG; 160 restricted_register = NO_REG;
158 UnmarkValidJumpTarget((instruction_begin - data), valid_targets); 161 UnmarkValidJumpTarget((instruction_begin - data), valid_targets);
159 }; 162 };
160 163
161 # Special %rsp modifications - the ones which don't need a sandboxing. 164 # Special %rsp modifications - the ones which don't need a sandboxing.
162 # 165 #
163 # Note that there are two different opcodes for "mov": in x86-64 there are two 166 # Note that there are two different opcodes for "mov": in x86-64 there are two
164 # fields in ModR/M byte (REG field and RM field) and "mov" may be used to move 167 # fields in ModR/M byte (REG field and RM field) and "mov" may be used to move
165 # from REG field to RM or in the other direction thus there are two encodings 168 # from REG field to RM or in the other direction thus there are two encodings
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 instruction_info_collected |= UNRESTRICTED_RSP_PROCESSED; 217 instruction_info_collected |= UNRESTRICTED_RSP_PROCESSED;
215 restricted_register = NO_REG; 218 restricted_register = NO_REG;
216 UnmarkValidJumpTarget((instruction_begin - data), valid_targets); 219 UnmarkValidJumpTarget((instruction_begin - data), valid_targets);
217 }; 220 };
218 221
219 # naclcall or nacljmp. These are three-instruction indirection-jump sequences. 222 # naclcall or nacljmp. These are three-instruction indirection-jump sequences.
220 # and $~0x1f, %eXX 223 # and $~0x1f, %eXX
221 # and RBASE, %rXX 224 # and RBASE, %rXX
222 # jmpq *%rXX (or: callq *%rXX) 225 # jmpq *%rXX (or: callq *%rXX)
223 # Note: first "and $~0x1f, %eXX" is a normal instruction (it can occur not 226 # Note: first "and $~0x1f, %eXX" is a normal instruction (it can occur not
224 # just as part of the naclcall/nacljmp, but also as a standolene instruction). 227 # just as part of the naclcall/nacljmp, but also as a standalene instruction).
225 # 228 #
226 # This means that when naclcall_or_nacljmp ragel machine will be combined with 229 # This means that when naclcall_or_nacljmp ragel machine will be combined with
227 # "normal_instruction*" regular action process_1_operand_zero_extends will be 230 # "normal_instruction*" regular action process_1_operand_zero_extends will be
228 # triggered when main ragel machine will accept "and $~0x1f, %eXX" x86-64 231 # triggered when main ragel machine will accept "and $~0x1f, %eXX" x86-64
229 # instruction. This action will check if %rbp/%rsp is legally modified thus 232 # instruction. This action will check if %rbp/%rsp is legally modified thus
230 # we don't need to duplicate this logic in naclcall_or_nacljmp ragel machine. 233 # we don't need to duplicate this logic in naclcall_or_nacljmp ragel machine.
231 # 234 #
232 # There are number of variants present which differ by the REX prefix usage: 235 # There are number of variants present which differ by the REX prefix usage:
233 # we need to make sure "%eXX" in "and", "%rXX" in "add", and "%eXX" in "jmpq" 236 # we need to make sure "%eXX" in "and", "%rXX" in "add", and "%eXX" in "jmpq"
234 # or "callq" is the same register and it's much simpler to do if one single 237 # or "callq" is the same register and it's much simpler to do if one single
235 # action handles only fixed number of bytes. 238 # action handles only fixed number of bytes.
236 # 239 #
237 # Additional complication arises because x86-64 contains two different "add" 240 # Additional complication arises because x86-64 contains two different "add"
238 # instruction: with "0x01" and "0x03" opcode. They differ in the direction 241 # instruction: with "0x01" and "0x03" opcode. They differ in the direction
239 # used: both can encode "add %src_register, %dst_register", but the first one 242 # used: both can encode "add %src_register, %dst_register", but the first one
240 # uses field REG of the ModR/M byte for the src and field RM of the ModR/M 243 # uses field REG of the ModR/M byte for the src and field RM of the ModR/M
241 # byte for the dst while last one uses field RM of the ModR/M byte for the src 244 # byte for the dst while last one uses field RM of the ModR/M byte for the src
242 # and field REG of the ModR/M byte for dst. Both should be allowed. 245 # and field REG of the ModR/M byte for dst. Both should be allowed.
243 # 246 #
244 # See AMD/Intel manual for clarification "add" instruction encoding. 247 # See AMD/Intel manual for clarification about “add instruction encoding.
245 # 248 #
246 # REGISTER USAGE ABBREVIATIONS: 249 # REGISTER USAGE ABBREVIATIONS:
247 # E86: legacy ia32 registers (all eight: %eax to %edi) 250 # E86: legacy ia32 registers (all eight: %eax to %edi)
248 # R86: 64-bit counterparts for legacy 386 registers (%rax to %rdi) 251 # R86: 64-bit counterparts for legacy 386 registers (%rax to %rdi)
249 # E64: 32-bit counterparts for new amd64 registers (%r8d to %r14d) 252 # E64: 32-bit counterparts for new amd64 registers (%r8d to %r14d)
250 # R64: new amd64 registers (only seven: %r8 to %r14) 253 # R64: new amd64 registers (only seven: %r8 to %r14)
251 # RBASE: %r15 (used as "base of untrusted world" in NaCl for amd64) 254 # RBASE: %r15 (used as "base of untrusted world" in NaCl for amd64)
252 naclcall_or_nacljmp = 255 naclcall_or_nacljmp =
253 # This block encodes call and jump "superinstruction" of the following form: 256 # This block encodes call and jump "superinstruction" of the following form:
254 # 0: 83 e_ e0 and $~0x1f,E86 257 # 0: 83 e_ e0 and $~0x1f,E86
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 ((b_0100_xxx1 0xff (b_11_010_xxx - b_11_010_111)) | 368 ((b_0100_xxx1 0xff (b_11_010_xxx - b_11_010_111)) |
366 #### INSTRUCTION THREE: jmp (three bytes) 369 #### INSTRUCTION THREE: jmp (three bytes)
367 # jmpq R64 370 # jmpq R64
368 (b_0100_xxx1 0xff (b_11_100_xxx - b_11_100_111))))) 371 (b_0100_xxx1 0xff (b_11_100_xxx - b_11_100_111)))))
369 @{ 372 @{
370 ProcessNaclCallOrJmpAddToRegWithRex(&instruction_info_collected, 373 ProcessNaclCallOrJmpAddToRegWithRex(&instruction_info_collected,
371 &instruction_begin, current_position, 374 &instruction_begin, current_position,
372 data, valid_targets); 375 data, valid_targets);
373 }; 376 };
374 377
375 # EMMS/SSE2/AVX instructions which have implicit %ds:(%rsi) operand 378 # EMMX/SSE/SSE2/AVX instructions which have implicit %ds:(%rsi) operand
376 # maskmovq %mmX,%mmY 379
377 maskmovq = 380 # maskmovq %mmX,%mmY (EMMX or SSE)
378 REX_WRXB? (0x0f 0xf7) 381 maskmovq = REX_WRXB? 0x0f 0xf7 @CPUFeature_EMMXSSE modrm_registers;
379 @CPUFeature_EMMX modrm_registers; 382
380 # maskmovdqu %xmmX, %xmmY 383 # maskmovdqu %xmmX, %xmmY (SSE2)
381 maskmovdqu = 384 maskmovdqu = 0x66 REX_WRXB? 0x0f 0xf7 @CPUFeature_SSE2 modrm_registers;
382 0x66 REX_WRXB? (0x0f 0xf7) @not_data16_prefix 385
383 @CPUFeature_SSE2 modrm_registers; 386 # vmaskmovdqu %xmmX, %xmmY (AVX)
384 # vmaskmovdqu %xmmX, %xmmY 387 vmaskmovdqu = ((0xc4 (VEX_RB & VEX_map00001) b_0_1111_0_01) |
385 vmaskmovdqu = 388 (0xc5 b_X_1111_0_01)) 0xf7 @CPUFeature_AVX modrm_registers;
386 ((0xc4 (VEX_RB & VEX_map00001) 0x79 @vex_prefix3) | 389
387 (0xc5 (0x79 | 0xf9) @vex_prefix_short)) 0xf7
388 @CPUFeature_AVX modrm_registers;
389 mmx_sse_rdi_instruction = maskmovq | maskmovdqu | vmaskmovdqu; 390 mmx_sse_rdi_instruction = maskmovq | maskmovdqu | vmaskmovdqu;
390 391
391 # Temporary fix: for string instructions combination of data16 and rep(ne) 392 # Temporary fix: for string instructions combination of data16 and rep(ne)
392 # prefixes is disallowed to mimic old validator behavior. 393 # prefixes is disallowed to mimic old validator behavior.
393 # See http://code.google.com/p/nativeclient/issues/detail?id=1950 394 # See http://code.google.com/p/nativeclient/issues/detail?id=1950
394 395
395 # data16rep = (data16 | rep data16 | data16 rep); 396 # data16rep = (data16 | rep data16 | data16 rep);
396 # data16condrep = (data16 | condrep data16 | data16 condrep); 397 # data16condrep = (data16 | condrep data16 | data16 condrep);
397 data16rep = data16; 398 data16rep = data16;
398 data16condrep = data16; 399 data16condrep = data16;
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 # Mark the instruction as special - currently this information is used only 547 # Mark the instruction as special - currently this information is used only
547 # in tests, but in the future we may use it for dynamic code modification 548 # in tests, but in the future we may use it for dynamic code modification
548 # support. 549 # support.
549 @{ 550 @{
550 instruction_info_collected |= SPECIAL_INSTRUCTION; 551 instruction_info_collected |= SPECIAL_INSTRUCTION;
551 }; 552 };
552 553
553 # Remove special instructions which are only allowed in special cases. 554 # Remove special instructions which are only allowed in special cases.
554 normal_instruction = one_instruction - special_instruction; 555 normal_instruction = one_instruction - special_instruction;
555 556
556 # Check if call is properly aligned. 557 # Ragel machine which checks if call is properly aligned.
557 # 558 #
558 # For direct call we explicitly encode all variations. For indirect call 559 # For direct call we explicitly encode all variations. For indirect call
559 # we accept all the special instructions which ends with indirect call. 560 # we accept all the special instructions which ends with indirect call.
560 call_alignment = 561 call_alignment =
561 ((normal_instruction & 562 ((normal_instruction &
562 # Direct call 563 # Direct call
563 ((data16 REX_RXB? 0xe8 rel16) | 564 ((data16 REX_RXB? 0xe8 rel16) |
564 (REX_WRXB? 0xe8 rel32) | 565 (REX_WRXB? 0xe8 rel32) |
565 (data16 REXW_RXB 0xe8 rel32))) | 566 (data16 REXW_RXB 0xe8 rel32))) |
566 (special_instruction & 567 (special_instruction &
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
626 * the ValidateChunkAMD64 function. 627 * the ValidateChunkAMD64 function.
627 * 628 *
628 * It does not affect the case which we really care about (when code 629 * It does not affect the case which we really care about (when code
629 * is validatable), but makes it possible to detect more errors in one 630 * is validatable), but makes it possible to detect more errors in one
630 * run in tools like ncval. 631 * run in tools like ncval.
631 */ 632 */
632 continue; 633 continue;
633 } 634 }
634 635
635 # This is main ragel machine: it does 99% of validation work. There are only 636 # This is main ragel machine: it does 99% of validation work. There are only
636 # one thing to do with bundle if this machine accepts the bundle: 637 # one thing to do with bundle if this ragel machine accepts the bundle:
637 # * check for the state of the restricted_register at the end of the bundle. 638 # * check for the state of the restricted_register at the end of the bundle.
638 # It's an error is %rbp or %rsp is restricted at the end of the bundle. 639 # It's an error is %rbp or %rsp is restricted at the end of the bundle.
639 # Additionally if all the bundles are fine you need to check that direct jumps 640 # Additionally if all the bundles are fine you need to check that direct jumps
640 # are corect. Thiis is done in the following way: 641 # are corect. Thiis is done in the following way:
641 # * DFA fills two arrays: valid_targets and jump_dests. 642 # * DFA fills two arrays: valid_targets and jump_dests.
642 # * ProcessInvalidJumpTargets checks that "jump_dests & !valid_targets == 0". 643 # * ProcessInvalidJumpTargets checks that "jump_dests & !valid_targets == 0".
643 # All other checks are done here. 644 # All other checks are done here.
644 645
645 main := ((call_alignment | normal_instruction | special_instruction) 646 main := ((call_alignment | normal_instruction | special_instruction)
646 @end_of_instruction_cleanup)* 647 @end_of_instruction_cleanup)*
647 $!report_fatal_error; 648 $!report_fatal_error;
648 649
649 }%% 650 }%%
650 651
652 /*
653 * The "write data" statement causes Ragel to emit the constant static data
654 * needed by the ragel machine.
655 */
651 %% write data; 656 %% write data;
652 657
653 enum OperandKind { 658 enum OperandKind {
654 OPERAND_SANDBOX_IRRELEVANT = 0, 659 OPERAND_SANDBOX_IRRELEVANT = 0,
655 /* 660 /*
656 * Currently we do not distinguish 8bit and 16bit modifications from 661 * Currently we do not distinguish 8bit and 16bit modifications from
657 * OPERAND_SANDBOX_UNRESTRICTED to match the behavior of the old validator. 662 * OPERAND_SANDBOX_UNRESTRICTED to match the behavior of the old validator.
658 * 663 *
659 * 8bit operands must be distinguished from other types because the REX prefix 664 * 8bit operands must be distinguished from other types because the REX prefix
660 * regulates the choice between %ah and %spl, as well as %ch and %bpl. 665 * regulates the choice between %ah and %spl, as well as %ch and %bpl.
(...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after
1164 free(jump_dests); 1169 free(jump_dests);
1165 free(valid_targets); 1170 free(valid_targets);
1166 errno = ENOMEM; 1171 errno = ENOMEM;
1167 return FALSE; 1172 return FALSE;
1168 } 1173 }
1169 } 1174 }
1170 1175
1171 /* 1176 /*
1172 * This option is usually used in tests: we will process the whole chunk 1177 * This option is usually used in tests: we will process the whole chunk
1173 * in one pass. Usually each bundle is processed separately which means 1178 * in one pass. Usually each bundle is processed separately which means
1174 * instructions (and super-instructions) can not cross borders of the bundle. 1179 * instructions (and "superinstructions") can not cross borders of the bundle.
1175 */ 1180 */
1176 if (options & PROCESS_CHUNK_AS_A_CONTIGUOUS_STREAM) 1181 if (options & PROCESS_CHUNK_AS_A_CONTIGUOUS_STREAM)
1177 end_of_bundle = data + size; 1182 end_of_bundle = data + size;
1178 else 1183 else
1179 end_of_bundle = data + kBundleSize; 1184 end_of_bundle = data + kBundleSize;
1180 1185
1181 /* 1186 /*
1182 * Main loop. Here we process the data array bundle-after-bundle. 1187 * Main loop. Here we process the data array bundle-after-bundle.
1183 * Ragel-produced DFA does all the checks with one exception: direct jumps. 1188 * Ragel-produced DFA does all the checks with one exception: direct jumps.
1184 * It collects the two arrays: valid_targets and jump_dests which are used 1189 * It collects the two arrays: valid_targets and jump_dests which are used
(...skipping 15 matching lines...) Expand all
1200 uint32_t operand_states = 0; 1205 uint32_t operand_states = 0;
1201 enum OperandName base = NO_REG; 1206 enum OperandName base = NO_REG;
1202 enum OperandName index = NO_REG; 1207 enum OperandName index = NO_REG;
1203 enum OperandName restricted_register = 1208 enum OperandName restricted_register =
1204 EXTRACT_RESTRICTED_REGISTER_INITIAL_VALUE(options); 1209 EXTRACT_RESTRICTED_REGISTER_INITIAL_VALUE(options);
1205 uint8_t rex_prefix = FALSE; 1210 uint8_t rex_prefix = FALSE;
1206 /* Top three bits of VEX2 are inverted: see AMD/Intel manual. */ 1211 /* Top three bits of VEX2 are inverted: see AMD/Intel manual. */
1207 uint8_t vex_prefix2 = VEX_R | VEX_X | VEX_B; 1212 uint8_t vex_prefix2 = VEX_R | VEX_X | VEX_B;
1208 uint8_t vex_prefix3 = 0x00; 1213 uint8_t vex_prefix3 = 0x00;
1209 1214
1215 /*
1216 * The "write init" statement causes Ragel to emit initialization code.
1217 * This should be executed once before the ragel machine is started.
1218 */
1210 %% write init; 1219 %% write init;
1220 /*
1221 * The "write exec" statement causes Ragel to emit the ragel machine's
1222 * execution code.
1223 */
1211 %% write exec; 1224 %% write exec;
1212 1225
1213 /* 1226 /*
1214 * Ragel DFA accepted the bundle, but we still need to make sure the last 1227 * Ragel DFA accepted the bundle, but we still need to make sure the last
1215 * instruction haven't left %rbp or %rsp in restricted state. 1228 * instruction haven't left %rbp or %rsp in restricted state.
1216 */ 1229 */
1217 if (restricted_register == REG_RBP) 1230 if (restricted_register == REG_RBP)
1218 result &= user_callback(end_of_bundle, end_of_bundle, 1231 result &= user_callback(end_of_bundle, end_of_bundle,
1219 RESTRICTED_RBP_UNPROCESSED | 1232 RESTRICTED_RBP_UNPROCESSED |
1220 ((REG_RBP << RESTRICTED_REGISTER_SHIFT) & 1233 ((REG_RBP << RESTRICTED_REGISTER_SHIFT) &
(...skipping 11 matching lines...) Expand all
1232 */ 1245 */
1233 result &= ProcessInvalidJumpTargets(data, size, valid_targets, jump_dests, 1246 result &= ProcessInvalidJumpTargets(data, size, valid_targets, jump_dests,
1234 user_callback, callback_data); 1247 user_callback, callback_data);
1235 1248
1236 /* We only use malloc for a large code sequences */ 1249 /* We only use malloc for a large code sequences */
1237 if (jump_dests != &jump_dests_small) free(jump_dests); 1250 if (jump_dests != &jump_dests_small) free(jump_dests);
1238 if (valid_targets != &valid_targets_small) free(valid_targets); 1251 if (valid_targets != &valid_targets_small) free(valid_targets);
1239 if (!result) errno = EINVAL; 1252 if (!result) errno = EINVAL;
1240 return result; 1253 return result;
1241 } 1254 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698