1/* 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 4 * found in the LICENSE file. 5 */ 6 7#include "ppapi/native_client/src/untrusted/pnacl_irt_shim/shim_ppapi.h" 8 9#include <string.h> 10#include "native_client/src/untrusted/irt/irt.h" 11#include "ppapi/nacl_irt/public/irt_ppapi.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" 14#include "ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.h" 15 16/* Use local strcmp to avoid dependency on libc. */ 17static int mystrcmp(const char* s1, const char *s2) { 18 while((*s1 && *s2) && (*s1++ == *s2++)); 19 return *(--s1) - *(--s2); 20} 21 22TYPE_nacl_irt_query __pnacl_real_irt_query_func = NULL; 23 24size_t __pnacl_wrap_irt_query_func(const char *interface_ident, 25 void *table, size_t tablesize) { 26 /* 27 * Note there is a benign race in initializing the wrapper. 28 * We build the "hook" structure by copying from the IRT's hook and then 29 * writing our wrapper for the ppapi method. Two threads may end up 30 * attempting to do this simultaneously, which should not be a problem, 31 * as they are writing the same values. 32 */ 33 if (0 != mystrcmp(interface_ident, NACL_IRT_PPAPIHOOK_v0_1)) { 34 /* 35 * The interface is not wrapped, so use the real interface. 36 */ 37 return (*__pnacl_real_irt_query_func)(interface_ident, table, tablesize); 38 } 39#ifndef PNACL_SHIM_AOT 40 /* 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) != 56 sizeof real_irt_ppapi_hook) { 57 return 0; 58 } 59 real_irt_ppapi_start = real_irt_ppapi_hook.ppapi_start; 60 /* 61 * Copy the interface structure into the client. 62 */ 63 struct nacl_irt_ppapihook *dest = table; 64 if (sizeof *dest <= tablesize) { 65 dest->ppapi_start = irt_shim_ppapi_start; 66 dest->ppapi_register_thread_creator = 67 real_irt_ppapi_hook.ppapi_register_thread_creator; 68 return sizeof *dest; 69 } 70 return 0; 71#endif 72} 73