diff options
author | mseaborn <mseaborn@chromium.org> | 2015-07-21 19:55:07 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-07-22 02:55:42 +0000 |
commit | d735c8b9e7d1c2267d65a357e9a3541358e846e2 (patch) | |
tree | cc8b43f4d517f21c84d88e149dd954ba5222841c /ppapi | |
parent | 2194f54bd4e254605a60350f2077266017364f9f (diff) | |
download | chromium_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/DEPS | 3 | ||||
-rw-r--r-- | ppapi/nacl_irt/irt_interfaces.cc | 16 | ||||
-rw-r--r-- | ppapi/nacl_irt/irt_interfaces.h | 4 | ||||
-rw-r--r-- | ppapi/nacl_irt/irt_pnacl_translator_compile.cc | 117 | ||||
-rw-r--r-- | ppapi/nacl_irt/irt_pnacl_translator_link.cc | 61 | ||||
-rw-r--r-- | ppapi/ppapi_proxy.gypi | 2 | ||||
-rw-r--r-- | ppapi/proxy/BUILD.gn | 2 |
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", |