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

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

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

Powered by Google App Engine
This is Rietveld 408576698