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) |