| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2011 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 * ncvalidate_iter.c | 8 * ncvalidate_iter.c |
| 9 * Validate x86 instructions for Native Client | 9 * Validate x86 instructions for Native Client |
| 10 * | 10 * |
| 11 */ | 11 */ |
| 12 | 12 |
| 13 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncvalidate_iter.
h" | 13 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncvalidate_iter.
h" |
| 14 | 14 |
| 15 #include <assert.h> | 15 #include <assert.h> |
| 16 #include <string.h> | 16 #include <string.h> |
| 17 | 17 |
| 18 #include "native_client/src/shared/platform/nacl_check.h" | 18 #include "native_client/src/shared/platform/nacl_check.h" |
| 19 #include "native_client/src/shared/platform/nacl_log.h" | 19 #include "native_client/src/shared/platform/nacl_log.h" |
| 20 #include "native_client/src/trusted/validator/x86/decoder/ncop_exps.h" | 20 #include "native_client/src/trusted/validator/x86/decoder/ncop_exps.h" |
| 21 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_state_internal
.h" | 21 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_state_internal
.h" |
| 22 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_iter.h" | |
| 23 #include "native_client/src/trusted/validator/x86/halt_trim.h" | 22 #include "native_client/src/trusted/validator/x86/halt_trim.h" |
| 24 #include "native_client/src/trusted/validator/x86/nc_segment.h" | 23 #include "native_client/src/trusted/validator/x86/nc_segment.h" |
| 25 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncvalidate_iter_
internal.h" | 24 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncvalidate_iter_
internal.h" |
| 26 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncvalidator_regi
stry.h" | 25 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncvalidator_regi
stry.h" |
| 27 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncval_decode_tab
les.h" | 26 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncval_decode_tab
les.h" |
| 28 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/nc_jumps.h" | 27 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/nc_jumps.h" |
| 29 #include "native_client/src/trusted/validator_x86/ncdis_decode_tables.h" | 28 #include "native_client/src/trusted/validator_x86/ncdis_decode_tables.h" |
| 30 | 29 |
| 31 /* To turn on debugging of instruction decoding, change value of | 30 /* To turn on debugging of instruction decoding, change value of |
| 32 * DEBUGGING to 1. | 31 * DEBUGGING to 1. |
| 33 */ | 32 */ |
| 34 #define DEBUGGING 0 | 33 #define DEBUGGING 0 |
| 35 | 34 |
| 36 #include "native_client/src/shared/utils/debugging.h" | 35 #include "native_client/src/shared/utils/debugging.h" |
| 37 | 36 |
| 37 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_iter_inl.c" |
| 38 |
| 38 /* When >= 0, only print that many errors before quiting. When | 39 /* When >= 0, only print that many errors before quiting. When |
| 39 * < 0, print all errors. | 40 * < 0, print all errors. |
| 40 */ | 41 */ |
| 41 int NACL_FLAGS_max_reported_errors = 100; | 42 int NACL_FLAGS_max_reported_errors = 100; |
| 42 | 43 |
| 43 Bool NACL_FLAGS_validator_trace_instructions = FALSE; | 44 Bool NACL_FLAGS_validator_trace_instructions = FALSE; |
| 44 | 45 |
| 45 Bool NACL_FLAGS_validator_trace_inst_internals = FALSE; | 46 Bool NACL_FLAGS_validator_trace_inst_internals = FALSE; |
| 46 | 47 |
| 47 Bool NACL_FLAGS_ncval_annotate = TRUE; | 48 Bool NACL_FLAGS_ncval_annotate = TRUE; |
| (...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 557 if (NaClValidatorStateInitializeValidators(state)) { | 558 if (NaClValidatorStateInitializeValidators(state)) { |
| 558 NCHaltTrimSegment(mbase, vbase, state->alignment, &size, &state->vlimit); | 559 NCHaltTrimSegment(mbase, vbase, state->alignment, &size, &state->vlimit); |
| 559 NaClSegmentInitialize(mbase, vbase, size, &segment); | 560 NaClSegmentInitialize(mbase, vbase, size, &segment); |
| 560 do { | 561 do { |
| 561 iter = NaClInstIterCreateWithLookback(state->decoder_tables, | 562 iter = NaClInstIterCreateWithLookback(state->decoder_tables, |
| 562 &segment, kLookbackSize); | 563 &segment, kLookbackSize); |
| 563 if (NULL == iter) { | 564 if (NULL == iter) { |
| 564 NaClValidatorMessage(LOG_ERROR, state, "Not enough memory\n"); | 565 NaClValidatorMessage(LOG_ERROR, state, "Not enough memory\n"); |
| 565 break; | 566 break; |
| 566 } | 567 } |
| 567 for (; NaClInstIterHasNext(iter); NaClInstIterAdvance(iter)) { | 568 for (; NaClInstIterHasNextInline(iter); NaClInstIterAdvanceInline(iter)) { |
| 568 state->cur_inst_state = NaClInstIterGetState(iter); | 569 state->cur_inst_state = NaClInstIterGetStateInline(iter); |
| 569 state->cur_inst = NaClInstStateInst(state->cur_inst_state); | 570 state->cur_inst = NaClInstStateInst(state->cur_inst_state); |
| 570 state->cur_inst_vector = NaClInstStateExpVector(state->cur_inst_state); | 571 state->cur_inst_vector = NaClInstStateExpVector(state->cur_inst_state); |
| 571 NaClApplyValidators(state, iter); | 572 NaClApplyValidators(state, iter); |
| 572 if (state->quit) break; | 573 if (state->quit) break; |
| 573 } | 574 } |
| 574 state->cur_inst_state = NULL; | 575 state->cur_inst_state = NULL; |
| 575 state->cur_inst = NULL; | 576 state->cur_inst = NULL; |
| 576 state->cur_inst_vector = NULL; | 577 state->cur_inst_vector = NULL; |
| 577 } while (0); | 578 } while (0); |
| 578 NaClApplyPostValidators(state, iter); | 579 NaClApplyPostValidators(state, iter); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 628 * Return value: TRUE if the instruction was changed, FALSE if it's identical. | 629 * Return value: TRUE if the instruction was changed, FALSE if it's identical. |
| 629 */ | 630 */ |
| 630 static Bool NaClValidateInstReplacement(NaClInstIter *iter_old, | 631 static Bool NaClValidateInstReplacement(NaClInstIter *iter_old, |
| 631 NaClInstIter *iter_new, | 632 NaClInstIter *iter_new, |
| 632 struct NaClValidatorState *state) { | 633 struct NaClValidatorState *state) { |
| 633 NaClInstState *istate_old, *istate_new; | 634 NaClInstState *istate_old, *istate_new; |
| 634 NaClExpVector *exp_old, *exp_new; | 635 NaClExpVector *exp_old, *exp_new; |
| 635 uint32_t i; | 636 uint32_t i; |
| 636 Bool inst_changed = FALSE; | 637 Bool inst_changed = FALSE; |
| 637 | 638 |
| 638 istate_old = NaClInstIterGetState(iter_old); | 639 istate_old = NaClInstIterGetStateInline(iter_old); |
| 639 istate_new = NaClInstIterGetState(iter_new); | 640 istate_new = NaClInstIterGetStateInline(iter_new); |
| 640 | 641 |
| 641 /* Location/length must match */ | 642 /* Location/length must match */ |
| 642 if (istate_new->vpc != istate_old->vpc || | 643 if (istate_new->vpc != istate_old->vpc || |
| 643 istate_new->bytes.length != istate_old->bytes.length) { | 644 istate_new->bytes.length != istate_old->bytes.length) { |
| 644 NaClValidatorTwoInstMessage(LOG_ERROR, state, istate_old, istate_new, | 645 NaClValidatorTwoInstMessage(LOG_ERROR, state, istate_old, istate_new, |
| 645 "Code modification: instructions length/addresses do not match"); | 646 "Code modification: instructions length/addresses do not match"); |
| 646 inst_changed = TRUE; | 647 inst_changed = TRUE; |
| 647 return inst_changed; | 648 return inst_changed; |
| 648 } | 649 } |
| 649 | 650 |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 770 NaClValidatorStateInitializeValidators(state); | 771 NaClValidatorStateInitializeValidators(state); |
| 771 NaClSegmentInitialize(mbase_old, vbase, size, &segment_old); | 772 NaClSegmentInitialize(mbase_old, vbase, size, &segment_old); |
| 772 NaClSegmentInitialize(mbase_new, vbase, size, &segment_new); | 773 NaClSegmentInitialize(mbase_new, vbase, size, &segment_new); |
| 773 do { | 774 do { |
| 774 iter_old = NaClInstIterCreateWithLookback(state->decoder_tables, | 775 iter_old = NaClInstIterCreateWithLookback(state->decoder_tables, |
| 775 &segment_old, kLookbackSize); | 776 &segment_old, kLookbackSize); |
| 776 if (NULL == iter_old) break; | 777 if (NULL == iter_old) break; |
| 777 iter_new = NaClInstIterCreateWithLookback(state->decoder_tables, | 778 iter_new = NaClInstIterCreateWithLookback(state->decoder_tables, |
| 778 &segment_new, kLookbackSize); | 779 &segment_new, kLookbackSize); |
| 779 if (NULL == iter_new) break; | 780 if (NULL == iter_new) break; |
| 780 while (NaClInstIterHasNext(iter_old) && | 781 while (NaClInstIterHasNextInline(iter_old) && |
| 781 NaClInstIterHasNext(iter_new)) { | 782 NaClInstIterHasNextInline(iter_new)) { |
| 782 Bool inst_changed; | 783 Bool inst_changed; |
| 783 state->cur_inst_state = NaClInstIterGetState(iter_new); | 784 state->cur_inst_state = NaClInstIterGetStateInline(iter_new); |
| 784 state->cur_inst = NaClInstStateInst(state->cur_inst_state); | 785 state->cur_inst = NaClInstStateInst(state->cur_inst_state); |
| 785 state->cur_inst_vector = NaClInstStateExpVector(state->cur_inst_state); | 786 state->cur_inst_vector = NaClInstStateExpVector(state->cur_inst_state); |
| 786 inst_changed = NaClValidateInstReplacement(iter_old, iter_new, state); | 787 inst_changed = NaClValidateInstReplacement(iter_old, iter_new, state); |
| 787 if (inst_changed) | 788 if (inst_changed) |
| 788 NaClApplyValidators(state, iter_new); | 789 NaClApplyValidators(state, iter_new); |
| 789 else | 790 else |
| 790 NaClRememberIpOnly(state, iter_new); | 791 NaClRememberIpOnly(state, iter_new); |
| 791 if (state->quit) break; | 792 if (state->quit) break; |
| 792 NaClInstIterAdvance(iter_old); | 793 NaClInstIterAdvanceInline(iter_old); |
| 793 NaClInstIterAdvance(iter_new); | 794 NaClInstIterAdvanceInline(iter_new); |
| 794 } | 795 } |
| 795 if (NaClInstIterHasNext(iter_old) || | 796 if (NaClInstIterHasNextInline(iter_old) || |
| 796 NaClInstIterHasNext(iter_new)) { | 797 NaClInstIterHasNextInline(iter_new)) { |
| 797 NaClValidatorMessage( | 798 NaClValidatorMessage( |
| 798 LOG_ERROR, state, | 799 LOG_ERROR, state, |
| 799 "Code modification: code segments have different " | 800 "Code modification: code segments have different " |
| 800 "number of instructions\n"); | 801 "number of instructions\n"); |
| 801 } | 802 } |
| 802 } while (0); | 803 } while (0); |
| 803 | 804 |
| 804 state->cur_inst_state = NULL; | 805 state->cur_inst_state = NULL; |
| 805 state->cur_inst = NULL; | 806 state->cur_inst = NULL; |
| 806 state->cur_inst_vector = NULL; | 807 state->cur_inst_vector = NULL; |
| 807 NaClApplyPostValidators(state, iter_new); | 808 NaClApplyPostValidators(state, iter_new); |
| 808 NaClInstIterDestroy(iter_old); | 809 NaClInstIterDestroy(iter_old); |
| 809 NaClInstIterDestroy(iter_new); | 810 NaClInstIterDestroy(iter_new); |
| 810 NaClValidatorStatePrintStats(state); | 811 NaClValidatorStatePrintStats(state); |
| 811 } | 812 } |
| OLD | NEW |