summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhidehiko <hidehiko@chromium.org>2014-10-23 20:49:27 -0700
committerCommit bot <commit-bot@chromium.org>2014-10-24 03:49:59 +0000
commitc2eec0d81f92df06e614e104eba8b3e12bbc6030 (patch)
tree403c5ac0be4b793f720effab75c6ef17e32b79c5
parentb60e628410931c87e1ca3fdbf7787f5e2a3fb4fa (diff)
downloadchromium_src-c2eec0d81f92df06e614e104eba8b3e12bbc6030.zip
chromium_src-c2eec0d81f92df06e614e104eba8b3e12bbc6030.tar.gz
chromium_src-c2eec0d81f92df06e614e104eba8b3e12bbc6030.tar.bz2
Non-SFI Mode: Build ipc/ library by PNaCl toolchain for nacl_helper_nonsfi.
This CL is to build ipc/ for nacl_helper_nonsfi. The library is similar to ipc_nacl, but slightly different: - The IPC::Channel should use ChannelPosix rather than ChannelNaCl, as it runs under linux directly. - Some features of ChannelPosix cannot be compiled by PNaCl toolchain for Non-SFI build, but these are not necessary for nacl_helper_nonsfi. These are dropped by "ifdef" guard. Note that this library is not used yet, but should be built successfully. BUG=358465 TEST=Ran trybot. Implement nacl_helper_nonsfi on top of this CL, and made sure it works. Review URL: https://codereview.chromium.org/659243002 Cr-Commit-Position: refs/heads/master@{#301037}
-rw-r--r--components/nacl_nonsfi.gyp16
-rw-r--r--ipc/ipc_channel.cc3
-rw-r--r--ipc/ipc_channel.h10
-rw-r--r--ipc/ipc_channel_posix.cc42
-rw-r--r--ipc/ipc_channel_proxy.cc3
-rw-r--r--ipc/ipc_channel_proxy.h5
-rw-r--r--ipc/ipc_nacl.gyp32
7 files changed, 98 insertions, 13 deletions
diff --git a/components/nacl_nonsfi.gyp b/components/nacl_nonsfi.gyp
index 5b96c7e..1625451 100644
--- a/components/nacl_nonsfi.gyp
+++ b/components/nacl_nonsfi.gyp
@@ -13,6 +13,20 @@
['disable_nacl==0 and disable_nacl_untrusted==0', {
'targets': [
{
+ # nacl_helper_nonsfi is similar to nacl_helper (built in nacl.gyp)
+ # but for the NaCl plugin in Non-SFI mode.
+ # This binary is built using the PNaCl toolchain, but it is native
+ # linux binary and will run on Linux directly.
+ # Most library code can be shared with the one for untrusted build
+ # (i.e. the one for irt.nexe built by the NaCl/PNaCl toolchain), but
+ # as nacl_helper_nonsfi runs on Linux, there are some differences,
+ # such as MessageLoopForIO (which is based on libevent in Non-SFI
+ # mode) or ipc_channel implementation.
+ # Because of the toolchain, in both builds, OS_NACL macro (derived
+ # from __native_client__ macro) is defined. Code can test whether
+ # __native_client_nonsfi__ is #defined in order to determine
+ # whether it is being compiled for SFI mode or Non-SFI mode.
+ #
# Currently, nacl_helper_nonsfi is under development and the binary
# does nothing (i.e. it has only empty main(), now).
# TODO(crbug.com/358465): Implement it then switch nacl_helper in
@@ -48,6 +62,7 @@
'>(tc_lib_dir_nonsfi_helper32)/libgles2_implementation_nacl.a',
'>(tc_lib_dir_nonsfi_helper32)/libgles2_utils_nacl.a',
'>(tc_lib_dir_nonsfi_helper32)/libgpu_ipc_nacl.a',
+ '>(tc_lib_dir_nonsfi_helper32)/libipc_nacl_nonsfi.a',
'>(tc_lib_dir_nonsfi_helper32)/libshared_memory_support_nacl.a',
],
}],
@@ -55,6 +70,7 @@
},
'dependencies': [
'../base/base_nacl.gyp:base_nacl_nonsfi',
+ '../ipc/ipc_nacl.gyp:ipc_nacl_nonsfi',
'../native_client/src/nonsfi/irt/irt.gyp:nacl_sys_private',
'../native_client/src/untrusted/nacl/nacl.gyp:nacl_lib_newlib',
'../native_client/tools.gyp:prep_toolchain',
diff --git a/ipc/ipc_channel.cc b/ipc/ipc_channel.cc
index a6ee14c..4a4e40d 100644
--- a/ipc/ipc_channel.cc
+++ b/ipc/ipc_channel.cc
@@ -10,14 +10,12 @@
#include "base/rand_util.h"
#include "base/strings/stringprintf.h"
-#if !defined(OS_NACL)
namespace {
// Global atomic used to guarantee channel IDs are unique.
base::StaticAtomicSequenceNumber g_last_id;
} // namespace
-#endif
namespace IPC {
@@ -39,4 +37,3 @@ std::string Channel::GenerateUniqueRandomChannelID() {
}
} // namespace IPC
-
diff --git a/ipc/ipc_channel.h b/ipc/ipc_channel.h
index 2d8d449..3ed5e6a 100644
--- a/ipc/ipc_channel.h
+++ b/ipc/ipc_channel.h
@@ -179,7 +179,11 @@ class IPC_EXPORT Channel : public Sender {
// deleted once the contents of the Message have been sent.
virtual bool Send(Message* message) = 0;
-#if defined(OS_POSIX) && !defined(OS_NACL)
+ // NaCl in Non-SFI mode runs on Linux directly, and the following functions
+ // compiled on Linux are also needed. Please see also comments in
+ // components/nacl_nonsfi.gyp for more details.
+#if defined(OS_POSIX) && \
+ (!defined(OS_NACL) || defined(__native_client_nonsfi__))
// On POSIX an IPC::Channel wraps a socketpair(), this method returns the
// FD # for the client end of the socket.
// This method may only be called on the server side of a channel.
@@ -190,13 +194,13 @@ class IPC_EXPORT Channel : public Sender {
// file descriptor to the caller.
// This method can be called on any thread.
virtual base::ScopedFD TakeClientFileDescriptor() = 0;
-#endif // defined(OS_POSIX) && !defined(OS_NACL)
+#endif
// Returns true if a named server channel is initialized on the given channel
// ID. Even if true, the server may have already accepted a connection.
static bool IsNamedServerInitialized(const std::string& channel_id);
-#if !defined(OS_NACL)
+#if !defined(OS_NACL) || defined(__native_client_nonsfi__)
// Generates a channel ID that's non-predictable and unique.
static std::string GenerateUniqueRandomChannelID();
diff --git a/ipc/ipc_channel_posix.cc b/ipc/ipc_channel_posix.cc
index c864db2..8e74c3a 100644
--- a/ipc/ipc_channel_posix.cc
+++ b/ipc/ipc_channel_posix.cc
@@ -10,13 +10,16 @@
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
-#include <sys/un.h>
#include <unistd.h>
#if defined(OS_OPENBSD)
#include <sys/uio.h>
#endif
+#if !defined(__native_client_nonsfi__)
+#include <sys/un.h>
+#endif
+
#include <map>
#include <string>
@@ -255,6 +258,10 @@ bool ChannelPosix::CreatePipe(
}
#endif // IPC_USES_READWRITE
} else if (mode_ & MODE_NAMED_FLAG) {
+#if defined(__native_client_nonsfi__)
+ LOG(FATAL)
+ << "IPC channels in nacl_helper_nonsfi should not be in NAMED mode.";
+#else
// Case 2 from comment above.
int local_pipe_fd = -1;
@@ -276,6 +283,7 @@ bool ChannelPosix::CreatePipe(
}
local_pipe.reset(local_pipe_fd);
+#endif // !defined(__native_client_nonsfi__)
} else {
local_pipe.reset(PipeMap::GetInstance()->Lookup(pipe_name_));
if (mode_ & MODE_CLIENT_FLAG) {
@@ -336,10 +344,16 @@ bool ChannelPosix::CreatePipe(
}
#endif // IPC_USES_READWRITE
- if ((mode_ & MODE_SERVER_FLAG) && (mode_ & MODE_NAMED_FLAG))
+ if ((mode_ & MODE_SERVER_FLAG) && (mode_ & MODE_NAMED_FLAG)) {
+#if defined(__native_client_nonsfi__)
+ LOG(FATAL) << "IPC channels in nacl_helper_nonsfi "
+ << "should not be in NAMED or SERVER mode.";
+#else
server_listen_pipe_.reset(local_pipe.release());
- else
+#endif
+ } else {
pipe_.reset(local_pipe.release());
+ }
return true;
}
@@ -351,6 +365,10 @@ bool ChannelPosix::Connect() {
bool did_connect = true;
if (server_listen_pipe_.is_valid()) {
+#if defined(__native_client_nonsfi__)
+ LOG(FATAL) << "IPC channels in nacl_helper_nonsfi "
+ << "should always be in client mode.";
+#else
// Watch the pipe for connections, and turn any connections into
// active sockets.
base::MessageLoopForIO::current()->WatchFileDescriptor(
@@ -359,6 +377,7 @@ bool ChannelPosix::Connect() {
base::MessageLoopForIO::WATCH_READ,
&server_listen_connection_watcher_,
this);
+#endif
} else {
did_connect = AcceptConnection();
}
@@ -581,10 +600,13 @@ bool ChannelPosix::HasAcceptedConnection() const {
return AcceptsConnections() && pipe_.is_valid();
}
+#if !defined(__native_client_nonsfi__)
+// GetPeerEuid is not supported in nacl_helper_nonsfi.
bool ChannelPosix::GetPeerEuid(uid_t* peer_euid) const {
DCHECK(!(mode_ & MODE_SERVER) || HasAcceptedConnection());
return IPC::GetPeerEuid(pipe_.get(), peer_euid);
}
+#endif
void ChannelPosix::ResetToAcceptingConnectionState() {
// Unregister libevent for the unix domain socket and close it.
@@ -633,6 +655,10 @@ void ChannelPosix::SetGlobalPid(int pid) {
// Called by libevent when we can read from the pipe without blocking.
void ChannelPosix::OnFileCanReadWithoutBlocking(int fd) {
if (fd == server_listen_pipe_.get()) {
+#if defined(__native_client_nonsfi__)
+ LOG(FATAL)
+ << "IPC channels in nacl_helper_nonsfi should not be SERVER mode.";
+#else
int new_pipe = 0;
if (!ServerAcceptConnection(server_listen_pipe_.get(), &new_pipe) ||
new_pipe < 0) {
@@ -671,6 +697,7 @@ void ChannelPosix::OnFileCanReadWithoutBlocking(int fd) {
NOTREACHED() << "AcceptConnection should not fail on server";
}
waiting_connect_ = false;
+#endif
} else if (fd == pipe_) {
if (waiting_connect_ && (mode_ & MODE_SERVER_FLAG)) {
waiting_connect_ = false;
@@ -923,11 +950,15 @@ bool ChannelPosix::ExtractFileDescriptorsFromMsghdr(msghdr* msg) {
file_descriptors,
file_descriptors + num_file_descriptors);
+#if !defined(__native_client_nonsfi__)
+ // The PNaCl toolchain for Non-SFI binary build does not support
+ // MSG_CTRUNC.
// Check this after adding the FDs so we don't leak them.
if (msg->msg_flags & MSG_CTRUNC) {
ClearInputFDs();
return false;
}
+#endif
return true;
}
@@ -1032,9 +1063,14 @@ void ChannelPosix::Close() {
}
if (server_listen_pipe_.is_valid()) {
+#if defined(__native_client_nonsfi__)
+ LOG(FATAL)
+ << "IPC channels in nacl_helper_nonsfi should not be SERVER mode.";
+#else
server_listen_pipe_.reset();
// Unregister libevent for the listening socket and close it.
server_listen_connection_watcher_.StopWatchingFileDescriptor();
+#endif
}
CloseClientFileDescriptor();
diff --git a/ipc/ipc_channel_proxy.cc b/ipc/ipc_channel_proxy.cc
index e2d7ad4..07f9552 100644
--- a/ipc/ipc_channel_proxy.cc
+++ b/ipc/ipc_channel_proxy.cc
@@ -434,7 +434,8 @@ void ChannelProxy::ClearIPCTaskRunner() {
context()->ClearIPCTaskRunner();
}
-#if defined(OS_POSIX) && !defined(OS_NACL)
+#if defined(OS_POSIX) && \
+ (!defined(OS_NACL) || defined(__native_client_nonsfi__))
// See the TODO regarding lazy initialization of the channel in
// ChannelProxy::Init().
int ChannelProxy::GetClientFileDescriptor() {
diff --git a/ipc/ipc_channel_proxy.h b/ipc/ipc_channel_proxy.h
index 71a014b..e2ad4a9 100644
--- a/ipc/ipc_channel_proxy.h
+++ b/ipc/ipc_channel_proxy.h
@@ -119,11 +119,12 @@ class IPC_EXPORT ChannelProxy : public Sender, public base::NonThreadSafe {
// Returns base::kNullProcessId if the peer is not connected yet.
base::ProcessId GetPeerPID() const { return context_->peer_pid_; }
-#if defined(OS_POSIX) && !defined(OS_NACL)
+#if defined(OS_POSIX) && \
+ (!defined(OS_NACL) || defined(__native_client_nonsfi__))
// Calls through to the underlying channel's methods.
int GetClientFileDescriptor();
base::ScopedFD TakeClientFileDescriptor();
-#endif // defined(OS_POSIX)
+#endif
protected:
class Context;
diff --git a/ipc/ipc_nacl.gyp b/ipc/ipc_nacl.gyp
index 3119f46..6f0d522 100644
--- a/ipc/ipc_nacl.gyp
+++ b/ipc/ipc_nacl.gyp
@@ -25,8 +25,38 @@
'build_irt': 1,
},
'dependencies': [
- '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
'../base/base_nacl.gyp:base_nacl',
+ '../native_client/tools.gyp:prep_toolchain',
+ ],
+ },
+ {
+ 'target_name': 'ipc_nacl_nonsfi',
+ 'type': 'none',
+ 'variables': {
+ 'ipc_target': 1,
+ 'nacl_untrusted_build': 1,
+ 'nlib_target': 'libipc_nacl_nonsfi.a',
+ 'build_glibc': 0,
+ 'build_newlib': 0,
+ 'build_irt': 0,
+ 'build_pnacl_newlib': 0,
+ 'build_nonsfi_helper': 1,
+
+ # Use linux IPC channel implementation for nacl_helper_nonsfi,
+ # instead of NaCl's IPC implementation (ipc_channel_nacl.cc),
+ # because nacl_helper_nonsfi will be running directly on Linux.
+ # ipc_channel_nacl.cc is excluded below.
+ 'sources': [
+ 'ipc_channel.cc',
+ 'ipc_channel_posix.cc',
+ ],
+ },
+ 'sources!': [
+ 'ipc_channel_nacl.cc',
+ ],
+ 'dependencies': [
+ '../base/base_nacl.gyp:base_nacl_nonsfi',
+ '../native_client/tools.gyp:prep_toolchain',
],
},
],