Chromium Code Reviews| Index: src/trusted/validator/driver/ncval.cc |
| diff --git a/src/trusted/validator/driver/ncval.cc b/src/trusted/validator/driver/ncval.cc |
| index c9736e6e33c8ad34911e75784135472c689325e0..906aef6d3b216a380d2b50cd48f4ffc0c7bd0f98 100644 |
| --- a/src/trusted/validator/driver/ncval.cc |
| +++ b/src/trusted/validator/driver/ncval.cc |
| @@ -55,14 +55,17 @@ struct UserData { |
| vector<Error> *errors; |
| vector<Jump> *jumps; |
| set<uint32_t> *bad_jump_targets; |
| + bool pnacl_mode; |
| UserData(Segment segment, |
| vector<Error> *errors, |
| vector<Jump> *jumps, |
| - set<uint32_t> *bad_jump_targets) |
| + set<uint32_t> *bad_jump_targets, |
| + bool pnacl_mode) |
| : segment(segment), |
| errors(errors), |
| jumps(jumps), |
| - bad_jump_targets(bad_jump_targets) { |
| + bad_jump_targets(bad_jump_targets), |
| + pnacl_mode(pnacl_mode) { |
| } |
| }; |
| @@ -94,6 +97,11 @@ Bool ProcessInstruction( |
| } |
| } |
| + // For non-pnacl-mode, 'unsupported instruction' should pass validation, |
| + // and we simply clear the flag. |
| + if (!user_data.pnacl_mode) |
| + validation_info &= ~UNSUPPORTED_INSTRUCTION; |
| + |
| Bool result = (validation_info & (VALIDATION_ERRORS_MASK | BAD_JUMP_TARGET)) |
| ? FALSE |
| : TRUE; |
| @@ -120,6 +128,11 @@ Bool ProcessInstruction( |
| errors.push_back(Error(offset, "required CPU feature not found")); |
| } |
| + if (validation_info & UNSUPPORTED_INSTRUCTION) { |
| + validation_info &= ~UNSUPPORTED_INSTRUCTION; |
| + errors.push_back(Error(offset, "unsupported instruction")); |
| + } |
| + |
| if (validation_info & FORBIDDEN_BASE_REGISTER) { |
| validation_info &= ~FORBIDDEN_BASE_REGISTER; |
| errors.push_back(Error(offset, "improper memory address - bad base")); |
| @@ -192,9 +205,18 @@ Bool ProcessError( |
| uint32_t validation_info, void *user_data_ptr) { |
| UNREFERENCED_PARAMETER(begin); |
| UNREFERENCED_PARAMETER(end); |
| - UNREFERENCED_PARAMETER(validation_info); |
| - UNREFERENCED_PARAMETER(user_data_ptr); |
| - return FALSE; |
| + UserData &user_data = *reinterpret_cast<UserData *>(user_data_ptr); |
| + |
| + // We do the same thing as in ProcessInstruction(): for non-pnacl-mode, |
| + // 'unsupported instruction' should pass validation, and we simply clear |
| + // the flag. |
| + if (!user_data.pnacl_mode) |
| + validation_info &= ~UNSUPPORTED_INSTRUCTION; |
| + |
| + Bool result = (validation_info & (VALIDATION_ERRORS_MASK | BAD_JUMP_TARGET)) |
|
gdeepti
2015/07/28 03:08:58
Why BAD_JUMP_TARGET here?
ruiq
2015/07/28 04:58:55
This is to be consistent with the handling in Proc
|
| + ? FALSE |
| + : TRUE; |
| + return result; |
| } |
| @@ -209,7 +231,8 @@ typedef Bool ValidateChunkFunc( |
| bool ValidateX86( |
| const Segment &segment, |
| ValidateChunkFunc validate_chunk, |
| - vector<Error> *errors) { |
| + vector<Error> *errors, |
| + bool pnacl_mode) { |
| errors->clear(); |
| @@ -233,7 +256,7 @@ bool ValidateX86( |
| vector<Jump> jumps; |
| set<uint32_t> bad_jump_targets; |
| - UserData user_data(segment, errors, &jumps, &bad_jump_targets); |
| + UserData user_data(segment, errors, &jumps, &bad_jump_targets, pnacl_mode); |
| // TODO(shcherbina): customize from command line |
| @@ -258,7 +281,7 @@ bool ValidateX86( |
| CHECK(result == validate_chunk( |
| segment.data, segment.size, |
| 0, &kFullCPUIDFeatures, |
| - ProcessError, NULL)); |
| + ProcessError, &user_data)); |
| return static_cast<bool>(result); |
| } |
| @@ -324,9 +347,10 @@ void Usage() { |
| struct Options { |
| - Options() : input_file(NULL), verbose(false) {} |
| + Options() : input_file(NULL), verbose(false), pnacl_mode(false) {} |
| const char *input_file; |
| bool verbose; |
| + bool pnacl_mode; |
|
Petr Hosek
2015/07/28 19:05:46
Rename to `flags`.
ruiq
2015/07/28 21:34:55
Done.
|
| }; |
| @@ -337,6 +361,9 @@ void ParseOptions(int argc, char **argv, Options *options) { |
| case 'v': |
| options->verbose = true; |
| break; |
| + case 'p': |
| + options->pnacl_mode = true; |
|
Petr Hosek
2015/07/28 19:05:46
The 'p' option seems to be missing from the optstr
ruiq
2015/07/28 21:34:55
Done.
|
| + break; |
| default: |
| fprintf(stderr, "ERROR: unknown option: [%c]\n\n", opt); |
| Usage(); |
| @@ -368,10 +395,12 @@ int main(int argc, char **argv) { |
| bool result = false; |
| switch (architecture) { |
| case elf_load::X86_32: |
| - result = ValidateX86(segment, ValidateChunkIA32, &errors); |
| + result = ValidateX86(segment, ValidateChunkIA32, &errors, |
| + options.pnacl_mode); |
| break; |
| case elf_load::X86_64: |
| - result = ValidateX86(segment, ValidateChunkAMD64, &errors); |
| + result = ValidateX86(segment, ValidateChunkAMD64, &errors, |
| + options.pnacl_mode); |
| break; |
| case elf_load::ARM: |
| result = ValidateArm(segment, &errors); |