| 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 /* | |
| 8 * ncinstbuffer.h - Models bytes of matched instruction. | |
| 9 * | |
| 10 * Separates memory into two parts. The first is a block | |
| 11 * of memory corresponding to the code segment, that needs | |
| 12 * to be parsed to find instructions. The second is a copy | |
| 13 * of the bytes read that corresponds to the current parsed | |
| 14 * instruction. | |
| 15 * | |
| 16 * Note: We intentionally create a copy of the instruction bytes, | |
| 17 * since the parsed instruction may be longer than the actual | |
| 18 * code segment. In such cases, the memory segment reader automatically | |
| 19 * fills in any extra reads with a zero byte value. | |
| 20 */ | |
| 21 #ifndef NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_X86_NCINSTBUFFER_H_ | |
| 22 #define NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_X86_NCINSTBUFFER_H_ | |
| 23 | |
| 24 #include "native_client/src/include/portability.h" | |
| 25 #include "native_client/src/trusted/validator/types_memory_model.h" | |
| 26 | |
| 27 EXTERN_C_BEGIN | |
| 28 | |
| 29 struct NCValidatorState; | |
| 30 | |
| 31 /* Types of errors that can occur while parsing the memory segment. */ | |
| 32 typedef enum { | |
| 33 /* Read past the end of the memory segment. Note: this problem will also | |
| 34 * be noted by byte overflow_count > 0 in the NCRemainingMemory structure. | |
| 35 */ | |
| 36 NCRemainingMemoryOverflow, | |
| 37 /* Too many bytes in an instruction, and can't fit in instruction buffer. */ | |
| 38 NCInstBufferOverflow, | |
| 39 /* An unknown error occurred while parsing the memory segment. */ | |
| 40 NCUnknownMemoryError | |
| 41 } NCRemainingMemoryError; | |
| 42 | |
| 43 struct NCRemainingMemory; | |
| 44 | |
| 45 /* Type of routine to call if an error occurs parsing the memory segment | |
| 46 * into an instruction buffer. Note: memory handling code will apply | |
| 47 * recovery rules if the corresponding error function returns. | |
| 48 */ | |
| 49 typedef void (*NCRemainingMemoryErrorFn)(NCRemainingMemoryError error, | |
| 50 struct NCRemainingMemory* memory); | |
| 51 | |
| 52 /* Structure holding the memory segment to be parsed. | |
| 53 * Note: In general, unless doing a post mortem on what happened, | |
| 54 * you should not access fields. Rather use the API functions below. | |
| 55 */ | |
| 56 typedef struct NCRemainingMemory { | |
| 57 /* The next byte in memory, or 0x00 if the memory segment has been | |
| 58 * completely parsed. | |
| 59 */ | |
| 60 uint8_t next_byte; | |
| 61 /* Pointer to the next character to read from the memory segment. */ | |
| 62 uint8_t* cur_pos; | |
| 63 /* Pointer to the byte after the end of the memory segment. */ | |
| 64 uint8_t* mlimit; | |
| 65 /* Pointer to the beginning of the current instruction in memory | |
| 66 * segment being parsed. | |
| 67 */ | |
| 68 uint8_t* mpc; | |
| 69 /* The actual number of bytes read from the memory segment for the | |
| 70 * current instruction being parsed. | |
| 71 */ | |
| 72 uint8_t read_length; | |
| 73 /* The number of additional (0x00) bytes added, so that we could parse | |
| 74 * the instruction. | |
| 75 */ | |
| 76 uint8_t overflow_count; | |
| 77 /* The error reporting function to use. Defaults to | |
| 78 * NCRemainingMemoryReportError. Caller should set this immediately | |
| 79 * after calling NCRemainingMemoryInit, if a different error reporting | |
| 80 * function should be used. | |
| 81 */ | |
| 82 NCRemainingMemoryErrorFn error_fn; | |
| 83 /* Additional state associated with the memory segment. | |
| 84 * Caller should set this immdiately after calling NCRemainingMemoryInit. | |
| 85 * Used to communicate additional state to the validator error function. | |
| 86 * Initialized to NULL in NCRemainingMemoryInit. | |
| 87 * Note: The type is not specified since the notion of state is | |
| 88 * decoder/validator specific, and corresponds to additional state | |
| 89 * that may be needed by field error_fn. This field, by default is set | |
| 90 * to NULL. When setting field error_fn, one can also set this field to | |
| 91 * a corresponding structure that holds additional information for reporting | |
| 92 * errors. | |
| 93 */ | |
| 94 void* error_fn_state; | |
| 95 } NCRemainingMemory; | |
| 96 | |
| 97 /* Initialize the (remaining) memory to the memory segment beginning | |
| 98 * at memory_base, and containing size bytes. | |
| 99 */ | |
| 100 void NCRemainingMemoryInit(uint8_t* memory_base, NaClMemorySize size, | |
| 101 NCRemainingMemory* memory); | |
| 102 | |
| 103 /* Returns the next byte in the memory segment, or 0x00 if at the | |
| 104 * end of the memory segment. | |
| 105 * Note: Same as NCRemainingMemoryLookahead(m, 0). Written as macro | |
| 106 * for performance (using a cached field next_byte). | |
| 107 */ | |
| 108 #define NCRemainingMemoryGetNext(m) ((m)->next_byte) | |
| 109 | |
| 110 /* Looks ahead N bytes into the memory, and returns the corresponding | |
| 111 * byte, or 0x00 if at the end of memory. i is zero-based. | |
| 112 */ | |
| 113 uint8_t NCRemainingMemoryLookahead(NCRemainingMemory* memory, ssize_t n); | |
| 114 | |
| 115 /* Reads and returns the next byte in the memory segment. Returns 0x00 if at | |
| 116 * the end of the memory segment. | |
| 117 */ | |
| 118 uint8_t NCRemainingMemoryRead(NCRemainingMemory* memory); | |
| 119 | |
| 120 /* Moves back to the beginning of the current instruction in | |
| 121 * the memory segment. | |
| 122 */ | |
| 123 void NCRemainingMemoryReset(NCRemainingMemory* memory); | |
| 124 | |
| 125 /* Starts a new instruction at the current position in the memory | |
| 126 * segment. | |
| 127 */ | |
| 128 void NCRemainingMemoryAdvance(NCRemainingMemory* memory); | |
| 129 | |
| 130 /* Default error message for type of error. */ | |
| 131 const char* NCRemainingMemoryErrorMessage(NCRemainingMemoryError error); | |
| 132 | |
| 133 /* Default memory segment reader error function. Prints out | |
| 134 * string defined by NCRemainingMemoryErrorMessage to stdout. | |
| 135 */ | |
| 136 void NCRemainingMemoryReportError(NCRemainingMemoryError error, | |
| 137 NCRemainingMemory* memory); | |
| 138 | |
| 139 /* The maximum number of bytes to be recognized as an instruction. */ | |
| 140 #define MAX_INST_LENGTH 15 | |
| 141 | |
| 142 /* Structure holding buffered bytes of a nacl instruction. This | |
| 143 * structure is filled as the memory segment is parsed to recognize | |
| 144 * the current instruction. | |
| 145 */ | |
| 146 typedef struct NCInstBytes { | |
| 147 /* The sequence of bytes defining the instruction. */ | |
| 148 uint8_t byte[MAX_INST_LENGTH]; | |
| 149 /* The number of bytes (in buffer) defining the instruction. */ | |
| 150 uint8_t length; | |
| 151 /* The memory associated with the bytes. Used to report | |
| 152 * buffer overflows through the corresponding error function. | |
| 153 */ | |
| 154 NCRemainingMemory* memory; | |
| 155 } NCInstBytes; | |
| 156 | |
| 157 /* Associate memory with the corresponding instruction bytes. */ | |
| 158 void NCInstBytesInitMemory(NCInstBytes* bytes, NCRemainingMemory* memory); | |
| 159 | |
| 160 /* Resets bytes back to the beginning of the current instruction. */ | |
| 161 void NCInstBytesReset(NCInstBytes* bytes); | |
| 162 | |
| 163 /* Initializes the instruction buffer as the empty buffer, and | |
| 164 * advances the memory segment so that one is beginning the | |
| 165 * parsing of the current instruction at the current position | |
| 166 * in the memory segment. | |
| 167 * Note: Assumes that NCInstBytesInitMemory has already been called to associate | |
| 168 * memory. | |
| 169 */ | |
| 170 void NCInstBytesInit(NCInstBytes* bytes); | |
| 171 | |
| 172 /* Peek ahead and return the nth (zero based) byte from the current position | |
| 173 * in the sequence of bytes being parsed. | |
| 174 */ | |
| 175 uint8_t NCInstBytesPeek(NCInstBytes* bytes, ssize_t n); | |
| 176 | |
| 177 /* Peek at the nth character in the sequence of bytes being parsed (independent | |
| 178 * of the current position). | |
| 179 */ | |
| 180 uint8_t NCInstByte(NCInstBytes* bytes, ssize_t n); | |
| 181 | |
| 182 /* Reads a byte from the memory segment and adds it to the instruction buffer. | |
| 183 * Returns the read byte. | |
| 184 * Note: Assumes that NCInstBytesInitMemory has already been called to associate | |
| 185 * memory. | |
| 186 */ | |
| 187 uint8_t NCInstBytesRead(NCInstBytes* bytes); | |
| 188 | |
| 189 /* Reads n bytes from the memory segment and adds it to the instruction buffer. | |
| 190 * Note: Assumes that NCInstBytesInitMemory has already been called to associate | |
| 191 * memory. | |
| 192 */ | |
| 193 void NCInstBytesReadBytes(ssize_t n, NCInstBytes* bytes); | |
| 194 | |
| 195 /* Structure holding pointer into bufferred bytes of a parsed instruction. */ | |
| 196 typedef struct NCInstBytesPtr { | |
| 197 /* The bytes the pointer is in. */ | |
| 198 const NCInstBytes* bytes; | |
| 199 /* The index into bytes associated with the pointer. */ | |
| 200 uint8_t pos; | |
| 201 } NCInstBytesPtr; | |
| 202 | |
| 203 /* Initializes the instruction bytes pointer to the given index in | |
| 204 * the buffered bytes of a nacl instruction. | |
| 205 */ | |
| 206 void NCInstBytesPtrInit(NCInstBytesPtr* ptr, const NCInstBytes* bytes); | |
| 207 | |
| 208 /* Initializes the instruction bytes pointer to the position of base, advanced | |
| 209 * the given number of positions. | |
| 210 */ | |
| 211 void NCInstBytesPtrInitInc(NCInstBytesPtr* ptr, const NCInstBytesPtr* base, | |
| 212 int pos); | |
| 213 | |
| 214 /* Returns the index position of the given bytes ptr in the instruction | |
| 215 * bytes. | |
| 216 */ | |
| 217 uint8_t NCInstBytesPos(const NCInstBytesPtr* ptr); | |
| 218 | |
| 219 /* Sign extends the given number of bytes, generating a corresponding 32-bit | |
| 220 * integer. Valid values for num_bytes is 1, 2, and 4. | |
| 221 */ | |
| 222 int32_t NCInstBytesInt32(const NCInstBytesPtr* ptr, int num_bytes); | |
| 223 | |
| 224 /* Sign extends the given number of bytes, generating a corresponding 64-bit | |
| 225 * integer. Valid values for num_bytes is 1, 2, 4, and 8. | |
| 226 */ | |
| 227 int64_t NCInstBytesInt64(const NCInstBytesPtr* ptr, int num_bytes); | |
| 228 | |
| 229 /* Returns the indexed byte pointed to by the instruction buffer pointer. */ | |
| 230 uint8_t NCInstBytesByte(const NCInstBytesPtr* ptr, int n); | |
| 231 | |
| 232 /* Advances the instruction buffer pointer by the number of bytes. */ | |
| 233 void NCInstBytesAdvance(NCInstBytesPtr* ptr, int n); | |
| 234 | |
| 235 /* Returns the number of bytes left in the instruction buffer, based | |
| 236 * on the pointer postiion. | |
| 237 */ | |
| 238 int NCInstBytesLength(const NCInstBytesPtr* ptr); | |
| 239 | |
| 240 EXTERN_C_END | |
| 241 | |
| 242 #endif /* NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_X86_NCINSTBUFFER_H_ */ | |
| OLD | NEW |