OLD | NEW |
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 "native_client/src/trusted/service_runtime/nacl_config.h" | 8 #include "native_client/src/trusted/service_runtime/nacl_config.h" |
9 #include "native_client/src/trusted/validator_mips/validator.h" | 9 #include "native_client/src/trusted/validator_mips/validator.h" |
10 #include "native_client/src/include/nacl_macros.h" | 10 #include "native_client/src/include/nacl_macros.h" |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 out->ReportProblem(second.addr(), second.safety(), | 209 out->ReportProblem(second.addr(), second.safety(), |
210 kProblemUnsafeLoadStore); | 210 kProblemUnsafeLoadStore); |
211 return PATTERN_UNSAFE; | 211 return PATTERN_UNSAFE; |
212 } | 212 } |
213 } | 213 } |
214 return NO_MATCH; | 214 return NO_MATCH; |
215 } | 215 } |
216 | 216 |
217 | 217 |
218 /* | 218 /* |
| 219 * A thread pointer access is only allowed by these two instructions: |
| 220 * lw Rn, 0($t8) ; load user thread pointer. |
| 221 * lw Rn, 4($t8) ; load IRT thread pointer. |
| 222 */ |
| 223 static PatternMatch CheckLoadThreadPointer(const SfiValidator &sfi, |
| 224 const DecodedInstruction &instr, |
| 225 ProblemSink *out) { |
| 226 UNREFERENCED_PARAMETER(sfi); |
| 227 if (!instr.IsLoadStore()) |
| 228 return NO_MATCH; |
| 229 |
| 230 Register base_addr_reg = instr.BaseAddressRegister(); |
| 231 if (!base_addr_reg.Equals(Register::Tls())) |
| 232 return NO_MATCH; |
| 233 |
| 234 if (instr.IsLoadWord()) { |
| 235 uint32_t offset = instr.GetImm(); |
| 236 if (offset == 0 || offset == 4) |
| 237 return PATTERN_SAFE; |
| 238 } |
| 239 |
| 240 out->ReportProblem(instr.addr(), instr.safety(), |
| 241 kProblemUnsafeLoadStoreThreadPointer); |
| 242 return PATTERN_UNSAFE; |
| 243 } |
| 244 |
| 245 /* |
219 * Checks if there is jump/branch in the delay slot. | 246 * Checks if there is jump/branch in the delay slot. |
220 */ | 247 */ |
221 static PatternMatch CheckBranchInDelaySlot(const SfiValidator &sfi, | 248 static PatternMatch CheckBranchInDelaySlot(const SfiValidator &sfi, |
222 const DecodedInstruction &first, | 249 const DecodedInstruction &first, |
223 const DecodedInstruction &second, | 250 const DecodedInstruction &second, |
224 ProblemSink *out) { | 251 ProblemSink *out) { |
225 UNREFERENCED_PARAMETER(sfi); | 252 UNREFERENCED_PARAMETER(sfi); |
226 if (first.HasDelaySlot() && second.HasDelaySlot()) { | 253 if (first.HasDelaySlot() && second.HasDelaySlot()) { |
227 out->ReportProblem(second.addr(), second.safety(), | 254 out->ReportProblem(second.addr(), second.safety(), |
228 kProblemBranchInDelaySlot); | 255 kProblemBranchInDelaySlot); |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
416 bool SfiValidator::ApplyPatterns(const DecodedInstruction &inst, | 443 bool SfiValidator::ApplyPatterns(const DecodedInstruction &inst, |
417 ProblemSink *out) { | 444 ProblemSink *out) { |
418 // Single-instruction patterns. | 445 // Single-instruction patterns. |
419 typedef PatternMatch (*OneInstPattern)(const SfiValidator &, | 446 typedef PatternMatch (*OneInstPattern)(const SfiValidator &, |
420 const DecodedInstruction &, | 447 const DecodedInstruction &, |
421 ProblemSink *out); | 448 ProblemSink *out); |
422 static const OneInstPattern one_inst_patterns[] = { | 449 static const OneInstPattern one_inst_patterns[] = { |
423 &CheckSafety, | 450 &CheckSafety, |
424 &CheckReadOnly, | 451 &CheckReadOnly, |
425 &CheckCallPosition, | 452 &CheckCallPosition, |
426 &CheckJumpDestAddr | 453 &CheckJumpDestAddr, |
| 454 &CheckLoadThreadPointer |
427 }; | 455 }; |
428 | 456 |
429 bool complete_success = true; | 457 bool complete_success = true; |
430 | 458 |
431 for (uint32_t i = 0; i < NACL_ARRAY_SIZE(one_inst_patterns); i++) { | 459 for (uint32_t i = 0; i < NACL_ARRAY_SIZE(one_inst_patterns); i++) { |
432 PatternMatch r = one_inst_patterns[i](*this, inst, out); | 460 PatternMatch r = one_inst_patterns[i](*this, inst, out); |
433 switch (r) { | 461 switch (r) { |
434 case PATTERN_SAFE: | 462 case PATTERN_SAFE: |
435 case NO_MATCH: | 463 case NO_MATCH: |
436 break; | 464 break; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
521 DecodedInstruction::DecodedInstruction(uint32_t vaddr, | 549 DecodedInstruction::DecodedInstruction(uint32_t vaddr, |
522 Instruction inst, | 550 Instruction inst, |
523 const ClassDecoder &decoder) | 551 const ClassDecoder &decoder) |
524 : vaddr_(vaddr), | 552 : vaddr_(vaddr), |
525 inst_(inst), | 553 inst_(inst), |
526 decoder_(&decoder), | 554 decoder_(&decoder), |
527 safety_(decoder.safety(inst_)) | 555 safety_(decoder.safety(inst_)) |
528 {} | 556 {} |
529 | 557 |
530 } // namespace nacl_mips_val | 558 } // namespace nacl_mips_val |
OLD | NEW |