| |
| // NACL MOD TRACK "third_party/nacl-glibc/sysdeps/nacl/irt_syscalls.c" |
| #include <irt.h> |
| #include <irt_syscalls.h> |
| #include <elf.h> |
| |
| // Remove unnecessary functions which call NaCl syscalls directly. |
| |
| // Define variables. |
| |
| #define DL_DST_LIB "/lib" |
| static int __strncmp(const char* s1, const char *s2, size_t len) { |
| while (len) { |
| if (*s1 != *s2) |
| return 1; |
| len--; |
| } |
| |
| return 0; |
| } |
| |
| static int nacl_irt_open_resource (const char *pathname, int *newfd) { |
| if (__strncmp("/lib", pathname, 4)) |
| return __nacl_irt_open(pathname, O_RDONLY, 0, newfd); |
| else |
| return __nacl_irt_open(pathname + 1, O_RDONLY, 0, newfd); |
| } |
| |
| static int not_implemented() { |
| return (38 /* ENOSYS */); |
| } |
| |
| void __init_irt_table (void) { |
| _irt_syscalls_t* irt = nacl_get_irt_syscalls(); |
| union { |
| struct nacl_irt_basic nacl_irt_basic; |
| struct nacl_irt_fdio nacl_irt_fdio; |
| struct nacl_irt_filename nacl_irt_filename; |
| struct nacl_irt_memory nacl_irt_memory; |
| // As the first element (sysbrk) of nacl_irt_memory is removed in |
| // v0.3, we should have different storage for v0.1 and v0.2. |
| struct nacl_irt_memory_v0_2 nacl_irt_memory_v0_2; |
| struct nacl_irt_dyncode nacl_irt_dyncode; |
| struct nacl_irt_thread nacl_irt_thread; |
| struct nacl_irt_mutex nacl_irt_mutex; |
| struct nacl_irt_cond nacl_irt_cond; |
| struct nacl_irt_tls nacl_irt_tls; |
| struct nacl_irt_resource_open nacl_irt_resource_open; |
| struct nacl_irt_clock nacl_irt_clock; |
| struct nacl_irt_futex nacl_irt_futex; |
| } u; |
| |
| if (irt->nacl_irt_query && |
| irt->nacl_irt_query(NACL_IRT_BASIC_v0_1, &u.nacl_irt_basic, |
| sizeof(u.nacl_irt_basic)) == sizeof(u.nacl_irt_basic)) { |
| irt->nacl_irt_exit = u.nacl_irt_basic.exit; |
| irt->nacl_irt_gettod = u.nacl_irt_basic.gettod; |
| irt->nacl_irt_clock = u.nacl_irt_basic.clock; |
| irt->nacl_irt_nanosleep = u.nacl_irt_basic.nanosleep; |
| irt->nacl_irt_sched_yield = u.nacl_irt_basic.sched_yield; |
| irt->nacl_irt_sysconf = u.nacl_irt_basic.sysconf; |
| } |
| |
| if (irt->nacl_irt_query && |
| irt->nacl_irt_query(NACL_IRT_FDIO_v0_1, &u.nacl_irt_fdio, |
| sizeof(u.nacl_irt_fdio)) == sizeof(u.nacl_irt_fdio)) { |
| irt->nacl_irt_close = u.nacl_irt_fdio.close; |
| irt->nacl_irt_dup = u.nacl_irt_fdio.dup; |
| irt->nacl_irt_dup2 = u.nacl_irt_fdio.dup2; |
| irt->nacl_irt_read = u.nacl_irt_fdio.read; |
| irt->nacl_irt_write = u.nacl_irt_fdio.write; |
| irt->nacl_irt_seek = u.nacl_irt_fdio.seek; |
| irt->nacl_irt_fstat = u.nacl_irt_fdio.fstat; |
| irt->nacl_irt_getdents = u.nacl_irt_fdio.getdents; |
| } |
| |
| if (irt->nacl_irt_query && |
| irt->nacl_irt_query(NACL_IRT_FILENAME_v0_1, &u.nacl_irt_filename, |
| sizeof(u.nacl_irt_filename)) == |
| sizeof(u.nacl_irt_filename)) { |
| irt->nacl_irt_open = u.nacl_irt_filename.open; |
| irt->nacl_irt_stat = u.nacl_irt_filename.stat; |
| } |
| |
| irt->nacl_irt_sysbrk = not_implemented; |
| if (irt->nacl_irt_query && |
| irt->nacl_irt_query(NACL_IRT_MEMORY_v0_3, &u.nacl_irt_memory, |
| sizeof(u.nacl_irt_memory)) == |
| sizeof(u.nacl_irt_memory)) { |
| irt->nacl_irt_mmap = u.nacl_irt_memory.mmap; |
| irt->nacl_irt_munmap = u.nacl_irt_memory.munmap; |
| irt->nacl_irt_mprotect = u.nacl_irt_memory.mprotect; |
| } |
| else if (irt->nacl_irt_query && |
| irt->nacl_irt_query(NACL_IRT_MEMORY_v0_2, &u.nacl_irt_memory_v0_2, |
| sizeof(u.nacl_irt_memory_v0_2)) == |
| sizeof(u.nacl_irt_memory_v0_2)) { |
| irt->nacl_irt_mmap = u.nacl_irt_memory_v0_2.mmap; |
| irt->nacl_irt_munmap = u.nacl_irt_memory_v0_2.munmap; |
| irt->nacl_irt_mprotect = u.nacl_irt_memory_v0_2.mprotect; |
| } |
| else if (irt->nacl_irt_query && |
| irt->nacl_irt_query(NACL_IRT_MEMORY_v0_1, &u.nacl_irt_memory_v0_2, |
| sizeof(struct nacl_irt_memory_v0_1)) == |
| sizeof(struct nacl_irt_memory_v0_1)) { |
| irt->nacl_irt_mmap = u.nacl_irt_memory_v0_2.mmap; |
| irt->nacl_irt_munmap = u.nacl_irt_memory_v0_2.munmap; |
| irt->nacl_irt_mprotect = not_implemented; |
| } |
| |
| if (irt->nacl_irt_query && |
| irt->nacl_irt_query(NACL_IRT_DYNCODE_v0_1, &u.nacl_irt_dyncode, |
| sizeof(u.nacl_irt_dyncode)) == |
| sizeof(u.nacl_irt_dyncode)) { |
| irt->nacl_irt_dyncode_create = u.nacl_irt_dyncode.dyncode_create; |
| irt->nacl_irt_dyncode_modify = u.nacl_irt_dyncode.dyncode_modify; |
| irt->nacl_irt_dyncode_delete = u.nacl_irt_dyncode.dyncode_delete; |
| } |
| |
| if (irt->nacl_irt_query && |
| irt->nacl_irt_query(NACL_IRT_THREAD_v0_1, &u.nacl_irt_thread, |
| sizeof(u.nacl_irt_thread)) == |
| sizeof(u.nacl_irt_thread)) { |
| irt->nacl_irt_thread_create = u.nacl_irt_thread.thread_create; |
| irt->nacl_irt_thread_exit = u.nacl_irt_thread.thread_exit; |
| irt->nacl_irt_thread_nice = u.nacl_irt_thread.thread_nice; |
| } |
| |
| if (irt->nacl_irt_query && |
| irt->nacl_irt_query(NACL_IRT_MUTEX_v0_1, &u.nacl_irt_mutex, |
| sizeof(u.nacl_irt_mutex)) == |
| sizeof(u.nacl_irt_mutex)) { |
| irt->nacl_irt_mutex_create = u.nacl_irt_mutex.mutex_create; |
| irt->nacl_irt_mutex_destroy = u.nacl_irt_mutex.mutex_destroy; |
| irt->nacl_irt_mutex_lock = u.nacl_irt_mutex.mutex_lock; |
| irt->nacl_irt_mutex_unlock = u.nacl_irt_mutex.mutex_unlock; |
| irt->nacl_irt_mutex_trylock = u.nacl_irt_mutex.mutex_trylock; |
| } |
| |
| if (irt->nacl_irt_query && |
| irt->nacl_irt_query(NACL_IRT_COND_v0_1, &u.nacl_irt_cond, |
| sizeof(u.nacl_irt_cond)) == sizeof(u.nacl_irt_cond)) { |
| irt->nacl_irt_cond_create = u.nacl_irt_cond.cond_create; |
| irt->nacl_irt_cond_destroy = u.nacl_irt_cond.cond_destroy; |
| irt->nacl_irt_cond_signal = u.nacl_irt_cond.cond_signal; |
| irt->nacl_irt_cond_broadcast = u.nacl_irt_cond.cond_broadcast; |
| irt->nacl_irt_cond_wait = u.nacl_irt_cond.cond_wait; |
| irt->nacl_irt_cond_timed_wait_abs = u.nacl_irt_cond.cond_timed_wait_abs; |
| } |
| |
| if (irt->nacl_irt_query && |
| irt->nacl_irt_query(NACL_IRT_TLS_v0_1, &u.nacl_irt_tls, |
| sizeof(u.nacl_irt_tls)) == sizeof(u.nacl_irt_tls)) { |
| irt->nacl_irt_tls_init = u.nacl_irt_tls.tls_init; |
| irt->nacl_irt_tls_get = u.nacl_irt_tls.tls_get; |
| } |
| |
| if (irt->nacl_irt_query && |
| irt->nacl_irt_query(NACL_IRT_RESOURCE_OPEN_v0_1, &u.nacl_irt_resource_open, |
| sizeof(u.nacl_irt_resource_open)) == |
| sizeof(u.nacl_irt_resource_open)) { |
| irt->nacl_irt_open_resource = u.nacl_irt_resource_open.open_resource; |
| } |
| |
| if (irt->nacl_irt_query && |
| irt->nacl_irt_query(NACL_IRT_CLOCK_v0_1, &u.nacl_irt_clock, |
| sizeof(u.nacl_irt_clock)) == |
| sizeof(u.nacl_irt_clock)) { |
| irt->nacl_irt_clock_getres = u.nacl_irt_clock.clock_getres; |
| irt->nacl_irt_clock_gettime = u.nacl_irt_clock.clock_gettime; |
| } |
| |
| // Get futex functions. |
| if (irt->nacl_irt_query && |
| irt->nacl_irt_query(NACL_IRT_FUTEX_v0_1, |
| &u.nacl_irt_futex, |
| sizeof(u.nacl_irt_futex)) == |
| sizeof(u.nacl_irt_futex)) { |
| irt->nacl_irt_futex_wait_abs = u.nacl_irt_futex.futex_wait_abs; |
| irt->nacl_irt_futex_wake = u.nacl_irt_futex.futex_wake; |
| } |
| irt->nacl_irt_mkdir = |
| (int (*)(const char* pathname, mode_t mode))not_implemented; |
| |
| irt->nacl_irt_chdir = not_implemented; |
| irt->nacl_irt_rmdir = not_implemented; |
| irt->nacl_irt_getcwd = not_implemented; |
| |
| irt->nacl_irt_epoll_create = not_implemented; |
| irt->nacl_irt_epoll_create1 = not_implemented; |
| irt->nacl_irt_epoll_ctl = not_implemented; |
| irt->nacl_irt_epoll_pwait = not_implemented; |
| irt->nacl_irt_epoll_wait = not_implemented; |
| irt->nacl_irt_poll = not_implemented; |
| irt->nacl_irt_ppoll = not_implemented; |
| irt->nacl_irt_socket = not_implemented; |
| irt->nacl_irt_accept = not_implemented; |
| irt->nacl_irt_bind = not_implemented; |
| irt->nacl_irt_listen = not_implemented; |
| irt->nacl_irt_connect = not_implemented; |
| irt->nacl_irt_send = not_implemented; |
| irt->nacl_irt_sendmsg = not_implemented; |
| irt->nacl_irt_sendto = not_implemented; |
| irt->nacl_irt_recv = not_implemented; |
| irt->nacl_irt_recvmsg = not_implemented; |
| irt->nacl_irt_recvfrom = not_implemented; |
| irt->nacl_irt_select = not_implemented; |
| irt->nacl_irt_pselect = not_implemented; |
| irt->nacl_irt_getpeername = not_implemented; |
| irt->nacl_irt_getsockname = not_implemented; |
| irt->nacl_irt_getsockopt = not_implemented; |
| irt->nacl_irt_setsockopt = not_implemented; |
| irt->nacl_irt_socketpair = not_implemented; |
| irt->nacl_irt_shutdown = not_implemented; |
| } |
| |
| size_t nacl_interface_query(const char *interface_ident, |
| void *table, size_t tablesize) { |
| return (*irt->nacl_irt_query)(interface_ident, table, tablesize); |
| } |
| |
| #ifndef AT_NULL |
| #define AT_NULL 0 |
| #endif |
| |
| #ifndef AT_SYSINFO |
| #define AT_SYSINFO 32 |
| #endif |
| |
| void __init_irt_from_auxv (uintptr_t *auxv) { |
| for (; *auxv != AT_NULL; auxv += 2) { |
| if (*auxv == AT_SYSINFO) |
| irt->nacl_irt_query = (irt->nacl_irt_query_fn_t)auxv[1]; |
| } |
| // We will just crash in __init_irt_table due to NULL pointer access |
| // if we could not find irt->nacl_irt_query. This should not happen. |
| __init_irt_table(); |
| } |
| |