Add wxGetNativeCpuArchitectureName()

This allows to retrieve the native CPU architecture name regardless of
the current process CPU architecture.

Common examples for CPU architecture differences are the following:
    - Win32 process in x64 Windows (WoW)
    - Win32 or x64 process on ARM64 Windows (WoW64)
    - x86_64 process on ARM64 macOS (Rosetta 2)

Closes #22036.
This commit is contained in:
Tobias Taschner
2022-01-21 14:55:49 +01:00
committed by Vadim Zeitlin
parent 512f40d614
commit 1ae0037330
7 changed files with 123 additions and 1 deletions

View File

@@ -296,6 +296,8 @@ public:
{ return GetEndiannessName(m_endian); } { return GetEndiannessName(m_endian); }
wxString GetCpuArchitectureName() const wxString GetCpuArchitectureName() const
{ return m_cpuArch; } { return m_cpuArch; }
wxString GetNativeCpuArchitectureName() const
{ return m_nativeCpuArch; }
wxString GetOperatingSystemDescription() const wxString GetOperatingSystemDescription() const
{ return m_osDesc; } { return m_osDesc; }
wxString GetDesktopEnvironment() const wxString GetDesktopEnvironment() const
@@ -339,6 +341,8 @@ public:
{ m_endian = n; } { m_endian = n; }
void SetCpuArchitectureName(const wxString& cpuArch) void SetCpuArchitectureName(const wxString& cpuArch)
{ m_cpuArch = cpuArch; } { m_cpuArch = cpuArch; }
void SetNativeCpuArchitectureName(const wxString& cpuArch)
{ m_nativeCpuArch = cpuArch; }
void SetDesktopEnvironment(const wxString& de) void SetDesktopEnvironment(const wxString& de)
{ m_desktopEnv = de; } { m_desktopEnv = de; }
@@ -427,6 +431,9 @@ protected:
// CPU architecture family name, possibly empty if unknown // CPU architecture family name, possibly empty if unknown
wxString m_cpuArch; wxString m_cpuArch;
// native CPU architecture family name, possibly empty if unknown
wxString m_nativeCpuArch;
}; };
// Returns true only for MSW programs running under Wine. // Returns true only for MSW programs running under Wine.

View File

@@ -156,6 +156,9 @@ WXDLLIMPEXP_BASE bool wxIsPlatform64Bit();
// Get machine CPU architecture // Get machine CPU architecture
WXDLLIMPEXP_BASE wxString wxGetCpuArchitectureName(); WXDLLIMPEXP_BASE wxString wxGetCpuArchitectureName();
// Get native machine CPU architecture
WXDLLIMPEXP_BASE wxString wxGetNativeCpuArchitectureName();
#ifdef __LINUX__ #ifdef __LINUX__
// Get linux-distro information // Get linux-distro information
WXDLLIMPEXP_BASE wxLinuxDistributionInfo wxGetLinuxDistributionInfo(); WXDLLIMPEXP_BASE wxLinuxDistributionInfo wxGetLinuxDistributionInfo();

View File

@@ -410,12 +410,21 @@ public:
/** /**
Returns the CPU architecture name, if available. Returns the CPU architecture name, if available.
@see wxGetCpuArchitectureName() @see wxGetCpuArchitectureName(), GetNativeCpuArchitectureName()
@since 3.1.5 @since 3.1.5
*/ */
wxString GetCpuArchitectureName() const; wxString GetCpuArchitectureName() const;
/**
Returns the native CPU architecture name, if available.
@since 3.1.6
@see ::wxGetNativeCpuArchitectureName(), GetCpuArchitectureName()
*/
wxString GetNativeCpuArchitectureName() const;
/** /**
Returns the run-time major version of the OS associated with this Returns the run-time major version of the OS associated with this
wxPlatformInfo instance. wxPlatformInfo instance.

View File

@@ -1099,10 +1099,31 @@ bool wxIsPlatformLittleEndian();
The returned string may be empty if the CPU architecture couldn't be The returned string may be empty if the CPU architecture couldn't be
recognized. recognized.
@see wxGetNativeCpuArchitectureName()
@since 3.1.5 @since 3.1.5
*/ */
wxString wxGetCpuArchitectureName(); wxString wxGetCpuArchitectureName();
/**
In some situations the current process and native CPU architecture may be
different. This returns the native CPU architecture regardless of the
current process CPU architecture.
Common examples for CPU architecture differences are the following:
- Win32 process in x64 Windows (WoW)
- Win32 or x64 process on ARM64 Windows (WoW64)
- x86_64 process on ARM64 macOS (Rosetta 2)
The returned string may be empty if the CPU architecture couldn't be
recognized.
@see wxGetCpuArchitectureName()
@since 3.1.6
*/
wxString wxGetNativeCpuArchitectureName();
/** /**
Returns a structure containing information about the currently running Returns a structure containing information about the currently running
Linux distribution. Linux distribution.

View File

@@ -202,6 +202,7 @@ void wxPlatformInfo::InitForCurrentPlatform()
m_endian = wxIsPlatformLittleEndian() ? wxENDIAN_LITTLE : wxENDIAN_BIG; m_endian = wxIsPlatformLittleEndian() ? wxENDIAN_LITTLE : wxENDIAN_BIG;
m_bitness = wxIsPlatform64Bit() ? wxBITNESS_64 : wxBITNESS_32; m_bitness = wxIsPlatform64Bit() ? wxBITNESS_64 : wxBITNESS_32;
m_cpuArch = wxGetCpuArchitectureName(); m_cpuArch = wxGetCpuArchitectureName();
m_nativeCpuArch = wxGetNativeCpuArchitectureName();
#ifdef __LINUX__ #ifdef __LINUX__
m_ldi = wxGetLinuxDistributionInfo(); m_ldi = wxGetLinuxDistributionInfo();

View File

@@ -90,6 +90,14 @@
#define PROCESSOR_ARCHITECTURE_ARM64 12 #define PROCESSOR_ARCHITECTURE_ARM64 12
#endif #endif
#ifndef IMAGE_FILE_MACHINE_ARM64
#define IMAGE_FILE_MACHINE_ARM64 0xAA64
#endif
#ifndef IMAGE_FILE_MACHINE_ARMNT
#define IMAGE_FILE_MACHINE_ARMNT 0x01c4
#endif
#include <errno.h> #include <errno.h>
// For wxKillAllChildren // For wxKillAllChildren
@@ -1312,8 +1320,52 @@ wxWinVersion wxGetWinVersion()
return wxWinVersion_Unknown; return wxWinVersion_Unknown;
} }
wxString wxGetCpuArchitecureNameFromImageType(USHORT imageType)
{
switch (imageType)
{
case IMAGE_FILE_MACHINE_I386:
return "x86";
case IMAGE_FILE_MACHINE_AMD64:
return "x64";
case IMAGE_FILE_MACHINE_IA64:
return "Itanium";
case IMAGE_FILE_MACHINE_ARMNT:
return "arm";
case IMAGE_FILE_MACHINE_ARM64:
return "arm64";
default:
return wxString();
}
}
// Wrap IsWow64Process2 API (Available since Win10 1511)
BOOL wxIsWow64Process2(HANDLE hProcess, USHORT* pProcessMachine, USHORT* pNativeMachine)
{
#if wxUSE_DYNLIB_CLASS // Win32
typedef BOOL(WINAPI *IsWow64Process2_t)(HANDLE, USHORT *, USHORT *);
wxDynamicLibrary dllKernel32("kernel32.dll");
IsWow64Process2_t pfnIsWow64Process2 =
(IsWow64Process2_t)dllKernel32.RawGetSymbol("IsWow64Process2");
if (pfnIsWow64Process2)
return pfnIsWow64Process2(hProcess, pProcessMachine, pNativeMachine);
else
#endif
return FALSE;
}
wxString wxGetCpuArchitectureName() wxString wxGetCpuArchitectureName()
{ {
// Try to get the current active CPU architecture via IsWow64Process2()
// first, fallback to GetNativeSystemInfo() otherwise
USHORT machine;
if (wxIsWow64Process2(::GetCurrentProcess(), &machine, NULL) &&
machine != IMAGE_FILE_MACHINE_UNKNOWN)
return wxGetCpuArchitecureNameFromImageType(machine);
SYSTEM_INFO si; SYSTEM_INFO si;
GetNativeSystemInfo(&si); GetNativeSystemInfo(&si);
@@ -1340,6 +1392,18 @@ wxString wxGetCpuArchitectureName()
} }
} }
wxString wxGetNativeCpuArchitectureName()
{
USHORT machine;
USHORT nativeMachine;
if (wxIsWow64Process2(::GetCurrentProcess(), &machine, &nativeMachine))
return wxGetCpuArchitecureNameFromImageType(nativeMachine);
else
return wxGetCpuArchitectureName();
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// sleep functions // sleep functions
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -145,6 +145,10 @@
#include <sys/resource.h> // for setpriority() #include <sys/resource.h> // for setpriority()
#endif #endif
#if defined(__DARWIN__)
#include <sys/sysctl.h>
#endif
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// conditional compilation // conditional compilation
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -1124,6 +1128,19 @@ wxString wxGetCpuArchitectureName()
return wxGetCommandOutput(wxT("uname -m")); return wxGetCommandOutput(wxT("uname -m"));
} }
wxString wxGetNativeCpuArchitectureName()
{
#if defined(__DARWIN__)
// macOS on ARM will report an x86_64 process as translated, assume the native CPU is arm64
int translated;
size_t translated_size = sizeof(translated);
if (sysctlbyname("sysctl.proc_translated", &translated, &translated_size, NULL, 0) == 0)
return "arm64";
else
#endif
return wxGetCpuArchitectureName();
}
#ifdef __LINUX__ #ifdef __LINUX__
static bool static bool