My previous blog post raised more questions in my mind than it answered. While Microsoft talks about x64 support being added to Windows 10 Insider builds, it doesn’t say how. And the view of powershell.exe in Task Manager was particularly interesting:
So Task Manager shows it as an ARM64 process, but x64 compatible? What does that mean? First, let’s look at powershell.exe from C:Windowssystem32WindowsPowerShellv1.0, which would normally be the “native” version, using DUMPBIN (from the Windows SDK) to see the headers:
OK, that’s slightly different from powershell.exe on an x64 device:
Even though the machine type value is the same, the utility knows there is something different about this file, hence the “ARM64X” text. So what is ARM64X and where did DUMPBIN.EXE even come up with that value, with the machine type (8664) being the same in both cases? Obviously it’s looking at something else, just not clear what.
And if I look at the Windows.old version (from C:Windows.oldWindowssystem32windowspowershellv1.0), it’s definitely changed as it used to be x86 (32-bit emulated):
So DUMPBIN.EXE (which gets updated regularly as part of Visual Studio) knows something that doesn’t seem to be documented. And with the strong tie between LINK.EXE (which creates the executables) and DUMPBIN.EXE (which reads info from those executables), maybe LINK.EXE also knows something that isn’t documented. Sure enough, it shows a new ARM64X machine type not listed in the documentation:
But we’re still no closer to understanding what that is. So back to the ARM device to dig some more. Since all executables are typically going to use one or more DLLs to get anything done, it’s useful to look at those DLLs for more “inspiration.” USER32.DLL is a fairly common DLL, so let’s look at that:
So the file in C:Windowssystem32 would typically be the ARM64 version, the one in SysArm32 would be the ARM32 version, and the one in SysWOW64 would be the x86 (32-bit) version. But what is SyChpe32? Those have been around a while as others discovered some time back. They are “hybrid” binaries containing x86-to-ARM stubs to improve the x86 emulation performance. There were 56 of those in the Windows 10 20H2 release, and 55 in the current Insider build. So no big change there.
So let’s focus on the System32 file. It is an ARM64 binary, but also marked ARM64X (like powershell.exe, and unlike the System32 version from 20H2):
And as was pointed out in the article this file also contains extra file sections, similar to the SyChpe32 files:
Not only that, the file got significantly bigger:
Combine that with what we don’t see: a set of x64-specific files (e.g. a Syswow6464 folder). You would think that adding x64 support to the ARM64 OS would require adding a set of x64-specific files, just like the x86 support added a set of x86-specific files. Nope, definitely not the case here. So what was done instead? More hybrid binaries. But unlike the SyChpe32 files, you don’t need a separate set of files, it’s all stashed inside the System32 DLLs. Certainly that probably saves some space overall, but if all the DLLs get bigger similarly to USER32.DLL, the OS overall will get bigger to support x64 apps. That’s probably not surprising, but this ARM64X logic appears to actually reduce the impact overall. Presumably there are also performance benefits (e.g. avoiding x64->ARM64->x64 code transitions, using native code more often instead of falling back to x64 versions, etc.).
To summarize all of this, there are some pretty significant changes going on here to support running x64 code on Windows 10 on ARM64. It’s not just “throw in a bunch of x64 DLLs and translate at runtime” but rather a reworking of how all of this is packaged and executed with x64. Combine that with a more “rational” way of running things like powershell.exe that will help with tool compatibility, and this looks like a winner. As long as the compatibility with x64 code works really well — that’s the main aspect to follow.
Now that I’ve got an ARM64 device of my own, I can follow along with the progress, even if this doesn’t get released until 21H2 (when I also hope to see new generations of Qualcomm ARM64 processors)…