Commit d735c8b9 authored by mseaborn's avatar mseaborn Committed by Commit bot

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}
parent 2194f54b
...@@ -11,6 +11,9 @@ include_rules = [ ...@@ -11,6 +11,9 @@ include_rules = [
# The untrusted build references the NaCl integrated runtime (IRT). # The untrusted build references the NaCl integrated runtime (IRT).
"+native_client/src/public", "+native_client/src/public",
"+native_client/src/untrusted/irt/irt.h", "+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. # 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/errno.h",
"+native_client/src/trusted/service_runtime/include/sys/unistd.h", "+native_client/src/trusted/service_runtime/include/sys/unistd.h",
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "native_client/src/public/irt_core.h" #include "native_client/src/public/irt_core.h"
#include "native_client/src/trusted/service_runtime/include/sys/unistd.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.h"
#include "native_client/src/untrusted/irt/irt_dev.h"
#include "ppapi/nacl_irt/irt_manifest.h" #include "ppapi/nacl_irt/irt_manifest.h"
#include "ppapi/nacl_irt/public/irt_ppapi.h" #include "ppapi/nacl_irt/public/irt_ppapi.h"
#include "ppapi/native_client/src/untrusted/pnacl_irt_shim/irt_shim_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[] = { ...@@ -54,6 +55,21 @@ static const struct nacl_irt_interface irt_interfaces[] = {
NULL, NULL,
#endif #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, size_t chrome_irt_query(const char* interface_ident,
......
...@@ -8,6 +8,10 @@ ...@@ -8,6 +8,10 @@
#include <stdlib.h> #include <stdlib.h>
extern const struct nacl_irt_ppapihook nacl_irt_ppapihook; 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, size_t chrome_irt_query(const char* interface_ident,
void* table, size_t tablesize); void* table, size_t tablesize);
......
// 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
};
// 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
};
...@@ -255,6 +255,8 @@ ...@@ -255,6 +255,8 @@
'sources': [ 'sources': [
'nacl_irt/irt_interfaces.cc', 'nacl_irt/irt_interfaces.cc',
'nacl_irt/irt_interfaces.h', '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.cc',
'nacl_irt/irt_ppapi.h', 'nacl_irt/irt_ppapi.h',
'nacl_irt/irt_start.cc', 'nacl_irt/irt_start.cc',
......
...@@ -198,6 +198,8 @@ component("proxy") { ...@@ -198,6 +198,8 @@ component("proxy") {
sources += [ sources += [
"../nacl_irt/irt_interfaces.cc", "../nacl_irt/irt_interfaces.cc",
"../nacl_irt/irt_interfaces.h", "../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.cc",
"../nacl_irt/irt_ppapi.h", "../nacl_irt/irt_ppapi.h",
"../nacl_irt/irt_start.cc", "../nacl_irt/irt_start.cc",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment