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

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

Issue 271513002: [NaCl SDK] nacl_io: Make IRT intercepts (and their test code) more robust. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <sys/types.h> // Include something that will define __GLIBC__. 5 #include <sys/types.h> // Include something that will define __GLIBC__.
6 6
7 // The entire file is wrapped in this #if. We do this so this .cc file can be 7 // The entire file is wrapped in this #if. We do this so this .cc file can be
8 // compiled, even on a non-glibc build. 8 // compiled, even on a non-glibc build.
9 #if defined(__native_client__) && defined(__GLIBC__) 9 #if defined(__native_client__) && defined(__GLIBC__)
10 10
11 #include "nacl_io/kernel_wrap.h" 11 #include "nacl_io/kernel_wrap.h"
12 12
13 #include <alloca.h> 13 #include <alloca.h>
14 #include <assert.h> 14 #include <assert.h>
15 #include <dirent.h> 15 #include <dirent.h>
16 #include <errno.h> 16 #include <errno.h>
17 #include <irt.h> 17 #include <irt.h>
18 #include <irt_syscalls.h> 18 #include <irt_syscalls.h>
19 #include <nacl_stat.h> 19 #include <nacl_stat.h>
20 #include <string.h> 20 #include <string.h>
21 #include <sys/stat.h> 21 #include <sys/stat.h>
22 #include <sys/time.h> 22 #include <sys/time.h>
23 23
24 #include "nacl_io/kernel_intercept.h" 24 #include "nacl_io/kernel_intercept.h"
25 #include "nacl_io/kernel_wrap_real.h" 25 #include "nacl_io/kernel_wrap_real.h"
26 #include "nacl_io/log.h"
26 #include "nacl_io/osmman.h" 27 #include "nacl_io/osmman.h"
27 28
28 29
29 namespace { 30 namespace {
30 31
31 void stat_to_nacl_stat(const struct stat* buf, nacl_abi_stat* nacl_buf) { 32 void stat_to_nacl_stat(const struct stat* buf, nacl_abi_stat* nacl_buf) {
32 memset(nacl_buf, 0, sizeof(struct nacl_abi_stat)); 33 memset(nacl_buf, 0, sizeof(struct nacl_abi_stat));
33 nacl_buf->nacl_abi_st_dev = buf->st_dev; 34 nacl_buf->nacl_abi_st_dev = buf->st_dev;
34 nacl_buf->nacl_abi_st_ino = buf->st_ino; 35 nacl_buf->nacl_abi_st_ino = buf->st_ino;
35 nacl_buf->nacl_abi_st_mode = buf->st_mode; 36 nacl_buf->nacl_abi_st_mode = buf->st_mode;
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 REAL(name) = __nacl_irt_##name; 116 REAL(name) = __nacl_irt_##name;
116 117
117 // Switch IRT's pointer to the REAL pointer 118 // Switch IRT's pointer to the REAL pointer
118 #define USE_REAL(name) \ 119 #define USE_REAL(name) \
119 __nacl_irt_##name = (typeof(__nacl_irt_##name)) REAL(name) 120 __nacl_irt_##name = (typeof(__nacl_irt_##name)) REAL(name)
120 121
121 // Switch IRT's pointer to the WRAP function 122 // Switch IRT's pointer to the WRAP function
122 #define USE_WRAP(name) \ 123 #define USE_WRAP(name) \
123 __nacl_irt_##name = (typeof(__nacl_irt_##name)) WRAP(name) 124 __nacl_irt_##name = (typeof(__nacl_irt_##name)) WRAP(name)
124 125
125
126 #define EXPAND_SYMBOL_LIST_OPERATION(OP) \ 126 #define EXPAND_SYMBOL_LIST_OPERATION(OP) \
127 OP(chdir); \ 127 OP(chdir); \
128 OP(close); \ 128 OP(close); \
129 OP(dup); \ 129 OP(dup); \
130 OP(dup2); \ 130 OP(dup2); \
131 OP(exit); \ 131 OP(exit); \
132 OP(fstat); \ 132 OP(fstat); \
133 OP(getcwd); \ 133 OP(getcwd); \
134 OP(getdents); \ 134 OP(getdents); \
135 OP(mkdir); \ 135 OP(mkdir); \
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 // OP(epoll_create1); 168 // OP(epoll_create1);
169 // OP(epoll_ctl); 169 // OP(epoll_ctl);
170 // OP(epoll_pwait); 170 // OP(epoll_pwait);
171 // OP(ppoll); 171 // OP(ppoll);
172 // OP(pselect); 172 // OP(pselect);
173 // 173 //
174 174
175 EXPAND_SYMBOL_LIST_OPERATION(DECLARE_REAL_PTR); 175 EXPAND_SYMBOL_LIST_OPERATION(DECLARE_REAL_PTR);
176 176
177 int WRAP(chdir)(const char* pathname) { 177 int WRAP(chdir)(const char* pathname) {
178 return (ki_chdir(pathname)) ? errno : 0; 178 RTN_ERRNO_IF(ki_chdir(pathname) < 0);
179 return 0;
179 } 180 }
180 181
181 int WRAP(close)(int fd) { 182 int WRAP(close)(int fd) {
182 return (ki_close(fd) < 0) ? errno : 0; 183 RTN_ERRNO_IF(ki_close(fd) < 0);
184 return 0;
183 } 185 }
184 186
185 int WRAP(dup)(int fd, int* newfd) NOTHROW { 187 int WRAP(dup)(int fd, int* newfd) NOTHROW {
186 *newfd = ki_dup(fd); 188 *newfd = ki_dup(fd);
187 return (*newfd < 0) ? errno : 0; 189 RTN_ERRNO_IF(*newfd < 0);
190 return 0;
188 } 191 }
189 192
190 int WRAP(dup2)(int fd, int newfd) NOTHROW { 193 int WRAP(dup2)(int fd, int newfd) NOTHROW {
191 return (ki_dup2(fd, newfd) < 0) ? errno : 0; 194 RTN_ERRNO_IF(ki_dup2(fd, newfd) < 0);
195 return 0;
192 } 196 }
193 197
194 void WRAP(exit)(int status) { 198 void WRAP(exit)(int status) {
195 ki_exit(status); 199 ki_exit(status);
196 } 200 }
197 201
198 int WRAP(fstat)(int fd, struct nacl_abi_stat *nacl_buf) { 202 int WRAP(fstat)(int fd, struct nacl_abi_stat *nacl_buf) {
199 struct stat buf; 203 struct stat buf;
200 memset(&buf, 0, sizeof(struct stat)); 204 memset(&buf, 0, sizeof(struct stat));
201 int res = ki_fstat(fd, &buf); 205 int res = ki_fstat(fd, &buf);
202 if (res < 0) 206 RTN_ERRNO_IF(res < 0);
203 return errno;
204 stat_to_nacl_stat(&buf, nacl_buf); 207 stat_to_nacl_stat(&buf, nacl_buf);
205 return 0; 208 return 0;
206 } 209 }
207 210
208 int WRAP(getcwd)(char* buf, size_t size) { 211 int WRAP(getcwd)(char* buf, size_t size) {
209 if (ki_getcwd(buf, size) == NULL) 212 RTN_ERRNO_IF(ki_getcwd(buf, size) == NULL);
210 return errno;
211 return 0; 213 return 0;
212 } 214 }
213 215
214 int WRAP(getdents)(int fd, dirent* nacl_buf, size_t nacl_count, size_t *nread) { 216 int WRAP(getdents)(int fd, dirent* nacl_buf, size_t nacl_count, size_t *nread) {
215 int nacl_offset = 0; 217 int nacl_offset = 0;
216 // "buf" contains dirent(s); "nacl_buf" contains nacl_abi_dirent(s). 218 // "buf" contains dirent(s); "nacl_buf" contains nacl_abi_dirent(s).
217 // nacl_abi_dirent(s) are smaller than dirent(s), so nacl_count bytes buffer 219 // nacl_abi_dirent(s) are smaller than dirent(s), so nacl_count bytes buffer
218 // is enough 220 // is enough
219 char* buf = (char*)alloca(nacl_count); 221 char* buf = (char*)alloca(nacl_count);
220 int offset = 0; 222 int offset = 0;
221 int count; 223 int count;
222 224
223 count = ki_getdents(fd, buf, nacl_count); 225 count = ki_getdents(fd, buf, nacl_count);
224 if (count < 0) 226 RTN_ERRNO_IF(count < 0);
225 return errno;
226 227
227 while (offset < count) { 228 while (offset < count) {
228 dirent* d = (dirent*)(buf + offset); 229 dirent* d = (dirent*)(buf + offset);
229 nacl_abi_dirent* nacl_d = (nacl_abi_dirent*)((char*)nacl_buf + nacl_offset); 230 nacl_abi_dirent* nacl_d = (nacl_abi_dirent*)((char*)nacl_buf + nacl_offset);
230 nacl_d->nacl_abi_d_ino = d->d_ino; 231 nacl_d->nacl_abi_d_ino = d->d_ino;
231 nacl_d->nacl_abi_d_off = d->d_off; 232 nacl_d->nacl_abi_d_off = d->d_off;
232 nacl_d->nacl_abi_d_reclen = d->d_reclen - d_name_shift; 233 nacl_d->nacl_abi_d_reclen = d->d_reclen - d_name_shift;
233 size_t d_name_len = d->d_reclen - offsetof(dirent, d_name); 234 size_t d_name_len = d->d_reclen - offsetof(dirent, d_name);
234 memcpy(nacl_d->nacl_abi_d_name, d->d_name, d_name_len); 235 memcpy(nacl_d->nacl_abi_d_name, d->d_name, d_name_len);
235 236
236 offset += d->d_reclen; 237 offset += d->d_reclen;
237 nacl_offset += nacl_d->nacl_abi_d_reclen; 238 nacl_offset += nacl_d->nacl_abi_d_reclen;
238 } 239 }
239 240
240 *nread = nacl_offset; 241 *nread = nacl_offset;
241 return 0; 242 return 0;
242 } 243 }
243 244
244 int WRAP(mkdir)(const char* pathname, mode_t mode) { 245 int WRAP(mkdir)(const char* pathname, mode_t mode) {
245 return (ki_mkdir(pathname, mode)) ? errno : 0; 246 RTN_ERRNO_IF(ki_mkdir(pathname, mode) < 0);
247 return 0;
246 } 248 }
247 249
248 int WRAP(mmap)(void** addr, size_t length, int prot, int flags, int fd, 250 int WRAP(mmap)(void** addr, size_t length, int prot, int flags, int fd,
249 off_t offset) { 251 off_t offset) {
250 if (flags & MAP_ANONYMOUS) 252 if (flags & MAP_ANONYMOUS)
251 return REAL(mmap)(addr, length, prot, flags, fd, offset); 253 return REAL(mmap)(addr, length, prot, flags, fd, offset);
252 254
253 *addr = ki_mmap(*addr, length, prot, flags, fd, offset); 255 *addr = ki_mmap(*addr, length, prot, flags, fd, offset);
254 return *addr == (void*)-1 ? errno : 0; 256 RTN_ERRNO_IF(*addr == (void*)-1);
257 return 0;
255 } 258 }
256 259
257 int WRAP(munmap)(void* addr, size_t length) { 260 int WRAP(munmap)(void* addr, size_t length) {
258 // Always let the real munmap run on the address range. It is not an error if 261 // Always let the real munmap run on the address range. It is not an error if
259 // there are no mapped pages in that range. 262 // there are no mapped pages in that range.
260 ki_munmap(addr, length); 263 ki_munmap(addr, length);
261 return REAL(munmap)(addr, length); 264 return REAL(munmap)(addr, length);
262 } 265 }
263 266
264 int WRAP(open)(const char* pathname, int oflag, mode_t cmode, int* newfd) { 267 int WRAP(open)(const char* pathname, int oflag, mode_t cmode, int* newfd) {
265 *newfd = ki_open(pathname, oflag); 268 *newfd = ki_open(pathname, oflag);
266 return (*newfd < 0) ? errno : 0; 269 RTN_ERRNO_IF(*newfd < 0);
270 return 0;
267 } 271 }
268 272
269 int WRAP(open_resource)(const char* file, int* fd) { 273 int WRAP(open_resource)(const char* file, int* fd) {
270 *fd = ki_open_resource(file); 274 *fd = ki_open_resource(file);
271 return (*fd < 0) ? errno : 0; 275 RTN_ERRNO_IF(*fd < 0);
276 return 0;
272 } 277 }
273 278
274 int WRAP(poll)(struct pollfd *fds, nfds_t nfds, int timeout, int* count) { 279 int WRAP(poll)(struct pollfd *fds, nfds_t nfds, int timeout, int* count) {
275 *count = ki_poll(fds, nfds, timeout); 280 *count = ki_poll(fds, nfds, timeout);
276 return (*count < 0) ? errno : 0; 281 RTN_ERRNO_IF(*count < 0);
277 282 return 0;
278 } 283 }
279 284
280 int WRAP(read)(int fd, void *buf, size_t count, size_t *nread) { 285 int WRAP(read)(int fd, void *buf, size_t count, size_t *nread) {
281 ssize_t signed_nread = ki_read(fd, buf, count); 286 ssize_t signed_nread = ki_read(fd, buf, count);
282 *nread = static_cast<size_t>(signed_nread); 287 *nread = static_cast<size_t>(signed_nread);
283 return (signed_nread < 0) ? errno : 0; 288 RTN_ERRNO_IF(signed_nread < 0);
289 return 0;
284 } 290 }
285 291
286 int WRAP(rmdir)(const char* pathname) { 292 int WRAP(rmdir)(const char* pathname) {
287 return (ki_rmdir(pathname) < 0) ? errno : 0; 293 RTN_ERRNO_IF(ki_rmdir(pathname) < 0);
294 return 0;
288 } 295 }
289 296
290 int WRAP(seek)(int fd, off_t offset, int whence, off_t* new_offset) { 297 int WRAP(seek)(int fd, off_t offset, int whence, off_t* new_offset) {
291 *new_offset = ki_lseek(fd, offset, whence); 298 *new_offset = ki_lseek(fd, offset, whence);
292 return (*new_offset < 0) ? errno : 0; 299 RTN_ERRNO_IF(*new_offset < 0);
300 return 0;
293 } 301 }
294 302
295 int WRAP(select)(int nfds, fd_set* readfds, fd_set* writefds, 303 int WRAP(select)(int nfds, fd_set* readfds, fd_set* writefds,
296 fd_set* exceptfds, struct timeval* timeout, int* count) { 304 fd_set* exceptfds, struct timeval* timeout, int* count) {
297 *count = ki_select(nfds, readfds, writefds, exceptfds, timeout); 305 *count = ki_select(nfds, readfds, writefds, exceptfds, timeout);
298 return (*count < 0) ? errno : 0; 306 RTN_ERRNO_IF(*count < 0);
307 return 0;
299 } 308 }
300 309
301 int WRAP(stat)(const char *pathname, struct nacl_abi_stat *nacl_buf) { 310 int WRAP(stat)(const char *pathname, struct nacl_abi_stat *nacl_buf) {
302 struct stat buf; 311 struct stat buf;
303 memset(&buf, 0, sizeof(struct stat)); 312 memset(&buf, 0, sizeof(struct stat));
304 int res = ki_stat(pathname, &buf); 313 int res = ki_stat(pathname, &buf);
305 if (res < 0) 314 RTN_ERRNO_IF(res < 0);
306 return errno;
307 stat_to_nacl_stat(&buf, nacl_buf); 315 stat_to_nacl_stat(&buf, nacl_buf);
308 return 0; 316 return 0;
309 } 317 }
310 318
311 int WRAP(write)(int fd, const void* buf, size_t count, size_t* nwrote) { 319 int WRAP(write)(int fd, const void* buf, size_t count, size_t* nwrote) {
312 ssize_t signed_nwrote = ki_write(fd, buf, count); 320 ssize_t signed_nwrote = ki_write(fd, buf, count);
313 *nwrote = static_cast<size_t>(signed_nwrote); 321 *nwrote = static_cast<size_t>(signed_nwrote);
314 return (signed_nwrote < 0) ? errno : 0; 322 RTN_ERRNO_IF(signed_nwrote < 0);
323 return 0;
315 } 324 }
316 325
317 int WRAP(accept)(int sockfd, struct sockaddr* addr, 326 int WRAP(accept)(int sockfd, struct sockaddr* addr,
318 socklen_t* addrlen, int *sd) { 327 socklen_t* addrlen, int *sd) {
319 int result = ki_accept(sockfd, addr, addrlen); 328 int result = ki_accept(sockfd, addr, addrlen);
320 if (result < 0) { 329 if (result < 0) {
321 *sd = -1; 330 *sd = -1;
322 return errno; 331 return errno;
323 } else { 332 } else {
324 *sd = result; 333 *sd = result;
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 } 536 }
528 537
529 int _real_write(int fd, const void *buf, size_t count, size_t *nwrote) { 538 int _real_write(int fd, const void *buf, size_t count, size_t *nwrote) {
530 CHECK_REAL(write); 539 CHECK_REAL(write);
531 return REAL(write)(fd, buf, count, nwrote); 540 return REAL(write)(fd, buf, count, nwrote);
532 } 541 }
533 542
534 static bool s_wrapped = false; 543 static bool s_wrapped = false;
535 void kernel_wrap_init() { 544 void kernel_wrap_init() {
536 if (!s_wrapped) { 545 if (!s_wrapped) {
546 LOG_TRACE("kernel_wrap_init");
537 assign_real_pointers(); 547 assign_real_pointers();
538 EXPAND_SYMBOL_LIST_OPERATION(USE_WRAP) 548 EXPAND_SYMBOL_LIST_OPERATION(USE_WRAP)
539 s_wrapped = true; 549 s_wrapped = true;
540 } 550 }
541 } 551 }
542 552
543 void kernel_wrap_uninit() { 553 void kernel_wrap_uninit() {
544 if (s_wrapped) { 554 if (s_wrapped) {
555 LOG_TRACE("kernel_wrap_uninit");
545 EXPAND_SYMBOL_LIST_OPERATION(USE_REAL) 556 EXPAND_SYMBOL_LIST_OPERATION(USE_REAL)
546 s_wrapped = false; 557 s_wrapped = false;
547 } 558 }
548 } 559 }
549 560
550 EXTERN_C_END 561 EXTERN_C_END
551 562
552 #endif // defined(__native_client__) && defined(__GLIBC__) 563 #endif // defined(__native_client__) && defined(__GLIBC__)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698