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

Side by Side Diff: native_client_sdk/src/libraries/nacl_io/kernel_wrap_irt_ext.c

Issue 608913003: Added support for NaCl IO to use the IRT Extension API. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Reordered functions, routed mprotect to irt version. Created 6 years, 2 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
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2014 The Native Client Authors. All rights reserved.
binji 2014/10/02 17:54:34 Chromium authors. Copy this from one of the other
David Yen 2014/10/02 18:23:49 Done.
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 /* NACL_IO_IRT_EXT is defined in this header */
8 #include "nacl_io/kernel_wrap.h"
9
10 /*
11 * The entire file is wrapped in this #if. We do this so this .c file can
12 * always be compiled.
13 */
14 #if defined(NACL_IO_IRT_EXT)
15
16 #include <assert.h>
17 #include <errno.h>
18 #include <stdbool.h>
19 #include <string.h>
20 #include <sys/mman.h>
21
22 #include "nacl_io/kernel_intercept.h"
23 #include "nacl_io/log.h"
24 #include "native_client/src/untrusted/irt/irt.h"
25 #include "native_client/src/untrusted/irt/irt_dev.h"
26 #include "native_client/src/untrusted/irt/irt_extension.h"
27
28 /*
29 * The following macros are used to interfact with IRT interfaces.
30 */
31 /* This macro defines an interfact structure, use as a regular type. */
32 #define NACL_IRT_INTERFACE(interface_type) \
33 struct nacl_io_##interface_type { \
34 bool initialized; \
35 const char *query_string; \
36 struct interface_type interface; \
37 }
38
39 /* This macro unconditionally initializes an interface (do not use directly). */
40 #define INIT_INTERFACE_BARE(interface_struct) \
41 do { \
42 const size_t bytes __attribute__((unused)) = \
43 nacl_interface_query(interface_struct.query_string, \
44 &interface_struct.interface, \
45 sizeof(interface_struct.interface)); \
46 interface_struct.initialized = \
47 (bytes == sizeof(interface_struct.interface)); \
48 } while (false)
49
50 /* This macro initializes an interface and does not handle errors. */
51 #define INIT_INTERFACE(interface_struct) \
52 if (!interface_struct.initialized) { \
53 INIT_INTERFACE_BARE(interface_struct); \
54 }
55
56 /* This macro initializes an interface and returns ENOSYS on failure. */
57 #define INIT_INTERFACE_ENOSYS(interface_struct) \
58 if (!interface_struct.initialized) { \
59 INIT_INTERFACE_BARE(interface_struct); \
60 if (!interface_struct.initialized) \
61 return ENOSYS; \
62 }
63
64 /* This macro initializes an interface and asserts on failure. */
65 #define INIT_INTERFACE_ASSERT(interface_struct) \
66 if (!interface_struct.initialized) { \
67 INIT_INTERFACE_BARE(interface_struct); \
68 assert(interface.initialized); \
69 }
70
71 /* This macro supplies an IRT Extension interface and asserts on failure. */
72 #define EXT_SUPPLY_INTERFACE_ASSERT(interface_struct, supplied_struct) \
73 do { \
74 const size_t bytes __attribute__((unused)) = \
75 nacl_interface_ext_supply(interface_struct.query_string, \
76 &supplied_struct, \
77 sizeof(supplied_struct)); \
78 assert(bytes == sizeof(supplied_struct)); \
79 } while (false)
80
81 /*
82 * IRT interfaces as declared in irt.h.
83 */
84 static NACL_IRT_INTERFACE(nacl_irt_basic) s_irt_basic = {
85 false,
binji 2014/10/02 17:54:34 this looks strange. Maybe reorder the fields above
David Yen 2014/10/02 18:23:49 Done.
86 NACL_IRT_BASIC_v0_1,
87 };
88
89 static NACL_IRT_INTERFACE(nacl_irt_fdio) s_irt_fdio = {
90 false,
91 NACL_IRT_FDIO_v0_1,
92 };
93
94 static NACL_IRT_INTERFACE(nacl_irt_memory) s_irt_memory = {
95 false,
96 NACL_IRT_MEMORY_v0_3,
97 };
98
99 static NACL_IRT_INTERFACE(nacl_irt_resource_open) s_irt_resource_open = {
100 false,
101 NACL_IRT_RESOURCE_OPEN_v0_1,
102 };
103
104 /*
105 * IRT Dev interfaces as declared in irt_dev.h.
106 */
107 static NACL_IRT_INTERFACE(nacl_irt_dev_fdio) s_irt_dev_fdio = {
108 false,
109 NACL_IRT_DEV_FDIO_v0_3,
110 };
111
112 static NACL_IRT_INTERFACE(nacl_irt_dev_filename) s_irt_dev_filename = {
113 false,
114 NACL_IRT_DEV_FILENAME_v0_3,
115 };
116
117 static bool s_wrapped = false;
118
119 /*
120 * Functions for the nacl_irt_dev_fdio interface.
121 */
122 static int ext_close(int fd) {
123 ERRNO_RTN(ki_close(fd));
124 }
125
126 static int ext_dup(int fd, int *newfd) {
127 *newfd = ki_dup(fd);
128 ERRNO_RTN(*newfd);
129 }
130
131 static int ext_dup2(int fd, int newfd) {
132 newfd = ki_dup2(fd, newfd);
133 ERRNO_RTN(newfd);
134 }
135
136 static int ext_read(int fd, void *buf, size_t count, size_t *nread) {
137 ssize_t signed_nread = ki_read(fd, buf, count);
138 *nread = (size_t) signed_nread;
139 ERRNO_RTN(signed_nread);
140 }
141
142 static int ext_write(int fd, const void *buf, size_t count, size_t *nwrote) {
143 ssize_t signed_nwrote = ki_write(fd, buf, count);
144 *nwrote = (size_t) signed_nwrote;
145 ERRNO_RTN(signed_nwrote);
146 }
147
148 static int ext_seek(int fd, nacl_irt_off_t offset, int whence,
149 nacl_irt_off_t *new_offset) {
150 *new_offset = ki_lseek(fd, offset, whence);
151 ERRNO_RTN(*new_offset);
152 }
153
154 static int ext_fstat(int fd, struct stat *buf) {
155 ERRNO_RTN(ki_fstat(fd, buf));
156 }
157
158 static int ext_getdents(int fd, struct dirent *ents, size_t count,
159 size_t *nread) {
160 int rtn = ki_getdents(fd, ents, count);
161 RTN_ERRNO_IF(rtn < 0);
162 *nread = rtn;
163 return 0;
164 }
165
166 /*
167 * Functions for the nacl_irt_memory interface.
168 */
169 static int ext_mmap(void **addr, size_t len, int prot, int flags, int fd,
170 nacl_irt_off_t off) {
171 if (flags & MAP_ANONYMOUS)
172 return s_irt_memory.interface.mmap(addr, len, prot, flags, fd, off);
binji 2014/10/02 17:54:34 nit: this is a bit clearer in kernel_wrap_newlib,
David Yen 2014/10/02 18:23:49 The newlib version just uses pointers so this one
173
174 *addr = ki_mmap(*addr, len, prot, flags, fd, off);
175 RTN_ERRNO_IF(*addr == (void*)-1);
176 return 0;
177 }
178
179 static int ext_munmap(void *addr, size_t length) {
180 /*
181 * Always let the real munmap run on the address range. It is not an error if
182 * there are no mapped pages in that range.
183 */
184 ki_munmap(addr, length);
185 return s_irt_memory.interface.munmap(addr, length);
186 }
187
188 /*
189 * Extra functions for the nacl_irt_dev_fdio interface.
190 */
191 static int ext_fchdir(int fd) {
192 ERRNO_RTN(ki_fchdir(fd));
193 }
194
195 static int ext_fchmod(int fd, mode_t mode) {
196 ERRNO_RTN(ki_fchmod(fd, mode));
197 }
198
199 static int ext_fsync(int fd) {
200 ERRNO_RTN(ki_fsync(fd));
201 }
202
203 static int ext_fdatasync(int fd) {
204 ERRNO_RTN(ki_fdatasync(fd));
205 }
206
207 static int ext_ftruncate(int fd, nacl_irt_off_t length) {
208 ERRNO_RTN(ki_ftruncate(fd, length));
209 }
210
211 static int ext_isatty(int fd, int *result) {
212 *result = ki_isatty(fd);
213 RTN_ERRNO_IF(*result == 0);
214 return 0;
215 }
216
217 /*
218 * Functions for the nacl_irt_dev_filename interface.
219 */
220 static int ext_open(const char *pathname, int oflag, mode_t cmode, int *newfd) {
221 *newfd = ki_open(pathname, oflag, cmode);
222 ERRNO_RTN(*newfd);
223 }
224
225 static int ext_stat(const char *pathname, struct stat *buf) {
226 ERRNO_RTN(ki_stat(pathname, buf));
227 }
228
229 static int ext_mkdir(const char *pathname, mode_t mode) {
230 ERRNO_RTN(ki_mkdir(pathname, mode));
231 }
232
233 static int ext_rmdir(const char *pathname) {
234 ERRNO_RTN(ki_rmdir(pathname));
235 }
236
237 static int ext_chdir(const char *pathname) {
238 ERRNO_RTN(ki_chdir(pathname));
239 }
240
241 static int ext_getcwd(char *pathname, size_t len) {
242 char *rtn = ki_getcwd(pathname, len);
243 RTN_ERRNO_IF(NULL == rtn);
244 return 0;
245 }
246
247 static int ext_unlink(const char *pathname) {
248 ERRNO_RTN(ki_unlink(pathname));
249 }
250
251 static int ext_truncate(const char *pathname, nacl_irt_off_t length) {
252 ERRNO_RTN(ki_truncate(pathname, length));
253 }
254
255 static int ext_lstat(const char *pathname, struct stat *buf) {
256 ERRNO_RTN(ki_lstat(pathname, buf));
257 }
258
259 static int ext_link(const char *pathname, const char *newpath) {
260 ERRNO_RTN(ki_link(pathname, newpath));
261 }
262
263 static int ext_rename(const char *pathname, const char *newpath) {
264 ERRNO_RTN(ki_rename(pathname, newpath));
265 }
266
267 static int ext_symlink(const char *pathname, const char *newpath) {
268 ERRNO_RTN(ki_symlink(pathname, newpath));
269 }
270
271 static int ext_chmod(const char *pathname, mode_t mode) {
272 ERRNO_RTN(ki_chmod(pathname, mode));
273 }
274
275 static int ext_access(const char *pathname, int amode) {
276 ERRNO_RTN(ki_access(pathname, amode));
277 }
278
279 static int ext_readlink(const char *pathname, char *buf, size_t count,
280 size_t *nread) {
281 int rtn = ki_readlink(pathname, buf, count);
282 RTN_ERRNO_IF(rtn < 0);
283 *nread = rtn;
284 return 0;
285 }
286
287 static int ext_utimes(const char *pathname, const struct timeval *times) {
288 ERRNO_RTN(ki_utimes(pathname, times));
289 }
290
291 /*
292 * Functions declared inside of kernel_wrap_real.h.
293 */
294
295 int _real_close(int fd) {
296 INIT_INTERFACE_ENOSYS(s_irt_fdio);
297 return s_irt_fdio.interface.close(fd);
298 }
299
300 void _real_exit(int status) {
301 INIT_INTERFACE_ASSERT(s_irt_basic);
302 return s_irt_basic.interface.exit(status);
303 }
304
305 int _real_fstat(int fd, struct stat *buf) {
306 INIT_INTERFACE_ENOSYS(s_irt_fdio);
307 return s_irt_fdio.interface.fstat(fd, buf);
308 }
309
310 int _real_getdents(int fd, void *nacl_buf, size_t nacl_count, size_t *nread) {
311 INIT_INTERFACE_ENOSYS(s_irt_fdio);
312 return s_irt_fdio.interface.getdents(fd, (struct dirent *) nacl_buf,
313 nacl_count, nread);
314 }
315
316 int _real_isatty(int fd, int *result) {
317 INIT_INTERFACE_ENOSYS(s_irt_dev_fdio);
318 return s_irt_dev_fdio.interface.isatty(fd, result);
319 }
320
321 int _real_lseek(int fd, int64_t offset, int whence, int64_t *new_offset) {
322 INIT_INTERFACE_ENOSYS(s_irt_fdio);
323 return s_irt_fdio.interface.seek(fd, offset, whence, new_offset);
324 }
325
326 int _real_mkdir(const char *pathname, mode_t mode) {
327 INIT_INTERFACE_ENOSYS(s_irt_dev_filename);
328 return s_irt_dev_filename.interface.mkdir(pathname, mode);
329 }
330
331 int _real_mmap(void **addr,
332 size_t length,
333 int prot,
334 int flags,
335 int fd,
336 int64_t offset) {
337 INIT_INTERFACE_ENOSYS(s_irt_memory);
338 return s_irt_memory.interface.mmap(addr, length, prot, flags, fd, offset);
339 }
340
341 int _real_munmap(void *addr, size_t length) {
342 INIT_INTERFACE_ENOSYS(s_irt_memory);
343 return s_irt_memory.interface.munmap(addr, length);
344 }
345
346 int _real_open(const char *pathname, int oflag, mode_t mode, int *newfd) {
347 INIT_INTERFACE_ENOSYS(s_irt_dev_filename);
348 return s_irt_dev_filename.interface.open(pathname, oflag, mode, newfd);
349 }
350
351 int _real_open_resource(const char *file, int *fd) {
352 INIT_INTERFACE_ENOSYS(s_irt_resource_open);
353 return s_irt_resource_open.interface.open_resource(file, fd);
354 }
355
356 int _real_read(int fd, void *buf, size_t count, size_t *nread) {
357 INIT_INTERFACE_ENOSYS(s_irt_fdio);
358 return s_irt_fdio.interface.read(fd, buf, count, nread);
359 }
360
361 int _real_rmdir(const char *pathname) {
362 INIT_INTERFACE_ENOSYS(s_irt_dev_filename);
363 return s_irt_dev_filename.interface.rmdir(pathname);
364 }
365
366 int _real_write(int fd, const void *buf, size_t count, size_t *nwrote) {
367 INIT_INTERFACE_ENOSYS(s_irt_fdio);
368 return s_irt_fdio.interface.write(fd, buf, count, nwrote);
369 }
370
371 int _real_getcwd(char *pathname, size_t len) {
372 INIT_INTERFACE_ENOSYS(s_irt_dev_filename);
373 return s_irt_dev_filename.interface.getcwd(pathname, len);
374 }
375
376 /*
377 * Kernel Wrap init/uninit functions declared in kernel_wrap.h.
378 */
379 void kernel_wrap_init() {
380 if (!s_wrapped) {
381 LOG_TRACE("kernel_wrap_init");
382
383 /*
384 * Register interfaces as listed in irt.h.
385 */
386
387 /* Register nacl_irt_basic interface. */
388 INIT_INTERFACE_ASSERT(s_irt_basic);
389 struct nacl_irt_basic basic_calls = {
390 ki_exit,
391 s_irt_basic.interface.gettod,
392 s_irt_basic.interface.clock,
393 s_irt_basic.interface.nanosleep,
394 s_irt_basic.interface.sched_yield,
395 s_irt_basic.interface.sysconf,
396 };
397 EXT_SUPPLY_INTERFACE_ASSERT(s_irt_basic, basic_calls);
398
399 /* Register nacl_irt_fdio interface. */
400 struct nacl_irt_fdio fdio = {
401 ext_close,
402 ext_dup,
403 ext_dup2,
404 ext_read,
405 ext_write,
406 ext_seek,
407 ext_fstat,
408 ext_getdents,
409 };
410 EXT_SUPPLY_INTERFACE_ASSERT(s_irt_fdio, fdio);
411
412 /* Register nacl_irt_memory interface. */
413 INIT_INTERFACE_ASSERT(s_irt_memory);
414 struct nacl_irt_memory mem = {
415 ext_mmap,
416 ext_munmap,
417 s_irt_memory.interface.mprotect,
418 };
419 EXT_SUPPLY_INTERFACE_ASSERT(s_irt_memory, mem);
420
421 /*
422 * Register interfaces as listed in irt_dev.h.
423 */
424
425 /* Register nacl_irt_dev_fdio interface. */
426 struct nacl_irt_dev_fdio dev_fdio = {
427 ext_close,
428 ext_dup,
429 ext_dup2,
430 ext_read,
431 ext_write,
432 ext_seek,
433 ext_fstat,
434 ext_getdents,
435 ext_fchdir,
436 ext_fchmod,
437 ext_fsync,
438 ext_fdatasync,
439 ext_ftruncate,
440 ext_isatty,
441 };
442 EXT_SUPPLY_INTERFACE_ASSERT(s_irt_dev_fdio, dev_fdio);
443
444 /* Register nacl_irt_dev_filename interface. */
445 struct nacl_irt_dev_filename dev_filename = {
446 ext_open,
447 ext_stat,
448 ext_mkdir,
449 ext_rmdir,
450 ext_chdir,
451 ext_getcwd,
452 ext_unlink,
453 ext_truncate,
454 ext_lstat,
455 ext_link,
456 ext_rename,
457 ext_symlink,
458 ext_chmod,
459 ext_access,
460 ext_readlink,
461 ext_utimes,
462 };
463 EXT_SUPPLY_INTERFACE_ASSERT(s_irt_dev_filename, dev_filename);
464
465 s_wrapped = true;
466 }
467 }
468
469 void kernel_wrap_uninit() {
470 if (s_wrapped) {
471 LOG_TRACE("kernel_wrap_uninit");
472
473 /* Register original IRT interfaces in irt.h. */
474 INIT_INTERFACE_ASSERT(s_irt_basic);
475 EXT_SUPPLY_INTERFACE_ASSERT(s_irt_basic, s_irt_basic.interface);
476
477 INIT_INTERFACE_ASSERT(s_irt_fdio);
478 EXT_SUPPLY_INTERFACE_ASSERT(s_irt_fdio, s_irt_fdio.interface);
479
480 INIT_INTERFACE_ASSERT(s_irt_memory);
481 EXT_SUPPLY_INTERFACE_ASSERT(s_irt_memory, s_irt_memory.interface);
482
483 /*
484 * Register optional original IRT dev interfaces in irt_dev.h, these
485 * may or may not exist (for example irt_fdio exists in PNaCl but not
486 * irt_dev_fdio), but if they do not exist go ahead and supply an
487 * empty interface as that's what they should be now.
488 */
489 INIT_INTERFACE(s_irt_dev_fdio);
490 EXT_SUPPLY_INTERFACE_ASSERT(s_irt_dev_fdio,
binji 2014/10/02 17:54:34 should this not assert if the interface doesn't ex
David Yen 2014/10/02 18:23:49 The details of this case is a bit tricky, we will
491 s_irt_dev_fdio.interface);
492
493 INIT_INTERFACE(s_irt_dev_filename);
494 EXT_SUPPLY_INTERFACE_ASSERT(s_irt_dev_filename,
495 s_irt_dev_filename.interface);
496
497 s_wrapped = false;
498 }
499 }
500
501 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698