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