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