Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(164)

Side by Side Diff: src/trusted/gio/gio_shm.c

Issue 594733005: Cleanup: Remove src/trusted/gio/, since it is unused (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: Fix Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/trusted/gio/gio_shm.h ('k') | src/trusted/gio/gio_shm_test.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 #include <errno.h>
8 #include <string.h>
9
10 #include "native_client/src/include/portability.h"
11
12 #include "native_client/src/shared/platform/nacl_check.h"
13 #include "native_client/src/shared/platform/nacl_host_desc.h"
14 #include "native_client/src/shared/platform/nacl_log.h"
15
16 #include "native_client/src/trusted/gio/gio_shm.h"
17 #include "native_client/src/trusted/service_runtime/include/bits/mman.h"
18 #include "native_client/src/trusted/service_runtime/include/sys/stat.h"
19 #include "native_client/src/trusted/service_runtime/nacl_config.h"
20 #include "native_client/src/trusted/service_runtime/sel_util.h"
21
22 #include "native_client/src/trusted/desc/nacl_desc_base.h"
23 #include "native_client/src/trusted/desc/nacl_desc_effector_trusted_mem.h"
24 #include "native_client/src/trusted/desc/nacl_desc_imc_shm.h"
25
26 /*
27 * This code maps in GIO_SHM_WINDOWSIZE bytes at a time for doing
28 * "I/O" from/to the shared memory object. This value must be an
29 * integer multiple of NACL_MAP_PAGESIZE.
30 */
31 #define GIO_SHM_WINDOWSIZE (16 * NACL_MAP_PAGESIZE)
32
33 /*
34 * Release current window if it exists, then map in window at the
35 * provided new_window_offset. This is akin to filbuf.
36 *
37 * Preconditions: 0 == (new_win_offset & (NACL_MAP_PAGESIZE - 1))
38 * new_win_offset < self->shm_sz
39 */
40 static int NaClGioShmSetWindow(struct NaClGioShm *self,
41 size_t new_win_offset) {
42 uintptr_t map_result;
43 size_t actual_len;
44
45 NaClLog(4,
46 "NaClGioShmSetWindow: new_win_offset 0x%"NACL_PRIxS"\n",
47 new_win_offset);
48 if (0 != (new_win_offset & (NACL_MAP_PAGESIZE - 1))) {
49 NaClLog(LOG_FATAL,
50 ("NaClGioShmSetWindow: internal error, requested"
51 " new window offset 0x%"NACL_PRIxS" is not aligned.\n"),
52 new_win_offset);
53 }
54
55 if (new_win_offset >= self->shm_sz) {
56 NaClLog(LOG_FATAL,
57 ("NaClGioShmSetWindow: setting window beyond end of shm object"
58 " offset 0x%"NACL_PRIxS", size 0x%"NACL_PRIxS"\n"),
59 new_win_offset, self->shm_sz);
60 }
61
62 if (NULL != self->cur_window) {
63 NaClDescUnmapUnsafe(self->shmp, (void *) self->cur_window,
64 self->window_size);
65 }
66 self->cur_window = NULL;
67 self->window_size = 0;
68
69 /*
70 * The Map virtual function will NOT pad space beyond the end of the
71 * memory mapping object with zero-filled pages. This is done for
72 * user code in nacl_syscall_common.c (NaClSysMmap), and the Map
73 * virtual function exposes the behavioral inconsistencies wrt
74 * allowing but ignoring mapping an offset beyond the end of file
75 * (linux) versus disallowing the mapping (MapViewOfFileEx).
76 *
77 * Here, we know the actual size of the shm object, and can deal
78 * with it.
79 */
80 actual_len = GIO_SHM_WINDOWSIZE;
81 if (actual_len > self->shm_sz - new_win_offset) {
82 actual_len = self->shm_sz - new_win_offset;
83 }
84 map_result =
85 (*((struct NaClDescVtbl const *) self->shmp->base.vtbl)->
86 Map)(self->shmp,
87 NaClDescEffectorTrustedMem(),
88 (void *) NULL,
89 actual_len,
90 NACL_ABI_PROT_READ | NACL_ABI_PROT_WRITE,
91 NACL_ABI_MAP_SHARED,
92 (nacl_off64_t) new_win_offset);
93 NaClLog(4,
94 "NaClGioShmSetWindow: Map returned 0x%"NACL_PRIxPTR"\n",
95 map_result);
96 if (NaClPtrIsNegErrno(&map_result)) {
97 return 0;
98 }
99
100 self->cur_window = (char *) map_result;
101 self->window_size = actual_len;
102 self->window_offset = new_win_offset;
103
104 return 1;
105 }
106
107 static ssize_t NaClGioShmReadOrWrite(struct Gio *vself,
108 void *buf,
109 size_t count,
110 int is_write) {
111 struct NaClGioShm *self = (struct NaClGioShm *) vself;
112 size_t new_window_offset;
113 size_t transfer;
114 size_t window_end;
115 size_t window_remain;
116 size_t sofar;
117
118 NaClLog(4,
119 ("NaClGioShmReadOrWrite: 0x%"NACL_PRIxPTR","
120 " 0x%"NACL_PRIxPTR", 0x%"NACL_PRIxS", %d\n"),
121 (uintptr_t) vself,
122 (uintptr_t) buf,
123 count,
124 is_write);
125 sofar = 0;
126 while (count > 0) {
127 NaClLog(4, "NaClGioShmReadOrWrite: count 0x%"NACL_PRIxS"\n", count);
128 if (self->io_offset >= self->shm_sz) {
129 break;
130 }
131 NaClLog(4, " cur_window 0x%"NACL_PRIxPTR"\n",
132 (uintptr_t) self->cur_window);
133 NaClLog(4, " io_offset 0x%"NACL_PRIxS"\n", self->io_offset);
134 NaClLog(4, "window_offset 0x%"NACL_PRIxS"\n", self->window_offset);
135 if (NULL == self->cur_window
136 || self->io_offset < self->window_offset
137 || self->window_offset + self->window_size <= self->io_offset) {
138 /*
139 * io_offset is outside the window. move the window so that
140 * it's within.
141 */
142 NaClLog(4, "Seek required\n");
143
144 new_window_offset = (self->io_offset
145 & (~(((size_t) NACL_MAP_PAGESIZE) - 1)));
146 NaClLog(4, "new_window_offset 0x%"NACL_PRIxS"\n", new_window_offset);
147 CHECK(0 == (new_window_offset &
148 (((size_t) NACL_MAP_PAGESIZE)-1)));
149 if (!NaClGioShmSetWindow(self, new_window_offset)) {
150 if (0 == sofar) {
151 errno = EIO;
152 sofar = -1;
153 }
154 return sofar;
155 }
156 } else {
157 NaClLog(4, "no seek required\n");
158 }
159 NaClLog(4, " cur_window 0x%"NACL_PRIxPTR"\n",
160 (uintptr_t) self->cur_window);
161 NaClLog(4, " io_offset 0x%"NACL_PRIxS"\n", self->io_offset);
162 NaClLog(4, "window_offset 0x%"NACL_PRIxS"\n", self->window_offset);
163
164 CHECK(self->window_offset <= self->io_offset);
165 CHECK(self->io_offset < self->window_offset + self->window_size);
166
167 transfer = count;
168 window_end = self->window_offset + self->window_size;
169 if (window_end > self->shm_sz) {
170 window_end = self->shm_sz;
171 }
172 window_remain = window_end - self->io_offset;
173
174 NaClLog(4, "remaining in window 0x%"NACL_PRIxS"\n", window_remain);
175
176 CHECK(window_remain <= GIO_SHM_WINDOWSIZE);
177
178 if (transfer > window_remain) {
179 transfer = window_remain;
180 }
181
182 NaClLog(4, "transfer 0x%"NACL_PRIxS"\n", transfer);
183
184 if (is_write) {
185 NaClLog(4,
186 ("about to \"write\" memcpy(0x%"NACL_PRIxPTR", "
187 " 0x%"NACL_PRIxPTR", 0x%"NACL_PRIxS" bytes)\n"),
188 (uintptr_t) (self->cur_window
189 + (self->io_offset - self->window_offset)),
190 (uintptr_t) buf,
191 transfer);
192
193 memcpy(self->cur_window + (self->io_offset - self->window_offset),
194 buf,
195 transfer);
196 } else {
197 NaClLog(4,
198 ("about to \"read\" memcpy(0x%"NACL_PRIxPTR", "
199 " 0x%"NACL_PRIxPTR", 0x%"NACL_PRIxS" bytes)\n"),
200 (uintptr_t) buf,
201 (uintptr_t) (self->cur_window
202 + (self->io_offset - self->window_offset)),
203 transfer);
204
205 memcpy(buf,
206 self->cur_window + (self->io_offset - self->window_offset),
207 transfer);
208 }
209 self->io_offset += transfer;
210 sofar += transfer;
211
212 buf = (void *)((uintptr_t) buf + transfer);
213 count -= transfer;
214 }
215
216 return sofar;
217 }
218
219 static ssize_t NaClGioShmRead(struct Gio *vself,
220 void *buf,
221 size_t count) {
222 return NaClGioShmReadOrWrite(vself, buf, count, 0);
223 }
224
225 static ssize_t NaClGioShmWrite(struct Gio *vself,
226 const void *buf,
227 size_t count) {
228 return NaClGioShmReadOrWrite(vself, (void *) buf, count, 1);
229 }
230
231 static off_t NaClGioShmSeek(struct Gio *vself,
232 off_t offset,
233 int whence) {
234 struct NaClGioShm *self = (struct NaClGioShm *) vself;
235 size_t new_pos = (size_t) -1;
236
237 NaClLog(4, "NaClGioShmSeek(0x%"NACL_PRIxPTR", %ld (0x%lx), %d)\n",
238 (uintptr_t) vself, (long) offset, (long) offset, whence);
239 /*
240 * Note that if sizeof(new_pos) < sizeof(offset), we are dropping
241 * high-order bits and we do not detect this. However, the check
242 * after the switch keeps the values somewhat sane: we will never
243 * set the I/O offset to be outside the range [0, self->shm_sz].
244 */
245 switch (whence) {
246 case SEEK_SET:
247 new_pos = (size_t) offset;
248 break;
249 case SEEK_CUR:
250 new_pos = self->io_offset + offset;
251 break;
252 case SEEK_END:
253 new_pos = self->shm_sz + offset;
254 break;
255 }
256 /* allow equality, so setting to the end of file is okay */
257 if (self->shm_sz < new_pos) {
258 NaClLog(4, " invalid offset\n");
259 errno = EINVAL;
260 return -1;
261 }
262 NaClLog(4, " setting to %ld (0x%lx)\n", (long) new_pos, (long) new_pos);
263 /* sizeof(off_t) >= sizeof(size_t) */
264 self->io_offset = new_pos;
265 return (off_t) self->io_offset;
266 }
267
268 static int NaClGioShmFlush(struct Gio *vself) {
269 UNREFERENCED_PARAMETER(vself);
270 return 0;
271 }
272
273 static int NaClGioShmClose(struct Gio *vself) {
274 struct NaClGioShm *self = (struct NaClGioShm *) vself;
275
276 if (NULL != self->cur_window) {
277 NaClDescUnmapUnsafe(self->shmp, (void *) self->cur_window,
278 NACL_MAP_PAGESIZE);
279 }
280 self->cur_window = NULL;
281
282 if (NULL == self->shmp) {
283 NaClLog(LOG_ERROR, "NaClGioShmClose: double close detected\n");
284 errno = EIO;
285 return -1;
286 }
287
288 NaClDescUnref(self->shmp);
289 self->shmp = NULL; /* double close will fault */
290 return 0;
291 }
292
293 static void NaClGioShmDtor(struct Gio *vself) {
294 struct NaClGioShm *self = (struct NaClGioShm *) vself;
295
296 /*
297 * Users of Gio objects are expected to Close then Dtor, but Dtor
298 * should cleanup regardless.
299 */
300 if (NULL != self->shmp) {
301 if (-1 == (*vself->vtbl->Close)(vself)) {
302 NaClLog(LOG_ERROR, "NaClGioShmDtor: auto Close failed!\n");
303 }
304 }
305
306 self->shmp = NULL;
307 self->base.vtbl = NULL;
308 }
309
310 const struct GioVtbl kNaClGioShmVtbl = {
311 NaClGioShmDtor,
312 NaClGioShmRead,
313 NaClGioShmWrite,
314 NaClGioShmSeek,
315 NaClGioShmFlush,
316 NaClGioShmClose,
317 };
318
319
320 static int NaClGioShmCtorIntern(struct NaClGioShm *self,
321 struct NaClDesc *shmp,
322 size_t shm_size) {
323 struct nacl_abi_stat stbuf;
324 int vfret;
325 int rval = 0;
326
327 self->base.vtbl = NULL;
328
329 self->shmp = NULL;
330 self->cur_window = NULL;
331
332 if (0 != (vfret = (*((struct NaClDescVtbl const *) shmp->base.vtbl)->
333 Fstat)(shmp, &stbuf))) {
334 NaClLog(1, "NaClGioShmCtorIntern: Fstat virtual function returned %d\n",
335 vfret);
336 goto cleanup;
337 }
338 /*
339 * nacl_abi_off_t is signed 32-bit quantity, but we don't want to
340 * hardwire in that knowledge here.
341 *
342 * size_t is unsigned, and may be 32-bits or 64-bits, depending on
343 * the underlying host OS.
344 *
345 * we want to ensure that the shm's size, as reported by the desc
346 * abstraction and thus is in nacl_abi_off_t, is at least that
347 * claimed by the ctor argument. so, if (as Integers)
348 *
349 * stbuf.nacl_abi_st_size < shm_size
350 *
351 * holds, this is an error. however, the value-preserving cast rule
352 * makes this harder.
353 *
354 * Note that for signed sizes (ssize_t), the kernel ABI generally
355 * only reserve -1 for error, and asking for an I/O operation via a
356 * size_t that would succeed but yield a ssize_t return value that
357 * is negative is okay, since -1 is never valid as an I/O size on a
358 * von Neuman machine (except for a writev where the iov entries
359 * overlap): there just isn't that much data to read/write, when the
360 * instructions also take up space in the process address space.
361 * Whether requiring the programmer to detect this corner case is
362 * advisable is a different argument -- similar to negative ssize_t
363 * sizes, the syscall can just succeed with a partial transfer to
364 * avoid returning -1 on a success, just as we could avoid returning
365 * negative values; in practice, we do the latter, since we often
366 * see code written that tests for syscall error by comparing the
367 * return value to see if it is less than zero, rather than if it is
368 * equal to -1.
369 */
370 if (stbuf.nacl_abi_st_size < 0) {
371 NaClLog(LOG_ERROR, "NaClGioShmCtorIntern: actual shm size negative\n");
372 goto cleanup;
373 }
374 if (stbuf.nacl_abi_st_size <= (nacl_abi_off_t) SIZE_T_MAX
375 && (size_t) stbuf.nacl_abi_st_size < shm_size) {
376 NaClLog(LOG_ERROR,
377 "NaClGioShmCtorIntern: claimed shm file size greater than"
378 " actual shm segment size\n");
379 goto cleanup;
380 }
381 if (OFF_T_MAX < SIZE_T_MAX && (size_t) OFF_T_MAX < shm_size) {
382 NaClLog(LOG_ERROR,
383 ("NaClGioShmCtorIntern: claimed shm file size greater than"
384 " off_t max value, %"NACL_PRId64"\n"),
385 (int64_t) OFF_T_MAX);
386 goto cleanup;
387 }
388
389 self->shmp = NaClDescRef(shmp);
390
391 self->io_offset = 0;
392 self->shm_sz = shm_size;
393 self->window_offset = 0;
394
395 self->base.vtbl = &kNaClGioShmVtbl;
396
397 if (!NaClGioShmSetWindow(self, 0)) {
398 NaClLog(LOG_ERROR,
399 ("NaClGioShmCtorIntern: initial seek to beginning failed\n"));
400 NaClDescUnref(self->shmp);
401 self->shmp = NULL;
402 self->shm_sz = 0;
403 self->base.vtbl = NULL;
404 goto cleanup;
405 }
406
407 rval = 1;
408 cleanup:
409 return rval;
410 }
411
412 int NaClGioShmCtor(struct NaClGioShm *self,
413 struct NaClDesc *shmp,
414 size_t shm_size) {
415
416 int rv;
417
418 CHECK(shm_size == NaClRoundAllocPage(shm_size));
419
420 rv = NaClGioShmCtorIntern(self, shmp, shm_size);
421
422 return rv;
423 }
424
425 int NaClGioShmAllocCtor(struct NaClGioShm *self,
426 size_t shm_size) {
427 struct NaClDescImcShm *shmp;
428 int rv;
429
430 CHECK(shm_size == NaClRoundAllocPage(shm_size));
431
432 shmp = malloc(sizeof *shmp);
433 if (NULL == shmp) {
434 return 0;
435 }
436 if (!NaClDescImcShmAllocCtor(shmp, shm_size, /* executable= */ 0)) {
437 free(shmp);
438 return 0;
439 }
440
441 rv = NaClGioShmCtorIntern(self, (struct NaClDesc *) shmp, shm_size);
442 NaClDescUnref((struct NaClDesc *) shmp);
443
444 if (!rv) {
445 free(shmp);
446 }
447 return rv;
448 }
OLDNEW
« no previous file with comments | « src/trusted/gio/gio_shm.h ('k') | src/trusted/gio/gio_shm_test.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698