summaryrefslogtreecommitdiffstats
path: root/ppapi
diff options
context:
space:
mode:
authormseaborn <mseaborn@chromium.org>2015-07-21 19:55:07 -0700
committerCommit bot <commit-bot@chromium.org>2015-07-22 02:55:42 +0000
commitd735c8b9e7d1c2267d65a357e9a3541358e846e2 (patch)
treecc8b43f4d517f21c84d88e149dd954ba5222841c /ppapi
parent2194f54bd4e254605a60350f2077266017364f9f (diff)
downloadchromium_src-d735c8b9e7d1c2267d65a357e9a3541358e846e2.zip
chromium_src-d735c8b9e7d1c2267d65a357e9a3541358e846e2.tar.gz
chromium_src-d735c8b9e7d1c2267d65a357e9a3541358e846e2.tar.bz2
NaCl: Copy PNaCl translator IRT interfaces to the Chromium side
Add a copy of the existing SRPC-based implementation -- native_client/src/untrusted/irt/irt_pnacl_translator_{compile,link}.c -- to the Chromium side. This will allow the two implementations to be independently changed to remove use of SRPC. In copying this code, I have made some changes to follow the Chromium style: * Switching to C++ and using C++ comments * Using anon namespaces instead of "static" * "*" spacing (using clang-format) * "FooBar" function naming instead of "foo_bar" * Using the Chromium copyright notice BUG=302078 TEST=e.g. NaClBrowserTestPnacl.PPAPICore in browser_tests (also manually tested with NaCl-side interface disabled, to ensure the Chromium-side one is really being used) Review URL: https://codereview.chromium.org/1240343004 Cr-Commit-Position: refs/heads/master@{#339825}
Diffstat (limited to 'ppapi')
-rw-r--r--ppapi/nacl_irt/DEPS3
-rw-r--r--ppapi/nacl_irt/irt_interfaces.cc16
-rw-r--r--ppapi/nacl_irt/irt_interfaces.h4
-rw-r--r--ppapi/nacl_irt/irt_pnacl_translator_compile.cc117
-rw-r--r--ppapi/nacl_irt/irt_pnacl_translator_link.cc61
-rw-r--r--ppapi/ppapi_proxy.gypi2
-rw-r--r--ppapi/proxy/BUILD.gn2
7 files changed, 205 insertions, 0 deletions
diff --git a/ppapi/nacl_irt/DEPS b/ppapi/nacl_irt/DEPS
index a173f60..e3f5767 100644
--- a/ppapi/nacl_irt/DEPS
+++ b/ppapi/nacl_irt/DEPS
@@ -11,6 +11,9 @@ include_rules = [
# The untrusted build references the NaCl integrated runtime (IRT).
"+native_client/src/public",
"+native_client/src/untrusted/irt/irt.h",
+ "+native_client/src/untrusted/irt/irt_dev.h",
+ "+native_client/src/shared/platform/nacl_log.h",
+ "+native_client/src/shared/srpc/nacl_srpc.h",
# The IRT also needs to know the errno and sysconf enums.
"+native_client/src/trusted/service_runtime/include/sys/errno.h",
"+native_client/src/trusted/service_runtime/include/sys/unistd.h",
diff --git a/ppapi/nacl_irt/irt_interfaces.cc b/ppapi/nacl_irt/irt_interfaces.cc
index 77ce9d8..60a63cf 100644
--- a/ppapi/nacl_irt/irt_interfaces.cc
+++ b/ppapi/nacl_irt/irt_interfaces.cc
@@ -10,6 +10,7 @@
#include "native_client/src/public/irt_core.h"
#include "native_client/src/trusted/service_runtime/include/sys/unistd.h"
#include "native_client/src/untrusted/irt/irt.h"
+#include "native_client/src/untrusted/irt/irt_dev.h"
#include "ppapi/nacl_irt/irt_manifest.h"
#include "ppapi/nacl_irt/public/irt_ppapi.h"
#include "ppapi/native_client/src/untrusted/pnacl_irt_shim/irt_shim_ppapi.h"
@@ -54,6 +55,21 @@ static const struct nacl_irt_interface irt_interfaces[] = {
NULL,
#endif
},
+#if defined(OS_NACL_SFI)
+ // TODO(mseaborn): Ideally these two PNaCl translator interfaces should
+ // be hidden in processes that aren't PNaCl sandboxed translator
+ // processes. However, we haven't yet plumbed though a flag to indicate
+ // when a NaCl process is a PNaCl translator process. The risk of an app
+ // accidentally depending on the presence of this interface is much lower
+ // than for other non-stable IRT interfaces, because this interface is
+ // not useful to apps.
+ { NACL_IRT_PRIVATE_PNACL_TRANSLATOR_LINK_v0_1,
+ &nacl_irt_private_pnacl_translator_link,
+ sizeof(nacl_irt_private_pnacl_translator_link), NULL },
+ { NACL_IRT_PRIVATE_PNACL_TRANSLATOR_COMPILE_v0_1,
+ &nacl_irt_private_pnacl_translator_compile,
+ sizeof(nacl_irt_private_pnacl_translator_compile), NULL },
+#endif
};
size_t chrome_irt_query(const char* interface_ident,
diff --git a/ppapi/nacl_irt/irt_interfaces.h b/ppapi/nacl_irt/irt_interfaces.h
index 0971900..c18d34e 100644
--- a/ppapi/nacl_irt/irt_interfaces.h
+++ b/ppapi/nacl_irt/irt_interfaces.h
@@ -8,6 +8,10 @@
#include <stdlib.h>
extern const struct nacl_irt_ppapihook nacl_irt_ppapihook;
+extern const struct nacl_irt_private_pnacl_translator_link
+ nacl_irt_private_pnacl_translator_link;
+extern const struct nacl_irt_private_pnacl_translator_compile
+ nacl_irt_private_pnacl_translator_compile;
size_t chrome_irt_query(const char* interface_ident,
void* table, size_t tablesize);
diff --git a/ppapi/nacl_irt/irt_pnacl_translator_compile.cc b/ppapi/nacl_irt/irt_pnacl_translator_compile.cc
new file mode 100644
index 0000000..e546098
--- /dev/null
+++ b/ppapi/nacl_irt/irt_pnacl_translator_compile.cc
@@ -0,0 +1,117 @@
+// 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.
+
+#include <argz.h>
+#include <string.h>
+
+#include "native_client/src/shared/platform/nacl_log.h"
+#include "native_client/src/shared/srpc/nacl_srpc.h"
+#include "native_client/src/untrusted/irt/irt_dev.h"
+#include "ppapi/nacl_irt/irt_interfaces.h"
+
+namespace {
+
+const int kMaxObjectFiles = 16;
+
+const struct nacl_irt_pnacl_compile_funcs* g_funcs;
+
+void StreamInitWithSplit(NaClSrpcRpc* rpc,
+ NaClSrpcArg** in_args,
+ NaClSrpcArg** out_args,
+ NaClSrpcClosure* done) {
+ int num_threads = in_args[0]->u.ival;
+ if (num_threads < 0 || num_threads > kMaxObjectFiles) {
+ NaClLog(LOG_FATAL, "Invalid # of threads (%d)\n", num_threads);
+ }
+ int fd_start = 1;
+ int i = fd_start;
+ int num_valid_fds = 0;
+ int obj_fds[kMaxObjectFiles];
+ while (num_valid_fds < kMaxObjectFiles && in_args[i]->u.hval >= 0) {
+ obj_fds[num_valid_fds] = in_args[i]->u.hval;
+ ++i;
+ ++num_valid_fds;
+ }
+ // Convert the null-delimited strings into an array of
+ // null-terminated strings.
+ char* cmd_argz = in_args[kMaxObjectFiles + fd_start]->arrays.carr;
+ size_t cmd_argz_len = in_args[kMaxObjectFiles + fd_start]->u.count;
+ size_t argc = argz_count(cmd_argz, cmd_argz_len);
+ char** argv = (char**)malloc((argc + 1) * sizeof(char*));
+ argz_extract(cmd_argz, cmd_argz_len, argv);
+ char* result =
+ g_funcs->init_callback(num_threads, obj_fds, num_valid_fds, argv, argc);
+ free(argv);
+ if (result != NULL) {
+ rpc->result = NACL_SRPC_RESULT_APP_ERROR;
+ // SRPC wants to free() the string, so just strdup here so that the
+ // init_callback implementation doesn't have to know if the string
+ // comes from malloc or new. On error, we don't care so much
+ // about leaking this bit of memory.
+ out_args[0]->arrays.str = strdup(result);
+ } else {
+ rpc->result = NACL_SRPC_RESULT_OK;
+ out_args[0]->arrays.str = strdup("");
+ }
+ done->Run(done);
+}
+
+void StreamChunk(NaClSrpcRpc* rpc,
+ NaClSrpcArg** in_args,
+ NaClSrpcArg** out_args,
+ NaClSrpcClosure* done) {
+ int result =
+ g_funcs->data_callback(in_args[0]->arrays.carr, in_args[0]->u.count);
+ rpc->result = result == 0 ? NACL_SRPC_RESULT_OK : NACL_SRPC_RESULT_APP_ERROR;
+ done->Run(done);
+}
+
+void StreamEnd(NaClSrpcRpc* rpc,
+ NaClSrpcArg** in_args,
+ NaClSrpcArg** out_args,
+ NaClSrpcClosure* done) {
+ char* result = g_funcs->end_callback();
+ // Fill in the deprecated return values with dummy values.
+ out_args[0]->u.ival = 0;
+ out_args[1]->arrays.str = strdup("");
+ out_args[2]->arrays.str = strdup("");
+ if (result != NULL) {
+ rpc->result = NACL_SRPC_RESULT_APP_ERROR;
+ // SRPC wants to free(), so strdup() and leak to hide this detail.
+ out_args[3]->arrays.str = strdup(result);
+ } else {
+ rpc->result = NACL_SRPC_RESULT_OK;
+ out_args[3]->arrays.str = strdup("");
+ }
+ done->Run(done);
+}
+
+const struct NaClSrpcHandlerDesc kSrpcMethods[] = {
+ // Protocol for streaming:
+ // StreamInitWithSplit(num_threads, obj_fd x 16, cmdline_flags) -> error_str
+ // StreamChunk(data) +
+ // TODO(jvoung): remove these is_shared_lib, etc.
+ // StreamEnd() -> (is_shared_lib, soname, dependencies, error_str)
+ { "StreamInitWithSplit:ihhhhhhhhhhhhhhhhC:s", StreamInitWithSplit },
+ { "StreamChunk:C:", StreamChunk },
+ { "StreamEnd::isss", StreamEnd },
+ { NULL, NULL },
+};
+
+void ServeTranslateRequest(const struct nacl_irt_pnacl_compile_funcs* funcs) {
+ g_funcs = funcs;
+ if (!NaClSrpcModuleInit()) {
+ NaClLog(LOG_FATAL, "NaClSrpcModuleInit() failed\n");
+ }
+ if (!NaClSrpcAcceptClientConnection(kSrpcMethods)) {
+ NaClLog(LOG_FATAL, "NaClSrpcAcceptClientConnection() failed\n");
+ }
+}
+
+}
+
+const struct nacl_irt_private_pnacl_translator_compile
+ nacl_irt_private_pnacl_translator_compile = {
+ ServeTranslateRequest
+};
diff --git a/ppapi/nacl_irt/irt_pnacl_translator_link.cc b/ppapi/nacl_irt/irt_pnacl_translator_link.cc
new file mode 100644
index 0000000..f5569aa
--- /dev/null
+++ b/ppapi/nacl_irt/irt_pnacl_translator_link.cc
@@ -0,0 +1,61 @@
+// 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.
+
+#include "native_client/src/shared/platform/nacl_log.h"
+#include "native_client/src/shared/srpc/nacl_srpc.h"
+#include "native_client/src/untrusted/irt/irt_dev.h"
+#include "ppapi/nacl_irt/irt_interfaces.h"
+
+namespace {
+
+const int kMaxObjectFiles = 16;
+
+int (*g_func)(int nexe_fd,
+ const int* obj_file_fds,
+ int obj_file_fd_count);
+
+void HandleLinkRequest(NaClSrpcRpc* rpc,
+ NaClSrpcArg** in_args,
+ NaClSrpcArg** out_args,
+ NaClSrpcClosure* done) {
+ int obj_file_count = in_args[0]->u.ival;
+ int nexe_fd = in_args[kMaxObjectFiles + 1]->u.hval;
+
+ if (obj_file_count < 1 || obj_file_count > kMaxObjectFiles) {
+ NaClLog(LOG_FATAL, "Bad object file count (%i)\n", obj_file_count);
+ }
+ int obj_file_fds[obj_file_count];
+ for (int i = 0; i < obj_file_count; i++) {
+ obj_file_fds[i] = in_args[i + 1]->u.hval;
+ }
+
+ int result = g_func(nexe_fd, obj_file_fds, obj_file_count);
+
+ rpc->result = result == 0 ? NACL_SRPC_RESULT_OK : NACL_SRPC_RESULT_APP_ERROR;
+ done->Run(done);
+}
+
+const struct NaClSrpcHandlerDesc kSrpcMethods[] = {
+ { "RunWithSplit:ihhhhhhhhhhhhhhhhh:", HandleLinkRequest },
+ { NULL, NULL },
+};
+
+void ServeLinkRequest(int (*func)(int nexe_fd,
+ const int* obj_file_fds,
+ int obj_file_fd_count)) {
+ g_func = func;
+ if (!NaClSrpcModuleInit()) {
+ NaClLog(LOG_FATAL, "NaClSrpcModuleInit() failed\n");
+ }
+ if (!NaClSrpcAcceptClientConnection(kSrpcMethods)) {
+ NaClLog(LOG_FATAL, "NaClSrpcAcceptClientConnection() failed\n");
+ }
+}
+
+}
+
+const struct nacl_irt_private_pnacl_translator_link
+ nacl_irt_private_pnacl_translator_link = {
+ ServeLinkRequest
+};
diff --git a/ppapi/ppapi_proxy.gypi b/ppapi/ppapi_proxy.gypi
index bfb3b5c..eccb91e 100644
--- a/ppapi/ppapi_proxy.gypi
+++ b/ppapi/ppapi_proxy.gypi
@@ -255,6 +255,8 @@
'sources': [
'nacl_irt/irt_interfaces.cc',
'nacl_irt/irt_interfaces.h',
+ 'nacl_irt/irt_pnacl_translator_compile.cc',
+ 'nacl_irt/irt_pnacl_translator_link.cc',
'nacl_irt/irt_ppapi.cc',
'nacl_irt/irt_ppapi.h',
'nacl_irt/irt_start.cc',
diff --git a/ppapi/proxy/BUILD.gn b/ppapi/proxy/BUILD.gn
index c9de244..62a5370 100644
--- a/ppapi/proxy/BUILD.gn
+++ b/ppapi/proxy/BUILD.gn
@@ -198,6 +198,8 @@ component("proxy") {
sources += [
"../nacl_irt/irt_interfaces.cc",
"../nacl_irt/irt_interfaces.h",
+ "../nacl_irt/irt_pnacl_translator_compile.cc",
+ "../nacl_irt/irt_pnacl_translator_link.cc",
"../nacl_irt/irt_ppapi.cc",
"../nacl_irt/irt_ppapi.h",
"../nacl_irt/irt_start.cc",