| Index: content/common/child_process_host.cc
|
| ===================================================================
|
| --- content/common/child_process_host.cc (revision 97969)
|
| +++ content/common/child_process_host.cc (working copy)
|
| @@ -6,6 +6,7 @@
|
|
|
| #include "base/command_line.h"
|
| #include "base/file_path.h"
|
| +#include "base/logging.h"
|
| #include "base/metrics/histogram.h"
|
| #include "base/path_service.h"
|
| #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
|
| @@ -19,6 +20,52 @@
|
| #include "base/linux_util.h"
|
| #endif // OS_LINUX
|
|
|
| +#if defined(OS_MACOSX)
|
| +namespace {
|
| +
|
| +// Given |path| identifying a Mac-style child process executable path, adjusts
|
| +// it to correspond to |feature|. For a child process path such as
|
| +// ".../Chromium Helper.app/Contents/MacOS/Chromium Helper", the transformed
|
| +// path for feature "NP" would be
|
| +// ".../Chromium Helper NP.app/Contents/MacOS/Chromium Helper NP". The new
|
| +// path is returned.
|
| +FilePath TransformPathForFeature(const FilePath& path,
|
| + const std::string& feature) {
|
| + std::string basename = path.BaseName().value();
|
| +
|
| + FilePath macos_path = path.DirName();
|
| + const char kMacOSName[] = "MacOS";
|
| + DCHECK_EQ(kMacOSName, macos_path.BaseName().value());
|
| +
|
| + FilePath contents_path = macos_path.DirName();
|
| + const char kContentsName[] = "Contents";
|
| + DCHECK_EQ(kContentsName, contents_path.BaseName().value());
|
| +
|
| + FilePath helper_app_path = contents_path.DirName();
|
| + const char kAppExtension[] = ".app";
|
| + std::string basename_app = basename;
|
| + basename_app.append(kAppExtension);
|
| + DCHECK_EQ(basename_app, helper_app_path.BaseName().value());
|
| +
|
| + FilePath root_path = helper_app_path.DirName();
|
| +
|
| + std::string new_basename = basename;
|
| + new_basename.append(1, ' ');
|
| + new_basename.append(feature);
|
| + std::string new_basename_app = new_basename;
|
| + new_basename_app.append(kAppExtension);
|
| +
|
| + FilePath new_path = root_path.Append(new_basename_app)
|
| + .Append(kContentsName)
|
| + .Append(kMacOSName)
|
| + .Append(new_basename);
|
| +
|
| + return new_path;
|
| +}
|
| +
|
| +} // namespace
|
| +#endif // OS_MACOSX
|
| +
|
| ChildProcessHost::ChildProcessHost()
|
| : ALLOW_THIS_IN_INITIALIZER_LIST(listener_(this)),
|
| opening_channel_(false) {
|
| @@ -39,7 +86,7 @@
|
| }
|
|
|
| // static
|
| -FilePath ChildProcessHost::GetChildPath(bool allow_self) {
|
| +FilePath ChildProcessHost::GetChildPath(int flags) {
|
| FilePath child_path;
|
|
|
| child_path = CommandLine::ForCurrentProcess()->GetSwitchValuePath(
|
| @@ -53,13 +100,33 @@
|
| // When running under Valgrind, forking /proc/self/exe ends up forking the
|
| // Valgrind executable, which then crashes. However, it's almost safe to
|
| // assume that the updates won't happen while testing with Valgrind tools.
|
| - if (allow_self && !RunningOnValgrind())
|
| + if (flags & CHILD_ALLOW_SELF && !RunningOnValgrind())
|
| return FilePath("/proc/self/exe");
|
| #endif
|
|
|
| // On most platforms, the child executable is the same as the current
|
| // executable.
|
| PathService::Get(content::CHILD_PROCESS_EXE, &child_path);
|
| +
|
| +#if defined(OS_MACOSX)
|
| + DCHECK(!(flags & CHILD_NO_PIE && flags & CHILD_ALLOW_HEAP_EXECUTION));
|
| +
|
| + // If needed, choose an executable with special flags set that inform the
|
| + // kernel to enable or disable specific optional process-wide features.
|
| + if (flags & CHILD_NO_PIE) {
|
| + // "NP" is "No PIE". This results in Chromium Helper NP.app or
|
| + // Google Chrome Helper NP.app.
|
| + child_path = TransformPathForFeature(child_path, "NP");
|
| + } else if (flags & CHILD_ALLOW_HEAP_EXECUTION) {
|
| + // "EH" is "Executable Heap". A non-executable heap is only available to
|
| + // 32-bit processes on Mac OS X 10.7. Most code can and should run with a
|
| + // non-executable heap, but the "EH" feature is provided to allow code
|
| + // intolerant of a non-executable heap to work properly on 10.7. This
|
| + // results in Chromium Helper EH.app or Google Chrome Helper EH.app.
|
| + child_path = TransformPathForFeature(child_path, "EH");
|
| + }
|
| +#endif
|
| +
|
| return child_path;
|
| }
|
|
|
|
|