| 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 /* | 7 /* |
| 8 * Tests the decoder. | 8 * Tests the decoder. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #ifndef NACL_TRUSTED_BUT_NOT_TCB |
| 12 #error This file is not meant for use in the TCB |
| 13 #endif |
| 14 |
| 11 #include "native_client/src/trusted/validator_arm/decoder_tester.h" | 15 #include "native_client/src/trusted/validator_arm/decoder_tester.h" |
| 12 | 16 |
| 13 #include <string> | 17 #include <string> |
| 14 #include "gtest/gtest.h" | 18 #include "gtest/gtest.h" |
| 15 | 19 |
| 16 using nacl_arm_dec::kArm32InstSize; | 20 using nacl_arm_dec::kArm32InstSize; |
| 17 using nacl_arm_dec::kThumbWordSize; | 21 using nacl_arm_dec::kThumbWordSize; |
| 18 using nacl_arm_dec::ClassDecoder; | |
| 19 using nacl_arm_dec::Instruction; | 22 using nacl_arm_dec::Instruction; |
| 20 using nacl_arm_dec::MAY_BE_SAFE; | 23 using nacl_arm_dec::MAY_BE_SAFE; |
| 21 | 24 |
| 22 namespace nacl_arm_test { | 25 namespace nacl_arm_test { |
| 23 | 26 |
| 24 DecoderTester::DecoderTester() | 27 DecoderTester::DecoderTester() |
| 25 {} | 28 {} |
| 26 | 29 |
| 27 void DecoderTester::ApplySanityChecks(Instruction inst, | 30 void DecoderTester::ApplySanityChecks(Instruction inst, |
| 28 const ClassDecoder& decoder) { | 31 const NamedClassDecoder& decoder) { |
| 29 UNREFERENCED_PARAMETER(inst); | 32 UNREFERENCED_PARAMETER(inst); |
| 30 EXPECT_EQ(&decoder, &ExpectedDecoder()) | 33 EXPECT_EQ(&decoder, &ExpectedDecoder()) |
| 31 << "Expected " << ExpectedDecoder().name() << " but found " | 34 << "Expected " << ExpectedDecoder().name() << " but found " |
| 32 << decoder.name() << " for " << InstContents(); | 35 << decoder.name() << " for " << InstContents(); |
| 33 } | 36 } |
| 34 | 37 |
| 35 void DecoderTester::TestAtIndex(int index) { | 38 void DecoderTester::TestAtIndex(int index) { |
| 36 while (true) { | 39 while (true) { |
| 37 // First see if we have completed generating test. | 40 // First see if we have completed generating test. |
| 38 if (index < 0) { | 41 if (index < 0) { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 } | 124 } |
| 122 } | 125 } |
| 123 | 126 |
| 124 void DecoderTester::TestAtIndexExpandFill4(int index, int length, bool value) { | 127 void DecoderTester::TestAtIndexExpandFill4(int index, int length, bool value) { |
| 125 if (length == 0) TestAtIndex(index); | 128 if (length == 0) TestAtIndex(index); |
| 126 | 129 |
| 127 int stride = (length <= 4) ? 4 : length; | 130 int stride = (length <= 4) ? 4 : length; |
| 128 TestAtIndexExpandFillAll(index, stride, length, value); | 131 TestAtIndexExpandFillAll(index, stride, length, value); |
| 129 } | 132 } |
| 130 | 133 |
| 131 Arm32DecoderTester::Arm32DecoderTester(const ClassDecoder& expected_decoder) | 134 Arm32DecoderTester::Arm32DecoderTester( |
| 135 const NamedClassDecoder& expected_decoder) |
| 132 : DecoderTester(), | 136 : DecoderTester(), |
| 133 expected_decoder_(expected_decoder), | 137 expected_decoder_(expected_decoder), |
| 134 pattern_(""), | 138 pattern_(""), |
| 135 state_(), | 139 state_(), |
| 136 inst_((uint32_t) 0xFFFFFFFF) { | 140 inst_((uint32_t) 0xFFFFFFFF) { |
| 137 } | 141 } |
| 138 | 142 |
| 139 Arm32DecoderTester:: ~Arm32DecoderTester() { | 143 Arm32DecoderTester:: ~Arm32DecoderTester() { |
| 140 } | 144 } |
| 141 | 145 |
| 142 void Arm32DecoderTester::Test(const char* pattern) { | 146 void Arm32DecoderTester::Test(const char* pattern) { |
| 143 pattern_ = pattern; | 147 pattern_ = pattern; |
| 144 ASSERT_EQ(static_cast<int>(kArm32InstSize), | 148 ASSERT_EQ(static_cast<int>(kArm32InstSize), |
| 145 static_cast<int>(strlen(pattern_))) | 149 static_cast<int>(strlen(pattern_))) |
| 146 << "Arm32 pattern length incorrect: " << pattern_; | 150 << "Arm32 pattern length incorrect: " << pattern_; |
| 147 TestAtIndex(kArm32InstSize-1); | 151 TestAtIndex(kArm32InstSize-1); |
| 148 } | 152 } |
| 149 | 153 |
| 150 const ClassDecoder& Arm32DecoderTester::ExpectedDecoder() const { | 154 const NamedClassDecoder& Arm32DecoderTester::ExpectedDecoder() const { |
| 151 return expected_decoder_; | 155 return expected_decoder_; |
| 152 } | 156 } |
| 153 | 157 |
| 154 static inline char BoolToChar(bool value) { | 158 static inline char BoolToChar(bool value) { |
| 155 return '0' + (uint8_t) value; | 159 return '0' + (uint8_t) value; |
| 156 } | 160 } |
| 157 | 161 |
| 158 const char* Arm32DecoderTester::InstContents() const { | 162 const char* Arm32DecoderTester::InstContents() const { |
| 159 static char buffer[kArm32InstSize + 1]; | 163 static char buffer[kArm32InstSize + 1]; |
| 160 for (int i = 1; i <= kArm32InstSize; ++i) { | 164 for (int i = 1; i <= kArm32InstSize; ++i) { |
| 161 buffer[kArm32InstSize - i] = BoolToChar(inst_.bit(i - 1)); | 165 buffer[kArm32InstSize - i] = BoolToChar(inst_.bit(i - 1)); |
| 162 } | 166 } |
| 163 buffer[kArm32InstSize] = '\0'; | 167 buffer[kArm32InstSize] = '\0'; |
| 164 return buffer; | 168 return buffer; |
| 165 } | 169 } |
| 166 | 170 |
| 167 char Arm32DecoderTester::Pattern(int index) const { | 171 char Arm32DecoderTester::Pattern(int index) const { |
| 168 return pattern_[kArm32InstSize - (index + 1)]; | 172 return pattern_[kArm32InstSize - (index + 1)]; |
| 169 } | 173 } |
| 170 | 174 |
| 171 void Arm32DecoderTester::ProcessMatch() { | 175 void Arm32DecoderTester::ProcessMatch() { |
| 172 // Completed pattern, decode and test resulting state. | 176 // Completed pattern, decode and test resulting state. |
| 173 const ClassDecoder& decoder = state_.decode(inst_); | 177 const NamedClassDecoder& decoder = state_.decode_named(inst_); |
| 174 if (MAY_BE_SAFE == decoder.safety(inst_)) ApplySanityChecks(inst_, decoder); | 178 if (MAY_BE_SAFE == decoder.safety(inst_)) ApplySanityChecks(inst_, decoder); |
| 175 return; | 179 return; |
| 176 } | 180 } |
| 177 | 181 |
| 178 void Arm32DecoderTester::SetBit(int index, bool value) { | 182 void Arm32DecoderTester::SetBit(int index, bool value) { |
| 179 ASSERT_LT(index, kArm32InstSize) | 183 ASSERT_LT(index, kArm32InstSize) |
| 180 << "Arm32DecoderTester::SetBit(" << index << ", " << value << ")"; | 184 << "Arm32DecoderTester::SetBit(" << index << ", " << value << ")"; |
| 181 ASSERT_GE(index , 0) | 185 ASSERT_GE(index , 0) |
| 182 << "Arm32DecoderTester::SetBit(" << index << ", " << value << ")"; | 186 << "Arm32DecoderTester::SetBit(" << index << ", " << value << ")"; |
| 183 inst_.set_bit(index, value); | 187 inst_.set_bit(index, value); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 205 pattern_ = pattern; | 209 pattern_ = pattern; |
| 206 ASSERT_LE(static_cast<int>(kThumbWordSize), | 210 ASSERT_LE(static_cast<int>(kThumbWordSize), |
| 207 static_cast<int>(strlen(pattern))) << | 211 static_cast<int>(strlen(pattern))) << |
| 208 "Thumb word 1 pattern length incorrect: " << pattern; | 212 "Thumb word 1 pattern length incorrect: " << pattern; |
| 209 } | 213 } |
| 210 | 214 |
| 211 void ThumbWord1DecoderTester::Test() { | 215 void ThumbWord1DecoderTester::Test() { |
| 212 TestAtIndex(kThumbWordSize-1); | 216 TestAtIndex(kThumbWordSize-1); |
| 213 } | 217 } |
| 214 | 218 |
| 215 const ClassDecoder& ThumbWord1DecoderTester::ExpectedDecoder() const { | 219 const NamedClassDecoder& ThumbWord1DecoderTester::ExpectedDecoder() const { |
| 216 return thumb_tester_->ExpectedDecoder(); | 220 return thumb_tester_->ExpectedDecoder(); |
| 217 } | 221 } |
| 218 | 222 |
| 219 char ThumbWord1DecoderTester::Pattern(int index) const { | 223 char ThumbWord1DecoderTester::Pattern(int index) const { |
| 220 return pattern_[kThumbWordSize - (index + 1)]; | 224 return pattern_[kThumbWordSize - (index + 1)]; |
| 221 } | 225 } |
| 222 | 226 |
| 223 const char* ThumbWord1DecoderTester::InstContents() const { | 227 const char* ThumbWord1DecoderTester::InstContents() const { |
| 224 return thumb_tester_->InstContents(); | 228 return thumb_tester_->InstContents(); |
| 225 } | 229 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 pattern_ = pattern; | 263 pattern_ = pattern; |
| 260 ASSERT_LE(static_cast<int>(kThumbWordSize), | 264 ASSERT_LE(static_cast<int>(kThumbWordSize), |
| 261 static_cast<int>(strlen(pattern))) << | 265 static_cast<int>(strlen(pattern))) << |
| 262 "Thumb word 2 pattern length incorrect: " << pattern; | 266 "Thumb word 2 pattern length incorrect: " << pattern; |
| 263 } | 267 } |
| 264 | 268 |
| 265 void ThumbWord2DecoderTester::Test() { | 269 void ThumbWord2DecoderTester::Test() { |
| 266 TestAtIndex(kThumbWordSize); | 270 TestAtIndex(kThumbWordSize); |
| 267 } | 271 } |
| 268 | 272 |
| 269 const ClassDecoder& ThumbWord2DecoderTester::ExpectedDecoder() const { | 273 const NamedClassDecoder& ThumbWord2DecoderTester::ExpectedDecoder() const { |
| 270 return thumb_tester_->ExpectedDecoder(); | 274 return thumb_tester_->ExpectedDecoder(); |
| 271 } | 275 } |
| 272 | 276 |
| 273 const char* ThumbWord2DecoderTester::InstContents() const { | 277 const char* ThumbWord2DecoderTester::InstContents() const { |
| 274 return thumb_tester_->InstContents(); | 278 return thumb_tester_->InstContents(); |
| 275 } | 279 } |
| 276 | 280 |
| 277 char ThumbWord2DecoderTester::Pattern(int index) const { | 281 char ThumbWord2DecoderTester::Pattern(int index) const { |
| 278 return pattern_[kThumbWordSize - (index + 1)]; | 282 return pattern_[kThumbWordSize - (index + 1)]; |
| 279 } | 283 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 297 ASSERT_LE(index + length, kThumbWordSize) | 301 ASSERT_LE(index + length, kThumbWordSize) |
| 298 << "ThumbWord2DecoderTester::SetBitRange(" << index << ", " << length | 302 << "ThumbWord2DecoderTester::SetBitRange(" << index << ", " << length |
| 299 << ", " << value << ")"; | 303 << ", " << value << ")"; |
| 300 ASSERT_GE(index, 0) | 304 ASSERT_GE(index, 0) |
| 301 << "ThumbWord1DecoderTester::SetBitRange(" << index << ", " << length | 305 << "ThumbWord1DecoderTester::SetBitRange(" << index << ", " << length |
| 302 << ", " << value << ")"; | 306 << ", " << value << ")"; |
| 303 thumb_tester_->inst_.word1_set_bits(index + (length - 1), index, | 307 thumb_tester_->inst_.word1_set_bits(index + (length - 1), index, |
| 304 (uint16_t) value); | 308 (uint16_t) value); |
| 305 } | 309 } |
| 306 | 310 |
| 307 ThumbDecoderTester::ThumbDecoderTester(const ClassDecoder& expected_decoder) | 311 ThumbDecoderTester::ThumbDecoderTester( |
| 312 const NamedClassDecoder& expected_decoder) |
| 308 : expected_decoder_(expected_decoder), | 313 : expected_decoder_(expected_decoder), |
| 309 pattern_(""), | 314 pattern_(""), |
| 310 state_(), | 315 state_(), |
| 311 inst_((uint16_t) 0, (uint16_t) 0), | 316 inst_((uint16_t) 0, (uint16_t) 0), |
| 312 word1_tester_(this), | 317 word1_tester_(this), |
| 313 word2_tester_(this) | 318 word2_tester_(this) |
| 314 {} | 319 {} |
| 315 | 320 |
| 316 ThumbDecoderTester::~ThumbDecoderTester() { | 321 ThumbDecoderTester::~ThumbDecoderTester() { |
| 317 } | 322 } |
| 318 | 323 |
| 319 void ThumbDecoderTester::Test(const char* pattern) { | 324 void ThumbDecoderTester::Test(const char* pattern) { |
| 320 int len = static_cast<int>(strlen(pattern_)); | 325 int len = static_cast<int>(strlen(pattern_)); |
| 321 pattern_ = pattern; | 326 pattern_ = pattern; |
| 322 if (kThumbWordSize == len) { | 327 if (kThumbWordSize == len) { |
| 323 word1_tester_.SetPattern(pattern_); | 328 word1_tester_.SetPattern(pattern_); |
| 324 word2_tester_.SetPattern("XXXXXXXXXXXXXXXX"); | 329 word2_tester_.SetPattern("XXXXXXXXXXXXXXXX"); |
| 325 } else { | 330 } else { |
| 326 ASSERT_EQ(static_cast<int>((2*kThumbWordSize) + 1), | 331 ASSERT_EQ(static_cast<int>((2*kThumbWordSize) + 1), |
| 327 static_cast<int>(strlen(pattern_))) | 332 static_cast<int>(strlen(pattern_))) |
| 328 << "Thumb attern length incorrect: " << pattern_; | 333 << "Thumb attern length incorrect: " << pattern_; |
| 329 word1_tester_.SetPattern(pattern_); | 334 word1_tester_.SetPattern(pattern_); |
| 330 word2_tester_.SetPattern(pattern + kThumbWordSize + 1); | 335 word2_tester_.SetPattern(pattern + kThumbWordSize + 1); |
| 331 } | 336 } |
| 332 word1_tester_.Test(); | 337 word1_tester_.Test(); |
| 333 } | 338 } |
| 334 | 339 |
| 335 const ClassDecoder& ThumbDecoderTester::ExpectedDecoder() const { | 340 const NamedClassDecoder& ThumbDecoderTester::ExpectedDecoder() const { |
| 336 return expected_decoder_; | 341 return expected_decoder_; |
| 337 } | 342 } |
| 338 | 343 |
| 339 const char* ThumbDecoderTester::InstContents() const { | 344 const char* ThumbDecoderTester::InstContents() const { |
| 340 static char buffer[2 * kThumbWordSize + 2]; | 345 static char buffer[2 * kThumbWordSize + 2]; |
| 341 for (int i = 1; i <= kThumbWordSize; ++i) { | 346 for (int i = 1; i <= kThumbWordSize; ++i) { |
| 342 buffer[kThumbWordSize - i] = BoolToChar(inst_.word1_bit(i - 1)); | 347 buffer[kThumbWordSize - i] = BoolToChar(inst_.word1_bit(i - 1)); |
| 343 } | 348 } |
| 344 buffer[kThumbWordSize] = '|'; | 349 buffer[kThumbWordSize] = '|'; |
| 345 for (int i = 0; i < kThumbWordSize; ++i) { | 350 for (int i = 0; i < kThumbWordSize; ++i) { |
| 346 buffer[2 * kThumbWordSize - i] = BoolToChar(inst_.word2_bit(i)); | 351 buffer[2 * kThumbWordSize - i] = BoolToChar(inst_.word2_bit(i)); |
| 347 } | 352 } |
| 348 buffer[2 * kThumbWordSize + 1] = '0'; | 353 buffer[2 * kThumbWordSize + 1] = '0'; |
| 349 return buffer; | 354 return buffer; |
| 350 } | 355 } |
| 351 | 356 |
| 352 char ThumbDecoderTester::Pattern(int index) const { | 357 char ThumbDecoderTester::Pattern(int index) const { |
| 353 // This should never be called. The decoders word1_tester_ | 358 // This should never be called. The decoders word1_tester_ |
| 354 // and word2_tester_ should be doing all the accesses to | 359 // and word2_tester_ should be doing all the accesses to |
| 355 // the pattern. | 360 // the pattern. |
| 356 UNREFERENCED_PARAMETER(index); | 361 UNREFERENCED_PARAMETER(index); |
| 357 return '0'; | 362 return '0'; |
| 358 } | 363 } |
| 359 | 364 |
| 360 void ThumbDecoderTester::ProcessMatch() { | 365 void ThumbDecoderTester::ProcessMatch() { |
| 361 // Completed pattern, decode and test resulting state. | 366 // Completed pattern, decode and test resulting state. |
| 362 const ClassDecoder& decoder = state_.decode(inst_); | 367 const NamedClassDecoder& decoder = state_.decode_named(inst_); |
| 363 if (MAY_BE_SAFE == decoder.safety(inst_)) ApplySanityChecks(inst_, decoder); | 368 if (MAY_BE_SAFE == decoder.safety(inst_)) ApplySanityChecks(inst_, decoder); |
| 364 return; | 369 return; |
| 365 } | 370 } |
| 366 | 371 |
| 367 void ThumbDecoderTester::SetBit(int index, bool value) { | 372 void ThumbDecoderTester::SetBit(int index, bool value) { |
| 368 // This should never be called. The decoders word1_tester_ | 373 // This should never be called. The decoders word1_tester_ |
| 369 // and word2_tester_ should be doing all of the bit setting. | 374 // and word2_tester_ should be doing all of the bit setting. |
| 370 GTEST_FAIL() << "ThumbDecoderTester::SetBit(" << index << | 375 GTEST_FAIL() << "ThumbDecoderTester::SetBit(" << index << |
| 371 ", " << value << ")"; | 376 ", " << value << ")"; |
| 372 } | 377 } |
| 373 | 378 |
| 374 void ThumbDecoderTester::SetBitRange(int index, int length, uint32_t value) { | 379 void ThumbDecoderTester::SetBitRange(int index, int length, uint32_t value) { |
| 375 // This should never be called. The decoders word1_tester_ | 380 // This should never be called. The decoders word1_tester_ |
| 376 // and word2_tester_ should be doing all of the bit setting. | 381 // and word2_tester_ should be doing all of the bit setting. |
| 377 GTEST_FAIL() << "ThumbDecoderTester::SetBitRange(" << index << | 382 GTEST_FAIL() << "ThumbDecoderTester::SetBitRange(" << index << |
| 378 ", " << length << ", " << value << ")"; | 383 ", " << length << ", " << value << ")"; |
| 379 } | 384 } |
| 380 | 385 |
| 381 } // namespace | 386 } // namespace |
| OLD | NEW |