blob: ea59becd2adc2c8e19f07e6b066c83ed2af55cfa [file] [log] [blame]
// ARC MOD TRACK "third_party/nacl-glibc/sysdeps/nacl/irt_syscalls.c"
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include <nacl_stat.h>
// ARC MOD BEGIN
// Add some include files.
#if defined(BARE_METAL_BIONIC)
#include <bare_metal/common/bare_metal_irt.h>
#endif
#include <irt_syscalls.h>
#include <irt.h>
#include <irt_dev.h>
#include <irt_nonsfi.h>
#include <private/at_sysinfo.h>
#include <private/dl_dst_lib.h>
// Remove unnecessary functions which call NaCl syscalls directly.
// Define variables.
// Two macros to minimize the difference between the upstream code and
// this code.
#define off_t nacl_abi_off_t
#define socklen_t nacl_abi_socklen_t
// ARC MOD END
/* Load files from DL_DST_LIB using IRT's open_resource. Other paths
will be processed using regular open syscall.
Note: nacl_mount may change this logic if needed. */
static int (*___nacl_irt_open_resource) (const char* file, int *fd);
static int nacl_irt_open_resource (const char *pathname, int *newfd) {
if (memcmp (DL_DST_LIB "/", pathname, sizeof (DL_DST_LIB)))
return __nacl_irt_open (pathname, O_RDONLY, 0, newfd);
else
return ___nacl_irt_open_resource (pathname + sizeof (DL_DST_LIB) - 1,
newfd);
}
// ARC MOD BEGIN
// Remove unnecessary functions which call NaCl syscalls directly.
// ARC MOD END
static size_t no_interface (const char *interface_ident,
void *table, size_t tablesize) {
return 0;
}
static int not_implemented() {
return (38 /* ENOSYS */);
}
size_t (*__nacl_irt_query) (const char *interface_ident,
void *table, size_t tablesize);
// ARC MOD BEGIN
#ifdef BARE_METAL_BIONIC
// For Bare Metal Mode, we'll inject irt_open_resource. It is necessary
// to run the arc, but it is not yet developed. This just fills the gap.
// TODO(crbug.com/354290): Remove the code when irt_resource_open is actually
// implemented.
// Original irt_query pointer.
static size_t (*___nacl_irt_query) (const char *interface_ident,
void *table, size_t tablesize);
// If available, we'd like to use real irt_open_resource() implementation.
// So, keep the pointer.
static int (*__nacl_irt_open_resource_real) (const char *pathname,
int *newfd);
// The injected version of irt_open_resource opens a local file directly.
// However, __nacl_irt_open will be wrapped by file_wrap.cc later, so we keep
// its raw pointer here.
static int (*__nacl_irt_open_real) (const char *pathname, int oflag,
mode_t cmode, int *newfd);
// Instead of real implementation of irt_open_resource, we use local files for
// the demo.
static int nacl_irt_open_resource_injected(const char *pathname, int *newfd) {
// If available try the real open resource first.
if (__nacl_irt_open_resource_real) {
int error = __nacl_irt_open_resource_real(pathname, newfd);
if (error != ENOSYS)
return error;
}
#if defined(__i386__)
// As this string will be used as a part of an ARC's target name
// (e.g., bare_metal_i686), this must be "i686", not "i386".
#define ARCH "i686"
#elif defined(__arm__)
#define ARCH "arm"
#else
#error "Unknown CPU architecture!"
#endif
// Rewrite the path to local file name. There are two cases to reach here.
// 1) Called from the loader to load shared object files.
// 2) Called from NaClManifestFile.
// The given path name will be different for each case, and that's why
// some files have different paths (such as "/main.nexe" and "main.nexe").
char realpath[256] =
#if defined(__arm__)
"/var/tmp/arc/"
#endif
ARC_TARGET_PATH "/runtime/"
"_platform_specific/bare_metal_" ARCH "/";
// Get the basename (without basename, which libc_common.a does not have).
const char* found = strrchr(pathname, '/');
if (found)
pathname = found + 1;
if (!strcmp(pathname, "main.nexe")) {
strcat(realpath, "arc_bare_metal_" ARCH ".nexe");
} else if (!strcmp(pathname, "readonly_fs_image.img")) {
strcat(realpath, "readonly_fs_image.img");
} else if (!strcmp(pathname, "audio_policy.default.so") ||
!strcmp(pathname, "audio.primary.arc.so") ||
!strcmp(pathname, "gralloc.arc.so") ||
!strcmp(pathname, "local_time.default.so")) {
strcat(strcat(realpath, "hw/"), pathname);
} else if (!strcmp(pathname, "libEGL_emulation.so") ||
!strcmp(pathname, "libGLESv1_CM_emulation.so") ||
!strcmp(pathname, "libGLES_android.so") ||
!strcmp(pathname, "libGLESv2_emulation.so") ||
!strcmp(pathname, "egl.cfg")) {
strcat(strcat(realpath, "egl/"), pathname);
} else if (!strcmp(pathname, "libbundlewrapper.so") ||
!strcmp(pathname, "libdownmix.so") ||
!strcmp(pathname, "libreverbwrapper.so") ||
!strcmp(pathname, "libvisualizer.so")) {
strcat(strcat(realpath, "soundfx/"), pathname);
} else {
strcat(realpath, pathname);
}
return __nacl_irt_open_real(realpath, O_RDONLY, 0, newfd);
}
static size_t nacl_irt_query(const char *interface_ident,
void *table, size_t tablesize) {
size_t result = ___nacl_irt_query(interface_ident, table, tablesize);
if (strcmp(interface_ident, NACL_IRT_RESOURCE_OPEN_v0_1))
return result;
if (tablesize < sizeof(struct nacl_irt_resource_open))
return 0;
if (result > 0 && __nacl_irt_open_resource_real == NULL) {
__nacl_irt_open_resource_real =
((struct nacl_irt_resource_open *)table)->open_resource;
}
// If obtaining nacl_irt_open_resource fails, it means we are
// running unittests. For this case, open_resource call should fail.
struct nacl_irt_resource_open irt_resource_open_injected = {
result ? nacl_irt_open_resource_injected : not_implemented
};
memcpy(table, &irt_resource_open_injected,
sizeof(struct nacl_irt_resource_open));
return sizeof(struct nacl_irt_resource_open);
}
#endif
static int not_implemented_open(const char *pathname, int oflag, mode_t cmode,
int *newfd) {
return ENOSYS;
}
// ARC MOD END
int (*__nacl_irt_mkdir) (const char* pathname, mode_t mode);
int (*__nacl_irt_rmdir) (const char* pathname);
int (*__nacl_irt_chdir) (const char* pathname);
int (*__nacl_irt_getcwd) (char* buf, size_t size);
void (*__nacl_irt_exit) (int status);
int (*__nacl_irt_gettod) (struct timeval *tv);
int (*__nacl_irt_clock) (clock_t *ticks);
// ARC MOD BEGIN UPSTREAM nacl-use-abi-timespec
int (*__nacl_irt_nanosleep) (const struct nacl_abi_timespec *req, struct nacl_abi_timespec *rem);
// ARC MOD END UPSTREAM
int (*__nacl_irt_sched_yield) (void);
int (*__nacl_irt_sysconf) (int name, int *value);
int (*__nacl_irt_open) (const char *pathname, int oflag, mode_t cmode,
int *newfd);
int (*__nacl_irt_close) (int fd);
int (*__nacl_irt_read) (int fd, void *buf, size_t count, size_t *nread);
int (*__nacl_irt_write) (int fd, const void *buf, size_t count,
size_t *nwrote);
int (*__nacl_irt_seek) (int fd, off_t offset, int whence, off_t *new_offset);
int (*__nacl_irt_dup) (int fd, int *newfd);
int (*__nacl_irt_dup2) (int fd, int newfd);
int (*__nacl_irt_fstat) (int fd, struct nacl_abi_stat *);
int (*__nacl_irt_stat) (const char *pathname, struct nacl_abi_stat *);
int (*__nacl_irt_getdents) (int fd, struct dirent *, size_t count,
size_t *nread);
int (*__nacl_irt_socket) (int domain, int type, int protocol, int *sd);
int (*__nacl_irt_accept) (int sockfd, struct sockaddr *addr,
socklen_t *addrlen, int *sd);
int (*__nacl_irt_bind) (int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
int (*__nacl_irt_listen) (int sockfd, int backlog);
int (*__nacl_irt_connect) (int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
int (*__nacl_irt_send) (int sockfd, const void *buf, size_t len, int flags,
int *count);
int (*__nacl_irt_sendmsg) (int sockfd, const struct msghdr *msg, int flags,
int *count);
int (*__nacl_irt_sendto) (int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen,
int *count);
int (*__nacl_irt_recv) (int sockfd, void *buf, size_t len, int flags,
int *count);
int (*__nacl_irt_recvmsg) (int sockfd, struct msghdr *msg, int flags,
int *count);
int (*__nacl_irt_recvfrom) (int sockfd, void *buf, size_t len, int flags,
struct sockaddr *dest_addr, socklen_t* addrlen,
int *count);
int (*__nacl_irt_epoll_create) (int size, int *fd);
int (*__nacl_irt_epoll_create1) (int flags, int *fd);
int (*__nacl_irt_epoll_ctl) (int epfd, int op, int fd,
struct epoll_event *event);
int (*__nacl_irt_epoll_pwait) (int epfd, struct epoll_event *events,
int maxevents, int timeout,
const sigset_t *sigmask, size_t sigset_size,
int *count);
int (*__nacl_irt_epoll_wait) (int epfd, struct epoll_event *events,
int maxevents, int timeout, int *count);
int (*__nacl_irt_poll) (struct pollfd *fds, nfds_t nfds,
int timeout, int *count);
int (*__nacl_irt_ppoll) (struct pollfd *fds, nfds_t nfds,
// ARC MOD BEGIN UPSTREAM nacl-use-abi-timespec
const struct nacl_abi_timespec *timeout,
// ARC MOD END UPSTREAM
const sigset_t *sigmask,
size_t sigset_size, int *count);
int (*__nacl_irt_select) (int nfds, fd_set *readfds,
fd_set *writefds, fd_set *exceptfds,
const struct timeval *timeout,
int *count);
int (*__nacl_irt_pselect) (int nfds, fd_set *readfds,
fd_set *writefds, fd_set *exceptfds,
const struct timeval *timeout,
void* sigmask, int *count);
int (*__nacl_irt_getpeername) (int sockfd, struct sockaddr *addr,
socklen_t *addrlen);
int (*__nacl_irt_getsockname) (int sockfd, struct sockaddr *addr,
socklen_t *addrlen);
int (*__nacl_irt_getsockopt) (int sockfd, int level, int optname,
void *optval, socklen_t *optlen);
int (*__nacl_irt_setsockopt) (int sockfd, int level, int optname,
const void *optval, socklen_t optlen);
int (*__nacl_irt_socketpair) (int domain, int type, int protocol, int sv[2]);
int (*__nacl_irt_shutdown) (int sockfd, int how);
int (*__nacl_irt_sysbrk) (void **newbrk);
int (*__nacl_irt_mmap) (void **addr, size_t len, int prot, int flags,
int fd, off_t off);
int (*__nacl_irt_munmap) (void *addr, size_t len);
int (*__nacl_irt_mprotect) (void *addr, size_t len, int prot);
int (*__nacl_irt_dyncode_create) (void *dest, const void *src, size_t size);
int (*__nacl_irt_dyncode_modify) (void *dest, const void *src, size_t size);
int (*__nacl_irt_dyncode_delete) (void *dest, size_t size);
int (*__nacl_irt_thread_create) (void (*start_user_address)(void),
void *stack,
void *thread_ptr);
void (*__nacl_irt_thread_exit) (int32_t *stack_flag);
int (*__nacl_irt_thread_nice) (const int nice);
int (*__nacl_irt_mutex_create) (int *mutex_handle);
int (*__nacl_irt_mutex_destroy) (int mutex_handle);
int (*__nacl_irt_mutex_lock) (int mutex_handle);
int (*__nacl_irt_mutex_unlock) (int mutex_handle);
int (*__nacl_irt_mutex_trylock) (int mutex_handle);
int (*__nacl_irt_cond_create) (int *cond_handle);
int (*__nacl_irt_cond_destroy) (int cond_handle);
int (*__nacl_irt_cond_signal) (int cond_handle);
int (*__nacl_irt_cond_broadcast) (int cond_handle);
int (*__nacl_irt_cond_wait) (int cond_handle, int mutex_handle);
int (*__nacl_irt_cond_timed_wait_abs) (int cond_handle, int mutex_handle,
// ARC MOD BEGIN UPSTREAM nacl-use-abi-timespec
const struct nacl_abi_timespec *abstime);
// ARC MOD END UPSTREAM
int (*__nacl_irt_tls_init) (void *tdb);
void *(*__nacl_irt_tls_get) (void);
int (*__nacl_irt_open_resource) (const char* file, int *fd);
// ARC MOD BEGIN UPSTREAM nacl-use-abi-timespec
// Use nacl_abi_timespec.
int (*__nacl_irt_clock_getres) (nacl_irt_clockid_t clk_id,
struct nacl_abi_timespec *res);
int (*__nacl_irt_clock_gettime) (nacl_irt_clockid_t clk_id,
struct nacl_abi_timespec *tp);
// ARC MOD END UPSTREAM
int (*__nacl_irt_getpid) (int *pid);
int (*__nacl_irt_unlink)(const char *pathname);
int (*__nacl_irt_truncate)(const char *pathname, off_t length);
int (*__nacl_irt_lstat) (const char *pathname, struct nacl_abi_stat *);
int (*__nacl_irt_link)(const char *oldpath, const char *newpath);
int (*__nacl_irt_rename)(const char *oldpath, const char *newpath);
int (*__nacl_irt_symlink)(const char *oldpath, const char *newpath);
int (*__nacl_irt_chmod)(const char *path, mode_t mode);
int (*__nacl_irt_access)(const char *path, int amode);
int (*__nacl_irt_readlink)(const char *path, char *buf,
size_t count, size_t *nread);
int (*__nacl_irt_utimes)(const char *filename,
const struct timeval *times);
int (*__nacl_irt_fchdir)(int fd);
int (*__nacl_irt_fchmod)(int fd, mode_t mode);
int (*__nacl_irt_fsync)(int fd);
int (*__nacl_irt_fdatasync)(int fd);
int (*__nacl_irt_ftruncate)(int fd, off_t length);
// ARC MOD BEGIN
// Add a function pointer for nacl_list_mappings.
int (*__nacl_irt_list_mappings) (struct NaClMemMappingInfo *regions,
size_t count, size_t *result_count);
// Add functions for nacl_futex.
int (*__nacl_irt_futex_wait_abs) (volatile int *addr, int value,
const struct nacl_abi_timespec *abstime);
int (*__nacl_irt_futex_wake) (volatile int *addr, int nwake, int *count);
// ARC MOD END
// ARC MOD BEGIN
// Add __nacl_irt_write_real.
__LIBC_HIDDEN__
int (*__nacl_irt_write_real) (int fd, const void *buf, size_t count,
size_t *nwrote);
// Add __nacl_irt_clear_cache.
int (*__nacl_irt_clear_cache) (void *addr, size_t size);
// Add Bare Metal specific interfaces.
#if defined(BARE_METAL_BIONIC)
void (*__bare_metal_irt_notify_gdb_of_load)(struct link_map* map);
void (*__bare_metal_irt_notify_gdb_of_unload)(struct link_map* map);
void (*__bare_metal_irt_notify_gdb_of_libraries)(void);
#endif
// ARC MOD END
void
// ARC MOD BEGIN
// Renamed from init_irt_table to __init_irt_table.
__init_irt_table (void)
// ARC MOD END
{
union {
struct nacl_irt_basic nacl_irt_basic;
struct nacl_irt_fdio nacl_irt_fdio;
struct nacl_irt_filename nacl_irt_filename;
// ARC MOD BEGIN
// Use nacl_irt_memory instead of nacl_irt_memory_v0_2 if 0.3 is
// available.
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;
// ARC MOD END
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_dev_getpid nacl_irt_dev_getpid;
struct nacl_irt_dev_fdio nacl_irt_dev_fdio;
struct nacl_irt_dev_filename_v0_2 nacl_irt_dev_filename_v0_2;
struct nacl_irt_dev_filename nacl_irt_dev_filename;
// ARC MOD BEGIN
// Add some IRT interface structures.
struct nacl_irt_futex nacl_irt_futex;
struct nacl_irt_dev_list_mappings nacl_irt_list_mappings;
struct nacl_irt_icache nacl_irt_icache;
#if defined(BARE_METAL_BIONIC)
struct bare_metal_irt_debugger bare_metal_irt_debugger;
#endif
// ARC MOD END
} u;
if (__nacl_irt_query &&
__nacl_irt_query (NACL_IRT_BASIC_v0_1, &u.nacl_irt_basic,
sizeof(u.nacl_irt_basic)) == sizeof(u.nacl_irt_basic))
{
__nacl_irt_exit = u.nacl_irt_basic.exit;
__nacl_irt_gettod = u.nacl_irt_basic.gettod;
__nacl_irt_clock = u.nacl_irt_basic.clock;
__nacl_irt_nanosleep = u.nacl_irt_basic.nanosleep;
__nacl_irt_sched_yield = u.nacl_irt_basic.sched_yield;
__nacl_irt_sysconf = u.nacl_irt_basic.sysconf;
}
// ARC MOD BEGIN
// Remove the fallback to direct NaCl syscalls.
// ARC MOD END
// ARC MOD BEGIN
// TODO(crbug.com/242349): Getting NACL_IRT_DEV_FDIO_v0_2 always fails at
// this point. Need to fix native_client/src/untrusted/irt/irt_interfaces.c.
// ARC MOD END
if (__nacl_irt_query &&
__nacl_irt_query (NACL_IRT_FDIO_v0_1, &u.nacl_irt_fdio,
sizeof(u.nacl_irt_fdio)) == sizeof(u.nacl_irt_fdio))
{
__nacl_irt_close = u.nacl_irt_fdio.close;
__nacl_irt_dup = u.nacl_irt_fdio.dup;
__nacl_irt_dup2 = u.nacl_irt_fdio.dup2;
__nacl_irt_read = u.nacl_irt_fdio.read;
__nacl_irt_write = u.nacl_irt_fdio.write;
__nacl_irt_seek = u.nacl_irt_fdio.seek;
__nacl_irt_fstat = u.nacl_irt_fdio.fstat;
__nacl_irt_getdents = u.nacl_irt_fdio.getdents;
}
// ARC MOD BEGIN
// Remove the fallback to direct NaCl syscalls.
// ARC MOD END
// ARC MOD BEGIN
// For Bare Metal's debugger support. See crbug.com/354290
__nacl_irt_open = not_implemented_open;
#ifdef BARE_METAL_BIONIC
// TODO(crbug.com/354290): Remove this code.
__nacl_irt_open_real = not_implemented_open;
#endif
// ARC MOD END
if (__nacl_irt_query &&
__nacl_irt_query (NACL_IRT_FILENAME_v0_1, &u.nacl_irt_filename,
sizeof(u.nacl_irt_filename)) ==
sizeof(u.nacl_irt_filename))
{
__nacl_irt_open = u.nacl_irt_filename.open;
// ARC MOD BEGIN
// Upstream uses nacl_abi_stat as it #define stat.
// __nacl_irt_stat = u.nacl_irt_filename.nacl_abi_stat;
__nacl_irt_stat = u.nacl_irt_filename.stat;
}
// Remove the fallback to direct NaCl syscalls.
// ARC MOD END
// ARC MOD BEGIN
// Do not fill __nacl_irt_sysbrk and use NACL_IRT_MEMORY_v0_3.
__nacl_irt_sysbrk = not_implemented;
if (__nacl_irt_query &&
__nacl_irt_query(NACL_IRT_MEMORY_v0_3, &u.nacl_irt_memory,
sizeof(u.nacl_irt_memory)) ==
sizeof(u.nacl_irt_memory)) {
__nacl_irt_mmap = u.nacl_irt_memory.mmap;
__nacl_irt_munmap = u.nacl_irt_memory.munmap;
__nacl_irt_mprotect = u.nacl_irt_memory.mprotect;
}
// Remove the fallback to direct NaCl syscalls and old IRT handling.
// ARC MOD END
if (__nacl_irt_query &&
__nacl_irt_query (NACL_IRT_DYNCODE_v0_1, &u.nacl_irt_dyncode,
sizeof(u.nacl_irt_dyncode)) ==
sizeof(u.nacl_irt_dyncode))
{
__nacl_irt_dyncode_create = u.nacl_irt_dyncode.dyncode_create;
__nacl_irt_dyncode_modify = u.nacl_irt_dyncode.dyncode_modify;
__nacl_irt_dyncode_delete = u.nacl_irt_dyncode.dyncode_delete;
}
// ARC MOD BEGIN
// Remove the fallback to direct NaCl syscalls.
// ARC MOD END
if (__nacl_irt_query &&
__nacl_irt_query (NACL_IRT_THREAD_v0_1, &u.nacl_irt_thread,
sizeof(u.nacl_irt_thread)) ==
sizeof(u.nacl_irt_thread))
{
__nacl_irt_thread_create = u.nacl_irt_thread.thread_create;
__nacl_irt_thread_exit = u.nacl_irt_thread.thread_exit;
__nacl_irt_thread_nice = u.nacl_irt_thread.thread_nice;
}
// ARC MOD BEGIN
// Remove the fallback to direct NaCl syscalls.
// ARC MOD END
// ARC MOD BEGIN
// Remove deprecated NACL_IRT_MUTEX and NACL_IRT_COND.
// ARC MOD END
if (__nacl_irt_query &&
__nacl_irt_query (NACL_IRT_TLS_v0_1, &u.nacl_irt_tls,
sizeof(u.nacl_irt_tls)) == sizeof(u.nacl_irt_tls))
{
__nacl_irt_tls_init = u.nacl_irt_tls.tls_init;
__nacl_irt_tls_get = u.nacl_irt_tls.tls_get;
}
// ARC MOD BEGIN
// Remove the fallback to direct NaCl syscalls.
// ARC MOD END
if (__nacl_irt_query &&
__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))
{
___nacl_irt_open_resource = u.nacl_irt_resource_open.open_resource;
__nacl_irt_open_resource = nacl_irt_open_resource;
#ifdef IS_IN_rtld
if (_dl_argc == 1)
{
static const char *argv[] =
{
DL_DST_LIB "/runnable-ld.so",
DL_DST_LIB "/main.nexe",
0
};
_dl_argc = 2;
_dl_argv = (char **)argv;
}
#endif
}
// ARC MOD BEGIN
// Remove the fallback to direct NaCl syscalls.
// ARC MOD END
if (__nacl_irt_query &&
__nacl_irt_query (NACL_IRT_CLOCK_v0_1, &u.nacl_irt_clock,
sizeof(u.nacl_irt_clock)) == sizeof(u.nacl_irt_clock))
{
__nacl_irt_clock_getres = u.nacl_irt_clock.clock_getres;
__nacl_irt_clock_gettime = u.nacl_irt_clock.clock_gettime;
}
// ARC MOD BEGIN
// Remove the fallback to direct NaCl syscalls.
// ARC MOD END
if (__nacl_irt_query &&
__nacl_irt_query (NACL_IRT_DEV_GETPID_v0_1, &u.nacl_irt_dev_getpid,
sizeof(u.nacl_irt_dev_getpid)) ==
sizeof(u.nacl_irt_dev_getpid))
{
__nacl_irt_getpid = u.nacl_irt_dev_getpid.getpid;
}
else
{
__nacl_irt_getpid = not_implemented;
}
// ARC MOD BEGIN
// TODO(crbug.com/242349): Getting NACL_IRT_DEV_FDIO_v0_2 always
// fails at this point. For SFI NaCl, we should be able to use v0_3
// interface, but this is not ready in non-SFI mode.
// ARC MOD END
if (__nacl_irt_query &&
__nacl_irt_query (NACL_IRT_DEV_FDIO_v0_2, &u.nacl_irt_dev_fdio,
sizeof(u.nacl_irt_dev_fdio)) ==
sizeof(u.nacl_irt_dev_fdio))
{
__nacl_irt_fchdir = u.nacl_irt_dev_fdio.fchdir;
__nacl_irt_fchmod = u.nacl_irt_dev_fdio.fchmod;
__nacl_irt_fsync = u.nacl_irt_dev_fdio.fsync;
__nacl_irt_fdatasync = u.nacl_irt_dev_fdio.fdatasync;
__nacl_irt_ftruncate = u.nacl_irt_dev_fdio.ftruncate;
}
else
{
__nacl_irt_fchdir = not_implemented;
// ARC MOD BEGIN
// Add a cast. We need this because mode_t is a short and GCC
// thinks this is incompatible with variable args.
__nacl_irt_fchmod = (int (*)(int, mode_t))not_implemented;
// ARC MOD END
__nacl_irt_fsync = not_implemented;
__nacl_irt_fdatasync = not_implemented;
__nacl_irt_ftruncate = not_implemented;
}
if (__nacl_irt_query &&
__nacl_irt_query (NACL_IRT_DEV_FILENAME_v0_3, &u.nacl_irt_dev_filename,
sizeof(u.nacl_irt_dev_filename)) ==
sizeof(u.nacl_irt_dev_filename))
{
// ARC MOD BEGIN
__nacl_irt_open = u.nacl_irt_dev_filename.open;
// For Bare Metal's debugger support. See crbug.com/354290
#ifdef BARE_METAL_BIONIC
// TODO(crbug.com/354290): Remove this code.
__nacl_irt_open_real = u.nacl_irt_dev_filename.open;
#endif
// Upstream uses nacl_abi_stat as it #define stat.
// __nacl_irt_stat = u.nacl_irt_filename.nacl_abi_stat;
__nacl_irt_stat = u.nacl_irt_filename.stat;
// ARC MOD END
__nacl_irt_mkdir = u.nacl_irt_dev_filename.mkdir;
__nacl_irt_chdir = u.nacl_irt_dev_filename.chdir;
__nacl_irt_rmdir = u.nacl_irt_dev_filename.rmdir;
__nacl_irt_getcwd = u.nacl_irt_dev_filename.getcwd;
__nacl_irt_unlink = u.nacl_irt_dev_filename.unlink;
__nacl_irt_truncate = u.nacl_irt_dev_filename.truncate;
__nacl_irt_lstat = u.nacl_irt_dev_filename.lstat;
__nacl_irt_link = u.nacl_irt_dev_filename.link;
__nacl_irt_rename = u.nacl_irt_dev_filename.rename;
__nacl_irt_symlink = u.nacl_irt_dev_filename.symlink;
__nacl_irt_chmod = u.nacl_irt_dev_filename.chmod;
__nacl_irt_access = u.nacl_irt_dev_filename.access;
__nacl_irt_readlink = u.nacl_irt_dev_filename.readlink;
__nacl_irt_utimes = u.nacl_irt_dev_filename.utimes;
}
else if (__nacl_irt_query &&
__nacl_irt_query (NACL_IRT_DEV_FILENAME_v0_2,
&u.nacl_irt_dev_filename_v0_2,
sizeof(u.nacl_irt_dev_filename_v0_2)) ==
sizeof(u.nacl_irt_dev_filename_v0_2))
{
__nacl_irt_mkdir = u.nacl_irt_dev_filename_v0_2.mkdir;
__nacl_irt_chdir = u.nacl_irt_dev_filename_v0_2.chdir;
__nacl_irt_rmdir = u.nacl_irt_dev_filename_v0_2.rmdir;
__nacl_irt_getcwd = u.nacl_irt_dev_filename_v0_2.getcwd;
__nacl_irt_unlink = u.nacl_irt_dev_filename_v0_2.unlink;
__nacl_irt_truncate = not_implemented;
__nacl_irt_lstat = not_implemented;
__nacl_irt_link = not_implemented;
__nacl_irt_rename = not_implemented;
__nacl_irt_symlink = not_implemented;
// ARC MOD BEGIN
// Add a cast. We need this because mode_t is a short and GCC
// thinks this is incompatible with variable args.
__nacl_irt_chmod = (int (*)(const char *, mode_t))not_implemented;
// ARC MOD END
__nacl_irt_access = not_implemented;
__nacl_irt_readlink = not_implemented;
__nacl_irt_utimes = not_implemented;
}
else
{
// ARC MOD BEGIN
// Add a cast. We need this because mode_t is a short and GCC
// thinks this is incompatible with variable args.
__nacl_irt_mkdir = (int (*)(const char *, mode_t))not_implemented;
// ARC MOD END
__nacl_irt_chdir = not_implemented;
__nacl_irt_rmdir = not_implemented;
__nacl_irt_getcwd = not_implemented;
__nacl_irt_unlink = not_implemented;
__nacl_irt_truncate = not_implemented;
__nacl_irt_lstat = not_implemented;
__nacl_irt_link = not_implemented;
__nacl_irt_rename = not_implemented;
__nacl_irt_symlink = not_implemented;
// ARC MOD BEGIN
// Add a cast. We need this because mode_t is a short and GCC
// thinks this is incompatible with variable args.
__nacl_irt_chmod = (int (*)(const char *, mode_t))not_implemented;
// ARC MOD END
__nacl_irt_access = not_implemented;
__nacl_irt_readlink = not_implemented;
__nacl_irt_utimes = not_implemented;
}
// ARC MOD BEGIN
// Get __nacl_irt_list_mappings.
if (__nacl_irt_query &&
__nacl_irt_query(NACL_IRT_DEV_LIST_MAPPINGS_v0_1,
&u.nacl_irt_list_mappings,
sizeof(u.nacl_irt_list_mappings)) ==
sizeof(u.nacl_irt_list_mappings)) {
__nacl_irt_list_mappings = u.nacl_irt_list_mappings.list_mappings;
}
// Get futex functions.
if (__nacl_irt_query &&
__nacl_irt_query(NACL_IRT_FUTEX_v0_1,
&u.nacl_irt_futex,
sizeof(u.nacl_irt_futex)) ==
sizeof(u.nacl_irt_futex)) {
__nacl_irt_futex_wait_abs = u.nacl_irt_futex.futex_wait_abs;
__nacl_irt_futex_wake = u.nacl_irt_futex.futex_wake;
}
// Get __nacl_irt_clear_cache.
// __nacl_irt_clear_cache is supported only for Non-SFI NaCl on ARM.
__nacl_irt_clear_cache = not_implemented;
if (__nacl_irt_query &&
__nacl_irt_query(NACL_IRT_ICACHE_v0_1,
&u.nacl_irt_icache,
sizeof(u.nacl_irt_icache)) ==
sizeof(u.nacl_irt_icache)) {
__nacl_irt_clear_cache = u.nacl_irt_icache.clear_cache;
}
// ARC MOD END
// ARC MOD BEGIN
// Add Bare Metal specific interfaces.
#if defined(BARE_METAL_BIONIC)
if (__nacl_irt_query &&
__nacl_irt_query(BARE_METAL_IRT_DEBUGGER_v0_1,
&u.bare_metal_irt_debugger,
sizeof(u.bare_metal_irt_debugger)) ==
sizeof(u.bare_metal_irt_debugger)) {
__bare_metal_irt_notify_gdb_of_load =
u.bare_metal_irt_debugger.notify_gdb_of_load;
__bare_metal_irt_notify_gdb_of_unload =
u.bare_metal_irt_debugger.notify_gdb_of_unload;
__bare_metal_irt_notify_gdb_of_libraries =
u.bare_metal_irt_debugger.notify_gdb_of_libraries;
}
#endif
// ARC MOD END
__nacl_irt_epoll_create = not_implemented;
__nacl_irt_epoll_create1 = not_implemented;
__nacl_irt_epoll_ctl = not_implemented;
__nacl_irt_epoll_pwait = not_implemented;
__nacl_irt_epoll_wait = not_implemented;
__nacl_irt_poll = not_implemented;
__nacl_irt_ppoll = not_implemented;
__nacl_irt_socket = not_implemented;
__nacl_irt_accept = not_implemented;
__nacl_irt_bind = not_implemented;
__nacl_irt_listen = not_implemented;
__nacl_irt_connect = not_implemented;
__nacl_irt_send = not_implemented;
__nacl_irt_sendmsg = not_implemented;
__nacl_irt_sendto = not_implemented;
__nacl_irt_recv = not_implemented;
__nacl_irt_recvmsg = not_implemented;
__nacl_irt_recvfrom = not_implemented;
__nacl_irt_select = not_implemented;
__nacl_irt_pselect = not_implemented;
__nacl_irt_getpeername = not_implemented;
__nacl_irt_getsockname = not_implemented;
__nacl_irt_getsockopt = not_implemented;
__nacl_irt_setsockopt = not_implemented;
__nacl_irt_socketpair = not_implemented;
__nacl_irt_shutdown = not_implemented;
// ARC MOD BEGIN
// Initialize __nacl_irt_write_real.
__nacl_irt_write_real = __nacl_irt_write;
// ARC MOD END
}
size_t nacl_interface_query(const char *interface_ident,
void *table, size_t tablesize) {
return (*__nacl_irt_query)(interface_ident, table, tablesize);
}
// ARC MOD BEGIN
// Note that this function or __init_irt_table() must be called from
// both the loader and main program because the addresses of their
// __nacl_irt_* are different.
void __init_irt_from_irt_query(__nacl_irt_query_fn_t irt_query) {
#ifdef BARE_METAL_BIONIC
// TODO(crbug.com/354290): Remove this code.
___nacl_irt_query = irt_query;
__nacl_irt_query = nacl_irt_query;
#else
__nacl_irt_query = irt_query;
#endif
// We will just crash in __init_irt_table due to NULL pointer access
// if we could not find __nacl_irt_query. This should not happen.
__init_irt_table();
}
// ARC MOD END