Index: src/untrusted/nacl/nacl_irt_module.c |
diff --git a/src/untrusted/nacl/nacl_irt_module.c b/src/untrusted/nacl/nacl_irt_module.c |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f7db0ef869668d415e97d6c29539734b663085cd |
--- /dev/null |
+++ b/src/untrusted/nacl/nacl_irt_module.c |
@@ -0,0 +1,234 @@ |
+/* |
+ * 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 "native_client/src/untrusted/nacl/nacl_irt_module.h" |
+ |
+#include <errno.h> |
+#include <pthread.h> |
+#include <stdio.h> |
+#include <stdlib.h> |
+#include <string.h> |
+#include <unistd.h> |
+ |
+#include "native_client/src/untrusted/nacl/nacl_irt.h" |
+ |
+/*static pthread_key_t nacl_irt_context_key;*/ |
+/*static pthread_mutex_t nacl_irt_context_lock = PTHREAD_MUTEX_INITIALIZER;*/ |
+static int nacl_irt_context_ref; |
+static struct nacl_irt_module *nacl_irt_modules; |
+static struct nacl_irt_context context; |
+ |
+struct nacl_irt_context *nacl_irt_get_context(void) { |
+ return (struct nacl_irt_context *) &context; /*pthread_getspecific(nacl_irt_context_key);*/ |
+} |
+ |
+/* |
+static struct nacl_irt_context *nacl_irt_create_context(struct nacl_irt *irt) { |
+ struct nacl_irt_context *ctx = nacl_irt_get_context(); |
+ |
+ if (NULL == ctx) { |
+ ctx = (struct nacl_irt_context *) malloc(sizeof *ctx); |
+ if (NULL == ctx) { |
+ fprintf(stderr, "irt: failed to allocate thread specific data\n"); |
+ abort(); |
+ } |
+ pthread_setspecific(nacl_irt_context_key, ctx); |
+ } else { |
+ memset(ctx, 0, sizeof *ctx); |
+ } |
+ ctx->irt = irt; |
+ |
+ return ctx; |
+} |
+*/ |
+/* |
+static void nacl_irt_free_context(void *data) { |
+ free(data); |
+} |
+*/ |
+ |
+static int nacl_irt_create_context_key(void) { |
+ int err = 0; |
+ |
+ /*pthread_mutex_lock(&nacl_irt_context_lock);*/ |
+ if (0 != nacl_irt_context_ref) { |
+ err = 0; |
+ /*pthread_key_create(&nacl_irt_context_key, nacl_irt_free_context);*/ |
+ if (0 != err) { |
+ fprintf(stderr, "irt: failed to create thread specific key: %s\n", |
+ strerror(err)); |
+ goto out; |
+ } |
+ } |
+ nacl_irt_context_ref++; |
+out: |
+ /*pthread_mutex_unlock(&nacl_irt_context_lock);*/ |
+ return err; |
+} |
+ |
+static void nacl_irt_delete_context_key(void) { |
+ /*pthread_mutex_lock(&nacl_irt_context_lock);*/ |
+ if (0 != nacl_irt_context_ref) { |
+ } |
+ /*pthread_mutex_unlock(&nacl_irt_context_lock);*/ |
+} |
+ |
+void nacl_irt_layer_init(struct nacl_irt_layer *layer) { |
+ struct nacl_irt_instance irt_instance; |
+ |
+ fprintf(stderr, "query %p\n", __nacl_irt_query); |
+ /*nacl_irt_get_context()->private_data = layer->user_data;*/ |
+ if (layer->irt_query(NACL_IRT_INSTANCE_v0_1, &irt_instance, |
+ sizeof(irt_instance)) != sizeof(irt_instance)) { |
+ static const char fail_msg[] = |
+ "query failed for essential interface \""NACL_IRT_INSTANCE_v0_1 "\"\n"; |
+ write(2, fail_msg, sizeof(fail_msg) - 1); |
+ _exit(-1); |
+ } |
+ |
+ fprintf(stderr, "init = %p\n", irt_instance.init); |
+ irt_instance.init(); |
+ /* if(!layer->interfaces.init(x, &layer->user_data)) {} */ |
+} |
+ |
+void nacl_irt_layer_destroy(struct nacl_irt_layer *layer) { |
+ nacl_irt_get_context()->private_data = layer->user_data; |
+ /* layer->user_data = layer->interfaces.destroy(); */ |
+ free(layer); |
+} |
+ |
+static struct nacl_irt_module *nacl_irt_find_module(const char *name) { |
+ struct nacl_irt_module *module = NULL; |
+ |
+ for (module = nacl_irt_modules; NULL != module; module = module->next) { |
+ if (0 == strcmp(name, module->name)) { |
+ break; |
+ } |
+ } |
+ return module; |
+} |
+ |
+static struct nacl_irt_module *nacl_irt_get_module(const char *name) { |
+ struct nacl_irt_module *module; |
+ |
+ /*pthread_mutex_lock(&nacl_irt_context_lock);*/ |
+ module = nacl_irt_find_module(name); |
+ /*pthread_mutex_unlock(&nacl_irt_context_lock);*/ |
+ return module; |
+} |
+ |
+static int nacl_irt_load_module(struct nacl_irt *irt, const char *name, struct nacl_irt_args *args) { |
+ struct nacl_irt_layer *layers[2] = { irt->layer, NULL }; |
+ struct nacl_irt_layer *new_layer; |
+ struct nacl_irt_module *module = nacl_irt_get_module(name); |
+ |
+ if (NULL == module) { |
+ return -1; |
+ } |
+ |
+ new_layer = module->factory(args, layers); |
+ if (NULL == new_layer) { |
+ return -1; |
+ } |
+ |
+ new_layer->module = module; |
+ irt->layer = new_layer; |
+ |
+ return 0; |
+} |
+ |
+struct nacl_irt_layer *nacl_irt_layer_new(/*const struct nacl_irt_interface *itf,*/ |
+ /*size_t itf_size,*/ |
+ TYPE_nacl_irt_query query, |
+ void *user_data) { |
+ struct nacl_irt_layer *layer; |
+ |
+ layer = (struct nacl_irt_layer *) malloc(sizeof *layer); |
+ if (NULL == layer) { |
+ fprintf(stderr, "irt: failed to allocate layer\n"); |
+ return NULL; |
+ } |
+ |
+ layer->user_data = user_data; |
+ if (NULL != query) { |
+ /*memcpy(&layer->interfaces, interfaces, interfaces_size);*/ |
+ /*layer->interfaces = (struct nacl_irt_interface *) itf;*/ |
+ layer->irt_query = query; |
+ } |
+ return layer; |
+} |
+ |
+struct nacl_irt *nacl_irt_new(struct nacl_irt_args *args, |
+ TYPE_nacl_irt_query query, |
+ /*const struct nacl_irt_interface *itf,*/ |
+ /*size_t itf_size,*/ |
+ void *user_data) { |
+ struct nacl_irt *irt; |
+ struct nacl_irt_layer *layer; |
+ |
+ if (-1 == nacl_irt_create_context_key()) { |
+ fprintf(stderr, "irt: failed to create context key\n"); |
+ goto out; |
+ } |
+ |
+ irt = (struct nacl_irt *) malloc(sizeof *irt); |
+ if (NULL == irt) { |
+ fprintf(stderr, "irt: failed to allocate irt\n"); |
+ goto out_delete_context_key; |
+ } |
+ |
+ fprintf(stderr, "in: %p\n", query); |
+ |
+ layer = nacl_irt_layer_new(query, user_data); |
+ /*layer = nacl_irt_layer_new(itf, itf_size, user_data);*/ |
+ if (NULL == layer) { |
+ fprintf(stderr, "irt: failed to allocate layer\n"); |
+ goto out_free; |
+ } |
+ |
+ irt->layer = layer; |
+ |
+ /* |
+ * if (nacl_irt_opt_parse(args, &irt->conf, irt_lib_opts, |
+ * irt_lib_opt_proc) == -1) { |
+ * goto out_free; |
+ * } |
+ */ |
+ |
+ { |
+ const char *modules[] = { "irt_trace", NULL }; |
+ const char **module; |
+ for (module = &modules[0]; *module; module++) { |
+ if (-1 == nacl_irt_load_module(irt, *module, args)) { |
+ goto out_free; |
+ } |
+ } |
+ } |
+ |
+ return irt; |
+ |
+out_free: |
+ free(irt); |
+out_delete_context_key: |
+ nacl_irt_delete_context_key(); |
+out: |
+ return NULL; |
+} |
+ |
+void nacl_irt_register_module(struct nacl_irt_module *module) { |
+ fprintf(stderr, "register\n"); |
+ module->next = nacl_irt_modules; |
+ nacl_irt_modules = module; |
+} |
+ |
+typedef int (*TYPE_nacl_irt_module)(int argc, char **argv); |
+ |
+void __libnacl_irt_register_module(struct nacl_irt_module *module) { |
+ fprintf(stderr, "register\n"); |
+ module->next = nacl_irt_modules; |
+ module->factory( |
+ nacl_irt_modules = module; |
+} |