| Index: tests/stacked_irt/irt_trace.c
|
| diff --git a/tests/stacked_irt/irt_trace.c b/tests/stacked_irt/irt_trace.c
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c64092dc03ec885a2d9d5eddc29717548660e5bc
|
| --- /dev/null
|
| +++ b/tests/stacked_irt/irt_trace.c
|
| @@ -0,0 +1,844 @@
|
| +/*
|
| + * Copyright (c) 2013 The Native Client Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style license that can be
|
| + * found in the LICENSE file.
|
| + */
|
| +
|
| +#include <string.h>
|
| +
|
| +#include <stdarg.h>
|
| +#include <stddef.h>
|
| +#include <stdio.h>
|
| +#include <sys/types.h>
|
| +#include <time.h>
|
| +
|
| +#include "native_client/src/include/nacl_macros.h"
|
| +#include "native_client/src/include/portability.h"
|
| +#include "native_client/src/untrusted/irt/irt.h"
|
| +#include "native_client/src/untrusted/irt/irt_interfaces.h"
|
| +#include "native_client/src/untrusted/irt/irt_module.h"
|
| +
|
| +#include "native_client/tests/stacked_irt/irt_trace.h"
|
| +
|
| +#include "native_client/src/untrusted/nacl/nacl_irt.h"
|
| +
|
| +static struct nacl_irt_basic __nacl_irt_basic;
|
| +static struct nacl_irt_fdio __nacl_irt_fdio;
|
| +static struct nacl_irt_dev_filename __nacl_irt_dev_filename;
|
| +static struct nacl_irt_memory __nacl_irt_memory;
|
| +static struct nacl_irt_dyncode __nacl_irt_dyncode;
|
| +static struct nacl_irt_thread __nacl_irt_thread;
|
| +static struct nacl_irt_futex __nacl_irt_futex;
|
| +static struct nacl_irt_mutex __nacl_irt_mutex;
|
| +static struct nacl_irt_cond __nacl_irt_cond;
|
| +static struct nacl_irt_sem __nacl_irt_sem;
|
| +static struct nacl_irt_tls __nacl_irt_tls;
|
| +static struct nacl_irt_blockhook __nacl_irt_blockhook;
|
| +#ifdef IRT_PPAPI
|
| +static struct nacl_irt_ppapihook __nacl_irt_ppapihook;
|
| +#endif
|
| +static struct nacl_irt_resource_open __nacl_irt_resource_open;
|
| +static struct nacl_irt_random __nacl_irt_random;
|
| +static struct nacl_irt_clock __nacl_irt_clock;
|
| +static struct nacl_irt_exception_handling __nacl_irt_exception_handling;
|
| +
|
| +struct irt_trace {
|
| + int timestamp;
|
| +};
|
| +
|
| +static struct irt_trace *irt_trace_get(void) {
|
| + return (struct irt_trace *) nacl_irt_get_context()->private_data;
|
| +}
|
| +
|
| +size_t irt_vdprintf(int d, char const *fmt, va_list ap) {
|
| + static char buf[1024];
|
| + int rv;
|
| + size_t wrote;
|
| +
|
| + /*
|
| + * We cannot dynamically allocate the buffer here since malloc
|
| + * internally uses mmap/munmap/sysbrk which could potentially
|
| + * lead to an infinite loop.
|
| + */
|
| + rv = vsnprintf(buf, sizeof buf, fmt, ap);
|
| + if (rv >= 0) {
|
| + __nacl_irt_fdio.write(d, buf, rv, &wrote); /* TODO: check rv */
|
| + rv = wrote;
|
| + }
|
| +
|
| + return rv;
|
| +}
|
| +
|
| +size_t irt_dprintf(int d, char const *fmt, ...) {
|
| + va_list ap;
|
| + size_t rv;
|
| +
|
| + va_start(ap, fmt);
|
| + rv = irt_vdprintf(d, fmt, ap);
|
| + va_end(ap);
|
| +
|
| + return rv;
|
| +}
|
| +
|
| +char *irt_timestamp_string(char *buf,
|
| + size_t size) {
|
| + struct timeval tv;
|
| + struct tm bdt; /* broken down time */
|
| +
|
| + if (-1 == __nacl_irt_basic.gettod(&tv)) {
|
| + snprintf(buf, size, "-NA-");
|
| + return buf;
|
| + }
|
| + (void) localtime_r(&tv.tv_sec, &bdt);
|
| + /* suseconds_t holds at most 10**6 < 16**6 = (2**4)**6 = 2**24 < 2**32 */
|
| + snprintf(buf, size, "%02d:%02d:%02d.%06d",
|
| + bdt.tm_hour, bdt.tm_min, bdt.tm_sec, (int) tv.tv_usec);
|
| + return buf;
|
| +}
|
| +
|
| +static void irt_output_tag(int d) {
|
| + struct irt_trace *trace = irt_trace_get();
|
| + char timestamp[128];
|
| + /*int pid; */
|
| +
|
| + if (trace->timestamp) {
|
| + irt_dprintf(d, "[%s] ",
|
| + irt_timestamp_string(timestamp, sizeof timestamp));
|
| + }
|
| + /*if (timestamp_enabled && tag_output) {
|
| + pid = GETPID();
|
| + gprintf(s, "[%d,%u:%s] ",
|
| + pid,
|
| + NaClThreadId(),
|
| + NaClTimeStampString(timestamp, sizeof timestamp));
|
| + tag_output = 0;
|
| + }*/
|
| +}
|
| +
|
| +#if 0
|
| +#define IRT_TRACE_CALL(name) do { \
|
| + static const char msg[] = ""name"\n"; \
|
| + size_t wrote; \
|
| + __nacl_irt_fdio.write(2, msg, sizeof(msg) - 1, &wrote); \
|
| + } while (0);
|
| +#else
|
| +#define IRT_TRACE_CALL(name) do { \
|
| + static char msg[100]; \
|
| + int length; \
|
| + size_t wrote; \
|
| + length = snprintf(msg, sizeof(msg), "%s() = 0\n", name); \
|
| + __nacl_irt_fdio.write(2, msg, length, &wrote); \
|
| + } while (0);
|
| +#define IRT_TRACE_CALL1(interface, name) do { \
|
| + static char msg[100]; \
|
| + int length; \
|
| + size_t wrote; \
|
| + irt_output_tag(2); \
|
| + length = snprintf(msg, sizeof(msg), "%s.%s()%20s", interface, name, ""); \
|
| + __nacl_irt_fdio.write(2, msg, length, &wrote); \
|
| + } while (0);
|
| +#endif
|
| +
|
| +static void irt_trace_exit(int status) {
|
| + IRT_TRACE_CALL1("basic", "exit");
|
| + __nacl_irt_basic.exit(status);
|
| +}
|
| +
|
| +static int irt_trace_gettod(struct timeval *tv) {
|
| + IRT_TRACE_CALL1("basic", "gettod");
|
| + return __nacl_irt_basic.gettod(tv);
|
| +}
|
| +
|
| +static int irt_trace_clock(clock_t *ticks) {
|
| + IRT_TRACE_CALL1("basic", "clock");
|
| + return __nacl_irt_basic.clock(ticks);
|
| +}
|
| +
|
| +static int irt_trace_nanosleep(const struct timespec *req, struct timespec *rem) {
|
| + IRT_TRACE_CALL1("basic", "nanosleep");
|
| + return __nacl_irt_basic.nanosleep(req, rem);
|
| +}
|
| +
|
| +static int irt_trace_sched_yield(void) {
|
| + IRT_TRACE_CALL1("basic", "sched_yield");
|
| + return __nacl_irt_basic.sched_yield();
|
| +}
|
| +
|
| +static int irt_trace_sysconf(int name, int *value) {
|
| + int rv;
|
| + IRT_TRACE_CALL1("basic", "sysconf");
|
| + rv = __nacl_irt_basic.sysconf(name, value);
|
| + irt_dprintf(2, " = %d\n", rv);
|
| + return rv;
|
| +}
|
| +
|
| +static struct nacl_irt_basic logged_nacl_irt_basic = {
|
| + irt_trace_exit,
|
| + irt_trace_gettod,
|
| + irt_trace_clock,
|
| + irt_trace_nanosleep,
|
| + irt_trace_sched_yield,
|
| + irt_trace_sysconf,
|
| +};
|
| +
|
| +static int irt_trace_close(int fd) {
|
| + int rv;
|
| + /*IRT_TRACE_CALL1("fdio", "close");*/
|
| + irt_dprintf(2, "fdio.close(%d", fd);
|
| + rv = __nacl_irt_fdio.close(fd);
|
| + irt_dprintf(2, ")%20s = %d\n", "", rv);
|
| + return rv;
|
| +}
|
| +
|
| +static int irt_trace_read(int fd, void *buf, size_t count, size_t *nread) {
|
| + IRT_TRACE_CALL1("fdio", "read");
|
| + return __nacl_irt_fdio.read(fd, buf, count, nread);
|
| +}
|
| +
|
| +static int irt_trace_write(int fd, const void *buf, size_t count,
|
| + size_t *nwrote) {
|
| + int rv;
|
| + /*IRT_TRACE_CALL1("fdio", "write");*/
|
| + irt_dprintf(2, "fdio.write(%d, \"%s\", %zd, %p)", fd, buf, count, nwrote);
|
| + rv = __nacl_irt_fdio.write(fd, buf, count, nwrote);
|
| + irt_dprintf(2, " = %d\n", rv);
|
| + return rv;
|
| +}
|
| +
|
| +static int irt_trace_seek(int fd, off_t offset, int whence, off_t *new_offset) {
|
| + IRT_TRACE_CALL1("fdio", "seek");
|
| + return __nacl_irt_fdio.seek(fd, offset, whence, new_offset);
|
| +}
|
| +
|
| +static int irt_trace_dup(int fd, int *newfd) {
|
| + IRT_TRACE_CALL1("fdio", "dup");
|
| + return __nacl_irt_fdio.dup(fd, newfd);
|
| +}
|
| +
|
| +static int irt_trace_dup2(int fd, int newfd) {
|
| + IRT_TRACE_CALL1("fdio", "dup2");
|
| + return __nacl_irt_fdio.dup2(fd, newfd);
|
| +}
|
| +
|
| +static int irt_trace_fstat(int fd, struct stat *st) {
|
| + int rv;
|
| + /*IRT_TRACE_CALL1("fdio", "fstat");*/
|
| + irt_dprintf(2, "fdio.fstat(%d, %x)", fd);
|
| + rv = __nacl_irt_fdio.fstat(fd, st);
|
| + irt_dprintf(2, "%20s = %d\n", "", rv);
|
| + return rv;
|
| +}
|
| +
|
| +static int irt_trace_getdents(int fd, struct dirent *buf, size_t count,
|
| + size_t *nread) {
|
| + IRT_TRACE_CALL1("fdio", "getdents");
|
| + return __nacl_irt_fdio.getdents(fd, buf, count, nread);
|
| +}
|
| +
|
| +static struct nacl_irt_fdio logged_nacl_irt_fdio = {
|
| + irt_trace_close,
|
| + irt_trace_dup,
|
| + irt_trace_dup2,
|
| + irt_trace_read,
|
| + irt_trace_write,
|
| + irt_trace_seek,
|
| + irt_trace_fstat,
|
| + irt_trace_getdents,
|
| +};
|
| +
|
| +static int irt_trace_open(const char *pathname, int oflag, mode_t cmode, int *newfd) {
|
| + IRT_TRACE_CALL("open");
|
| + return __nacl_irt_dev_filename.open(pathname, oflag, cmode, newfd);
|
| +}
|
| +
|
| +static int irt_trace_stat(const char *pathname, struct stat *buf) {
|
| + IRT_TRACE_CALL("stat");
|
| + return __nacl_irt_dev_filename.stat(pathname, buf);
|
| +}
|
| +
|
| +static int irt_trace_mkdir(const char *pathname, mode_t mode) {
|
| + IRT_TRACE_CALL("mkdir");
|
| + return __nacl_irt_dev_filename.mkdir(pathname, mode);
|
| +}
|
| +
|
| +static int irt_trace_rmdir(const char *pathname) {
|
| + IRT_TRACE_CALL("rmdir");
|
| + return __nacl_irt_dev_filename.rmdir(pathname);
|
| +}
|
| +
|
| +static int irt_trace_chdir(const char *pathname) {
|
| + IRT_TRACE_CALL("chdir");
|
| + return __nacl_irt_dev_filename.chdir(pathname);
|
| +}
|
| +
|
| +static int irt_trace_getcwd(char *pathname, size_t len) {
|
| + IRT_TRACE_CALL("getcwd");
|
| + return __nacl_irt_dev_filename.getcwd(pathname, len);
|
| +}
|
| +
|
| +static int irt_trace_unlink(const char *pathname) {
|
| + IRT_TRACE_CALL("unlink");
|
| + return __nacl_irt_dev_filename.unlink(pathname);
|
| +}
|
| +
|
| +static struct nacl_irt_dev_filename logged_nacl_irt_dev_filename = {
|
| + irt_trace_open,
|
| + irt_trace_stat,
|
| + irt_trace_mkdir,
|
| + irt_trace_rmdir,
|
| + irt_trace_chdir,
|
| + irt_trace_getcwd,
|
| + irt_trace_unlink,
|
| +};
|
| +
|
| +static int irt_trace_mmap(void **addr, size_t len, int prot, int flags, int fd, off_t off) {
|
| + IRT_TRACE_CALL("mmap");
|
| + return __nacl_irt_memory.mmap(addr, len, prot, flags, fd, off);
|
| +}
|
| +static int irt_trace_munmap(void *addr, size_t len) {
|
| + IRT_TRACE_CALL("munmap");
|
| + return __nacl_irt_memory.munmap(addr, len);
|
| +}
|
| +static int irt_trace_mprotect(void *addr, size_t len, int prot) {
|
| + IRT_TRACE_CALL("mprotect");
|
| + return __nacl_irt_memory.mprotect(addr, len, prot);
|
| +}
|
| +
|
| +static struct nacl_irt_memory logged_nacl_irt_memory = {
|
| + irt_trace_mmap,
|
| + irt_trace_munmap,
|
| + irt_trace_mprotect,
|
| +};
|
| +
|
| +static int irt_trace_dyncode_create(void *dest, const void *src, size_t size) {
|
| + IRT_TRACE_CALL("dyncode_create");
|
| + return __nacl_irt_dyncode.dyncode_create(dest, src, size);
|
| +}
|
| +static int irt_trace_dyncode_modify(void *dest, const void *src, size_t size) {
|
| + IRT_TRACE_CALL("dyncode_modify");
|
| + return __nacl_irt_dyncode.dyncode_modify(dest, src, size);
|
| +}
|
| +static int irt_trace_dyncode_delete(void *dest, size_t size) {
|
| + IRT_TRACE_CALL("dyncode_delete");
|
| + return __nacl_irt_dyncode.dyncode_delete(dest, size);
|
| +}
|
| +
|
| +static struct nacl_irt_dyncode logged_nacl_irt_dyncode = {
|
| + irt_trace_dyncode_create,
|
| + irt_trace_dyncode_modify,
|
| + irt_trace_dyncode_delete,
|
| +};
|
| +
|
| +static int irt_trace_thread_create(void (*start_func)(void), void *stack, void *thread_ptr) {
|
| + IRT_TRACE_CALL("thread_create");
|
| + return __nacl_irt_thread.thread_create(start_func, stack, thread_ptr);
|
| +}
|
| +static void irt_trace_thread_exit(int32_t *stack_flag) {
|
| + IRT_TRACE_CALL("thread_exit");
|
| + __nacl_irt_thread.thread_exit(stack_flag);
|
| +}
|
| +static int irt_trace_thread_nice(const int nice) {
|
| + IRT_TRACE_CALL("thread_nice");
|
| + return __nacl_irt_thread.thread_nice(nice);
|
| +}
|
| +
|
| +static struct nacl_irt_thread logged_nacl_irt_thread = {
|
| + irt_trace_thread_create,
|
| + irt_trace_thread_exit,
|
| + irt_trace_thread_nice,
|
| +};
|
| +
|
| +static int irt_trace_futex_wait_abs(volatile int *addr, int value, const struct timespec *abstime) {
|
| + IRT_TRACE_CALL("futex_wait_abs");
|
| + return __nacl_irt_futex.futex_wait_abs(addr, value, abstime);
|
| +}
|
| +static int irt_trace_futex_wake(volatile int *addr, int nwake, int *count) {
|
| + IRT_TRACE_CALL("futex_wake");
|
| + return __nacl_irt_futex.futex_wake(addr, nwake, count);
|
| +}
|
| +
|
| +static struct nacl_irt_futex logged_nacl_irt_futex = {
|
| + irt_trace_futex_wait_abs,
|
| + irt_trace_futex_wake,
|
| +};
|
| +
|
| +static int irt_trace_mutex_create(int *mutex_handle) {
|
| + IRT_TRACE_CALL("mutex_create");
|
| + return __nacl_irt_mutex.mutex_create(mutex_handle);
|
| +}
|
| +static int irt_trace_mutex_destroy(int mutex_handle) {
|
| + IRT_TRACE_CALL("mutex_destroy");
|
| + return __nacl_irt_mutex.mutex_destroy(mutex_handle);
|
| +}
|
| +static int irt_trace_mutex_lock(int mutex_handle) {
|
| + IRT_TRACE_CALL("mutex_lock");
|
| + return __nacl_irt_mutex.mutex_lock(mutex_handle);
|
| +}
|
| +static int irt_trace_mutex_unlock(int mutex_handle) {
|
| + IRT_TRACE_CALL("mutex_unlock");
|
| + return __nacl_irt_mutex.mutex_unlock(mutex_handle);
|
| +}
|
| +static int irt_trace_mutex_trylock(int mutex_handle) {
|
| + IRT_TRACE_CALL("mutex_trylock");
|
| + return __nacl_irt_mutex.mutex_trylock(mutex_handle);
|
| +}
|
| +
|
| +static struct nacl_irt_mutex logged_nacl_irt_mutex = {
|
| + irt_trace_mutex_create,
|
| + irt_trace_mutex_destroy,
|
| + irt_trace_mutex_lock,
|
| + irt_trace_mutex_unlock,
|
| + irt_trace_mutex_trylock,
|
| +};
|
| +
|
| +static int irt_trace_cond_create(int *cond_handle) {
|
| + IRT_TRACE_CALL("cond_create");
|
| + return __nacl_irt_cond.cond_create(cond_handle);
|
| +}
|
| +static int irt_trace_cond_destroy(int cond_handle) {
|
| + IRT_TRACE_CALL("cond_destroy");
|
| + return __nacl_irt_cond.cond_destroy(cond_handle);
|
| +}
|
| +static int irt_trace_cond_signal(int cond_handle) {
|
| + IRT_TRACE_CALL("cond_signal");
|
| + return __nacl_irt_cond.cond_signal(cond_handle);
|
| +}
|
| +static int irt_trace_cond_broadcast(int cond_handle) {
|
| + IRT_TRACE_CALL("cond_broadcast");
|
| + return __nacl_irt_cond.cond_broadcast(cond_handle);
|
| +}
|
| +static int irt_trace_cond_wait(int cond_handle, int mutex_handle) {
|
| + IRT_TRACE_CALL("cond_wait");
|
| + return __nacl_irt_cond.cond_wait(cond_handle, mutex_handle);
|
| +}
|
| +static int irt_trace_cond_timed_wait_abs(int cond_handle, int mutex_handle, const struct timespec *abstime) {
|
| + IRT_TRACE_CALL("cond_timed_wait_abs");
|
| + return __nacl_irt_cond.cond_timed_wait_abs(cond_handle, mutex_handle, abstime);
|
| +}
|
| +
|
| +static struct nacl_irt_cond logged_nacl_irt_cond = {
|
| + irt_trace_cond_create,
|
| + irt_trace_cond_destroy,
|
| + irt_trace_cond_signal,
|
| + irt_trace_cond_broadcast,
|
| + irt_trace_cond_wait,
|
| + irt_trace_cond_timed_wait_abs,
|
| +};
|
| +
|
| +static int irt_trace_sem_create(int *sem_handle, int32_t value) {
|
| + IRT_TRACE_CALL("sem_create");
|
| + return __nacl_irt_sem.sem_create(sem_handle, value);
|
| +}
|
| +static int irt_trace_sem_destroy(int sem_handle) {
|
| + IRT_TRACE_CALL("sem_destroy");
|
| + return __nacl_irt_sem.sem_destroy(sem_handle);
|
| +}
|
| +static int irt_trace_sem_post(int sem_handle) {
|
| + IRT_TRACE_CALL("sem_post");
|
| + return __nacl_irt_sem.sem_post(sem_handle);
|
| +}
|
| +static int irt_trace_sem_wait(int sem_handle) {
|
| + IRT_TRACE_CALL("sem_wait");
|
| + return __nacl_irt_sem.sem_wait(sem_handle);
|
| +}
|
| +
|
| +static struct nacl_irt_sem logged_nacl_irt_sem = {
|
| + irt_trace_sem_create,
|
| + irt_trace_sem_destroy,
|
| + irt_trace_sem_post,
|
| + irt_trace_sem_wait,
|
| +};
|
| +
|
| +static int irt_trace_tls_init(void *thread_ptr) {
|
| + IRT_TRACE_CALL("tls_init");
|
| + return __nacl_irt_tls.tls_init(thread_ptr);
|
| +}
|
| +static void *irt_trace_tls_get(void) {
|
| + IRT_TRACE_CALL("tls_get");
|
| + return __nacl_irt_tls.tls_get();
|
| +}
|
| +
|
| +static struct nacl_irt_tls logged_nacl_irt_tls = {
|
| + irt_trace_tls_init,
|
| + irt_trace_tls_get,
|
| +};
|
| +
|
| +static int irt_trace_register_block_hooks(void (*pre)(void), void (*post)(void)) {
|
| + IRT_TRACE_CALL("register_block_hooks");
|
| + return __nacl_irt_blockhook.register_block_hooks(pre, post);
|
| +}
|
| +
|
| +static struct nacl_irt_blockhook logged_nacl_irt_blockhook = {
|
| + irt_trace_register_block_hooks,
|
| +};
|
| +
|
| +#ifdef IRT_PPAPI
|
| +static int irt_trace_ppapi_start(const struct PP_StartFunctions *) {
|
| + IRT_TRACE_CALL("ppapi_start");
|
| + return __nacl_irt_ppapihook.ppapi_start(funcs);
|
| +}
|
| +static void irt_trace_ppapi_register_thread_creator(const struct PP_ThreadFunctions *funcs) {
|
| + IRT_TRACE_CALL("ppapi_register_thread_creator");
|
| + return __nacl_irt_ppapihook.ppapi_register_thread_creator(funcs);
|
| +}
|
| +
|
| +static struct nacl_irt_ppapihook logged_nacl_irt_ppapihook = {
|
| + irt_trace_ppapi_start,
|
| + irt_trace_ppapi_register_thread_creator,
|
| +}
|
| +#endif
|
| +
|
| +static int irt_trace_open_resource(const char *file, int *fd) {
|
| + IRT_TRACE_CALL("open_resource");
|
| + return __nacl_irt_resource_open.open_resource(file, fd);
|
| +}
|
| +
|
| +static struct nacl_irt_resource_open logged_nacl_irt_resource_open = {
|
| + irt_trace_open_resource,
|
| +};
|
| +
|
| +static int irt_trace_get_random_bytes(void *buf, size_t count, size_t *nread) {
|
| + IRT_TRACE_CALL("get_random_bytes");
|
| + return __nacl_irt_random.get_random_bytes(buf, count, nread);
|
| +}
|
| +
|
| +static struct nacl_irt_random logged_nacl_irt_random = {
|
| + irt_trace_get_random_bytes,
|
| +};
|
| +
|
| +static int irt_trace_clock_getres(clockid_t clk_id, struct timespec *res) {
|
| + IRT_TRACE_CALL("clock_getres");
|
| + return __nacl_irt_clock.clock_getres(clk_id, res);
|
| +}
|
| +static int irt_trace_clock_gettime(clockid_t clk_id, struct timespec *tp) {
|
| + IRT_TRACE_CALL("clock_gettime");
|
| + return __nacl_irt_clock.clock_gettime(clk_id, tp);
|
| +}
|
| +
|
| +static struct nacl_irt_clock logged_nacl_irt_clock = {
|
| + irt_trace_clock_getres,
|
| + irt_trace_clock_gettime,
|
| +};
|
| +
|
| +static int irt_trace_exception_handler(NaClExceptionHandler handler,
|
| + NaClExceptionHandler *old_handler) {
|
| + IRT_TRACE_CALL("exception_handler");
|
| + return __nacl_irt_exception_handling.exception_handler(handler, old_handler);
|
| +}
|
| +static int irt_trace_exception_stack(void *stack, size_t size) {
|
| + IRT_TRACE_CALL("exception_stack");
|
| + return __nacl_irt_exception_handling.exception_stack(stack, size);
|
| +}
|
| +static int irt_trace_exception_clear_flag(void) {
|
| + IRT_TRACE_CALL("exception_clear_flag");
|
| + return __nacl_irt_exception_handling.exception_clear_flag();
|
| +}
|
| +
|
| +static struct nacl_irt_exception_handling logged_nacl_irt_exception_handling = {
|
| + irt_trace_exception_handler,
|
| + irt_trace_exception_stack,
|
| + irt_trace_exception_clear_flag,
|
| +};
|
| +
|
| +static int irt_trace_init(void) {
|
| + /*struct irt_trace *trace = irt_trace_get();*/
|
| + fprintf(stderr, "irt_trace_init\n");
|
| + /*IRT_TRACE_CALL("init");*/
|
| + /*return __nacl_irt_instance.init(trace->next, );*/
|
| + /**data = trace;*/
|
| + return 0;
|
| +}
|
| +static void irt_trace_destroy(void) {
|
| + /*struct irt_trace *trace = irt_trace_get();*/
|
| + IRT_TRACE_CALL("destroy");
|
| +}
|
| +
|
| +static struct nacl_irt_instance logged_nacl_irt_instance = {
|
| + irt_trace_init,
|
| + irt_trace_destroy,
|
| +};
|
| +
|
| +/*static TYPE_nacl_irt_query nacl_irt_query;*/
|
| +
|
| +struct nacl_interface_table {
|
| + const char *name;
|
| + const void *table;
|
| + size_t size;
|
| +};
|
| +
|
| +static const struct nacl_interface_table irt_trace_interfaces[] = {
|
| + { NACL_IRT_INSTANCE_v0_1, &logged_nacl_irt_instance, sizeof(logged_nacl_irt_instance) },
|
| + { NACL_IRT_BASIC_v0_1, &logged_nacl_irt_basic, sizeof(logged_nacl_irt_basic) },
|
| + { NACL_IRT_FDIO_v0_1, &logged_nacl_irt_fdio, sizeof(logged_nacl_irt_fdio) },
|
| + { NACL_IRT_DEV_FILENAME_v0_2, &logged_nacl_irt_dev_filename, sizeof(logged_nacl_irt_dev_filename) },
|
| + { NACL_IRT_MEMORY_v0_3, &logged_nacl_irt_memory, sizeof(logged_nacl_irt_memory) },
|
| + { NACL_IRT_DYNCODE_v0_1, &logged_nacl_irt_dyncode, sizeof(logged_nacl_irt_dyncode) },
|
| + { NACL_IRT_THREAD_v0_1, &logged_nacl_irt_thread, sizeof(logged_nacl_irt_thread) },
|
| + { NACL_IRT_FUTEX_v0_1, &logged_nacl_irt_futex, sizeof(logged_nacl_irt_futex) },
|
| + { NACL_IRT_MUTEX_v0_1, &logged_nacl_irt_mutex, sizeof(logged_nacl_irt_mutex) },
|
| + { NACL_IRT_COND_v0_1, &logged_nacl_irt_cond, sizeof(logged_nacl_irt_cond) },
|
| + { NACL_IRT_SEM_v0_1, &logged_nacl_irt_sem, sizeof(logged_nacl_irt_sem) },
|
| + { NACL_IRT_TLS_v0_1, &logged_nacl_irt_tls, sizeof(logged_nacl_irt_tls) },
|
| + { NACL_IRT_BLOCKHOOK_v0_1, &logged_nacl_irt_blockhook, sizeof(logged_nacl_irt_blockhook) },
|
| + { NACL_IRT_RESOURCE_OPEN_v0_1, &logged_nacl_irt_resource_open,
|
| + sizeof(logged_nacl_irt_resource_open) },
|
| +#ifdef IRT_PPAPI
|
| + { NACL_IRT_PPAPIHOOK_v0_1, &logged_nacl_irt_ppapihook, sizeof(logged_nacl_irt_ppapihook) },
|
| +#endif
|
| + { NACL_IRT_RANDOM_v0_1, &logged_nacl_irt_random, sizeof(logged_nacl_irt_random) },
|
| + { NACL_IRT_CLOCK_v0_1, &logged_nacl_irt_clock, sizeof(logged_nacl_irt_clock) },
|
| + { NACL_IRT_EXCEPTION_HANDLING_v0_1, &logged_nacl_irt_exception_handling,
|
| + sizeof(logged_nacl_irt_exception_handling) },
|
| +};
|
| +
|
| +static size_t irt_trace_interface(const char *interface_ident,
|
| + void *table, size_t tablesize) {
|
| + int i;
|
| + for (i = 0; i < NACL_ARRAY_SIZE(irt_trace_interfaces); ++i) {
|
| + if (0 == strcmp(interface_ident, irt_trace_interfaces[i].name)) {
|
| + const size_t size = irt_trace_interfaces[i].size;
|
| + if (size <= tablesize) {
|
| + memcpy(table, irt_trace_interfaces[i].table, size);
|
| + return size;
|
| + }
|
| + break;
|
| + }
|
| + }
|
| + return 0;
|
| +}
|
| +
|
| +/*
|
| +TYPE_nacl_irt_query irt_trace_module_query(TYPE_nacl_irt_query nacl_irt_query) {
|
| + if (nacl_irt_query(NACL_IRT_BASIC_v0_1, &__nacl_irt_basic,
|
| + sizeof(__nacl_irt_basic)) == sizeof(__nacl_irt_basic)) {
|
| + }
|
| + if (nacl_irt_query(NACL_IRT_FDIO_v0_1, &__nacl_irt_fdio,
|
| + sizeof(__nacl_irt_fdio)) == sizeof(__nacl_irt_fdio)) {
|
| + }
|
| + if (nacl_irt_query(NACL_IRT_DEV_FILENAME_v0_2, &__nacl_irt_dev_filename,
|
| + sizeof(__nacl_irt_dev_filename)) == sizeof(__nacl_irt_dev_filename)) {
|
| + }
|
| + if (nacl_irt_query(NACL_IRT_MEMORY_v0_3, &__nacl_irt_memory,
|
| + sizeof(__nacl_irt_memory)) == sizeof(__nacl_irt_memory)) {
|
| + }
|
| + if (nacl_irt_query(NACL_IRT_DYNCODE_v0_1, &__nacl_irt_dyncode,
|
| + sizeof(__nacl_irt_dyncode)) == sizeof(__nacl_irt_basic)) {
|
| + }
|
| + if (nacl_irt_query(NACL_IRT_THREAD_v0_1, &__nacl_irt_thread,
|
| + sizeof(__nacl_irt_thread)) == sizeof(__nacl_irt_basic)) {
|
| + }
|
| + if (nacl_irt_query(NACL_IRT_FUTEX_v0_1, &__nacl_irt_futex,
|
| + sizeof(__nacl_irt_futex)) == sizeof(__nacl_irt_basic)) {
|
| + }
|
| + if (nacl_irt_query(NACL_IRT_MUTEX_v0_1, &__nacl_irt_mutex,
|
| + sizeof(__nacl_irt_mutex)) == sizeof(__nacl_irt_basic)) {
|
| + }
|
| + if (nacl_irt_query(NACL_IRT_COND_v0_1, &__nacl_irt_cond,
|
| + sizeof(__nacl_irt_cond)) == sizeof(__nacl_irt_basic)) {
|
| + }
|
| + if (nacl_irt_query(NACL_IRT_SEM_v0_1, &__nacl_irt_sem,
|
| + sizeof(__nacl_irt_sem)) == sizeof(__nacl_irt_basic)) {
|
| + }
|
| + if (nacl_irt_query(NACL_IRT_TLS_v0_1, &__nacl_irt_tls,
|
| + sizeof(__nacl_irt_tls)) == sizeof(__nacl_irt_basic)) {
|
| + }
|
| + if (nacl_irt_query(NACL_IRT_BLOCKHOOK_v0_1, &__nacl_irt_blockhook,
|
| + sizeof(__nacl_irt_blockhook)) == sizeof(__nacl_irt_blockhook)) {
|
| + }
|
| +#ifdef IRT_PPAPI
|
| + if (nacl_irt_query(NACL_IRT_PPAPIHOOK_v0_1, &__nacl_irt_ppapihook,
|
| + sizeof(__nacl_irt_ppapihook)) == sizeof(__nacl_irt_basic)) {
|
| + }
|
| +#endif
|
| + if (nacl_irt_query(NACL_IRT_RESOURCE_OPEN_v0_1, &__nacl_irt_resource_open,
|
| + sizeof(__nacl_irt_resource_open)) == sizeof(__nacl_irt_basic)) {
|
| + }
|
| + if (nacl_irt_query(NACL_IRT_RANDOM_v0_1, &__nacl_irt_random,
|
| + sizeof(__nacl_irt_random)) == sizeof(__nacl_irt_basic)) {
|
| + }
|
| + if (nacl_irt_query(NACL_IRT_CLOCK_v0_1, &__nacl_irt_clock,
|
| + sizeof(__nacl_irt_clock)) == sizeof(__nacl_irt_basic)) {
|
| + }
|
| + if (nacl_irt_query(NACL_IRT_EXCEPTION_HANDLING_v0_1, &__nacl_irt_exception_handling,
|
| + sizeof(__nacl_irt_exception_handling)) == sizeof(__nacl_irt_basic)) {
|
| + }
|
| +
|
| + return irt_trace_interface;
|
| +}
|
| +*/
|
| +
|
| +#if 0
|
| +void irt_logged_module_init(void) {
|
| + nacl_irt_module_register(irt_logged_module_query);
|
| +}
|
| +
|
| +void irt_logged_module_fini(void) {
|
| +}
|
| +#endif
|
| +
|
| +void irt_trace_module_init(void) {
|
| + if (nacl_irt_interface_set(NACL_IRT_BASIC_v0_1, &logged_nacl_irt_basic,
|
| + sizeof(logged_nacl_irt_basic), &__nacl_irt_basic) == sizeof(logged_nacl_irt_basic)) {
|
| + }
|
| + if (nacl_irt_interface_set(NACL_IRT_FDIO_v0_1, &logged_nacl_irt_fdio,
|
| + sizeof(logged_nacl_irt_fdio), &__nacl_irt_fdio) == sizeof(logged_nacl_irt_fdio)) {
|
| + }
|
| + if (nacl_irt_interface_set(NACL_IRT_DEV_FILENAME_v0_2, &logged_nacl_irt_dev_filename,
|
| + sizeof(logged_nacl_irt_dev_filename), &__nacl_irt_dev_filename) == sizeof(logged_nacl_irt_dev_filename)) {
|
| + }
|
| + if (nacl_irt_interface_set(NACL_IRT_MEMORY_v0_3, &logged_nacl_irt_memory,
|
| + sizeof(logged_nacl_irt_memory), &__nacl_irt_memory) == sizeof(logged_nacl_irt_memory)) {
|
| + }
|
| + if (nacl_irt_interface_set(NACL_IRT_DYNCODE_v0_1, &logged_nacl_irt_dyncode,
|
| + sizeof(logged_nacl_irt_dyncode), &__nacl_irt_dyncode) == sizeof(logged_nacl_irt_dyncode)) {
|
| + }
|
| + if (nacl_irt_interface_set(NACL_IRT_THREAD_v0_1, &logged_nacl_irt_thread,
|
| + sizeof(logged_nacl_irt_thread), &__nacl_irt_thread) == sizeof(logged_nacl_irt_thread)) {
|
| + }
|
| + if (nacl_irt_interface_set(NACL_IRT_FUTEX_v0_1, &logged_nacl_irt_futex,
|
| + sizeof(logged_nacl_irt_futex), &__nacl_irt_futex) == sizeof(logged_nacl_irt_futex)) {
|
| + }
|
| + if (nacl_irt_interface_set(NACL_IRT_MUTEX_v0_1, &logged_nacl_irt_mutex,
|
| + sizeof(logged_nacl_irt_mutex), &__nacl_irt_mutex) == sizeof(logged_nacl_irt_mutex)) {
|
| + }
|
| + if (nacl_irt_interface_set(NACL_IRT_COND_v0_1, &logged_nacl_irt_cond,
|
| + sizeof(logged_nacl_irt_cond), &__nacl_irt_cond) == sizeof(logged_nacl_irt_cond)) {
|
| + }
|
| + if (nacl_irt_interface_set(NACL_IRT_SEM_v0_1, &logged_nacl_irt_sem,
|
| + sizeof(logged_nacl_irt_sem), &__nacl_irt_sem) == sizeof(logged_nacl_irt_sem)) {
|
| + }
|
| + if (nacl_irt_interface_set(NACL_IRT_TLS_v0_1, &logged_nacl_irt_tls,
|
| + sizeof(logged_nacl_irt_tls), &__nacl_irt_tls) == sizeof(logged_nacl_irt_tls)) {
|
| + }
|
| + if (nacl_irt_interface_set(NACL_IRT_BLOCKHOOK_v0_1, &logged_nacl_irt_blockhook,
|
| + sizeof(logged_nacl_irt_blockhook), &__nacl_irt_blockhook) == sizeof(logged_nacl_irt_blockhook)) {
|
| + }
|
| +#ifdef IRT_PPAPI
|
| + if (nacl_irt_interface_set(NACL_IRT_PPAPIHOOK_v0_1, &logged_nacl_irt_ppapihook,
|
| + sizeof(logged_nacl_irt_ppapihook), &__nacl_irt_ppapihook) == sizeof(logged_nacl_irt_ppapihook)) {
|
| + }
|
| +#endif
|
| + if (nacl_irt_interface_set(NACL_IRT_RESOURCE_OPEN_v0_1, &logged_nacl_irt_resource_open,
|
| + sizeof(logged_nacl_irt_resource_open), &__nacl_irt_resource_open) == sizeof(logged_nacl_irt_resource_open)) {
|
| + }
|
| + if (nacl_irt_interface_set(NACL_IRT_RANDOM_v0_1, &logged_nacl_irt_random,
|
| + sizeof(logged_nacl_irt_random), &__nacl_irt_random) == sizeof(logged_nacl_irt_random)) {
|
| + }
|
| + if (nacl_irt_interface_set(NACL_IRT_CLOCK_v0_1, &logged_nacl_irt_clock,
|
| + sizeof(logged_nacl_irt_clock), &__nacl_irt_clock) == sizeof(logged_nacl_irt_clock)) {
|
| + }
|
| + if (nacl_irt_interface_set(NACL_IRT_EXCEPTION_HANDLING_v0_1, &logged_nacl_irt_exception_handling,
|
| + sizeof(logged_nacl_irt_exception_handling), &__nacl_irt_exception_handling) == sizeof(logged_nacl_irt_exception_handling)) {
|
| + }
|
| +}
|
| +
|
| +/*
|
| +static const struct nacl_irt_opt irt_trace_opts[] = {
|
| + IRT_OPT_KEY("-h", 0),
|
| + IRT_OPT_KEY("--help", 0),
|
| + { "timestamp", offsetof(struct irt_trace, timestamp), 0 },
|
| + { NULL, 0, 0 },
|
| +};
|
| +
|
| +static void irt_trace_help(void) {
|
| + printf("-p prefix\n");
|
| +}
|
| +
|
| +static int irt_trace_opt_proc(void *data, const char *arg, int key, struct nacl_irt_args *outargs) {
|
| + if (NULL == key) {
|
| + irt_trace_help();
|
| + return -1;
|
| + }
|
| +
|
| + return 1;
|
| +}
|
| +*/
|
| +
|
| +#if 0
|
| +static struct nacl_irt_layer *irt_trace_new(struct nacl_irt_args *args,
|
| + struct nacl_irt_layer *next[]) {
|
| + struct nacl_irt_layer *layer;
|
| + struct irt_trace *trace;
|
| +
|
| + fprintf(stderr, "initializing\n");
|
| +
|
| + trace = malloc(sizeof *trace);
|
| + if (NULL == trace) {
|
| + fprintf(stderr, "irt-trace: malloc failed\n");
|
| + return NULL;
|
| + }
|
| +
|
| + /*if (-1 == nacl_irt_opt_parse(args, trace, irt_trace_opts, irt_trace_opt_proc)) {
|
| + goto out_error;
|
| + }*/
|
| +
|
| + if (NULL == next[0]) {
|
| + fprintf(stderr, "irt-trace: at least one layer needed\n");
|
| + goto out_error;
|
| + }
|
| +
|
| + irt_trace_module_init();
|
| + fprintf(stderr, "trace= %p\n", (void *)(uintptr_t) irt_trace_interface);
|
| + layer = nacl_irt_layer_new(/*irt_trace_interfaces,
|
| + sizeof irt_trace_interfaces,*/
|
| + irt_trace_interface,
|
| + /*irt_trace_module_query(next[0]->irt_query),*/
|
| + (void *) trace);
|
| + if (NULL == layer) {
|
| + fprintf(stderr, "irt_trace: failed to allocate layer\n");
|
| + goto out_error;
|
| + }
|
| +
|
| + fprintf(stderr, "new layer\n");
|
| + return layer;
|
| +
|
| +out_error:
|
| + free(trace);
|
| + return NULL;
|
| +}
|
| +
|
| +NACL_IRT_REGISTER_MODULE(irt_trace, irt_trace_new)
|
| +#endif
|
| +
|
| +static struct nacl_irt_layer *irt_trace_new(int argc, char **args) {
|
| + struct nacl_irt_layer *layer;
|
| + struct irt_trace *trace;
|
| +
|
| + fprintf(stderr, "initializing\n");
|
| +
|
| + trace = malloc(sizeof *trace);
|
| + if (NULL == trace) {
|
| + fprintf(stderr, "irt-trace: malloc failed\n");
|
| + return NULL;
|
| + }
|
| +
|
| + /*if (-1 == nacl_irt_opt_parse(args, trace, irt_trace_opts, irt_trace_opt_proc)) {
|
| + goto out_error;
|
| + }*/
|
| +
|
| + if (NULL == next[0]) {
|
| + fprintf(stderr, "irt-trace: at least one layer needed\n");
|
| + goto out_error;
|
| + }
|
| +
|
| + irt_trace_module_init();
|
| + fprintf(stderr, "trace= %p\n", (void *)(uintptr_t) irt_trace_interface);
|
| + layer = nacl_irt_layer_new(/*irt_trace_interfaces,
|
| + sizeof irt_trace_interfaces,*/
|
| + irt_trace_interface,
|
| + /*irt_trace_module_query(next[0]->irt_query),*/
|
| + (void *) trace);
|
| + if (NULL == layer) {
|
| + fprintf(stderr, "irt_trace: failed to allocate layer\n");
|
| + goto out_error;
|
| + }
|
| +
|
| + fprintf(stderr, "new layer\n");
|
| + return layer;
|
| +
|
| +out_error:
|
| + free(trace);
|
| + return NULL;
|
| +}
|
| +
|
| +NACL_IRT_REGISTER_MODULE(irt_trace, irt_trace_new)
|
|
|