1 /* 2 * Copyright (c) 2011 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 <stddef.h> 8 #include <stdlib.h> 9 #include <string.h> 10 #include <unistd.h> 11 12 #include "native_client/src/include/elf32.h" 13 #include "native_client/src/include/elf_auxv.h" 14 #include "native_client/src/untrusted/irt/irt.h" 15 #include "ppapi/nacl_irt/public/irt_ppapi.h" 16 #include "ppapi/native_client/src/shared/ppapi_proxy/ppruntime.h" 17 #include "ppapi/native_client/src/untrusted/irt_stub/thread_creator.h" 18 fatal_error(const char * message)19static void fatal_error(const char *message) { 20 ssize_t wrote __attribute__((unused)); 21 wrote = write(2, message, strlen(message)); 22 _exit(127); 23 } 24 25 /* 26 * TODO(mcgrathr): This extremely stupid function should not exist. 27 * If the startup calling sequence were sane, this would be done 28 * someplace that has the initial pointer locally rather than stealing 29 * it from environ. 30 * See http://code.google.com/p/nativeclient/issues/detail?id=651 31 */ find_auxv(void)32static Elf32_auxv_t *find_auxv(void) { 33 /* 34 * This presumes environ has its startup-time value on the stack. 35 */ 36 char **ep = environ; 37 while (*ep != NULL) 38 ++ep; 39 return (void *) (ep + 1); 40 } 41 42 /* 43 * Scan the auxv for AT_SYSINFO, which is the pointer to the IRT query function. 44 * TODO(mcgrathr): Could get this from __nacl_irt_query, where the libnacl 45 * startup code stored it, but that would have to be also added as part of 46 * the glibc ABI. 47 */ grok_auxv(const Elf32_auxv_t * auxv)48static TYPE_nacl_irt_query grok_auxv(const Elf32_auxv_t *auxv) { 49 const Elf32_auxv_t *av; 50 for (av = auxv; av->a_type != AT_NULL; ++av) { 51 if (av->a_type == AT_SYSINFO) 52 return (TYPE_nacl_irt_query) av->a_un.a_val; 53 } 54 return NULL; 55 } 56 PpapiPluginStart(const struct PP_StartFunctions * funcs)57int PpapiPluginStart(const struct PP_StartFunctions *funcs) { 58 TYPE_nacl_irt_query query_func = grok_auxv(find_auxv()); 59 60 if (NULL == query_func) 61 fatal_error("PpapiPluginStart: No AT_SYSINFO item found in auxv, " 62 "so cannot start PPAPI. Is the IRT library not present?\n"); 63 64 struct nacl_irt_ppapihook hooks; 65 if (sizeof(hooks) != query_func(NACL_IRT_PPAPIHOOK_v0_1, 66 &hooks, sizeof(hooks))) 67 fatal_error("PpapiPluginStart: PPAPI hooks not found\n"); 68 69 __nacl_register_thread_creator(&hooks); 70 71 return hooks.ppapi_start(funcs); 72 } 73