Chromium Code Reviews| 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 <assert.h> | |
| 8 #include <errno.h> | |
| 9 #include <stdio.h> | |
| 10 #include <stdlib.h> | |
| 11 #include <string.h> | |
| 12 #include <sys/mman.h> | |
| 13 #include <unistd.h> | |
| 14 | |
| 15 #include "native_client/src/include/elf32.h" | |
| 16 #include "native_client/src/include/elf_auxv.h" | |
| 17 #include "native_client/src/include/nacl_macros.h" | |
| 18 #include "native_client/src/trusted/service_runtime/include/sys/unistd.h" | |
| 19 #include "native_client/src/untrusted/irt/irt.h" | |
| 20 | |
| 21 | |
|
eliben
2013/10/08 23:24:16
A comment in this file explaining what it contains
Mark Seaborn
2013/10/10 23:55:49
I've added a comment.
| |
| 22 void _user_start(void *info); | |
| 23 | |
| 24 static __thread void *g_tls_value; | |
| 25 | |
| 26 | |
| 27 static int irt_close(int fd) { | |
| 28 if (close(fd) != 0) | |
| 29 return errno; | |
| 30 return 0; | |
| 31 } | |
| 32 | |
| 33 static int irt_write(int fd, const void *buf, size_t count, size_t *nwrote) { | |
| 34 int result = write(fd, buf, count); | |
| 35 if (result < 0) | |
| 36 return errno; | |
| 37 *nwrote = result; | |
| 38 return 0; | |
| 39 } | |
| 40 | |
| 41 static int irt_fstat(int fd, struct stat *st) { | |
| 42 /* TODO(mseaborn): Implement this and convert "struct stat". */ | |
| 43 return ENOSYS; | |
| 44 } | |
| 45 | |
| 46 static void irt_exit(int status) { | |
| 47 _exit(status); | |
| 48 } | |
| 49 | |
| 50 static int irt_sysconf(int name, int *value) { | |
| 51 switch (name) { | |
| 52 case NACL_ABI__SC_PAGESIZE: | |
| 53 /* | |
| 54 * For now, return the host's page size (typically 4k) rather | |
| 55 * than 64k (NaCl's usual page size), which pexes will usually | |
| 56 * be tested with. We could change this to 64k, but then the | |
| 57 * mmap() we define here should round up requested sizes to | |
| 58 * multiples of 64k. | |
| 59 */ | |
| 60 *value = getpagesize(); | |
| 61 return 0; | |
| 62 default: | |
| 63 return EINVAL; | |
| 64 } | |
| 65 } | |
| 66 | |
| 67 static int irt_mmap(void **addr, size_t len, int prot, int flags, | |
| 68 int fd, off_t off) { | |
| 69 void *result = mmap(*addr, len, prot, flags, fd, off); | |
| 70 if (result == MAP_FAILED) | |
| 71 return errno; | |
| 72 *addr = result; | |
| 73 return 0; | |
| 74 } | |
| 75 | |
| 76 static int tls_init(void *ptr) { | |
| 77 g_tls_value = ptr; | |
| 78 return 0; | |
| 79 } | |
| 80 | |
| 81 static void *tls_get(void) { | |
| 82 return g_tls_value; | |
| 83 } | |
| 84 | |
| 85 void *__nacl_read_tp(void) { | |
| 86 return g_tls_value; | |
| 87 } | |
| 88 | |
| 89 static void irt_stub_func(const char *name) { | |
| 90 fprintf(stderr, "Error: Unimplemented IRT function: %s\n", name); | |
| 91 abort(); | |
| 92 } | |
| 93 | |
| 94 #define DEFINE_STUB(name) \ | |
| 95 static void irt_stub_##name() { irt_stub_func(#name); } | |
| 96 #define USE_STUB(s, name) (typeof(s.name)) irt_stub_##name | |
| 97 | |
| 98 DEFINE_STUB(gettod) | |
| 99 DEFINE_STUB(clock) | |
| 100 DEFINE_STUB(nanosleep) | |
| 101 DEFINE_STUB(sched_yield) | |
| 102 static struct nacl_irt_basic irt_basic = { | |
| 103 irt_exit, | |
| 104 USE_STUB(irt_basic, gettod), | |
| 105 USE_STUB(irt_basic, clock), | |
| 106 USE_STUB(irt_basic, nanosleep), | |
| 107 USE_STUB(irt_basic, sched_yield), | |
| 108 irt_sysconf, | |
| 109 }; | |
| 110 | |
| 111 DEFINE_STUB(dup) | |
| 112 DEFINE_STUB(dup2) | |
| 113 DEFINE_STUB(read) | |
| 114 DEFINE_STUB(seek) | |
| 115 DEFINE_STUB(getdents) | |
| 116 static struct nacl_irt_fdio irt_fdio = { | |
| 117 irt_close, | |
| 118 USE_STUB(irt_fdio, dup), | |
| 119 USE_STUB(irt_fdio, dup2), | |
| 120 USE_STUB(irt_fdio, read), | |
| 121 irt_write, | |
| 122 USE_STUB(irt_fdio, seek), | |
| 123 irt_fstat, | |
| 124 USE_STUB(irt_fdio, getdents), | |
| 125 }; | |
| 126 | |
| 127 DEFINE_STUB(munmap) | |
| 128 DEFINE_STUB(mprotect) | |
| 129 static struct nacl_irt_memory irt_memory = { | |
| 130 irt_mmap, | |
| 131 USE_STUB(irt_memory, munmap), | |
| 132 USE_STUB(irt_memory, mprotect), | |
| 133 }; | |
| 134 | |
| 135 static struct nacl_irt_tls irt_tls = { | |
| 136 tls_init, | |
| 137 tls_get, | |
| 138 }; | |
| 139 | |
| 140 struct nacl_interface_table { | |
| 141 const char *name; | |
| 142 const void *table; | |
| 143 size_t size; | |
| 144 }; | |
| 145 | |
| 146 static const struct nacl_interface_table irt_interfaces[] = { | |
| 147 { NACL_IRT_BASIC_v0_1, &irt_basic, sizeof(irt_basic) }, | |
| 148 { NACL_IRT_FDIO_v0_1, &irt_fdio, sizeof(irt_fdio) }, | |
| 149 { NACL_IRT_MEMORY_v0_3, &irt_memory, sizeof(irt_memory) }, | |
| 150 { NACL_IRT_TLS_v0_1, &irt_tls, sizeof(irt_tls) }, | |
| 151 }; | |
| 152 | |
| 153 static size_t irt_interface_query(const char *interface_ident, | |
| 154 void *table, size_t tablesize) { | |
| 155 unsigned i; | |
| 156 for (i = 0; i < NACL_ARRAY_SIZE(irt_interfaces); ++i) { | |
| 157 if (0 == strcmp(interface_ident, irt_interfaces[i].name)) { | |
| 158 const size_t size = irt_interfaces[i].size; | |
| 159 if (size <= tablesize) { | |
| 160 memcpy(table, irt_interfaces[i].table, size); | |
| 161 return size; | |
| 162 } | |
| 163 break; | |
| 164 } | |
| 165 } | |
| 166 fprintf(stderr, "Warning: unavailable IRT interface queried: %s\n", | |
| 167 interface_ident); | |
| 168 return 0; | |
| 169 } | |
| 170 | |
| 171 /* Layout for empty argv/env arrays. */ | |
| 172 struct startup_info { | |
| 173 void (*cleanup_func)(); | |
| 174 int envc; | |
| 175 int argc; | |
| 176 char *argv0; | |
| 177 char *envp0; | |
| 178 Elf32_auxv_t auxv[2]; | |
| 179 }; | |
| 180 | |
| 181 int main(int argc, char **argv) { | |
| 182 /* TODO(mseaborn): Copy across argv and environment arrays. */ | |
| 183 struct startup_info info; | |
| 184 info.cleanup_func = NULL; | |
| 185 info.envc = 0; | |
| 186 info.argc = 0; | |
| 187 info.argv0 = NULL; | |
| 188 info.envp0 = NULL; | |
| 189 info.auxv[0].a_type = AT_SYSINFO; | |
| 190 info.auxv[0].a_un.a_val = (uintptr_t) irt_interface_query; | |
| 191 info.auxv[1].a_type = 0; | |
| 192 info.auxv[1].a_un.a_val = 0; | |
| 193 | |
| 194 _user_start(&info); | |
| 195 return 1; | |
| 196 } | |
| OLD | NEW |