| 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 * Defines an instruction (decoder) iterator that processes code segments. | 8 * Defines an instruction (decoder) iterator that processes code segments. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_iter.h" | 11 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_iter.h" |
| 12 | 12 |
| 13 #include <stdio.h> | 13 #include <stdio.h> |
| 14 #include <stdlib.h> | 14 #include <stdlib.h> |
| 15 #include <assert.h> | |
| 16 | 15 |
| 17 #include "native_client/src/shared/platform/nacl_log.h" | 16 #include "native_client/src/shared/platform/nacl_log.h" |
| 17 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_iter_inl.h" |
| 18 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_state.h" | 18 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_state.h" |
| 19 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_state_internal
.h" | 19 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_state_internal
.h" |
| 20 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_trans.h" | 20 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_trans.h" |
| 21 #include "native_client/src/trusted/validator/x86/decoder/ncop_exps.h" | 21 #include "native_client/src/trusted/validator/x86/decoder/ncop_exps.h" |
| 22 #include "native_client/src/trusted/validator/x86/nc_segment.h" | |
| 23 | 22 |
| 24 /* To turn on debugging of instruction decoding, change value of | 23 /* To turn on debugging of instruction decoding, change value of |
| 25 * DEBUGGING to 1. | 24 * DEBUGGING to 1. |
| 26 */ | 25 */ |
| 27 #define DEBUGGING 0 | 26 #define DEBUGGING 0 |
| 28 | 27 |
| 29 #include "native_client/src/shared/utils/debugging.h" | 28 #include "native_client/src/shared/utils/debugging.h" |
| 30 | 29 |
| 31 static void NaClInstIterLogError(const char* error_message) { | 30 static void NaClInstIterLogError(const char* error_message) { |
| 32 NaClLog(LOG_ERROR, "*ERROR* %s\n", error_message); | 31 NaClLog(LOG_ERROR, "*ERROR* %s\n", error_message); |
| 33 } | 32 } |
| 34 | 33 |
| 35 /* Default handler for errors while running instruction iterator. | 34 void NaClInstIterFatal(const char* error_message) { |
| 36 * Should only be called when caller has incorrectly called a | |
| 37 * method. | |
| 38 */ | |
| 39 static void NaClInstIterFatal(const char* error_message) { | |
| 40 NaClInstIterLogError(error_message); | 35 NaClInstIterLogError(error_message); |
| 41 exit(1); | 36 exit(1); |
| 42 } | 37 } |
| 43 | 38 |
| 44 /* Default handler for errors found while parsing the memory segment.*/ | 39 /* Default handler for errors found while parsing the memory segment.*/ |
| 45 static void NaClInstIterReportRemainingMemoryError( | 40 static void NaClInstIterReportRemainingMemoryError( |
| 46 NCRemainingMemoryError error, | 41 NCRemainingMemoryError error, |
| 47 struct NCRemainingMemory* memory) { | 42 struct NCRemainingMemory* memory) { |
| 48 NaClInstIterLogError(NCRemainingMemoryErrorMessage(error)); | 43 NaClInstIterLogError(NCRemainingMemoryErrorMessage(error)); |
| 49 } | 44 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 } | 83 } |
| 89 | 84 |
| 90 void NaClInstIterDestroy(NaClInstIter* iter) { | 85 void NaClInstIterDestroy(NaClInstIter* iter) { |
| 91 if (NULL != iter) { | 86 if (NULL != iter) { |
| 92 free(iter->buffer); | 87 free(iter->buffer); |
| 93 free(iter); | 88 free(iter); |
| 94 } | 89 } |
| 95 } | 90 } |
| 96 | 91 |
| 97 NaClInstState* NaClInstIterGetUndecodedState(NaClInstIter* iter) { | 92 NaClInstState* NaClInstIterGetUndecodedState(NaClInstIter* iter) { |
| 98 return &iter->buffer[iter->buffer_index]; | 93 return NaClInstIterGetUndecodedStateInline(iter); |
| 99 } | 94 } |
| 100 | 95 |
| 101 NaClInstState* NaClInstIterGetState(NaClInstIter* iter) { | 96 NaClInstState* NaClInstIterGetState(NaClInstIter* iter) { |
| 102 NaClInstState* state = NaClInstIterGetUndecodedState(iter); | 97 return NaClInstIterGetStateInline(iter); |
| 103 if (NULL == state->inst) { | |
| 104 NaClDecodeInst(iter, state); | |
| 105 } | |
| 106 return state; | |
| 107 } | 98 } |
| 108 | 99 |
| 109 Bool NaClInstIterHasLookbackState(NaClInstIter* iter, size_t distance) { | 100 Bool NaClInstIterHasLookbackState(NaClInstIter* iter, size_t distance) { |
| 110 return distance < iter->buffer_size && distance <= iter->inst_count; | 101 return NaClInstIterHasLookbackStateInline(iter, distance); |
| 111 } | 102 } |
| 112 | 103 |
| 113 NaClInstState* NaClInstIterGetLookbackState(NaClInstIter* iter, | 104 NaClInstState* NaClInstIterGetLookbackState(NaClInstIter* iter, |
| 114 size_t distance) { | 105 size_t distance) { |
| 115 NaClInstState* state; | 106 return NaClInstIterGetLookbackStateInline(iter, distance); |
| 116 assert(distance < iter->buffer_size); | |
| 117 assert(distance <= iter->inst_count); | |
| 118 state = &iter->buffer[((iter->buffer_index + iter->buffer_size) - distance) | |
| 119 % iter->buffer_size]; | |
| 120 if (NULL == state->inst) { | |
| 121 NaClDecodeInst(iter, state); | |
| 122 } | |
| 123 return state; | |
| 124 } | 107 } |
| 125 | 108 |
| 126 Bool NaClInstIterHasNext(NaClInstIter* iter) { | 109 Bool NaClInstIterHasNext(NaClInstIter* iter) { |
| 127 DEBUG(NaClLog(LOG_INFO, "iter has next index %"NACL_PRIxNaClMemorySize | 110 return NaClInstIterHasNextInline(iter); |
| 128 " < %"NACL_PRIxNaClMemorySize"\n", | |
| 129 iter->index, iter->segment->size)); | |
| 130 return iter->index < iter->segment->size; | |
| 131 } | 111 } |
| 132 | 112 |
| 133 void NaClInstIterAdvance(NaClInstIter* iter) { | 113 void NaClInstIterAdvance(NaClInstIter* iter) { |
| 134 if (iter->index >= iter->segment->size) { | 114 NaClInstIterAdvanceInline(iter); |
| 135 NaClInstIterFatal("NaClInstIterAdvance with no next element."); | |
| 136 } | |
| 137 NaClInstIterGetState(iter); | |
| 138 iter->index += iter->memory.read_length; | |
| 139 ++iter->inst_count; | |
| 140 iter->buffer_index = (iter->buffer_index + 1) % iter->buffer_size; | |
| 141 DEBUG( | |
| 142 NaClLog(LOG_INFO, | |
| 143 "iter advance: index %"NACL_PRIxNaClMemorySize", " | |
| 144 "buffer index %"NACL_PRIuS"\n", | |
| 145 iter->index, iter->buffer_index)); | |
| 146 iter->buffer[iter->buffer_index].inst = NULL; | |
| 147 } | 115 } |
| 148 | 116 |
| 149 uint8_t* NaClInstIterGetInstMemory(NaClInstIter* iter) { | 117 uint8_t* NaClInstIterGetInstMemory(NaClInstIter* iter) { |
| 150 if (iter->index >= iter->segment->size) { | 118 return NaClInstIterGetInstMemoryInline(iter); |
| 151 NaClInstIterFatal("NaClInstIterGetInstMemory with no next element."); | |
| 152 } | |
| 153 return iter->segment->mbase + iter->index; | |
| 154 } | 119 } |
| OLD | NEW |