Skip to content

Commit

Permalink
Merge pull request rust-lang#3010 from arlosi/aarch64
Browse files Browse the repository at this point in the history
Fix detection of aarch64 host on Windows
  • Loading branch information
kinnison authored Jun 15, 2022
2 parents 3277323 + 4871a38 commit 20ed5d9
Showing 1 changed file with 72 additions and 18 deletions.
90 changes: 72 additions & 18 deletions src/dist/dist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,27 +229,80 @@ impl TargetTriple {
#[cfg(windows)]
fn inner() -> Option<TargetTriple> {
use std::mem;
use winapi::um::sysinfoapi::GetNativeSystemInfo;

// First detect architecture
const PROCESSOR_ARCHITECTURE_AMD64: u16 = 9;
const PROCESSOR_ARCHITECTURE_INTEL: u16 = 0;
const PROCESSOR_ARCHITECTURE_ARM64: u16 = 12;
/// Get the host architecture using `IsWow64Process2`. This function
/// produces the most accurate results (supports detecting aarch64), but
/// it is only available on Windows 10 1511+, so we use `GetProcAddress`
/// to maintain backward compatibility with older Windows versions.
fn arch_primary() -> Option<&'static str> {
use winapi::shared::minwindef::BOOL;
use winapi::um::libloaderapi::{GetModuleHandleA, GetProcAddress};
use winapi::um::processthreadsapi::GetCurrentProcess;
use winapi::um::winnt::HANDLE;

const IMAGE_FILE_MACHINE_ARM64: u16 = 0xAA64;
const IMAGE_FILE_MACHINE_AMD64: u16 = 0x8664;
const IMAGE_FILE_MACHINE_I386: u16 = 0x014c;

#[allow(non_snake_case)]
let IsWow64Process2: unsafe extern "system" fn(
HANDLE,
*mut u16,
*mut u16,
)
-> BOOL = unsafe {
let module = GetModuleHandleA(b"kernel32.dll\0" as *const u8 as *const i8);
if module.is_null() {
return None;
}
let process =
GetProcAddress(module, b"IsWow64Process2\0" as *const u8 as *const i8);
if process.is_null() {
return None;
}
mem::transmute(process)
};

let mut sys_info;
unsafe {
sys_info = mem::zeroed();
GetNativeSystemInfo(&mut sys_info);
let mut _machine = 0;
let mut native_machine = 0;
unsafe {
// cannot fail; handle does not need to be closed.
let process = GetCurrentProcess();
if IsWow64Process2(process, &mut _machine, &mut native_machine) == 0 {
return None;
}
};
match native_machine {
IMAGE_FILE_MACHINE_AMD64 => Some("x86_64"),
IMAGE_FILE_MACHINE_I386 => Some("i686"),
IMAGE_FILE_MACHINE_ARM64 => Some("aarch64"),
_ => None,
}
}

let arch = match unsafe { sys_info.u.s() }.wProcessorArchitecture {
PROCESSOR_ARCHITECTURE_AMD64 => "x86_64",
PROCESSOR_ARCHITECTURE_INTEL => "i686",
PROCESSOR_ARCHITECTURE_ARM64 => "aarch64",
_ => return None,
};
/// Get the host architecture using `GetNativeSystemInfo`.
/// Does not support detecting aarch64.
fn arch_fallback() -> Option<&'static str> {
use winapi::um::sysinfoapi::GetNativeSystemInfo;

const PROCESSOR_ARCHITECTURE_AMD64: u16 = 9;
const PROCESSOR_ARCHITECTURE_INTEL: u16 = 0;

let mut sys_info;
unsafe {
sys_info = mem::zeroed();
GetNativeSystemInfo(&mut sys_info);
}

match unsafe { sys_info.u.s() }.wProcessorArchitecture {
PROCESSOR_ARCHITECTURE_AMD64 => Some("x86_64"),
PROCESSOR_ARCHITECTURE_INTEL => Some("i686"),
_ => None,
}
}

// Default to msvc
let arch = arch_primary().or_else(arch_fallback)?;
let msvc_triple = format!("{}-pc-windows-msvc", arch);
Some(TargetTriple(msvc_triple))
}
Expand Down Expand Up @@ -328,12 +381,13 @@ impl TargetTriple {
let ret = if partial_self.os != partial_other.os {
false
} else if partial_self.os.as_deref() == Some("pc-windows") {
// Windows is a special case here, we know we can run 32bit on 64bit
// and we know we can run gnu and msvc on the same system
// We don't immediately assume we can cross between x86 and aarch64 though
// Windows is a special case here: we can run gnu and msvc on the same system,
// x86_64 can run i686, and aarch64 can run i686 through emulation
(partial_self.arch == partial_other.arch)
|| (partial_self.arch.as_deref() == Some("x86_64")
&& partial_other.arch.as_deref() == Some("i686"))
|| (partial_self.arch.as_deref() == Some("aarch64")
&& partial_other.arch.as_deref() == Some("i686"))
} else {
// For other OSes, for now, we assume other toolchains won't run
false
Expand Down

0 comments on commit 20ed5d9

Please sign in to comment.