diff options
author | mseaborn@chromium.org <mseaborn@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-03 04:27:43 +0000 |
---|---|---|
committer | mseaborn@chromium.org <mseaborn@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-03 04:27:43 +0000 |
commit | 338466a8586c58074b8ffb9fcc0d8739a9ff2729 (patch) | |
tree | 93cfefbf64c382aee5b3972b8781dbd59f94567f /chrome | |
parent | acf668bc247c7d432ca6b4e348d1dcdbef408557 (diff) | |
download | chromium_src-338466a8586c58074b8ffb9fcc0d8739a9ff2729.zip chromium_src-338466a8586c58074b8ffb9fcc0d8739a9ff2729.tar.gz chromium_src-338466a8586c58074b8ffb9fcc0d8739a9ff2729.tar.bz2 |
NaCl: Send the integrated runtime (IRT) library to NaCl
Change the browser process to open the IRT file and send it to the
nascent NaCl process.
If the IRT file is not present, handle this gracefully while still
allowing the NaCl process to run. This is because there may be corner
cases to sort out for getting the IRT into the various Chrome install
images. In the mean time, NaCl executables that are not built to use
the IRT should continue to work.
BUG=http://code.google.com/p/nativeclient/issues/detail?id=1595
TEST=nacl_integration on the Chrome trybot
Review URL: http://codereview.chromium.org/6873133
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@83855 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/nacl_host/nacl_process_host.cc | 66 | ||||
-rw-r--r-- | chrome/browser/nacl_host/nacl_process_host.h | 13 | ||||
-rw-r--r-- | chrome/chrome_exe.gypi | 9 | ||||
-rw-r--r-- | chrome/common/nacl_messages.h | 7 | ||||
-rw-r--r-- | chrome/nacl/nacl_launcher_thread.cc | 27 | ||||
-rw-r--r-- | chrome/nacl/nacl_launcher_thread.h | 3 |
6 files changed, 109 insertions, 16 deletions
diff --git a/chrome/browser/nacl_host/nacl_process_host.cc b/chrome/browser/nacl_host/nacl_process_host.cc index 2b9409d..1ab2ddc 100644 --- a/chrome/browser/nacl_host/nacl_process_host.cc +++ b/chrome/browser/nacl_host/nacl_process_host.cc @@ -12,8 +12,10 @@ #include "base/command_line.h" #include "base/metrics/nacl_histogram.h" +#include "base/path_service.h" #include "base/utf_string_conversions.h" #include "base/win/windows_version.h" +#include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/logging_chrome.h" #include "chrome/common/nacl_cmd_line.h" @@ -53,7 +55,8 @@ NaClProcessHost::NaClProcessHost(const std::wstring& url) : BrowserChildProcessHost(NACL_LOADER_PROCESS), reply_msg_(NULL), internal_(new NaClInternal()), - running_on_wow64_(false) { + running_on_wow64_(false), + ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)) { set_name(url); #if defined(OS_WIN) running_on_wow64_ = (base::win::OSInfo::GetInstance()->wow64_status() == @@ -183,9 +186,55 @@ void NaClProcessHost::OnChildDied() { BrowserChildProcessHost::OnChildDied(); } +FilePath::StringType NaClProcessHost::GetIrtLibraryFilename() { + bool on_x86_64 = running_on_wow64_; +#if defined(__x86_64__) + on_x86_64 = true; +#endif + if (on_x86_64) { + return FILE_PATH_LITERAL("nacl_irt_x86_64.nexe"); + } else { + return FILE_PATH_LITERAL("nacl_irt_x86_32.nexe"); + } +} + void NaClProcessHost::OnProcessLaunched() { + // TODO(mseaborn): Opening the IRT file every time a NaCl process is + // launched probably does not work with auto-update on Linux. We + // might need to open the file on startup. If so, we would need to + // ensure that NaCl's ELF loader does not use lseek() on the shared + // IRT file descriptor, otherwise there would be a race condition. + FilePath plugin_dir; + if (!PathService::Get(chrome::DIR_INTERNAL_PLUGINS, &plugin_dir)) { + LOG(ERROR) << "Failed to locate the plugins directory"; + delete this; + return; + } + FilePath irt_path = plugin_dir.Append(GetIrtLibraryFilename()); + base::FileUtilProxy::CreateOrOpenCallback* callback = + callback_factory_.NewCallback(&NaClProcessHost::OpenIrtFileDone); + if (!base::FileUtilProxy::CreateOrOpen( + BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE), + irt_path, + base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ, + callback)) { + delete callback; + delete this; + } +} + +void NaClProcessHost::OpenIrtFileDone(base::PlatformFileError error_code, + base::PassPlatformFile file, + bool created) { std::vector<nacl::FileDescriptor> handles_for_renderer; base::ProcessHandle nacl_process_handle; + bool have_irt_file = false; + if (base::PLATFORM_FILE_OK == error_code) { + internal_->sockets_for_sel_ldr.push_back(file.ReleaseValue()); + have_irt_file = true; + } else { + LOG(ERROR) << "Failed to open the NaCl IRT library file"; + } for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) { #if defined(OS_WIN) @@ -196,9 +245,9 @@ void NaClProcessHost::OnProcessLaunched() { internal_->sockets_for_renderer[i]), chrome_render_message_filter_->peer_handle(), &handle_in_renderer, - GENERIC_READ | GENERIC_WRITE, + 0, // Unused given DUPLICATE_SAME_ACCESS. FALSE, - DUPLICATE_CLOSE_SOURCE); + DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS); handles_for_renderer.push_back( reinterpret_cast<nacl::FileDescriptor>(handle_in_renderer)); #else @@ -235,10 +284,6 @@ void NaClProcessHost::OnProcessLaunched() { reply_msg_ = NULL; internal_->sockets_for_renderer.clear(); - SendStartMessage(); -} - -void NaClProcessHost::SendStartMessage() { std::vector<nacl::FileDescriptor> handles_for_sel_ldr; for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) { #if defined(OS_WIN) @@ -248,8 +293,9 @@ void NaClProcessHost::SendStartMessage() { internal_->sockets_for_sel_ldr[i]), handle(), &channel, - GENERIC_READ | GENERIC_WRITE, - FALSE, DUPLICATE_CLOSE_SOURCE)) { + 0, // Unused given DUPLICATE_SAME_ACCESS. + FALSE, + DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { return; } handles_for_sel_ldr.push_back( @@ -286,7 +332,7 @@ void NaClProcessHost::SendStartMessage() { handles_for_sel_ldr.push_back(memory_fd); #endif - Send(new NaClProcessMsg_Start(handles_for_sel_ldr)); + Send(new NaClProcessMsg_Start(handles_for_sel_ldr, have_irt_file)); internal_->sockets_for_sel_ldr.clear(); } diff --git a/chrome/browser/nacl_host/nacl_process_host.h b/chrome/browser/nacl_host/nacl_process_host.h index 3e36b63..e6e7c3e 100644 --- a/chrome/browser/nacl_host/nacl_process_host.h +++ b/chrome/browser/nacl_host/nacl_process_host.h @@ -8,7 +8,10 @@ #include "build/build_config.h" +#include "base/file_path.h" +#include "base/file_util_proxy.h" #include "base/memory/ref_counted.h" +#include "base/memory/scoped_callback_factory.h" #include "chrome/common/nacl_types.h" #include "content/browser/browser_child_process_host.h" @@ -47,10 +50,16 @@ class NaClProcessHost : public BrowserChildProcessHost { bool LaunchSelLdr(); - void SendStartMessage(); + // Get the architecture-specific filename of NaCl's integrated + // runtime (IRT) library, relative to the plugins directory. + FilePath::StringType GetIrtLibraryFilename(); virtual void OnProcessLaunched(); + void OpenIrtFileDone(base::PlatformFileError error_code, + base::PassPlatformFile file, + bool created); + virtual bool CanShutdown(); private: @@ -67,6 +76,8 @@ class NaClProcessHost : public BrowserChildProcessHost { // Windows platform flag bool running_on_wow64_; + base::ScopedCallbackFactory<NaClProcessHost> callback_factory_; + DISALLOW_COPY_AND_ASSIGN(NaClProcessHost); }; diff --git a/chrome/chrome_exe.gypi b/chrome/chrome_exe.gypi index 1cec8cc..3089092 100644 --- a/chrome/chrome_exe.gypi +++ b/chrome/chrome_exe.gypi @@ -148,6 +148,15 @@ 'chrome_exe_target': 1, 'use_system_xdg_utils%': 0, }, + 'copies': [ + { + 'destination': '<(PRODUCT_DIR)', + 'files': [ + '../native_client/irt_binaries/nacl_irt_x86_32.nexe', + '../native_client/irt_binaries/nacl_irt_x86_64.nexe', + ], + }, + ], 'conditions': [ ['OS=="linux" or OS=="freebsd" or OS=="openbsd"', { 'actions': [ diff --git a/chrome/common/nacl_messages.h b/chrome/common/nacl_messages.h index bcc99fc..5f4aaa6 100644 --- a/chrome/common/nacl_messages.h +++ b/chrome/common/nacl_messages.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -20,8 +20,9 @@ // NaClProcess messages // These are messages sent from the browser to the NaCl process. // Tells the NaCl process to start. -IPC_MESSAGE_CONTROL1(NaClProcessMsg_Start, - std::vector<nacl::FileDescriptor> /* sockets */) +IPC_MESSAGE_CONTROL2(NaClProcessMsg_Start, + std::vector<nacl::FileDescriptor> /* sockets */, + bool /* have_irt_file */) // Tells the NaCl broker to launch a NaCl loader process. IPC_MESSAGE_CONTROL1(NaClProcessMsg_LaunchLoaderThroughBroker, diff --git a/chrome/nacl/nacl_launcher_thread.cc b/chrome/nacl/nacl_launcher_thread.cc index 1a435a0..6ea9a6c 100644 --- a/chrome/nacl/nacl_launcher_thread.cc +++ b/chrome/nacl/nacl_launcher_thread.cc @@ -15,6 +15,11 @@ #include "content/renderer/renderer_sandbox_support_linux.h" #endif +#if defined(OS_WIN) +#include <fcntl.h> +#include <io.h> +#endif + #if defined(OS_MACOSX) namespace { @@ -65,6 +70,7 @@ typedef int NaClHandle; // LOG_FATAL (from base/logging.h). extern "C" int NaClMainForChromium(int handle_count, const NaClHandle* handles, int debug); +extern "C" void NaClSetIrtFileDesc(int fd); NaClLauncherThread::NaClLauncherThread(bool debug) { debug_enabled_ = debug ? 1 : 0; @@ -87,7 +93,8 @@ bool NaClLauncherThread::OnControlMessageReceived(const IPC::Message& msg) { } void NaClLauncherThread::OnStartSelLdr( - std::vector<nacl::FileDescriptor> handles) { + std::vector<nacl::FileDescriptor> handles, + bool have_irt_file) { #if defined(OS_LINUX) nacl::SetCreateMemoryObjectFunc( renderer_sandbox_support::MakeSharedMemorySegmentViaIPC); @@ -97,6 +104,24 @@ void NaClLauncherThread::OnStartSelLdr( g_shm_fd = nacl::ToNativeHandle(handles[handles.size() - 1]); handles.pop_back(); #endif + + if (have_irt_file) { + CHECK(handles.size() >= 1); + NaClHandle irt_handle = nacl::ToNativeHandle(handles[handles.size() - 1]); + handles.pop_back(); +#if defined(OS_WIN) + int irt_desc = _open_osfhandle(reinterpret_cast<intptr_t>(irt_handle), + _O_RDWR | _O_BINARY); + if (irt_desc < 0) { + LOG(ERROR) << "_open_osfhandle() failed"; + return; + } +#else + int irt_desc = irt_handle; +#endif + NaClSetIrtFileDesc(irt_desc); + } + scoped_array<NaClHandle> array(new NaClHandle[handles.size()]); for (size_t i = 0; i < handles.size(); i++) { array[i] = nacl::ToNativeHandle(handles[i]); diff --git a/chrome/nacl/nacl_launcher_thread.h b/chrome/nacl/nacl_launcher_thread.h index 4452ef1..26992ae 100644 --- a/chrome/nacl/nacl_launcher_thread.h +++ b/chrome/nacl/nacl_launcher_thread.h @@ -21,7 +21,8 @@ class NaClLauncherThread : public ChildThread { private: virtual bool OnControlMessageReceived(const IPC::Message& msg); - void OnStartSelLdr(std::vector<nacl::FileDescriptor> handles); + void OnStartSelLdr(std::vector<nacl::FileDescriptor> handles, + bool have_irt_file); int debug_enabled_; |