summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/nacl.gypi1
-rw-r--r--chrome/nacl/nacl_thread.cc7
-rw-r--r--chrome/nacl/sel_main.cc199
-rw-r--r--chrome/renderer/render_process_impl.cc8
4 files changed, 204 insertions, 11 deletions
diff --git a/chrome/nacl.gypi b/chrome/nacl.gypi
index e61dbbf..d4be912 100644
--- a/chrome/nacl.gypi
+++ b/chrome/nacl.gypi
@@ -30,6 +30,7 @@
'nacl/nacl_main_platform_delegate_win.cc',
'nacl/nacl_thread.cc',
'nacl/nacl_thread.h',
+ 'nacl/sel_main.cc',
],
# TODO(gregoryd): consider switching NaCl to use Chrome OS defines
'conditions': [
diff --git a/chrome/nacl/nacl_thread.cc b/chrome/nacl/nacl_thread.cc
index 33c0195..0f05f06 100644
--- a/chrome/nacl/nacl_thread.cc
+++ b/chrome/nacl/nacl_thread.cc
@@ -16,9 +16,7 @@ typedef HANDLE NaClHandle;
typedef int NaClHandle;
#endif // NaClHandle
-// This is currently necessary because we have a conflict between
-// NaCl's "struct NaClThread" and Chromium's "class NaClThread".
-extern "C" int NaClMainForChromium(int handle_count, const NaClHandle* handles);
+int SelMain(const int desc, const NaClHandle handle);
NaClThread::NaClThread() {
}
@@ -38,6 +36,5 @@ void NaClThread::OnControlMessageReceived(const IPC::Message& msg) {
void NaClThread::OnStartSelLdr(int channel_descriptor,
nacl::FileDescriptor handle) {
- NaClHandle nacl_handle = nacl::ToNativeHandle(handle);
- NaClMainForChromium(/* handle_count= */ 1, &nacl_handle);
+ SelMain(channel_descriptor, nacl::ToNativeHandle(handle));
}
diff --git a/chrome/nacl/sel_main.cc b/chrome/nacl/sel_main.cc
new file mode 100644
index 0000000..445f283
--- /dev/null
+++ b/chrome/nacl/sel_main.cc
@@ -0,0 +1,199 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "native_client/src/include/portability.h"
+
+#if NACL_OSX
+#include <crt_externs.h>
+#endif
+
+#ifdef _WIN64 /* TODO(gregoryd): remove this when win64 issues are fixed */
+#define NACL_NO_INLINE
+#endif
+
+EXTERN_C_BEGIN
+#include "native_client/src/shared/platform/nacl_sync.h"
+#include "native_client/src/shared/platform/nacl_sync_checked.h"
+#include "native_client/src/trusted/service_runtime/nacl_globals.h"
+#include "native_client/src/trusted/service_runtime/expiration.h"
+#include "native_client/src/trusted/service_runtime/nacl_app.h"
+#include "native_client/src/trusted/service_runtime/nacl_all_modules.h"
+#include "native_client/src/trusted/service_runtime/sel_ldr.h"
+#include "native_client/src/trusted/platform_qualify/nacl_os_qualify.h"
+EXTERN_C_END
+
+int verbosity = 0;
+
+#ifdef __GNUC__
+
+/*
+ * GDB's canonical overlay managment routine.
+ * We need its symbol in the symbol table so don't inline it.
+ * Note: _ovly_debug_event has to be an unmangled 'C' style symbol.
+ * TODO(dje): add some explanation for the non-GDB person.
+ */
+EXTERN_C_BEGIN
+static void __attribute__ ((noinline)) _ovly_debug_event (void) {
+ /*
+ * The asm volatile is here as instructed by the GCC docs.
+ * It's not enough to declare a function noinline.
+ * GCC will still look inside the function to see if it's worth calling.
+ */
+ asm volatile ("");
+}
+EXTERN_C_END
+
+#endif
+
+static void StopForDebuggerInit(const struct NaClApp *state) {
+ /* Put xlate_base in a place where gdb can find it. */
+ nacl_global_xlate_base = state->mem_start;
+
+#ifdef __GNUC__
+ _ovly_debug_event();
+#endif
+}
+
+int SelMain(const int desc, const NaClHandle handle) {
+ char *av[1];
+ int ac = 1;
+
+ char **envp;
+ struct NaClApp state;
+ int main_thread_only = 1;
+ int export_addr_to = -2;
+
+ struct NaClApp *nap;
+
+ NaClErrorCode errcode;
+
+ int ret_code = 1;
+#if NACL_OSX
+ // Mac dynamic libraries cannot access the environ variable directly.
+ envp = *_NSGetEnviron();
+#else
+ extern char **environ;
+ envp = environ;
+#endif
+
+ NaClAllModulesInit();
+
+ /* used to be -P */
+ NaClSrpcFileDescriptor = desc;
+ /* used to be -X */
+ export_addr_to = desc;
+
+ /* to be passed to NaClMain, eventually... */
+ av[0] = const_cast<char*>("NaClMain");
+
+ if (!NaClAppCtor(&state)) {
+ fprintf(stderr, "Error while constructing app state\n");
+ goto done;
+ }
+
+ state.restrict_to_main_thread = main_thread_only;
+
+ nap = &state;
+ errcode = LOAD_OK;
+
+ /* import IMC handle - used to be "-i" */
+ NaClAddImcHandle(nap, handle, desc);
+
+ /*
+ * in order to report load error to the browser plugin through the
+ * secure command channel, we do not immediate jump to cleanup code
+ * on error. rather, we continue processing (assuming earlier
+ * errors do not make it inappropriate) until the secure command
+ * channel is set up, and then bail out.
+ */
+
+ /*
+ * Ensure this operating system platform is supported.
+ */
+ if (!NaClOsIsSupported()) {
+ errcode = LOAD_UNSUPPORTED_OS_PLATFORM;
+ nap->module_load_status = errcode;
+ fprintf(stderr, "Error while loading in SelMain: %s\n",
+ NaClErrorString(errcode));
+ }
+
+ /* Give debuggers a well known point at which xlate_base is known. */
+ StopForDebuggerInit(&state);
+
+ /*
+ * If export_addr_to is set to a non-negative integer, we create a
+ * bound socket and socket address pair and bind the former to
+ * descriptor 3 and the latter to descriptor 4. The socket address
+ * is written out to the export_addr_to descriptor.
+ *
+ * The service runtime also accepts a connection on the bound socket
+ * and spawns a secure command channel thread to service it.
+ *
+ * If export_addr_to is -1, we only create the bound socket and
+ * socket address pair, and we do not export to an IMC socket. This
+ * use case is typically only used in testing, where we only "dump"
+ * the socket address to stdout or similar channel.
+ */
+ if (-2 < export_addr_to) {
+ NaClCreateServiceSocket(nap);
+ if (0 <= export_addr_to) {
+ NaClSendServiceAddressTo(nap, export_addr_to);
+ /*
+ * NB: spawns a thread that uses the command channel. we do
+ * this after NaClAppLoadFile so that NaClApp object is more
+ * fully populated. Hereafter any changes to nap should be done
+ * while holding locks.
+ */
+ NaClSecureCommandChannel(nap);
+ }
+ }
+
+ NaClXMutexLock(&nap->mu);
+ nap->module_load_status = LOAD_OK;
+ NaClXCondVarBroadcast(&nap->cv);
+ NaClXMutexUnlock(&nap->mu);
+
+ if (NULL != nap->secure_channel) {
+ /*
+ * wait for start_module RPC call on secure channel thread.
+ */
+ NaClWaitForModuleStartStatusCall(nap);
+ }
+
+ /*
+ * error reporting done; can quit now if there was an error earlier.
+ */
+ if (LOAD_OK != errcode) {
+ goto done;
+ }
+
+ /*
+ * only nap->ehdrs.e_entry is usable, no symbol table is
+ * available.
+ */
+ if (!NaClCreateMainThread(nap,
+ ac,
+ av,
+ envp)) {
+ fprintf(stderr, "creating main thread failed\n");
+ goto done;
+ }
+
+ ret_code = NaClWaitForMainThreadToExit(nap);
+
+ /*
+ * exit_group or equiv kills any still running threads while module
+ * addr space is still valid. otherwise we'd have to kill threads
+ * before we clean up the address space.
+ */
+ return ret_code;
+
+ done:
+ fflush(stdout);
+
+ NaClAllModulesFini();
+
+ return ret_code;
+}
+
diff --git a/chrome/renderer/render_process_impl.cc b/chrome/renderer/render_process_impl.cc
index 0085ae7..e610df9 100644
--- a/chrome/renderer/render_process_impl.cc
+++ b/chrome/renderer/render_process_impl.cc
@@ -154,12 +154,8 @@ RenderProcessImpl::RenderProcessImpl()
}
#ifndef DISABLE_NACL
- if (command_line.HasSwitch(switches::kInternalNaCl)) {
- std::map<std::string, uintptr_t> funcs;
- funcs["launch_nacl_process"] =
- reinterpret_cast<uintptr_t>(LaunchNaClProcess);
- RegisterInternalNaClPlugin(funcs);
- }
+ if (command_line.HasSwitch(switches::kInternalNaCl))
+ RegisterInternalNaClPlugin(LaunchNaClProcess);
#endif
if (!command_line.HasSwitch(switches::kDisableByteRangeSupport)) {