OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 * Copyright (c) 2012 The Chromium 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 "ppapi/native_client/src/untrusted/pnacl_irt_shim/shim_ppapi.h" | 7 #include "ppapi/native_client/src/untrusted/pnacl_irt_shim/shim_ppapi.h" |
8 | 8 |
9 #include <string.h> | 9 #include <string.h> |
10 #include "native_client/src/untrusted/irt/irt.h" | 10 #include "native_client/src/untrusted/irt/irt.h" |
11 #include "ppapi/nacl_irt/irt_ppapi.h" | 11 #include "ppapi/nacl_irt/irt_ppapi.h" |
12 #include "ppapi/native_client/src/shared/ppapi_proxy/ppruntime.h" | 12 #include "ppapi/native_client/src/shared/ppapi_proxy/ppruntime.h" |
| 13 #include "ppapi/native_client/src/untrusted/pnacl_irt_shim/irt_shim_ppapi.h" |
13 #include "ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.h" | 14 #include "ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.h" |
14 | 15 |
15 /* Use local strcmp to avoid dependency on libc. */ | 16 /* Use local strcmp to avoid dependency on libc. */ |
16 static int mystrcmp(const char* s1, const char *s2) { | 17 static int mystrcmp(const char* s1, const char *s2) { |
17 while((*s1 && *s2) && (*s1++ == *s2++)); | 18 while((*s1 && *s2) && (*s1++ == *s2++)); |
18 return *(--s1) - *(--s2); | 19 return *(--s1) - *(--s2); |
19 } | 20 } |
20 | 21 |
21 TYPE_nacl_irt_query __pnacl_real_irt_interface = NULL; | 22 TYPE_nacl_irt_query __pnacl_real_irt_query_func = NULL; |
22 | 23 |
23 /* | 24 size_t __pnacl_wrap_irt_query_func(const char *interface_ident, |
24 * These remember the interface pointers the user registers by calling the | |
25 * IRT entry point. | |
26 */ | |
27 static struct PP_StartFunctions user_start_functions; | |
28 | |
29 static int32_t wrap_PPPInitializeModule(PP_Module module_id, | |
30 PPB_GetInterface get_browser_intf) { | |
31 __set_real_Pnacl_PPBGetInterface(get_browser_intf); | |
32 /* | |
33 * Calls from user code to the PPB interfaces pass through here and may | |
34 * require shims to convert the ABI. | |
35 */ | |
36 return (*user_start_functions.PPP_InitializeModule)(module_id, | |
37 &__Pnacl_PPBGetInterface); | |
38 } | |
39 | |
40 static void wrap_PPPShutdownModule() { | |
41 (*user_start_functions.PPP_ShutdownModule)(); | |
42 } | |
43 | |
44 static const struct PP_StartFunctions wrapped_ppapi_methods = { | |
45 wrap_PPPInitializeModule, | |
46 wrap_PPPShutdownModule, | |
47 /* | |
48 * Calls from the IRT to the user plugin pass through here and may require | |
49 * shims to convert the ABI. | |
50 */ | |
51 __Pnacl_PPPGetInterface | |
52 }; | |
53 | |
54 static struct nacl_irt_ppapihook real_irt_ppapi_hook; | |
55 | |
56 static int wrap_ppapi_start(const struct PP_StartFunctions *funcs) { | |
57 /* | |
58 * Save the user's real bindings for the start functions. | |
59 */ | |
60 user_start_functions = *funcs; | |
61 __set_real_Pnacl_PPPGetInterface(user_start_functions.PPP_GetInterface); | |
62 | |
63 /* | |
64 * Invoke the IRT's ppapi_start interface with the wrapped interface. | |
65 */ | |
66 return (*real_irt_ppapi_hook.ppapi_start)(&wrapped_ppapi_methods); | |
67 } | |
68 | |
69 size_t __pnacl_irt_interface_wrapper(const char *interface_ident, | |
70 void *table, size_t tablesize) { | 25 void *table, size_t tablesize) { |
71 /* | 26 /* |
72 * Note there is a benign race in initializing the wrapper. | 27 * Note there is a benign race in initializing the wrapper. |
73 * We build the "hook" structure by copying from the IRT's hook and then | 28 * We build the "hook" structure by copying from the IRT's hook and then |
74 * writing our wrapper for the ppapi method. Two threads may end up | 29 * writing our wrapper for the ppapi method. Two threads may end up |
75 * attempting to do this simultaneously, which should not be a problem, | 30 * attempting to do this simultaneously, which should not be a problem, |
76 * as they are writing the same values. | 31 * as they are writing the same values. |
77 */ | 32 */ |
78 if (0 != mystrcmp(interface_ident, NACL_IRT_PPAPIHOOK_v0_1)) { | 33 if (0 != mystrcmp(interface_ident, NACL_IRT_PPAPIHOOK_v0_1)) { |
79 /* | 34 /* |
80 * The interface is not wrapped, so use the real interface. | 35 * The interface is not wrapped, so use the real interface. |
81 */ | 36 */ |
82 return (*__pnacl_real_irt_interface)(interface_ident, table, tablesize); | 37 return (*__pnacl_real_irt_query_func)(interface_ident, table, tablesize); |
83 } | 38 } |
84 if ((*__pnacl_real_irt_interface)(NACL_IRT_PPAPIHOOK_v0_1, | 39 #ifndef PNACL_SHIM_AOT |
85 &real_irt_ppapi_hook, | 40 /* |
86 sizeof real_irt_ppapi_hook) != | 41 * For PNaCl in-the-browser, redirect to using |
| 42 * NACL_IRT_PPAPIHOOK_PNACL_PRIVATE_v0_1 instead of NACL_IRT_PPAPIHOOK_v0_1. |
| 43 */ |
| 44 return (*__pnacl_real_irt_query_func)(NACL_IRT_PPAPIHOOK_PNACL_PRIVATE_v0_1, |
| 45 table, tablesize); |
| 46 #else |
| 47 /* |
| 48 * For offline generated nexes, avoid depending on the private |
| 49 * NACL_IRT_PPAPIHOOK_PNACL_PRIVATE_v0_1 interface, and just do the |
| 50 * overriding here manually. |
| 51 */ |
| 52 struct nacl_irt_ppapihook real_irt_ppapi_hook; |
| 53 if ((*__pnacl_real_irt_query_func)(NACL_IRT_PPAPIHOOK_v0_1, |
| 54 &real_irt_ppapi_hook, |
| 55 sizeof real_irt_ppapi_hook) != |
87 sizeof real_irt_ppapi_hook) { | 56 sizeof real_irt_ppapi_hook) { |
88 return 0; | 57 return 0; |
89 } | 58 } |
| 59 real_irt_ppapi_start = real_irt_ppapi_hook.ppapi_start; |
90 /* | 60 /* |
91 * Copy the interface structure into the client. | 61 * Copy the interface structure into the client. |
92 */ | 62 */ |
93 struct nacl_irt_ppapihook *dest = table; | 63 struct nacl_irt_ppapihook *dest = table; |
94 if (sizeof *dest <= tablesize) { | 64 if (sizeof *dest <= tablesize) { |
95 dest->ppapi_start = wrap_ppapi_start; | 65 dest->ppapi_start = irt_shim_ppapi_start; |
96 dest->ppapi_register_thread_creator = | 66 dest->ppapi_register_thread_creator = |
97 real_irt_ppapi_hook.ppapi_register_thread_creator; | 67 real_irt_ppapi_hook.ppapi_register_thread_creator; |
98 return sizeof *dest; | 68 return sizeof *dest; |
99 } | 69 } |
100 return 0; | 70 return 0; |
| 71 #endif |
101 } | 72 } |
OLD | NEW |