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); |