2 * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
8 * This file defines various POSIX-like functions directly using NaCl
9 * syscall trampolines. For normal application use, these are defined
10 * instead using the IRT function tables. Here we're defining the versions
11 * to be used inside the IRT itself, and in various local tests that do not
14 * We define these all in one file so that we can be sure that we get
15 * them all defined here and won't have any stragglers brought in from
16 * the normal C libraries, where we'd get the IRT-based versions instead.
17 * Since the first thing in the link (../stubs/crt1.x) forces a reference
18 * to _exit, we can be sure that this file will be brought in first.
28 #include <sys/types.h>
31 #include "native_client/src/include/elf32.h"
32 #include "native_client/src/untrusted/nacl/syscall_bindings_trampoline.h"
39 static int errno_call(int error) {
47 static int errno_value_call(int rv) {
55 void _exit(int status) {
56 NACL_SYSCALL(exit)(status);
57 while (1) *(volatile int *) 0 = 0; /* Crash. */
60 int gettimeofday(struct timeval *tv, void *tz) {
61 return errno_call(NACL_SYSCALL(gettimeofday)(tv, NULL));
65 return NACL_SYSCALL(clock)();
68 int nanosleep(const struct timespec *req, struct timespec *rem) {
69 return errno_call(NACL_GC_WRAP_SYSCALL(NACL_SYSCALL(nanosleep)(req, rem)));
72 int clock_getres(clockid_t clk_id, struct timespec *res) {
73 return errno_call(NACL_SYSCALL(clock_getres)(clk_id, res));
76 int clock_gettime(clockid_t clk_id, struct timespec *tp) {
77 return errno_call(NACL_SYSCALL(clock_gettime)(clk_id, tp));
80 int sched_yield(void) {
81 return errno_call(NACL_GC_WRAP_SYSCALL(NACL_SYSCALL(sched_yield)()));
84 long int sysconf(int name) {
86 int error = NACL_SYSCALL(sysconf)(name, &value);
94 void *mmap(void *start, size_t length, int prot, int flags,
95 int fd, off_t offset) {
96 uint32_t rv = (uintptr_t) NACL_SYSCALL(mmap)(start, length, prot, flags,
98 if ((uint32_t) rv > 0xffff0000u) {
99 errno = -(int32_t) rv;
102 return (void *) (uintptr_t) rv;
105 int munmap(void *start, size_t length) {
106 return errno_call(NACL_SYSCALL(munmap)(start, length));
109 int mprotect(void *start, size_t length, int prot) {
110 return errno_call(NACL_SYSCALL(mprotect)(start, length, prot));
113 int open(char const *pathname, int oflag, ...) {
117 if (oflag & O_CREAT) {
119 cmode = va_arg(ap, mode_t);
125 return errno_value_call(NACL_GC_WRAP_SYSCALL(
126 NACL_SYSCALL(open)(pathname, oflag, cmode)));
130 return errno_call(NACL_SYSCALL(close)(fd));
133 int read(int fd, void *buf, size_t count) {
134 return errno_value_call(NACL_GC_WRAP_SYSCALL(
135 NACL_SYSCALL(read)(fd, buf, count)));
138 int write(int fd, const void *buf, size_t count) {
139 return errno_value_call(NACL_GC_WRAP_SYSCALL(
140 NACL_SYSCALL(write)(fd, buf, count)));
143 int pread(int fd, void *buf, size_t count, off_t offset) {
144 return errno_value_call(NACL_GC_WRAP_SYSCALL(
145 NACL_SYSCALL(pread)(fd, buf, count, &offset)));
148 int pwrite(int fd, const void *buf, size_t count, off_t offset) {
149 return errno_value_call(NACL_GC_WRAP_SYSCALL(
150 NACL_SYSCALL(pwrite)(fd, buf, count, &offset)));
153 off_t lseek(int fd, off_t offset, int whence) {
154 int error = NACL_SYSCALL(lseek)(fd, &offset, whence);
163 return errno_value_call(NACL_SYSCALL(dup)(fd));
166 int dup2(int oldfd, int newfd) {
167 return errno_value_call(NACL_SYSCALL(dup2)(oldfd, newfd));
170 int fstat(int fd, struct stat *st) {
171 return errno_call(NACL_SYSCALL(fstat)(fd, st));
174 int stat(const char *file, struct stat *st) {
175 return errno_call(NACL_SYSCALL(stat)(file, st));
178 int getdents(int fd, struct dirent *buf, size_t count) {
179 return errno_value_call(NACL_GC_WRAP_SYSCALL(
180 NACL_SYSCALL(getdents)(fd, buf, count)));
184 int result = NACL_SYSCALL(isatty)(fd);
193 return errno_value_call(NACL_SYSCALL(getpid)());
196 int mkdir(const char *path, int mode) {
197 return errno_call(NACL_SYSCALL(mkdir)(path, mode));
200 int rmdir(const char *path) {
201 return errno_call(NACL_SYSCALL(rmdir)(path));
204 int chdir(const char *path) {
205 return errno_call(NACL_SYSCALL(chdir)(path));
208 char *getcwd(char *buffer, size_t len) {
209 int retval = NACL_SYSCALL(getcwd)(buffer, len);
218 int unlink(const char *path) {
219 return errno_call(NACL_SYSCALL(unlink)(path));
222 int truncate(const char *path, off_t length) {
223 return errno_call(NACL_SYSCALL(truncate)(path, &length));
226 int lstat(const char *file, struct stat *st) {
227 return errno_call(NACL_SYSCALL(lstat)(file, st));
230 int link(const char *oldpath, const char *newpath) {
231 return errno_call(NACL_SYSCALL(link)(oldpath, newpath));
234 int rename(const char *oldpath, const char* newpath) {
235 return errno_call(NACL_SYSCALL(rename)(oldpath, newpath));
238 int symlink(const char *oldpath, const char* newpath) {
239 return errno_call(NACL_SYSCALL(symlink)(oldpath, newpath));
242 int chmod(const char *path, mode_t mode) {
243 return errno_call(NACL_SYSCALL(chmod)(path, mode));
246 int access(const char *path, int amode) {
247 return errno_call(NACL_SYSCALL(access)(path, amode));
250 int readlink(const char *path, char *buf, int bufsize) {
251 return errno_value_call(NACL_SYSCALL(readlink)(path, buf, bufsize));
254 int utimes(const char *path, const struct timeval times[2]) {
255 return errno_value_call(NACL_SYSCALL(utimes)(path, times));
259 * This is a stub since _start will call it but we don't want to
260 * do the normal initialization.
262 void __libnacl_irt_init(Elf32_auxv_t *auxv) {
266 * These have to be weak because the IRT defines its own versions.
268 __attribute__((weak)) int nacl_tls_init(void *thread_ptr) {
269 return -NACL_SYSCALL(tls_init)(thread_ptr);
272 __attribute__((weak)) void *nacl_tls_get(void) {
273 return NACL_SYSCALL(tls_get)();