OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright (c) 2013 The Native Client Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. |
| 5 */ |
| 6 |
| 7 #include "native_client/src/untrusted/nacl/nacl_irt_module.h" |
| 8 |
| 9 #include <errno.h> |
| 10 #include <pthread.h> |
| 11 #include <stdio.h> |
| 12 #include <stdlib.h> |
| 13 #include <string.h> |
| 14 #include <unistd.h> |
| 15 |
| 16 #include "native_client/src/untrusted/nacl/nacl_irt.h" |
| 17 |
| 18 /*static pthread_key_t nacl_irt_context_key;*/ |
| 19 /*static pthread_mutex_t nacl_irt_context_lock = PTHREAD_MUTEX_INITIALIZER;*/ |
| 20 static int nacl_irt_context_ref; |
| 21 static struct nacl_irt_module *nacl_irt_modules; |
| 22 static struct nacl_irt_context context; |
| 23 |
| 24 struct nacl_irt_context *nacl_irt_get_context(void) { |
| 25 return (struct nacl_irt_context *) &context; /*pthread_getspecific(nacl_irt_co
ntext_key);*/ |
| 26 } |
| 27 |
| 28 /* |
| 29 static struct nacl_irt_context *nacl_irt_create_context(struct nacl_irt *irt) { |
| 30 struct nacl_irt_context *ctx = nacl_irt_get_context(); |
| 31 |
| 32 if (NULL == ctx) { |
| 33 ctx = (struct nacl_irt_context *) malloc(sizeof *ctx); |
| 34 if (NULL == ctx) { |
| 35 fprintf(stderr, "irt: failed to allocate thread specific data\n"); |
| 36 abort(); |
| 37 } |
| 38 pthread_setspecific(nacl_irt_context_key, ctx); |
| 39 } else { |
| 40 memset(ctx, 0, sizeof *ctx); |
| 41 } |
| 42 ctx->irt = irt; |
| 43 |
| 44 return ctx; |
| 45 } |
| 46 */ |
| 47 /* |
| 48 static void nacl_irt_free_context(void *data) { |
| 49 free(data); |
| 50 } |
| 51 */ |
| 52 |
| 53 static int nacl_irt_create_context_key(void) { |
| 54 int err = 0; |
| 55 |
| 56 /*pthread_mutex_lock(&nacl_irt_context_lock);*/ |
| 57 if (0 != nacl_irt_context_ref) { |
| 58 err = 0; |
| 59 /*pthread_key_create(&nacl_irt_context_key, nacl_irt_free_context);*/ |
| 60 if (0 != err) { |
| 61 fprintf(stderr, "irt: failed to create thread specific key: %s\n", |
| 62 strerror(err)); |
| 63 goto out; |
| 64 } |
| 65 } |
| 66 nacl_irt_context_ref++; |
| 67 out: |
| 68 /*pthread_mutex_unlock(&nacl_irt_context_lock);*/ |
| 69 return err; |
| 70 } |
| 71 |
| 72 static void nacl_irt_delete_context_key(void) { |
| 73 /*pthread_mutex_lock(&nacl_irt_context_lock);*/ |
| 74 if (0 != nacl_irt_context_ref) { |
| 75 } |
| 76 /*pthread_mutex_unlock(&nacl_irt_context_lock);*/ |
| 77 } |
| 78 |
| 79 void nacl_irt_layer_init(struct nacl_irt_layer *layer) { |
| 80 struct nacl_irt_instance irt_instance; |
| 81 |
| 82 fprintf(stderr, "query %p\n", __nacl_irt_query); |
| 83 /*nacl_irt_get_context()->private_data = layer->user_data;*/ |
| 84 if (layer->irt_query(NACL_IRT_INSTANCE_v0_1, &irt_instance, |
| 85 sizeof(irt_instance)) != sizeof(irt_instance)) { |
| 86 static const char fail_msg[] = |
| 87 "query failed for essential interface \""NACL_IRT_INSTANCE_v0_1 "\"\n"; |
| 88 write(2, fail_msg, sizeof(fail_msg) - 1); |
| 89 _exit(-1); |
| 90 } |
| 91 |
| 92 fprintf(stderr, "init = %p\n", irt_instance.init); |
| 93 irt_instance.init(); |
| 94 /* if(!layer->interfaces.init(x, &layer->user_data)) {} */ |
| 95 } |
| 96 |
| 97 void nacl_irt_layer_destroy(struct nacl_irt_layer *layer) { |
| 98 nacl_irt_get_context()->private_data = layer->user_data; |
| 99 /* layer->user_data = layer->interfaces.destroy(); */ |
| 100 free(layer); |
| 101 } |
| 102 |
| 103 static struct nacl_irt_module *nacl_irt_find_module(const char *name) { |
| 104 struct nacl_irt_module *module = NULL; |
| 105 |
| 106 for (module = nacl_irt_modules; NULL != module; module = module->next) { |
| 107 if (0 == strcmp(name, module->name)) { |
| 108 break; |
| 109 } |
| 110 } |
| 111 return module; |
| 112 } |
| 113 |
| 114 static struct nacl_irt_module *nacl_irt_get_module(const char *name) { |
| 115 struct nacl_irt_module *module; |
| 116 |
| 117 /*pthread_mutex_lock(&nacl_irt_context_lock);*/ |
| 118 module = nacl_irt_find_module(name); |
| 119 /*pthread_mutex_unlock(&nacl_irt_context_lock);*/ |
| 120 return module; |
| 121 } |
| 122 |
| 123 static int nacl_irt_load_module(struct nacl_irt *irt, const char *name, struct n
acl_irt_args *args) { |
| 124 struct nacl_irt_layer *layers[2] = { irt->layer, NULL }; |
| 125 struct nacl_irt_layer *new_layer; |
| 126 struct nacl_irt_module *module = nacl_irt_get_module(name); |
| 127 |
| 128 if (NULL == module) { |
| 129 return -1; |
| 130 } |
| 131 |
| 132 new_layer = module->factory(args, layers); |
| 133 if (NULL == new_layer) { |
| 134 return -1; |
| 135 } |
| 136 |
| 137 new_layer->module = module; |
| 138 irt->layer = new_layer; |
| 139 |
| 140 return 0; |
| 141 } |
| 142 |
| 143 struct nacl_irt_layer *nacl_irt_layer_new(/*const struct nacl_irt_interface *itf
,*/ |
| 144 /*size_t itf_size,*/ |
| 145 TYPE_nacl_irt_query query, |
| 146 void *user_data) { |
| 147 struct nacl_irt_layer *layer; |
| 148 |
| 149 layer = (struct nacl_irt_layer *) malloc(sizeof *layer); |
| 150 if (NULL == layer) { |
| 151 fprintf(stderr, "irt: failed to allocate layer\n"); |
| 152 return NULL; |
| 153 } |
| 154 |
| 155 layer->user_data = user_data; |
| 156 if (NULL != query) { |
| 157 /*memcpy(&layer->interfaces, interfaces, interfaces_size);*/ |
| 158 /*layer->interfaces = (struct nacl_irt_interface *) itf;*/ |
| 159 layer->irt_query = query; |
| 160 } |
| 161 return layer; |
| 162 } |
| 163 |
| 164 struct nacl_irt *nacl_irt_new(struct nacl_irt_args *args, |
| 165 TYPE_nacl_irt_query query, |
| 166 /*const struct nacl_irt_interface *itf,*/ |
| 167 /*size_t itf_size,*/ |
| 168 void *user_data) { |
| 169 struct nacl_irt *irt; |
| 170 struct nacl_irt_layer *layer; |
| 171 |
| 172 if (-1 == nacl_irt_create_context_key()) { |
| 173 fprintf(stderr, "irt: failed to create context key\n"); |
| 174 goto out; |
| 175 } |
| 176 |
| 177 irt = (struct nacl_irt *) malloc(sizeof *irt); |
| 178 if (NULL == irt) { |
| 179 fprintf(stderr, "irt: failed to allocate irt\n"); |
| 180 goto out_delete_context_key; |
| 181 } |
| 182 |
| 183 fprintf(stderr, "in: %p\n", query); |
| 184 |
| 185 layer = nacl_irt_layer_new(query, user_data); |
| 186 /*layer = nacl_irt_layer_new(itf, itf_size, user_data);*/ |
| 187 if (NULL == layer) { |
| 188 fprintf(stderr, "irt: failed to allocate layer\n"); |
| 189 goto out_free; |
| 190 } |
| 191 |
| 192 irt->layer = layer; |
| 193 |
| 194 /* |
| 195 * if (nacl_irt_opt_parse(args, &irt->conf, irt_lib_opts, |
| 196 * irt_lib_opt_proc) == -1) { |
| 197 * goto out_free; |
| 198 * } |
| 199 */ |
| 200 |
| 201 { |
| 202 const char *modules[] = { "irt_trace", NULL }; |
| 203 const char **module; |
| 204 for (module = &modules[0]; *module; module++) { |
| 205 if (-1 == nacl_irt_load_module(irt, *module, args)) { |
| 206 goto out_free; |
| 207 } |
| 208 } |
| 209 } |
| 210 |
| 211 return irt; |
| 212 |
| 213 out_free: |
| 214 free(irt); |
| 215 out_delete_context_key: |
| 216 nacl_irt_delete_context_key(); |
| 217 out: |
| 218 return NULL; |
| 219 } |
| 220 |
| 221 void nacl_irt_register_module(struct nacl_irt_module *module) { |
| 222 fprintf(stderr, "register\n"); |
| 223 module->next = nacl_irt_modules; |
| 224 nacl_irt_modules = module; |
| 225 } |
| 226 |
| 227 typedef int (*TYPE_nacl_irt_module)(int argc, char **argv); |
| 228 |
| 229 void __libnacl_irt_register_module(struct nacl_irt_module *module) { |
| 230 fprintf(stderr, "register\n"); |
| 231 module->next = nacl_irt_modules; |
| 232 module->factory( |
| 233 nacl_irt_modules = module; |
| 234 } |
OLD | NEW |