Rearrange mojo/nacl files.

Files that were previously generated are now checked in to make SDK and
Chromium integration easier. Files needed to build mojo apps have been
moved to //mojo/public/platform/nacl. Files needed to integrate NaCl with
Mojo (used by the NaCl content handler and Chromium) have been moved to
//nacl_bindings. This directory will be copied into the Chrome tree.
//nacl_bindings_generator contains the script for regenerating the
checked-in files. This script will likely go away when the NaCl bindings
have stabilized. //mojo/nacl is deprecated and currently contains testing
and build files specific to the Mojo repo.

BUG=401761
R=jamesr@chromium.org

Review URL: https://codereview.chromium.org/955113002
diff --git a/mojo/nacl/BUILD.gn b/mojo/nacl/BUILD.gn
index 8c17ef1..267f701 100644
--- a/mojo/nacl/BUILD.gn
+++ b/mojo/nacl/BUILD.gn
@@ -2,53 +2,8 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-# All toolchains use the same generated code.
-gen_dir = "$root_build_dir/gen/mojo/nacl"
-
-# Only allow the generator to be run by one toolchain.
-if (current_toolchain == default_toolchain) {
-  # Generate the code to plumb the Mojo public API into the NaCl sandbox.
-  action("mojo_nacl_codegen") {
-    script = "generator/generate_nacl_bindings.py"
-    args = [
-      "-d",
-      rebase_path(gen_dir, root_build_dir),
-    ]
-    inputs = [
-      script,
-      "generator/interface.py",
-      "generator/interface_dsl.py",
-      "generator/mojo_syscall.cc.tmpl",
-      "generator/libmojo.cc.tmpl",
-    ]
-    outputs = [
-      "$gen_dir/mojo_irt.c",
-      "$gen_dir/mojo_irt.h",
-      "$gen_dir/mojo_syscall.cc",
-      "$gen_dir/libmojo.cc",
-    ]
-  }
-}
-
 # Trusted code
 if (!is_nacl) {
-  # A library for launching a NaCl sandbox connected to a Mojo embedder.
-  static_library("monacl_sel") {
-    sources = [
-      "mojo_syscall_internal.h",
-      "$gen_dir/mojo_syscall.cc",
-      "monacl_sel_main.cc",
-    ]
-    deps = [
-      # This target makes sure we have all the pre-processor defines needed to
-      # use NaCl's headers.
-      "//native_client/build/config/nacl:nacl_base",
-      "//native_client/src/trusted/desc:nrd_xfer",
-      "//native_client/src/trusted/service_runtime:sel_main_chrome",
-      ":mojo_nacl_codegen($default_toolchain)",
-    ]
-  }
-
   # A simple shell for running untrusted binaries that talk to the Mojo
   # embedder. (No services.)
   executable("monacl_shell") {
@@ -59,28 +14,15 @@
     deps = [
       "//base:base",
       "//mojo/edk/system:system",
-      ":monacl_sel",
+      "//nacl_bindings:monacl_sel",
     ]
 
-    data_deps =
-        [ ":irt_mojo(//native_client/build/toolchain/nacl:irt_${cpu_arch})" ]
+    data_deps = [ "//nacl_bindings:irt_mojo(//native_client/build/toolchain/nacl:irt_${cpu_arch})" ]
   }
 }
 
 # Untrusted code
 if (is_nacl) {
-  # Thunk mapping the Mojo public API onto NaCl syscalls.
-  static_library("mojo") {
-    sources = [
-      "$gen_dir/libmojo.cc",
-      "$gen_dir/mojo_irt.h",
-    ]
-    include_dirs = [ "$root_build_dir/gen" ]
-    deps = [
-      ":mojo_nacl_codegen($default_toolchain)",
-    ]
-  }
-
   # Unit test for the Mojo public API.
   executable("monacl_test") {
     testonly = true
@@ -91,25 +33,9 @@
     deps = [
       "//mojo/public/c/system/tests:tests",
       "//mojo/public/cpp/system:system",
+      "//mojo/public/platform/nacl:mojo",
       "//testing/gtest:gtest",
       "//testing/gtest:gtest_main",
-      ":mojo",
-    ]
-  }
-
-  executable("irt_mojo") {
-    cflags_c = [ "-std=c99" ]
-    sources = [
-      "irt_entry_mojo.c",
-      "$gen_dir/mojo_irt.c",
-      "$gen_dir/mojo_irt.h",
-    ]
-    include_dirs = [ "$root_build_dir/gen" ]
-    deps = [
-      "//native_client/build/config/nacl:nacl_base",
-      "//native_client/src/untrusted/irt:irt_core_lib",
-      "//native_client/src/untrusted/nacl:imc_syscalls",
-      ":mojo_nacl_codegen($default_toolchain)",
     ]
   }
 }
diff --git a/mojo/nacl/monacl_shell.cc b/mojo/nacl/monacl_shell.cc
index b51126d..714c04f 100644
--- a/mojo/nacl/monacl_shell.cc
+++ b/mojo/nacl/monacl_shell.cc
@@ -9,7 +9,7 @@
 #include "base/logging.h"
 #include "mojo/edk/embedder/embedder.h"
 #include "mojo/edk/embedder/simple_platform_support.h"
-#include "mojo/nacl/monacl_sel_main.h"
+#include "nacl_bindings/monacl_sel_main.h"
 #include "native_client/src/public/nacl_desc.h"
 
 NaClDesc* OpenFile(const char* filename) {
diff --git a/mojo/public/platform/nacl/BUILD.gn b/mojo/public/platform/nacl/BUILD.gn
new file mode 100644
index 0000000..7b4fb2d
--- /dev/null
+++ b/mojo/public/platform/nacl/BUILD.gn
@@ -0,0 +1,17 @@
+# Copyright 2014 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.
+
+import("../../mojo_sdk.gni")
+
+# Untrusted code
+if (is_nacl) {
+  # Thunk mapping the Mojo public API onto NaCl syscalls.
+  mojo_sdk_source_set("mojo") {
+    sources = [
+      "libmojo.cc",
+      "mojo_irt.h",
+    ]
+    mojo_sdk_deps = [ "mojo/public/c/system" ]
+  }
+}
diff --git a/mojo/public/platform/nacl/libmojo.cc b/mojo/public/platform/nacl/libmojo.cc
new file mode 100644
index 0000000..99eddf0
--- /dev/null
+++ b/mojo/public/platform/nacl/libmojo.cc
@@ -0,0 +1,226 @@
+// Copyright 2014 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.
+
+// WARNING this file was generated by generate_nacl_bindings.py
+// Do not edit by hand.
+
+#include "mojo/public/c/system/core.h"
+#include "mojo/public/platform/nacl/mojo_irt.h"
+#include "native_client/src/public/chrome_main.h"
+#include "native_client/src/public/imc_syscalls.h"
+#include "native_client/src/public/imc_types.h"
+#include "native_client/src/untrusted/irt/irt.h"
+
+// The value for this FD must not conflict with uses inside Chromium. However,
+// mojo/nacl doesn't depend on any Chromium headers, so we can't use a #define
+// from there.
+#define NACL_MOJO_DESC (NACL_CHROME_DESC_BASE + 3)
+
+bool g_irt_mojo_valid = false;
+struct nacl_irt_mojo g_irt_mojo;
+
+struct nacl_irt_mojo* get_irt_mojo() {
+  if (!g_irt_mojo_valid) {
+    size_t rc = nacl_interface_query(NACL_IRT_MOJO_v0_1, &g_irt_mojo,
+                                     sizeof(g_irt_mojo));
+    if (rc != sizeof(g_irt_mojo))
+      return NULL;
+    else
+      g_irt_mojo_valid = true;
+  }
+  return &g_irt_mojo;
+}
+
+MojoResult MojoCreateSharedBuffer(
+    const struct MojoCreateSharedBufferOptions* options,
+    uint64_t num_bytes,
+    MojoHandle* shared_buffer_handle) {
+  struct nacl_irt_mojo* irt_mojo = get_irt_mojo();
+  if (irt_mojo == NULL)
+    return MOJO_RESULT_INTERNAL;
+  return irt_mojo->MojoCreateSharedBuffer(options, num_bytes,
+                                          shared_buffer_handle);
+}
+
+MojoResult MojoDuplicateBufferHandle(
+    MojoHandle buffer_handle,
+    const struct MojoDuplicateBufferHandleOptions* options,
+    MojoHandle* new_buffer_handle) {
+  struct nacl_irt_mojo* irt_mojo = get_irt_mojo();
+  if (irt_mojo == NULL)
+    return MOJO_RESULT_INTERNAL;
+  return irt_mojo->MojoDuplicateBufferHandle(buffer_handle, options,
+                                             new_buffer_handle);
+}
+
+MojoResult MojoMapBuffer(MojoHandle buffer_handle,
+                         uint64_t offset,
+                         uint64_t num_bytes,
+                         void** buffer,
+                         MojoMapBufferFlags flags) {
+  struct nacl_irt_mojo* irt_mojo = get_irt_mojo();
+  if (irt_mojo == NULL)
+    return MOJO_RESULT_INTERNAL;
+  return irt_mojo->MojoMapBuffer(buffer_handle, offset, num_bytes, buffer,
+                                 flags);
+}
+
+MojoResult MojoUnmapBuffer(void* buffer) {
+  struct nacl_irt_mojo* irt_mojo = get_irt_mojo();
+  if (irt_mojo == NULL)
+    return MOJO_RESULT_INTERNAL;
+  return irt_mojo->MojoUnmapBuffer(buffer);
+}
+
+MojoResult MojoCreateDataPipe(const struct MojoCreateDataPipeOptions* options,
+                              MojoHandle* data_pipe_producer_handle,
+                              MojoHandle* data_pipe_consumer_handle) {
+  struct nacl_irt_mojo* irt_mojo = get_irt_mojo();
+  if (irt_mojo == NULL)
+    return MOJO_RESULT_INTERNAL;
+  return irt_mojo->MojoCreateDataPipe(options, data_pipe_producer_handle,
+                                      data_pipe_consumer_handle);
+}
+
+MojoResult MojoWriteData(MojoHandle data_pipe_producer_handle,
+                         const void* elements,
+                         uint32_t* num_bytes,
+                         MojoWriteDataFlags flags) {
+  struct nacl_irt_mojo* irt_mojo = get_irt_mojo();
+  if (irt_mojo == NULL)
+    return MOJO_RESULT_INTERNAL;
+  return irt_mojo->MojoWriteData(data_pipe_producer_handle, elements, num_bytes,
+                                 flags);
+}
+
+MojoResult MojoBeginWriteData(MojoHandle data_pipe_producer_handle,
+                              void** buffer,
+                              uint32_t* buffer_num_bytes,
+                              MojoWriteDataFlags flags) {
+  struct nacl_irt_mojo* irt_mojo = get_irt_mojo();
+  if (irt_mojo == NULL)
+    return MOJO_RESULT_INTERNAL;
+  return irt_mojo->MojoBeginWriteData(data_pipe_producer_handle, buffer,
+                                      buffer_num_bytes, flags);
+}
+
+MojoResult MojoEndWriteData(MojoHandle data_pipe_producer_handle,
+                            uint32_t num_bytes_written) {
+  struct nacl_irt_mojo* irt_mojo = get_irt_mojo();
+  if (irt_mojo == NULL)
+    return MOJO_RESULT_INTERNAL;
+  return irt_mojo->MojoEndWriteData(data_pipe_producer_handle,
+                                    num_bytes_written);
+}
+
+MojoResult MojoReadData(MojoHandle data_pipe_consumer_handle,
+                        void* elements,
+                        uint32_t* num_bytes,
+                        MojoReadDataFlags flags) {
+  struct nacl_irt_mojo* irt_mojo = get_irt_mojo();
+  if (irt_mojo == NULL)
+    return MOJO_RESULT_INTERNAL;
+  return irt_mojo->MojoReadData(data_pipe_consumer_handle, elements, num_bytes,
+                                flags);
+}
+
+MojoResult MojoBeginReadData(MojoHandle data_pipe_consumer_handle,
+                             const void** buffer,
+                             uint32_t* buffer_num_bytes,
+                             MojoReadDataFlags flags) {
+  struct nacl_irt_mojo* irt_mojo = get_irt_mojo();
+  if (irt_mojo == NULL)
+    return MOJO_RESULT_INTERNAL;
+  return irt_mojo->MojoBeginReadData(data_pipe_consumer_handle, buffer,
+                                     buffer_num_bytes, flags);
+}
+
+MojoResult MojoEndReadData(MojoHandle data_pipe_consumer_handle,
+                           uint32_t num_bytes_read) {
+  struct nacl_irt_mojo* irt_mojo = get_irt_mojo();
+  if (irt_mojo == NULL)
+    return MOJO_RESULT_INTERNAL;
+  return irt_mojo->MojoEndReadData(data_pipe_consumer_handle, num_bytes_read);
+}
+
+MojoTimeTicks MojoGetTimeTicksNow() {
+  struct nacl_irt_mojo* irt_mojo = get_irt_mojo();
+  if (irt_mojo == NULL)
+    return MOJO_RESULT_INTERNAL;
+  return irt_mojo->MojoGetTimeTicksNow();
+}
+
+MojoResult MojoClose(MojoHandle handle) {
+  struct nacl_irt_mojo* irt_mojo = get_irt_mojo();
+  if (irt_mojo == NULL)
+    return MOJO_RESULT_INTERNAL;
+  return irt_mojo->MojoClose(handle);
+}
+
+MojoResult MojoWait(MojoHandle handle,
+                    MojoHandleSignals signals,
+                    MojoDeadline deadline,
+                    struct MojoHandleSignalsState* signals_state) {
+  struct nacl_irt_mojo* irt_mojo = get_irt_mojo();
+  if (irt_mojo == NULL)
+    return MOJO_RESULT_INTERNAL;
+  return irt_mojo->MojoWait(handle, signals, deadline, signals_state);
+}
+
+MojoResult MojoWaitMany(const MojoHandle* handles,
+                        const MojoHandleSignals* signals,
+                        uint32_t num_handles,
+                        MojoDeadline deadline,
+                        uint32_t* result_index,
+                        struct MojoHandleSignalsState* signals_states) {
+  struct nacl_irt_mojo* irt_mojo = get_irt_mojo();
+  if (irt_mojo == NULL)
+    return MOJO_RESULT_INTERNAL;
+  return irt_mojo->MojoWaitMany(handles, signals, num_handles, deadline,
+                                result_index, signals_states);
+}
+
+MojoResult MojoCreateMessagePipe(
+    const struct MojoCreateMessagePipeOptions* options,
+    MojoHandle* message_pipe_handle0,
+    MojoHandle* message_pipe_handle1) {
+  struct nacl_irt_mojo* irt_mojo = get_irt_mojo();
+  if (irt_mojo == NULL)
+    return MOJO_RESULT_INTERNAL;
+  return irt_mojo->MojoCreateMessagePipe(options, message_pipe_handle0,
+                                         message_pipe_handle1);
+}
+
+MojoResult MojoWriteMessage(MojoHandle message_pipe_handle,
+                            const void* bytes,
+                            uint32_t num_bytes,
+                            const MojoHandle* handles,
+                            uint32_t num_handles,
+                            MojoWriteMessageFlags flags) {
+  struct nacl_irt_mojo* irt_mojo = get_irt_mojo();
+  if (irt_mojo == NULL)
+    return MOJO_RESULT_INTERNAL;
+  return irt_mojo->MojoWriteMessage(message_pipe_handle, bytes, num_bytes,
+                                    handles, num_handles, flags);
+}
+
+MojoResult MojoReadMessage(MojoHandle message_pipe_handle,
+                           void* bytes,
+                           uint32_t* num_bytes,
+                           MojoHandle* handles,
+                           uint32_t* num_handles,
+                           MojoReadMessageFlags flags) {
+  struct nacl_irt_mojo* irt_mojo = get_irt_mojo();
+  if (irt_mojo == NULL)
+    return MOJO_RESULT_INTERNAL;
+  return irt_mojo->MojoReadMessage(message_pipe_handle, bytes, num_bytes,
+                                   handles, num_handles, flags);
+}
+
+MojoResult _MojoGetInitialHandle(MojoHandle* handle) {
+  struct nacl_irt_mojo* irt_mojo = get_irt_mojo();
+  if (irt_mojo == NULL)
+    return MOJO_RESULT_INTERNAL;
+  return irt_mojo->_MojoGetInitialHandle(handle);
+}
diff --git a/mojo/public/platform/nacl/mojo_irt.h b/mojo/public/platform/nacl/mojo_irt.h
new file mode 100644
index 0000000..db3a180
--- /dev/null
+++ b/mojo/public/platform/nacl/mojo_irt.h
@@ -0,0 +1,100 @@
+// Copyright 2015 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.
+
+// WARNING this file was generated by generate_nacl_bindings.py
+// Do not edit by hand.
+
+#ifndef MOJO_PUBLIC_PLATFORM_NACL_MOJO_IRT_H_
+#define MOJO_PUBLIC_PLATFORM_NACL_MOJO_IRT_H_
+
+#include "mojo/public/c/system/buffer.h"
+#include "mojo/public/c/system/data_pipe.h"
+#include "mojo/public/c/system/message_pipe.h"
+#include "mojo/public/c/system/types.h"
+
+#define NACL_IRT_MOJO_v0_1 "nacl-irt-mojo-0.1"
+
+struct nacl_irt_mojo {
+  MojoResult (*MojoCreateSharedBuffer)(
+      const struct MojoCreateSharedBufferOptions* options,
+      uint64_t num_bytes,
+      MojoHandle* shared_buffer_handle);
+  MojoResult (*MojoDuplicateBufferHandle)(
+      MojoHandle buffer_handle,
+      const struct MojoDuplicateBufferHandleOptions* options,
+      MojoHandle* new_buffer_handle);
+  MojoResult (*MojoMapBuffer)(MojoHandle buffer_handle,
+                              uint64_t offset,
+                              uint64_t num_bytes,
+                              void** buffer,
+                              MojoMapBufferFlags flags);
+  MojoResult (*MojoUnmapBuffer)(void* buffer);
+  MojoResult (*MojoCreateDataPipe)(
+      const struct MojoCreateDataPipeOptions* options,
+      MojoHandle* data_pipe_producer_handle,
+      MojoHandle* data_pipe_consumer_handle);
+  MojoResult (*MojoWriteData)(MojoHandle data_pipe_producer_handle,
+                              const void* elements,
+                              uint32_t* num_bytes,
+                              MojoWriteDataFlags flags);
+  MojoResult (*MojoBeginWriteData)(MojoHandle data_pipe_producer_handle,
+                                   void** buffer,
+                                   uint32_t* buffer_num_bytes,
+                                   MojoWriteDataFlags flags);
+  MojoResult (*MojoEndWriteData)(MojoHandle data_pipe_producer_handle,
+                                 uint32_t num_bytes_written);
+  MojoResult (*MojoReadData)(MojoHandle data_pipe_consumer_handle,
+                             void* elements,
+                             uint32_t* num_bytes,
+                             MojoReadDataFlags flags);
+  MojoResult (*MojoBeginReadData)(MojoHandle data_pipe_consumer_handle,
+                                  const void** buffer,
+                                  uint32_t* buffer_num_bytes,
+                                  MojoReadDataFlags flags);
+  MojoResult (*MojoEndReadData)(MojoHandle data_pipe_consumer_handle,
+                                uint32_t num_bytes_read);
+  MojoTimeTicks (*MojoGetTimeTicksNow)();
+  MojoResult (*MojoClose)(MojoHandle handle);
+  MojoResult (*MojoWait)(MojoHandle handle,
+                         MojoHandleSignals signals,
+                         MojoDeadline deadline,
+                         struct MojoHandleSignalsState* signals_state);
+  MojoResult (*MojoWaitMany)(const MojoHandle* handles,
+                             const MojoHandleSignals* signals,
+                             uint32_t num_handles,
+                             MojoDeadline deadline,
+                             uint32_t* result_index,
+                             struct MojoHandleSignalsState* signals_states);
+  MojoResult (*MojoCreateMessagePipe)(
+      const struct MojoCreateMessagePipeOptions* options,
+      MojoHandle* message_pipe_handle0,
+      MojoHandle* message_pipe_handle1);
+  MojoResult (*MojoWriteMessage)(MojoHandle message_pipe_handle,
+                                 const void* bytes,
+                                 uint32_t num_bytes,
+                                 const MojoHandle* handles,
+                                 uint32_t num_handles,
+                                 MojoWriteMessageFlags flags);
+  MojoResult (*MojoReadMessage)(MojoHandle message_pipe_handle,
+                                void* bytes,
+                                uint32_t* num_bytes,
+                                MojoHandle* handles,
+                                uint32_t* num_handles,
+                                MojoReadMessageFlags flags);
+  MojoResult (*_MojoGetInitialHandle)(MojoHandle* handle);
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+size_t mojo_irt_query(const char* interface_ident,
+                      void* table,
+                      size_t tablesize);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // MOJO_PUBLIC_PLATFORM_NACL_MOJO_IRT_H_
diff --git a/mojo/tools/roll/rev_sdk.py b/mojo/tools/roll/rev_sdk.py
index 870a89b..e3dfdea 100755
--- a/mojo/tools/roll/rev_sdk.py
+++ b/mojo/tools/roll/rev_sdk.py
@@ -13,6 +13,7 @@
 sdk_dirs_to_clone = [
   "mojo/edk",
   "mojo/public",
+  "nacl_bindings",
 ]
 
 
diff --git a/nacl_bindings/BUILD.gn b/nacl_bindings/BUILD.gn
new file mode 100644
index 0000000..84920ee
--- /dev/null
+++ b/nacl_bindings/BUILD.gn
@@ -0,0 +1,42 @@
+# Copyright 2015 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.
+
+# Trusted code
+if (!is_nacl) {
+  # A library for launching a NaCl sandbox connected to a Mojo embedder.
+  source_set("monacl_sel") {
+    sources = [
+      "mojo_syscall_internal.h",
+      "mojo_syscall.cc",
+      "monacl_sel_main.cc",
+    ]
+    deps = [
+      "../mojo/public/c/system",
+
+      # This target makes sure we have all the pre-processor defines needed to
+      # use NaCl's headers.
+      "//native_client/build/config/nacl:nacl_base",
+      "//native_client/src/trusted/desc:nrd_xfer",
+      "//native_client/src/trusted/service_runtime:sel_main_chrome",
+    ]
+  }
+}
+
+# Untrusted code
+if (is_nacl) {
+  executable("irt_mojo") {
+    cflags_c = [ "-std=c99" ]
+    sources = [
+      "../mojo/public/platform/nacl/mojo_irt.h",
+      "irt_entry_mojo.c",
+      "mojo_irt.c",
+    ]
+    deps = [
+      "../mojo/public/c/system",
+      "//native_client/build/config/nacl:nacl_base",
+      "//native_client/src/untrusted/irt:irt_core_lib",
+      "//native_client/src/untrusted/nacl:imc_syscalls",
+    ]
+  }
+}
diff --git a/mojo/nacl/irt_entry_mojo.c b/nacl_bindings/irt_entry_mojo.c
similarity index 92%
rename from mojo/nacl/irt_entry_mojo.c
rename to nacl_bindings/irt_entry_mojo.c
index 186da0e..5c413dd 100644
--- a/mojo/nacl/irt_entry_mojo.c
+++ b/nacl_bindings/irt_entry_mojo.c
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "mojo/nacl/mojo_irt.h"
+#include "mojo/public/platform/nacl/mojo_irt.h"
 #include "native_client/src/public/irt_core.h"
 
 static size_t irt_query(const char* interface_ident,
diff --git a/nacl_bindings/mojo_irt.c b/nacl_bindings/mojo_irt.c
new file mode 100644
index 0000000..3595f0b
--- /dev/null
+++ b/nacl_bindings/mojo_irt.c
@@ -0,0 +1,357 @@
+// Copyright 2015 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.
+
+// WARNING this file was generated by generate_nacl_bindings.py
+// Do not edit by hand.
+
+#include <stdio.h>
+#include <string.h>
+
+#include "mojo/public/c/system/core.h"
+#include "mojo/public/platform/nacl/mojo_irt.h"
+#include "native_client/src/public/chrome_main.h"
+#include "native_client/src/public/imc_syscalls.h"
+#include "native_client/src/public/imc_types.h"
+#include "native_client/src/public/irt_core.h"
+
+#define NACL_MOJO_DESC (NACL_CHROME_DESC_BASE + 3)
+
+static void DoMojoCall(uint32_t params[], nacl_abi_size_t num_params) {
+  struct NaClAbiNaClImcMsgIoVec iov[1] = {
+    {params, num_params}
+  };
+  struct NaClAbiNaClImcMsgHdr msgh = {iov, 1, NULL, 0};
+  // Note: return value unchecked.  We're relying on the result parameter being
+  // unmodified - if the syscall fails, the Mojo function will return whatever
+  // the result parameter was initialized to before this function was called.
+  imc_sendmsg(NACL_MOJO_DESC, &msgh, 0);
+}
+
+static MojoResult irt_MojoCreateSharedBuffer(
+    const struct MojoCreateSharedBufferOptions* options,
+    uint64_t num_bytes,
+    MojoHandle* shared_buffer_handle) {
+  uint32_t params[5];
+  MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
+  params[0] = 0;
+  params[1] = (uint32_t)(options);
+  params[2] = (uint32_t)(&num_bytes);
+  params[3] = (uint32_t)(shared_buffer_handle);
+  params[4] = (uint32_t)(&result);
+  DoMojoCall(params, sizeof(params));
+  return result;
+};
+
+static MojoResult irt_MojoDuplicateBufferHandle(
+    MojoHandle buffer_handle,
+    const struct MojoDuplicateBufferHandleOptions* options,
+    MojoHandle* new_buffer_handle) {
+  uint32_t params[5];
+  MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
+  params[0] = 1;
+  params[1] = (uint32_t)(&buffer_handle);
+  params[2] = (uint32_t)(options);
+  params[3] = (uint32_t)(new_buffer_handle);
+  params[4] = (uint32_t)(&result);
+  DoMojoCall(params, sizeof(params));
+  return result;
+};
+
+static MojoResult irt_MojoMapBuffer(
+    MojoHandle buffer_handle,
+    uint64_t offset,
+    uint64_t num_bytes,
+    void** buffer,
+    MojoMapBufferFlags flags) {
+  uint32_t params[7];
+  MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
+  params[0] = 2;
+  params[1] = (uint32_t)(&buffer_handle);
+  params[2] = (uint32_t)(&offset);
+  params[3] = (uint32_t)(&num_bytes);
+  params[4] = (uint32_t)(buffer);
+  params[5] = (uint32_t)(&flags);
+  params[6] = (uint32_t)(&result);
+  DoMojoCall(params, sizeof(params));
+  return result;
+};
+
+static MojoResult irt_MojoUnmapBuffer(void* buffer) {
+  uint32_t params[3];
+  MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
+  params[0] = 3;
+  params[1] = (uint32_t)(&buffer);
+  params[2] = (uint32_t)(&result);
+  DoMojoCall(params, sizeof(params));
+  return result;
+};
+
+static MojoResult irt_MojoCreateDataPipe(
+    const struct MojoCreateDataPipeOptions* options,
+    MojoHandle* data_pipe_producer_handle,
+    MojoHandle* data_pipe_consumer_handle) {
+  uint32_t params[5];
+  MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
+  params[0] = 4;
+  params[1] = (uint32_t)(options);
+  params[2] = (uint32_t)(data_pipe_producer_handle);
+  params[3] = (uint32_t)(data_pipe_consumer_handle);
+  params[4] = (uint32_t)(&result);
+  DoMojoCall(params, sizeof(params));
+  return result;
+};
+
+static MojoResult irt_MojoWriteData(
+    MojoHandle data_pipe_producer_handle,
+    const void* elements,
+    uint32_t* num_bytes,
+    MojoWriteDataFlags flags) {
+  uint32_t params[6];
+  MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
+  params[0] = 5;
+  params[1] = (uint32_t)(&data_pipe_producer_handle);
+  params[2] = (uint32_t)(elements);
+  params[3] = (uint32_t)(num_bytes);
+  params[4] = (uint32_t)(&flags);
+  params[5] = (uint32_t)(&result);
+  DoMojoCall(params, sizeof(params));
+  return result;
+};
+
+static MojoResult irt_MojoBeginWriteData(
+    MojoHandle data_pipe_producer_handle,
+    void** buffer,
+    uint32_t* buffer_num_bytes,
+    MojoWriteDataFlags flags) {
+  uint32_t params[6];
+  MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
+  params[0] = 6;
+  params[1] = (uint32_t)(&data_pipe_producer_handle);
+  params[2] = (uint32_t)(buffer);
+  params[3] = (uint32_t)(buffer_num_bytes);
+  params[4] = (uint32_t)(&flags);
+  params[5] = (uint32_t)(&result);
+  DoMojoCall(params, sizeof(params));
+  return result;
+};
+
+static MojoResult irt_MojoEndWriteData(
+    MojoHandle data_pipe_producer_handle,
+    uint32_t num_bytes_written) {
+  uint32_t params[4];
+  MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
+  params[0] = 7;
+  params[1] = (uint32_t)(&data_pipe_producer_handle);
+  params[2] = (uint32_t)(&num_bytes_written);
+  params[3] = (uint32_t)(&result);
+  DoMojoCall(params, sizeof(params));
+  return result;
+};
+
+static MojoResult irt_MojoReadData(
+    MojoHandle data_pipe_consumer_handle,
+    void* elements,
+    uint32_t* num_bytes,
+    MojoReadDataFlags flags) {
+  uint32_t params[6];
+  MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
+  params[0] = 8;
+  params[1] = (uint32_t)(&data_pipe_consumer_handle);
+  params[2] = (uint32_t)(elements);
+  params[3] = (uint32_t)(num_bytes);
+  params[4] = (uint32_t)(&flags);
+  params[5] = (uint32_t)(&result);
+  DoMojoCall(params, sizeof(params));
+  return result;
+};
+
+static MojoResult irt_MojoBeginReadData(
+    MojoHandle data_pipe_consumer_handle,
+    const void** buffer,
+    uint32_t* buffer_num_bytes,
+    MojoReadDataFlags flags) {
+  uint32_t params[6];
+  MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
+  params[0] = 9;
+  params[1] = (uint32_t)(&data_pipe_consumer_handle);
+  params[2] = (uint32_t)(buffer);
+  params[3] = (uint32_t)(buffer_num_bytes);
+  params[4] = (uint32_t)(&flags);
+  params[5] = (uint32_t)(&result);
+  DoMojoCall(params, sizeof(params));
+  return result;
+};
+
+static MojoResult irt_MojoEndReadData(
+    MojoHandle data_pipe_consumer_handle,
+    uint32_t num_bytes_read) {
+  uint32_t params[4];
+  MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
+  params[0] = 10;
+  params[1] = (uint32_t)(&data_pipe_consumer_handle);
+  params[2] = (uint32_t)(&num_bytes_read);
+  params[3] = (uint32_t)(&result);
+  DoMojoCall(params, sizeof(params));
+  return result;
+};
+
+static MojoTimeTicks irt_MojoGetTimeTicksNow() {
+  uint32_t params[2];
+  MojoTimeTicks result = 0;
+  params[0] = 11;
+  params[1] = (uint32_t)(&result);
+  DoMojoCall(params, sizeof(params));
+  return result;
+};
+
+static MojoResult irt_MojoClose(MojoHandle handle) {
+  uint32_t params[3];
+  MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
+  params[0] = 12;
+  params[1] = (uint32_t)(&handle);
+  params[2] = (uint32_t)(&result);
+  DoMojoCall(params, sizeof(params));
+  return result;
+};
+
+static MojoResult irt_MojoWait(
+    MojoHandle handle,
+    MojoHandleSignals signals,
+    MojoDeadline deadline,
+    struct MojoHandleSignalsState* signals_state) {
+  uint32_t params[6];
+  MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
+  params[0] = 13;
+  params[1] = (uint32_t)(&handle);
+  params[2] = (uint32_t)(&signals);
+  params[3] = (uint32_t)(&deadline);
+  params[4] = (uint32_t)(signals_state);
+  params[5] = (uint32_t)(&result);
+  DoMojoCall(params, sizeof(params));
+  return result;
+};
+
+static MojoResult irt_MojoWaitMany(
+    const MojoHandle* handles,
+    const MojoHandleSignals* signals,
+    uint32_t num_handles,
+    MojoDeadline deadline,
+    uint32_t* result_index,
+    struct MojoHandleSignalsState* signals_states) {
+  uint32_t params[8];
+  MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
+  params[0] = 14;
+  params[1] = (uint32_t)(handles);
+  params[2] = (uint32_t)(signals);
+  params[3] = (uint32_t)(&num_handles);
+  params[4] = (uint32_t)(&deadline);
+  params[5] = (uint32_t)(result_index);
+  params[6] = (uint32_t)(signals_states);
+  params[7] = (uint32_t)(&result);
+  DoMojoCall(params, sizeof(params));
+  return result;
+};
+
+static MojoResult irt_MojoCreateMessagePipe(
+    const struct MojoCreateMessagePipeOptions* options,
+    MojoHandle* message_pipe_handle0,
+    MojoHandle* message_pipe_handle1) {
+  uint32_t params[5];
+  MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
+  params[0] = 15;
+  params[1] = (uint32_t)(options);
+  params[2] = (uint32_t)(message_pipe_handle0);
+  params[3] = (uint32_t)(message_pipe_handle1);
+  params[4] = (uint32_t)(&result);
+  DoMojoCall(params, sizeof(params));
+  return result;
+};
+
+static MojoResult irt_MojoWriteMessage(
+    MojoHandle message_pipe_handle,
+    const void* bytes,
+    uint32_t num_bytes,
+    const MojoHandle* handles,
+    uint32_t num_handles,
+    MojoWriteMessageFlags flags) {
+  uint32_t params[8];
+  MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
+  params[0] = 16;
+  params[1] = (uint32_t)(&message_pipe_handle);
+  params[2] = (uint32_t)(bytes);
+  params[3] = (uint32_t)(&num_bytes);
+  params[4] = (uint32_t)(handles);
+  params[5] = (uint32_t)(&num_handles);
+  params[6] = (uint32_t)(&flags);
+  params[7] = (uint32_t)(&result);
+  DoMojoCall(params, sizeof(params));
+  return result;
+};
+
+static MojoResult irt_MojoReadMessage(
+    MojoHandle message_pipe_handle,
+    void* bytes,
+    uint32_t* num_bytes,
+    MojoHandle* handles,
+    uint32_t* num_handles,
+    MojoReadMessageFlags flags) {
+  uint32_t params[8];
+  MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
+  params[0] = 17;
+  params[1] = (uint32_t)(&message_pipe_handle);
+  params[2] = (uint32_t)(bytes);
+  params[3] = (uint32_t)(num_bytes);
+  params[4] = (uint32_t)(handles);
+  params[5] = (uint32_t)(num_handles);
+  params[6] = (uint32_t)(&flags);
+  params[7] = (uint32_t)(&result);
+  DoMojoCall(params, sizeof(params));
+  return result;
+};
+
+static MojoResult irt__MojoGetInitialHandle(MojoHandle* handle) {
+  uint32_t params[3];
+  MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
+  params[0] = 18;
+  params[1] = (uint32_t)(handle);
+  params[2] = (uint32_t)(&result);
+  DoMojoCall(params, sizeof(params));
+  return result;
+};
+
+struct nacl_irt_mojo kIrtMojo = {
+  &irt_MojoCreateSharedBuffer,
+  &irt_MojoDuplicateBufferHandle,
+  &irt_MojoMapBuffer,
+  &irt_MojoUnmapBuffer,
+  &irt_MojoCreateDataPipe,
+  &irt_MojoWriteData,
+  &irt_MojoBeginWriteData,
+  &irt_MojoEndWriteData,
+  &irt_MojoReadData,
+  &irt_MojoBeginReadData,
+  &irt_MojoEndReadData,
+  &irt_MojoGetTimeTicksNow,
+  &irt_MojoClose,
+  &irt_MojoWait,
+  &irt_MojoWaitMany,
+  &irt_MojoCreateMessagePipe,
+  &irt_MojoWriteMessage,
+  &irt_MojoReadMessage,
+  &irt__MojoGetInitialHandle,
+};
+
+
+size_t mojo_irt_query(const char* interface_ident,
+                      void* table,
+                      size_t tablesize) {
+  static const size_t size = sizeof(kIrtMojo);
+  if (0 == strcmp(interface_ident, NACL_IRT_MOJO_v0_1)) {
+    if (size <= tablesize) {
+      memcpy(table, &kIrtMojo, size);
+      return size;
+    }
+  }
+  return 0;
+}
diff --git a/nacl_bindings/mojo_syscall.cc b/nacl_bindings/mojo_syscall.cc
new file mode 100644
index 0000000..34fcccb
--- /dev/null
+++ b/nacl_bindings/mojo_syscall.cc
@@ -0,0 +1,879 @@
+// Copyright 2014 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.
+
+// WARNING this file was generated by generate_nacl_bindings.py
+// Do not edit by hand.
+
+#include "nacl_bindings/mojo_syscall.h"
+
+#include <stdio.h>
+
+#include "mojo/public/c/system/core.h"
+#include "nacl_bindings/mojo_syscall_internal.h"
+#include "native_client/src/public/chrome_main.h"
+#include "native_client/src/public/nacl_app.h"
+#include "native_client/src/trusted/desc/nacl_desc_custom.h"
+
+MojoHandle g_mojo_handle = MOJO_HANDLE_INVALID;
+
+namespace {
+
+MojoResult _MojoGetInitialHandle(MojoHandle* handle) {
+  *handle = g_mojo_handle;
+  return MOJO_RESULT_OK;
+}
+
+void MojoDescDestroy(void* handle) {
+}
+
+ssize_t MojoDescSendMsg(void* handle,
+                        const struct NaClImcTypedMsgHdr* msg,
+                        int flags) {
+  struct NaClApp* nap = static_cast<struct NaClApp*>(handle);
+
+  if (msg->iov_length != 1 || msg->ndesc_length != 0) {
+    return -1;
+  }
+
+  uint32_t volatile* params = static_cast<uint32_t volatile*>(msg->iov[0].base);
+  size_t num_params = msg->iov[0].length / sizeof(*params);
+
+  if (num_params < 1) {
+    return -1;
+  }
+
+  uint32_t msg_type = params[0];
+  switch (msg_type) {
+    case 0: {
+      if (num_params != 5) {
+        return -1;
+      }
+      const struct MojoCreateSharedBufferOptions* options;
+      uint64_t num_bytes_value;
+      MojoHandle volatile* shared_buffer_handle_ptr;
+      MojoHandle shared_buffer_handle_value;
+      MojoResult volatile* result_ptr;
+      MojoResult result_value;
+      {
+        ScopedCopyLock copy_lock(nap);
+        if (!ConvertExtensibleStructInput(nap, params[1], true, &options)) {
+          return -1;
+        }
+        if (!ConvertScalarInput(nap, params[2], &num_bytes_value)) {
+          return -1;
+        }
+        if (!ConvertScalarInOut(nap, params[3], false,
+                                &shared_buffer_handle_value,
+                                &shared_buffer_handle_ptr)) {
+          return -1;
+        }
+        if (!ConvertScalarOutput(nap, params[4], false, &result_ptr)) {
+          return -1;
+        }
+      }
+
+      result_value = MojoCreateSharedBuffer(options, num_bytes_value,
+                                            &shared_buffer_handle_value);
+
+      {
+        ScopedCopyLock copy_lock(nap);
+        *shared_buffer_handle_ptr = shared_buffer_handle_value;
+        *result_ptr = result_value;
+      }
+
+      return 0;
+    }
+    case 1: {
+      if (num_params != 5) {
+        return -1;
+      }
+      MojoHandle buffer_handle_value;
+      const struct MojoDuplicateBufferHandleOptions* options;
+      MojoHandle volatile* new_buffer_handle_ptr;
+      MojoHandle new_buffer_handle_value;
+      MojoResult volatile* result_ptr;
+      MojoResult result_value;
+      {
+        ScopedCopyLock copy_lock(nap);
+        if (!ConvertScalarInput(nap, params[1], &buffer_handle_value)) {
+          return -1;
+        }
+        if (!ConvertExtensibleStructInput(nap, params[2], true, &options)) {
+          return -1;
+        }
+        if (!ConvertScalarInOut(nap, params[3], false, &new_buffer_handle_value,
+                                &new_buffer_handle_ptr)) {
+          return -1;
+        }
+        if (!ConvertScalarOutput(nap, params[4], false, &result_ptr)) {
+          return -1;
+        }
+      }
+
+      result_value = MojoDuplicateBufferHandle(buffer_handle_value, options,
+                                               &new_buffer_handle_value);
+
+      {
+        ScopedCopyLock copy_lock(nap);
+        *new_buffer_handle_ptr = new_buffer_handle_value;
+        *result_ptr = result_value;
+      }
+
+      return 0;
+    }
+    case 2: {
+      if (num_params != 7) {
+        return -1;
+      }
+      MojoHandle buffer_handle_value;
+      uint64_t offset_value;
+      uint64_t num_bytes_value;
+      void* volatile* buffer_ptr;
+      void* buffer_value;
+      MojoMapBufferFlags flags_value;
+      MojoResult volatile* result_ptr;
+      MojoResult result_value;
+      {
+        ScopedCopyLock copy_lock(nap);
+        if (!ConvertScalarInput(nap, params[1], &buffer_handle_value)) {
+          return -1;
+        }
+        if (!ConvertScalarInput(nap, params[2], &offset_value)) {
+          return -1;
+        }
+        if (!ConvertScalarInput(nap, params[3], &num_bytes_value)) {
+          return -1;
+        }
+        if (!ConvertScalarInOut(nap, params[4], false, &buffer_value,
+                                &buffer_ptr)) {
+          return -1;
+        }
+        if (!ConvertScalarInput(nap, params[5], &flags_value)) {
+          return -1;
+        }
+        if (!ConvertScalarOutput(nap, params[6], false, &result_ptr)) {
+          return -1;
+        }
+      }
+
+      result_value = MojoMapBuffer(buffer_handle_value, offset_value,
+                                   num_bytes_value, &buffer_value, flags_value);
+
+      {
+        ScopedCopyLock copy_lock(nap);
+        *buffer_ptr = buffer_value;
+        *result_ptr = result_value;
+      }
+
+      return 0;
+    }
+    case 3: {
+      if (num_params != 3) {
+        return -1;
+      }
+      void* buffer_value;
+      MojoResult volatile* result_ptr;
+      MojoResult result_value;
+      {
+        ScopedCopyLock copy_lock(nap);
+        if (!ConvertScalarInput(nap, params[1], &buffer_value)) {
+          return -1;
+        }
+        if (!ConvertScalarOutput(nap, params[2], false, &result_ptr)) {
+          return -1;
+        }
+      }
+
+      result_value = MojoUnmapBuffer(buffer_value);
+
+      {
+        ScopedCopyLock copy_lock(nap);
+        *result_ptr = result_value;
+      }
+
+      return 0;
+    }
+    case 4: {
+      if (num_params != 5) {
+        return -1;
+      }
+      const struct MojoCreateDataPipeOptions* options;
+      MojoHandle volatile* data_pipe_producer_handle_ptr;
+      MojoHandle data_pipe_producer_handle_value;
+      MojoHandle volatile* data_pipe_consumer_handle_ptr;
+      MojoHandle data_pipe_consumer_handle_value;
+      MojoResult volatile* result_ptr;
+      MojoResult result_value;
+      {
+        ScopedCopyLock copy_lock(nap);
+        if (!ConvertExtensibleStructInput(nap, params[1], true, &options)) {
+          return -1;
+        }
+        if (!ConvertScalarInOut(nap, params[2], false,
+                                &data_pipe_producer_handle_value,
+                                &data_pipe_producer_handle_ptr)) {
+          return -1;
+        }
+        if (!ConvertScalarInOut(nap, params[3], false,
+                                &data_pipe_consumer_handle_value,
+                                &data_pipe_consumer_handle_ptr)) {
+          return -1;
+        }
+        if (!ConvertScalarOutput(nap, params[4], false, &result_ptr)) {
+          return -1;
+        }
+      }
+
+      result_value =
+          MojoCreateDataPipe(options, &data_pipe_producer_handle_value,
+                             &data_pipe_consumer_handle_value);
+
+      {
+        ScopedCopyLock copy_lock(nap);
+        *data_pipe_producer_handle_ptr = data_pipe_producer_handle_value;
+        *data_pipe_consumer_handle_ptr = data_pipe_consumer_handle_value;
+        *result_ptr = result_value;
+      }
+
+      return 0;
+    }
+    case 5: {
+      if (num_params != 6) {
+        return -1;
+      }
+      MojoHandle data_pipe_producer_handle_value;
+      const void* elements;
+      uint32_t volatile* num_bytes_ptr;
+      uint32_t num_bytes_value;
+      MojoWriteDataFlags flags_value;
+      MojoResult volatile* result_ptr;
+      MojoResult result_value;
+      {
+        ScopedCopyLock copy_lock(nap);
+        if (!ConvertScalarInput(nap, params[1],
+                                &data_pipe_producer_handle_value)) {
+          return -1;
+        }
+        if (!ConvertScalarInOut(nap, params[3], false, &num_bytes_value,
+                                &num_bytes_ptr)) {
+          return -1;
+        }
+        if (!ConvertScalarInput(nap, params[4], &flags_value)) {
+          return -1;
+        }
+        if (!ConvertScalarOutput(nap, params[5], false, &result_ptr)) {
+          return -1;
+        }
+        if (!ConvertArray(nap, params[2], num_bytes_value, 1, false,
+                          &elements)) {
+          return -1;
+        }
+      }
+
+      result_value = MojoWriteData(data_pipe_producer_handle_value, elements,
+                                   &num_bytes_value, flags_value);
+
+      {
+        ScopedCopyLock copy_lock(nap);
+        *num_bytes_ptr = num_bytes_value;
+        *result_ptr = result_value;
+      }
+
+      return 0;
+    }
+    case 6: {
+      if (num_params != 6) {
+        return -1;
+      }
+      MojoHandle data_pipe_producer_handle_value;
+      void* volatile* buffer_ptr;
+      void* buffer_value;
+      uint32_t volatile* buffer_num_bytes_ptr;
+      uint32_t buffer_num_bytes_value;
+      MojoWriteDataFlags flags_value;
+      MojoResult volatile* result_ptr;
+      MojoResult result_value;
+      {
+        ScopedCopyLock copy_lock(nap);
+        if (!ConvertScalarInput(nap, params[1],
+                                &data_pipe_producer_handle_value)) {
+          return -1;
+        }
+        if (!ConvertScalarInOut(nap, params[2], false, &buffer_value,
+                                &buffer_ptr)) {
+          return -1;
+        }
+        if (!ConvertScalarInOut(nap, params[3], false, &buffer_num_bytes_value,
+                                &buffer_num_bytes_ptr)) {
+          return -1;
+        }
+        if (!ConvertScalarInput(nap, params[4], &flags_value)) {
+          return -1;
+        }
+        if (!ConvertScalarOutput(nap, params[5], false, &result_ptr)) {
+          return -1;
+        }
+      }
+
+      result_value =
+          MojoBeginWriteData(data_pipe_producer_handle_value, &buffer_value,
+                             &buffer_num_bytes_value, flags_value);
+
+      {
+        ScopedCopyLock copy_lock(nap);
+        *buffer_ptr = buffer_value;
+        *buffer_num_bytes_ptr = buffer_num_bytes_value;
+        *result_ptr = result_value;
+      }
+
+      return 0;
+    }
+    case 7: {
+      if (num_params != 4) {
+        return -1;
+      }
+      MojoHandle data_pipe_producer_handle_value;
+      uint32_t num_bytes_written_value;
+      MojoResult volatile* result_ptr;
+      MojoResult result_value;
+      {
+        ScopedCopyLock copy_lock(nap);
+        if (!ConvertScalarInput(nap, params[1],
+                                &data_pipe_producer_handle_value)) {
+          return -1;
+        }
+        if (!ConvertScalarInput(nap, params[2], &num_bytes_written_value)) {
+          return -1;
+        }
+        if (!ConvertScalarOutput(nap, params[3], false, &result_ptr)) {
+          return -1;
+        }
+      }
+
+      result_value = MojoEndWriteData(data_pipe_producer_handle_value,
+                                      num_bytes_written_value);
+
+      {
+        ScopedCopyLock copy_lock(nap);
+        *result_ptr = result_value;
+      }
+
+      return 0;
+    }
+    case 8: {
+      if (num_params != 6) {
+        return -1;
+      }
+      MojoHandle data_pipe_consumer_handle_value;
+      void* elements;
+      uint32_t volatile* num_bytes_ptr;
+      uint32_t num_bytes_value;
+      MojoReadDataFlags flags_value;
+      MojoResult volatile* result_ptr;
+      MojoResult result_value;
+      {
+        ScopedCopyLock copy_lock(nap);
+        if (!ConvertScalarInput(nap, params[1],
+                                &data_pipe_consumer_handle_value)) {
+          return -1;
+        }
+        if (!ConvertScalarInOut(nap, params[3], false, &num_bytes_value,
+                                &num_bytes_ptr)) {
+          return -1;
+        }
+        if (!ConvertScalarInput(nap, params[4], &flags_value)) {
+          return -1;
+        }
+        if (!ConvertScalarOutput(nap, params[5], false, &result_ptr)) {
+          return -1;
+        }
+        if (!ConvertArray(nap, params[2], num_bytes_value, 1, false,
+                          &elements)) {
+          return -1;
+        }
+      }
+
+      result_value = MojoReadData(data_pipe_consumer_handle_value, elements,
+                                  &num_bytes_value, flags_value);
+
+      {
+        ScopedCopyLock copy_lock(nap);
+        *num_bytes_ptr = num_bytes_value;
+        *result_ptr = result_value;
+      }
+
+      return 0;
+    }
+    case 9: {
+      if (num_params != 6) {
+        return -1;
+      }
+      MojoHandle data_pipe_consumer_handle_value;
+      const void* volatile* buffer_ptr;
+      const void* buffer_value;
+      uint32_t volatile* buffer_num_bytes_ptr;
+      uint32_t buffer_num_bytes_value;
+      MojoReadDataFlags flags_value;
+      MojoResult volatile* result_ptr;
+      MojoResult result_value;
+      {
+        ScopedCopyLock copy_lock(nap);
+        if (!ConvertScalarInput(nap, params[1],
+                                &data_pipe_consumer_handle_value)) {
+          return -1;
+        }
+        if (!ConvertScalarInOut(nap, params[2], false, &buffer_value,
+                                &buffer_ptr)) {
+          return -1;
+        }
+        if (!ConvertScalarInOut(nap, params[3], false, &buffer_num_bytes_value,
+                                &buffer_num_bytes_ptr)) {
+          return -1;
+        }
+        if (!ConvertScalarInput(nap, params[4], &flags_value)) {
+          return -1;
+        }
+        if (!ConvertScalarOutput(nap, params[5], false, &result_ptr)) {
+          return -1;
+        }
+      }
+
+      result_value =
+          MojoBeginReadData(data_pipe_consumer_handle_value, &buffer_value,
+                            &buffer_num_bytes_value, flags_value);
+
+      {
+        ScopedCopyLock copy_lock(nap);
+        *buffer_ptr = buffer_value;
+        *buffer_num_bytes_ptr = buffer_num_bytes_value;
+        *result_ptr = result_value;
+      }
+
+      return 0;
+    }
+    case 10: {
+      if (num_params != 4) {
+        return -1;
+      }
+      MojoHandle data_pipe_consumer_handle_value;
+      uint32_t num_bytes_read_value;
+      MojoResult volatile* result_ptr;
+      MojoResult result_value;
+      {
+        ScopedCopyLock copy_lock(nap);
+        if (!ConvertScalarInput(nap, params[1],
+                                &data_pipe_consumer_handle_value)) {
+          return -1;
+        }
+        if (!ConvertScalarInput(nap, params[2], &num_bytes_read_value)) {
+          return -1;
+        }
+        if (!ConvertScalarOutput(nap, params[3], false, &result_ptr)) {
+          return -1;
+        }
+      }
+
+      result_value = MojoEndReadData(data_pipe_consumer_handle_value,
+                                     num_bytes_read_value);
+
+      {
+        ScopedCopyLock copy_lock(nap);
+        *result_ptr = result_value;
+      }
+
+      return 0;
+    }
+    case 11: {
+      if (num_params != 2) {
+        return -1;
+      }
+      MojoTimeTicks volatile* result_ptr;
+      MojoTimeTicks result_value;
+      {
+        ScopedCopyLock copy_lock(nap);
+        if (!ConvertScalarOutput(nap, params[1], false, &result_ptr)) {
+          return -1;
+        }
+      }
+
+      result_value = MojoGetTimeTicksNow();
+
+      {
+        ScopedCopyLock copy_lock(nap);
+        *result_ptr = result_value;
+      }
+
+      return 0;
+    }
+    case 12: {
+      if (num_params != 3) {
+        return -1;
+      }
+      MojoHandle handle_value;
+      MojoResult volatile* result_ptr;
+      MojoResult result_value;
+      {
+        ScopedCopyLock copy_lock(nap);
+        if (!ConvertScalarInput(nap, params[1], &handle_value)) {
+          return -1;
+        }
+        if (!ConvertScalarOutput(nap, params[2], false, &result_ptr)) {
+          return -1;
+        }
+      }
+
+      result_value = MojoClose(handle_value);
+
+      {
+        ScopedCopyLock copy_lock(nap);
+        *result_ptr = result_value;
+      }
+
+      return 0;
+    }
+    case 13: {
+      if (num_params != 6) {
+        return -1;
+      }
+      MojoHandle handle_value;
+      MojoHandleSignals signals_value;
+      MojoDeadline deadline_value;
+      MojoHandleSignalsState volatile* signals_state_ptr;
+      MojoHandleSignalsState signals_state_value;
+      MojoResult volatile* result_ptr;
+      MojoResult result_value;
+      {
+        ScopedCopyLock copy_lock(nap);
+        if (!ConvertScalarInput(nap, params[1], &handle_value)) {
+          return -1;
+        }
+        if (!ConvertScalarInput(nap, params[2], &signals_value)) {
+          return -1;
+        }
+        if (!ConvertScalarInput(nap, params[3], &deadline_value)) {
+          return -1;
+        }
+        if (!ConvertScalarOutput(nap, params[4], true, &signals_state_ptr)) {
+          return -1;
+        }
+        if (!ConvertScalarOutput(nap, params[5], false, &result_ptr)) {
+          return -1;
+        }
+      }
+
+      result_value = MojoWait(handle_value, signals_value, deadline_value,
+                              signals_state_ptr ? &signals_state_value : NULL);
+
+      {
+        ScopedCopyLock copy_lock(nap);
+        if (signals_state_ptr != NULL) {
+          memcpy_volatile_out(signals_state_ptr, &signals_state_value,
+                              sizeof(MojoHandleSignalsState));
+        }
+        *result_ptr = result_value;
+      }
+
+      return 0;
+    }
+    case 14: {
+      if (num_params != 8) {
+        return -1;
+      }
+      const MojoHandle* handles;
+      const MojoHandleSignals* signals;
+      uint32_t num_handles_value;
+      MojoDeadline deadline_value;
+      uint32_t volatile* result_index_ptr;
+      uint32_t result_index_value;
+      struct MojoHandleSignalsState* signals_states;
+      MojoResult volatile* result_ptr;
+      MojoResult result_value;
+      {
+        ScopedCopyLock copy_lock(nap);
+        if (!ConvertScalarInput(nap, params[3], &num_handles_value)) {
+          return -1;
+        }
+        if (!ConvertScalarInput(nap, params[4], &deadline_value)) {
+          return -1;
+        }
+        if (!ConvertScalarInOut(nap, params[5], true, &result_index_value,
+                                &result_index_ptr)) {
+          return -1;
+        }
+        if (!ConvertScalarOutput(nap, params[7], false, &result_ptr)) {
+          return -1;
+        }
+        if (!ConvertArray(nap, params[1], num_handles_value, sizeof(*handles),
+                          false, &handles)) {
+          return -1;
+        }
+        if (!ConvertArray(nap, params[2], num_handles_value, sizeof(*signals),
+                          false, &signals)) {
+          return -1;
+        }
+        if (!ConvertArray(nap, params[6], num_handles_value,
+                          sizeof(*signals_states), true, &signals_states)) {
+          return -1;
+        }
+      }
+
+      result_value = MojoWaitMany(
+          handles, signals, num_handles_value, deadline_value,
+          result_index_ptr ? &result_index_value : NULL, signals_states);
+
+      {
+        ScopedCopyLock copy_lock(nap);
+        if (result_index_ptr != NULL) {
+          *result_index_ptr = result_index_value;
+        }
+        *result_ptr = result_value;
+      }
+
+      return 0;
+    }
+    case 15: {
+      if (num_params != 5) {
+        return -1;
+      }
+      const struct MojoCreateMessagePipeOptions* options;
+      MojoHandle volatile* message_pipe_handle0_ptr;
+      MojoHandle message_pipe_handle0_value;
+      MojoHandle volatile* message_pipe_handle1_ptr;
+      MojoHandle message_pipe_handle1_value;
+      MojoResult volatile* result_ptr;
+      MojoResult result_value;
+      {
+        ScopedCopyLock copy_lock(nap);
+        if (!ConvertExtensibleStructInput(nap, params[1], true, &options)) {
+          return -1;
+        }
+        if (!ConvertScalarInOut(nap, params[2], false,
+                                &message_pipe_handle0_value,
+                                &message_pipe_handle0_ptr)) {
+          return -1;
+        }
+        if (!ConvertScalarInOut(nap, params[3], false,
+                                &message_pipe_handle1_value,
+                                &message_pipe_handle1_ptr)) {
+          return -1;
+        }
+        if (!ConvertScalarOutput(nap, params[4], false, &result_ptr)) {
+          return -1;
+        }
+      }
+
+      result_value = MojoCreateMessagePipe(options, &message_pipe_handle0_value,
+                                           &message_pipe_handle1_value);
+
+      {
+        ScopedCopyLock copy_lock(nap);
+        *message_pipe_handle0_ptr = message_pipe_handle0_value;
+        *message_pipe_handle1_ptr = message_pipe_handle1_value;
+        *result_ptr = result_value;
+      }
+
+      return 0;
+    }
+    case 16: {
+      if (num_params != 8) {
+        return -1;
+      }
+      MojoHandle message_pipe_handle_value;
+      const void* bytes;
+      uint32_t num_bytes_value;
+      const MojoHandle* handles;
+      uint32_t num_handles_value;
+      MojoWriteMessageFlags flags_value;
+      MojoResult volatile* result_ptr;
+      MojoResult result_value;
+      {
+        ScopedCopyLock copy_lock(nap);
+        if (!ConvertScalarInput(nap, params[1], &message_pipe_handle_value)) {
+          return -1;
+        }
+        if (!ConvertScalarInput(nap, params[3], &num_bytes_value)) {
+          return -1;
+        }
+        if (!ConvertScalarInput(nap, params[5], &num_handles_value)) {
+          return -1;
+        }
+        if (!ConvertScalarInput(nap, params[6], &flags_value)) {
+          return -1;
+        }
+        if (!ConvertScalarOutput(nap, params[7], false, &result_ptr)) {
+          return -1;
+        }
+        if (!ConvertArray(nap, params[2], num_bytes_value, 1, true, &bytes)) {
+          return -1;
+        }
+        if (!ConvertArray(nap, params[4], num_handles_value, sizeof(*handles),
+                          true, &handles)) {
+          return -1;
+        }
+      }
+
+      result_value =
+          MojoWriteMessage(message_pipe_handle_value, bytes, num_bytes_value,
+                           handles, num_handles_value, flags_value);
+
+      {
+        ScopedCopyLock copy_lock(nap);
+        *result_ptr = result_value;
+      }
+
+      return 0;
+    }
+    case 17: {
+      if (num_params != 8) {
+        return -1;
+      }
+      MojoHandle message_pipe_handle_value;
+      void* bytes;
+      uint32_t volatile* num_bytes_ptr;
+      uint32_t num_bytes_value;
+      MojoHandle* handles;
+      uint32_t volatile* num_handles_ptr;
+      uint32_t num_handles_value;
+      MojoReadMessageFlags flags_value;
+      MojoResult volatile* result_ptr;
+      MojoResult result_value;
+      {
+        ScopedCopyLock copy_lock(nap);
+        if (!ConvertScalarInput(nap, params[1], &message_pipe_handle_value)) {
+          return -1;
+        }
+        if (!ConvertScalarInOut(nap, params[3], true, &num_bytes_value,
+                                &num_bytes_ptr)) {
+          return -1;
+        }
+        if (!ConvertScalarInOut(nap, params[5], true, &num_handles_value,
+                                &num_handles_ptr)) {
+          return -1;
+        }
+        if (!ConvertScalarInput(nap, params[6], &flags_value)) {
+          return -1;
+        }
+        if (!ConvertScalarOutput(nap, params[7], false, &result_ptr)) {
+          return -1;
+        }
+        if (!ConvertArray(nap, params[2], num_bytes_value, 1, true, &bytes)) {
+          return -1;
+        }
+        if (!ConvertArray(nap, params[4], num_handles_value, sizeof(*handles),
+                          true, &handles)) {
+          return -1;
+        }
+      }
+
+      result_value = MojoReadMessage(
+          message_pipe_handle_value, bytes,
+          num_bytes_ptr ? &num_bytes_value : NULL, handles,
+          num_handles_ptr ? &num_handles_value : NULL, flags_value);
+
+      {
+        ScopedCopyLock copy_lock(nap);
+        if (num_bytes_ptr != NULL) {
+          *num_bytes_ptr = num_bytes_value;
+        }
+        if (num_handles_ptr != NULL) {
+          *num_handles_ptr = num_handles_value;
+        }
+        *result_ptr = result_value;
+      }
+
+      return 0;
+    }
+    case 18: {
+      if (num_params != 3) {
+        return -1;
+      }
+      MojoHandle volatile* handle_ptr;
+      MojoHandle handle_value;
+      MojoResult volatile* result_ptr;
+      MojoResult result_value;
+      {
+        ScopedCopyLock copy_lock(nap);
+        if (!ConvertScalarInOut(nap, params[1], false, &handle_value,
+                                &handle_ptr)) {
+          return -1;
+        }
+        if (!ConvertScalarOutput(nap, params[2], false, &result_ptr)) {
+          return -1;
+        }
+      }
+
+      result_value = _MojoGetInitialHandle(&handle_value);
+
+      {
+        ScopedCopyLock copy_lock(nap);
+        *handle_ptr = handle_value;
+        *result_ptr = result_value;
+      }
+
+      return 0;
+    }
+  }
+
+  return -1;
+}
+
+ssize_t MojoDescRecvMsg(void* handle,
+                        struct NaClImcTypedMsgHdr* msg,
+                        int flags) {
+  return -1;
+}
+
+struct NaClDesc* MakeMojoDesc(struct NaClApp* nap) {
+  struct NaClDescCustomFuncs funcs = NACL_DESC_CUSTOM_FUNCS_INITIALIZER;
+  funcs.Destroy = MojoDescDestroy;
+  funcs.SendMsg = MojoDescSendMsg;
+  funcs.RecvMsg = MojoDescRecvMsg;
+  return NaClDescMakeCustomDesc(nap, &funcs);
+}
+
+void MojoDisabledDescDestroy(void* handle) {
+}
+
+ssize_t MojoDisabledDescSendMsg(void* handle,
+                                const struct NaClImcTypedMsgHdr* msg,
+                                int flags) {
+  fprintf(stderr, "Mojo is not currently supported.");
+  abort();
+}
+
+ssize_t MojoDisabledDescRecvMsg(void* handle,
+                                struct NaClImcTypedMsgHdr* msg,
+                                int flags) {
+  fprintf(stderr, "Mojo is not currently supported.");
+  abort();
+}
+
+struct NaClDesc* MakeDisabledMojoDesc(struct NaClApp* nap) {
+  struct NaClDescCustomFuncs funcs = NACL_DESC_CUSTOM_FUNCS_INITIALIZER;
+  funcs.Destroy = MojoDisabledDescDestroy;
+  funcs.SendMsg = MojoDisabledDescSendMsg;
+  funcs.RecvMsg = MojoDisabledDescRecvMsg;
+  return NaClDescMakeCustomDesc(nap, &funcs);
+}
+
+}  // namespace
+
+// The value for this FD must not conflict with uses inside Chromium. However,
+// mojo/nacl doesn't depend on any Chromium headers, so we can't use a #define
+// from there.
+#define NACL_MOJO_DESC (NACL_CHROME_DESC_BASE + 3)
+
+void InjectMojo(struct NaClApp* nap) {
+  NaClAppSetDesc(nap, NACL_MOJO_DESC, MakeMojoDesc(nap));
+  g_mojo_handle = MOJO_HANDLE_INVALID;
+}
+
+void InjectMojo(struct NaClApp* nap, MojoHandle handle) {
+  NaClAppSetDesc(nap, NACL_MOJO_DESC, MakeMojoDesc(nap));
+  g_mojo_handle = handle;
+}
+
+void InjectDisabledMojo(struct NaClApp* nap) {
+  NaClAppSetDesc(nap, NACL_MOJO_DESC, MakeDisabledMojoDesc(nap));
+}
diff --git a/mojo/nacl/mojo_syscall.h b/nacl_bindings/mojo_syscall.h
similarity index 96%
rename from mojo/nacl/mojo_syscall.h
rename to nacl_bindings/mojo_syscall.h
index 2902337..700d191 100644
--- a/mojo/nacl/mojo_syscall.h
+++ b/nacl_bindings/mojo_syscall.h
@@ -23,4 +23,4 @@
 // more straightforward in the case where Mojo is not enabled for NaCl plugins.
 void InjectDisabledMojo(struct NaClApp* nap);
 
-#endif // MOJO_NACL_MOJO_SYSCALL_H_
+#endif  // MOJO_NACL_MOJO_SYSCALL_H_
diff --git a/mojo/nacl/mojo_syscall_internal.h b/nacl_bindings/mojo_syscall_internal.h
similarity index 62%
rename from mojo/nacl/mojo_syscall_internal.h
rename to nacl_bindings/mojo_syscall_internal.h
index 8aa32d1..9200c1a 100644
--- a/mojo/nacl/mojo_syscall_internal.h
+++ b/nacl_bindings/mojo_syscall_internal.h
@@ -15,18 +15,16 @@
   explicit ScopedCopyLock(struct NaClApp* nap) : nap_(nap) {
     NaClCopyTakeLock(nap_);
   }
-  ~ScopedCopyLock() {
-    NaClCopyDropLock(nap_);
-  }
+  ~ScopedCopyLock() { NaClCopyDropLock(nap_); }
+
  private:
   struct NaClApp* nap_;
 };
 
-static inline uintptr_t NaClUserToSysAddrArray(
-    struct NaClApp* nap,
-    uint32_t uaddr,
-    size_t count,
-    size_t size) {
+static inline uintptr_t NaClUserToSysAddrArray(struct NaClApp* nap,
+                                               uint32_t uaddr,
+                                               size_t count,
+                                               size_t size) {
   // TODO(ncbray): overflow checking
   size_t range = count * size;
   return NaClUserToSysAddrRange(nap, uaddr, range);
@@ -42,10 +40,9 @@
 // time of check vs. time of use problems, or worse.  For this binding code in
 // particular, where memcpy is being called with a constant size, it is entirely
 // conceivable the function will be inlined, unrolled, and optimized.
-static inline void memcpy_volatile_out(
-    void volatile* dst,
-    const void* src,
-    size_t n) {
+static inline void memcpy_volatile_out(void volatile* dst,
+                                       const void* src,
+                                       size_t n) {
   char volatile* c_dst = static_cast<char volatile*>(dst);
   const char* c_src = static_cast<const char*>(src);
   for (size_t i = 0; i < n; i++) {
@@ -53,10 +50,8 @@
   }
 }
 
-template <typename T> bool ConvertScalarInput(
-    struct NaClApp* nap,
-    uint32_t user_ptr,
-    T* value) {
+template <typename T>
+bool ConvertScalarInput(struct NaClApp* nap, uint32_t user_ptr, T* value) {
   if (user_ptr) {
     uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T));
     if (temp != kNaClBadAddress) {
@@ -67,11 +62,11 @@
   return false;
 }
 
-template <typename T> bool ConvertScalarOutput(
-    struct NaClApp* nap,
-    uint32_t user_ptr,
-    bool optional,
-    T volatile** sys_ptr) {
+template <typename T>
+bool ConvertScalarOutput(struct NaClApp* nap,
+                         uint32_t user_ptr,
+                         bool optional,
+                         T volatile** sys_ptr) {
   if (user_ptr) {
     uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T));
     if (temp != kNaClBadAddress) {
@@ -82,16 +77,16 @@
     *sys_ptr = 0;
     return true;
   }
-  *sys_ptr = 0; // Paranoia.
+  *sys_ptr = 0;  // Paranoia.
   return false;
 }
 
-template <typename T> bool ConvertScalarInOut(
-    struct NaClApp* nap,
-    uint32_t user_ptr,
-    bool optional,
-    T* value,
-    T volatile** sys_ptr) {
+template <typename T>
+bool ConvertScalarInOut(struct NaClApp* nap,
+                        uint32_t user_ptr,
+                        bool optional,
+                        T* value,
+                        T volatile** sys_ptr) {
   if (user_ptr) {
     uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T));
     if (temp != kNaClBadAddress) {
@@ -102,24 +97,24 @@
     }
   } else if (optional) {
     *sys_ptr = 0;
-    *value = static_cast<T>(0); // Paranoia.
+    *value = static_cast<T>(0);  // Paranoia.
     return true;
   }
-  *sys_ptr = 0; // Paranoia.
-  *value = static_cast<T>(0); // Paranoia.
+  *sys_ptr = 0;                // Paranoia.
+  *value = static_cast<T>(0);  // Paranoia.
   return false;
 }
 
-template <typename T> bool ConvertArray(
-    struct NaClApp* nap,
-    uint32_t user_ptr,
-    uint32_t length,
-    size_t element_size,
-    bool optional,
-    T** sys_ptr) {
+template <typename T>
+bool ConvertArray(struct NaClApp* nap,
+                  uint32_t user_ptr,
+                  uint32_t length,
+                  size_t element_size,
+                  bool optional,
+                  T** sys_ptr) {
   if (user_ptr) {
-    uintptr_t temp = NaClUserToSysAddrArray(nap, user_ptr, length,
-                                            element_size);
+    uintptr_t temp =
+        NaClUserToSysAddrArray(nap, user_ptr, length, element_size);
     if (temp != kNaClBadAddress) {
       *sys_ptr = reinterpret_cast<T*>(temp);
       return true;
@@ -131,12 +126,12 @@
   return false;
 }
 
-template <typename T> bool ConvertBytes(
-    struct NaClApp* nap,
-    uint32_t user_ptr,
-    uint32_t length,
-    bool optional,
-    T** sys_ptr) {
+template <typename T>
+bool ConvertBytes(struct NaClApp* nap,
+                  uint32_t user_ptr,
+                  uint32_t length,
+                  bool optional,
+                  T** sys_ptr) {
   if (user_ptr) {
     uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, length);
     if (temp != kNaClBadAddress) {
@@ -152,11 +147,11 @@
 
 // TODO(ncbray): size validation and complete copy.
 // TODO(ncbray): ensure non-null / missized structs are covered by a test case.
-template <typename T> bool ConvertExtensibleStructInput(
-    struct NaClApp* nap,
-    uint32_t user_ptr,
-    bool optional,
-    T** sys_ptr) {
+template <typename T>
+bool ConvertExtensibleStructInput(struct NaClApp* nap,
+                                  uint32_t user_ptr,
+                                  bool optional,
+                                  T** sys_ptr) {
   if (user_ptr) {
     uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T));
     if (temp != kNaClBadAddress) {
@@ -170,6 +165,6 @@
   return false;
 }
 
-} // namespace
+}  // namespace
 
-#endif // MOJO_NACL_MOJO_SYSCALL_INTERNAL_H_
+#endif  // MOJO_NACL_MOJO_SYSCALL_INTERNAL_H_
diff --git a/mojo/nacl/monacl_sel_main.cc b/nacl_bindings/monacl_sel_main.cc
similarity index 88%
rename from mojo/nacl/monacl_sel_main.cc
rename to nacl_bindings/monacl_sel_main.cc
index 631fa61..100f161 100644
--- a/mojo/nacl/monacl_sel_main.cc
+++ b/nacl_bindings/monacl_sel_main.cc
@@ -2,9 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "mojo/nacl/monacl_sel_main.h"
+#include "nacl_bindings/monacl_sel_main.h"
 
-#include "mojo/nacl/mojo_syscall.h"
+#include "nacl_bindings/mojo_syscall.h"
 #include "native_client/src/public/chrome_main.h"
 #include "native_client/src/public/nacl_app.h"
 
@@ -36,4 +36,4 @@
   ::NaClExit(code);
 }
 
-} // namespace mojo
+}  // namespace mojo
diff --git a/mojo/nacl/monacl_sel_main.h b/nacl_bindings/monacl_sel_main.h
similarity index 90%
rename from mojo/nacl/monacl_sel_main.h
rename to nacl_bindings/monacl_sel_main.h
index eac17c6..d376f64 100644
--- a/mojo/nacl/monacl_sel_main.h
+++ b/nacl_bindings/monacl_sel_main.h
@@ -20,6 +20,6 @@
 
 void NaClExit(int code);
 
-} // namespace mojo
+}  // namespace mojo
 
-#endif // MOJO_NACL_MONACL_SEL_MAIN_H_
+#endif  // MOJO_NACL_MONACL_SEL_MAIN_H_
diff --git a/mojo/nacl/generator/generate_nacl_bindings.py b/nacl_bindings_generator/generate_nacl_bindings.py
similarity index 88%
rename from mojo/nacl/generator/generate_nacl_bindings.py
rename to nacl_bindings_generator/generate_nacl_bindings.py
index ee6189c..e06ffa9 100755
--- a/mojo/nacl/generator/generate_nacl_bindings.py
+++ b/nacl_bindings_generator/generate_nacl_bindings.py
@@ -6,36 +6,28 @@
 # pylint: disable=W0104,W0106,F0401,R0201
 
 import errno
-import optparse
 import os.path
 import sys
 
 import interface
 
 
-def _ScriptDir():
+def ScriptDir():
   return os.path.dirname(os.path.abspath(__file__))
 
 
-def _GetDirAbove(dirname):
-  """Returns the directory "above" this file containing |dirname| (which must
-  also be "above" this file)."""
-  path = _ScriptDir()
-  while True:
-    path, tail = os.path.split(path)
-    assert tail
-    if tail == dirname:
-      return path
+def RepoRoot():
+  return os.path.dirname(ScriptDir())
 
 
 def _AddThirdPartyImportPath():
-  sys.path.append(os.path.join(_GetDirAbove('mojo'), 'third_party'))
+  sys.path.append(os.path.join(RepoRoot(), 'third_party'))
 
 
 _AddThirdPartyImportPath()
 import jinja2
 
-loader = jinja2.FileSystemLoader(_ScriptDir())
+loader = jinja2.FileSystemLoader(ScriptDir())
 jinja_env = jinja2.Environment(loader=loader, keep_trailing_newline=True)
 
 
@@ -103,7 +95,7 @@
 
 # Untrusted library which thunks from the public Mojo API to the IRT interface
 # implementing the public Mojo API.
-def GenerateLibMojo(functions, out):
+def GenerateLibMojo(functions, common_vars, out):
   template = jinja_env.get_template('libmojo.cc.tmpl')
 
   code = CodeWriter()
@@ -125,8 +117,8 @@
 
   body = code.GetValue()
   text = template.render(
-    generator_warning=GeneratorWarning(),
-    body=body)
+    body=body,
+    **common_vars)
   out.write(text)
 
 
@@ -308,7 +300,7 @@
 
 # A trusted wrapper that validates the arguments passed from untrusted code
 # before passing them to the underlying public Mojo API.
-def GenerateMojoSyscall(functions, out):
+def GenerateMojoSyscall(functions, common_vars, out):
   template = jinja_env.get_template('mojo_syscall.cc.tmpl')
 
   code = CodeWriter()
@@ -377,13 +369,13 @@
 
   body = code.GetValue()
   text = template.render(
-    generator_warning=GeneratorWarning(),
-    body=body)
+    body=body,
+    **common_vars)
   out.write(text)
 
 
 # A header declaring the IRT interface for accessing Mojo functions.
-def GenerateMojoIrtHeader(functions, out):
+def GenerateMojoIrtHeader(functions, common_vars, out):
   template = jinja_env.get_template('mojo_irt.h.tmpl')
   code = CodeWriter()
 
@@ -400,12 +392,12 @@
   body = code.GetValue()
 
   text = template.render(
-    generator_warning=GeneratorWarning(),
-    body=body)
+    body=body,
+    **common_vars)
   out.write(text)
 
 # IRT interface which implements the Mojo public API.
-def GenerateMojoIrtImplementation(functions, out):
+def GenerateMojoIrtImplementation(functions, common_vars, out):
   template = jinja_env.get_template('mojo_irt.c.tmpl')
   code = CodeWriter()
 
@@ -459,8 +451,8 @@
   body = code.GetValue()
 
   text = template.render(
-    generator_warning=GeneratorWarning(),
-    body=body)
+    body=body,
+    **common_vars)
   out.write(text)
 
 
@@ -472,36 +464,40 @@
       # There may have been a race to create this directory.
       if e.errno != errno.EEXIST:
         raise
-  return open(os.path.join(dir_path, name), 'w')
+  full_path = os.path.join(dir_path, name)
+  print full_path
+  return open(full_path, 'w')
 
 
-def main(args):
-  usage = 'usage: %prog [options]'
-  parser = optparse.OptionParser(usage=usage)
-  parser.add_option(
-      '-d',
-      dest='out_dir',
-      metavar='DIR',
-      help='output generated code into directory DIR')
-  options, args = parser.parse_args(args=args)
-  if not options.out_dir:
-    parser.error('-d is required')
-  if args:
-    parser.error('unexpected positional arguments: %s' % ' '.join(args))
+def main():
+  root_dir = RepoRoot()
+
+  platform_dir = 'mojo/public/platform/nacl'
+  bindings_dir = 'nacl_bindings'
+
+  full_platform_dir = os.path.join(root_dir, platform_dir)
+  full_bindings_dir = os.path.join(root_dir, bindings_dir)
+
+  common_vars = dict(
+    generator_warning=GeneratorWarning(),
+    platform_dir=platform_dir,
+    platform_dir_header_path=platform_dir.replace("/", "_").upper(),
+    bindings_dir=bindings_dir,
+  )
 
   mojo = interface.MakeInterface()
 
-  out = OutFile(options.out_dir, 'libmojo.cc')
-  GenerateLibMojo(mojo.functions, out)
+  out = OutFile(full_platform_dir, 'libmojo.cc')
+  GenerateLibMojo(mojo.functions, common_vars, out)
 
-  out = OutFile(options.out_dir, 'mojo_syscall.cc')
-  GenerateMojoSyscall(mojo.functions, out)
+  out = OutFile(full_bindings_dir, 'mojo_syscall.cc')
+  GenerateMojoSyscall(mojo.functions, common_vars, out)
 
-  out = OutFile(options.out_dir, 'mojo_irt.h')
-  GenerateMojoIrtHeader(mojo.functions, out)
+  out = OutFile(full_platform_dir, 'mojo_irt.h')
+  GenerateMojoIrtHeader(mojo.functions, common_vars, out)
 
-  out = OutFile(options.out_dir, 'mojo_irt.c')
-  GenerateMojoIrtImplementation(mojo.functions, out)
+  out = OutFile(full_bindings_dir, 'mojo_irt.c')
+  GenerateMojoIrtImplementation(mojo.functions, common_vars, out)
 
 if __name__ == '__main__':
-  main(sys.argv[1:])
+  main()
diff --git a/mojo/nacl/generator/interface.py b/nacl_bindings_generator/interface.py
similarity index 100%
rename from mojo/nacl/generator/interface.py
rename to nacl_bindings_generator/interface.py
diff --git a/mojo/nacl/generator/interface_dsl.py b/nacl_bindings_generator/interface_dsl.py
similarity index 100%
rename from mojo/nacl/generator/interface_dsl.py
rename to nacl_bindings_generator/interface_dsl.py
diff --git a/mojo/nacl/generator/libmojo.cc.tmpl b/nacl_bindings_generator/libmojo.cc.tmpl
similarity index 96%
rename from mojo/nacl/generator/libmojo.cc.tmpl
rename to nacl_bindings_generator/libmojo.cc.tmpl
index a012798..a486c7e 100644
--- a/mojo/nacl/generator/libmojo.cc.tmpl
+++ b/nacl_bindings_generator/libmojo.cc.tmpl
@@ -4,8 +4,8 @@
 
 {{generator_warning}}
 
-#include "mojo/nacl/mojo_irt.h"
 #include "mojo/public/c/system/core.h"
+#include "{{platform_dir}}/mojo_irt.h"
 #include "native_client/src/public/chrome_main.h"
 #include "native_client/src/public/imc_syscalls.h"
 #include "native_client/src/public/imc_types.h"
diff --git a/mojo/nacl/generator/mojo_irt.c.tmpl b/nacl_bindings_generator/mojo_irt.c.tmpl
similarity index 96%
rename from mojo/nacl/generator/mojo_irt.c.tmpl
rename to nacl_bindings_generator/mojo_irt.c.tmpl
index e205496..7885751 100644
--- a/mojo/nacl/generator/mojo_irt.c.tmpl
+++ b/nacl_bindings_generator/mojo_irt.c.tmpl
@@ -7,8 +7,8 @@
 #include <stdio.h>
 #include <string.h>
 
-#include "mojo/nacl/mojo_irt.h"
 #include "mojo/public/c/system/core.h"
+#include "{{platform_dir}}/mojo_irt.h"
 #include "native_client/src/public/chrome_main.h"
 #include "native_client/src/public/imc_syscalls.h"
 #include "native_client/src/public/imc_types.h"
diff --git a/mojo/nacl/generator/mojo_irt.h.tmpl b/nacl_bindings_generator/mojo_irt.h.tmpl
similarity index 80%
rename from mojo/nacl/generator/mojo_irt.h.tmpl
rename to nacl_bindings_generator/mojo_irt.h.tmpl
index 09dbe69..b742ebe 100644
--- a/mojo/nacl/generator/mojo_irt.h.tmpl
+++ b/nacl_bindings_generator/mojo_irt.h.tmpl
@@ -4,10 +4,9 @@
 
 {{generator_warning}}
 
-#ifndef MOJO_NACL_MOJO_IRT_H_
-#define MOJO_NACL_MOJO_IRT_H_
+#ifndef {{platform_dir_header_path}}_MOJO_IRT_H_
+#define {{platform_dir_header_path}}_MOJO_IRT_H_
 
-#include "mojo/common/mojo_common_export.h"
 #include "mojo/public/c/system/buffer.h"
 #include "mojo/public/c/system/data_pipe.h"
 #include "mojo/public/c/system/message_pipe.h"
@@ -29,4 +28,4 @@
 }
 #endif
 
-#endif  // MOJO_NACL_MOJO_IRT_H_
+#endif  // {{platform_dir_header_path}}_MOJO_IRT_H_
diff --git a/mojo/nacl/generator/mojo_syscall.cc.tmpl b/nacl_bindings_generator/mojo_syscall.cc.tmpl
similarity index 96%
rename from mojo/nacl/generator/mojo_syscall.cc.tmpl
rename to nacl_bindings_generator/mojo_syscall.cc.tmpl
index 84c1577..4ef183f 100644
--- a/mojo/nacl/generator/mojo_syscall.cc.tmpl
+++ b/nacl_bindings_generator/mojo_syscall.cc.tmpl
@@ -4,11 +4,11 @@
 
 {{generator_warning}}
 
-#include "mojo/nacl/mojo_syscall.h"
+#include "{{bindings_dir}}/mojo_syscall.h"
 
 #include <stdio.h>
 
-#include "mojo/nacl/mojo_syscall_internal.h"
+#include "{{bindings_dir}}/mojo_syscall_internal.h"
 #include "mojo/public/c/system/core.h"
 #include "native_client/src/public/chrome_main.h"
 #include "native_client/src/public/nacl_app.h"
diff --git a/services/nacl/BUILD.gn b/services/nacl/BUILD.gn
index c5aa369..a30fe86 100644
--- a/services/nacl/BUILD.gn
+++ b/services/nacl/BUILD.gn
@@ -16,11 +16,11 @@
       "//mojo/application:application",
       "//mojo/application:content_handler",
       "//mojo/common",
-      "//mojo/nacl:monacl_sel",
       "//mojo/services/network/public/interfaces",
+      "//nacl_bindings:monacl_sel",
       "//url",
     ]
 
-    data_deps = [ "//mojo/nacl:irt_mojo(//native_client/build/toolchain/nacl:irt_${cpu_arch})" ]
+    data_deps = [ "//nacl_bindings:irt_mojo(//native_client/build/toolchain/nacl:irt_${cpu_arch})" ]
   }
 }
diff --git a/services/nacl/content_handler_main.cc b/services/nacl/content_handler_main.cc
index 4947087..a418ddf 100644
--- a/services/nacl/content_handler_main.cc
+++ b/services/nacl/content_handler_main.cc
@@ -10,13 +10,13 @@
 #include "mojo/application/content_handler_factory.h"
 #include "mojo/common/data_pipe_utils.h"
 #include "mojo/common/message_pump_mojo.h"
-#include "mojo/nacl/monacl_sel_main.h"
 #include "mojo/public/c/system/main.h"
 #include "mojo/public/cpp/application/application_connection.h"
 #include "mojo/public/cpp/application/application_delegate.h"
 #include "mojo/public/cpp/application/application_impl.h"
 #include "mojo/services/network/public/interfaces/network_service.mojom.h"
 #include "mojo/services/network/public/interfaces/url_loader.mojom.h"
+#include "nacl_bindings/monacl_sel_main.h"
 #include "native_client/src/public/nacl_desc.h"
 #include "url/gurl.h"