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 |