| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 /* TODO(mcgrathr): this should be predefined in all builds, | 7 /* TODO(mcgrathr): this should be predefined in all builds, |
| 8 but that needs cleaning up scons hooey of nacl_extra_sdk_env vs nacl_env */ | 8 but that needs cleaning up scons hooey of nacl_extra_sdk_env vs nacl_env */ |
| 9 #undef _GNU_SOURCE | 9 #undef _GNU_SOURCE |
| 10 #define _GNU_SOURCE /* This makes glibc's unistd.h declare environ. */ | 10 #define _GNU_SOURCE /* This makes glibc's unistd.h declare environ. */ |
| 11 #include <string.h> | 11 #include <string.h> |
| 12 #include <unistd.h> | 12 #include <unistd.h> |
| 13 | 13 |
| 14 #include "native_client/src/include/elf_auxv.h" | 14 #include "native_client/src/include/elf_auxv.h" |
| 15 #include "native_client/src/include/elf32.h" | 15 #include "native_client/src/include/elf32.h" |
| 16 #include "native_client/src/untrusted/irt/irt_interfaces.h" | 16 #include "native_client/src/untrusted/irt/irt_interfaces.h" |
| 17 #include "native_client/src/untrusted/nacl/nacl_irt.h" | 17 #include "native_client/src/untrusted/nacl/nacl_irt.h" |
| 18 | 18 |
| 19 struct nacl_irt_basic __libnacl_irt_basic; | 19 struct nacl_irt_basic __libnacl_irt_basic; |
| 20 struct nacl_irt_file __libnacl_irt_file; | 20 struct nacl_irt_file __libnacl_irt_file; |
| 21 struct nacl_irt_memory __libnacl_irt_memory; | 21 struct nacl_irt_memory __libnacl_irt_memory; |
| 22 struct nacl_irt_dyncode __libnacl_irt_dyncode; | 22 struct nacl_irt_dyncode __libnacl_irt_dyncode; |
| 23 struct nacl_irt_tls __libnacl_irt_tls; | 23 struct nacl_irt_tls __libnacl_irt_tls; |
| 24 struct nacl_irt_blockhook __libnacl_irt_blockhook; | 24 struct nacl_irt_blockhook __libnacl_irt_blockhook; |
| 25 | 25 |
| 26 TYPE_nacl_irt_query __nacl_irt_query; | 26 TYPE_nacl_irt_query __nacl_irt_query; |
| 27 | 27 |
| 28 /* | 28 /* |
| 29 * TODO(mcgrathr): This extremely stupid function should not exist. | |
| 30 * If the startup calling sequence were sane, this would be done | |
| 31 * someplace that has the initial pointer locally rather than stealing | |
| 32 * it from environ. | |
| 33 * See http://code.google.com/p/nativeclient/issues/detail?id=651 | |
| 34 */ | |
| 35 static Elf32_auxv_t *find_auxv(void) { | |
| 36 /* | |
| 37 * This presumes environ has its startup-time value on the stack. | |
| 38 */ | |
| 39 char **ep = environ; | |
| 40 while (*ep != NULL) | |
| 41 ++ep; | |
| 42 return (void *) (ep + 1); | |
| 43 } | |
| 44 | |
| 45 /* | |
| 46 * Scan the auxv for AT_SYSINFO, which is the pointer to the IRT query function. | 29 * Scan the auxv for AT_SYSINFO, which is the pointer to the IRT query function. |
| 47 * Stash that for later use. | 30 * Stash that for later use. |
| 48 */ | 31 */ |
| 49 static void grok_auxv(const Elf32_auxv_t *auxv) { | 32 static void grok_auxv(const Elf32_auxv_t *auxv) { |
| 50 const Elf32_auxv_t *av; | 33 const Elf32_auxv_t *av; |
| 51 for (av = auxv; av->a_type != AT_NULL; ++av) { | 34 for (av = auxv; av->a_type != AT_NULL; ++av) { |
| 52 if (av->a_type == AT_SYSINFO) { | 35 if (av->a_type == AT_SYSINFO) { |
| 53 __nacl_irt_query = (TYPE_nacl_irt_query) av->a_un.a_val; | 36 __nacl_irt_query = (TYPE_nacl_irt_query) av->a_un.a_val; |
| 54 } | 37 } |
| 55 } | 38 } |
| 56 } | 39 } |
| 57 | 40 |
| 58 #define DO_QUERY(ident, name) \ | 41 #define DO_QUERY(ident, name) \ |
| 59 do_irt_query(ident, &__libnacl_irt_##name, \ | 42 do_irt_query(ident, &__libnacl_irt_##name, \ |
| 60 sizeof(__libnacl_irt_##name), &nacl_irt_##name) | 43 sizeof(__libnacl_irt_##name), &nacl_irt_##name) |
| 61 | 44 |
| 62 static void do_irt_query(const char *interface_ident, | 45 static void do_irt_query(const char *interface_ident, |
| 63 void *buffer, size_t table_size, | 46 void *buffer, size_t table_size, |
| 64 const void *fallback) { | 47 const void *fallback) { |
| 65 if (NULL == __nacl_irt_query || | 48 if (NULL == __nacl_irt_query || |
| 66 __nacl_irt_query(interface_ident, buffer, table_size) != table_size) { | 49 __nacl_irt_query(interface_ident, buffer, table_size) != table_size) { |
| 67 memcpy(buffer, fallback, table_size); | 50 memcpy(buffer, fallback, table_size); |
| 68 } | 51 } |
| 69 } | 52 } |
| 70 | 53 |
| 71 /* | 54 /* |
| 72 * Initialize all our IRT function tables using the query function. | 55 * Initialize all our IRT function tables using the query function. |
| 73 * The query function's address is passed via AT_SYSINFO in auxv. | 56 * The query function's address is passed via AT_SYSINFO in auxv. |
| 74 */ | 57 */ |
| 75 void __libnacl_irt_init(void) { | 58 void __libnacl_irt_init(Elf32_auxv_t *auxv) { |
| 76 grok_auxv(find_auxv()); | 59 grok_auxv(auxv); |
| 77 | 60 |
| 78 DO_QUERY(NACL_IRT_BASIC_v0_1, basic); | 61 DO_QUERY(NACL_IRT_BASIC_v0_1, basic); |
| 79 DO_QUERY(NACL_IRT_FILE_v0_1, file); | 62 DO_QUERY(NACL_IRT_FILE_v0_1, file); |
| 80 DO_QUERY(NACL_IRT_MEMORY_v0_1, memory); | 63 DO_QUERY(NACL_IRT_MEMORY_v0_1, memory); |
| 81 DO_QUERY(NACL_IRT_DYNCODE_v0_1, dyncode); | 64 DO_QUERY(NACL_IRT_DYNCODE_v0_1, dyncode); |
| 82 DO_QUERY(NACL_IRT_TLS_v0_1, tls); | 65 DO_QUERY(NACL_IRT_TLS_v0_1, tls); |
| 83 DO_QUERY(NACL_IRT_BLOCKHOOK_v0_1, blockhook); | 66 DO_QUERY(NACL_IRT_BLOCKHOOK_v0_1, blockhook); |
| 84 } | 67 } |
| OLD | NEW |