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 1075698 : void NCRemainingMemoryReset(NCRemainingMemory* memory) {
26 1075698 : NCRemainingMemoryResetInline(memory);
27 1075698 : }
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 : }
40 :
41 125 : void NCRemainingMemoryReportError(NCRemainingMemoryError error,
42 : NCRemainingMemory* memory) {
43 125 : fprintf(stdout, "%s\n", NCRemainingMemoryErrorMessage(error));
44 125 : }
45 :
46 606 : void NCRemainingMemoryInit(uint8_t* memory_base, NaClMemorySize size,
47 : NCRemainingMemory* memory) {
48 606 : memory->mpc = memory_base;
49 606 : memory->cur_pos = memory->mpc;
50 606 : memory->mlimit = memory_base + size;
51 606 : memory->next_byte = NCRemainingMemoryPeekInline(memory);
52 606 : memory->error_fn = NCRemainingMemoryReportError;
53 606 : memory->error_fn_state = NULL;
54 606 : NCRemainingMemoryAdvanceInline(memory);
55 606 : }
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 1142 : void NCInstBytesInitMemory(NCInstBytes* bytes, NCRemainingMemory* memory) {
66 : #if NCBUF_CLEAR_CACHE
67 : int i;
68 18272 : for (i = 0; i < MAX_INST_LENGTH; ++i) {
69 17130 : bytes->byte[i] = 0;
70 : }
71 : #endif
72 1142 : bytes->memory = memory;
73 1142 : bytes->length = 0;
74 1142 : }
75 :
76 516557 : void NCInstBytesReset(NCInstBytes* buffer) {
77 516557 : NCInstBytesResetInline(buffer);
78 516557 : }
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 228950 : static INLINE void NCInstBytesPtrInitPos(
107 : NCInstBytesPtr* ptr, const NCInstBytes* bytes, int pos) {
108 228950 : ptr->bytes = bytes;
109 228950 : if (pos <= NCBUF_BYTES_LENGTH(bytes)) {
110 228950 : ptr->pos = (uint8_t) pos;
111 : } else {
112 0 : bytes->memory->error_fn(NCInstBufferOverflow, bytes->memory);
113 0 : ptr->pos = bytes->length;
114 : }
115 228950 : }
116 :
117 948 : void NCInstBytesPtrInit(NCInstBytesPtr* ptr, const NCInstBytes* bytes) {
118 948 : NCInstBytesPtrInitPos(ptr, bytes, 0);
119 948 : }
120 :
121 228002 : void NCInstBytesPtrInitInc(NCInstBytesPtr* ptr, const NCInstBytesPtr* base,
122 : int pos) {
123 228002 : NCInstBytesPtrInitPos(ptr, base->bytes, base->pos + pos);
124 228002 : }
125 :
126 0 : uint8_t NCInstBytesPos(const NCInstBytesPtr* ptr) {
127 0 : return ptr->pos;
128 : }
129 :
130 478187 : uint8_t NCInstBytesByte(const NCInstBytesPtr* ptr, int n) {
131 478187 : return NCInstBytesByteInline(ptr, n);
132 : }
133 :
134 54323 : int32_t NCInstBytesInt32(const NCInstBytesPtr* ptr, int num_bytes) {
135 54323 : switch (num_bytes) {
136 : case 1:
137 26617 : return (int8_t) NCInstBytesByteInline(ptr, 0);
138 : case 2:
139 122 : return (int16_t) (NCInstBytesByteInline(ptr, 0) +
140 61 : (NCInstBytesByteInline(ptr, 1) << 8));
141 : case 3:
142 : /* Note: Handle special case of Iw, Ib in 32 bit validator. */
143 6 : return (int32_t) (NCInstBytesByteInline(ptr, 0) +
144 2 : (NCInstBytesByteInline(ptr, 1) << 8) +
145 2 : (NCInstBytesByteInline(ptr, 2) << 16));
146 : case 4:
147 82929 : return (int32_t) (NCInstBytesByteInline(ptr, 0) +
148 55286 : (NCInstBytesByteInline(ptr, 1) << 8) +
149 27643 : (NCInstBytesByteInline(ptr, 2) << 16) +
150 27643 : (NCInstBytesByteInline(ptr, 3) << 24));
151 : default:
152 0 : CHECK(0); /* Fail -- should not happen. */
153 0 : return -1;
154 : }
155 : }
156 :
157 10150 : int64_t NCInstBytesInt64(const NCInstBytesPtr* ptr, int num_bytes) {
158 10150 : 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 10150 : 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 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 : 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 : }
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 : } else {
188 0 : ptr->bytes->memory->error_fn(NCInstBufferOverflow, ptr->bytes->memory);
189 : }
190 0 : }
191 :
192 162939 : int NCInstBytesLength(const NCInstBytesPtr* ptr) {
193 162939 : return (int) ptr->bytes->length - (int) ptr->pos;
194 : }
|