Home | History | Annotate | Download | only in irt_stub
      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