blob: 0d10938ed461f7a78241b45ce350f5907b8fb69b [file] [log] [blame]
// 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();
}