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

Side by Side Diff: src/trusted/validator_mips/inst_classes.h

Issue 9979025: [MIPS] Adding validator for MIPS architecture. (Closed) Base URL: http://src.chromium.org/native_client/trunk/src/native_client/
Patch Set: Rebased patch, conflict resolved. Created 8 years, 6 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
« no previous file with comments | « src/trusted/validator_mips/gen/decode.cc ('k') | src/trusted/validator_mips/mips-opt.table » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2012 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can
4 * be found in the LICENSE file.
5 * Copyright 2012, Google Inc.
6 */
7
8 #ifndef NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_MIPS_INST_CLASSES_H
9 #define NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_MIPS_INST_CLASSES_H
10
11 #include <stdint.h>
12 #include "native_client/src/trusted/validator_mips/model.h"
13 #include "native_client/src/include/portability.h"
14
15
16 /*
17 * Models the "instruction classes" that the decoder produces.
18 */
19 namespace nacl_mips_dec {
20
21 /*
22 * Used to describe whether an instruction is safe, and if not, what the issue
23 * is. Only instructions that MAY_BE_SAFE should be allowed in untrusted code,
24 * and even those may be rejected by the validator.
25 */
26 enum SafetyLevel {
27 /*
28 * The initial value of uninitialized SafetyLevels -- treat as unsafe.
29 */
30 UNKNOWN = 0,
31 /*
32 * This instruction is forbidden by our SFI model.
33 */
34 FORBIDDEN,
35 /*
36 * This instruction may be safe in untrusted code: in isolation it contains
37 * nothing scary, but the validator may overrule this during global analysis.
38 */
39 MAY_BE_SAFE
40 };
41
42
43 // Function (op)codes.
44 uint32_t const kBitwiseLogicalAnd = 0x24; // b100100.
45
46
47 /*
48 * Decodes a class of instructions. Does spooky undefined things if handed
49 * instructions that don't belong to its class. Who defines which instructions
50 * these are? Why, the generated decoder, of course.
51 *
52 * This is an abstract base class intended to be overridden with the details of
53 * particular instruction-classes.
54 *
55 * ClassDecoders should be stateless, and should provide a no-arg constructor
56 * for use by the generated decoder.
57 */
58 class ClassDecoder {
59 public:
60 /*
61 * Checks how safe this instruction is, in isolation.
62 * This will detect any violation in the Mips spec -- undefined encodings,
63 * use of registers that are unpredictable -- and the most basic constraints
64 * in our SFI model. Because ClassDecoders are referentially-transparent and
65 * cannot touch global state, this will not check things that may vary with
66 * ABI version.
67 *
68 * The most positive result this can return is called MAY_BE_SAFE because it
69 * is necessary, but not sufficient: the validator has the final say.
70 */
71 virtual SafetyLevel safety(const Instruction instr) const = 0;
72
73 /*
74 * For instructions that perform 'masking', this function will return whether
75 * this is true or not for the given instruction.
76 *
77 * The result is useful only for Arithm3 'and' instruction.
78 */
79 virtual bool IsMask(const Instruction instr,
80 const nacl_mips_dec::Register dest,
81 const nacl_mips_dec::Register mask) const {
82 UNREFERENCED_PARAMETER(instr);
83 UNREFERENCED_PARAMETER(dest);
84 UNREFERENCED_PARAMETER(mask);
85 return false;
86 }
87
88 /*
89 * The gpr register altered by the instruction.
90 */
91 virtual Register DestGprReg(const Instruction instr) const {
92 UNREFERENCED_PARAMETER(instr);
93 return kRegisterNone;
94 }
95
96 /*
97 * May be used for instr's with immediate operand; like addiu or jal.
98 */
99 virtual uint32_t GetImm(const Instruction instr) const {
100 UNREFERENCED_PARAMETER(instr);
101 return -1;
102 }
103
104 /*
105 * For direct jumps (j, jal, branch instructions).
106 */
107 virtual bool IsDirectJump() const {
108 return false;
109 }
110
111 /*
112 * For jump and link (jal, jalr, bal).
113 */
114 virtual bool IsJal() const {
115 return false;
116 }
117
118 /*
119 * For jump register instructions (jr, jalr).
120 */
121 virtual bool IsJmpReg() const {
122 return false;
123 }
124
125 /*
126 * For the instructions that are followed by a delay slot.
127 */
128 virtual bool HasDelaySlot() const {
129 return IsDirectJump() || IsJmpReg();
130 }
131
132 /*
133 * For load and store instructions.
134 */
135 virtual bool IsLoadStore() const {
136 return false;
137 }
138
139 /*
140 * For direct jumps, returning the destination address.
141 */
142 virtual uint32_t DestAddr(const Instruction instr, uint32_t addr) const {
143 UNREFERENCED_PARAMETER(instr);
144 UNREFERENCED_PARAMETER(addr);
145 return 0;
146 }
147
148 /*
149 * Used by jump register instructions; returns the register that holds the
150 * address to jump to.
151 */
152 virtual Register TargetReg(const Instruction instr) const {
153 UNREFERENCED_PARAMETER(instr);
154 return kRegisterNone;
155 }
156
157 /*
158 * Base address register, for load and store instructions.
159 */
160 virtual Register BaseAddressRegister(const Instruction instr) const {
161 UNREFERENCED_PARAMETER(instr);
162 return kRegisterNone;
163 }
164
165
166 protected:
167 ClassDecoder() {}
168 virtual ~ClassDecoder() {}
169 };
170
171 /*
172 * Current Mips NaCl halt (jr $zero).
173 */
174 class NaClHalt : public ClassDecoder {
175 public:
176 virtual ~NaClHalt() {}
177 virtual SafetyLevel safety(const Instruction instr) const {
178 UNREFERENCED_PARAMETER(instr);
179 return MAY_BE_SAFE;
180 }
181 };
182
183 /*
184 * Represents an instruction that is forbidden under all circumstances, so we
185 * didn't bother decoding it further.
186 */
187 class Forbidden : public ClassDecoder {
188 public:
189 virtual ~Forbidden() {}
190 virtual SafetyLevel safety(const Instruction instr) const {
191 UNREFERENCED_PARAMETER(instr);
192 return FORBIDDEN;
193 }
194 };
195
196 /*
197 * Instructions with 2 registers and an immediate value, where bits 20-16
198 * contain the destination gpr register.
199 */
200 class Arithm2 : public ClassDecoder {
201 public:
202 virtual ~Arithm2() {}
203 virtual Register DestGprReg(const Instruction instr) const {
204 return instr.Reg(20, 16);
205 }
206 virtual SafetyLevel safety(const Instruction instr) const {
207 UNREFERENCED_PARAMETER(instr);
208 return MAY_BE_SAFE;
209 }
210 };
211
212 /*
213 * Instruction with 3 registers, with bits 15-11 containing the destination gpr
214 * register.
215 */
216 class Arithm3 : public ClassDecoder {
217 public:
218 virtual ~Arithm3() {}
219 virtual Register DestGprReg(const Instruction instr) const {
220 return instr.Reg(15, 11);
221 }
222 virtual SafetyLevel safety(const Instruction instr) const {
223 UNREFERENCED_PARAMETER(instr);
224 return MAY_BE_SAFE;
225 }
226 virtual bool IsMask(const Instruction instr,
227 const nacl_mips_dec::Register dest,
228 const nacl_mips_dec::Register mask) const {
229 return ((instr.Bits(5, 0) == kBitwiseLogicalAnd)
230 && instr.Reg(15, 11).Equals(dest)
231 && instr.Reg(25, 21).Equals(dest)
232 && instr.Reg(20, 16).Equals(mask));
233 }
234 };
235
236 /*
237 * Direct jump class, subclassed by Branch and JmpImm.
238 */
239 class DirectJump : public ClassDecoder {
240 public:
241 virtual ~DirectJump() {}
242 virtual SafetyLevel safety(const Instruction instr) const {
243 UNREFERENCED_PARAMETER(instr);
244 return MAY_BE_SAFE;
245 }
246 virtual bool IsDirectJump() const {
247 return true;
248 }
249 };
250
251 /*
252 * Branch instructions.
253 */
254 class Branch : public DirectJump {
255 public:
256 virtual ~Branch() {}
257 virtual uint32_t GetImm(const Instruction instr) const {
258 return instr.Bits(15, 0);
259 }
260 virtual uint32_t DestAddr(const Instruction instr, uint32_t addr) const {
261 return ((addr + kInstrSize) + ((int16_t)GetImm(instr) << 2));
262 }
263 };
264
265 /*
266 * Branch and link instructions (bal, bgezal, bltzal, bgezall, bltzall).
267 */
268 class BranchAndLink : public Branch {
269 public:
270 virtual ~BranchAndLink() {}
271 virtual bool IsJal() const {
272 return true;
273 }
274 };
275
276 /*
277 * Load and store instructions.
278 */
279 class AbstractLoadStore : public ClassDecoder {
280 public:
281 virtual bool IsLoadStore() const {
282 return true;
283 }
284 virtual ~AbstractLoadStore() {}
285 virtual SafetyLevel safety(const Instruction instr) const {
286 UNREFERENCED_PARAMETER(instr);
287 return MAY_BE_SAFE;
288 }
289 virtual Register BaseAddressRegister(const Instruction instr) const {
290 return instr.Reg(25, 21);
291 }
292 };
293
294 /*
295 * Store instructions.
296 */
297 class Store : public AbstractLoadStore {
298 public:
299 virtual ~Store() {}
300 };
301
302 /*
303 * Load instructions, which alter the destination register.
304 */
305 class Load : public AbstractLoadStore {
306 public:
307 virtual ~Load() {}
308 virtual Register DestGprReg(const Instruction instr) const {
309 return instr.Reg(20, 16);
310 }
311 };
312
313 /*
314 * Floating point load and store instructions.
315 */
316 class FPLoadStore : public AbstractLoadStore {
317 public:
318 virtual ~FPLoadStore() {}
319 };
320
321 /*
322 * Store Conditional class, containing the sc instruction,
323 * which might alter the contents of the register which is the 1st operand.
324 */
325 class StoreConditional : public Store {
326 public:
327 virtual ~StoreConditional() {}
328 virtual Register DestGprReg(const Instruction instr) const {
329 return instr.Reg(20, 16);
330 }
331 };
332
333 /*
334 * Direct jumps - j, jal.
335 */
336 class JmpImm : public DirectJump {
337 public:
338 virtual ~JmpImm() {}
339 virtual uint32_t GetImm(const Instruction instr) const {
340 return instr.Bits(25, 0);
341 }
342 virtual uint32_t DestAddr(const Instruction instr, uint32_t addr) const {
343 return ((addr + kInstrSize) & 0xf0000000) + (GetImm(instr) << 2);
344 }
345 };
346
347 /*
348 * Direct jump and link (jal).
349 */
350 class JalImm : public JmpImm {
351 public:
352 virtual ~JalImm() {}
353 virtual bool IsJal() const {
354 return true;
355 }
356 };
357
358 /*
359 * Jump register instructions - jr, jalr.
360 */
361 class JmpReg : public ClassDecoder {
362 public:
363 virtual ~JmpReg() {}
364 virtual SafetyLevel safety(const Instruction instr) const {
365 UNREFERENCED_PARAMETER(instr);
366 return MAY_BE_SAFE;
367 }
368 virtual bool IsJmpReg() const {
369 return true;
370 }
371 virtual Register TargetReg(const Instruction instr) const {
372 return instr.Reg(25, 21);
373 }
374 };
375
376 /*
377 * Jump and link register - jalr.
378 */
379 class JalReg : public JmpReg {
380 public:
381 virtual ~JalReg() {}
382 virtual bool IsJal() const {
383 return true;
384 }
385 virtual Register DestGprReg(const Instruction instr) const {
386 return instr.Reg(15, 11);
387 }
388 };
389
390 /*
391 * ext and ins instructions.
392 */
393 class ExtIns : public ClassDecoder {
394 public:
395 virtual ~ExtIns() {}
396 virtual Register DestGprReg(const Instruction instr) const {
397 return instr.Reg(20, 16);
398 }
399 virtual SafetyLevel safety(const Instruction instr) const {
400 UNREFERENCED_PARAMETER(instr);
401 return MAY_BE_SAFE;
402 }
403 };
404 /*
405 * The instructions that are safe under all circumstances.
406 */
407 class Safe : public ClassDecoder {
408 public:
409 virtual ~Safe() {}
410 virtual SafetyLevel safety(const Instruction instr) const {
411 UNREFERENCED_PARAMETER(instr);
412 return MAY_BE_SAFE;
413 }
414 };
415
416 class Other : public ClassDecoder {
417 public:
418 virtual ~Other() {}
419 virtual SafetyLevel safety(const Instruction instr) const {
420 UNREFERENCED_PARAMETER(instr);
421 return FORBIDDEN;
422 }
423 };
424
425 /*
426 * Unknown instructions, treated as forbidden.
427 */
428 class Unrecognized : public ClassDecoder {
429 public:
430 virtual ~Unrecognized() {}
431 virtual SafetyLevel safety(const Instruction instr) const {
432 UNREFERENCED_PARAMETER(instr);
433 return FORBIDDEN;
434 }
435 };
436 } // namespace
437
438 #endif // NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_MIPS_INST_CLASSES_H
OLDNEW
« no previous file with comments | « src/trusted/validator_mips/gen/decode.cc ('k') | src/trusted/validator_mips/mips-opt.table » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698