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 #ifndef NACL_TRUSTED_BUT_NOT_TCB | 7 #ifndef NACL_TRUSTED_BUT_NOT_TCB |
8 #error This file is not meant for use in the TCB | 8 #error This file is not meant for use in the TCB |
9 #endif | 9 #endif |
10 | 10 |
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
513 << undefined_insts[i].about; | 513 << undefined_insts[i].about; |
514 EXPECT_EQ(nacl_arm_dec::UNDEFINED, spy.GetSafetyLevel(first)) | 514 EXPECT_EQ(nacl_arm_dec::UNDEFINED, spy.GetSafetyLevel(first)) |
515 << "Instruction must be flagged as UNDEFINED: " | 515 << "Instruction must be flagged as UNDEFINED: " |
516 << undefined_insts[i].about; | 516 << undefined_insts[i].about; |
517 EXPECT_EQ(nacl_arm_val::kProblemUnsafe, first.problem()) | 517 EXPECT_EQ(nacl_arm_val::kProblemUnsafe, first.problem()) |
518 << "Instruction must be marked unsafe: " | 518 << "Instruction must be marked unsafe: " |
519 << undefined_insts[i].about; | 519 << undefined_insts[i].about; |
520 } | 520 } |
521 } | 521 } |
522 | 522 |
523 TEST_F(ValidatorTests, LessScaryUndefinedInstructions) { | |
524 // These instructions are specified by ARM as *permanently* undefined, so we | |
525 // treat them as a reliable Illegal Instruction trap. | |
526 | |
527 static const AnnotatedInstruction perm_undefined[] = { | |
528 { 0xE7FFDEFE, "permanently undefined instruction produced by LLVM" }, | |
529 }; | |
530 | |
531 for (unsigned i = 0; i < NACL_ARRAY_SIZE(perm_undefined); i++) { | |
532 arm_inst program[] = { perm_undefined[i].inst }; | |
533 validation_should_pass(program, | |
534 1, | |
535 kDefaultBaseAddr, | |
536 perm_undefined[i].about); | |
537 } | |
538 } | |
539 | |
540 TEST_F(ValidatorTests, PcRelativeFirstInst) { | 523 TEST_F(ValidatorTests, PcRelativeFirstInst) { |
541 // Note: This tests the fix for issue 2771. | 524 // Note: This tests the fix for issue 2771. |
542 static const arm_inst pcrel_boundary_tests[] = { | 525 static const arm_inst pcrel_boundary_tests[] = { |
543 0xe59f0000, // ldr r0, [pc, #0] | 526 0xe59f0000, // ldr r0, [pc, #0] |
544 0xe320f000, // nop {0} | 527 0xe320f000, // nop {0} |
545 0xe320f000, // nop {0} | 528 0xe320f000, // nop {0} |
546 0xe320f000, // nop {0}" | 529 0xe320f000, // nop {0}" |
547 }; | 530 }; |
548 validation_should_pass(pcrel_boundary_tests, | 531 validation_should_pass(pcrel_boundary_tests, |
549 NACL_ARRAY_SIZE(pcrel_boundary_tests), | 532 NACL_ARRAY_SIZE(pcrel_boundary_tests), |
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1039 } | 1022 } |
1040 } | 1023 } |
1041 | 1024 |
1042 TEST_F(ValidatorTests, LiteralPoolHeadIsBreakpoint) { | 1025 TEST_F(ValidatorTests, LiteralPoolHeadIsBreakpoint) { |
1043 EXPECT_EQ(nacl_arm_dec::kLiteralPoolHeadInstruction & 0xFFF000F0, | 1026 EXPECT_EQ(nacl_arm_dec::kLiteralPoolHeadInstruction & 0xFFF000F0, |
1044 0xE1200070) // BKPT #0 | 1027 0xE1200070) // BKPT #0 |
1045 << ("the literal pool head should be a breakpoint: " | 1028 << ("the literal pool head should be a breakpoint: " |
1046 "it needs to act as a roadblock"); | 1029 "it needs to act as a roadblock"); |
1047 } | 1030 } |
1048 | 1031 |
| 1032 TEST_F(ValidatorTests, Breakpoint) { |
| 1033 EXPECT_EQ(nacl_arm_dec::kBreakpoint & 0xFFF000F0, |
| 1034 0xE1200070) // BKPT #0 |
| 1035 << ("the breakpoint instruction should be a breakpoint: " |
| 1036 "it needs to trap"); |
| 1037 } |
| 1038 |
| 1039 TEST_F(ValidatorTests, HaltFill) { |
| 1040 EXPECT_EQ(nacl_arm_dec::kHaltFill & 0xFFF000F0, |
| 1041 0xE7F000F0) // UDF #0 |
| 1042 << ("the halt fill instruction should be UDF: " |
| 1043 "it needs to trap"); |
| 1044 } |
| 1045 |
| 1046 TEST_F(ValidatorTests, AbortNow) { |
| 1047 EXPECT_EQ(nacl_arm_dec::kAbortNow & 0xFFF000F0, |
| 1048 0xE7F000F0) // UDF #0 |
| 1049 << ("the abort now instruction should be UDF: " |
| 1050 "it needs to trap"); |
| 1051 } |
| 1052 |
| 1053 TEST_F(ValidatorTests, FailValidation) { |
| 1054 EXPECT_EQ(nacl_arm_dec::kFailValidation & 0xFFF000F0, |
| 1055 0xE7F000F0) // UDF #0 |
| 1056 << ("the fail validation instruction should be UDF: " |
| 1057 "it needs to trap"); |
| 1058 } |
| 1059 |
| 1060 TEST_F(ValidatorTests, UDFAndBKPTValidateAsExpected) { |
| 1061 ProblemSpy spy; |
| 1062 for (uint32_t i = 0; i < 0xFFFF; ++i) { |
| 1063 arm_inst bkpt_inst = 0xE1200070 | ((i & 0xFFF0) << 4) | (i & 0xF); |
| 1064 arm_inst udf_inst = 0xE7F000F0 | ((i & 0xFFF0) << 4) | (i & 0xF); |
| 1065 EXPECT_EQ(validate(&bkpt_inst, 1, kDefaultBaseAddr, &spy), |
| 1066 ((bkpt_inst == nacl_arm_dec::kLiteralPoolHeadInstruction) || |
| 1067 (bkpt_inst == nacl_arm_dec::kBreakpoint))); |
| 1068 EXPECT_EQ(validate(&udf_inst, 1, kDefaultBaseAddr, &spy), |
| 1069 ((udf_inst == nacl_arm_dec::kHaltFill) || |
| 1070 (udf_inst == nacl_arm_dec::kAbortNow))); |
| 1071 // Tautological note: kFailValidation should fail validation. |
| 1072 } |
| 1073 } |
| 1074 |
1049 TEST_F(ValidatorTests, LiteralPoolHeadInstruction) { | 1075 TEST_F(ValidatorTests, LiteralPoolHeadInstruction) { |
1050 // Make sure that literal pools are handled properly: they should be preceded | 1076 // Make sure that literal pools are handled properly: they should be preceded |
1051 // by a special breakpoint instruction at the start of the bundle, and can | 1077 // by a special breakpoint instruction at the start of the bundle, and can |
1052 // then contain any bits that would otherwise look malicious. | 1078 // then contain any bits that would otherwise look malicious. |
1053 // Each literal pool bundle has to start with such a literal pool head. | 1079 // Each literal pool bundle has to start with such a literal pool head. |
1054 vector<arm_inst> literal_pool(_validator.InstructionsPerBundle(), | 1080 vector<arm_inst> literal_pool(_validator.InstructionsPerBundle(), |
1055 0xEF000000); // SVC #0 | 1081 0xEF000000); // SVC #0 |
1056 literal_pool[0] = 0xE1200070; // BKPT #0 | 1082 literal_pool[0] = 0xE1200070; // BKPT #0 |
1057 // Try out all BKPT encodings, and make sure only one of them works. | 1083 // Try out all BKPT encodings, and make sure only one of them works. |
1058 for (uint32_t imm16 = 0; imm16 <= 0xFFFF; ++imm16) { | 1084 for (uint32_t imm16 = 0; imm16 <= 0xFFFF; ++imm16) { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1158 } | 1184 } |
1159 } | 1185 } |
1160 | 1186 |
1161 }; // anonymous namespace | 1187 }; // anonymous namespace |
1162 | 1188 |
1163 // Test driver function. | 1189 // Test driver function. |
1164 int main(int argc, char *argv[]) { | 1190 int main(int argc, char *argv[]) { |
1165 testing::InitGoogleTest(&argc, argv); | 1191 testing::InitGoogleTest(&argc, argv); |
1166 return RUN_ALL_TESTS(); | 1192 return RUN_ALL_TESTS(); |
1167 } | 1193 } |
OLD | NEW |