From 47468ec984c490fbce44fe80e0b289b337f367c9 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 23 Sep 2023 11:34:25 -0400 Subject: [PATCH] When running a 32-bit rustup on an aarch64 CPU, select a 32-bit toolchain this mirrors a similar check that exists in rustup-init.sh fixes #3307 --- src/dist/dist.rs | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/dist/dist.rs b/src/dist/dist.rs index 97093a21c1b..ca221d60b0f 100644 --- a/src/dist/dist.rs +++ b/src/dist/dist.rs @@ -1,7 +1,8 @@ use std::collections::HashSet; use std::env; use std::fmt; -use std::io::Write; +use std::fs; +use std::io::{self, Read, Write}; use std::ops::Deref; use std::path::Path; use std::str::FromStr; @@ -219,6 +220,25 @@ impl Deref for TargetTriple { } } +fn is_32bit_userspace() -> bool { + // Check if /bin/sh is a 32-bit binary. If it doesn't exist, fall back to + // checking if _we_ are a 32-bit binary. + // rustup-init.sh also relies on checking /bin/sh for bitness. + + fn inner() -> io::Result { + let mut f = fs::File::open("/bin/sh")?; + let mut buf = [0; 5]; + f.read_exact(&mut buf)?; + + // ELF files start out "\x7fELF", and the following byte is + // 0x01 for 32-bit and + // 0x02 for 64-bit. + Ok(&buf == b"\x7fELF\x01") + } + + inner().unwrap_or(cfg!(target_pointer_width = "32")) +} + impl TargetTriple { pub fn new(name: &str) -> Self { Self(name.to_string()) @@ -346,7 +366,13 @@ impl TargetTriple { (b"Linux", b"arm") => Some("arm-unknown-linux-gnueabi"), (b"Linux", b"armv7l") => Some("armv7-unknown-linux-gnueabihf"), (b"Linux", b"armv8l") => Some("armv7-unknown-linux-gnueabihf"), - (b"Linux", b"aarch64") => Some(TRIPLE_AARCH64_UNKNOWN_LINUX), + (b"Linux", b"aarch64") => { + if is_32bit_userspace() { + Some("armv7-unknown-linux-gnueabihf") + } else { + Some(TRIPLE_AARCH64_UNKNOWN_LINUX) + } + } (b"Darwin", b"x86_64") => Some("x86_64-apple-darwin"), (b"Darwin", b"i686") => Some("i686-apple-darwin"), (b"FreeBSD", b"x86_64") => Some("x86_64-unknown-freebsd"),