OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. | 2 * Copyright 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 #include <stddef.h> |
7 #include "native_client/src/include/elf32.h" | 8 #include "native_client/src/include/elf32.h" |
8 #include "native_client/src/include/elf_auxv.h" | 9 #include "native_client/src/include/elf_auxv.h" |
9 #include "native_client/src/include/nacl_macros.h" | 10 #include "native_client/src/include/nacl_macros.h" |
10 #include "native_client/src/untrusted/pnacl_irt_shim/shim_ppapi.h" | 11 #include "native_client/src/untrusted/irt/irt.h" |
| 12 #include "native_client/src/untrusted/irt/irt_shim.h" |
11 #include "native_client/src/untrusted/nacl/nacl_startup.h" | 13 #include "native_client/src/untrusted/nacl/nacl_startup.h" |
12 | 14 |
| 15 /* |
| 16 * For more information about this hack cf. |
| 17 * src/untrusted/irt/irt_ppapi.c |
| 18 */ |
| 19 |
| 20 static TYPE_nacl_irt_query real_irt_interface; |
| 21 |
| 22 /* cf. src/untrusted/irt/irt.h NACL_IRT_PPAPIHOOK_(SHIMMED_)v0_1 */ |
| 23 static const char prefix_search[] = "nacl-irt-ppapihook"; |
| 24 static const char prefix_replace[] = "nacl-irt-ppapihook-shimmed"; |
| 25 |
| 26 /* Do not make assumptions about strcmp being available. */ |
| 27 static int my_strcmp(const char* s1, const char* s2) { |
| 28 while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2) { |
| 29 s1++; |
| 30 s2++; |
| 31 } |
| 32 return *s1 - *s2; |
| 33 } |
| 34 |
| 35 static size_t pnacl_irt_interface_interceptor(const char *interface_ident, |
| 36 void *table, size_t tablesize) { |
| 37 if (0 == my_strcmp(interface_ident, NACL_IRT_PPAPIHOOK_v0_1)) { |
| 38 return real_irt_interface(NACL_IRT_PPAPIHOOK_SHIMMED_v0_1, table, tablesize)
; |
| 39 } |
| 40 return real_irt_interface(ident, table, tablesize); |
| 41 } |
13 | 42 |
14 /* | 43 /* |
15 * This is the true entry point for untrusted code. | 44 * This is the true entry point for untrusted code. |
16 * See nacl_startup.h for the layout at the argument pointer. | 45 * See nacl_startup.h for the layout at the argument pointer. |
17 */ | 46 */ |
18 void _pnacl_wrapper_start(uint32_t *info) { | 47 void _pnacl_wrapper_start(uint32_t *info) { |
19 Elf32_auxv_t *auxv = nacl_startup_auxv(info); | 48 Elf32_auxv_t *auxv = nacl_startup_auxv(info); |
20 | 49 |
21 Elf32_auxv_t *entry = NULL; | 50 Elf32_auxv_t *entry = NULL; |
22 for (Elf32_auxv_t *av = auxv; av->a_type != AT_NULL; ++av) { | 51 for (Elf32_auxv_t *av = auxv; av->a_type != AT_NULL; ++av) { |
23 if (av->a_type == AT_SYSINFO) { | 52 if (av->a_type == AT_SYSINFO) { |
24 entry = av; | 53 entry = av; |
25 break; | 54 break; |
26 } | 55 } |
27 } | 56 } |
28 | 57 |
29 if (entry != NULL) { | 58 if (entry != NULL) { |
30 /* | 59 /* |
31 * Save the real irt interface. | 60 * Save the real irt interface. |
32 */ | 61 */ |
33 __pnacl_real_irt_interface = (TYPE_nacl_irt_query) entry->a_un.a_val; | 62 real_irt_interface = (TYPE_nacl_irt_query) entry->a_un.a_val; |
34 | 63 |
35 /* | 64 /* |
36 * Overwrite the auxv slot with the pnacl IRT shim query function. | 65 * Overwrite the auxv slot with the pnacl IRT shim query function. |
37 */ | 66 */ |
38 entry->a_type = AT_SYSINFO; | 67 entry->a_type = AT_SYSINFO; |
39 entry->a_un.a_val = (uintptr_t) __pnacl_irt_interface_wrapper; | 68 entry->a_un.a_val = (uintptr_t) pnacl_irt_interface_interceptor; |
40 } | 69 } |
41 | 70 |
42 /* If entry is NULL still allow startup to continue. It may be the case | 71 /* If entry is NULL still allow startup to continue. It may be the case |
43 * that the IRT was not actually used (e.g., for some commandline tests). | 72 * that the IRT was not actually used (e.g., for some commandline tests). |
44 * For newlib, we can tell that the IRT isn't used when libnacl_sys_private.a | 73 * For newlib, we can tell that the IRT isn't used when libnacl_sys_private.a |
45 * is in the bitcode link line. However, glibc does not use | 74 * is in the bitcode link line. However, glibc does not use |
46 * libnacl_sys_private, so that would not work. We could look for -lppapi | 75 * libnacl_sys_private, so that would not work. We could look for -lppapi |
47 * in the bitcode link line, but looking at the bitcode link line | 76 * in the bitcode link line, but looking at the bitcode link line |
48 * seems brittle (what if the bitcode link was separated from translation). | 77 * seems brittle (what if the bitcode link was separated from translation). |
49 * Thus we always wrap _start, even if there is no IRT auxv entry. | 78 * Thus we always wrap _start, even if there is no IRT auxv entry. |
50 */ | 79 */ |
51 | 80 |
52 /* | 81 /* |
53 * Call the user entry point function. It should not return. | 82 * Call the user entry point function. It should not return. |
54 * TODO(sehr): Find a way to ensure this is invoked via a tail call. | 83 * TODO(sehr): Find a way to ensure this is invoked via a tail call. |
55 */ | 84 */ |
56 _start(info); | 85 _start(info); |
57 } | 86 } |
OLD | NEW |