From dddb71fa705248774fd0b7d443b5ca46109959bd Mon Sep 17 00:00:00 2001
From: Sergey Fedorov <barracuda@macos-powerpc.org>
Date: Thu, 23 Jul 2026 04:38:39 +0000
Subject: [PATCH] apple: add PowerPC mcontext and mach `_structs`
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

See: https://github.com/rust-lang/libc/issues/5319

Adds `powerpc`/`powerpc64` implementations to the new Apple XNU tree,
mirroring the existing i386/arm arch pairs:

* `xnu/mach/ppc/_structs.rs` — `__darwin_ppc_{thread,exception,float,
  vector}_state[64]`
* `xnu/ppc/_mcontext.rs` — `__darwin_mcontext` (ppc32) /
  `__darwin_mcontext64` (ppc64) and the arch-gated `mcontext_t`

Wired into `xnu/mod.rs`, `xnu/mach/mod.rs`, `xnu/machine/_mcontext.rs`,
and `xnu/mach/machine/_structs.rs`.

Definitions follow the last ppc-capable SDK (`MacOSX10.6.sdk`):
`mach/ppc/_structs.h` and `ppc/_structs.h`. Field counts and types are
verified against the header, including its quirks: the 64-bit
`thread_state` drops `__mq`, `exception_state64` drops `__pad0`, and the
exception/vector fields are 32-bit on both arches (`unsigned int` under
`__LP64__`, 32-bit `unsigned long` otherwise).

`thread_state64` and `exception_state64` carry `#[repr(packed(4))]` to
match the header's `#pragma pack(4)`. On Darwin ppc32 this is load-
bearing: under `#pragma pack` GCC suppresses the
`darwin_rs6000_special_round_type_align` first-field alignment bump (GCC
PR110044), so the leading `u64` does not raise the struct to 8-byte
alignment. The remaining structs are naturally aligned and use the plain
`s!` macro.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M9i5qXwudh11Nn4iUvdhqV
---
 src/new/apple/xnu/mach/machine/_structs.rs |   2 +
 src/new/apple/xnu/mach/mod.rs              |   9 ++
 src/new/apple/xnu/mach/ppc/_structs.rs     | 135 +++++++++++++++++++++
 src/new/apple/xnu/machine/_mcontext.rs     |   2 +
 src/new/apple/xnu/mod.rs                   |   9 ++
 src/new/apple/xnu/ppc/_mcontext.rs         |  32 +++++
 6 files changed, 189 insertions(+)
 create mode 100644 src/new/apple/xnu/mach/ppc/_structs.rs
 create mode 100644 src/new/apple/xnu/ppc/_mcontext.rs

diff --git a/src/new/apple/xnu/mach/machine/_structs.rs b/src/new/apple/xnu/mach/machine/_structs.rs
index 6acae8d9a..3db11c46a 100644
--- .home/.cargo/macports/libc-0.2.189/src/new/apple/xnu/mach/machine/_structs.rs
+++ .home/.cargo/macports/libc-0.2.189/src/new/apple/xnu/mach/machine/_structs.rs
@@ -7,6 +7,8 @@ cfg_if! {
         pub use crate::mach::i386::_structs::*;
     } else if #[cfg(any(target_arch = "arm", target_arch = "aarch64"))] {
         pub use crate::mach::arm::_structs::*;
+    } else if #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] {
+        pub use crate::mach::ppc::_structs::*;
     } else {
         // Unsupported arch
     }
diff --git a/src/new/apple/xnu/mach/mod.rs b/src/new/apple/xnu/mach/mod.rs
index 90751260a..f39442bf6 100644
--- .home/.cargo/macports/libc-0.2.189/src/new/apple/xnu/mach/mod.rs
+++ .home/.cargo/macports/libc-0.2.189/src/new/apple/xnu/mach/mod.rs
@@ -14,6 +14,15 @@ pub(crate) mod i386 {
     pub(crate) mod _structs;
 }
 
+/// Directory: `mach/ppc`
+///
+/// PowerPC is no longer supported upstream; these follow the last ppc-capable SDK,
+/// `MacOSX10.6.sdk`.
+#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))]
+pub(crate) mod ppc {
+    pub(crate) mod _structs;
+}
+
 /// Directory: `mach/machine`
 pub(crate) mod machine {
     pub(crate) mod _structs;
diff --git a/src/new/apple/xnu/mach/ppc/_structs.rs b/src/new/apple/xnu/mach/ppc/_structs.rs
new file mode 100644
index 000000000..d3cbead5c
--- /dev/null
+++ .home/.cargo/macports/libc-0.2.189/src/new/apple/xnu/mach/ppc/_structs.rs
@@ -0,0 +1,135 @@
+//! Header: `ppc/_structs.h`
+//!
+//! <https://github.com/apple-oss-distributions/xnu/blob/main/osfmk/mach/ppc/_structs.h>
+//!
+//! PowerPC is no longer supported by upstream XNU; these definitions follow the last
+//! ppc-capable SDK, `MacOSX10.6.sdk`.
+
+use crate::prelude::*;
+
+s! {
+    pub struct __darwin_ppc_thread_state {
+        pub __srr0: c_uint,
+        pub __srr1: c_uint,
+        pub __r0: c_uint,
+        pub __r1: c_uint,
+        pub __r2: c_uint,
+        pub __r3: c_uint,
+        pub __r4: c_uint,
+        pub __r5: c_uint,
+        pub __r6: c_uint,
+        pub __r7: c_uint,
+        pub __r8: c_uint,
+        pub __r9: c_uint,
+        pub __r10: c_uint,
+        pub __r11: c_uint,
+        pub __r12: c_uint,
+        pub __r13: c_uint,
+        pub __r14: c_uint,
+        pub __r15: c_uint,
+        pub __r16: c_uint,
+        pub __r17: c_uint,
+        pub __r18: c_uint,
+        pub __r19: c_uint,
+        pub __r20: c_uint,
+        pub __r21: c_uint,
+        pub __r22: c_uint,
+        pub __r23: c_uint,
+        pub __r24: c_uint,
+        pub __r25: c_uint,
+        pub __r26: c_uint,
+        pub __r27: c_uint,
+        pub __r28: c_uint,
+        pub __r29: c_uint,
+        pub __r30: c_uint,
+        pub __r31: c_uint,
+        pub __cr: c_uint,
+        pub __xer: c_uint,
+        pub __lr: c_uint,
+        pub __ctr: c_uint,
+        pub __mq: c_uint,
+        pub __vrsave: c_uint,
+    }
+
+    // The header wraps this in `#pragma pack(4)`, which forces its `u64` fields to 4-byte
+    // alignment on both `powerpc` and `powerpc64` (`long long` is 8-byte aligned by default
+    // in the PowerPC ABI).
+    #[repr(packed(4))]
+    pub struct __darwin_ppc_thread_state64 {
+        pub __srr0: u64,
+        pub __srr1: u64,
+        pub __r0: u64,
+        pub __r1: u64,
+        pub __r2: u64,
+        pub __r3: u64,
+        pub __r4: u64,
+        pub __r5: u64,
+        pub __r6: u64,
+        pub __r7: u64,
+        pub __r8: u64,
+        pub __r9: u64,
+        pub __r10: u64,
+        pub __r11: u64,
+        pub __r12: u64,
+        pub __r13: u64,
+        pub __r14: u64,
+        pub __r15: u64,
+        pub __r16: u64,
+        pub __r17: u64,
+        pub __r18: u64,
+        pub __r19: u64,
+        pub __r20: u64,
+        pub __r21: u64,
+        pub __r22: u64,
+        pub __r23: u64,
+        pub __r24: u64,
+        pub __r25: u64,
+        pub __r26: u64,
+        pub __r27: u64,
+        pub __r28: u64,
+        pub __r29: u64,
+        pub __r30: u64,
+        pub __r31: u64,
+        pub __cr: c_uint,
+        pub __xer: u64,
+        pub __lr: u64,
+        pub __ctr: u64,
+        pub __vrsave: c_uint,
+    }
+
+    // `unsigned int` in the `__LP64__` branch of the header, `unsigned long` otherwise; on ppc
+    // both resolve to 32 bits, so the layout is identical on `powerpc` and `powerpc64`.
+    pub struct __darwin_ppc_exception_state {
+        pub __dar: c_uint,
+        pub __dsisr: c_uint,
+        pub __exception: c_uint,
+        pub __pad0: c_uint,
+        pub __pad1: [c_uint; 4],
+    }
+
+    // Wrapped in `#pragma pack(4)` in the header, forcing `__dar` (the only field wider than
+    // 4 bytes) to 4-byte alignment on both `powerpc` and `powerpc64`.
+    #[repr(packed(4))]
+    pub struct __darwin_ppc_exception_state64 {
+        pub __dar: u64,
+        // `unsigned int` under `__LP64__`, `unsigned long` otherwise; 32 bits on ppc either way.
+        pub __dsisr: c_uint,
+        pub __exception: c_uint,
+        pub __pad1: [c_uint; 4],
+    }
+
+    pub struct __darwin_ppc_float_state {
+        pub __fpregs: [c_double; 32],
+        pub __fpscr_pad: c_uint,
+        pub __fpscr: c_uint,
+    }
+
+    // Same 32-bit-field reasoning as `__darwin_ppc_exception_state`.
+    pub struct __darwin_ppc_vector_state {
+        pub __save_vr: [[c_uint; 4]; 32],
+        pub __save_vscr: [c_uint; 4],
+        pub __save_pad5: [c_uint; 4],
+        pub __save_vrvalid: c_uint,
+        pub __save_pad6: [c_uint; 7],
+    }
+}
diff --git a/src/new/apple/xnu/machine/_mcontext.rs b/src/new/apple/xnu/machine/_mcontext.rs
index 004b94707..8753db461 100644
--- .home/.cargo/macports/libc-0.2.189/src/new/apple/xnu/machine/_mcontext.rs
+++ .home/.cargo/macports/libc-0.2.189/src/new/apple/xnu/machine/_mcontext.rs
@@ -5,6 +5,8 @@ cfg_if! {
         pub use crate::i386::_mcontext::*;
     } else if #[cfg(any(target_arch = "arm", target_arch = "aarch64"))] {
         pub use crate::arm::_mcontext::*;
+    } else if #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] {
+        pub use crate::ppc::_mcontext::*;
     } else {
         // Unsupported arch
     }
diff --git a/src/new/apple/xnu/mod.rs b/src/new/apple/xnu/mod.rs
index a81d38db5..1a88e1fa9 100644
--- .home/.cargo/macports/libc-0.2.189/src/new/apple/xnu/mod.rs
+++ .home/.cargo/macports/libc-0.2.189/src/new/apple/xnu/mod.rs
@@ -18,6 +18,15 @@ pub(crate) mod i386 {
     pub(crate) mod _mcontext;
 }
 
+/// Directory: `ppc/`
+///
+/// PowerPC is no longer supported upstream; these follow the last ppc-capable SDK,
+/// `MacOSX10.6.sdk`.
+#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))]
+pub(crate) mod ppc {
+    pub(crate) mod _mcontext;
+}
+
 pub(crate) mod mach;
 
 /// Directory: `machine/`
diff --git a/src/new/apple/xnu/ppc/_mcontext.rs b/src/new/apple/xnu/ppc/_mcontext.rs
new file mode 100644
index 000000000..0bf4e0d04
--- /dev/null
+++ .home/.cargo/macports/libc-0.2.189/src/new/apple/xnu/ppc/_mcontext.rs
@@ -0,0 +1,32 @@
+//! Header: `ppc/_mcontext.h`
+//!
+//! <https://github.com/apple-oss-distributions/xnu/blob/main/bsd/ppc/_mcontext.h>
+//!
+//! PowerPC is no longer supported by upstream XNU; these definitions follow the last
+//! ppc-capable SDK, `MacOSX10.6.sdk`.
+
+pub use crate::mach::machine::_structs::*;
+
+s! {
+    #[cfg(target_arch = "powerpc")]
+    pub struct __darwin_mcontext {
+        pub __es: __darwin_ppc_exception_state,
+        pub __ss: __darwin_ppc_thread_state,
+        pub __fs: __darwin_ppc_float_state,
+        pub __vs: __darwin_ppc_vector_state,
+    }
+
+    #[cfg(target_arch = "powerpc64")]
+    pub struct __darwin_mcontext64 {
+        pub __es: __darwin_ppc_exception_state64,
+        pub __ss: __darwin_ppc_thread_state64,
+        pub __fs: __darwin_ppc_float_state,
+        pub __vs: __darwin_ppc_vector_state,
+    }
+}
+
+#[cfg(target_arch = "powerpc")]
+pub type mcontext_t = *mut __darwin_mcontext;
+
+#[cfg(target_arch = "powerpc64")]
+pub type mcontext_t = *mut __darwin_mcontext64;
