summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbradchen@google.com <bradchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-17 15:30:13 +0000
committerbradchen@google.com <bradchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-17 15:30:13 +0000
commit34169bda0e64aa826c113c0bed199f8469736f75 (patch)
tree9f12d961ac1416cc9fdb8a367856ea97340d4261
parentb967a1b2bc8ae2c714a3c692cf086fdf7815e9eb (diff)
downloadchromium_src-34169bda0e64aa826c113c0bed199f8469736f75.zip
chromium_src-34169bda0e64aa826c113c0bed199f8469736f75.tar.gz
chromium_src-34169bda0e64aa826c113c0bed199f8469736f75.tar.bz2
Reserve 1GB at the base of the address space of linux nacl_helper for Native Client module.
Use PathService instead of command line flag to enable helper. Adds a nacl_helper_bootstrap executable that implements the actual space reservation. This is for resubmit of reverted CL 7670011, fixing nacl.gypi for the linux_shared build. See 7670011 and 7599011 for review history. TBR=agl,bradnelson BUG=92964, nativeclient:480 TEST=manual for now Review URL: http://codereview.chromium.org/7655010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@97137 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/common/chrome_paths.cc13
-rw-r--r--chrome/common/chrome_paths.h6
-rw-r--r--chrome/nacl.gypi35
-rw-r--r--chrome/nacl/nacl_fork_delegate_linux.cc22
-rw-r--r--chrome/nacl/nacl_helper_bootstrap_linux.c24
-rw-r--r--chrome/nacl/nacl_helper_exports.txt10
-rw-r--r--chrome/nacl/nacl_helper_linux.cc24
-rwxr-xr-xtools/ld_bfd/ld2
8 files changed, 124 insertions, 12 deletions
diff --git a/chrome/common/chrome_paths.cc b/chrome/common/chrome_paths.cc
index 550b18b..0758f1e 100644
--- a/chrome/common/chrome_paths.cc
+++ b/chrome/common/chrome_paths.cc
@@ -52,6 +52,12 @@ const FilePath::CharType kInternalNaClPluginFileName[] =
FILE_PATH_LITERAL("libppGoogleNaClPluginChrome.so");
#endif
+#if defined(OS_POSIX) && !defined(OS_MACOSX)
+// File name of the nacl_helper, Linux only.
+const FilePath::CharType kInternalNaClHelperFileName[] =
+ FILE_PATH_LITERAL("nacl_helper_bootstrap");
+#endif
+
} // namespace
namespace chrome {
@@ -234,6 +240,13 @@ bool PathProvider(int key, FilePath* result) {
return false;
cur = cur.Append(kInternalNaClPluginFileName);
break;
+#if defined(OS_POSIX) && !defined(OS_MACOSX)
+ case chrome::FILE_NACL_HELPER:
+ if (!PathService::Get(base::DIR_MODULE, &cur))
+ return false;
+ cur = cur.Append(kInternalNaClHelperFileName);
+ break;
+#endif
case chrome::FILE_RESOURCES_PACK:
#if defined(OS_MACOSX)
if (base::mac::AmIBundled()) {
diff --git a/chrome/common/chrome_paths.h b/chrome/common/chrome_paths.h
index 43140ea..4998213 100644
--- a/chrome/common/chrome_paths.h
+++ b/chrome/common/chrome_paths.h
@@ -40,7 +40,7 @@ enum {
// using it.
DIR_INTERNAL_PLUGINS, // Directory where internal plugins reside.
DIR_MEDIA_LIBS, // Directory where the Media libraries reside.
-#if !defined(OS_MACOSX) && defined(OS_POSIX)
+#if defined(OS_POSIX) && !defined(OS_MACOSX)
DIR_POLICY_FILES, // Directory for system-wide read-only
// policy files that allow sys-admins
// to set policies for chrome. This directory
@@ -68,6 +68,10 @@ enum {
FILE_FLASH_PLUGIN, // Full path to the internal Flash plugin file.
FILE_PEPPER_FLASH_PLUGIN, // Full path to the pepper Flash plugin file.
FILE_PDF_PLUGIN, // Full path to the internal PDF plugin file.
+
+#if defined(OS_POSIX) && !defined(OS_MACOSX)
+ FILE_NACL_HELPER, // Full path to Linux nacl_helper executable.
+#endif
FILE_NACL_PLUGIN, // Full path to the internal NaCl plugin file.
FILE_LIBAVCODEC, // Full path to libavcodec media decoding
// library.
diff --git a/chrome/nacl.gypi b/chrome/nacl.gypi
index 9467359..bfc6652 100644
--- a/chrome/nacl.gypi
+++ b/chrome/nacl.gypi
@@ -144,10 +144,12 @@
},
],
}],
- ['OS=="linux" and touchui == 0', {
+ ['OS=="linux"', {
'targets': [
{
- 'target_name': 'nacl_helper',
+ 'target_name': 'nacl_helper.so',
+ # 'executable' will be overridden below when we add the -shared
+ # flag; here it prevents gyp from using the --whole-archive flag
'type': 'executable',
'include_dirs': [
'..',
@@ -165,6 +167,35 @@
],
}],
],
+ 'link_settings': {
+ # NOTE: '-shared' overrides 'executable' above
+ 'ldflags': ['-shared',
+ '-Wl,--version-script=chrome/nacl/nacl_helper_exports.txt',
+ ],
+ },
+ },
+ {
+ 'target_name': 'nacl_helper_bootstrap',
+ 'type': 'executable',
+ 'dependencies': [
+ 'nacl_helper.so',
+ ],
+ 'sources': [
+ '../chrome/nacl/nacl_helper_bootstrap_linux.c',
+ ],
+ # TODO(bradchen): Delete the -B argument when Gold supports
+ # -Ttext properly. Until then use ld.bfd.
+ 'link_settings': {
+ 'ldflags': ['-B', 'tools/ld_bfd',
+ # Force text segment at 0x10000 (64KB)
+ # The max-page-size option is needed on x86-64 linux
+ # where 4K pages are not the default in the BFD linker.
+ '-Wl,-Ttext-segment,10000,-z,max-page-size=0x1000',
+ # reference nacl_helper as a shared library
+ '<(PRODUCT_DIR)/nacl_helper.so',
+ '-Wl,-rpath,<(SHARED_LIB_DIR)',
+ ],
+ },
},
],
}],
diff --git a/chrome/nacl/nacl_fork_delegate_linux.cc b/chrome/nacl/nacl_fork_delegate_linux.cc
index 794cfda..e5ee01a 100644
--- a/chrome/nacl/nacl_fork_delegate_linux.cc
+++ b/chrome/nacl/nacl_fork_delegate_linux.cc
@@ -13,9 +13,11 @@
#include "base/eintr_wrapper.h"
#include "base/logging.h"
#include "base/file_path.h"
+#include "base/path_service.h"
#include "base/process_util.h"
#include "content/common/unix_domain_socket_posix.h"
#include "content/common/zygote_fork_delegate_linux.h"
+#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/nacl_helper_linux.h"
@@ -40,18 +42,24 @@ void NaClForkDelegate::Init(const bool sandboxed,
base::file_handle_mapping_vector fds_to_map;
fds_to_map.push_back(std::make_pair(fds[1], kNaClZygoteDescriptor));
fds_to_map.push_back(std::make_pair(sandboxdesc, kNaClSandboxDescriptor));
- // TODO(bradchen): Before making this the default for release builds,
- // replace command line switch with PathService::Get().
- const std::string nacl_zygote_exe =
- CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
- switches::kNaClLinuxHelper);
+ // TODO(bradchen): To make this the default for release builds,
+ // remove command line switch.
ready_ = false;
- if (nacl_zygote_exe.length() != 0) {
+ const bool use_helper = CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kNaClLinuxHelper);
+ FilePath helper_exe;
+ if (use_helper && PathService::Get(chrome::FILE_NACL_HELPER, &helper_exe)) {
CommandLine::StringVector argv = CommandLine::ForCurrentProcess()->argv();
- argv[0] = nacl_zygote_exe;
+ argv[0] = helper_exe.value();
base::LaunchOptions options;
options.fds_to_remap = &fds_to_map;
options.clone_flags = CLONE_FS | SIGCHLD;
+ // LD_BIND_NOW forces non-lazy binding in the dynamic linker, to
+ // prevent the linker from trying to look at the text of the nacl_helper
+ // program after it has been replaced by the nacl module.
+ base::environment_vector env;
+ env.push_back(std::make_pair("LD_BIND_NOW", "1"));
+ options.environ = &env;
ready_ = base::LaunchProcess(argv, options, NULL);
// parent and error cases are handled below
}
diff --git a/chrome/nacl/nacl_helper_bootstrap_linux.c b/chrome/nacl/nacl_helper_bootstrap_linux.c
new file mode 100644
index 0000000..7a0ace7
--- /dev/null
+++ b/chrome/nacl/nacl_helper_bootstrap_linux.c
@@ -0,0 +1,24 @@
+/* Copyright (c) 2011 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.
+ *
+ * Bootstraping the nacl_helper. This executable reserves the bottom 1G
+ * of the address space, then invokes nacl_helper_init. Note that,
+ * as the text of this executable will eventually be overwritten by the
+ * native_client module, nacl_helper_init must not attempt to return.
+ */
+
+#include <stdlib.h>
+
+/* reserve 1GB of space */
+#define ONEGIG (1 << 30)
+char nacl_reserved_space[ONEGIG];
+
+void nacl_helper_init(int argc, char *argv[],
+ const char *nacl_reserved_space);
+
+int main(int argc, char *argv[]) {
+ nacl_helper_init(argc, argv, nacl_reserved_space);
+ abort();
+ return 0; // convince the tools I'm sane.
+}
diff --git a/chrome/nacl/nacl_helper_exports.txt b/chrome/nacl/nacl_helper_exports.txt
new file mode 100644
index 0000000..af930c1
--- /dev/null
+++ b/chrome/nacl/nacl_helper_exports.txt
@@ -0,0 +1,10 @@
+# gnu-ld version script for exporting desired symbols from nacl_helper
+#
+
+NACL_HELPER_1_0 {
+ global:
+ nacl_helper_init;
+ nacl_helper_get_1G_address;
+ local:
+ *;
+};
diff --git a/chrome/nacl/nacl_helper_linux.cc b/chrome/nacl/nacl_helper_linux.cc
index b943e2b..b53cf8d 100644
--- a/chrome/nacl/nacl_helper_linux.cc
+++ b/chrome/nacl/nacl_helper_linux.cc
@@ -116,14 +116,33 @@ void HandleForkRequest(const std::vector<int>& child_fds) {
} // namespace
-int main(int argc, char *argv[]) {
+static const void* g_nacl_reserved_space = NULL;
+extern "C" __attribute__((visibility("default")))
+const void* nacl_helper_get_1G_address() {
+ return g_nacl_reserved_space;
+}
+
+// nacl_helper_init does the real work of this module. It is invoked as
+// a static constructor and never returns, preventing main() from the
+// nacl_helper_bootstrap program from being called.
+//
+// NOTE This routine must not return.
+extern "C" __attribute__((visibility("default")))
+void nacl_helper_init(int argc, char *argv[],
+ const char *nacl_reserved_space) {
CommandLine::Init(argc, argv);
base::AtExitManager exit_manager;
base::RandUint64(); // acquire /dev/urandom fd before sandbox is raised
std::vector<int> empty; // for SendMsg() calls
g_suid_sandbox_active = (NULL != getenv("SBX_D"));
-
+ g_nacl_reserved_space = nacl_reserved_space;
+ if (!nacl_reserved_space) {
+ VLOG(1) << "nacl_reserved_space is NULL";
+ } else {
+ VLOG(1) << "nacl_reserved_space is at "
+ << (void *)nacl_reserved_space;
+ }
// Send the zygote a message to let it know we are ready to help
if (!UnixDomainSocket::SendMsg(kNaClZygoteDescriptor,
kNaClHelperStartupAck,
@@ -163,4 +182,5 @@ int main(int argc, char *argv[]) {
LOG(ERROR) << "*** send() to zygote failed";
}
}
+ CHECK(false); // This routine must not return
}
diff --git a/tools/ld_bfd/ld b/tools/ld_bfd/ld
index 5a5d84e..124f202 100755
--- a/tools/ld_bfd/ld
+++ b/tools/ld_bfd/ld
@@ -34,6 +34,8 @@ def main():
continue
if arg == "-Wl,--thread-count=4" or arg == "--thread-count=4":
continue
+ if arg == "--icf=none":
+ continue
args.append(arg)
print("ld_bfd/ld: exec ", args)
sys.exit(subprocess.call(args))