summaryrefslogtreecommitdiffstats
path: root/chrome/nacl
diff options
context:
space:
mode:
authormseaborn@chromium.org <mseaborn@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-11 23:16:30 +0000
committermseaborn@chromium.org <mseaborn@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-11 23:16:30 +0000
commit2c68bf03d6980afc7d6efb33b6468ea74b416378 (patch)
treed0fe974faa5175dd053020cc8f6e03c961da8aa9 /chrome/nacl
parent2f455515bf4477a86ac3fb8ca577ee9ecd05e2d6 (diff)
downloadchromium_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.cc42
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++) {