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