From 2e3200cd1e8854c86e642953943a370f9a25ec6f Mon Sep 17 00:00:00 2001 From: t4lz Date: Mon, 22 Jan 2024 16:10:15 +0100 Subject: [PATCH] Allow x86_64 and arm64 when patching a thin binary (#2187) In a thin binay there is no arch choice anyway, so patch if we know how to patch that binary type (we know how to patch `x86_64` and `arm_64`). Up until now we would try to (imperfectly) forbid patching thin `arm64` binaries on `x86_64` systems, but there is no point in that, as that is not a valid situation anyways, so it should not happen, and if it does happen, that's not a mirrord error, so we can let it fail naturally as it would without mirrord. --- changelog.d/2186.fixed.md | 1 + changelog.d/2186.internal.md | 1 + mirrord/sip/src/lib.rs | 25 +++++++------------------ 3 files changed, 9 insertions(+), 18 deletions(-) create mode 100644 changelog.d/2186.fixed.md create mode 100644 changelog.d/2186.internal.md diff --git a/changelog.d/2186.fixed.md b/changelog.d/2186.fixed.md new file mode 100644 index 00000000000..f8e85cfd00a --- /dev/null +++ b/changelog.d/2186.fixed.md @@ -0,0 +1 @@ +Running R on macOS. diff --git a/changelog.d/2186.internal.md b/changelog.d/2186.internal.md new file mode 100644 index 00000000000..64d197af7c3 --- /dev/null +++ b/changelog.d/2186.internal.md @@ -0,0 +1 @@ +Allow both `x86_64` and `arm64` when patching thin binaries. diff --git a/mirrord/sip/src/lib.rs b/mirrord/sip/src/lib.rs index 4bf6a61d1fd..549c1e018aa 100644 --- a/mirrord/sip/src/lib.rs +++ b/mirrord/sip/src/lib.rs @@ -71,7 +71,6 @@ mod main { /// Check if a cpu subtype (already parsed with the correct endianness) is arm64e, given its /// main cpu type is arm64. We only consider the lowest byte in the check. - #[cfg(target_arch = "aarch64")] fn is_cpu_subtype_arm64e(subtype: u32) -> bool { // We only compare the lowest 8 bit since the higher bits may contain "capability bits". // For example, usually arm64e would be @@ -109,22 +108,13 @@ mod main { /// returns either an Ok BinaryInfo (which points to the whole file, as it is not /// part of a fat file) if it is of a supported CPU architecture, or a /// `SipError::NoSupportedArchitecture` otherwise. - fn from_thin_mach_o( - cpu_type: u32, - #[cfg(target_arch = "aarch64")] cpu_subtype: u32, - bytes: &[u8], - ) -> Result { - // When running with apple chips both arm64 and x64 can run. - #[cfg(target_arch = "aarch64")] - let is_supported = (cpu_type == macho::CPU_TYPE_X86_64 - || cpu_type == macho::CPU_TYPE_ARM64) - && !is_cpu_subtype_arm64e(cpu_subtype); - - // When running with intel chips, only x86_64 can run. - #[cfg(target_arch = "x86_64")] - let is_supported = cpu_type == macho::CPU_TYPE_X86_64; - - if is_supported { + fn from_thin_mach_o(cpu_type: u32, cpu_subtype: u32, bytes: &[u8]) -> Result { + if cpu_type == macho::CPU_TYPE_X86_64 + || (cpu_type == macho::CPU_TYPE_ARM64 && !is_cpu_subtype_arm64e(cpu_subtype)) + { + // The binary has an architecture we know how to patch, so proceed. + // We don't check if this is a thin arm binary on an intel chip because that would + // not run regardless of SIP. Ok(Self::new(0, bytes.len())) } else { Err(SipError::NoSupportedArchitecture) @@ -155,7 +145,6 @@ mod main { })?; Self::from_thin_mach_o( header.cputype(Endianness::default()), - #[cfg(target_arch = "aarch64")] header.cpusubtype(Endianness::default()), bytes, )