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

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 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
Brad Chen 2012/10/04 17:26:04 What is this file? Please add a comment.
khim 2012/10/05 08:22:53 Done.
7 #include <assert.h> 7 #include <assert.h>
8 #include <errno.h> 8 #include <errno.h>
9 #include <stddef.h> 9 #include <stddef.h>
10 #include <stdio.h> 10 #include <stdio.h>
11 #include <stdlib.h> 11 #include <stdlib.h>
12 #include <string.h> 12 #include <string.h>
13 13
14 #include "native_client/src/trusted/validator_ragel/unreviewed/validator_interna l.h" 14 #include "native_client/src/trusted/validator_ragel/validator_internal.h"
15 15
16 %%{ 16 %%{
17 machine x86_64_validator; 17 machine x86_64_validator;
18 alphtype unsigned char; 18 alphtype unsigned char;
19 variable p current_position; 19 variable p current_position;
20 variable pe end_of_bundle; 20 variable pe end_of_bundle;
21 variable eof end_of_bundle; 21 variable eof end_of_bundle;
22 variable cs current_state; 22 variable cs current_state;
23 23
24 include byte_machine "byte_machines.rl"; 24 include byte_machine "byte_machines.rl";
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 process_2_operands_zero_extends(&restricted_register, 98 process_2_operands_zero_extends(&restricted_register,
99 &instruction_info_collected, rex_prefix, 99 &instruction_info_collected, rex_prefix,
100 operand_states); 100 operand_states);
101 } 101 }
102 102
103 include decode_x86_64 "validator_x86_64_instruction.rl"; 103 include decode_x86_64 "validator_x86_64_instruction.rl";
104 104
105 data16condrep = (data16 | condrep data16 | data16 condrep); 105 data16condrep = (data16 | condrep data16 | data16 condrep);
106 data16rep = (data16 | rep data16 | data16 rep); 106 data16rep = (data16 | rep data16 | data16 rep);
107 107
108 # Special %rbp modifications without required sandboxing 108 # Special %rbp modifications without required sandboxing
Brad Chen 2012/10/04 17:26:04 This comment is unclear. Why don't these special m
khim 2012/10/05 08:22:53 These special instructions don't require the sandb
109 #
110 # Note that there are two different opcodes for “mov”: “mov” with opcode
111 # “0x89” moves from “A” to “B” while “mov” with opcode “0x8b” moves from
112 # “B” to “A”.
109 rbp_modifications = 113 rbp_modifications =
110 (b_0100_10x0 0x89 0xe5) | # mov %rsp,%rbp 114 (b_0100_10x0 0x89 0xe5) | # mov %rsp,%rbp
111 (b_0100_10x0 0x8b 0xec) # | mov %rsp,%rbp 115 (b_0100_10x0 0x8b 0xec) # | mov %rsp,%rbp
112 #(b_0100_1xx0 0x81 0xe5 any{3} (0x80 .. 0xff)) | # and $XXX,%rbp 116 #(b_0100_1xx0 0x81 0xe5 any{3} (0x80 .. 0xff)) | # and $XXX,%rbp
113 #(b_0100_1xx0 0x83 0xe5 (0x80 .. 0xff)) # and $XXX,%rbp 117 #(b_0100_1xx0 0x83 0xe5 (0x80 .. 0xff)) # and $XXX,%rbp
Brad Chen 2012/10/04 17:26:04 The strange positioning of '|' and '#' and the com
khim 2012/10/05 08:22:53 These instructions are permitted in the similar bl
114 @process_0_operands; 118 @process_0_operands;
115 119
116 # Special instructions used for %rbp sandboxing 120 # Special instructions used for %rbp sandboxing
117 rbp_sandboxing = 121 rbp_sandboxing =
118 (b_0100_11x0 0x01 0xfd | # add %r15,%rbp 122 (b_0100_11x0 0x01 0xfd | # add %r15,%rbp
119 b_0100_10x1 0x03 0xef | # add %r15,%rbp 123 b_0100_10x1 0x03 0xef | # add %r15,%rbp
120 0x49 0x8d 0x2c 0x2f | # lea (%r15,%rbp,1),%rbp 124 0x49 0x8d 0x2c 0x2f | # lea (%r15,%rbp,1),%rbp
121 0x4a 0x8d 0x6c 0x3d 0x00) # lea 0x0(%rbp,%r15,1),%rbp 125 0x4a 0x8d 0x6c 0x3d 0x00) # lea 0x0(%rbp,%r15,1),%rbp
122 @{ if (restricted_register == REG_RBP) 126 @{ if (restricted_register == REG_RBP)
123 instruction_info_collected |= RESTRICTED_REGISTER_USED; 127 instruction_info_collected |= RESTRICTED_REGISTER_USED;
124 else 128 else
125 instruction_info_collected |= UNRESTRICTED_RBP_PROCESSED; 129 instruction_info_collected |= UNRESTRICTED_RBP_PROCESSED;
126 restricted_register = NO_REG; 130 restricted_register = NO_REG;
127 BitmapClearBit(valid_targets, (instruction_start - data)); 131 MakeJumpTargetInvalid((instruction_start - data), valid_targets);
Brad Chen 2012/10/04 17:26:04 Are you going to make the instruction at the targe
khim 2012/10/05 08:22:53 I have no opinion WRT to the best name. We clear t
128 }; 132 };
129 133
130 # Special %rbp modifications without required sandboxing 134 # Special %rbp modifications without required sandboxing
Brad Chen 2012/10/04 17:26:04 This line begins a section that is extremely simil
khim 2012/10/05 08:22:53 Actually this is just bad comment. Previous one de
135 #
136 # Note that there are two different opcodes for “mov”: “mov” with opcode
137 # “0x89” moves from “A” to “B” while “mov” with opcode “0x8b” moves from
138 # “B” to “A”.
131 rsp_modifications = 139 rsp_modifications =
132 (b_0100_10x0 0x89 0xec) | # mov %rbp,%rsp 140 (b_0100_10x0 0x89 0xec) | # mov %rbp,%rsp
133 (b_0100_10x0 0x8b 0xe5) | # mov %rbp,%rsp 141 (b_0100_10x0 0x8b 0xe5) | # mov %rbp,%rsp
134 #(b_0100_1xx0 0x81 0xe4 any{3} (0x80 .. 0xff)) | # and $XXX,%rsp 142 #(b_0100_1xx0 0x81 0xe4 any{3} (0x80 .. 0xff)) | # and $XXX,%rsp
135 #Superfluous bits are not supported: 143 #Superfluous bits are not supported:
136 # http://code.google.com/p/nativeclient/issues/detail?id=3012 144 # http://code.google.com/p/nativeclient/issues/detail?id=3012
137 (b_0100_1000 0x83 0xe4 (0x80 .. 0xff)) # and $XXX,%rsp 145 (b_0100_1000 0x83 0xe4 (0x80 .. 0xff)) # and $XXX,%rsp
138 @process_0_operands; 146 @process_0_operands;
139 147
140 # Special instructions used for %rbp sandboxing 148 # Special instructions used for %rbp sandboxing
141 rsp_sandboxing = 149 rsp_sandboxing =
142 (b_0100_11x0 0x01 0xfc | # add %r15,%rsp 150 (b_0100_11x0 0x01 0xfc | # add %r15,%rsp
143 b_0100_10x1 0x03 0xe7 | # add %r15,%rbp 151 b_0100_10x1 0x03 0xe7 | # add %r15,%rbp
144 0x4a 0x8d 0x24 0x3c) # lea (%rsp,%r15,1),%rsp 152 0x4a 0x8d 0x24 0x3c) # lea (%rsp,%r15,1),%rsp
145 @{ if (restricted_register == REG_RSP) 153 @{ if (restricted_register == REG_RSP)
Brad Chen 2012/10/04 17:26:04 Why isn't this action commented? Please comment al
khim 2012/10/05 08:22:53 Done.
146 instruction_info_collected |= RESTRICTED_REGISTER_USED; 154 instruction_info_collected |= RESTRICTED_REGISTER_USED;
147 else 155 else
148 instruction_info_collected |= UNRESTRICTED_RSP_PROCESSED; 156 instruction_info_collected |= UNRESTRICTED_RSP_PROCESSED;
149 restricted_register = NO_REG; 157 restricted_register = NO_REG;
150 BitmapClearBit(valid_targets, (instruction_start - data)); 158 MakeJumpTargetInvalid((instruction_start - data), valid_targets);
151 }; 159 };
152 160
153 # naclcall or nacljmp. Note: first "and $~0x1f, %eXX" is a normal instruction 161 # naclcall or nacljmp. These are indirect-jump sequences. They include three
Brad Chen 2012/10/04 17:26:04 Before getting into any specific instructions ther
khim 2012/10/05 08:22:53 This is validator_internals.html.
154 # and as such will detect case where %rbp/%rsp is illegally modified. 162 # commands:
Brad Chen 2012/10/04 17:26:04 How about "These are three-instruction indirection
khim 2012/10/05 08:22:53 Done.
163 # and “and $~0x1f, %eXX”
Brad Chen 2012/10/04 17:26:04 Why repeat the opcode "and" helpful in these comme
khim 2012/10/05 08:22:53 Tried to make easier to see that third command may
164 # add “and RBASE, %rXX”
165 # jmpq “*%rXX” or callq “*%rXX”
166 # Note: first "and $~0x1f, %eXX" is a normal instruction and as such will
167 # detect case where %rbp/%rsp is illegally modified.
Brad Chen 2012/10/04 17:26:04 Who will detect this case? I don't understand the
khim 2012/10/05 08:22:53 When this ragel machine will be combined with norm
168 #
169 # There are number of variants present which differ by the REX prefix usage:
Brad Chen 2012/10/04 17:26:04 Where are the variants?
khim 2012/10/05 08:22:53 Below. Should I write that?
170 # we need to make sure “%eXX” in “and”, “%rXX” in “add”, and “%eXX” in “jmpq”
171 # or “callq” is the same register and it's much simpler to do if one single
172 # action handles only fixed number of bytes.
173 #
174 # Additional complication arises because x86-64 contains two different “add”
175 # instruction: with “0x01” and “0x03” opcode. Both are in use in the wild
Brad Chen 2012/10/04 17:26:04 Please avoid colorful language such as "in use in
khim 2012/10/05 08:22:53 The only question is: how to determine if I wrote
176 # thus we can not support just one form. They differ in the direction used:
177 # both can add “A” and “B” but one of them stores the result in “A” and other
178 # stores the result in “B” (see AMD/Intel manual for clarification).
179 #
180 # REGISTER USAGE ABBREVIATIONS:
181 # E32: legacy ia32 registers (all eight: %eax to %edi)
182 # R32: 64-bit counterparts for legacy 386 registers (%rax to %rdi)
183 # R64: new amd64 registers (only seven: %r8 to %r14)
184 # R32: 32-bit counterparts for new amd64 registers (%r8d to %r14d)
Brad Chen 2012/10/04 17:26:04 You have defined R32 twice. I think you mean "E32"
khim 2012/10/05 08:22:53 Yes, and done.
185 # RBASE: %r15 (used as “base of untrusted world” in NaCl for amd64)
155 naclcall_or_nacljmp = 186 naclcall_or_nacljmp =
156 # and $~0x1f, %eax/%ecx/%edx/%ebx/%esp/%ebp/%esi/%edi 187 # This block encodes call and jump instructions of the form:
188 # 0: 83 e_ e0 and $~0x1f,E32
189 # 3: 4_ 01 f_ add RBASE,R32
190 # 6: ff e_ jmpq *R32
191 #### INSTRUCTION ONE (three bytes)
192 # and $~0x1f, E32
157 (0x83 (0xe0|0xe1|0xe2|0xe3|0xe4|0xe5|0xe6|0xe7) 0xe0 193 (0x83 (0xe0|0xe1|0xe2|0xe3|0xe4|0xe5|0xe6|0xe7) 0xe0
158 # add %r15,%rax/%rcx/%rdx/%rbx/%rsp/%rbp/%rsi/%rdi 194 #### INSTRUCTION TWO (three bytes)
195 # add RBASE, R32 (0x01 opcode)
159 b_0100_11x0 0x01 (0xf8|0xf9|0xfa|0xfb|0xfc|0xfd|0xfe|0xff) 196 b_0100_11x0 0x01 (0xf8|0xf9|0xfa|0xfb|0xfc|0xfd|0xfe|0xff)
160 # callq %rax/%rcx/%rdx/%rbx/%rsp/%rbp/%rsi/%rdi 197 #### INSTRUCTION THREE.c (three bytes plus optional REX prefix)
Brad Chen 2012/10/04 17:26:04 three or two bytes?
khim 2012/10/05 08:22:53 Done.
198 # callq R32
161 ((REX_WRX? 0xff (0xd0|0xd1|0xd2|0xd3|0xd4|0xd5|0xd6|0xd7)) | 199 ((REX_WRX? 0xff (0xd0|0xd1|0xd2|0xd3|0xd4|0xd5|0xd6|0xd7)) |
162 # jmpq %rax/%rcx/%rdx/%rbx/%rsp/%rbp/%rsi/%rdi 200 #### INSTRUCTION THREE.j (three bytes plus optional REX prefix)
Brad Chen 2012/10/04 17:26:04 Shouldn't 'three' be 'two' here too? Looks like 'j
khim 2012/10/05 08:22:53 Replaced "j" with "jmp". Now it's "INSTRUCTION TH
201 # jmpq R32
163 (REX_WRX? 0xff (0xe0|0xe1|0xe2|0xe3|0xe4|0xe5|0xe6|0xe7)))) 202 (REX_WRX? 0xff (0xe0|0xe1|0xe2|0xe3|0xe4|0xe5|0xe6|0xe7))))
203 # This action first compares register numbers in three atomic instructions
Brad Chen 2012/10/04 17:26:04 What do you mean by 'atomic instructions'? That me
khim 2012/10/05 08:22:53 atomic -> component.
204 # described above, then it redefines the range of the super-instruction to
205 # include the preceding sandboxing sequence and invalidates jump targets on
206 # the interior of the super-instructions and finally clears “the restricted
207 # register” variable.
208 #
209 # “Magic numbers” correspond to the structure of this particular variant of
210 # the superinstruction.
Brad Chen 2012/10/04 17:26:04 Please be consistent; use either 'super-instructio
khim 2012/10/05 08:22:53 Done.
164 @{ 211 @{
165 instruction_start -= 6; 212 instruction_start -= 6;
166 if (RMFromModRM(instruction_start[1]) != 213 if (RMFromModRM(instruction_start[1]) !=
167 RMFromModRM(instruction_start[5]) || 214 RMFromModRM(instruction_start[5]) ||
168 RMFromModRM(instruction_start[1]) != RMFromModRM(*current_position)) 215 RMFromModRM(instruction_start[1]) != RMFromModRM(*current_position))
169 instruction_info_collected |= UNRECOGNIZED_INSTRUCTION; 216 instruction_info_collected |= UNRECOGNIZED_INSTRUCTION;
170 BitmapClearBit(valid_targets, (instruction_start - data) + 3); 217 MakeJumpTargetInvalid((instruction_start - data) + 3, valid_targets);
171 BitmapClearBit(valid_targets, (instruction_start - data) + 6); 218 MakeJumpTargetInvalid((instruction_start - data) + 6, valid_targets);
172 restricted_register = NO_REG; 219 restricted_register = NO_REG;
173 } | 220 } |
174 221
175 # and $~0x1f, %eax/%ecx/%edx/%ebx/%esp/%ebp/%esi/%edi 222 # This block encodes call and jump instructions of the form:
223 # 0: 83 e_ e0 and $~0x1f,E32
224 # 3: 4_ 03 f_ add RBASE,R32
225 # 6: ff e_ jmpq *R32
226 #### INSTRUCTION ONE (three bytes)
227 # and $~0x1f, E32
176 (0x83 (0xe0|0xe1|0xe2|0xe3|0xe4|0xe5|0xe6|0xe7) 0xe0 228 (0x83 (0xe0|0xe1|0xe2|0xe3|0xe4|0xe5|0xe6|0xe7) 0xe0
177 # add %r15,%rax/%rcx/%rdx/%rbx/%rsp/%rbp/%rsi/%rdi 229 #### INSTRUCTION TWO (three bytes)
230 # add RBASE, R32 (0x03 opcode)
178 b_0100_10x1 0x03 (0xc7|0xcf|0xd7|0xdf|0xe7|0xef|0xf7|0xff) 231 b_0100_10x1 0x03 (0xc7|0xcf|0xd7|0xdf|0xe7|0xef|0xf7|0xff)
179 # callq %rax/%rcx/%rdx/%rbx/%rsp/%rbp/%rsi/%rdi 232 #### INSTRUCTION THREE.c (three bytes plus optional REX prefix)
Brad Chen 2012/10/04 17:26:04 Here again I think you mean 'two' instead of 'thre
khim 2012/10/05 08:22:53 Done.
233 # callq R32
180 ((REX_WRX? 0xff (0xd0|0xd1|0xd2|0xd3|0xd4|0xd5|0xd6|0xd7)) | 234 ((REX_WRX? 0xff (0xd0|0xd1|0xd2|0xd3|0xd4|0xd5|0xd6|0xd7)) |
181 # jmpq %rax/%rcx/%rdx/%rbx/%rsp/%rbp/%rsi/%rdi 235 #### INSTRUCTION THREE.j (three bytes plus optional REX prefix)
236 # jmpq R32
182 (REX_WRX? 0xff (0xe0|0xe1|0xe2|0xe3|0xe4|0xe5|0xe6|0xe7)))) 237 (REX_WRX? 0xff (0xe0|0xe1|0xe2|0xe3|0xe4|0xe5|0xe6|0xe7))))
238 # This action first compares register numbers in three atomic instructions
239 # described above, then it redefines the range of the super-instruction to
240 # include the preceding sandboxing sequence and invalidates jump targets on
241 # the interior of the super-instructions and finally clears “the restricted
242 # register” variable.
243 #
244 # “Magic numbers” correspond to the structure of this particular variant of
245 # the superinstruction.
Brad Chen 2012/10/04 17:26:04 This action is identical to the previous action. P
khim 2012/10/05 08:22:53 All actions are different: where actions are ident
183 @{ 246 @{
184 instruction_start -= 6; 247 instruction_start -= 6;
185 if (RMFromModRM(instruction_start[1]) != 248 if (RMFromModRM(instruction_start[1]) !=
186 RegFromModRM(instruction_start[5]) || 249 RegFromModRM(instruction_start[5]) ||
187 RMFromModRM(instruction_start[1]) != RMFromModRM(*current_position)) 250 RMFromModRM(instruction_start[1]) != RMFromModRM(*current_position))
188 instruction_info_collected |= UNRECOGNIZED_INSTRUCTION; 251 instruction_info_collected |= UNRECOGNIZED_INSTRUCTION;
189 BitmapClearBit(valid_targets, (instruction_start - data) + 3); 252 MakeJumpTargetInvalid((instruction_start - data) + 3, valid_targets);
190 BitmapClearBit(valid_targets, (instruction_start - data) + 6); 253 MakeJumpTargetInvalid((instruction_start - data) + 6, valid_targets);
191 restricted_register = NO_REG; 254 restricted_register = NO_REG;
192 } | 255 } |
193 256
194 # rex.R?X? and $~0x1f, %eax/%ecx/%edx/%ebx/%esp/%ebp/%esi/%edi 257 # This block encodes call and jump instructions of the form:
258 # 0: 4_ 83 e_ e0 and $~0x1f,E32
259 # 4: 4_ 01 f_ add RBASE,R32
260 # 7: ff e_ jmpq *R32
261 #### INSTRUCTION ONE (four bytes)
262 # and $~0x1f, E32
195 ((REX_RX 0x83 (0xe0|0xe1|0xe2|0xe3|0xe4|0xe5|0xe6|0xe7) 0xe0 263 ((REX_RX 0x83 (0xe0|0xe1|0xe2|0xe3|0xe4|0xe5|0xe6|0xe7) 0xe0
196 # add %r15,%rax/%rcx/%rdx/%rbx/%rsp/%rbp/%rsi/%rdi 264 #### INSTRUCTION TWO (three bytes)
265 # add RBASE, R32 (0x01 opcode)
197 b_0100_11x0 0x01 (0xf8|0xf9|0xfa|0xfb|0xfc|0xfd|0xfe|0xff) 266 b_0100_11x0 0x01 (0xf8|0xf9|0xfa|0xfb|0xfc|0xfd|0xfe|0xff)
198 # callq %rax/%rcx/%rdx/%rbx/%rsp/%rbp/%rsi/%rdi 267 #### INSTRUCTION THREE.c (three bytes plus optional REX prefix)
268 # callq R32
199 ((REX_WRX? 0xff (0xd0|0xd1|0xd2|0xd3|0xd4|0xd5|0xd6|0xd7)) | 269 ((REX_WRX? 0xff (0xd0|0xd1|0xd2|0xd3|0xd4|0xd5|0xd6|0xd7)) |
200 # jmpq %rax/%rcx/%rdx/%rbx/%rsp/%rbp/%rsi/%rdi 270 # jmpq R32
201 (REX_WRX? 0xff (0xe0|0xe1|0xe2|0xe3|0xe4|0xe5|0xe6|0xe7)))) | 271 (REX_WRX? 0xff (0xe0|0xe1|0xe2|0xe3|0xe4|0xe5|0xe6|0xe7)))) |
202 272
203 # and $~0x1f, %r8d/%r9d/%r10d/%r11d/%r12d/%r13d/%r14d 273 # This block encodes call and jump instructions of the form:
274 # 0: 4_ 83 e_ e0 and $~0x1f,E64
275 # 4: 4_ 01 f_ add RBASE,R64
276 # 7: 4_ ff e_ jmpq *R64
277 #### INSTRUCTION ONE (four bytes)
278 # and $~0x1f, E64
204 (b_0100_0xx1 0x83 (0xe0|0xe1|0xe2|0xe3|0xe4|0xe5|0xe6) 0xe0 279 (b_0100_0xx1 0x83 (0xe0|0xe1|0xe2|0xe3|0xe4|0xe5|0xe6) 0xe0
205 # add %r15, %r8d/%r9d/%r10d/%r11d/%r12d/%r13d/%r14d 280 #### INSTRUCTION TWO (three bytes)
281 # add RBASE, R64 (0x01 opcode)
206 b_0100_11x1 0x01 (0xf8|0xf9|0xfa|0xfb|0xfc|0xfd|0xfe) 282 b_0100_11x1 0x01 (0xf8|0xf9|0xfa|0xfb|0xfc|0xfd|0xfe)
207 # callq %r8/%r9/%r10/%r11/%r12/%r13/%r14 283 #### INSTRUCTION THREE.c (four bytes)
284 # callq R64
208 ((b_0100_xxx1 0xff (0xd0|0xd1|0xd2|0xd3|0xd4|0xd5|0xd6)) | 285 ((b_0100_xxx1 0xff (0xd0|0xd1|0xd2|0xd3|0xd4|0xd5|0xd6)) |
209 # jmpq %r8/%r9/%r10/%r11/%r12/%r13/%r14 286 #### INSTRUCTION THREE.j (four bytes)
287 # jmpq R64
210 (b_0100_xxx1 0xff (0xe0|0xe1|0xe2|0xe3|0xe4|0xe5|0xe6))))) 288 (b_0100_xxx1 0xff (0xe0|0xe1|0xe2|0xe3|0xe4|0xe5|0xe6)))))
289 # This action first compares register numbers in three atomic instructions
290 # described above, then it redefines the range of the super-instruction to
291 # include the preceding sandboxing sequence and invalidates jump targets on
292 # the interior of the super-instructions and finally clears “the restricted
293 # register” variable.
294 #
295 # “Magic numbers” correspond to the structure of this particular variant of
296 # the superinstruction (we group actions with identical “magic numbers”).
211 @{ 297 @{
Brad Chen 2012/10/04 17:26:04 This is much too repetitive. You are increasing my
khim 2012/10/05 08:22:53 You can not make the description of the instructio
212 instruction_start -= 7; 298 instruction_start -= 7;
213 if (RMFromModRM(instruction_start[2]) != 299 if (RMFromModRM(instruction_start[2]) !=
214 RMFromModRM(instruction_start[6]) || 300 RMFromModRM(instruction_start[6]) ||
215 RMFromModRM(instruction_start[2]) != RMFromModRM(*current_position)) 301 RMFromModRM(instruction_start[2]) != RMFromModRM(*current_position))
216 instruction_info_collected |= UNRECOGNIZED_INSTRUCTION; 302 instruction_info_collected |= UNRECOGNIZED_INSTRUCTION;
217 BitmapClearBit(valid_targets, (instruction_start - data) + 4); 303 MakeJumpTargetInvalid((instruction_start - data) + 4, valid_targets);
218 BitmapClearBit(valid_targets, (instruction_start - data) + 7); 304 MakeJumpTargetInvalid((instruction_start - data) + 7, valid_targets);
219 restricted_register = NO_REG; 305 restricted_register = NO_REG;
220 } | 306 } |
221 307
222 # rex.R?X? and $~0x1f, %eax/%ecx/%edx/%ebx/%esp/%ebp/%esi/%edi 308 # This block encodes call and jump instructions of the form:
Brad Chen 2012/10/04 17:26:04 Here I think you mean "super-instruction" not "ins
khim 2012/10/05 08:22:53 Done.
309 # 0: 4_ 83 e_ e0 and $~0x1f,E32
310 # 4: 4_ 03 f_ add RBASE,R32
311 # 7: ff e_ jmpq *R32
312 #### INSTRUCTION ONE (four bytes)
313 # and $~0x1f, E32
223 ((REX_RX 0x83 (0xe0|0xe1|0xe2|0xe3|0xe4|0xe5|0xe6|0xe7) 0xe0 314 ((REX_RX 0x83 (0xe0|0xe1|0xe2|0xe3|0xe4|0xe5|0xe6|0xe7) 0xe0
224 # add %r15,%rax/%rcx/%rdx/%rbx/%rsp/%rbp/%rsi/%rdi 315 #### INSTRUCTION TWO (three bytes)
316 # add RBASE, R32 (0x03 opcode)
225 b_0100_10x1 0x03 (0xc7|0xcf|0xd7|0xdf|0xe7|0xef|0xf7|0xff) 317 b_0100_10x1 0x03 (0xc7|0xcf|0xd7|0xdf|0xe7|0xef|0xf7|0xff)
226 # callq %rax/%rcx/%rdx/%rbx/%rsp/%rbp/%rsi/%rdi 318 #### INSTRUCTION THREE.c (three bytes plus optional REX prefix)
Brad Chen 2012/10/04 17:26:04 'two'?
khim 2012/10/05 08:22:53 Done.
319 # callq R32
227 ((REX_WRX? 0xff (0xd0|0xd1|0xd2|0xd3|0xd4|0xd5|0xd6|0xd7)) | 320 ((REX_WRX? 0xff (0xd0|0xd1|0xd2|0xd3|0xd4|0xd5|0xd6|0xd7)) |
228 # jmpq %rax/%rcx/%rdx/%rbx/%rsp/%rbp/%rsi/%rdi 321 # jmpq R32
229 (REX_WRX? 0xff (0xe0|0xe1|0xe2|0xe3|0xe4|0xe5|0xe6|0xe7)))) | 322 (REX_WRX? 0xff (0xe0|0xe1|0xe2|0xe3|0xe4|0xe5|0xe6|0xe7)))) |
Brad Chen 2012/10/04 17:26:04 It's really hard to figure out what parenthetical
khim 2012/10/05 08:22:53 Indeed: indentation was mixed up, sorry. Fixed.
230 323
231 # and $~0x1f, %r8d/%r9d/%r10d/%r11d/%r12d/%r13d/%r14d 324 # This block encodes call and jump instructions of the form:
325 # 0: 4_ 83 e_ e0 and $~0x1f,E64
326 # 4: 4_ 03 f_ add RBASE,R64
327 # 7: 4_ ff e_ jmpq *R64
328 #### INSTRUCTION ONE (four bytes)
329 # and $~0x1f, E64
232 (b_0100_0xx1 0x83 (0xe0|0xe1|0xe2|0xe3|0xe4|0xe5|0xe6) 0xe0 330 (b_0100_0xx1 0x83 (0xe0|0xe1|0xe2|0xe3|0xe4|0xe5|0xe6) 0xe0
233 # add %r15, %r8d/%r9d/%r10d/%r11d/%r12d/%r13d/%r14d 331 #### INSTRUCTION TWO (three bytes)
332 # add RBASE, R64 (0x03 opcode)
234 b_0100_11x1 0x03 (0xc7|0xcf|0xd7|0xdf|0xe7|0xef|0xf7) 333 b_0100_11x1 0x03 (0xc7|0xcf|0xd7|0xdf|0xe7|0xef|0xf7)
235 # callq %r8/%r9/%r10/%r11/%r12/%r13/%r14 334 #### INSTRUCTION THREE.c (four bytes)
335 # callq R64
236 ((b_0100_xxx1 0xff (0xd0|0xd1|0xd2|0xd3|0xd4|0xd5|0xd6)) | 336 ((b_0100_xxx1 0xff (0xd0|0xd1|0xd2|0xd3|0xd4|0xd5|0xd6)) |
237 # jmpq %r8/%r9/%r10/%r11/%r12/%r13/%r14 337 #### INSTRUCTION THREE.j (four bytes)
338 # jmpq R64
238 (b_0100_xxx1 0xff (0xe0|0xe1|0xe2|0xe3|0xe4|0xe5|0xe6))))) 339 (b_0100_xxx1 0xff (0xe0|0xe1|0xe2|0xe3|0xe4|0xe5|0xe6)))))
340 # This action first compares register numbers in three atomic instructions
Brad Chen 2012/10/04 17:26:04 Every place you find yourself repeating a comment
khim 2012/10/05 08:22:53 Done.
341 # described above, then it redefines the range of the super-instruction to
342 # include the preceding sandboxing sequence and invalidates jump targets on
343 # the interior of the super-instructions and finally clears “the restricted
344 # register” variable.
345 #
346 # “Magic numbers” correspond to the structure of this particular variant of
347 # the superinstruction (we group actions with identical “magic numbers”).
239 @{ 348 @{
240 instruction_start -= 7; 349 instruction_start -= 7;
241 if (RMFromModRM(instruction_start[2]) != 350 if (RMFromModRM(instruction_start[2]) !=
242 RegFromModRM(instruction_start[6]) || 351 RegFromModRM(instruction_start[6]) ||
243 RMFromModRM(instruction_start[2]) != RMFromModRM(*current_position)) 352 RMFromModRM(instruction_start[2]) != RMFromModRM(*current_position))
244 instruction_info_collected |= UNRECOGNIZED_INSTRUCTION; 353 instruction_info_collected |= UNRECOGNIZED_INSTRUCTION;
245 BitmapClearBit(valid_targets, (instruction_start - data) + 4); 354 MakeJumpTargetInvalid((instruction_start - data) + 4, valid_targets);
246 BitmapClearBit(valid_targets, (instruction_start - data) + 7); 355 MakeJumpTargetInvalid((instruction_start - data) + 7, valid_targets);
247 restricted_register = NO_REG; 356 restricted_register = NO_REG;
248 }; 357 };
249 358
250 # EMMS/SSE2/AVX instructions which have implicit %ds:(%rsi) operand 359 # EMMS/SSE2/AVX instructions which have implicit %ds:(%rsi) operand
251 # maskmovq %mmX,%mmY 360 # maskmovq %mmX,%mmY
252 maskmovq = 361 maskmovq =
253 REX_WRXB? (0x0f 0xf7) 362 REX_WRXB? (0x0f 0xf7)
254 @CPUFeature_EMMX modrm_registers; 363 @CPUFeature_EMMX modrm_registers;
255 # maskmovdqu %xmmX, %xmmY 364 # maskmovdqu %xmmX, %xmmY
256 maskmovdqu = 365 maskmovdqu =
(...skipping 25 matching lines...) Expand all
282 # String instructions which use both %ds:(%rsi) and %ds:(%rdi) 391 # String instructions which use both %ds:(%rsi) and %ds:(%rdi)
283 string_instruction_rsi_rdi = 392 string_instruction_rsi_rdi =
284 condrep? 0xa6 | # cmpsb %es:(%rdi),%ds:(%rsi) 393 condrep? 0xa6 | # cmpsb %es:(%rdi),%ds:(%rsi)
285 data16condrep 0xa7 | # cmpsw %es:(%rdi),%ds:(%rsi) 394 data16condrep 0xa7 | # cmpsw %es:(%rdi),%ds:(%rsi)
286 condrep? REXW_NONE? 0xa7 | # cmps[lq] %es:(%rdi),%ds:(%rsi) 395 condrep? REXW_NONE? 0xa7 | # cmps[lq] %es:(%rdi),%ds:(%rsi)
287 396
288 rep? 0xa4 | # movsb %es:(%rdi),%ds:(%rsi) 397 rep? 0xa4 | # movsb %es:(%rdi),%ds:(%rsi)
289 data16rep 0xa5 | # movsw %es:(%rdi),%ds:(%rsi) 398 data16rep 0xa5 | # movsw %es:(%rdi),%ds:(%rsi)
290 rep? REXW_NONE? 0xa5 ; # movs[lq] %es:(%rdi),%ds:(%rsi) 399 rep? REXW_NONE? 0xa5 ; # movs[lq] %es:(%rdi),%ds:(%rsi)
291 400
401 # Superinstruction which handle instructions which require sandboxed %rsi.
402 #
403 # There are two variants which handle spurious REX prefixes.
Brad Chen 2012/10/04 17:26:04 In what sense are the REX prefixes spurious? This
khim 2012/10/05 08:22:53 They don't change the meaning of the instruction b
404 #
405 # Note that both “0x89 0xf6” and “0x8b 0xf6” encode “mov %esi,%esi”:
406 # “mov” with opcode “0x89” moves from “A” to “B” while “mov” with opcode
407 # “0x8b” moves from “B” to “A” but when “A” and “B” happen to denote the
408 # same register there are no functional difference between these opcodes.
292 sandbox_instruction_rsi_no_rdi = 409 sandbox_instruction_rsi_no_rdi =
293 (0x89 | 0x8b) 0xf6 . # mov %esi,%esi 410 (0x89 | 0x8b) 0xf6 . # mov %esi,%esi
Brad Chen 2012/10/04 17:26:04 What does '.' mean here? How is it different from
khim 2012/10/05 08:22:53 "." means concatenation which is default action, t
294 0x49 0x8d 0x34 0x37 . # lea (%r15,%rsi,1),%rsi 411 0x49 0x8d 0x34 0x37 . # lea (%r15,%rsi,1),%rsi
295 string_instruction_rsi_no_rdi 412 string_instruction_rsi_no_rdi
413 # This action redefines the range of the super-instruction to include the
Brad Chen 2012/10/04 17:26:04 This same identical comment is repeated at least f
khim 2012/10/05 08:22:53 Done.
414 # preceding sandboxing sequence then invalidates jump targets on the
415 # interior of the super-instructions and finally clears “the restricted
416 # register” variable.
417 #
418 # “Magic numbers” correspond to the structure of this particular variant of
419 # the superinstruction.
296 @{ 420 @{
297 instruction_start -= 6; 421 instruction_start -= 6;
298 BitmapClearBit(valid_targets, (instruction_start - data) + 2); 422 MakeJumpTargetInvalid((instruction_start - data) + 2, valid_targets);
299 BitmapClearBit(valid_targets, (instruction_start - data) + 6); 423 MakeJumpTargetInvalid((instruction_start - data) + 6, valid_targets);
300 restricted_register = NO_REG; 424 restricted_register = NO_REG;
301 } | 425 } |
302 426
303 REX_X (0x89 | 0x8b) 0xf6 . # mov %esi,%esi 427 REX_X (0x89 | 0x8b) 0xf6 . # mov %esi,%esi
304 0x49 0x8d 0x34 0x37 . # lea (%r15,%rsi,1),%rsi 428 0x49 0x8d 0x34 0x37 . # lea (%r15,%rsi,1),%rsi
305 string_instruction_rsi_no_rdi 429 string_instruction_rsi_no_rdi
430 # This action redefines the range of the super-instruction to include the
431 # preceding sandboxing sequence then invalidates jump targets on the
432 # interior of the super-instructions and finally clears “the restricted
433 # register” variable.
434 #
435 # “Magic numbers” correspond to the structure of this particular variant of
436 # the superinstruction.
306 @{ 437 @{
307 instruction_start -= 7; 438 instruction_start -= 7;
308 BitmapClearBit(valid_targets, (instruction_start - data) + 3); 439 MakeJumpTargetInvalid((instruction_start - data) + 3, valid_targets);
309 BitmapClearBit(valid_targets, (instruction_start - data) + 7); 440 MakeJumpTargetInvalid((instruction_start - data) + 7, valid_targets);
310 restricted_register = NO_REG; 441 restricted_register = NO_REG;
311 }; 442 };
312 443
444 # Superinstruction which handle instructions which require sandboxed %rdi.
445 #
446 # There are two variants which handle spurious REX prefixes.
447 #
448 # Note that both “0x89 0xff” and “0x8b 0xff” encode “mov %edi,%edi”:
449 # “mov” with opcode “0x89” moves from “A” to “B” while “mov” with opcode
450 # “0x8b” moves from “B” to “A” but when “A” and “B” happen to denote the
451 # same register there are no functional difference between these opcodes.
313 sandbox_instruction_rdi_no_rsi = 452 sandbox_instruction_rdi_no_rsi =
314 (0x89 | 0x8b) 0xff . # mov %edi,%edi 453 (0x89 | 0x8b) 0xff . # mov %edi,%edi
315 0x49 0x8d 0x3c 0x3f . # lea (%r15,%rdi,1),%rdi 454 0x49 0x8d 0x3c 0x3f . # lea (%r15,%rdi,1),%rdi
316 (string_instruction_rdi_no_rsi | mmx_sse_rdi_instruction) 455 (string_instruction_rdi_no_rsi | mmx_sse_rdi_instruction)
456 # This action redefines the range of the super-instruction to include the
457 # preceding sandboxing sequence then invalidates jump targets on the
458 # interior of the super-instructions and finally clears “the restricted
459 # register” variable.
460 #
461 # “Magic numbers” correspond to the structure of this particular variant of
462 # the superinstruction.
317 @{ 463 @{
318 instruction_start -= 6; 464 instruction_start -= 6;
319 BitmapClearBit(valid_targets, (instruction_start - data) + 2); 465 MakeJumpTargetInvalid((instruction_start - data) + 2, valid_targets);
320 BitmapClearBit(valid_targets, (instruction_start - data) + 6); 466 MakeJumpTargetInvalid((instruction_start - data) + 6, valid_targets);
321 restricted_register = NO_REG; 467 restricted_register = NO_REG;
322 } | 468 } |
323 469
324 REX_X (0x89 | 0x8b) 0xff . # mov %edi,%edi 470 REX_X (0x89 | 0x8b) 0xff . # mov %edi,%edi
325 0x49 0x8d 0x3c 0x3f . # lea (%r15,%rdi,1),%rdi 471 0x49 0x8d 0x3c 0x3f . # lea (%r15,%rdi,1),%rdi
326 (string_instruction_rdi_no_rsi | mmx_sse_rdi_instruction) 472 (string_instruction_rdi_no_rsi | mmx_sse_rdi_instruction)
473 # This action redefines the range of the super-instruction to include the
474 # preceding sandboxing sequence then invalidates jump targets on the
475 # interior of the super-instructions and finally clears “the restricted
476 # register” variable.
477 #
478 # “Magic numbers” correspond to the structure of this particular variant of
479 # the superinstruction.
327 @{ 480 @{
328 instruction_start -= 7; 481 instruction_start -= 7;
329 BitmapClearBit(valid_targets, (instruction_start - data) + 3); 482 MakeJumpTargetInvalid((instruction_start - data) + 3, valid_targets);
330 BitmapClearBit(valid_targets, (instruction_start - data) + 7); 483 MakeJumpTargetInvalid((instruction_start - data) + 7, valid_targets);
331 restricted_register = NO_REG; 484 restricted_register = NO_REG;
332 }; 485 };
333 486
334 487
335 # String instructions which use both %ds:(%rsi) and %ds:(%rdi) 488 # Superinstruction which handle instructions which require both sandboxed %rsi
489 # and sandboxed %rdi.
490 #
491 # There are four variants which handle spurious REX prefixes.
492 #
493 # Note that both “0x89 0xf6” and “0x8b 0xf6” encode “mov %esi,%esi” while both
494 # “0x89 0xff” and “0x8b 0xff” encode “mov %edi,%edi”: “mov” with opcode “0x89”
495 # moves from “A” to “B” while “mov” with opcode “0x8b” moves from “B” to “A”
496 # but when “A” and “B” happen to denote the same register there are no
497 # functional difference between these opcodes.
336 sandbox_instruction_rsi_rdi = 498 sandbox_instruction_rsi_rdi =
337 (0x89 | 0x8b) 0xf6 . # mov %esi,%esi 499 (0x89 | 0x8b) 0xf6 . # mov %esi,%esi
338 0x49 0x8d 0x34 0x37 . # lea (%r15,%rsi,1),%rsi 500 0x49 0x8d 0x34 0x37 . # lea (%r15,%rsi,1),%rsi
339 (0x89 | 0x8b) 0xff . # mov %edi,%edi 501 (0x89 | 0x8b) 0xff . # mov %edi,%edi
340 0x49 0x8d 0x3c 0x3f . # lea (%r15,%rdi,1),%rdi 502 0x49 0x8d 0x3c 0x3f . # lea (%r15,%rdi,1),%rdi
341 string_instruction_rsi_rdi 503 string_instruction_rsi_rdi
504 # This action redefines the range of the super-instruction to include the
505 # preceding sandboxing sequence then invalidates jump targets on the
506 # interior of the super-instructions and finally clears “the restricted
507 # register” variable.
508 #
509 # “Magic numbers” correspond to the structure of this particular variant of
510 # the superinstruction.
342 @{ 511 @{
343 instruction_start -= 12; 512 instruction_start -= 12;
344 BitmapClearBit(valid_targets, (instruction_start - data) + 2); 513 MakeJumpTargetInvalid((instruction_start - data) + 2, valid_targets);
345 BitmapClearBit(valid_targets, (instruction_start - data) + 6); 514 MakeJumpTargetInvalid((instruction_start - data) + 6, valid_targets);
346 BitmapClearBit(valid_targets, (instruction_start - data) + 8); 515 MakeJumpTargetInvalid((instruction_start - data) + 8, valid_targets);
347 BitmapClearBit(valid_targets, (instruction_start - data) + 12); 516 MakeJumpTargetInvalid((instruction_start - data) + 12, valid_targets);
348 restricted_register = NO_REG; 517 restricted_register = NO_REG;
349 } | 518 } |
350 519
351 (0x89 | 0x8b) 0xf6 . # mov %esi,%esi 520 (0x89 | 0x8b) 0xf6 . # mov %esi,%esi
352 0x49 0x8d 0x34 0x37 . # lea (%r15,%rsi,1),%rsi 521 0x49 0x8d 0x34 0x37 . # lea (%r15,%rsi,1),%rsi
353 REX_X (0x89 | 0x8b) 0xff . # mov %edi,%edi 522 REX_X (0x89 | 0x8b) 0xff . # mov %edi,%edi
354 0x49 0x8d 0x3c 0x3f . # lea (%r15,%rdi,1),%rdi 523 0x49 0x8d 0x3c 0x3f . # lea (%r15,%rdi,1),%rdi
355 string_instruction_rsi_rdi 524 string_instruction_rsi_rdi
525 # This action redefines the range of the super-instruction to include the
526 # preceding sandboxing sequence then invalidates jump targets on the
527 # interior of the super-instructions and finally clears “the restricted
528 # register” variable.
529 #
530 # “Magic numbers” correspond to the structure of this particular variant of
531 # the superinstruction.
356 @{ 532 @{
357 instruction_start -= 13; 533 instruction_start -= 13;
358 BitmapClearBit(valid_targets, (instruction_start - data) + 2); 534 MakeJumpTargetInvalid((instruction_start - data) + 2, valid_targets);
359 BitmapClearBit(valid_targets, (instruction_start - data) + 6); 535 MakeJumpTargetInvalid((instruction_start - data) + 6, valid_targets);
360 BitmapClearBit(valid_targets, (instruction_start - data) + 9); 536 MakeJumpTargetInvalid((instruction_start - data) + 9, valid_targets);
361 BitmapClearBit(valid_targets, (instruction_start - data) + 13); 537 MakeJumpTargetInvalid((instruction_start - data) + 13, valid_targets);
362 restricted_register = NO_REG; 538 restricted_register = NO_REG;
363 } | 539 } |
364 540
365 REX_X (0x89 | 0x8b) 0xf6 . # mov %esi,%esi 541 REX_X (0x89 | 0x8b) 0xf6 . # mov %esi,%esi
366 0x49 0x8d 0x34 0x37 . # lea (%r15,%rsi,1),%rsi 542 0x49 0x8d 0x34 0x37 . # lea (%r15,%rsi,1),%rsi
367 (0x89 | 0x8b) 0xff . # mov %edi,%edi 543 (0x89 | 0x8b) 0xff . # mov %edi,%edi
368 0x49 0x8d 0x3c 0x3f . # lea (%r15,%rdi,1),%rdi 544 0x49 0x8d 0x3c 0x3f . # lea (%r15,%rdi,1),%rdi
369 string_instruction_rsi_rdi 545 string_instruction_rsi_rdi
546 # This action redefines the range of the super-instruction to include the
547 # preceding sandboxing sequence then invalidates jump targets on the
548 # interior of the super-instructions and finally clears “the restricted
549 # register” variable.
550 #
551 # “Magic numbers” correspond to the structure of this particular variant of
552 # the superinstruction.
370 @{ 553 @{
371 instruction_start -= 13; 554 instruction_start -= 13;
372 BitmapClearBit(valid_targets, (instruction_start - data) + 3); 555 MakeJumpTargetInvalid((instruction_start - data) + 3, valid_targets);
373 BitmapClearBit(valid_targets, (instruction_start - data) + 7); 556 MakeJumpTargetInvalid((instruction_start - data) + 7, valid_targets);
374 BitmapClearBit(valid_targets, (instruction_start - data) + 9); 557 MakeJumpTargetInvalid((instruction_start - data) + 9, valid_targets);
375 BitmapClearBit(valid_targets, (instruction_start - data) + 13); 558 MakeJumpTargetInvalid((instruction_start - data) + 13, valid_targets);
376 restricted_register = NO_REG; 559 restricted_register = NO_REG;
377 } | 560 } |
378 561
379 REX_X (0x89 | 0x8b) 0xf6 . # mov %esi,%esi 562 REX_X (0x89 | 0x8b) 0xf6 . # mov %esi,%esi
380 0x49 0x8d 0x34 0x37 . # lea (%r15,%rsi,1),%rsi 563 0x49 0x8d 0x34 0x37 . # lea (%r15,%rsi,1),%rsi
381 REX_X (0x89 | 0x8b) 0xff . # mov %edi,%edi 564 REX_X (0x89 | 0x8b) 0xff . # mov %edi,%edi
382 0x49 0x8d 0x3c 0x3f . # lea (%r15,%rdi,1),%rdi 565 0x49 0x8d 0x3c 0x3f . # lea (%r15,%rdi,1),%rdi
383 string_instruction_rsi_rdi 566 string_instruction_rsi_rdi
567 # This action redefines the range of the super-instruction to include the
568 # preceding sandboxing sequence then invalidates jump targets on the
569 # interior of the super-instructions and finally clears “the restricted
570 # register” variable.
571 #
572 # “Magic numbers” correspond to the structure of this particular variant of
573 # the superinstruction.
384 @{ 574 @{
385 instruction_start -= 14; 575 instruction_start -= 14;
386 BitmapClearBit(valid_targets, (instruction_start - data) + 3); 576 MakeJumpTargetInvalid((instruction_start - data) + 3, valid_targets);
387 BitmapClearBit(valid_targets, (instruction_start - data) + 7); 577 MakeJumpTargetInvalid((instruction_start - data) + 7, valid_targets);
388 BitmapClearBit(valid_targets, (instruction_start - data) + 10); 578 MakeJumpTargetInvalid((instruction_start - data) + 10, valid_targets);
389 BitmapClearBit(valid_targets, (instruction_start - data) + 14); 579 MakeJumpTargetInvalid((instruction_start - data) + 14, valid_targets);
390 restricted_register = NO_REG; 580 restricted_register = NO_REG;
391 }; 581 };
392 582
393 special_instruction = 583 special_instruction =
394 (rbp_modifications | 584 (rbp_modifications |
395 rsp_modifications | 585 rsp_modifications |
396 rbp_sandboxing | 586 rbp_sandboxing |
397 rsp_sandboxing | 587 rsp_sandboxing |
398 naclcall_or_nacljmp | 588 naclcall_or_nacljmp |
399 sandbox_instruction_rsi_no_rdi | 589 sandbox_instruction_rsi_no_rdi |
400 sandbox_instruction_rdi_no_rsi | 590 sandbox_instruction_rdi_no_rsi |
401 sandbox_instruction_rsi_rdi) 591 sandbox_instruction_rsi_rdi)
402 @{ 592 @{
403 instruction_info_collected |= SPECIAL_INSTRUCTION; 593 instruction_info_collected |= SPECIAL_INSTRUCTION;
404 }; 594 };
405 595
406 # Remove special instructions which are only allowed in special cases. 596 # Remove special instructions which are only allowed in special cases.
407 normal_instruction = one_instruction - special_instruction; 597 normal_instruction = one_instruction - special_instruction;
408 598
409 # Check if call is properly aligned 599 # Check if call is properly aligned.
600 #
601 # For direct call we explicitly encode all variations. For indirect call
602 # we accept all the special instructions which ends with indirect call.
410 call_alignment = 603 call_alignment =
411 ((normal_instruction & 604 ((normal_instruction &
412 # Direct call 605 # Direct call
413 ((data16 REX_RXB? 0xe8 rel16) | 606 ((data16 REX_RXB? 0xe8 rel16) |
414 (REX_WRXB? 0xe8 rel32) | 607 (REX_WRXB? 0xe8 rel32) |
415 (data16 REXW_RXB 0xe8 rel32))) | 608 (data16 REXW_RXB 0xe8 rel32))) |
416 (special_instruction & 609 (special_instruction &
417 # Indirect call 610 # Indirect call
418 (any* data16? REX_WRXB? 0xff ((opcode_2 | opcode_3) any* & 611 (any* data16? REX_WRXB? 0xff ((opcode_2 | opcode_3) any* &
419 (modrm_memory | modrm_registers))))) 612 (modrm_memory | modrm_registers)))))
420 @{ 613 @{
421 if (((current_position - data) & kBundleMask) != kBundleMask) 614 if (((current_position - data) & kBundleMask) != kBundleMask)
422 instruction_info_collected |= BAD_CALL_ALIGNMENT; 615 instruction_info_collected |= BAD_CALL_ALIGNMENT;
423 }; 616 };
424 617
425 618
426 main := ((call_alignment | normal_instruction | special_instruction) 619 main := ((call_alignment | normal_instruction | special_instruction)
427 >{ 620 >{
428 BitmapSetBit(valid_targets, current_position - data); 621 MakeJumpTargetValid(current_position - data, valid_targets);
429 } 622 }
430 @{ 623 @{
431 if ((instruction_info_collected & 624 if ((instruction_info_collected &
432 (VALIDATION_ERRORS_MASK | BAD_CALL_ALIGNMENT)) || 625 (VALIDATION_ERRORS_MASK | BAD_CALL_ALIGNMENT)) ||
433 (options & CALL_USER_CALLBACK_ON_EACH_INSTRUCTION)) { 626 (options & CALL_USER_CALLBACK_ON_EACH_INSTRUCTION)) {
434 result &= user_callback( 627 result &= user_callback(
435 instruction_start, current_position, 628 instruction_start, current_position,
436 instruction_info_collected | 629 instruction_info_collected |
437 ((restricted_register << RESTRICTED_REGISTER_SHIFT) & 630 ((restricted_register << RESTRICTED_REGISTER_SHIFT) &
438 RESTRICTED_REGISTER_MASK), callback_data); 631 RESTRICTED_REGISTER_MASK), callback_data);
439 } 632 }
440 /* On successful match the instruction start must point to the next byte 633 /* On successful match the instruction start must point to the next byte
441 * to be able to report the new offset as the start of instruction 634 * to be able to report the new offset as the start of instruction
442 * causing error. */ 635 * causing error. */
443 instruction_start = current_position + 1; 636 instruction_start = current_position + 1;
444 instruction_info_collected = 0; 637 instruction_info_collected = 0;
445 SET_REX_PREFIX(FALSE); 638 SET_REX_PREFIX(FALSE);
639 /* Top three bis of VEX2 are inverted: see AMD/Intel manual. */
446 SET_VEX_PREFIX2(0xe0); 640 SET_VEX_PREFIX2(0xe0);
447 SET_VEX_PREFIX3(0x00); 641 SET_VEX_PREFIX3(0x00);
448 operand_states = 0; 642 operand_states = 0;
449 })* 643 })*
450 $err{ 644 $err{
451 result &= user_callback(instruction_start, current_position, 645 result &= user_callback(instruction_start, current_position,
452 UNRECOGNIZED_INSTRUCTION, callback_data); 646 UNRECOGNIZED_INSTRUCTION, callback_data);
453 continue; 647 continue;
454 }; 648 };
455 649
456 }%% 650 }%%
457 651
458 %% write data; 652 %% write data;
459 653
460 Bool ValidateChunkAMD64(const uint8_t *data, size_t size, 654 Bool ValidateChunkAMD64(const uint8_t *data, size_t size,
461 enum validation_options options, 655 enum validation_options options,
462 const NaClCPUFeaturesX86 *cpu_features, 656 const NaClCPUFeaturesX86 *cpu_features,
463 validation_callback_func user_callback, 657 ValidationCallbackFunc user_callback,
464 void *callback_data) { 658 void *callback_data) {
465 bitmap_word valid_targets_small; 659 bitmap_word valid_targets_small;
466 bitmap_word jump_dests_small; 660 bitmap_word jump_dests_small;
467 bitmap_word *valid_targets; 661 bitmap_word *valid_targets;
468 bitmap_word *jump_dests; 662 bitmap_word *jump_dests;
469 const uint8_t *current_position; 663 const uint8_t *current_position;
470 const uint8_t *end_of_bundle; 664 const uint8_t *end_of_bundle;
471 int result = TRUE; 665 int result = TRUE;
472 666
473 CHECK(sizeof valid_targets_small == sizeof jump_dests_small); 667 CHECK(sizeof valid_targets_small == sizeof jump_dests_small);
(...skipping 26 matching lines...) Expand all
500 current_position = end_of_bundle, 694 current_position = end_of_bundle,
501 end_of_bundle = current_position + kBundleSize) { 695 end_of_bundle = current_position + kBundleSize) {
502 /* Start of the instruction being processed. */ 696 /* Start of the instruction being processed. */
503 const uint8_t *instruction_start = current_position; 697 const uint8_t *instruction_start = current_position;
504 int current_state; 698 int current_state;
505 uint32_t instruction_info_collected = 0; 699 uint32_t instruction_info_collected = 0;
506 /* Keeps one byte of information per operand in the current instruction: 700 /* Keeps one byte of information per operand in the current instruction:
507 * 2 bits for register kinds, 701 * 2 bits for register kinds,
508 * 5 bits for register numbers (16 regs plus RIZ). */ 702 * 5 bits for register numbers (16 regs plus RIZ). */
509 uint32_t operand_states = 0; 703 uint32_t operand_states = 0;
510 enum register_name base = NO_REG; 704 enum OperandName base = NO_REG;
511 enum register_name index = NO_REG; 705 enum OperandName index = NO_REG;
512 enum register_name restricted_register = NO_REG; 706 enum OperandName restricted_register = NO_REG;
513 uint8_t rex_prefix = FALSE; 707 uint8_t rex_prefix = FALSE;
514 uint8_t vex_prefix2 = 0xe0; 708 uint8_t vex_prefix2 = 0xe0;
515 uint8_t vex_prefix3 = 0x00; 709 uint8_t vex_prefix3 = 0x00;
516 710
517 %% write init; 711 %% write init;
518 %% write exec; 712 %% write exec;
519 713
520 if (restricted_register == REG_RBP) 714 if (restricted_register == REG_RBP)
521 result &= user_callback(end_of_bundle, end_of_bundle, 715 result &= user_callback(end_of_bundle, end_of_bundle,
522 RESTRICTED_RBP_UNPROCESSED | 716 RESTRICTED_RBP_UNPROCESSED |
(...skipping 10 matching lines...) Expand all
533 user_callback, callback_data); 727 user_callback, callback_data);
534 728
535 /* We only use malloc for a large code sequences */ 729 /* We only use malloc for a large code sequences */
536 if (size > sizeof valid_targets_small) { 730 if (size > sizeof valid_targets_small) {
537 free(jump_dests); 731 free(jump_dests);
538 free(valid_targets); 732 free(valid_targets);
539 } 733 }
540 if (!result) errno = EINVAL; 734 if (!result) errno = EINVAL;
541 return result; 735 return result;
542 } 736 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698