summarylogtreecommitdiffstats
path: root/restore_successful_build.patch
diff options
context:
space:
mode:
Diffstat (limited to 'restore_successful_build.patch')
-rw-r--r--restore_successful_build.patch2198
1 files changed, 2198 insertions, 0 deletions
diff --git a/restore_successful_build.patch b/restore_successful_build.patch
new file mode 100644
index 000000000000..fb16002ce707
--- /dev/null
+++ b/restore_successful_build.patch
@@ -0,0 +1,2198 @@
+From b95445f224c5eabedbe1a8b865529d1daea80775 Mon Sep 17 00:00:00 2001
+From: hawkeye116477 <hawkeye116477@gmail.com>
+Date: Tue, 20 Aug 2019 17:30:26 +0200
+Subject: [PATCH 1/5] Revert "Bug 1401790 - Remove ProcessArchitecture from
+ IPC. r=billm,jimm"
+
+This reverts commit 5b5fab3055a206a608dfa3f05956478d0e090031.
+---
+ dom/media/gmp/GMPProcessParent.cpp | 3 +-
+ dom/plugins/base/nsPluginsDirDarwin.cpp | 60 ++++++++++
+ dom/plugins/ipc/PluginProcessParent.cpp | 39 +++++-
+ ipc/chromium/src/base/process_util.h | 50 ++++++--
+ ipc/chromium/src/base/process_util_bsd.cc | 14 ++-
+ ipc/chromium/src/base/process_util_linux.cc | 14 ++-
+ ipc/chromium/src/base/process_util_mac.mm | 50 ++++++--
+ ipc/glue/GeckoChildProcessHost.cpp | 126 +++++++++++++++-----
+ ipc/glue/GeckoChildProcessHost.h | 19 ++-
+ 9 files changed, 312 insertions(+), 63 deletions(-)
+
+diff --git a/dom/media/gmp/GMPProcessParent.cpp b/dom/media/gmp/GMPProcessParent.cpp
+index 823e120bc3a4..aad88b3ab145 100644
+--- a/dom/media/gmp/GMPProcessParent.cpp
++++ b/dom/media/gmp/GMPProcessParent.cpp
+@@ -23,6 +23,7 @@ using std::string;
+
+ using mozilla::gmp::GMPProcessParent;
+ using mozilla::ipc::GeckoChildProcessHost;
++using base::ProcessArchitecture;
+
+ namespace mozilla {
+ namespace gmp {
+@@ -77,7 +78,7 @@ GMPProcessParent::Launch(int32_t aTimeoutMs)
+ args.push_back(mGMPPath);
+ #endif
+
+- return SyncLaunch(args, aTimeoutMs);
++ return SyncLaunch(args, aTimeoutMs, base::GetCurrentProcessArchitecture());
+ }
+
+ void
+diff --git a/dom/plugins/base/nsPluginsDirDarwin.cpp b/dom/plugins/base/nsPluginsDirDarwin.cpp
+index 11b46023f3fe..4fe96020ddda 100644
+--- a/dom/plugins/base/nsPluginsDirDarwin.cpp
++++ b/dom/plugins/base/nsPluginsDirDarwin.cpp
+@@ -65,6 +65,19 @@ static CFBundleRef getPluginBundle(const char* path)
+ return bundle;
+ }
+
++static nsresult toCFURLRef(nsIFile* file, CFURLRef& outURL)
++{
++ nsCOMPtr<nsILocalFileMac> lfm = do_QueryInterface(file);
++ if (!lfm)
++ return NS_ERROR_FAILURE;
++ CFURLRef url;
++ nsresult rv = lfm->GetCFURL(&url);
++ if (NS_SUCCEEDED(rv))
++ outURL = url;
++
++ return rv;
++}
++
+ bool nsPluginsDir::IsPluginFile(nsIFile* file)
+ {
+ nsCString fileName;
+@@ -352,6 +365,49 @@ static char* GetNextPluginStringFromHandle(Handle h, short *index)
+ return ret;
+ }
+
++static bool IsCompatibleArch(nsIFile *file)
++{
++ CFURLRef pluginURL = nullptr;
++ if (NS_FAILED(toCFURLRef(file, pluginURL)))
++ return false;
++
++ bool isPluginFile = false;
++
++ CFBundleRef pluginBundle = ::CFBundleCreate(kCFAllocatorDefault, pluginURL);
++ if (pluginBundle) {
++ UInt32 packageType, packageCreator;
++ ::CFBundleGetPackageInfo(pluginBundle, &packageType, &packageCreator);
++ if (packageType == 'BRPL' || packageType == 'IEPL' || packageType == 'NSPL') {
++ // Get path to plugin as a C string.
++ char executablePath[PATH_MAX];
++ executablePath[0] = '\0';
++ if (!::CFURLGetFileSystemRepresentation(pluginURL, true, (UInt8*)&executablePath, PATH_MAX)) {
++ executablePath[0] = '\0';
++ }
++
++ uint32_t pluginLibArchitectures;
++ nsresult rv = mozilla::ipc::GeckoChildProcessHost::GetArchitecturesForBinary(executablePath, &pluginLibArchitectures);
++ if (NS_FAILED(rv)) {
++ return false;
++ }
++
++ uint32_t supportedArchitectures =
++#ifdef __LP64__
++ mozilla::ipc::GeckoChildProcessHost::GetSupportedArchitecturesForProcessType(GeckoProcessType_Plugin);
++#else
++ base::GetCurrentProcessArchitecture();
++#endif
++
++ // Consider the plugin architecture valid if there is any overlap in the masks.
++ isPluginFile = !!(supportedArchitectures & pluginLibArchitectures);
++ }
++ ::CFRelease(pluginBundle);
++ }
++
++ ::CFRelease(pluginURL);
++ return isPluginFile;
++}
++
+ /**
+ * Obtains all of the information currently available for this plugin.
+ */
+@@ -361,6 +417,10 @@ nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info, PRLibrary **outLibrary)
+
+ nsresult rv = NS_OK;
+
++ if (!IsCompatibleArch(mPlugin)) {
++ return NS_ERROR_FAILURE;
++ }
++
+ // clear out the info, except for the first field.
+ memset(&info, 0, sizeof(info));
+
+diff --git a/dom/plugins/ipc/PluginProcessParent.cpp b/dom/plugins/ipc/PluginProcessParent.cpp
+index c652df36e285..e55d5378d99c 100644
+--- a/dom/plugins/ipc/PluginProcessParent.cpp
++++ b/dom/plugins/ipc/PluginProcessParent.cpp
+@@ -21,6 +21,7 @@ using mozilla::ipc::BrowserProcessSubThread;
+ using mozilla::ipc::GeckoChildProcessHost;
+ using mozilla::plugins::LaunchCompleteTask;
+ using mozilla::plugins::PluginProcessParent;
++using base::ProcessArchitecture;
+
+ #ifdef XP_WIN
+ PluginProcessParent::PidSet* PluginProcessParent::sPidSet = nullptr;
+@@ -63,12 +64,48 @@ PluginProcessParent::Launch(mozilla::UniquePtr<LaunchCompleteTask> aLaunchComple
+ }
+ #endif
+
++ ProcessArchitecture currentArchitecture = base::GetCurrentProcessArchitecture();
++ uint32_t containerArchitectures = GetSupportedArchitecturesForProcessType(GeckoProcessType_Plugin);
++
++ uint32_t pluginLibArchitectures = currentArchitecture;
++#ifdef XP_MACOSX
++ nsresult rv = GetArchitecturesForBinary(mPluginFilePath.c_str(), &pluginLibArchitectures);
++ if (NS_FAILED(rv)) {
++ // If the call failed just assume that we want the current architecture.
++ pluginLibArchitectures = currentArchitecture;
++ }
++#endif
++
++ ProcessArchitecture selectedArchitecture = currentArchitecture;
++ if (!(pluginLibArchitectures & containerArchitectures & currentArchitecture)) {
++ // Prefererence in order: x86_64, i386, PPC. The only particularly important thing
++ // about this order is that we'll prefer 64-bit architectures first.
++ if (base::PROCESS_ARCH_X86_64 & pluginLibArchitectures & containerArchitectures) {
++ selectedArchitecture = base::PROCESS_ARCH_X86_64;
++ }
++ else if (base::PROCESS_ARCH_I386 & pluginLibArchitectures & containerArchitectures) {
++ selectedArchitecture = base::PROCESS_ARCH_I386;
++ }
++ else if (base::PROCESS_ARCH_PPC & pluginLibArchitectures & containerArchitectures) {
++ selectedArchitecture = base::PROCESS_ARCH_PPC;
++ }
++ else if (base::PROCESS_ARCH_ARM & pluginLibArchitectures & containerArchitectures) {
++ selectedArchitecture = base::PROCESS_ARCH_ARM;
++ }
++ else if (base::PROCESS_ARCH_MIPS & pluginLibArchitectures & containerArchitectures) {
++ selectedArchitecture = base::PROCESS_ARCH_MIPS;
++ }
++ else {
++ return false;
++ }
++ }
++
+ mLaunchCompleteTask = mozilla::Move(aLaunchCompleteTask);
+
+ vector<string> args;
+ args.push_back(MungePluginDsoPath(mPluginFilePath));
+
+- bool result = AsyncLaunch(args);
++ bool result = AsyncLaunch(args, selectedArchitecture);
+ if (!result) {
+ mLaunchCompleteTask = nullptr;
+ }
+diff --git a/ipc/chromium/src/base/process_util.h b/ipc/chromium/src/base/process_util.h
+index 0bf4f5f25c55..42aa45ba1ff7 100644
+--- a/ipc/chromium/src/base/process_util.h
++++ b/ipc/chromium/src/base/process_util.h
+@@ -69,6 +69,35 @@ struct kinfo_proc;
+
+ namespace base {
+
++// These can be used in a 32-bit bitmask.
++enum ProcessArchitecture {
++ PROCESS_ARCH_I386 = 0x1,
++ PROCESS_ARCH_X86_64 = 0x2,
++ PROCESS_ARCH_PPC = 0x4,
++ PROCESS_ARCH_ARM = 0x8,
++ PROCESS_ARCH_MIPS = 0x10,
++ PROCESS_ARCH_ARM64 = 0x20
++};
++
++inline ProcessArchitecture GetCurrentProcessArchitecture()
++{
++ base::ProcessArchitecture currentArchitecture;
++#if defined(ARCH_CPU_X86)
++ currentArchitecture = base::PROCESS_ARCH_I386;
++#elif defined(ARCH_CPU_X86_64)
++ currentArchitecture = base::PROCESS_ARCH_X86_64;
++#elif defined(ARCH_CPU_PPC)
++ currentArchitecture = base::PROCESS_ARCH_PPC;
++#elif defined(ARCH_CPU_ARMEL)
++ currentArchitecture = base::PROCESS_ARCH_ARM;
++#elif defined(ARCH_CPU_MIPS)
++ currentArchitecture = base::PROCESS_ARCH_MIPS;
++#elif defined(ARCH_CPU_ARM64)
++ currentArchitecture = base::PROCESS_ARCH_ARM64;
++#endif
++ return currentArchitecture;
++}
++
+ // A minimalistic but hopefully cross-platform set of exit codes.
+ // Do not change the enumeration values or you will break third-party
+ // installers.
+@@ -152,19 +181,14 @@ typedef std::map<std::string, std::string> environment_map;
+ bool LaunchApp(const std::vector<std::string>& argv,
+ const file_handle_mapping_vector& fds_to_remap,
+ const environment_map& env_vars_to_set,
+- bool wait, ProcessHandle* process_handle);
+-
+-// Deleter for the array of strings allocated within BuildEnvironmentArray.
+-struct FreeEnvVarsArray
+-{
+- void operator()(char** array);
+-};
+-
+-typedef mozilla::UniquePtr<char*[], FreeEnvVarsArray> EnvironmentArray;
+-
+-// Merge an environment map with the current environment.
+-// Existing variables are overwritten by env_vars_to_set.
+-EnvironmentArray BuildEnvironmentArray(const environment_map& env_vars_to_set);
++ ChildPrivileges privs,
++ bool wait, ProcessHandle* process_handle,
++ ProcessArchitecture arch=GetCurrentProcessArchitecture());
++bool LaunchApp(const std::vector<std::string>& argv,
++ const file_handle_mapping_vector& fds_to_remap,
++ const environment_map& env_vars_to_set,
++ bool wait, ProcessHandle* process_handle,
++ ProcessArchitecture arch=GetCurrentProcessArchitecture());
+ #endif
+
+ // Adjust the privileges of this process to match |privs|. Only
+diff --git a/ipc/chromium/src/base/process_util_bsd.cc b/ipc/chromium/src/base/process_util_bsd.cc
+index a2260fc1c9e9..3f55ce86a1a6 100644
+--- a/ipc/chromium/src/base/process_util_bsd.cc
++++ b/ipc/chromium/src/base/process_util_bsd.cc
+@@ -43,7 +43,19 @@ bool LaunchApp(const std::vector<std::string>& argv,
+ bool LaunchApp(const std::vector<std::string>& argv,
+ const file_handle_mapping_vector& fds_to_remap,
+ const environment_map& env_vars_to_set,
+- bool wait, ProcessHandle* process_handle) {
++ bool wait, ProcessHandle* process_handle,
++ ProcessArchitecture arch) {
++ return LaunchApp(argv, fds_to_remap, env_vars_to_set,
++ PRIVILEGES_INHERIT,
++ wait, process_handle);
++}
++
++bool LaunchApp(const std::vector<std::string>& argv,
++ const file_handle_mapping_vector& fds_to_remap,
++ const environment_map& env_vars_to_set,
++ ChildPrivileges privs,
++ bool wait, ProcessHandle* process_handle,
++ ProcessArchitecture arch) {
+ bool retval = true;
+
+ char* argv_copy[argv.size() + 1];
+diff --git a/ipc/chromium/src/base/process_util_linux.cc b/ipc/chromium/src/base/process_util_linux.cc
+index f8cfb32fc160..d8dd245d368d 100644
+--- a/ipc/chromium/src/base/process_util_linux.cc
++++ b/ipc/chromium/src/base/process_util_linux.cc
+@@ -134,7 +134,19 @@ bool LaunchApp(const std::vector<std::string>& argv,
+ bool LaunchApp(const std::vector<std::string>& argv,
+ const file_handle_mapping_vector& fds_to_remap,
+ const environment_map& env_vars_to_set,
+- bool wait, ProcessHandle* process_handle) {
++ bool wait, ProcessHandle* process_handle,
++ ProcessArchitecture arch) {
++ return LaunchApp(argv, fds_to_remap, env_vars_to_set,
++ PRIVILEGES_INHERIT,
++ wait, process_handle);
++}
++
++bool LaunchApp(const std::vector<std::string>& argv,
++ const file_handle_mapping_vector& fds_to_remap,
++ const environment_map& env_vars_to_set,
++ ChildPrivileges privs,
++ bool wait, ProcessHandle* process_handle,
++ ProcessArchitecture arch) {
+ mozilla::UniquePtr<char*[]> argv_cstr(new char*[argv.size() + 1]);
+ // Illegal to allocate memory after fork and before execvp
+ InjectiveMultimap fd_shuffle1, fd_shuffle2;
+diff --git a/ipc/chromium/src/base/process_util_mac.mm b/ipc/chromium/src/base/process_util_mac.mm
+index fc708eab3110..7d06411b2565 100644
+--- a/ipc/chromium/src/base/process_util_mac.mm
++++ b/ipc/chromium/src/base/process_util_mac.mm
+@@ -44,7 +44,19 @@ bool LaunchApp(const std::vector<std::string>& argv,
+ bool LaunchApp(const std::vector<std::string>& argv,
+ const file_handle_mapping_vector& fds_to_remap,
+ const environment_map& env_vars_to_set,
+- bool wait, ProcessHandle* process_handle) {
++ bool wait, ProcessHandle* process_handle,
++ ProcessArchitecture arch) {
++ return LaunchApp(argv, fds_to_remap, env_vars_to_set,
++ PRIVILEGES_INHERIT,
++ wait, process_handle);
++}
++
++bool LaunchApp(const std::vector<std::string>& argv,
++ const file_handle_mapping_vector& fds_to_remap,
++ const environment_map& env_vars_to_set,
++ ChildPrivileges privs,
++ bool wait, ProcessHandle* process_handle,
++ ProcessArchitecture arch) {
+ bool retval = true;
+
+ char* argv_copy[argv.size() + 1];
+@@ -112,26 +124,40 @@ bool LaunchApp(const std::vector<std::string>& argv,
+ }
+ }
+
++ // Set up the CPU preference array.
++ cpu_type_t cpu_types[1];
++ switch (arch) {
++ case PROCESS_ARCH_I386:
++ cpu_types[0] = CPU_TYPE_X86;
++ break;
++ case PROCESS_ARCH_X86_64:
++ cpu_types[0] = CPU_TYPE_X86_64;
++ break;
++ case PROCESS_ARCH_PPC:
++ cpu_types[0] = CPU_TYPE_POWERPC;
++ break;
++ default:
++ cpu_types[0] = CPU_TYPE_ANY;
++ break;
++ }
++
++ // Initialize spawn attributes.
+ posix_spawnattr_t spawnattr;
+ if (posix_spawnattr_init(&spawnattr) != 0) {
+ FreeEnvVarsArray(vars, varsLen);
+ return false;
+ }
+
+- // Prevent the child process from inheriting any file descriptors
+- // that aren't named in `file_actions`. (This is an Apple-specific
+- // extension to posix_spawn.)
+- if (posix_spawnattr_setflags(&spawnattr, POSIX_SPAWN_CLOEXEC_DEFAULT) != 0) {
++ // Set spawn attributes.
++ size_t attr_count = 1;
++ size_t attr_ocount = 0;
++ if (posix_spawnattr_setbinpref_np(&spawnattr, attr_count, cpu_types, &attr_ocount) != 0 ||
++ attr_ocount != attr_count) {
++ FreeEnvVarsArray(vars, varsLen);
++ posix_spawnattr_destroy(&spawnattr);
+ return false;
+ }
+
+- // Exempt std{in,out,err} from being closed by POSIX_SPAWN_CLOEXEC_DEFAULT.
+- for (int fd = 0; fd <= STDERR_FILENO; ++fd) {
+- if (posix_spawn_file_actions_addinherit_np(&file_actions, fd) != 0) {
+- return false;
+- }
+- }
+-
+ int pid = 0;
+ int spawn_succeeded = (posix_spawnp(&pid,
+ argv_copy[0],
+diff --git a/ipc/glue/GeckoChildProcessHost.cpp b/ipc/glue/GeckoChildProcessHost.cpp
+index a35f6639b80d..dc9f811aee67 100644
+--- a/ipc/glue/GeckoChildProcessHost.cpp
++++ b/ipc/glue/GeckoChildProcessHost.cpp
+@@ -217,6 +217,77 @@ private:
+ };
+ #endif
+
++nsresult GeckoChildProcessHost::GetArchitecturesForBinary(const char *path, uint32_t *result)
++{
++ *result = 0;
++
++#ifdef MOZ_WIDGET_COCOA
++ CFURLRef url = ::CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
++ (const UInt8*)path,
++ strlen(path),
++ false);
++ if (!url) {
++ return NS_ERROR_FAILURE;
++ }
++ AutoCFTypeObject autoPluginContainerURL(url);
++
++ CFArrayRef pluginContainerArchs = ::CFBundleCopyExecutableArchitecturesForURL(url);
++ if (!pluginContainerArchs) {
++ return NS_ERROR_FAILURE;
++ }
++ AutoCFTypeObject autoPluginContainerArchs(pluginContainerArchs);
++
++ CFIndex pluginArchCount = ::CFArrayGetCount(pluginContainerArchs);
++ for (CFIndex i = 0; i < pluginArchCount; i++) {
++ CFNumberRef currentArch = static_cast<CFNumberRef>(::CFArrayGetValueAtIndex(pluginContainerArchs, i));
++ int currentArchInt = 0;
++ if (!::CFNumberGetValue(currentArch, kCFNumberIntType, &currentArchInt)) {
++ continue;
++ }
++ switch (currentArchInt) {
++ case kCFBundleExecutableArchitectureI386:
++ *result |= base::PROCESS_ARCH_I386;
++ break;
++ case kCFBundleExecutableArchitectureX86_64:
++ *result |= base::PROCESS_ARCH_X86_64;
++ break;
++ case kCFBundleExecutableArchitecturePPC:
++ *result |= base::PROCESS_ARCH_PPC;
++ break;
++ default:
++ break;
++ }
++ }
++
++ return (*result ? NS_OK : NS_ERROR_FAILURE);
++#else
++ return NS_ERROR_NOT_IMPLEMENTED;
++#endif
++}
++
++uint32_t GeckoChildProcessHost::GetSupportedArchitecturesForProcessType(GeckoProcessType type)
++{
++#ifdef MOZ_WIDGET_COCOA
++ if (type == GeckoProcessType_Plugin) {
++
++ // Cache this, it shouldn't ever change.
++ static uint32_t pluginContainerArchs = 0;
++ if (pluginContainerArchs == 0) {
++ FilePath exePath;
++ GetPathToBinary(exePath, type);
++ nsresult rv = GetArchitecturesForBinary(exePath.value().c_str(), &pluginContainerArchs);
++ NS_ASSERTION(NS_SUCCEEDED(rv) && pluginContainerArchs != 0, "Getting architecture of plugin container failed!");
++ if (NS_FAILED(rv) || pluginContainerArchs == 0) {
++ pluginContainerArchs = base::GetCurrentProcessArchitecture();
++ }
++ }
++ return pluginContainerArchs;
++ }
++#endif
++
++ return base::GetCurrentProcessArchitecture();
++}
++
+ // We start the unique IDs at 1 so that 0 can be used to mean that
+ // a component has no unique ID assigned to it.
+ uint32_t GeckoChildProcessHost::sNextUniqueID = 1;
+@@ -283,34 +354,39 @@ void GeckoChildProcessHost::InitWindowsGroupID()
+ #endif
+
+ bool
+-GeckoChildProcessHost::SyncLaunch(std::vector<std::string> aExtraOpts, int aTimeoutMs)
++GeckoChildProcessHost::SyncLaunch(std::vector<std::string> aExtraOpts, int aTimeoutMs, base::ProcessArchitecture arch)
+ {
+ PrepareLaunch();
+
+ MessageLoop* ioLoop = XRE_GetIOMessageLoop();
+ NS_ASSERTION(MessageLoop::current() != ioLoop, "sync launch from the IO thread NYI");
+
+- ioLoop->PostTask(NewNonOwningRunnableMethod<std::vector<std::string>>(
++ ioLoop->PostTask(NewNonOwningRunnableMethod<std::vector<std::string>,
++ base::ProcessArchitecture>(
+ "ipc::GeckoChildProcessHost::RunPerformAsyncLaunch",
+ this,
+ &GeckoChildProcessHost::RunPerformAsyncLaunch,
+- aExtraOpts));
++ aExtraOpts,
++ arch));
+
+ return WaitUntilConnected(aTimeoutMs);
+ }
+
+ bool
+-GeckoChildProcessHost::AsyncLaunch(std::vector<std::string> aExtraOpts)
++GeckoChildProcessHost::AsyncLaunch(std::vector<std::string> aExtraOpts,
++ base::ProcessArchitecture arch)
+ {
+ PrepareLaunch();
+
+ MessageLoop* ioLoop = XRE_GetIOMessageLoop();
+
+- ioLoop->PostTask(NewNonOwningRunnableMethod<std::vector<std::string>>(
++ ioLoop->PostTask(NewNonOwningRunnableMethod<std::vector<std::string>,
++ base::ProcessArchitecture>(
+ "ipc::GeckoChildProcessHost::RunPerformAsyncLaunch",
+ this,
+ &GeckoChildProcessHost::RunPerformAsyncLaunch,
+- aExtraOpts));
++ aExtraOpts,
++ arch));
+
+ // This may look like the sync launch wait, but we only delay as
+ // long as it takes to create the channel.
+@@ -366,11 +442,13 @@ GeckoChildProcessHost::LaunchAndWaitForProcessHandle(StringVector aExtraOpts)
+ PrepareLaunch();
+
+ MessageLoop* ioLoop = XRE_GetIOMessageLoop();
+- ioLoop->PostTask(NewNonOwningRunnableMethod<std::vector<std::string>>(
++ ioLoop->PostTask(NewNonOwningRunnableMethod<std::vector<std::string>,
++ base::ProcessArchitecture>(
+ "ipc::GeckoChildProcessHost::RunPerformAsyncLaunch",
+ this,
+ &GeckoChildProcessHost::RunPerformAsyncLaunch,
+- aExtraOpts));
++ aExtraOpts,
++ base::GetCurrentProcessArchitecture()));
+
+ MonitorAutoLock lock(mMonitor);
+ while (mProcessState < PROCESS_CREATED) {
+@@ -462,7 +540,7 @@ GeckoChildProcessHost::SetChildLogName(const char* varName, const char* origLogN
+ }
+
+ bool
+-GeckoChildProcessHost::PerformAsyncLaunch(std::vector<std::string> aExtraOpts)
++GeckoChildProcessHost::PerformAsyncLaunch(std::vector<std::string> aExtraOpts, base::ProcessArchitecture arch)
+ {
+ AutoSetProfilerEnvVarsForChildProcess profilerEnvironment;
+
+@@ -497,18 +575,7 @@ GeckoChildProcessHost::PerformAsyncLaunch(std::vector<std::string> aExtraOpts)
+ SetChildLogName("MOZ_LOG_FILE=", origMozLogName, mozLogName);
+ }
+
+- // `RUST_LOG_CHILD` is meant for logging child processes only.
+- // if (childRustLog) {
+- // if (mRestoreOrigRustLog.IsEmpty()) {
+- // mRestoreOrigRustLog.AssignLiteral("RUST_LOG=");
+- // mRestoreOrigRustLog.Append(origRustLog);
+- // }
+- // rustLog.AssignLiteral("RUST_LOG=");
+- // rustLog.Append(childRustLog);
+- // PR_SetEnv(rustLog.get());
+- // }
+-
+- bool retval = PerformAsyncLaunchInternal(aExtraOpts);
++ bool retval = PerformAsyncLaunchInternal(aExtraOpts, arch);
+
+ // Revert to original value
+ if (origNSPRLogName) {
+@@ -522,11 +589,12 @@ GeckoChildProcessHost::PerformAsyncLaunch(std::vector<std::string> aExtraOpts)
+ }
+
+ bool
+-GeckoChildProcessHost::RunPerformAsyncLaunch(std::vector<std::string> aExtraOpts)
++GeckoChildProcessHost::RunPerformAsyncLaunch(std::vector<std::string> aExtraOpts,
++ base::ProcessArchitecture aArch)
+ {
+ InitializeChannel();
+
+- bool ok = PerformAsyncLaunch(aExtraOpts);
++ bool ok = PerformAsyncLaunch(aExtraOpts, aArch);
+ if (!ok) {
+ // WaitUntilConnected might be waiting for us to signal.
+ // If something failed let's set the error state and notify.
+@@ -593,7 +661,7 @@ AddAppDirToCommandLine(std::vector<std::string>& aCmdLine)
+ }
+
+ bool
+-GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExtraOpts)
++GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExtraOpts, base::ProcessArchitecture arch)
+ {
+ // We rely on the fact that InitializeChannel() has already been processed
+ // on the IO thread before this point is reached.
+@@ -798,11 +866,11 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
+ LaunchAndroidService(childProcessType, childArgv, mFileMap, &process);
+ #else
+ base::LaunchApp(childArgv, mFileMap,
+-# if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_BSD) || defined(OS_SOLARIS)
+- newEnvVars,
+-# endif // defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_BSD) || defined(OS_SOLARIS)
+- false, &process);
+-# endif // defined(MOZ_WIDGET_ANDROID)
++#if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_BSD) || defined(OS_SOLARIS)
++ newEnvVars, privs,
++#endif
++ false, &process, arch);
++#endif // defined(MOZ_WIDGET_ANDROID)
+
+ // We're in the parent and the child was launched. Close the child FD in the
+ // parent as soon as possible, which will allow the parent to detect when the
+diff --git a/ipc/glue/GeckoChildProcessHost.h b/ipc/glue/GeckoChildProcessHost.h
+index 82e2a3c3f22d..8cf76f6019ec 100644
+--- a/ipc/glue/GeckoChildProcessHost.h
++++ b/ipc/glue/GeckoChildProcessHost.h
+@@ -45,12 +45,17 @@ public:
+
+ ~GeckoChildProcessHost();
+
++ static nsresult GetArchitecturesForBinary(const char *path, uint32_t *result);
++
++ static uint32_t GetSupportedArchitecturesForProcessType(GeckoProcessType type);
++
+ static uint32_t GetUniqueID();
+
+ // Block until the IPC channel for our subprocess is initialized,
+ // but no longer. The child process may or may not have been
+ // created when this method returns.
+- bool AsyncLaunch(StringVector aExtraOpts=StringVector());
++ bool AsyncLaunch(StringVector aExtraOpts=StringVector(),
++ base::ProcessArchitecture arch=base::GetCurrentProcessArchitecture());
+
+ virtual bool WaitUntilConnected(int32_t aTimeoutMs = 0);
+
+@@ -72,9 +77,11 @@ public:
+ // the IPC channel, meaning it's fully initialized. (Or until an
+ // error occurs.)
+ bool SyncLaunch(StringVector aExtraOpts=StringVector(),
+- int32_t timeoutMs=0);
++ int32_t timeoutMs=0,
++ base::ProcessArchitecture arch=base::GetCurrentProcessArchitecture());
+
+- virtual bool PerformAsyncLaunch(StringVector aExtraOpts=StringVector());
++ virtual bool PerformAsyncLaunch(StringVector aExtraOpts=StringVector(),
++ base::ProcessArchitecture aArch=base::GetCurrentProcessArchitecture());
+
+ virtual void OnChannelConnected(int32_t peer_pid);
+ virtual void OnMessageReceived(IPC::Message&& aMsg);
+@@ -170,9 +177,11 @@ private:
+ DISALLOW_EVIL_CONSTRUCTORS(GeckoChildProcessHost);
+
+ // Does the actual work for AsyncLaunch, on the IO thread.
+- bool PerformAsyncLaunchInternal(std::vector<std::string>& aExtraOpts);
++ bool PerformAsyncLaunchInternal(std::vector<std::string>& aExtraOpts,
++ base::ProcessArchitecture arch);
+
+- bool RunPerformAsyncLaunch(StringVector aExtraOpts=StringVector());
++ bool RunPerformAsyncLaunch(StringVector aExtraOpts=StringVector(),
++ base::ProcessArchitecture aArch=base::GetCurrentProcessArchitecture());
+
+ enum class BinaryPathType {
+ Self,
+--
+2.22.0
+
+
+From 420ed2883d28f00682ac08b2583c157793584a6f Mon Sep 17 00:00:00 2001
+From: Jed Davis <jld@mozilla.com>
+Date: Mon, 28 Aug 2017 12:45:29 -0600
+Subject: [PATCH 2/5] Bug 1397928 - Remove some unused type definitions from
+ process_util. r=billm
+
+MozReview-Commit-ID: I30AUWYOPwi
+---
+ ipc/chromium/src/base/process_util.h | 21 +--------------------
+ ipc/chromium/src/base/process_util_linux.cc | 5 -----
+ 2 files changed, 1 insertion(+), 25 deletions(-)
+
+diff --git a/ipc/chromium/src/base/process_util.h b/ipc/chromium/src/base/process_util.h
+index 42aa45ba1ff7..e75097e94aa0 100644
+--- a/ipc/chromium/src/base/process_util.h
++++ b/ipc/chromium/src/base/process_util.h
+@@ -40,26 +40,7 @@
+ #include "base/command_line.h"
+ #include "base/process.h"
+
+-#if defined(OS_WIN)
+-typedef PROCESSENTRY32 ProcessEntry;
+-typedef IO_COUNTERS IoCounters;
+-#elif defined(OS_POSIX)
+-// TODO(port): we should not rely on a Win32 structure.
+-struct ProcessEntry {
+- int pid;
+- int ppid;
+- char szExeFile[_POSIX_PATH_MAX + 1];
+-};
+-
+-struct IoCounters {
+- unsigned long long ReadOperationCount;
+- unsigned long long WriteOperationCount;
+- unsigned long long OtherOperationCount;
+- unsigned long long ReadTransferCount;
+- unsigned long long WriteTransferCount;
+- unsigned long long OtherTransferCount;
+-};
+-
++#if defined(OS_POSIX)
+ #include "base/file_descriptor_shuffle.h"
+ #endif
+
+diff --git a/ipc/chromium/src/base/process_util_linux.cc b/ipc/chromium/src/base/process_util_linux.cc
+index d8dd245d368d..a5b3e9d3b714 100644
+--- a/ipc/chromium/src/base/process_util_linux.cc
++++ b/ipc/chromium/src/base/process_util_linux.cc
+@@ -32,11 +32,6 @@
+
+ namespace {
+
+-enum ParsingState {
+- KEY_NAME,
+- KEY_VALUE
+-};
+-
+ static mozilla::EnvironmentLog gProcessLog("MOZ_PROCESS_LOG");
+
+ } // namespace
+--
+2.22.0
+
+
+From 87e23b1fc1416aac44526240766e51302b7fcc8d Mon Sep 17 00:00:00 2001
+From: Jed Davis <jld@mozilla.com>
+Date: Fri, 15 Sep 2017 11:18:43 -0600
+Subject: [PATCH 3/5] Bug 1259852 - Merge Linux/BSD/Mac child process
+ environment handling. r=billm f=jbeich
+
+This is mostly based on the BSD version, which in turn is more or less
+the Mac version minus some race conditions. The Linux version does
+something similar, but more verbosely and (at least in my opinion) is
+harder to follow. Some changes have been made, mainly to use C++11
+features like UniquePtr.
+
+MozReview-Commit-ID: 3Gv4DKCqWvu
+---
+ ipc/chromium/src/base/process_util.h | 14 +++
+ ipc/chromium/src/base/process_util_bsd.cc | 45 +--------
+ ipc/chromium/src/base/process_util_linux.cc | 102 +-------------------
+ ipc/chromium/src/base/process_util_mac.mm | 50 +---------
+ ipc/chromium/src/base/process_util_posix.cc | 42 ++++++++
+ 5 files changed, 65 insertions(+), 188 deletions(-)
+
+diff --git a/ipc/chromium/src/base/process_util.h b/ipc/chromium/src/base/process_util.h
+index e75097e94aa0..15ad66617730 100644
+--- a/ipc/chromium/src/base/process_util.h
++++ b/ipc/chromium/src/base/process_util.h
+@@ -44,6 +44,8 @@
+ #include "base/file_descriptor_shuffle.h"
+ #endif
+
++#include "mozilla/UniquePtr.h"
++
+ #if defined(OS_MACOSX)
+ struct kinfo_proc;
+ #endif
+@@ -170,6 +172,18 @@ bool LaunchApp(const std::vector<std::string>& argv,
+ const environment_map& env_vars_to_set,
+ bool wait, ProcessHandle* process_handle,
+ ProcessArchitecture arch=GetCurrentProcessArchitecture());
++
++// Deleter for the array of strings allocated within BuildEnvironmentArray.
++struct FreeEnvVarsArray
++{
++ void operator()(char** array);
++};
++
++typedef mozilla::UniquePtr<char*[], FreeEnvVarsArray> EnvironmentArray;
++
++// Merge an environment map with the current environment.
++// Existing variables are overwritten by env_vars_to_set.
++EnvironmentArray BuildEnvironmentArray(const environment_map& env_vars_to_set);
+ #endif
+
+ // Adjust the privileges of this process to match |privs|. Only
+diff --git a/ipc/chromium/src/base/process_util_bsd.cc b/ipc/chromium/src/base/process_util_bsd.cc
+index 3f55ce86a1a6..7392ace7cc41 100644
+--- a/ipc/chromium/src/base/process_util_bsd.cc
++++ b/ipc/chromium/src/base/process_util_bsd.cc
+@@ -14,7 +14,6 @@
+
+ #include <string>
+
+-#include "nspr.h"
+ #include "base/eintr_wrapper.h"
+
+ namespace {
+@@ -25,14 +24,6 @@ static mozilla::EnvironmentLog gProcessLog("MOZ_PROCESS_LOG");
+
+ namespace base {
+
+-void FreeEnvVarsArray(char* array[], int length)
+-{
+- for (int i = 0; i < length; i++) {
+- free(array[i]);
+- }
+- delete[] array;
+-}
+-
+ bool LaunchApp(const std::vector<std::string>& argv,
+ const file_handle_mapping_vector& fds_to_remap,
+ bool wait, ProcessHandle* process_handle) {
+@@ -68,39 +59,10 @@ bool LaunchApp(const std::vector<std::string>& argv,
+ // as close-on-exec.
+ SetAllFDsToCloseOnExec();
+
+- // Copy environment to a new char array and add the variables
+- // in env_vars_to_set.
+- // Existing variables are overwritten by env_vars_to_set.
+- int pos = 0;
+- environment_map combined_env_vars = env_vars_to_set;
+- char **environ = PR_DuplicateEnvironment();
+- while(environ[pos] != NULL) {
+- std::string varString = environ[pos];
+- std::string varName = varString.substr(0, varString.find_first_of('='));
+- std::string varValue = varString.substr(varString.find_first_of('=') + 1);
+- if (combined_env_vars.find(varName) == combined_env_vars.end()) {
+- combined_env_vars[varName] = varValue;
+- }
+- PR_Free(environ[pos++]); // PR_DuplicateEnvironment() uses PR_Malloc().
+- }
+- PR_Free(environ); // PR_DuplicateEnvironment() uses PR_Malloc().
+- int varsLen = combined_env_vars.size() + 1;
+-
+- char** vars = new char*[varsLen];
+- int i = 0;
+- for (environment_map::const_iterator it = combined_env_vars.begin();
+- it != combined_env_vars.end(); ++it) {
+- std::string entry(it->first);
+- entry += "=";
+- entry += it->second;
+- vars[i] = strdup(entry.c_str());
+- i++;
+- }
+- vars[i] = NULL;
++ EnvironmentArray vars = BuildEnvironmentArray(env_vars_to_set);
+
+ posix_spawn_file_actions_t file_actions;
+ if (posix_spawn_file_actions_init(&file_actions) != 0) {
+- FreeEnvVarsArray(vars, varsLen);
+ return false;
+ }
+
+@@ -119,7 +81,6 @@ bool LaunchApp(const std::vector<std::string>& argv,
+ } else {
+ if (posix_spawn_file_actions_adddup2(&file_actions, src_fd, dest_fd) != 0) {
+ posix_spawn_file_actions_destroy(&file_actions);
+- FreeEnvVarsArray(vars, varsLen);
+ return false;
+ }
+ }
+@@ -131,9 +92,7 @@ bool LaunchApp(const std::vector<std::string>& argv,
+ &file_actions,
+ NULL,
+ argv_copy,
+- vars) == 0);
+-
+- FreeEnvVarsArray(vars, varsLen);
++ vars.get()) == 0);
+
+ posix_spawn_file_actions_destroy(&file_actions);
+
+diff --git a/ipc/chromium/src/base/process_util_linux.cc b/ipc/chromium/src/base/process_util_linux.cc
+index a5b3e9d3b714..0c903e69da22 100644
+--- a/ipc/chromium/src/base/process_util_linux.cc
++++ b/ipc/chromium/src/base/process_util_linux.cc
+@@ -6,23 +6,16 @@
+
+ #include "base/process_util.h"
+
+-#include <ctype.h>
+-#include <fcntl.h>
+-#include <memory>
+-#include <unistd.h>
+ #include <string>
+ #include <sys/types.h>
+ #include <sys/wait.h>
++#include <unistd.h>
+
+ #include "base/eintr_wrapper.h"
+-#include "base/file_util.h"
+ #include "base/logging.h"
+-#include "base/string_util.h"
+-#include "nsLiteralString.h"
++#include "mozilla/Move.h"
+ #include "mozilla/UniquePtr.h"
+
+-#include "prenv.h"
+-
+ /*
+ * We fall back to an arbitrary UID. This is generally the UID for user
+ * `nobody', albeit it is not always the case.
+@@ -38,87 +31,6 @@ static mozilla::EnvironmentLog gProcessLog("MOZ_PROCESS_LOG");
+
+ namespace base {
+
+-class EnvironmentEnvp
+-{
+-public:
+- EnvironmentEnvp()
+- : mEnvp(PR_DuplicateEnvironment()) {}
+-
+- explicit EnvironmentEnvp(const environment_map &em)
+- {
+- mEnvp = (char**) malloc(sizeof(char *) * (em.size() + 1));
+- if (!mEnvp) {
+- return;
+- }
+- char **e = mEnvp;
+- for (environment_map::const_iterator it = em.begin();
+- it != em.end(); ++it, ++e) {
+- std::string str = it->first;
+- str += "=";
+- str += it->second;
+- size_t len = str.length() + 1;
+- *e = static_cast<char*>(malloc(len));
+- memcpy(*e, str.c_str(), len);
+- }
+- *e = NULL;
+- }
+-
+- ~EnvironmentEnvp()
+- {
+- if (!mEnvp) {
+- return;
+- }
+- for (char **e = mEnvp; *e; ++e) {
+- free(*e);
+- }
+- free(mEnvp);
+- }
+-
+- char * const *AsEnvp() { return mEnvp; }
+-
+- void ToMap(environment_map &em)
+- {
+- if (!mEnvp) {
+- return;
+- }
+- em.clear();
+- for (char **e = mEnvp; *e; ++e) {
+- const char *eq;
+- if ((eq = strchr(*e, '=')) != NULL) {
+- std::string varname(*e, eq - *e);
+- em[varname.c_str()] = &eq[1];
+- }
+- }
+- }
+-
+-private:
+- char **mEnvp;
+-};
+-
+-class Environment : public environment_map
+-{
+-public:
+- Environment()
+- {
+- EnvironmentEnvp envp;
+- envp.ToMap(*this);
+- }
+-
+- char * const *AsEnvp() {
+- mEnvp.reset(new EnvironmentEnvp(*this));
+- return mEnvp->AsEnvp();
+- }
+-
+- void Merge(const environment_map &em)
+- {
+- for (const_iterator it = em.begin(); it != em.end(); ++it) {
+- (*this)[it->first] = it->second;
+- }
+- }
+-private:
+- std::auto_ptr<EnvironmentEnvp> mEnvp;
+-};
+-
+ bool LaunchApp(const std::vector<std::string>& argv,
+ const file_handle_mapping_vector& fds_to_remap,
+ bool wait, ProcessHandle* process_handle) {
+@@ -148,13 +60,7 @@ bool LaunchApp(const std::vector<std::string>& argv,
+ fd_shuffle1.reserve(fds_to_remap.size());
+ fd_shuffle2.reserve(fds_to_remap.size());
+
+- Environment env;
+- env.Merge(env_vars_to_set);
+- char * const *envp = env.AsEnvp();
+- if (!envp) {
+- DLOG(ERROR) << "FAILED to duplicate environment for: " << argv_cstr[0];
+- return false;
+- }
++ EnvironmentArray envp = BuildEnvironmentArray(env_vars_to_set);
+
+ pid_t pid = fork();
+ if (pid < 0)
+@@ -178,7 +84,7 @@ bool LaunchApp(const std::vector<std::string>& argv,
+
+ SetCurrentProcessPrivileges(privs);
+
+- execve(argv_cstr[0], argv_cstr.get(), envp);
++ execve(argv_cstr[0], argv_cstr.get(), envp.get());
+ // if we get here, we're in serious trouble and should complain loudly
+ // NOTE: This is async signal unsafe; it could deadlock instead. (But
+ // only on debug builds; otherwise it's a signal-safe no-op.)
+diff --git a/ipc/chromium/src/base/process_util_mac.mm b/ipc/chromium/src/base/process_util_mac.mm
+index 7d06411b2565..0a3ff6fab557 100644
+--- a/ipc/chromium/src/base/process_util_mac.mm
++++ b/ipc/chromium/src/base/process_util_mac.mm
+@@ -5,8 +5,7 @@
+
+ #include "base/process_util.h"
+
+-#import <Cocoa/Cocoa.h>
+-#include <crt_externs.h>
++#include <fcntl.h>
+ #include <spawn.h>
+ #include <sys/wait.h>
+
+@@ -14,9 +13,6 @@
+
+ #include "base/eintr_wrapper.h"
+ #include "base/logging.h"
+-#include "base/rand_util.h"
+-#include "base/string_util.h"
+-#include "base/time.h"
+
+ namespace {
+
+@@ -26,14 +22,6 @@ static mozilla::EnvironmentLog gProcessLog("MOZ_PROCESS_LOG");
+
+ namespace base {
+
+-void FreeEnvVarsArray(char* array[], int length)
+-{
+- for (int i = 0; i < length; i++) {
+- free(array[i]);
+- }
+- delete[] array;
+-}
+-
+ bool LaunchApp(const std::vector<std::string>& argv,
+ const file_handle_mapping_vector& fds_to_remap,
+ bool wait, ProcessHandle* process_handle) {
+@@ -69,37 +57,10 @@ bool LaunchApp(const std::vector<std::string>& argv,
+ // as close-on-exec.
+ SetAllFDsToCloseOnExec();
+
+- // Copy _NSGetEnviron() to a new char array and add the variables
+- // in env_vars_to_set.
+- // Existing variables are overwritten by env_vars_to_set.
+- int pos = 0;
+- environment_map combined_env_vars = env_vars_to_set;
+- while((*_NSGetEnviron())[pos] != NULL) {
+- std::string varString = (*_NSGetEnviron())[pos];
+- std::string varName = varString.substr(0, varString.find_first_of('='));
+- std::string varValue = varString.substr(varString.find_first_of('=') + 1);
+- if (combined_env_vars.find(varName) == combined_env_vars.end()) {
+- combined_env_vars[varName] = varValue;
+- }
+- pos++;
+- }
+- int varsLen = combined_env_vars.size() + 1;
+-
+- char** vars = new char*[varsLen];
+- int i = 0;
+- for (environment_map::const_iterator it = combined_env_vars.begin();
+- it != combined_env_vars.end(); ++it) {
+- std::string entry(it->first);
+- entry += "=";
+- entry += it->second;
+- vars[i] = strdup(entry.c_str());
+- i++;
+- }
+- vars[i] = NULL;
++ EnvironmentArray vars = BuildEnvironmentArray(env_vars_to_set);
+
+ posix_spawn_file_actions_t file_actions;
+ if (posix_spawn_file_actions_init(&file_actions) != 0) {
+- FreeEnvVarsArray(vars, varsLen);
+ return false;
+ }
+
+@@ -118,7 +79,6 @@ bool LaunchApp(const std::vector<std::string>& argv,
+ } else {
+ if (posix_spawn_file_actions_adddup2(&file_actions, src_fd, dest_fd) != 0) {
+ posix_spawn_file_actions_destroy(&file_actions);
+- FreeEnvVarsArray(vars, varsLen);
+ return false;
+ }
+ }
+@@ -144,7 +104,6 @@ bool LaunchApp(const std::vector<std::string>& argv,
+ // Initialize spawn attributes.
+ posix_spawnattr_t spawnattr;
+ if (posix_spawnattr_init(&spawnattr) != 0) {
+- FreeEnvVarsArray(vars, varsLen);
+ return false;
+ }
+
+@@ -153,7 +112,6 @@ bool LaunchApp(const std::vector<std::string>& argv,
+ size_t attr_ocount = 0;
+ if (posix_spawnattr_setbinpref_np(&spawnattr, attr_count, cpu_types, &attr_ocount) != 0 ||
+ attr_ocount != attr_count) {
+- FreeEnvVarsArray(vars, varsLen);
+ posix_spawnattr_destroy(&spawnattr);
+ return false;
+ }
+@@ -164,9 +122,7 @@ bool LaunchApp(const std::vector<std::string>& argv,
+ &file_actions,
+ &spawnattr,
+ argv_copy,
+- vars) == 0);
+-
+- FreeEnvVarsArray(vars, varsLen);
++ vars.get()) == 0);
+
+ posix_spawn_file_actions_destroy(&file_actions);
+
+diff --git a/ipc/chromium/src/base/process_util_posix.cc b/ipc/chromium/src/base/process_util_posix.cc
+index 7a1a8c325b52..ac103003c2d3 100644
+--- a/ipc/chromium/src/base/process_util_posix.cc
++++ b/ipc/chromium/src/base/process_util_posix.cc
+@@ -29,6 +29,9 @@
+ #include "base/dir_reader_posix.h"
+
+ #include "mozilla/UniquePtr.h"
++// For PR_DuplicateEnvironment:
++#include "prenv.h"
++#include "prmem.h"
+
+ const int kMicrosecondsPerSecond = 1000000;
+
+@@ -353,4 +356,43 @@ int ProcessMetrics::GetCPUUsage() {
+ return cpu;
+ }
+
++void
++FreeEnvVarsArray::operator()(char** array)
++{
++ for (char** varPtr = array; *varPtr != nullptr; ++varPtr) {
++ free(*varPtr);
++ }
++ delete[] array;
++}
++
++EnvironmentArray
++BuildEnvironmentArray(const environment_map& env_vars_to_set)
++{
++ base::environment_map combined_env_vars = env_vars_to_set;
++ char **environ = PR_DuplicateEnvironment();
++ for (char** varPtr = environ; *varPtr != nullptr; ++varPtr) {
++ std::string varString = *varPtr;
++ size_t equalPos = varString.find_first_of('=');
++ std::string varName = varString.substr(0, equalPos);
++ std::string varValue = varString.substr(equalPos + 1);
++ if (combined_env_vars.find(varName) == combined_env_vars.end()) {
++ combined_env_vars[varName] = varValue;
++ }
++ PR_Free(*varPtr); // PR_DuplicateEnvironment() uses PR_Malloc().
++ }
++ PR_Free(environ); // PR_DuplicateEnvironment() uses PR_Malloc().
++
++ EnvironmentArray array(new char*[combined_env_vars.size() + 1]);
++ size_t i = 0;
++ for (const auto& key_val : combined_env_vars) {
++ std::string entry(key_val.first);
++ entry += "=";
++ entry += key_val.second;
++ array[i] = strdup(entry.c_str());
++ i++;
++ }
++ array[i] = nullptr;
++ return array;
++}
++
+ } // namespace base
+--
+2.22.0
+
+
+From 8f63ee30a1574755709844bcf35b3f256449f728 Mon Sep 17 00:00:00 2001
+From: hawkeye116477 <hawkeye116477@gmail.com>
+Date: Wed, 21 Aug 2019 10:39:17 +0200
+Subject: [PATCH 4/5] Bug 1316153 - Remove base::ChildPrivileges from IPC.
+
+ChildPrivileges is a leftover from the B2G process model; it's now mostly unused, except for the Windows sandbox using it to carry whether a content process has file:/// access.
+In general, when sandboxing needs to interact with process launch, the inputs are some subset of: the GeckoProcessType, the subtype if content, various prefs and even GPU configuration; and the resulting launch adjustments are platform-specific. And on some platforms (e.g., OS X)it's all done after launch. So a simple enum used cross-platform isn't a good fit.
+---
+ dom/ipc/ContentParent.cpp | 7 +---
+ dom/ipc/PContent.ipdl | 1 -
+ ipc/chromium/moz.build | 4 --
+ ipc/chromium/src/base/child_privileges.h | 23 -----------
+ ipc/chromium/src/base/process_util.h | 11 ------
+ ipc/chromium/src/base/process_util_bsd.cc | 15 --------
+ ipc/chromium/src/base/process_util_linux.cc | 38 -------------------
+ ipc/chromium/src/base/process_util_mac.mm | 15 --------
+ ipc/chromium/src/base/process_util_win.cc | 4 --
+ ipc/glue/GeckoChildProcessHost.cpp | 25 ++----------
+ ipc/glue/GeckoChildProcessHost.h | 7 +---
+ ipc/glue/IPCMessageUtils.h | 7 ----
+ .../win/src/sandboxbroker/sandboxBroker.cpp | 10 ++---
+ .../win/src/sandboxbroker/sandboxBroker.h | 4 +-
+ 14 files changed, 14 insertions(+), 157 deletions(-)
+ delete mode 100644 ipc/chromium/src/base/child_privileges.h
+
+diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp
+index 2097b0f5e380..df45fdd5c4e9 100644
+--- a/dom/ipc/ContentParent.cpp
++++ b/dom/ipc/ContentParent.cpp
+@@ -268,7 +268,6 @@ static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
+ extern const char* kForceEnableE10sPref;
+ #endif
+
+-using base::ChildPrivileges;
+ using base::KillProcess;
+
+ #ifdef MOZ_CRASHREPORTER
+@@ -2140,10 +2139,8 @@ ContentParent::ContentParent(ContentParent* aOpener,
+ #endif
+
+ NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+- ChildPrivileges privs = mRemoteType.EqualsLiteral(FILE_REMOTE_TYPE)
+- ? base::PRIVILEGES_FILEREAD
+- : base::PRIVILEGES_DEFAULT;
+- mSubprocess = new GeckoChildProcessHost(GeckoProcessType_Content, privs);
++ bool isFile = mRemoteType.EqualsLiteral(FILE_REMOTE_TYPE);
++ mSubprocess = new GeckoChildProcessHost(GeckoProcessType_Content, isFile);
+ }
+
+ ContentParent::~ContentParent()
+diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl
+index 6f3096a12c5b..6d4646e6cb1a 100644
+--- a/dom/ipc/PContent.ipdl
++++ b/dom/ipc/PContent.ipdl
+@@ -70,7 +70,6 @@ using AlertNotificationType from "mozilla/AlertNotificationIPCSerializer.h";
+ using struct ChromePackage from "mozilla/chrome/RegistryMessageUtils.h";
+ using struct SubstitutionMapping from "mozilla/chrome/RegistryMessageUtils.h";
+ using struct OverrideMapping from "mozilla/chrome/RegistryMessageUtils.h";
+-using base::ChildPrivileges from "base/process_util.h";
+ using base::ProcessId from "base/process.h";
+ using struct IPC::Permission from "mozilla/net/NeckoMessageUtils.h";
+ using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h";
+diff --git a/ipc/chromium/moz.build b/ipc/chromium/moz.build
+index d85366c6d9f3..5a95910b98bc 100644
+--- a/ipc/chromium/moz.build
++++ b/ipc/chromium/moz.build
+@@ -58,10 +58,6 @@ if os_win:
+ 'src/chrome/common/transport_dib_win.cc',
+ ]
+
+- EXPORTS.base += [
+- 'src/base/child_privileges.h',
+- ]
+-
+ elif not CONFIG['MOZ_SYSTEM_LIBEVENT']:
+ DIRS += ['src/third_party']
+
+diff --git a/ipc/chromium/src/base/child_privileges.h b/ipc/chromium/src/base/child_privileges.h
+deleted file mode 100644
+index 0a34d93f5dfc..000000000000
+--- a/ipc/chromium/src/base/child_privileges.h
++++ /dev/null
+@@ -1,23 +0,0 @@
+-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+-/* vim: set ts=2 et sw=2 tw=80: */
+-/* This Source Code Form is subject to the terms of the Mozilla Public
+- * License, v. 2.0. If a copy of the MPL was not distributed with this
+- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+-
+-#ifndef BASE_CHILD_PRIVILEGS_H_
+-#define BASE_CHILD_PRIVILEGS_H_
+-
+-namespace base {
+-
+-enum ChildPrivileges {
+- PRIVILEGES_DEFAULT,
+- PRIVILEGES_UNPRIVILEGED,
+- PRIVILEGES_INHERIT,
+- // PRIVILEGES_DEFAULT plus file read permissions, used for file content process.
+- PRIVILEGES_FILEREAD,
+- PRIVILEGES_LAST
+-};
+-
+-} // namespace base
+-
+-#endif // BASE_CHILD_PRIVILEGS_H_
+diff --git a/ipc/chromium/src/base/process_util.h b/ipc/chromium/src/base/process_util.h
+index 15ad66617730..32b1c803c2bf 100644
+--- a/ipc/chromium/src/base/process_util.h
++++ b/ipc/chromium/src/base/process_util.h
+@@ -36,7 +36,6 @@
+ #include <unistd.h>
+ #endif
+
+-#include "base/child_privileges.h"
+ #include "base/command_line.h"
+ #include "base/process.h"
+
+@@ -161,12 +160,6 @@ bool LaunchApp(const std::vector<std::string>& argv,
+ bool wait, ProcessHandle* process_handle);
+
+ typedef std::map<std::string, std::string> environment_map;
+-bool LaunchApp(const std::vector<std::string>& argv,
+- const file_handle_mapping_vector& fds_to_remap,
+- const environment_map& env_vars_to_set,
+- ChildPrivileges privs,
+- bool wait, ProcessHandle* process_handle,
+- ProcessArchitecture arch=GetCurrentProcessArchitecture());
+ bool LaunchApp(const std::vector<std::string>& argv,
+ const file_handle_mapping_vector& fds_to_remap,
+ const environment_map& env_vars_to_set,
+@@ -186,10 +179,6 @@ typedef mozilla::UniquePtr<char*[], FreeEnvVarsArray> EnvironmentArray;
+ EnvironmentArray BuildEnvironmentArray(const environment_map& env_vars_to_set);
+ #endif
+
+-// Adjust the privileges of this process to match |privs|. Only
+-// returns if privileges were successfully adjusted.
+-void SetCurrentProcessPrivileges(ChildPrivileges privs);
+-
+ // Executes the application specified by cl. This function delegates to one
+ // of the above two platform-specific functions.
+ bool LaunchApp(const CommandLine& cl,
+diff --git a/ipc/chromium/src/base/process_util_bsd.cc b/ipc/chromium/src/base/process_util_bsd.cc
+index 7392ace7cc41..cb7086ccd60a 100644
+--- a/ipc/chromium/src/base/process_util_bsd.cc
++++ b/ipc/chromium/src/base/process_util_bsd.cc
+@@ -36,17 +36,6 @@ bool LaunchApp(const std::vector<std::string>& argv,
+ const environment_map& env_vars_to_set,
+ bool wait, ProcessHandle* process_handle,
+ ProcessArchitecture arch) {
+- return LaunchApp(argv, fds_to_remap, env_vars_to_set,
+- PRIVILEGES_INHERIT,
+- wait, process_handle);
+-}
+-
+-bool LaunchApp(const std::vector<std::string>& argv,
+- const file_handle_mapping_vector& fds_to_remap,
+- const environment_map& env_vars_to_set,
+- ChildPrivileges privs,
+- bool wait, ProcessHandle* process_handle,
+- ProcessArchitecture arch) {
+ bool retval = true;
+
+ char* argv_copy[argv.size() + 1];
+@@ -119,8 +108,4 @@ bool LaunchApp(const CommandLine& cl,
+ return LaunchApp(cl.argv(), no_files, wait, process_handle);
+ }
+
+-void SetCurrentProcessPrivileges(ChildPrivileges privs) {
+-
+-}
+-
+ } // namespace base
+diff --git a/ipc/chromium/src/base/process_util_linux.cc b/ipc/chromium/src/base/process_util_linux.cc
+index 0c903e69da22..103c4f5ec5b6 100644
+--- a/ipc/chromium/src/base/process_util_linux.cc
++++ b/ipc/chromium/src/base/process_util_linux.cc
+@@ -16,13 +16,6 @@
+ #include "mozilla/Move.h"
+ #include "mozilla/UniquePtr.h"
+
+-/*
+- * We fall back to an arbitrary UID. This is generally the UID for user
+- * `nobody', albeit it is not always the case.
+- */
+-# define CHILD_UNPRIVILEGED_UID 65534
+-# define CHILD_UNPRIVILEGED_GID 65534
+-
+ namespace {
+
+ static mozilla::EnvironmentLog gProcessLog("MOZ_PROCESS_LOG");
+@@ -43,17 +36,6 @@ bool LaunchApp(const std::vector<std::string>& argv,
+ const environment_map& env_vars_to_set,
+ bool wait, ProcessHandle* process_handle,
+ ProcessArchitecture arch) {
+- return LaunchApp(argv, fds_to_remap, env_vars_to_set,
+- PRIVILEGES_INHERIT,
+- wait, process_handle);
+-}
+-
+-bool LaunchApp(const std::vector<std::string>& argv,
+- const file_handle_mapping_vector& fds_to_remap,
+- const environment_map& env_vars_to_set,
+- ChildPrivileges privs,
+- bool wait, ProcessHandle* process_handle,
+- ProcessArchitecture arch) {
+ mozilla::UniquePtr<char*[]> argv_cstr(new char*[argv.size() + 1]);
+ // Illegal to allocate memory after fork and before execvp
+ InjectiveMultimap fd_shuffle1, fd_shuffle2;
+@@ -82,8 +64,6 @@ bool LaunchApp(const std::vector<std::string>& argv,
+ argv_cstr[i] = const_cast<char*>(argv[i].c_str());
+ argv_cstr[argv.size()] = NULL;
+
+- SetCurrentProcessPrivileges(privs);
+-
+ execve(argv_cstr[0], argv_cstr.get(), envp.get());
+ // if we get here, we're in serious trouble and should complain loudly
+ // NOTE: This is async signal unsafe; it could deadlock instead. (But
+@@ -110,23 +90,5 @@ bool LaunchApp(const CommandLine& cl,
+ return LaunchApp(cl.argv(), no_files, wait, process_handle);
+ }
+
+-void SetCurrentProcessPrivileges(ChildPrivileges privs) {
+- if (privs == PRIVILEGES_INHERIT) {
+- return;
+- }
+-
+- gid_t gid = CHILD_UNPRIVILEGED_GID;
+- uid_t uid = CHILD_UNPRIVILEGED_UID;
+- if (setgid(gid) != 0) {
+- DLOG(ERROR) << "FAILED TO setgid() CHILD PROCESS";
+- _exit(127);
+- }
+- if (setuid(uid) != 0) {
+- DLOG(ERROR) << "FAILED TO setuid() CHILD PROCESS";
+- _exit(127);
+- }
+- if (chdir("/") != 0)
+- gProcessLog.print("==> could not chdir()\n");
+-}
+
+ } // namespace base
+diff --git a/ipc/chromium/src/base/process_util_mac.mm b/ipc/chromium/src/base/process_util_mac.mm
+index 0a3ff6fab557..1b332d0edabb 100644
+--- a/ipc/chromium/src/base/process_util_mac.mm
++++ b/ipc/chromium/src/base/process_util_mac.mm
+@@ -34,17 +34,6 @@ bool LaunchApp(const std::vector<std::string>& argv,
+ const environment_map& env_vars_to_set,
+ bool wait, ProcessHandle* process_handle,
+ ProcessArchitecture arch) {
+- return LaunchApp(argv, fds_to_remap, env_vars_to_set,
+- PRIVILEGES_INHERIT,
+- wait, process_handle);
+-}
+-
+-bool LaunchApp(const std::vector<std::string>& argv,
+- const file_handle_mapping_vector& fds_to_remap,
+- const environment_map& env_vars_to_set,
+- ChildPrivileges privs,
+- bool wait, ProcessHandle* process_handle,
+- ProcessArchitecture arch) {
+ bool retval = true;
+
+ char* argv_copy[argv.size() + 1];
+@@ -151,8 +140,4 @@ bool LaunchApp(const CommandLine& cl,
+ return LaunchApp(cl.argv(), no_files, wait, process_handle);
+ }
+
+-void SetCurrentProcessPrivileges(ChildPrivileges privs) {
+-
+-}
+-
+ } // namespace base
+diff --git a/ipc/chromium/src/base/process_util_win.cc b/ipc/chromium/src/base/process_util_win.cc
+index fcac62efc6b2..1b8f6158c0f2 100644
+--- a/ipc/chromium/src/base/process_util_win.cc
++++ b/ipc/chromium/src/base/process_util_win.cc
+@@ -401,10 +401,6 @@ bool DidProcessCrash(bool* child_exited, ProcessHandle handle) {
+ return true;
+ }
+
+-void SetCurrentProcessPrivileges(ChildPrivileges privs) {
+-
+-}
+-
+ ///////////////////////////////////////////////////////////////////////////////
+ // ProcesMetrics
+
+diff --git a/ipc/glue/GeckoChildProcessHost.cpp b/ipc/glue/GeckoChildProcessHost.cpp
+index dc9f811aee67..9271c7573875 100644
+--- a/ipc/glue/GeckoChildProcessHost.cpp
++++ b/ipc/glue/GeckoChildProcessHost.cpp
+@@ -75,28 +75,16 @@ using mozilla::ipc::GeckoChildProcessHost;
+ #include "mozilla/jni/Utils.h"
+ #endif
+
+-// We currently don't drop privileges on any platform, because we have to worry
+-// about plugins and extensions breaking.
+-static const bool kLowRightsSubprocesses = false;
+-
+ static bool
+ ShouldHaveDirectoryService()
+ {
+ return GeckoProcessType_Default == XRE_GetProcessType();
+ }
+
+-/*static*/
+-base::ChildPrivileges
+-GeckoChildProcessHost::DefaultChildPrivileges()
+-{
+- return (kLowRightsSubprocesses ?
+- base::PRIVILEGES_UNPRIVILEGED : base::PRIVILEGES_INHERIT);
+-}
+-
+ GeckoChildProcessHost::GeckoChildProcessHost(GeckoProcessType aProcessType,
+- ChildPrivileges aPrivileges)
++ bool aIsFileContent)
+ : mProcessType(aProcessType),
+- mPrivileges(aPrivileges),
++ mIsFileContent(aIsFileContent),
+ mMonitor("mozilla.ipc.GeckChildProcessHost.mMonitor"),
+ mProcessState(CREATING_CHANNEL),
+ #if defined(MOZ_SANDBOX) && defined(XP_WIN)
+@@ -689,11 +677,6 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
+
+ #if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_BSD) || defined(OS_SOLARIS)
+ base::environment_map newEnvVars;
+- ChildPrivileges privs = mPrivileges;
+- if (privs == base::PRIVILEGES_DEFAULT ||
+- privs == base::PRIVILEGES_FILEREAD) {
+- privs = DefaultChildPrivileges();
+- }
+
+ #if defined(MOZ_WIDGET_GTK)
+ if (mProcessType == GeckoProcessType_Content) {
+@@ -867,7 +850,7 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
+ #else
+ base::LaunchApp(childArgv, mFileMap,
+ #if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_BSD) || defined(OS_SOLARIS)
+- newEnvVars, privs,
++ newEnvVars,
+ #endif
+ false, &process, arch);
+ #endif // defined(MOZ_WIDGET_ANDROID)
+@@ -993,7 +976,7 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
+ // and just crash there right away. Should this change in the future then we
+ // should also handle the error here.
+ mSandboxBroker.SetSecurityLevelForContentProcess(mSandboxLevel,
+- mPrivileges);
++ mIsFileContent);
+ shouldSandboxCurrentProcess = true;
+ }
+ #endif // MOZ_CONTENT_SANDBOX
+diff --git a/ipc/glue/GeckoChildProcessHost.h b/ipc/glue/GeckoChildProcessHost.h
+index 8cf76f6019ec..9b65d77a2e9b 100644
+--- a/ipc/glue/GeckoChildProcessHost.h
++++ b/ipc/glue/GeckoChildProcessHost.h
+@@ -35,13 +35,10 @@ protected:
+ typedef std::vector<std::string> StringVector;
+
+ public:
+- typedef base::ChildPrivileges ChildPrivileges;
+ typedef base::ProcessHandle ProcessHandle;
+
+- static ChildPrivileges DefaultChildPrivileges();
+-
+ explicit GeckoChildProcessHost(GeckoProcessType aProcessType,
+- ChildPrivileges aPrivileges=base::PRIVILEGES_DEFAULT);
++ bool aIsFileContent = false);
+
+ ~GeckoChildProcessHost();
+
+@@ -125,7 +122,7 @@ public:
+
+ protected:
+ GeckoProcessType mProcessType;
+- ChildPrivileges mPrivileges;
++ bool mIsFileContent;
+ Monitor mMonitor;
+ FilePath mProcessPath;
+
+diff --git a/ipc/glue/IPCMessageUtils.h b/ipc/glue/IPCMessageUtils.h
+index 6d62cc25dd0c..b3065e25ab66 100644
+--- a/ipc/glue/IPCMessageUtils.h
++++ b/ipc/glue/IPCMessageUtils.h
+@@ -261,13 +261,6 @@ struct BitFlagsEnumSerializer
+ BitFlagsEnumValidator<E, AllBits>>
+ {};
+
+-template <>
+-struct ParamTraits<base::ChildPrivileges>
+- : public ContiguousEnumSerializer<base::ChildPrivileges,
+- base::PRIVILEGES_DEFAULT,
+- base::PRIVILEGES_LAST>
+-{ };
+-
+ /**
+ * A helper class for serializing plain-old data (POD) structures.
+ * The memory representation of the structure is written to and read from
+diff --git a/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp b/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp
+index b829f7e2d79d..b86492b47450 100644
+--- a/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp
++++ b/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp
+@@ -319,7 +319,7 @@ SetJobLevel(sandbox::TargetPolicy* aPolicy, sandbox::JobLevel aJobLevel,
+
+ void
+ SandboxBroker::SetSecurityLevelForContentProcess(int32_t aSandboxLevel,
+- base::ChildPrivileges aPrivs)
++ bool aIsFileProcess)
+ {
+ MOZ_RELEASE_ASSERT(mPolicy, "mPolicy must be set before this call.");
+
+@@ -359,8 +359,9 @@ SandboxBroker::SetSecurityLevelForContentProcess(int32_t aSandboxLevel,
+ delayedIntegrityLevel = sandbox::INTEGRITY_LEVEL_LOW;
+ }
+
+- // If PRIVILEGES_FILEREAD required, don't allow settings that block reads.
+- if (aPrivs == base::ChildPrivileges::PRIVILEGES_FILEREAD) {
++ // If the process will handle file: URLs, don't allow settings that
++ // block reads.
++ if (aIsFileProcess) {
+ if (accessTokenLevel < sandbox::USER_NON_ADMIN) {
+ accessTokenLevel = sandbox::USER_NON_ADMIN;
+ }
+@@ -433,8 +434,7 @@ SandboxBroker::SetSecurityLevelForContentProcess(int32_t aSandboxLevel,
+
+ // We still have edge cases where the child at low integrity can't read some
+ // files, so add a rule to allow read access to everything when required.
+- if (aSandboxLevel == 1 ||
+- aPrivs == base::ChildPrivileges::PRIVILEGES_FILEREAD) {
++ if (aSandboxLevel == 1 || aIsFileProcess) {
+ result = mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
+ sandbox::TargetPolicy::FILES_ALLOW_READONLY,
+ L"*");
+diff --git a/security/sandbox/win/src/sandboxbroker/sandboxBroker.h b/security/sandbox/win/src/sandboxbroker/sandboxBroker.h
+index 9a224438173b..4f3ae1166ebb 100644
+--- a/security/sandbox/win/src/sandboxbroker/sandboxBroker.h
++++ b/security/sandbox/win/src/sandboxbroker/sandboxBroker.h
+@@ -10,8 +10,6 @@
+ #include <stdint.h>
+ #include <windows.h>
+
+-#include "base/child_privileges.h"
+-
+ namespace sandbox {
+ class BrokerServices;
+ class TargetPolicy;
+@@ -41,7 +39,7 @@ public:
+ // Security levels for different types of processes
+ #if defined(MOZ_CONTENT_SANDBOX)
+ void SetSecurityLevelForContentProcess(int32_t aSandboxLevel,
+- base::ChildPrivileges aPrivs);
++ bool aIsFileProcess);
+ #endif
+
+ void SetSecurityLevelForGPUProcess(int32_t aSandboxLevel);
+--
+2.22.0
+
+
+From 734ed1a390bcfe505192fd04512d927e191d298a Mon Sep 17 00:00:00 2001
+From: hawkeye116477 <hawkeye116477@gmail.com>
+Date: Wed, 21 Aug 2019 10:45:23 +0200
+Subject: [PATCH 5/5] Bug 1401790 - Remove ProcessArchitecture from IPC.
+
+This was used to support cross-architecture NPAPI plugins on OS X, but we stopped supporting that in 54 (bug 1339182).
+---
+ dom/media/gmp/GMPProcessParent.cpp | 3 +-
+ dom/plugins/base/nsPluginsDirDarwin.cpp | 60 -----------
+ dom/plugins/ipc/PluginProcessParent.cpp | 39 +------
+ ipc/chromium/src/base/process_util.h | 32 +-----
+ ipc/chromium/src/base/process_util_bsd.cc | 3 +-
+ ipc/chromium/src/base/process_util_linux.cc | 3 +-
+ ipc/chromium/src/base/process_util_mac.mm | 30 +-----
+ ipc/glue/GeckoChildProcessHost.cpp | 107 +++-----------------
+ ipc/glue/GeckoChildProcessHost.h | 19 +---
+ 9 files changed, 25 insertions(+), 271 deletions(-)
+
+diff --git a/dom/media/gmp/GMPProcessParent.cpp b/dom/media/gmp/GMPProcessParent.cpp
+index aad88b3ab145..823e120bc3a4 100644
+--- a/dom/media/gmp/GMPProcessParent.cpp
++++ b/dom/media/gmp/GMPProcessParent.cpp
+@@ -23,7 +23,6 @@ using std::string;
+
+ using mozilla::gmp::GMPProcessParent;
+ using mozilla::ipc::GeckoChildProcessHost;
+-using base::ProcessArchitecture;
+
+ namespace mozilla {
+ namespace gmp {
+@@ -78,7 +77,7 @@ GMPProcessParent::Launch(int32_t aTimeoutMs)
+ args.push_back(mGMPPath);
+ #endif
+
+- return SyncLaunch(args, aTimeoutMs, base::GetCurrentProcessArchitecture());
++ return SyncLaunch(args, aTimeoutMs);
+ }
+
+ void
+diff --git a/dom/plugins/base/nsPluginsDirDarwin.cpp b/dom/plugins/base/nsPluginsDirDarwin.cpp
+index 4fe96020ddda..11b46023f3fe 100644
+--- a/dom/plugins/base/nsPluginsDirDarwin.cpp
++++ b/dom/plugins/base/nsPluginsDirDarwin.cpp
+@@ -65,19 +65,6 @@ static CFBundleRef getPluginBundle(const char* path)
+ return bundle;
+ }
+
+-static nsresult toCFURLRef(nsIFile* file, CFURLRef& outURL)
+-{
+- nsCOMPtr<nsILocalFileMac> lfm = do_QueryInterface(file);
+- if (!lfm)
+- return NS_ERROR_FAILURE;
+- CFURLRef url;
+- nsresult rv = lfm->GetCFURL(&url);
+- if (NS_SUCCEEDED(rv))
+- outURL = url;
+-
+- return rv;
+-}
+-
+ bool nsPluginsDir::IsPluginFile(nsIFile* file)
+ {
+ nsCString fileName;
+@@ -365,49 +352,6 @@ static char* GetNextPluginStringFromHandle(Handle h, short *index)
+ return ret;
+ }
+
+-static bool IsCompatibleArch(nsIFile *file)
+-{
+- CFURLRef pluginURL = nullptr;
+- if (NS_FAILED(toCFURLRef(file, pluginURL)))
+- return false;
+-
+- bool isPluginFile = false;
+-
+- CFBundleRef pluginBundle = ::CFBundleCreate(kCFAllocatorDefault, pluginURL);
+- if (pluginBundle) {
+- UInt32 packageType, packageCreator;
+- ::CFBundleGetPackageInfo(pluginBundle, &packageType, &packageCreator);
+- if (packageType == 'BRPL' || packageType == 'IEPL' || packageType == 'NSPL') {
+- // Get path to plugin as a C string.
+- char executablePath[PATH_MAX];
+- executablePath[0] = '\0';
+- if (!::CFURLGetFileSystemRepresentation(pluginURL, true, (UInt8*)&executablePath, PATH_MAX)) {
+- executablePath[0] = '\0';
+- }
+-
+- uint32_t pluginLibArchitectures;
+- nsresult rv = mozilla::ipc::GeckoChildProcessHost::GetArchitecturesForBinary(executablePath, &pluginLibArchitectures);
+- if (NS_FAILED(rv)) {
+- return false;
+- }
+-
+- uint32_t supportedArchitectures =
+-#ifdef __LP64__
+- mozilla::ipc::GeckoChildProcessHost::GetSupportedArchitecturesForProcessType(GeckoProcessType_Plugin);
+-#else
+- base::GetCurrentProcessArchitecture();
+-#endif
+-
+- // Consider the plugin architecture valid if there is any overlap in the masks.
+- isPluginFile = !!(supportedArchitectures & pluginLibArchitectures);
+- }
+- ::CFRelease(pluginBundle);
+- }
+-
+- ::CFRelease(pluginURL);
+- return isPluginFile;
+-}
+-
+ /**
+ * Obtains all of the information currently available for this plugin.
+ */
+@@ -417,10 +361,6 @@ nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info, PRLibrary **outLibrary)
+
+ nsresult rv = NS_OK;
+
+- if (!IsCompatibleArch(mPlugin)) {
+- return NS_ERROR_FAILURE;
+- }
+-
+ // clear out the info, except for the first field.
+ memset(&info, 0, sizeof(info));
+
+diff --git a/dom/plugins/ipc/PluginProcessParent.cpp b/dom/plugins/ipc/PluginProcessParent.cpp
+index e55d5378d99c..c652df36e285 100644
+--- a/dom/plugins/ipc/PluginProcessParent.cpp
++++ b/dom/plugins/ipc/PluginProcessParent.cpp
+@@ -21,7 +21,6 @@ using mozilla::ipc::BrowserProcessSubThread;
+ using mozilla::ipc::GeckoChildProcessHost;
+ using mozilla::plugins::LaunchCompleteTask;
+ using mozilla::plugins::PluginProcessParent;
+-using base::ProcessArchitecture;
+
+ #ifdef XP_WIN
+ PluginProcessParent::PidSet* PluginProcessParent::sPidSet = nullptr;
+@@ -64,48 +63,12 @@ PluginProcessParent::Launch(mozilla::UniquePtr<LaunchCompleteTask> aLaunchComple
+ }
+ #endif
+
+- ProcessArchitecture currentArchitecture = base::GetCurrentProcessArchitecture();
+- uint32_t containerArchitectures = GetSupportedArchitecturesForProcessType(GeckoProcessType_Plugin);
+-
+- uint32_t pluginLibArchitectures = currentArchitecture;
+-#ifdef XP_MACOSX
+- nsresult rv = GetArchitecturesForBinary(mPluginFilePath.c_str(), &pluginLibArchitectures);
+- if (NS_FAILED(rv)) {
+- // If the call failed just assume that we want the current architecture.
+- pluginLibArchitectures = currentArchitecture;
+- }
+-#endif
+-
+- ProcessArchitecture selectedArchitecture = currentArchitecture;
+- if (!(pluginLibArchitectures & containerArchitectures & currentArchitecture)) {
+- // Prefererence in order: x86_64, i386, PPC. The only particularly important thing
+- // about this order is that we'll prefer 64-bit architectures first.
+- if (base::PROCESS_ARCH_X86_64 & pluginLibArchitectures & containerArchitectures) {
+- selectedArchitecture = base::PROCESS_ARCH_X86_64;
+- }
+- else if (base::PROCESS_ARCH_I386 & pluginLibArchitectures & containerArchitectures) {
+- selectedArchitecture = base::PROCESS_ARCH_I386;
+- }
+- else if (base::PROCESS_ARCH_PPC & pluginLibArchitectures & containerArchitectures) {
+- selectedArchitecture = base::PROCESS_ARCH_PPC;
+- }
+- else if (base::PROCESS_ARCH_ARM & pluginLibArchitectures & containerArchitectures) {
+- selectedArchitecture = base::PROCESS_ARCH_ARM;
+- }
+- else if (base::PROCESS_ARCH_MIPS & pluginLibArchitectures & containerArchitectures) {
+- selectedArchitecture = base::PROCESS_ARCH_MIPS;
+- }
+- else {
+- return false;
+- }
+- }
+-
+ mLaunchCompleteTask = mozilla::Move(aLaunchCompleteTask);
+
+ vector<string> args;
+ args.push_back(MungePluginDsoPath(mPluginFilePath));
+
+- bool result = AsyncLaunch(args, selectedArchitecture);
++ bool result = AsyncLaunch(args);
+ if (!result) {
+ mLaunchCompleteTask = nullptr;
+ }
+diff --git a/ipc/chromium/src/base/process_util.h b/ipc/chromium/src/base/process_util.h
+index 32b1c803c2bf..77388d3869d0 100644
+--- a/ipc/chromium/src/base/process_util.h
++++ b/ipc/chromium/src/base/process_util.h
+@@ -51,35 +51,6 @@ struct kinfo_proc;
+
+ namespace base {
+
+-// These can be used in a 32-bit bitmask.
+-enum ProcessArchitecture {
+- PROCESS_ARCH_I386 = 0x1,
+- PROCESS_ARCH_X86_64 = 0x2,
+- PROCESS_ARCH_PPC = 0x4,
+- PROCESS_ARCH_ARM = 0x8,
+- PROCESS_ARCH_MIPS = 0x10,
+- PROCESS_ARCH_ARM64 = 0x20
+-};
+-
+-inline ProcessArchitecture GetCurrentProcessArchitecture()
+-{
+- base::ProcessArchitecture currentArchitecture;
+-#if defined(ARCH_CPU_X86)
+- currentArchitecture = base::PROCESS_ARCH_I386;
+-#elif defined(ARCH_CPU_X86_64)
+- currentArchitecture = base::PROCESS_ARCH_X86_64;
+-#elif defined(ARCH_CPU_PPC)
+- currentArchitecture = base::PROCESS_ARCH_PPC;
+-#elif defined(ARCH_CPU_ARMEL)
+- currentArchitecture = base::PROCESS_ARCH_ARM;
+-#elif defined(ARCH_CPU_MIPS)
+- currentArchitecture = base::PROCESS_ARCH_MIPS;
+-#elif defined(ARCH_CPU_ARM64)
+- currentArchitecture = base::PROCESS_ARCH_ARM64;
+-#endif
+- return currentArchitecture;
+-}
+-
+ // A minimalistic but hopefully cross-platform set of exit codes.
+ // Do not change the enumeration values or you will break third-party
+ // installers.
+@@ -163,8 +134,7 @@ typedef std::map<std::string, std::string> environment_map;
+ bool LaunchApp(const std::vector<std::string>& argv,
+ const file_handle_mapping_vector& fds_to_remap,
+ const environment_map& env_vars_to_set,
+- bool wait, ProcessHandle* process_handle,
+- ProcessArchitecture arch=GetCurrentProcessArchitecture());
++ bool wait, ProcessHandle* process_handle);
+
+ // Deleter for the array of strings allocated within BuildEnvironmentArray.
+ struct FreeEnvVarsArray
+diff --git a/ipc/chromium/src/base/process_util_bsd.cc b/ipc/chromium/src/base/process_util_bsd.cc
+index cb7086ccd60a..e695fe16f02f 100644
+--- a/ipc/chromium/src/base/process_util_bsd.cc
++++ b/ipc/chromium/src/base/process_util_bsd.cc
+@@ -34,8 +34,7 @@ bool LaunchApp(const std::vector<std::string>& argv,
+ bool LaunchApp(const std::vector<std::string>& argv,
+ const file_handle_mapping_vector& fds_to_remap,
+ const environment_map& env_vars_to_set,
+- bool wait, ProcessHandle* process_handle,
+- ProcessArchitecture arch) {
++ bool wait, ProcessHandle* process_handle) {
+ bool retval = true;
+
+ char* argv_copy[argv.size() + 1];
+diff --git a/ipc/chromium/src/base/process_util_linux.cc b/ipc/chromium/src/base/process_util_linux.cc
+index 103c4f5ec5b6..99b79b5a8f22 100644
+--- a/ipc/chromium/src/base/process_util_linux.cc
++++ b/ipc/chromium/src/base/process_util_linux.cc
+@@ -34,8 +34,7 @@ bool LaunchApp(const std::vector<std::string>& argv,
+ bool LaunchApp(const std::vector<std::string>& argv,
+ const file_handle_mapping_vector& fds_to_remap,
+ const environment_map& env_vars_to_set,
+- bool wait, ProcessHandle* process_handle,
+- ProcessArchitecture arch) {
++ bool wait, ProcessHandle* process_handle) {
+ mozilla::UniquePtr<char*[]> argv_cstr(new char*[argv.size() + 1]);
+ // Illegal to allocate memory after fork and before execvp
+ InjectiveMultimap fd_shuffle1, fd_shuffle2;
+diff --git a/ipc/chromium/src/base/process_util_mac.mm b/ipc/chromium/src/base/process_util_mac.mm
+index 1b332d0edabb..a969944823e4 100644
+--- a/ipc/chromium/src/base/process_util_mac.mm
++++ b/ipc/chromium/src/base/process_util_mac.mm
+@@ -32,8 +32,7 @@ bool LaunchApp(const std::vector<std::string>& argv,
+ bool LaunchApp(const std::vector<std::string>& argv,
+ const file_handle_mapping_vector& fds_to_remap,
+ const environment_map& env_vars_to_set,
+- bool wait, ProcessHandle* process_handle,
+- ProcessArchitecture arch) {
++ bool wait, ProcessHandle* process_handle) {
+ bool retval = true;
+
+ char* argv_copy[argv.size() + 1];
+@@ -73,38 +72,11 @@ bool LaunchApp(const std::vector<std::string>& argv,
+ }
+ }
+
+- // Set up the CPU preference array.
+- cpu_type_t cpu_types[1];
+- switch (arch) {
+- case PROCESS_ARCH_I386:
+- cpu_types[0] = CPU_TYPE_X86;
+- break;
+- case PROCESS_ARCH_X86_64:
+- cpu_types[0] = CPU_TYPE_X86_64;
+- break;
+- case PROCESS_ARCH_PPC:
+- cpu_types[0] = CPU_TYPE_POWERPC;
+- break;
+- default:
+- cpu_types[0] = CPU_TYPE_ANY;
+- break;
+- }
+-
+- // Initialize spawn attributes.
+ posix_spawnattr_t spawnattr;
+ if (posix_spawnattr_init(&spawnattr) != 0) {
+ return false;
+ }
+
+- // Set spawn attributes.
+- size_t attr_count = 1;
+- size_t attr_ocount = 0;
+- if (posix_spawnattr_setbinpref_np(&spawnattr, attr_count, cpu_types, &attr_ocount) != 0 ||
+- attr_ocount != attr_count) {
+- posix_spawnattr_destroy(&spawnattr);
+- return false;
+- }
+-
+ int pid = 0;
+ int spawn_succeeded = (posix_spawnp(&pid,
+ argv_copy[0],
+diff --git a/ipc/glue/GeckoChildProcessHost.cpp b/ipc/glue/GeckoChildProcessHost.cpp
+index 9271c7573875..249b6d3b18ab 100644
+--- a/ipc/glue/GeckoChildProcessHost.cpp
++++ b/ipc/glue/GeckoChildProcessHost.cpp
+@@ -205,77 +205,6 @@ private:
+ };
+ #endif
+
+-nsresult GeckoChildProcessHost::GetArchitecturesForBinary(const char *path, uint32_t *result)
+-{
+- *result = 0;
+-
+-#ifdef MOZ_WIDGET_COCOA
+- CFURLRef url = ::CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
+- (const UInt8*)path,
+- strlen(path),
+- false);
+- if (!url) {
+- return NS_ERROR_FAILURE;
+- }
+- AutoCFTypeObject autoPluginContainerURL(url);
+-
+- CFArrayRef pluginContainerArchs = ::CFBundleCopyExecutableArchitecturesForURL(url);
+- if (!pluginContainerArchs) {
+- return NS_ERROR_FAILURE;
+- }
+- AutoCFTypeObject autoPluginContainerArchs(pluginContainerArchs);
+-
+- CFIndex pluginArchCount = ::CFArrayGetCount(pluginContainerArchs);
+- for (CFIndex i = 0; i < pluginArchCount; i++) {
+- CFNumberRef currentArch = static_cast<CFNumberRef>(::CFArrayGetValueAtIndex(pluginContainerArchs, i));
+- int currentArchInt = 0;
+- if (!::CFNumberGetValue(currentArch, kCFNumberIntType, &currentArchInt)) {
+- continue;
+- }
+- switch (currentArchInt) {
+- case kCFBundleExecutableArchitectureI386:
+- *result |= base::PROCESS_ARCH_I386;
+- break;
+- case kCFBundleExecutableArchitectureX86_64:
+- *result |= base::PROCESS_ARCH_X86_64;
+- break;
+- case kCFBundleExecutableArchitecturePPC:
+- *result |= base::PROCESS_ARCH_PPC;
+- break;
+- default:
+- break;
+- }
+- }
+-
+- return (*result ? NS_OK : NS_ERROR_FAILURE);
+-#else
+- return NS_ERROR_NOT_IMPLEMENTED;
+-#endif
+-}
+-
+-uint32_t GeckoChildProcessHost::GetSupportedArchitecturesForProcessType(GeckoProcessType type)
+-{
+-#ifdef MOZ_WIDGET_COCOA
+- if (type == GeckoProcessType_Plugin) {
+-
+- // Cache this, it shouldn't ever change.
+- static uint32_t pluginContainerArchs = 0;
+- if (pluginContainerArchs == 0) {
+- FilePath exePath;
+- GetPathToBinary(exePath, type);
+- nsresult rv = GetArchitecturesForBinary(exePath.value().c_str(), &pluginContainerArchs);
+- NS_ASSERTION(NS_SUCCEEDED(rv) && pluginContainerArchs != 0, "Getting architecture of plugin container failed!");
+- if (NS_FAILED(rv) || pluginContainerArchs == 0) {
+- pluginContainerArchs = base::GetCurrentProcessArchitecture();
+- }
+- }
+- return pluginContainerArchs;
+- }
+-#endif
+-
+- return base::GetCurrentProcessArchitecture();
+-}
+-
+ // We start the unique IDs at 1 so that 0 can be used to mean that
+ // a component has no unique ID assigned to it.
+ uint32_t GeckoChildProcessHost::sNextUniqueID = 1;
+@@ -342,39 +271,34 @@ void GeckoChildProcessHost::InitWindowsGroupID()
+ #endif
+
+ bool
+-GeckoChildProcessHost::SyncLaunch(std::vector<std::string> aExtraOpts, int aTimeoutMs, base::ProcessArchitecture arch)
++GeckoChildProcessHost::SyncLaunch(std::vector<std::string> aExtraOpts, int aTimeoutMs)
+ {
+ PrepareLaunch();
+
+ MessageLoop* ioLoop = XRE_GetIOMessageLoop();
+ NS_ASSERTION(MessageLoop::current() != ioLoop, "sync launch from the IO thread NYI");
+
+- ioLoop->PostTask(NewNonOwningRunnableMethod<std::vector<std::string>,
+- base::ProcessArchitecture>(
++ ioLoop->PostTask(NewNonOwningRunnableMethod<std::vector<std::string>>(
+ "ipc::GeckoChildProcessHost::RunPerformAsyncLaunch",
+ this,
+ &GeckoChildProcessHost::RunPerformAsyncLaunch,
+- aExtraOpts,
+- arch));
++ aExtraOpts));
+
+ return WaitUntilConnected(aTimeoutMs);
+ }
+
+ bool
+-GeckoChildProcessHost::AsyncLaunch(std::vector<std::string> aExtraOpts,
+- base::ProcessArchitecture arch)
++GeckoChildProcessHost::AsyncLaunch(std::vector<std::string> aExtraOpts)
+ {
+ PrepareLaunch();
+
+ MessageLoop* ioLoop = XRE_GetIOMessageLoop();
+
+- ioLoop->PostTask(NewNonOwningRunnableMethod<std::vector<std::string>,
+- base::ProcessArchitecture>(
++ ioLoop->PostTask(NewNonOwningRunnableMethod<std::vector<std::string>>(
+ "ipc::GeckoChildProcessHost::RunPerformAsyncLaunch",
+ this,
+ &GeckoChildProcessHost::RunPerformAsyncLaunch,
+- aExtraOpts,
+- arch));
++ aExtraOpts));
+
+ // This may look like the sync launch wait, but we only delay as
+ // long as it takes to create the channel.
+@@ -430,13 +354,11 @@ GeckoChildProcessHost::LaunchAndWaitForProcessHandle(StringVector aExtraOpts)
+ PrepareLaunch();
+
+ MessageLoop* ioLoop = XRE_GetIOMessageLoop();
+- ioLoop->PostTask(NewNonOwningRunnableMethod<std::vector<std::string>,
+- base::ProcessArchitecture>(
++ ioLoop->PostTask(NewNonOwningRunnableMethod<std::vector<std::string>>(
+ "ipc::GeckoChildProcessHost::RunPerformAsyncLaunch",
+ this,
+ &GeckoChildProcessHost::RunPerformAsyncLaunch,
+- aExtraOpts,
+- base::GetCurrentProcessArchitecture()));
++ aExtraOpts));
+
+ MonitorAutoLock lock(mMonitor);
+ while (mProcessState < PROCESS_CREATED) {
+@@ -528,7 +450,7 @@ GeckoChildProcessHost::SetChildLogName(const char* varName, const char* origLogN
+ }
+
+ bool
+-GeckoChildProcessHost::PerformAsyncLaunch(std::vector<std::string> aExtraOpts, base::ProcessArchitecture arch)
++GeckoChildProcessHost::PerformAsyncLaunch(std::vector<std::string> aExtraOpts)
+ {
+ AutoSetProfilerEnvVarsForChildProcess profilerEnvironment;
+
+@@ -563,7 +485,7 @@ GeckoChildProcessHost::PerformAsyncLaunch(std::vector<std::string> aExtraOpts, b
+ SetChildLogName("MOZ_LOG_FILE=", origMozLogName, mozLogName);
+ }
+
+- bool retval = PerformAsyncLaunchInternal(aExtraOpts, arch);
++ bool retval = PerformAsyncLaunchInternal(aExtraOpts);
+
+ // Revert to original value
+ if (origNSPRLogName) {
+@@ -577,12 +499,11 @@ GeckoChildProcessHost::PerformAsyncLaunch(std::vector<std::string> aExtraOpts, b
+ }
+
+ bool
+-GeckoChildProcessHost::RunPerformAsyncLaunch(std::vector<std::string> aExtraOpts,
+- base::ProcessArchitecture aArch)
++GeckoChildProcessHost::RunPerformAsyncLaunch(std::vector<std::string> aExtraOpts)
+ {
+ InitializeChannel();
+
+- bool ok = PerformAsyncLaunch(aExtraOpts, aArch);
++ bool ok = PerformAsyncLaunch(aExtraOpts);
+ if (!ok) {
+ // WaitUntilConnected might be waiting for us to signal.
+ // If something failed let's set the error state and notify.
+@@ -649,7 +570,7 @@ AddAppDirToCommandLine(std::vector<std::string>& aCmdLine)
+ }
+
+ bool
+-GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExtraOpts, base::ProcessArchitecture arch)
++GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExtraOpts)
+ {
+ // We rely on the fact that InitializeChannel() has already been processed
+ // on the IO thread before this point is reached.
+@@ -852,7 +773,7 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
+ #if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_BSD) || defined(OS_SOLARIS)
+ newEnvVars,
+ #endif
+- false, &process, arch);
++ false, &process);
+ #endif // defined(MOZ_WIDGET_ANDROID)
+
+ // We're in the parent and the child was launched. Close the child FD in the
+diff --git a/ipc/glue/GeckoChildProcessHost.h b/ipc/glue/GeckoChildProcessHost.h
+index 9b65d77a2e9b..af98fc41f0a0 100644
+--- a/ipc/glue/GeckoChildProcessHost.h
++++ b/ipc/glue/GeckoChildProcessHost.h
+@@ -42,17 +42,12 @@ public:
+
+ ~GeckoChildProcessHost();
+
+- static nsresult GetArchitecturesForBinary(const char *path, uint32_t *result);
+-
+- static uint32_t GetSupportedArchitecturesForProcessType(GeckoProcessType type);
+-
+ static uint32_t GetUniqueID();
+
+ // Block until the IPC channel for our subprocess is initialized,
+ // but no longer. The child process may or may not have been
+ // created when this method returns.
+- bool AsyncLaunch(StringVector aExtraOpts=StringVector(),
+- base::ProcessArchitecture arch=base::GetCurrentProcessArchitecture());
++ bool AsyncLaunch(StringVector aExtraOpts=StringVector());
+
+ virtual bool WaitUntilConnected(int32_t aTimeoutMs = 0);
+
+@@ -74,11 +69,9 @@ public:
+ // the IPC channel, meaning it's fully initialized. (Or until an
+ // error occurs.)
+ bool SyncLaunch(StringVector aExtraOpts=StringVector(),
+- int32_t timeoutMs=0,
+- base::ProcessArchitecture arch=base::GetCurrentProcessArchitecture());
++ int32_t timeoutMs=0);
+
+- virtual bool PerformAsyncLaunch(StringVector aExtraOpts=StringVector(),
+- base::ProcessArchitecture aArch=base::GetCurrentProcessArchitecture());
++ virtual bool PerformAsyncLaunch(StringVector aExtraOpts=StringVector());
+
+ virtual void OnChannelConnected(int32_t peer_pid);
+ virtual void OnMessageReceived(IPC::Message&& aMsg);
+@@ -174,11 +167,9 @@ private:
+ DISALLOW_EVIL_CONSTRUCTORS(GeckoChildProcessHost);
+
+ // Does the actual work for AsyncLaunch, on the IO thread.
+- bool PerformAsyncLaunchInternal(std::vector<std::string>& aExtraOpts,
+- base::ProcessArchitecture arch);
++ bool PerformAsyncLaunchInternal(std::vector<std::string>& aExtraOpts);
+
+- bool RunPerformAsyncLaunch(StringVector aExtraOpts=StringVector(),
+- base::ProcessArchitecture aArch=base::GetCurrentProcessArchitecture());
++ bool RunPerformAsyncLaunch(StringVector aExtraOpts=StringVector());
+
+ enum class BinaryPathType {
+ Self,
+--
+2.22.0
+