diff options
author | mseaborn@chromium.org <mseaborn@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-11 23:16:30 +0000 |
---|---|---|
committer | mseaborn@chromium.org <mseaborn@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-11 23:16:30 +0000 |
commit | 2c68bf03d6980afc7d6efb33b6468ea74b416378 (patch) | |
tree | d0fe974faa5175dd053020cc8f6e03c961da8aa9 /chrome/nacl | |
parent | 2f455515bf4477a86ac3fb8ca577ee9ecd05e2d6 (diff) | |
download | chromium_src-2c68bf03d6980afc7d6efb33b6468ea74b416378.zip chromium_src-2c68bf03d6980afc7d6efb33b6468ea74b416378.tar.gz chromium_src-2c68bf03d6980afc7d6efb33b6468ea74b416378.tar.bz2 |
NaCl: Implement CreateMemoryObject() to support dynamic loading on Mac
Since NaCl needs only one shared memory object that is mappable with
PROT_EXEC, we can take a short cut and pass one in at startup, saving
on IPC.
BUG=http://code.google.com/p/nativeclient/issues/detail?id=583
TEST=test_runner.html with NaCl-side change applied, on a Mac
Review URL: http://codereview.chromium.org/4745001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@65873 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/nacl')
-rw-r--r-- | chrome/nacl/nacl_thread.cc | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/chrome/nacl/nacl_thread.cc b/chrome/nacl/nacl_thread.cc index 709b976..c1f9c67 100644 --- a/chrome/nacl/nacl_thread.cc +++ b/chrome/nacl/nacl_thread.cc @@ -4,6 +4,7 @@ #include "chrome/nacl/nacl_thread.h" +#include "base/atomicops.h" #include "base/scoped_ptr.h" #include "chrome/common/notification_service.h" #include "chrome/common/nacl_messages.h" @@ -13,6 +14,42 @@ #include "chrome/renderer/renderer_sandbox_support_linux.h" #endif +#if defined(OS_MACOSX) +namespace { + +// On Mac OS X, shm_open() works in the sandbox but does not give us +// an FD that we can map as PROT_EXEC. Rather than doing an IPC to +// get an executable SHM region when CreateMemoryObject() is called, +// we preallocate one on startup, since NaCl's sel_ldr only needs one +// of them. This saves a round trip. + +base::subtle::Atomic32 g_shm_fd = -1; + +int CreateMemoryObject(size_t size, bool executable) { + if (executable && size > 0) { + int result_fd = base::subtle::NoBarrier_AtomicExchange(&g_shm_fd, -1); + if (result_fd != -1) { + // ftruncate() is disallowed by the Mac OS X sandbox and + // returns EPERM. Luckily, we can get the same effect with + // lseek() + write(). + if (lseek(result_fd, size - 1, SEEK_SET) == -1) { + LOG(ERROR) << "lseek() failed: " << errno; + return -1; + } + if (write(result_fd, "", 1) != 1) { + LOG(ERROR) << "write() failed: " << errno; + return -1; + } + return result_fd; + } + } + // Fall back to NaCl's default implementation. + return -1; +} + +} +#endif + // This is ugly. We need an interface header file for the exported // sel_ldr interfaces. // TODO(gregoryd,sehr): Add an interface header. @@ -48,6 +85,11 @@ void NaClThread::OnStartSelLdr(std::vector<nacl::FileDescriptor> handles) { #if defined(OS_LINUX) nacl::SetCreateMemoryObjectFunc( renderer_sandbox_support::MakeSharedMemorySegmentViaIPCExecutable); +#elif defined(OS_MACOSX) + nacl::SetCreateMemoryObjectFunc(CreateMemoryObject); + CHECK(handles.size() >= 1); + g_shm_fd = nacl::ToNativeHandle(handles[handles.size() - 1]); + handles.pop_back(); #endif scoped_array<NaClHandle> array(new NaClHandle[handles.size()]); for (size_t i = 0; i < handles.size(); i++) { |