| 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 * ncval.c - command line validator for NaCl. | 8 * ncval.c - command line validator for NaCl. |
| 9 * Mostly for testing. | 9 * Mostly for testing. |
| 10 */ | 10 */ |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 * Note: Values, other than 1, is only used for profiling. | 84 * Note: Values, other than 1, is only used for profiling. |
| 85 */ | 85 */ |
| 86 static int NACL_FLAGS_validate_attempts = 1; | 86 static int NACL_FLAGS_validate_attempts = 1; |
| 87 | 87 |
| 88 /* Define the set of CPU features to use while validating. */ | 88 /* Define the set of CPU features to use while validating. */ |
| 89 static NaClCPUFeaturesX86 ncval_cpu_features; | 89 static NaClCPUFeaturesX86 ncval_cpu_features; |
| 90 | 90 |
| 91 /* Define whether timing should be applied when running the validator. */ | 91 /* Define whether timing should be applied when running the validator. */ |
| 92 static Bool NACL_FLAGS_print_timing = FALSE; | 92 static Bool NACL_FLAGS_print_timing = FALSE; |
| 93 | 93 |
| 94 /* Define the block alignment size to use. */ | |
| 95 static int NACL_FLAGS_block_alignment = 32; | |
| 96 | |
| 97 /* Define what level of errors will be printed. | 94 /* Define what level of errors will be printed. |
| 98 * Note: If multiple flags are true, the one with | 95 * Note: If multiple flags are true, the one with |
| 99 * the highest severity will be selected. | 96 * the highest severity will be selected. |
| 100 */ | 97 */ |
| 101 static Bool NACL_FLAGS_warnings = FALSE; | 98 static Bool NACL_FLAGS_warnings = FALSE; |
| 102 static Bool NACL_FLAGS_errors = FALSE; | 99 static Bool NACL_FLAGS_errors = FALSE; |
| 103 static Bool NACL_FLAGS_fatal = FALSE; | 100 static Bool NACL_FLAGS_fatal = FALSE; |
| 104 | 101 |
| 105 /* Define if special stubout tests should be run. Such | 102 /* Define if special stubout tests should be run. Such |
| 106 * tests apply stubout, and then print out the modified | 103 * tests apply stubout, and then print out the modified |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 329 NCValidateSegment(ncf->data + (phdr[ii].p_vaddr - ncf->vbase), | 326 NCValidateSegment(ncf->data + (phdr[ii].p_vaddr - ncf->vbase), |
| 330 phdr[ii].p_vaddr, phdr[ii].p_memsz, vstate); | 327 phdr[ii].p_vaddr, phdr[ii].p_memsz, vstate); |
| 331 } | 328 } |
| 332 return -badsections; | 329 return -badsections; |
| 333 } | 330 } |
| 334 | 331 |
| 335 /* Initialize segment validator, using detailed (summary) error | 332 /* Initialize segment validator, using detailed (summary) error |
| 336 * messages if selected. | 333 * messages if selected. |
| 337 */ | 334 */ |
| 338 struct NCValidatorState* NCValInit(const NaClPcAddress vbase, | 335 struct NCValidatorState* NCValInit(const NaClPcAddress vbase, |
| 339 const NaClMemorySize codesize, | 336 const NaClMemorySize codesize) { |
| 340 const uint8_t alignment) { | |
| 341 return NACL_FLAGS_detailed_errors | 337 return NACL_FLAGS_detailed_errors |
| 342 ? NCValidateInitDetailed(vbase, codesize, alignment, &ncval_cpu_features) | 338 ? NCValidateInitDetailed(vbase, codesize, &ncval_cpu_features) |
| 343 : NCValidateInit(vbase, codesize, alignment, FALSE, &ncval_cpu_features); | 339 : NCValidateInit(vbase, codesize, FALSE, &ncval_cpu_features); |
| 344 } | 340 } |
| 345 | 341 |
| 346 | 342 |
| 347 static Bool AnalyzeSegmentCodeSegments(ncfile *ncf, const char *fname) { | 343 static Bool AnalyzeSegmentCodeSegments(ncfile *ncf, const char *fname) { |
| 348 NaClPcAddress vbase, vlimit; | 344 NaClPcAddress vbase, vlimit; |
| 349 struct NCValidatorState *vstate; | 345 struct NCValidatorState *vstate; |
| 350 Bool result; | 346 Bool result; |
| 351 | 347 |
| 352 GetVBaseAndLimit(ncf, &vbase, &vlimit); | 348 GetVBaseAndLimit(ncf, &vbase, &vlimit); |
| 353 vstate = NCValInit(vbase, vlimit - vbase, ncf->ncalign); | 349 vstate = NCValInit(vbase, vlimit - vbase); |
| 354 if (vstate == NULL) return FALSE; | 350 if (vstate == NULL) return FALSE; |
| 355 NCValidateSetErrorReporter(vstate, &kNCVerboseErrorReporter); | 351 NCValidateSetErrorReporter(vstate, &kNCVerboseErrorReporter); |
| 356 if (AnalyzeSegmentSections(ncf, vstate) < 0) { | 352 if (AnalyzeSegmentSections(ncf, vstate) < 0) { |
| 357 NaClLog(LOG_INFO, "%s: text validate failed\n", fname); | 353 NaClLog(LOG_INFO, "%s: text validate failed\n", fname); |
| 358 } | 354 } |
| 359 result = (0 == NCValidateFinish(vstate)) ? TRUE : FALSE; | 355 result = (0 == NCValidateFinish(vstate)) ? TRUE : FALSE; |
| 360 NaClReportSafety(result, fname); | 356 NaClReportSafety(result, fname); |
| 361 if (NACL_FLAGS_stats_print) NCStatsPrint(vstate); | 357 if (NACL_FLAGS_stats_print) NCStatsPrint(vstate); |
| 362 NCValidateFreeState(&vstate); | 358 NCValidateFreeState(&vstate); |
| 363 NaClLog(LOG_INFO, "Validated %s\n", fname); | 359 NaClLog(LOG_INFO, "Validated %s\n", fname); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 375 */ | 371 */ |
| 376 static NaClOpKind nacl_base_register = | 372 static NaClOpKind nacl_base_register = |
| 377 (64 == NACL_TARGET_SUBARCH ? RegR15 : RegUnknown); | 373 (64 == NACL_TARGET_SUBARCH ? RegR15 : RegUnknown); |
| 378 | 374 |
| 379 /* Create validator state using detailed (summary) error messages | 375 /* Create validator state using detailed (summary) error messages |
| 380 * if selected. | 376 * if selected. |
| 381 */ | 377 */ |
| 382 struct NaClValidatorState* NaClValStateCreate( | 378 struct NaClValidatorState* NaClValStateCreate( |
| 383 const NaClPcAddress vbase, | 379 const NaClPcAddress vbase, |
| 384 const NaClMemorySize sz, | 380 const NaClMemorySize sz, |
| 385 const uint8_t alignment, | |
| 386 const NaClOpKind base_register) { | 381 const NaClOpKind base_register) { |
| 387 return | 382 return |
| 388 NACL_FLAGS_detailed_errors | 383 NACL_FLAGS_detailed_errors |
| 389 ? NaClValidatorStateCreateDetailed(vbase, sz, alignment, base_register, | 384 ? NaClValidatorStateCreateDetailed(vbase, sz, base_register, |
| 390 &ncval_cpu_features) | 385 &ncval_cpu_features) |
| 391 : NaClValidatorStateCreate(vbase, sz, alignment, base_register, | 386 : NaClValidatorStateCreate(vbase, sz, base_register, |
| 392 FALSE, &ncval_cpu_features); | 387 FALSE, &ncval_cpu_features); |
| 393 } | 388 } |
| 394 | 389 |
| 395 /* Returns the decoder tables to use. */ | 390 /* Returns the decoder tables to use. */ |
| 396 static const NaClDecodeTables* NaClGetDecoderTables() { | 391 static const NaClDecodeTables* NaClGetDecoderTables() { |
| 397 return NACL_FLAGS_validator_decoder | 392 return NACL_FLAGS_validator_decoder |
| 398 ? kNaClValDecoderTables | 393 ? kNaClValDecoderTables |
| 399 : kNaClDecoderTables; | 394 : kNaClDecoderTables; |
| 400 } | 395 } |
| 401 | 396 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 /* Analyze each code segment in the given elf file, stored in the | 451 /* Analyze each code segment in the given elf file, stored in the |
| 457 * file with the given path fname. | 452 * file with the given path fname. |
| 458 */ | 453 */ |
| 459 static Bool AnalyzeSfiCodeSegments(ncfile *ncf, const char *fname) { | 454 static Bool AnalyzeSfiCodeSegments(ncfile *ncf, const char *fname) { |
| 460 /* TODO(karl) convert these to be PcAddress and MemorySize */ | 455 /* TODO(karl) convert these to be PcAddress and MemorySize */ |
| 461 NaClPcAddress vbase, vlimit; | 456 NaClPcAddress vbase, vlimit; |
| 462 NaClValidatorState *vstate; | 457 NaClValidatorState *vstate; |
| 463 Bool return_value = TRUE; | 458 Bool return_value = TRUE; |
| 464 | 459 |
| 465 GetVBaseAndLimit(ncf, &vbase, &vlimit); | 460 GetVBaseAndLimit(ncf, &vbase, &vlimit); |
| 466 vstate = NaClValStateCreate(vbase, vlimit - vbase, | 461 vstate = NaClValStateCreate(vbase, vlimit - vbase, nacl_base_register); |
| 467 ncf->ncalign, nacl_base_register); | |
| 468 if (vstate == NULL) { | 462 if (vstate == NULL) { |
| 469 NaClValidatorMessage(LOG_ERROR, vstate, "Unable to create validator state"); | 463 NaClValidatorMessage(LOG_ERROR, vstate, "Unable to create validator state"); |
| 470 return FALSE; | 464 return FALSE; |
| 471 } | 465 } |
| 472 NaClValidatorStateSetErrorReporter(vstate, &kNaClVerboseErrorReporter); | 466 NaClValidatorStateSetErrorReporter(vstate, &kNaClVerboseErrorReporter); |
| 473 if (NACL_FLAGS_analyze_segments) { | 467 if (NACL_FLAGS_analyze_segments) { |
| 474 AnalyzeSfiSegments(ncf, vstate); | 468 AnalyzeSfiSegments(ncf, vstate); |
| 475 } else { | 469 } else { |
| 476 AnalyzeSfiSections(ncf, vstate); | 470 AnalyzeSfiSections(ncf, vstate); |
| 477 } | 471 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 519 NaClPcAddress base; | 513 NaClPcAddress base; |
| 520 } NaClValidateBytes; | 514 } NaClValidateBytes; |
| 521 | 515 |
| 522 /* Apply the validator to the sequence of bytes in the given data. */ | 516 /* Apply the validator to the sequence of bytes in the given data. */ |
| 523 static Bool NaClValidateAnalyzeBytes(NaClValidateBytes* data) { | 517 static Bool NaClValidateAnalyzeBytes(NaClValidateBytes* data) { |
| 524 Bool return_value = FALSE; | 518 Bool return_value = FALSE; |
| 525 #if NACL_TARGET_SUBARCH == 64 | 519 #if NACL_TARGET_SUBARCH == 64 |
| 526 NaClValidatorState* state; | 520 NaClValidatorState* state; |
| 527 state = NaClValStateCreate(data->base, | 521 state = NaClValStateCreate(data->base, |
| 528 data->num_bytes, | 522 data->num_bytes, |
| 529 (uint8_t) NACL_FLAGS_block_alignment, | |
| 530 nacl_base_register); | 523 nacl_base_register); |
| 531 if (NULL == state) { | 524 if (NULL == state) { |
| 532 NaClValidatorMessage(LOG_ERROR, NULL, "Unable to create validator state"); | 525 NaClValidatorMessage(LOG_ERROR, NULL, "Unable to create validator state"); |
| 533 return FALSE; | 526 return FALSE; |
| 534 } | 527 } |
| 535 if (NACL_FLAGS_stubout_memory) { | 528 if (NACL_FLAGS_stubout_memory) { |
| 536 NaClValidatorStateSetDoStubOut(state, TRUE); | 529 NaClValidatorStateSetDoStubOut(state, TRUE); |
| 537 } | 530 } |
| 538 NaClValidatorStateSetErrorReporter(state, &kNaClVerboseErrorReporter); | 531 NaClValidatorStateSetErrorReporter(state, &kNaClVerboseErrorReporter); |
| 539 NaClValidateSegmentUsingTables(data->bytes, data->base, data->num_bytes, | 532 NaClValidateSegmentUsingTables(data->bytes, data->base, data->num_bytes, |
| 540 state, NaClGetDecoderTables()); | 533 state, NaClGetDecoderTables()); |
| 541 return_value = NaClValidatesOk(state); | 534 return_value = NaClValidatesOk(state); |
| 542 if (state->did_stub_out) { | 535 if (state->did_stub_out) { |
| 543 /* Used for golden file testing. */ | 536 /* Used for golden file testing. */ |
| 544 printf("Some instructions were replaced with HLTs.\n"); | 537 printf("Some instructions were replaced with HLTs.\n"); |
| 545 } | 538 } |
| 546 NaClValidatorStateDestroy(state); | 539 NaClValidatorStateDestroy(state); |
| 547 NaClReportSafety(return_value, ""); | 540 NaClReportSafety(return_value, ""); |
| 548 #else | 541 #else |
| 549 struct NCValidatorState *vstate; | 542 struct NCValidatorState *vstate; |
| 550 vstate = NCValInit(data->base, data->num_bytes, | 543 vstate = NCValInit(data->base, data->num_bytes); |
| 551 (uint8_t) NACL_FLAGS_block_alignment); | |
| 552 if (vstate == NULL) { | 544 if (vstate == NULL) { |
| 553 printf("Unable to create validator state, quitting!\n"); | 545 printf("Unable to create validator state, quitting!\n"); |
| 554 } else { | 546 } else { |
| 555 if (NACL_FLAGS_stubout_memory) { | 547 if (NACL_FLAGS_stubout_memory) { |
| 556 NCValidateSetStubOutMode(vstate, 1); | 548 NCValidateSetStubOutMode(vstate, 1); |
| 557 } | 549 } |
| 558 NCValidateSetErrorReporter(vstate, &kNCVerboseErrorReporter); | 550 NCValidateSetErrorReporter(vstate, &kNCVerboseErrorReporter); |
| 559 NCValidateSegment(&data->bytes[0], data->base, data->num_bytes, vstate); | 551 NCValidateSegment(&data->bytes[0], data->base, data->num_bytes, vstate); |
| 560 return_value = (0 == NCValidateFinish(vstate)) ? TRUE : FALSE; | 552 return_value = (0 == NCValidateFinish(vstate)) ? TRUE : FALSE; |
| 561 if (vstate->stats.didstubout) { | 553 if (vstate->stats.didstubout) { |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 830 | 822 |
| 831 /* Checks if arg is one of the expected "int" flags, and if so, sets | 823 /* Checks if arg is one of the expected "int" flags, and if so, sets |
| 832 * the corresponding flag and returns true. | 824 * the corresponding flag and returns true. |
| 833 */ | 825 */ |
| 834 static Bool GrokAnIntFlag(const char *arg) { | 826 static Bool GrokAnIntFlag(const char *arg) { |
| 835 /* A set of boolean flags to be checked */ | 827 /* A set of boolean flags to be checked */ |
| 836 static struct { | 828 static struct { |
| 837 const char *flag_name; | 829 const char *flag_name; |
| 838 int *flag_ptr; | 830 int *flag_ptr; |
| 839 } flags[] = { | 831 } flags[] = { |
| 840 { "--alignment" , &NACL_FLAGS_block_alignment }, | |
| 841 { "--max_errors", &NACL_FLAGS_max_reported_errors}, | 832 { "--max_errors", &NACL_FLAGS_max_reported_errors}, |
| 842 { "--attempts" , &NACL_FLAGS_validate_attempts }, | 833 { "--attempts" , &NACL_FLAGS_validate_attempts }, |
| 843 }; | 834 }; |
| 844 int i; | 835 int i; |
| 845 for (i = 0; i < NACL_ARRAY_SIZE(flags); ++i) { | 836 for (i = 0; i < NACL_ARRAY_SIZE(flags); ++i) { |
| 846 if (GrokIntFlag(flags[i].flag_name, arg, flags[i].flag_ptr)) { | 837 if (GrokIntFlag(flags[i].flag_name, arg, flags[i].flag_ptr)) { |
| 847 return TRUE; | 838 return TRUE; |
| 848 } | 839 } |
| 849 } | 840 } |
| 850 return FALSE; | 841 return FALSE; |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 965 data.num_bytes, data.base); | 956 data.num_bytes, data.base); |
| 966 NaClMaybeDecodeDataSegment(&data.bytes[0], data.base, data.num_bytes); | 957 NaClMaybeDecodeDataSegment(&data.bytes[0], data.base, data.num_bytes); |
| 967 /* always succeed, so that the testing framework works. */ | 958 /* always succeed, so that the testing framework works. */ |
| 968 result = 0; | 959 result = 0; |
| 969 } | 960 } |
| 970 | 961 |
| 971 NaClLogModuleFini(); | 962 NaClLogModuleFini(); |
| 972 GioFileDtor(gout); | 963 GioFileDtor(gout); |
| 973 return result; | 964 return result; |
| 974 } | 965 } |
| OLD | NEW |