Index: src/trusted/validator_arm/validator_small_tests.cc |
diff --git a/src/trusted/validator_arm/validator_small_tests.cc b/src/trusted/validator_arm/validator_small_tests.cc |
index e58888ff2397f3a818f7afb2895d8d980d6b5f37..c9fa8df361251d7ebe69d7b0c7ca0f18926611c2 100644 |
--- a/src/trusted/validator_arm/validator_small_tests.cc |
+++ b/src/trusted/validator_arm/validator_small_tests.cc |
@@ -520,23 +520,6 @@ TEST_F(ValidatorTests, ScaryUndefinedInstructions) { |
} |
} |
-TEST_F(ValidatorTests, LessScaryUndefinedInstructions) { |
- // These instructions are specified by ARM as *permanently* undefined, so we |
- // treat them as a reliable Illegal Instruction trap. |
- |
- static const AnnotatedInstruction perm_undefined[] = { |
- { 0xE7FFDEFE, "permanently undefined instruction produced by LLVM" }, |
- }; |
- |
- for (unsigned i = 0; i < NACL_ARRAY_SIZE(perm_undefined); i++) { |
- arm_inst program[] = { perm_undefined[i].inst }; |
- validation_should_pass(program, |
- 1, |
- kDefaultBaseAddr, |
- perm_undefined[i].about); |
- } |
-} |
- |
TEST_F(ValidatorTests, PcRelativeFirstInst) { |
// Note: This tests the fix for issue 2771. |
static const arm_inst pcrel_boundary_tests[] = { |
@@ -1026,7 +1009,7 @@ TEST_F(ValidatorTests, CheckPushPcUnpredictable) { |
TEST_F(ValidatorTests, ConditionalBreakpoints) { |
ProblemSpy spy; |
arm_inst bkpt = 0xE1200070; // BKPT #0 |
- arm_inst pool_head = nacl_arm_dec::kLiteralPoolHeadInstruction; |
+ arm_inst pool_head = nacl_arm_dec::kLiteralPoolHead; |
for (Instruction::Condition cond = Instruction::EQ; |
cond < Instruction::AL; |
cond = Instruction::Next(cond)) { |
@@ -1040,12 +1023,55 @@ TEST_F(ValidatorTests, ConditionalBreakpoints) { |
} |
TEST_F(ValidatorTests, LiteralPoolHeadIsBreakpoint) { |
- EXPECT_EQ(nacl_arm_dec::kLiteralPoolHeadInstruction & 0xFFF000F0, |
+ EXPECT_EQ(nacl_arm_dec::kLiteralPoolHead & 0xFFF000F0, |
0xE1200070) // BKPT #0 |
<< ("the literal pool head should be a breakpoint: " |
"it needs to act as a roadblock"); |
} |
+TEST_F(ValidatorTests, Breakpoint) { |
+ EXPECT_EQ(nacl_arm_dec::kBreakpoint & 0xFFF000F0, |
+ 0xE1200070) // BKPT #0 |
+ << ("the breakpoint instruction should be a breakpoint: " |
+ "it needs to trap"); |
+} |
+ |
+TEST_F(ValidatorTests, HaltFill) { |
+ EXPECT_EQ(nacl_arm_dec::kHaltFill & 0xFFF000F0, |
+ 0xE7F000F0) // UDF #0 |
+ << ("the halt fill instruction should be UDF: " |
+ "it needs to trap"); |
+} |
+ |
+TEST_F(ValidatorTests, AbortNow) { |
+ EXPECT_EQ(nacl_arm_dec::kAbortNow & 0xFFF000F0, |
+ 0xE7F000F0) // UDF #0 |
+ << ("the abort now instruction should be UDF: " |
+ "it needs to trap"); |
+} |
+ |
+TEST_F(ValidatorTests, FailValidation) { |
+ EXPECT_EQ(nacl_arm_dec::kFailValidation & 0xFFF000F0, |
+ 0xE7F000F0) // UDF #0 |
+ << ("the fail validation instruction should be UDF: " |
+ "it needs to trap"); |
+} |
+ |
+TEST_F(ValidatorTests, UDFAndBKPTValidateAsExpected) { |
+ ProblemSpy spy; |
+ for (uint32_t i = 0; i < 0xFFFF; ++i) { |
+ arm_inst bkpt_inst = 0xE1200070 | ((i & 0xFFF0) << 4) | (i & 0xF); |
+ arm_inst udf_inst = 0xE7F000F0 | ((i & 0xFFF0) << 4) | (i & 0xF); |
+ EXPECT_EQ(validate(&bkpt_inst, 1, kDefaultBaseAddr, &spy), |
+ ((bkpt_inst == nacl_arm_dec::kLiteralPoolHead) || |
+ (bkpt_inst == nacl_arm_dec::kBreakpoint))); |
+ EXPECT_EQ(validate(&udf_inst, 1, kDefaultBaseAddr, &spy), |
+ ((udf_inst == nacl_arm_dec::kHaltFill) || |
+ (udf_inst == nacl_arm_dec::kAbortNow))); |
+ // Tautological note: kFailValidation should fail validation. |
+ } |
+} |
+ |
TEST_F(ValidatorTests, LiteralPoolHeadInstruction) { |
// Make sure that literal pools are handled properly: they should be preceded |
// by a special breakpoint instruction at the start of the bundle, and can |
@@ -1059,7 +1085,7 @@ TEST_F(ValidatorTests, LiteralPoolHeadInstruction) { |
literal_pool[0] = (literal_pool[0] & 0xFFF000F0) | |
(imm16 & 0xF) | |
((imm16 & 0xFFF0) << 8); |
- if (literal_pool[0] == nacl_arm_dec::kLiteralPoolHeadInstruction) { |
+ if (literal_pool[0] == nacl_arm_dec::kLiteralPoolHead) { |
validation_should_pass(literal_pool.data(), |
literal_pool.size(), |
kDefaultBaseAddr, |
@@ -1083,7 +1109,7 @@ TEST_F(ValidatorTests, LiteralPoolHeadPosition) { |
std::fill(literal_pool.begin(), literal_pool.end(), 0xEF000000); // SVC #0 |
if (pos != literal_pool.size()) { |
// We do one iteration without a literal pool head at all. |
- literal_pool[pos] = nacl_arm_dec::kLiteralPoolHeadInstruction; |
+ literal_pool[pos] = nacl_arm_dec::kLiteralPoolHead; |
} |
if (pos == 0) { |
validation_should_pass(literal_pool.data(), |
@@ -1108,7 +1134,7 @@ TEST_F(ValidatorTests, LiteralPoolBig) { |
for (size_t pos = 0; pos <= literal_pools.size(); ++pos) { |
std::fill(literal_pools.begin(), literal_pools.end(), |
0xEF000000); // SVC #0 |
- literal_pools[pos] = nacl_arm_dec::kLiteralPoolHeadInstruction; |
+ literal_pools[pos] = nacl_arm_dec::kLiteralPoolHead; |
validation_should_fail(literal_pools.data(), |
literal_pools.size(), |
kDefaultBaseAddr, |
@@ -1133,7 +1159,7 @@ TEST_F(ValidatorTests, LiteralPoolBranch) { |
continue; |
} |
std::fill(code.begin(), code.end(), 0xE320F000); // NOP |
- code[bundle_pos] = nacl_arm_dec::kLiteralPoolHeadInstruction; |
+ code[bundle_pos] = nacl_arm_dec::kLiteralPoolHead; |
for (size_t b_target = 0; b_target < code.size(); ++b_target) { |
// PC reads as current instruction address plus 8 (e.g. two instructions |
// ahead of b_pos). |