| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2014 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2014 The Native Client Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 /* | 7 /* |
| 8 * This file defines various POSIX-like functions directly using Linux | 8 * This file defines various POSIX-like functions directly using Linux |
| 9 * syscalls. This is analogous to src/untrusted/nacl/sys_private.c, which | 9 * syscalls. This is analogous to src/untrusted/nacl/sys_private.c, which |
| 10 * defines functions using NaCl syscalls directly. | 10 * defines functions using NaCl syscalls directly. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 #include "native_client/src/nonsfi/linux/linux_syscall_defines.h" | 27 #include "native_client/src/nonsfi/linux/linux_syscall_defines.h" |
| 28 #include "native_client/src/nonsfi/linux/linux_syscall_structs.h" | 28 #include "native_client/src/nonsfi/linux/linux_syscall_structs.h" |
| 29 #include "native_client/src/nonsfi/linux/linux_syscall_wrappers.h" | 29 #include "native_client/src/nonsfi/linux/linux_syscall_wrappers.h" |
| 30 #include "native_client/src/nonsfi/linux/linux_syscalls.h" | 30 #include "native_client/src/nonsfi/linux/linux_syscalls.h" |
| 31 #include "native_client/src/public/linux_syscalls/poll.h" | 31 #include "native_client/src/public/linux_syscalls/poll.h" |
| 32 #include "native_client/src/public/linux_syscalls/sys/prctl.h" | 32 #include "native_client/src/public/linux_syscalls/sys/prctl.h" |
| 33 #include "native_client/src/public/linux_syscalls/sys/socket.h" | 33 #include "native_client/src/public/linux_syscalls/sys/socket.h" |
| 34 #include "native_client/src/untrusted/nacl/tls.h" | 34 #include "native_client/src/untrusted/nacl/tls.h" |
| 35 | 35 |
| 36 | 36 |
| 37 /* Used in openat() and fstatat(). */ |
| 38 #define LINUX_AT_FDCWD (-100) |
| 39 |
| 37 /* | 40 /* |
| 38 * Note that Non-SFI NaCl uses a 4k page size, in contrast to SFI NaCl's | 41 * Note that Non-SFI NaCl uses a 4k page size, in contrast to SFI NaCl's |
| 39 * 64k page size. | 42 * 64k page size. |
| 40 */ | 43 */ |
| 41 static const int kPageSize = 0x1000; | 44 static const int kPageSize = 0x1000; |
| 42 | 45 |
| 43 static uintptr_t errno_value_call(uintptr_t result) { | 46 static uintptr_t errno_value_call(uintptr_t result) { |
| 44 if (linux_is_error_result(result)) { | 47 if (linux_is_error_result(result)) { |
| 45 errno = -result; | 48 errno = -result; |
| 46 return -1; | 49 return -1; |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 int read(int fd, void *buf, size_t count) { | 170 int read(int fd, void *buf, size_t count) { |
| 168 return errno_value_call(linux_syscall3(__NR_read, fd, | 171 return errno_value_call(linux_syscall3(__NR_read, fd, |
| 169 (uintptr_t) buf, count)); | 172 (uintptr_t) buf, count)); |
| 170 } | 173 } |
| 171 | 174 |
| 172 int write(int fd, const void *buf, size_t count) { | 175 int write(int fd, const void *buf, size_t count) { |
| 173 return errno_value_call(linux_syscall3(__NR_write, fd, | 176 return errno_value_call(linux_syscall3(__NR_write, fd, |
| 174 (uintptr_t) buf, count)); | 177 (uintptr_t) buf, count)); |
| 175 } | 178 } |
| 176 | 179 |
| 177 int open(char const *pathname, int oflag, ...) { | 180 int open(const char *pathname, int oflag, ...) { |
| 178 mode_t cmode; | 181 mode_t cmode; |
| 179 va_list ap; | |
| 180 | 182 |
| 181 if (oflag & O_CREAT) { | 183 oflag = nacl_oflags_to_linux_oflags(oflag); |
| 184 if (oflag == -1) { |
| 185 errno = EINVAL; |
| 186 return -1; |
| 187 } |
| 188 |
| 189 if (oflag & LINUX_O_CREAT) { |
| 190 va_list ap; |
| 182 va_start(ap, oflag); | 191 va_start(ap, oflag); |
| 183 cmode = va_arg(ap, mode_t); | 192 cmode = va_arg(ap, mode_t); |
| 184 va_end(ap); | 193 va_end(ap); |
| 185 } else { | 194 } else { |
| 186 cmode = 0; | 195 cmode = 0; |
| 187 } | 196 } |
| 188 | 197 |
| 189 return errno_value_call( | 198 return errno_value_call( |
| 190 linux_syscall3(__NR_open, (uintptr_t) pathname, oflag, cmode)); | 199 linux_syscall3(__NR_open, (uintptr_t) pathname, oflag, cmode)); |
| 191 } | 200 } |
| 192 | 201 |
| 202 int openat(int dirfd, const char *pathname, int oflag, ...) { |
| 203 mode_t cmode; |
| 204 |
| 205 if (dirfd == AT_FDCWD) |
| 206 dirfd = LINUX_AT_FDCWD; |
| 207 |
| 208 oflag = nacl_oflags_to_linux_oflags(oflag); |
| 209 if (oflag == -1) { |
| 210 errno = EINVAL; |
| 211 return -1; |
| 212 } |
| 213 |
| 214 if (oflag & LINUX_O_CREAT) { |
| 215 va_list ap; |
| 216 va_start(ap, oflag); |
| 217 cmode = va_arg(ap, mode_t); |
| 218 va_end(ap); |
| 219 } else { |
| 220 cmode = 0; |
| 221 } |
| 222 |
| 223 return errno_value_call( |
| 224 linux_syscall4(__NR_openat, dirfd, (uintptr_t) pathname, oflag, cmode)); |
| 225 } |
| 226 |
| 193 int close(int fd) { | 227 int close(int fd) { |
| 194 return errno_value_call(linux_syscall1(__NR_close, fd)); | 228 return errno_value_call(linux_syscall1(__NR_close, fd)); |
| 195 } | 229 } |
| 196 | 230 |
| 197 ssize_t pread(int fd, void *buf, size_t count, off_t offset) { | 231 ssize_t pread(int fd, void *buf, size_t count, off_t offset) { |
| 198 uint32_t offset_low = (uint32_t) offset; | 232 uint32_t offset_low = (uint32_t) offset; |
| 199 uint32_t offset_high = offset >> 32; | 233 uint32_t offset_high = offset >> 32; |
| 200 #if defined(__i386__) | 234 #if defined(__i386__) |
| 201 return errno_value_call( | 235 return errno_value_call( |
| 202 linux_syscall5(__NR_pread64, fd, (uintptr_t) buf, count, | 236 linux_syscall5(__NR_pread64, fd, (uintptr_t) buf, count, |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 int lstat(const char *file, struct stat *st) { | 312 int lstat(const char *file, struct stat *st) { |
| 279 struct linux_abi_stat64 linux_st; | 313 struct linux_abi_stat64 linux_st; |
| 280 int rc = errno_value_call( | 314 int rc = errno_value_call( |
| 281 linux_syscall2(__NR_lstat64, (uintptr_t) file, (uintptr_t) &linux_st)); | 315 linux_syscall2(__NR_lstat64, (uintptr_t) file, (uintptr_t) &linux_st)); |
| 282 if (rc == -1) | 316 if (rc == -1) |
| 283 return -1; | 317 return -1; |
| 284 linux_stat_to_nacl_stat(&linux_st, st); | 318 linux_stat_to_nacl_stat(&linux_st, st); |
| 285 return 0; | 319 return 0; |
| 286 } | 320 } |
| 287 | 321 |
| 322 int fstatat(int dirfd, const char *file, struct stat *st, int flags) { |
| 323 struct linux_abi_stat64 linux_st; |
| 324 if (dirfd == AT_FDCWD) |
| 325 dirfd = LINUX_AT_FDCWD; |
| 326 int rc = errno_value_call(linux_syscall4( |
| 327 __NR_fstatat64, dirfd, (uintptr_t) file, (uintptr_t) &linux_st, flags)); |
| 328 if (rc == -1) |
| 329 return -1; |
| 330 linux_stat_to_nacl_stat(&linux_st, st); |
| 331 return 0; |
| 332 } |
| 333 |
| 288 int mkdir(const char *path, mode_t mode) { | 334 int mkdir(const char *path, mode_t mode) { |
| 289 return errno_value_call(linux_syscall2(__NR_mkdir, (uintptr_t) path, mode)); | 335 return errno_value_call(linux_syscall2(__NR_mkdir, (uintptr_t) path, mode)); |
| 290 } | 336 } |
| 291 | 337 |
| 292 int rmdir(const char *path) { | 338 int rmdir(const char *path) { |
| 293 return errno_value_call(linux_syscall1(__NR_rmdir, (uintptr_t) path)); | 339 return errno_value_call(linux_syscall1(__NR_rmdir, (uintptr_t) path)); |
| 294 } | 340 } |
| 295 | 341 |
| 296 int chdir(const char *path) { | 342 int chdir(const char *path) { |
| 297 return errno_value_call(linux_syscall1(__NR_chdir, (uintptr_t) path)); | 343 return errno_value_call(linux_syscall1(__NR_chdir, (uintptr_t) path)); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 linux_syscall2(__NR_access, (uintptr_t) path, amode)); | 401 linux_syscall2(__NR_access, (uintptr_t) path, amode)); |
| 356 } | 402 } |
| 357 | 403 |
| 358 int readlink(const char *path, char *buf, int bufsize) { | 404 int readlink(const char *path, char *buf, int bufsize) { |
| 359 return errno_value_call( | 405 return errno_value_call( |
| 360 linux_syscall3(__NR_readlink, (uintptr_t) path, | 406 linux_syscall3(__NR_readlink, (uintptr_t) path, |
| 361 (uintptr_t) buf, bufsize)); | 407 (uintptr_t) buf, bufsize)); |
| 362 } | 408 } |
| 363 | 409 |
| 364 int fcntl(int fd, int cmd, ...) { | 410 int fcntl(int fd, int cmd, ...) { |
| 365 if (cmd == F_GETFL || cmd == F_GETFD) { | 411 if (cmd == F_GETFD) { |
| 366 return errno_value_call(linux_syscall2(__NR_fcntl64, fd, cmd)); | 412 return errno_value_call(linux_syscall2(__NR_fcntl64, fd, cmd)); |
| 367 } | 413 } |
| 368 if (cmd == F_SETFL || cmd == F_SETFD) { | 414 if (cmd == F_GETFL) { |
| 415 int rc = errno_value_call(linux_syscall2(__NR_fcntl64, fd, cmd)); |
| 416 if (rc == -1) |
| 417 return -1; |
| 418 return linux_oflags_to_nacl_oflags(rc); |
| 419 } |
| 420 if (cmd == F_SETFD) { |
| 369 va_list ap; | 421 va_list ap; |
| 370 va_start(ap, cmd); | 422 va_start(ap, cmd); |
| 371 int32_t arg = va_arg(ap, int32_t); | 423 int32_t arg = va_arg(ap, int32_t); |
| 372 va_end(ap); | 424 va_end(ap); |
| 373 return errno_value_call(linux_syscall3(__NR_fcntl64, fd, cmd, arg)); | 425 return errno_value_call(linux_syscall3(__NR_fcntl64, fd, cmd, arg)); |
| 374 } | 426 } |
| 427 if (cmd == F_SETFL) { |
| 428 va_list ap; |
| 429 va_start(ap, cmd); |
| 430 int32_t arg = va_arg(ap, int32_t); |
| 431 va_end(ap); |
| 432 arg = nacl_oflags_to_linux_oflags(arg); |
| 433 if (arg == -1) { |
| 434 errno = EINVAL; |
| 435 return -1; |
| 436 } |
| 437 return errno_value_call(linux_syscall3(__NR_fcntl64, fd, cmd, arg)); |
| 438 } |
| 375 /* We only support the fcntl commands above. */ | 439 /* We only support the fcntl commands above. */ |
| 376 errno = EINVAL; | 440 errno = EINVAL; |
| 377 return -1; | 441 return -1; |
| 378 } | 442 } |
| 379 | 443 |
| 380 int getpid(void) { | 444 int getpid(void) { |
| 381 return errno_value_call(linux_syscall0(__NR_getpid)); | 445 return errno_value_call(linux_syscall0(__NR_getpid)); |
| 382 } | 446 } |
| 383 | 447 |
| 384 int fork(void) { | 448 int fork(void) { |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 602 | 666 |
| 603 void *nacl_tls_get(void) { | 667 void *nacl_tls_get(void) { |
| 604 void *result; | 668 void *result; |
| 605 #if defined(__i386__) | 669 #if defined(__i386__) |
| 606 __asm__("mov %%gs:0, %0" : "=r"(result)); | 670 __asm__("mov %%gs:0, %0" : "=r"(result)); |
| 607 #elif defined(__arm__) | 671 #elif defined(__arm__) |
| 608 __asm__("mrc p15, 0, %0, c13, c0, 3" : "=r"(result)); | 672 __asm__("mrc p15, 0, %0, c13, c0, 3" : "=r"(result)); |
| 609 #endif | 673 #endif |
| 610 return result; | 674 return result; |
| 611 } | 675 } |
| OLD | NEW |