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

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

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: Changed assert checks to a macro 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 // Copyright (c) 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
Sam Clegg 2014/09/30 20:49:03 You're not going to like this but... do you think
David Yen 2014/09/30 21:37:36 Okay, I will do this as separate patches so as to
David Yen 2014/10/01 20:01:44 Done.
3 // found in the LICENSE file.
4
5 #include <sys/types.h> // Include something that will define __GLIBC__.
6 #include "nacl_io/kernel_wrap.h" // IRT_EXT is turned on in this header.
7
8 // The entire file is wrapped in this #if. We do this so this .cc file can
9 // always be compiled.
10 #if defined(__NACL_IO_IRT_EXT__)
11
12 #include <errno.h>
13 #include <string.h>
14 #include <sys/mman.h>
15
16 #include "nacl_io/kernel_intercept.h"
17 #include "nacl_io/log.h"
18 #include "native_client/src/untrusted/irt/irt.h"
19 #include "native_client/src/untrusted/irt/irt_dev.h"
20 #include "native_client/src/untrusted/irt/irt_extension.h"
21
22 #define CHECK_CALL(call) \
23 do { \
24 const bool ret = call; \
25 (void) ret; \
Sam Clegg 2014/09/30 20:49:03 Use __attribute__ unused?
David Yen 2014/09/30 21:37:36 Done.
26 assert(ret); \
27 } while(false)
28
29 template<typename T>
30 struct nacl_irt_interface {
31 bool initialized;
32 const char* query_string;
33 T interface;
34
35 nacl_irt_interface(const char* query)
36 : initialized(false),
37 query_string(query) {
38 memset(&interface, 0, sizeof(interface));
39 }
40
41 bool Initialized() const {
42 return initialized;
43 }
44
45 bool Initialize() {
46 if (Initialized())
47 return true;
48
49 size_t bytes = nacl_interface_query(query_string,
50 &interface,
51 sizeof(interface));
52 initialized = (bytes == sizeof(interface));
53 return initialized;
54 }
55
56 bool IRTExtSupply(const T& new_interface) const {
57 size_t bytes = nacl_interface_ext_supply(query_string,
58 &new_interface,
59 sizeof(new_interface));
60 return (bytes == sizeof(interface));
61 }
62
63 bool RevertIRTExtSupply(bool force_revert = false) {
64 if (!Initialize() && !force_revert)
65 return false;
66
67 size_t bytes = nacl_interface_ext_supply(query_string,
68 &interface,
69 sizeof(interface));
70 return (bytes == sizeof(interface));
71 }
72 };
73
74 // IRT interfaces as declared in irt.h.
75 static nacl_irt_interface<nacl_irt_basic> s_irt_basic(NACL_IRT_BASIC_v0_1);
76 static nacl_irt_interface<nacl_irt_fdio> s_irt_fdio(NACL_IRT_FDIO_v0_1);
77 static nacl_irt_interface<nacl_irt_memory> s_irt_memory(NACL_IRT_MEMORY_v0_3);
78 static nacl_irt_interface<nacl_irt_resource_open> s_irt_resource_open(
79 NACL_IRT_RESOURCE_OPEN_v0_1);
80
81 // IRT Dev interfaces as declared in irt_dev.h.
82 static nacl_irt_interface<nacl_irt_dev_fdio> s_irt_dev_fdio(
83 NACL_IRT_DEV_FDIO_v0_3);
84 static nacl_irt_interface<nacl_irt_dev_filename> s_irt_dev_filename(
85 NACL_IRT_DEV_FILENAME_v0_3);
86
87 static bool s_wrapped = false;
88
89 // Functions for the nacl_irt_dev_fdio interface.
90 static int ext_close(int fd) {
91 ERRNO_RTN(ki_close(fd));
92 }
93
94 static int ext_dup(int fd, int *newfd) {
95 *newfd = ki_dup(fd);
96 ERRNO_RTN(*newfd);
97 }
98
99 static int ext_dup2(int fd, int newfd) {
100 newfd = ki_dup2(fd, newfd);
101 ERRNO_RTN(newfd);
102 }
103
104 static int ext_read(int fd, void *buf, size_t count, size_t *nread) {
105 ssize_t signed_nread = ki_read(fd, buf, count);
106 *nread = static_cast<size_t>(signed_nread);
107 ERRNO_RTN(signed_nread);
108 }
109
110 static int ext_write(int fd, const void *buf, size_t count, size_t *nwrote) {
111 ssize_t signed_nwrote = ki_write(fd, buf, count);
112 *nwrote = static_cast<size_t>(signed_nwrote);
113 ERRNO_RTN(signed_nwrote);
114 }
115
116 static int ext_seek(int fd, nacl_irt_off_t offset, int whence,
117 nacl_irt_off_t *new_offset) {
118 *new_offset = ki_lseek(fd, offset, whence);
119 ERRNO_RTN(*new_offset);
120 }
121
122 static int ext_fstat(int fd, struct stat *buf) {
123 ERRNO_RTN(ki_fstat(fd, buf));
124 }
125
126 static int ext_getdents(int fd, struct dirent *ents, size_t count,
127 size_t *nread) {
128 int rtn = ki_getdents(fd, ents, count);
129 RTN_ERRNO_IF(rtn < 0);
130 *nread = rtn;
131 return 0;
132 }
133
134 // Functions for the nacl_irt_memory interface.
135 static int ext_mmap(void **addr, size_t len, int prot, int flags, int fd,
136 nacl_irt_off_t off) {
137 if (flags & MAP_ANONYMOUS)
138 return s_irt_memory.interface.mmap(addr, len, prot, flags, fd, off);
139
140 *addr = ki_mmap(*addr, len, prot, flags, fd, off);
141 RTN_ERRNO_IF(*addr == (void*)-1);
142 return 0;
143 }
144
145 // Extra functions for the nacl_irt_fdio interface.
146 static int ext_fchdir(int fd) {
147 ERRNO_RTN(ki_fchdir(fd));
148 }
149
150 static int ext_fchmod(int fd, mode_t mode) {
151 ERRNO_RTN(ki_fchmod(fd, mode));
152 }
153
154 static int ext_fsync(int fd) {
155 ERRNO_RTN(ki_fsync(fd));
156 }
157
158 static int ext_fdatasync(int fd) {
159 ERRNO_RTN(ki_fdatasync(fd));
160 }
161
162 static int ext_ftruncate(int fd, nacl_irt_off_t length) {
163 ERRNO_RTN(ki_ftruncate(fd, length));
164 }
165
166 static int ext_isatty(int fd, int *result) {
167 *result = ki_isatty(fd);
168 RTN_ERRNO_IF(*result == 0);
169 return 0;
170 }
171
172 static int ext_munmap(void *addr, size_t length) {
173 // Always let the real munmap run on the address range. It is not an error if
174 // there are no mapped pages in that range.
175 ki_munmap(addr, length);
176 return s_irt_memory.interface.munmap(addr, length);
177 }
178
179 static int ext_mprotect(void *addr, size_t len, int prot) {
180 return ENOSYS;
181 }
182
183 // Functions for the nacl_irt_dev_filename interface.
184 static int ext_open(const char *pathname, int oflag, mode_t cmode, int *newfd) {
185 *newfd = ki_open(pathname, oflag, cmode);
186 ERRNO_RTN(*newfd);
187 }
188
189 static int ext_stat(const char *pathname, struct stat *buf) {
190 ERRNO_RTN(ki_stat(pathname, buf));
191 }
192
193 static int ext_mkdir(const char *pathname, mode_t mode) {
194 ERRNO_RTN(ki_mkdir(pathname, mode));
195 }
196
197 static int ext_rmdir(const char *pathname) {
198 ERRNO_RTN(ki_rmdir(pathname));
199 }
200
201 static int ext_chdir(const char *pathname) {
202 ERRNO_RTN(ki_chdir(pathname));
203 }
204
205 static int ext_getcwd(char *pathname, size_t len) {
206 char* rtn = ki_getcwd(pathname, len);
207 RTN_ERRNO_IF(NULL == rtn);
208 return 0;
209 }
210
211 static int ext_unlink(const char *pathname) {
212 ERRNO_RTN(ki_unlink(pathname));
213 }
214
215 static int ext_truncate(const char *pathname, nacl_irt_off_t length) {
216 ERRNO_RTN(ki_truncate(pathname, length));
217 }
218
219 static int ext_lstat(const char *pathname, struct stat *buf) {
220 ERRNO_RTN(ki_lstat(pathname, buf));
221 }
222
223 static int ext_link(const char *pathname, const char *newpath) {
224 ERRNO_RTN(ki_link(pathname, newpath));
225 }
226
227 static int ext_rename(const char *pathname, const char *newpath) {
228 ERRNO_RTN(ki_rename(pathname, newpath));
229 }
230
231 static int ext_symlink(const char *pathname, const char *newpath) {
232 ERRNO_RTN(ki_symlink(pathname, newpath));
233 }
234
235 static int ext_chmod(const char *pathname, mode_t mode) {
236 ERRNO_RTN(ki_chmod(pathname, mode));
237 }
238
239 static int ext_access(const char *pathname, int amode) {
240 ERRNO_RTN(ki_access(pathname, amode));
241 }
242
243 static int ext_readlink(const char *pathname, char *buf, size_t count,
244 size_t *nread) {
245 int rtn = ki_readlink(pathname, buf, count);
246 RTN_ERRNO_IF(rtn < 0);
247 *nread = rtn;
248 return 0;
249 }
250
251 static int ext_utimes(const char *pathname, const struct timeval *times) {
252 ERRNO_RTN(ki_utimes(pathname, times));
253 }
254
255 // Functions declared inside of kernel_wrap_real.h.
256 EXTERN_C_BEGIN
257
258 int _real_close(int fd) {
259 if (!s_irt_fdio.Initialize())
260 return ENOSYS;
261 return s_irt_fdio.interface.close(fd);
262 }
263
264 void _real_exit(int status) {
265 CHECK_CALL(s_irt_basic.Initialize());
266 return s_irt_basic.interface.exit(status);
267 }
268
269 int _real_fstat(int fd, struct stat* buf) {
270 if (!s_irt_fdio.Initialize())
271 return ENOSYS;
272 return s_irt_fdio.interface.fstat(fd, buf);
273 }
274
275 int _real_getdents(int fd, void* nacl_buf, size_t nacl_count, size_t* nread) {
276 if (!s_irt_fdio.Initialize())
277 return ENOSYS;
278 return s_irt_fdio.interface.getdents(fd, static_cast<dirent*>(nacl_buf),
279 nacl_count, nread);
280 }
281
282 int _real_isatty(int fd, int* result) {
283 if (!s_irt_dev_fdio.Initialize())
284 return ENOSYS;
285 return s_irt_dev_fdio.interface.isatty(fd, result);
286 }
287
288 int _real_lseek(int fd, int64_t offset, int whence, int64_t* new_offset) {
289 if (!s_irt_fdio.Initialize())
290 return ENOSYS;
291 return s_irt_fdio.interface.seek(fd, offset, whence, new_offset);
292 }
293
294 int _real_mkdir(const char* pathname, mode_t mode) {
295 if (!s_irt_dev_filename.Initialize())
296 return ENOSYS;
297 return s_irt_dev_filename.interface.mkdir(pathname, mode);
298 }
299
300 int _real_mmap(void** addr,
301 size_t length,
302 int prot,
303 int flags,
304 int fd,
305 int64_t offset) {
306 if (!s_irt_memory.Initialize())
307 return ENOSYS;
308 return s_irt_memory.interface.mmap(addr, length, prot, flags, fd, offset);
309 }
310
311 int _real_munmap(void* addr, size_t length) {
312 if (!s_irt_memory.Initialize())
313 return ENOSYS;
314 return s_irt_memory.interface.munmap(addr, length);
315 }
316
317 int _real_open(const char* pathname, int oflag, mode_t mode, int* newfd) {
318 if (!s_irt_dev_filename.Initialize())
319 return ENOSYS;
320 return s_irt_dev_filename.interface.open(pathname, oflag, mode, newfd);
321 }
322
323 int _real_open_resource(const char* file, int* fd) {
324 if (!s_irt_resource_open.Initialize())
325 return ENOSYS;
326 return s_irt_resource_open.interface.open_resource(file, fd);
327 }
328
329 int _real_read(int fd, void* buf, size_t count, size_t* nread) {
330 if (!s_irt_fdio.Initialize())
331 return ENOSYS;
332 return s_irt_fdio.interface.read(fd, buf, count, nread);
333 }
334
335 int _real_rmdir(const char* pathname) {
336 if (!s_irt_dev_filename.Initialize())
337 return ENOSYS;
338 return s_irt_dev_filename.interface.rmdir(pathname);
339 }
340
341 int _real_write(int fd, const void* buf, size_t count, size_t* nwrote) {
342 if (!s_irt_fdio.Initialize())
343 return ENOSYS;
344 return s_irt_fdio.interface.write(fd, buf, count, nwrote);
345 }
346
347 int _real_getcwd(char* pathname, size_t len) {
348 if (!s_irt_dev_filename.Initialize())
349 return ENOSYS;
350 return s_irt_dev_filename.interface.getcwd(pathname, len);
351 }
352
353 // Kernel Wrap init/uninit functions declared in kernel_wrap.h.
354 void kernel_wrap_init() {
355 if (!s_wrapped) {
356 LOG_TRACE("kernel_wrap_init");
357
358 // Register interfaces as listed in irt.h.
359
360 // Register nacl_irt_basic interface.
361 CHECK_CALL(s_irt_basic.Initialize());
362 struct nacl_irt_basic basic_calls = {
363 ki_exit,
364 s_irt_basic.interface.gettod,
365 s_irt_basic.interface.clock,
366 s_irt_basic.interface.nanosleep,
367 s_irt_basic.interface.sched_yield,
368 s_irt_basic.interface.sysconf,
369 };
370 CHECK_CALL(s_irt_basic.IRTExtSupply(basic_calls));
371
372 // Register nacl_irt_fdio interface.
373 struct nacl_irt_fdio fdio = {
374 ext_close,
375 ext_dup,
376 ext_dup2,
377 ext_read,
378 ext_write,
379 ext_seek,
380 ext_fstat,
381 ext_getdents,
382 };
383 CHECK_CALL(s_irt_fdio.IRTExtSupply(fdio));
384
385 // Register nacl_irt_memory interface.
386 struct nacl_irt_memory mem = {
387 ext_mmap,
388 ext_munmap,
389 ext_mprotect,
390 };
391 CHECK_CALL(s_irt_memory.IRTExtSupply(mem));
392
393 // Register interfaces as listed in irt_dev.h.
394
395 // Register nacl_irt_dev_fdio interface.
396 struct nacl_irt_dev_fdio dev_fdio = {
397 ext_close,
398 ext_dup,
399 ext_dup2,
400 ext_read,
401 ext_write,
402 ext_seek,
403 ext_fstat,
404 ext_getdents,
405 ext_fchdir,
406 ext_fchmod,
407 ext_fsync,
408 ext_fdatasync,
409 ext_ftruncate,
410 ext_isatty,
411 };
412 CHECK_CALL(s_irt_dev_fdio.IRTExtSupply(dev_fdio));
413
414 // Register nacl_irt_dev_filename interface.
415 struct nacl_irt_dev_filename dev_filename = {
416 ext_open,
417 ext_stat,
418 ext_mkdir,
419 ext_rmdir,
420 ext_chdir,
421 ext_getcwd,
422 ext_unlink,
423 ext_truncate,
424 ext_lstat,
425 ext_link,
426 ext_rename,
427 ext_symlink,
428 ext_chmod,
429 ext_access,
430 ext_readlink,
431 ext_utimes,
432 };
433 CHECK_CALL(s_irt_dev_filename.IRTExtSupply(dev_filename));
434
435 s_wrapped = true;
436 }
437 }
438
439 void kernel_wrap_uninit() {
440 if (s_wrapped) {
441 LOG_TRACE("kernel_wrap_uninit");
442
443 // Register original IRT interfaces in irt.h.
444 CHECK_CALL(s_irt_basic.RevertIRTExtSupply());
445 CHECK_CALL(s_irt_fdio.RevertIRTExtSupply());
446 CHECK_CALL(s_irt_memory.RevertIRTExtSupply());
447
448 // Register optional original IRT dev interfaces in irt_dev.h.
449 s_irt_dev_fdio.RevertIRTExtSupply(true);
450 s_irt_dev_filename.RevertIRTExtSupply(true);
451
452 s_wrapped = false;
453 }
454 }
455
456 EXTERN_C_END
457
458 #endif // defined(__NACL_IO_IRT_EXT__)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698