| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. |  | 
| 2 // Use of this source code is governed by a BSD-style license that can be |  | 
| 3 // found in the LICENSE file. |  | 
| 4 |  | 
| 5 #include "build/build_config.h" |  | 
| 6 |  | 
| 7 #include "native_client/src/include/portability.h" |  | 
| 8 |  | 
| 9 #if NACL_OSX |  | 
| 10 #include <crt_externs.h> |  | 
| 11 #endif |  | 
| 12 |  | 
| 13 EXTERN_C_BEGIN |  | 
| 14 #include "native_client/src/shared/platform/nacl_sync.h" |  | 
| 15 #include "native_client/src/shared/platform/nacl_sync_checked.h" |  | 
| 16 #include "native_client/src/trusted/service_runtime/nacl_globals.h" |  | 
| 17 #include "native_client/src/trusted/service_runtime/expiration.h" |  | 
| 18 #include "native_client/src/trusted/service_runtime/nacl_app.h" |  | 
| 19 #include "native_client/src/trusted/service_runtime/nacl_all_modules.h" |  | 
| 20 #include "native_client/src/trusted/service_runtime/sel_ldr.h" |  | 
| 21 #include "native_client/src/trusted/platform_qualify/nacl_os_qualify.h" |  | 
| 22 EXTERN_C_END |  | 
| 23 |  | 
| 24 int verbosity = 0; |  | 
| 25 |  | 
| 26 #ifdef __GNUC__ |  | 
| 27 |  | 
| 28 /* |  | 
| 29  * GDB's canonical overlay managment routine. |  | 
| 30  * We need its symbol in the symbol table so don't inline it. |  | 
| 31  * TODO(dje): add some explanation for the non-GDB person. |  | 
| 32  */ |  | 
| 33 |  | 
| 34 static void __attribute__ ((noinline)) _ovly_debug_event (void) { |  | 
| 35   /* |  | 
| 36    * The asm volatile is here as instructed by the GCC docs. |  | 
| 37    * It's not enough to declare a function noinline. |  | 
| 38    * GCC will still look inside the function to see if it's worth calling. |  | 
| 39    */ |  | 
| 40   asm volatile (""); |  | 
| 41 } |  | 
| 42 |  | 
| 43 #endif |  | 
| 44 |  | 
| 45 static void StopForDebuggerInit (const struct NaClApp *state) { |  | 
| 46   /* Put xlate_base in a place where gdb can find it.  */ |  | 
| 47   nacl_global_xlate_base = state->xlate_base; |  | 
| 48 |  | 
| 49 #ifdef __GNUC__ |  | 
| 50   _ovly_debug_event (); |  | 
| 51 #endif |  | 
| 52 } |  | 
| 53 |  | 
| 54 int SelMain(const int desc, const NaClHandle handle) { |  | 
| 55   char *av[1]; |  | 
| 56   int ac = 1; |  | 
| 57 |  | 
| 58   char                          **envp; |  | 
| 59   struct NaClApp                state; |  | 
| 60   char                          *nacl_file = 0; |  | 
| 61   int                           main_thread_only = 1; |  | 
| 62   int                           export_addr_to = -2; |  | 
| 63 |  | 
| 64   struct NaClApp                *nap; |  | 
| 65 |  | 
| 66   NaClErrorCode                 errcode; |  | 
| 67 |  | 
| 68   int                           ret_code = 1; |  | 
| 69 #if NACL_OSX |  | 
| 70   // Mac dynamic libraries cannot access the environ variable directly. |  | 
| 71   envp = *_NSGetEnviron(); |  | 
| 72 #else |  | 
| 73   extern char                   **environ; |  | 
| 74   envp = environ; |  | 
| 75 #endif |  | 
| 76 |  | 
| 77 |  | 
| 78   if (NaClHasExpired()) { |  | 
| 79     // TODO(gregoryd): report error to browser? |  | 
| 80     fprintf(stderr, "This version of Native Client has expired.\n"); |  | 
| 81     fprintf(stderr, "Please visit: http://code.google.com/p/nativeclient/\n"); |  | 
| 82     exit(-1); |  | 
| 83   } |  | 
| 84 |  | 
| 85   NaClAllModulesInit(); |  | 
| 86 |  | 
| 87   /* used to be -P */ |  | 
| 88   NaClSrpcFileDescriptor = desc; |  | 
| 89   /* used to be -X */ |  | 
| 90   export_addr_to = desc; |  | 
| 91 |  | 
| 92   /* to be passed to NaClMain, eventually... */ |  | 
| 93   av[0] = const_cast<char*>("NaClMain"); |  | 
| 94 |  | 
| 95   if (!NaClAppCtor(&state)) { |  | 
| 96     fprintf(stderr, "Error while constructing app state\n"); |  | 
| 97     goto done_file_dtor; |  | 
| 98   } |  | 
| 99 |  | 
| 100   state.restrict_to_main_thread = main_thread_only; |  | 
| 101 |  | 
| 102   nap = &state; |  | 
| 103   errcode = LOAD_OK; |  | 
| 104 |  | 
| 105   /* import IMC handle - used to be "-i" */ |  | 
| 106   NaClAddImcHandle(nap, handle, desc); |  | 
| 107 |  | 
| 108   /* |  | 
| 109    * in order to report load error to the browser plugin through the |  | 
| 110    * secure command channel, we do not immediate jump to cleanup code |  | 
| 111    * on error.  rather, we continue processing (assuming earlier |  | 
| 112    * errors do not make it inappropriate) until the secure command |  | 
| 113    * channel is set up, and then bail out. |  | 
| 114    */ |  | 
| 115 |  | 
| 116   /* |  | 
| 117    * Ensure this operating system platform is supported. |  | 
| 118    */ |  | 
| 119   if (!NaClOsIsSupported()) { |  | 
| 120     errcode = LOAD_UNSUPPORTED_OS_PLATFORM; |  | 
| 121     nap->module_load_status = errcode; |  | 
| 122     fprintf(stderr, "Error while loading \"%s\": %s\n", |  | 
| 123             nacl_file, |  | 
| 124             NaClErrorString(errcode)); |  | 
| 125   } |  | 
| 126 |  | 
| 127   /* Give debuggers a well known point at which xlate_base is known.  */ |  | 
| 128   StopForDebuggerInit(&state); |  | 
| 129 |  | 
| 130   /* |  | 
| 131    * If export_addr_to is set to a non-negative integer, we create a |  | 
| 132    * bound socket and socket address pair and bind the former to |  | 
| 133    * descriptor 3 and the latter to descriptor 4.  The socket address |  | 
| 134    * is written out to the export_addr_to descriptor. |  | 
| 135    * |  | 
| 136    * The service runtime also accepts a connection on the bound socket |  | 
| 137    * and spawns a secure command channel thread to service it. |  | 
| 138    * |  | 
| 139    * If export_addr_to is -1, we only create the bound socket and |  | 
| 140    * socket address pair, and we do not export to an IMC socket.  This |  | 
| 141    * use case is typically only used in testing, where we only "dump" |  | 
| 142    * the socket address to stdout or similar channel. |  | 
| 143    */ |  | 
| 144   if (-2 < export_addr_to) { |  | 
| 145     NaClCreateServiceSocket(nap); |  | 
| 146     if (0 <= export_addr_to) { |  | 
| 147       NaClSendServiceAddressTo(nap, export_addr_to); |  | 
| 148       /* |  | 
| 149        * NB: spawns a thread that uses the command channel.  we do |  | 
| 150        * this after NaClAppLoadFile so that NaClApp object is more |  | 
| 151        * fully populated.  Hereafter any changes to nap should be done |  | 
| 152        * while holding locks. |  | 
| 153        */ |  | 
| 154       NaClSecureCommandChannel(nap); |  | 
| 155     } |  | 
| 156   } |  | 
| 157 |  | 
| 158   NaClXMutexLock(&nap->mu); |  | 
| 159   nap->module_load_status = LOAD_OK; |  | 
| 160   NaClXCondVarBroadcast(&nap->cv); |  | 
| 161   NaClXMutexUnlock(&nap->mu); |  | 
| 162 |  | 
| 163   if (NULL != nap->secure_channel) { |  | 
| 164     /* |  | 
| 165      * wait for start_module RPC call on secure channel thread. |  | 
| 166      */ |  | 
| 167     NaClWaitForModuleStartStatusCall(nap); |  | 
| 168   } |  | 
| 169 |  | 
| 170   /* |  | 
| 171    * error reporting done; can quit now if there was an error earlier. |  | 
| 172    */ |  | 
| 173   if (LOAD_OK != errcode) { |  | 
| 174     goto done; |  | 
| 175   } |  | 
| 176 |  | 
| 177   /* |  | 
| 178    * only nap->ehdrs.e_entry is usable, no symbol table is |  | 
| 179    * available. |  | 
| 180    */ |  | 
| 181   if (!NaClCreateMainThread(nap, |  | 
| 182                             ac, |  | 
| 183                             av, |  | 
| 184                             envp)) { |  | 
| 185     fprintf(stderr, "creating main thread failed\n"); |  | 
| 186     goto done; |  | 
| 187   } |  | 
| 188 |  | 
| 189   ret_code = NaClWaitForMainThreadToExit(nap); |  | 
| 190 |  | 
| 191   /* |  | 
| 192    * exit_group or equiv kills any still running threads while module |  | 
| 193    * addr space is still valid.  otherwise we'd have to kill threads |  | 
| 194    * before we clean up the address space. |  | 
| 195    */ |  | 
| 196   return ret_code; |  | 
| 197 |  | 
| 198  done: |  | 
| 199   fflush(stdout); |  | 
| 200 |  | 
| 201   NaClAppDtor(&state); |  | 
| 202 |  | 
| 203  done_file_dtor: |  | 
| 204   fflush(stdout); |  | 
| 205 |  | 
| 206   NaClAllModulesFini(); |  | 
| 207 |  | 
| 208   return ret_code; |  | 
| 209 } |  | 
| 210 |  | 
| OLD | NEW | 
|---|