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 : void NCRemainingMemoryReportError(NCRemainingMemoryError error,
42 125 : NCRemainingMemory* memory) {
43 125 : fprintf(stdout, "%s\n", NCRemainingMemoryErrorMessage(error));
44 125 : }
45 :
46 : void NCRemainingMemoryInit(uint8_t* memory_base, NaClMemorySize size,
47 591 : NCRemainingMemory* memory) {
48 591 : memory->mpc = memory_base;
49 591 : memory->cur_pos = memory->mpc;
50 591 : memory->mlimit = memory_base + size;
51 591 : memory->next_byte = NCRemainingMemoryPeekInline(memory);
52 591 : memory->error_fn = NCRemainingMemoryReportError;
53 591 : memory->error_fn_state = NULL;
54 591 : NCRemainingMemoryAdvanceInline(memory);
55 591 : }
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 1157 : void NCInstBytesInitMemory(NCInstBytes* bytes, NCRemainingMemory* memory) {
66 : #if NCBUF_CLEAR_CACHE
67 : int i;
68 18512 : for (i = 0; i < MAX_INST_LENGTH; ++i) {
69 17355 : bytes->byte[i] = 0;
70 : }
71 : #endif
72 1157 : bytes->memory = memory;
73 1157 : bytes->length = 0;
74 1157 : }
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 : static INLINE void NCInstBytesPtrInitPos(
107 103639 : NCInstBytesPtr* ptr, const NCInstBytes* bytes, int pos) {
108 103639 : ptr->bytes = bytes;
109 103639 : if (pos <= NCBUF_BYTES_LENGTH(bytes)) {
110 103639 : ptr->pos = (uint8_t) pos;
111 : } else {
112 0 : bytes->memory->error_fn(NCInstBufferOverflow, bytes->memory);
113 0 : ptr->pos = bytes->length;
114 : }
115 103639 : }
116 :
117 974 : void NCInstBytesPtrInit(NCInstBytesPtr* ptr, const NCInstBytes* bytes) {
118 974 : NCInstBytesPtrInitPos(ptr, bytes, 0);
119 974 : }
120 :
121 : void NCInstBytesPtrInitInc(NCInstBytesPtr* ptr, const NCInstBytesPtr* base,
122 102665 : int pos) {
123 102665 : NCInstBytesPtrInitPos(ptr, base->bytes, base->pos + pos);
124 102665 : }
125 :
126 0 : uint8_t NCInstBytesPos(const NCInstBytesPtr* ptr) {
127 0 : return ptr->pos;
128 : }
129 :
130 36812 : uint8_t NCInstBytesByte(const NCInstBytesPtr* ptr, int n) {
131 36812 : return NCInstBytesByteInline(ptr, n);
132 : }
133 :
134 46786 : int32_t NCInstBytesInt32(const NCInstBytesPtr* ptr, int num_bytes) {
135 46786 : switch (num_bytes) {
136 : case 1:
137 206 : return (int8_t) NCInstBytesByteInline(ptr, 0);
138 : case 2:
139 16 : return (int16_t) (NCInstBytesByteInline(ptr, 0) +
140 : (NCInstBytesByteInline(ptr, 1) << 8));
141 : case 4:
142 46564 : return (int32_t) (NCInstBytesByteInline(ptr, 0) +
143 : (NCInstBytesByteInline(ptr, 1) << 8) +
144 : (NCInstBytesByteInline(ptr, 2) << 16) +
145 : (NCInstBytesByteInline(ptr, 3) << 24));
146 : default:
147 0 : CHECK(0); /* Fail -- should not happen. */
148 0 : return -1;
149 : }
150 : }
151 :
152 135 : int64_t NCInstBytesInt64(const NCInstBytesPtr* ptr, int num_bytes) {
153 135 : switch (num_bytes) {
154 : case 1:
155 : case 2:
156 : case 4:
157 135 : return (int64_t) NCInstBytesInt32(ptr, num_bytes);
158 : case 8: {
159 : NCInstBytesPtr ptr_plus_4;
160 0 : NCInstBytesPtrInitInc(&ptr_plus_4, ptr, 4);
161 0 : return ((int64_t) (NCInstBytesInt32(&ptr_plus_4, 4)) << 32) |
162 : ((int64_t) (NCInstBytesInt32(ptr, 4)));
163 : }
164 : default:
165 0 : CHECK(0); /* Fail -- should not happen. */
166 0 : return -1;
167 : }
168 : }
169 :
170 0 : void NCInstBytesAdvance(NCInstBytesPtr* ptr, int n) {
171 0 : int index = ptr->pos + n;
172 0 : if (index < NCBUF_BYTES_LENGTH(ptr->bytes)) {
173 0 : ptr->pos = index;
174 : } else {
175 0 : ptr->bytes->memory->error_fn(NCInstBufferOverflow, ptr->bytes->memory);
176 : }
177 0 : }
178 :
179 393560 : int NCInstBytesLength(const NCInstBytesPtr* ptr) {
180 393560 : return (int) ptr->bytes->length - (int) ptr->pos;
181 : }
|