Skip to content

Commit

Permalink
Allow x86_64 and arm64 when patching a thin binary (#2187)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
t4lz authored Jan 22, 2024
1 parent 7f31a60 commit 2e3200c
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 18 deletions.
1 change: 1 addition & 0 deletions changelog.d/2186.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Running R on macOS.
1 change: 1 addition & 0 deletions changelog.d/2186.internal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Allow both `x86_64` and `arm64` when patching thin binaries.
25 changes: 7 additions & 18 deletions mirrord/sip/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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<Self> {
// 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<Self> {
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)
Expand Down Expand Up @@ -155,7 +145,6 @@ mod main {
})?;
Self::from_thin_mach_o(
header.cputype(Endianness::default()),
#[cfg(target_arch = "aarch64")]
header.cpusubtype(Endianness::default()),
bytes,
)
Expand Down

0 comments on commit 2e3200c

Please sign in to comment.