| OLD | NEW |
| (Empty) |
| 1 /* | |
| 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 | |
| 4 * found in the LICENSE file. | |
| 5 */ | |
| 6 | |
| 7 #include <stdio.h> | |
| 8 | |
| 9 #include "native_client/src/shared/platform/nacl_check.h" | |
| 10 #include "native_client/src/trusted/validator/x86/ncinstbuffer.h" | |
| 11 | |
| 12 /* To turn on debugging of instruction decoding, change value of | |
| 13 * DEBUGGING to 1. | |
| 14 */ | |
| 15 #define DEBUGGING 0 | |
| 16 | |
| 17 #include "native_client/src/shared/utils/debugging.h" | |
| 18 | |
| 19 #include "native_client/src/trusted/validator/x86/ncinstbuffer_inl.c" | |
| 20 | |
| 21 void NCRemainingMemoryAdvance(NCRemainingMemory* memory) { | |
| 22 NCRemainingMemoryAdvanceInline(memory); | |
| 23 } | |
| 24 | |
| 25 void NCRemainingMemoryReset(NCRemainingMemory* memory) { | |
| 26 NCRemainingMemoryResetInline(memory); | |
| 27 } | |
| 28 | |
| 29 const char* NCRemainingMemoryErrorMessage(NCRemainingMemoryError error) { | |
| 30 switch (error) { | |
| 31 case NCRemainingMemoryOverflow: | |
| 32 return "Read past end of memory segment occurred."; | |
| 33 case NCInstBufferOverflow: | |
| 34 return "Internal error: instruction buffer overflow."; | |
| 35 case NCUnknownMemoryError: | |
| 36 default: | |
| 37 return "Unknown memory error occurred."; | |
| 38 } | |
| 39 } | |
| 40 | |
| 41 void NCRemainingMemoryReportError(NCRemainingMemoryError error, | |
| 42 NCRemainingMemory* memory) { | |
| 43 fprintf(stdout, "%s\n", NCRemainingMemoryErrorMessage(error)); | |
| 44 } | |
| 45 | |
| 46 void NCRemainingMemoryInit(uint8_t* memory_base, NaClMemorySize size, | |
| 47 NCRemainingMemory* memory) { | |
| 48 memory->mpc = memory_base; | |
| 49 memory->cur_pos = memory->mpc; | |
| 50 memory->mlimit = memory_base + size; | |
| 51 memory->next_byte = NCRemainingMemoryPeekInline(memory); | |
| 52 memory->error_fn = NCRemainingMemoryReportError; | |
| 53 memory->error_fn_state = NULL; | |
| 54 NCRemainingMemoryAdvanceInline(memory); | |
| 55 } | |
| 56 | |
| 57 uint8_t NCRemainingMemoryLookahead(NCRemainingMemory* memory, ssize_t n) { | |
| 58 return NCRemainingMemoryLookaheadInline(memory, n); | |
| 59 } | |
| 60 | |
| 61 uint8_t NCRemainingMemoryRead(NCRemainingMemory* memory) { | |
| 62 return NCRemainingMemoryReadInline(memory); | |
| 63 } | |
| 64 | |
| 65 void NCInstBytesInitMemory(NCInstBytes* bytes, NCRemainingMemory* memory) { | |
| 66 #if NCBUF_CLEAR_CACHE | |
| 67 int i; | |
| 68 for (i = 0; i < MAX_INST_LENGTH; ++i) { | |
| 69 bytes->byte[i] = 0; | |
| 70 } | |
| 71 #endif | |
| 72 bytes->memory = memory; | |
| 73 bytes->length = 0; | |
| 74 } | |
| 75 | |
| 76 void NCInstBytesReset(NCInstBytes* buffer) { | |
| 77 NCInstBytesResetInline(buffer); | |
| 78 } | |
| 79 | |
| 80 void NCInstBytesInit(NCInstBytes* buffer) { | |
| 81 NCInstBytesInitInline(buffer); | |
| 82 } | |
| 83 | |
| 84 uint8_t NCInstBytesPeek(NCInstBytes* bytes, ssize_t n) { | |
| 85 return NCInstBytesPeekInline(bytes, n); | |
| 86 } | |
| 87 | |
| 88 uint8_t NCInstByte(NCInstBytes* bytes, ssize_t n) { | |
| 89 return NCInstByteInline(bytes, n); | |
| 90 } | |
| 91 | |
| 92 uint8_t NCInstBytesRead(NCInstBytes* bytes) { | |
| 93 return NCInstBytesReadInline(bytes); | |
| 94 } | |
| 95 | |
| 96 void NCInstBytesReadBytes(ssize_t n, NCInstBytes* bytes) { | |
| 97 NCInstBytesReadBytesInline(n, bytes); | |
| 98 } | |
| 99 | |
| 100 #if NCBUF_CLEAR_CACHE | |
| 101 #define NCBUF_BYTES_LENGTH(bytes) MAX_INST_LENGTH | |
| 102 #else | |
| 103 #define NCBUF_BYTES_LENGTH(bytes) (bytes)->length | |
| 104 #endif | |
| 105 | |
| 106 static INLINE void NCInstBytesPtrInitPos( | |
| 107 NCInstBytesPtr* ptr, const NCInstBytes* bytes, int pos) { | |
| 108 ptr->bytes = bytes; | |
| 109 if (pos <= NCBUF_BYTES_LENGTH(bytes)) { | |
| 110 ptr->pos = (uint8_t) pos; | |
| 111 } else { | |
| 112 bytes->memory->error_fn(NCInstBufferOverflow, bytes->memory); | |
| 113 ptr->pos = bytes->length; | |
| 114 } | |
| 115 } | |
| 116 | |
| 117 void NCInstBytesPtrInit(NCInstBytesPtr* ptr, const NCInstBytes* bytes) { | |
| 118 NCInstBytesPtrInitPos(ptr, bytes, 0); | |
| 119 } | |
| 120 | |
| 121 void NCInstBytesPtrInitInc(NCInstBytesPtr* ptr, const NCInstBytesPtr* base, | |
| 122 int pos) { | |
| 123 NCInstBytesPtrInitPos(ptr, base->bytes, base->pos + pos); | |
| 124 } | |
| 125 | |
| 126 uint8_t NCInstBytesPos(const NCInstBytesPtr* ptr) { | |
| 127 return ptr->pos; | |
| 128 } | |
| 129 | |
| 130 uint8_t NCInstBytesByte(const NCInstBytesPtr* ptr, int n) { | |
| 131 return NCInstBytesByteInline(ptr, n); | |
| 132 } | |
| 133 | |
| 134 int32_t NCInstBytesInt32(const NCInstBytesPtr* ptr, int num_bytes) { | |
| 135 switch (num_bytes) { | |
| 136 case 1: | |
| 137 return (int8_t) NCInstBytesByteInline(ptr, 0); | |
| 138 case 2: | |
| 139 return (int16_t) (NCInstBytesByteInline(ptr, 0) + | |
| 140 (NCInstBytesByteInline(ptr, 1) << 8)); | |
| 141 case 3: | |
| 142 /* Note: Handle special case of Iw, Ib in 32 bit validator. */ | |
| 143 return (int32_t) (NCInstBytesByteInline(ptr, 0) + | |
| 144 (NCInstBytesByteInline(ptr, 1) << 8) + | |
| 145 (NCInstBytesByteInline(ptr, 2) << 16)); | |
| 146 case 4: | |
| 147 return (int32_t) (NCInstBytesByteInline(ptr, 0) + | |
| 148 (NCInstBytesByteInline(ptr, 1) << 8) + | |
| 149 (NCInstBytesByteInline(ptr, 2) << 16) + | |
| 150 (NCInstBytesByteInline(ptr, 3) << 24)); | |
| 151 default: | |
| 152 CHECK(0); /* Fail -- should not happen. */ | |
| 153 return -1; | |
| 154 } | |
| 155 } | |
| 156 | |
| 157 int64_t NCInstBytesInt64(const NCInstBytesPtr* ptr, int num_bytes) { | |
| 158 switch (num_bytes) { | |
| 159 case 1: | |
| 160 case 2: | |
| 161 case 3: /* Handle special case of Iw, Ib in 32 bit validator. */ | |
| 162 case 4: | |
| 163 return (int64_t) NCInstBytesInt32(ptr, num_bytes); | |
| 164 case 6: { | |
| 165 /* Handle special case of 48-bit pointers in 32 bit validator. */ | |
| 166 NCInstBytesPtr ptr_plus_2; | |
| 167 NCInstBytesPtrInitInc(&ptr_plus_2, ptr, 2); | |
| 168 return ((int64_t) (NCInstBytesInt32(&ptr_plus_2, 2)) << 32) | | |
| 169 ((int64_t) (NCInstBytesInt32(ptr, 4))); | |
| 170 } | |
| 171 case 8: { | |
| 172 NCInstBytesPtr ptr_plus_4; | |
| 173 NCInstBytesPtrInitInc(&ptr_plus_4, ptr, 4); | |
| 174 return ((int64_t) (NCInstBytesInt32(&ptr_plus_4, 4)) << 32) | | |
| 175 ((int64_t) (NCInstBytesInt32(ptr, 4))); | |
| 176 } | |
| 177 default: | |
| 178 CHECK(0); /* Fail -- should not happen. */ | |
| 179 return -1; | |
| 180 } | |
| 181 } | |
| 182 | |
| 183 void NCInstBytesAdvance(NCInstBytesPtr* ptr, int n) { | |
| 184 int index = ptr->pos + n; | |
| 185 if (index < NCBUF_BYTES_LENGTH(ptr->bytes)) { | |
| 186 ptr->pos = index; | |
| 187 } else { | |
| 188 ptr->bytes->memory->error_fn(NCInstBufferOverflow, ptr->bytes->memory); | |
| 189 } | |
| 190 } | |
| 191 | |
| 192 int NCInstBytesLength(const NCInstBytesPtr* ptr) { | |
| 193 return (int) ptr->bytes->length - (int) ptr->pos; | |
| 194 } | |
| OLD | NEW |