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