Bug 1520929 - part 1 - add an isWowARM64 property to nsSystemInfo; r=aklotz
authorNathan Froyd <froydnj@mozilla.com>
Wed, 03 Apr 2019 04:44:49 -0500
changeset 467675 d49485b4f4221077442dc994c6e69b11f32ddc64
parent 467674 7dd52a4bdab50a655e2f8dfe94b7a39ec63500c6
child 467676 67a15c8abdbc1575df8059aceb8661e60a465535
push id35808
push useraciure@mozilla.com
push dateWed, 03 Apr 2019 20:46:05 +0000
treeherdermozilla-central@74be8815ccfc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaklotz
bugs1520929
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1520929 - part 1 - add an isWowARM64 property to nsSystemInfo; r=aklotz In addition to knowing whether we're running x86-on-x86-64, we'd also like to know about the x86-on-arm64 case. The current code doesn't provide enough information to determine that, so we need to query a little bit harder.
xpcom/base/nsSystemInfo.cpp
--- a/xpcom/base/nsSystemInfo.cpp
+++ b/xpcom/base/nsSystemInfo.cpp
@@ -726,24 +726,53 @@ nsresult nsSystemInfo::Init() {
     rv = SetPropertyAsBool(NS_ConvertASCIItoUTF16(cpuPropItems[i].name),
                            cpuPropItems[i].propfun());
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
   }
 
 #ifdef XP_WIN
-  BOOL isWow64;
-  BOOL gotWow64Value = IsWow64Process(GetCurrentProcess(), &isWow64);
+  // IsWow64Process2 is only available on Windows 10+, so we have to dynamically
+  // check for its existence.
+  typedef BOOL(WINAPI* LPFN_IWP2)(HANDLE, USHORT*, USHORT*);
+  LPFN_IWP2 iwp2 = reinterpret_cast<LPFN_IWP2>(GetProcAddress(
+      GetModuleHandle(L"kernel32"), "IsWow64Process2"));
+  BOOL isWow64 = false;
+  USHORT processMachine = IMAGE_FILE_MACHINE_UNKNOWN;
+  USHORT nativeMachine = IMAGE_FILE_MACHINE_UNKNOWN;
+  BOOL gotWow64Value;
+  if (iwp2) {
+    gotWow64Value = iwp2(GetCurrentProcess(), &processMachine, &nativeMachine);
+    if (gotWow64Value) {
+      isWow64 = (processMachine != IMAGE_FILE_MACHINE_UNKNOWN);
+    }
+  } else {
+    gotWow64Value = IsWow64Process(GetCurrentProcess(), &isWow64);
+    // The function only indicates a WOW64 environment if it's 32-bit x86
+    // running on x86-64, so emulate what IsWow64Process2 would have given.
+    if (gotWow64Value && isWow64) {
+      processMachine = IMAGE_FILE_MACHINE_I386;
+      nativeMachine = IMAGE_FILE_MACHINE_AMD64;
+    }
+  }
   NS_WARNING_ASSERTION(gotWow64Value, "IsWow64Process failed");
   if (gotWow64Value) {
+    // Set this always, even for the x86-on-arm64 case.
     rv = SetPropertyAsBool(NS_LITERAL_STRING("isWow64"), !!isWow64);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
+    // Additional information if we're running x86-on-arm64
+    bool isWowARM64 = (processMachine == IMAGE_FILE_MACHINE_I386 &&
+                       nativeMachine == IMAGE_FILE_MACHINE_ARM64);
+    rv = SetPropertyAsBool(NS_LITERAL_STRING("isWowARM64"), !!isWowARM64);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
   }
   if (NS_FAILED(GetProfileHDDInfo())) {
     // We might have been called before profile-do-change. We'll observe that
     // event so that we can fill this in later.
     nsCOMPtr<nsIObserverService> obsService =
         do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;