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 1 : void NCRemainingMemoryAdvance(NCRemainingMemory* memory) {
22 1 : NCRemainingMemoryAdvanceInline(memory);
23 1 : }
24 :
25 2 : void NCRemainingMemoryReset(NCRemainingMemory* memory) {
26 2 : NCRemainingMemoryResetInline(memory);
27 2 : }
28 :
29 2 : const char* NCRemainingMemoryErrorMessage(NCRemainingMemoryError error) {
30 2 : switch (error) {
31 : case NCRemainingMemoryOverflow:
32 2 : return "Read past end of memory segment occurred.";
33 : case NCInstBufferOverflow:
34 1 : return "Internal error: instruction buffer overflow.";
35 : case NCUnknownMemoryError:
36 : default:
37 0 : return "Unknown memory error occurred.";
38 : }
39 2 : }
40 :
41 : void NCRemainingMemoryReportError(NCRemainingMemoryError error,
42 2 : NCRemainingMemory* memory) {
43 2 : fprintf(stdout, "%s\n", NCRemainingMemoryErrorMessage(error));
44 2 : }
45 :
46 : void NCRemainingMemoryInit(uint8_t* memory_base, NaClMemorySize size,
47 5 : NCRemainingMemory* memory) {
48 5 : memory->mpc = memory_base;
49 5 : memory->cur_pos = memory->mpc;
50 5 : memory->mlimit = memory_base + size;
51 5 : memory->next_byte = NCRemainingMemoryPeekInline(memory);
52 5 : memory->error_fn = NCRemainingMemoryReportError;
53 5 : memory->error_fn_state = NULL;
54 5 : NCRemainingMemoryAdvanceInline(memory);
55 5 : }
56 :
57 1 : uint8_t NCRemainingMemoryLookahead(NCRemainingMemory* memory, ssize_t n) {
58 1 : return NCRemainingMemoryLookaheadInline(memory, n);
59 1 : }
60 :
61 1 : uint8_t NCRemainingMemoryRead(NCRemainingMemory* memory) {
62 1 : return NCRemainingMemoryReadInline(memory);
63 1 : }
64 :
65 4 : void NCInstBytesInitMemory(NCInstBytes* bytes, NCRemainingMemory* memory) {
66 : #if NCBUF_CLEAR_CACHE
67 : int i;
68 4 : for (i = 0; i < MAX_INST_LENGTH; ++i) {
69 4 : bytes->byte[i] = 0;
70 4 : }
71 : #endif
72 4 : bytes->memory = memory;
73 4 : bytes->length = 0;
74 4 : }
75 :
76 2 : void NCInstBytesReset(NCInstBytes* buffer) {
77 2 : NCInstBytesResetInline(buffer);
78 2 : }
79 :
80 0 : void NCInstBytesInit(NCInstBytes* buffer) {
81 0 : NCInstBytesInitInline(buffer);
82 0 : }
83 :
84 1 : uint8_t NCInstBytesPeek(NCInstBytes* bytes, ssize_t n) {
85 1 : return NCInstBytesPeekInline(bytes, n);
86 1 : }
87 :
88 0 : uint8_t NCInstByte(NCInstBytes* bytes, ssize_t n) {
89 0 : return NCInstByteInline(bytes, n);
90 0 : }
91 :
92 1 : uint8_t NCInstBytesRead(NCInstBytes* bytes) {
93 1 : return NCInstBytesReadInline(bytes);
94 1 : }
95 :
96 1 : void NCInstBytesReadBytes(ssize_t n, NCInstBytes* bytes) {
97 1 : NCInstBytesReadBytesInline(n, bytes);
98 1 : }
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 2 : NCInstBytesPtr* ptr, const NCInstBytes* bytes, int pos) {
108 2 : ptr->bytes = bytes;
109 2 : if (pos <= NCBUF_BYTES_LENGTH(bytes)) {
110 2 : ptr->pos = (uint8_t) pos;
111 2 : } else {
112 0 : bytes->memory->error_fn(NCInstBufferOverflow, bytes->memory);
113 0 : ptr->pos = bytes->length;
114 : }
115 2 : }
116 :
117 2 : void NCInstBytesPtrInit(NCInstBytesPtr* ptr, const NCInstBytes* bytes) {
118 2 : NCInstBytesPtrInitPos(ptr, bytes, 0);
119 2 : }
120 :
121 : void NCInstBytesPtrInitInc(NCInstBytesPtr* ptr, const NCInstBytesPtr* base,
122 2 : int pos) {
123 2 : NCInstBytesPtrInitPos(ptr, base->bytes, base->pos + pos);
124 2 : }
125 :
126 0 : uint8_t NCInstBytesPos(const NCInstBytesPtr* ptr) {
127 0 : return ptr->pos;
128 0 : }
129 :
130 2 : uint8_t NCInstBytesByte(const NCInstBytesPtr* ptr, int n) {
131 2 : return NCInstBytesByteInline(ptr, n);
132 2 : }
133 :
134 2 : int32_t NCInstBytesInt32(const NCInstBytesPtr* ptr, int num_bytes) {
135 2 : switch (num_bytes) {
136 : case 1:
137 2 : return (int8_t) NCInstBytesByteInline(ptr, 0);
138 : case 2:
139 : return (int16_t) (NCInstBytesByteInline(ptr, 0) +
140 2 : (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 1 : (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 2 : (NCInstBytesByteInline(ptr, 3) << 24));
151 : default:
152 0 : CHECK(0); /* Fail -- should not happen. */
153 0 : return -1;
154 : }
155 2 : }
156 :
157 2 : int64_t NCInstBytesInt64(const NCInstBytesPtr* ptr, int num_bytes) {
158 2 : 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 2 : 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 : 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 : 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 2 : }
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 0 : }
|