--- mono/utils/Makefile.in 2011-04-18 20:15:51.000000000 +0800 +++ mono/utils/Makefile.in 2026-01-23 15:09:36.000000000 +0800 @@ -37,6 +37,7 @@ @X86_TRUE@am__append_1 = mach-support-x86.c @AMD64_TRUE@am__append_2 = mach-support-amd64.c @ARM_TRUE@am__append_3 = mach-support-arm.c +@POWERPC_TRUE@am__append_4 = mach-support-ppc.c subdir = mono/utils DIST_COMMON = $(libmonoutilsinclude_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ChangeLog @@ -86,8 +87,9 @@ @X86_TRUE@am__objects_2 = mach-support-x86.lo @AMD64_TRUE@am__objects_3 = mach-support-amd64.lo @ARM_TRUE@am__objects_4 = mach-support-arm.lo -am__objects_5 = $(am__objects_2) $(am__objects_3) $(am__objects_4) -am_libmonoutils_la_OBJECTS = $(am__objects_1) $(am__objects_5) +@POWERPC_TRUE@am__objects_5 = mach-support-ppc.lo +am__objects_6 = $(am__objects_2) $(am__objects_3) $(am__objects_4) $(am__objects_5) +am_libmonoutils_la_OBJECTS = $(am__objects_1) $(am__objects_6) libmonoutils_la_OBJECTS = $(am_libmonoutils_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp @@ -376,7 +378,7 @@ mach-support.h \ memcheck.h -arch_sources = $(am__append_1) $(am__append_2) $(am__append_3) +arch_sources = $(am__append_1) $(am__append_2) $(am__append_3) $(am__append_4) libmonoutils_la_SOURCES = $(monoutils_sources) $(arch_sources) libmonoutilsincludedir = $(includedir)/mono-$(API_VER)/mono/utils libmonoutilsinclude_HEADERS = \ --- /dev/null 2026-01-23 14:48:46.000000000 +0800 +++ mono/utils/mach-support-ppc.c 2026-01-23 15:40:08.000000000 +0800 @@ -0,0 +1,104 @@ +/* + * mach-support-ppc.c: mach support for ppc + * + * Authors: + * Geoff Norton (gnorton@novell.com) + * Sergey Fedorov (barracuda@macos-powerpc.org) + * + * (C) 2026 Novell, Inc. + */ + +#include + +#if defined(__MACH__) +#include +#include +#include +#include "utils/mono-sigcontext.h" +#include "mach-support.h" + +void * +mono_mach_arch_get_ip (thread_state_t state) +{ + ppc_thread_state_t *arch_state = (ppc_thread_state_t *) state; + + return (void *) arch_state->__srr0; +} + +void * +mono_mach_arch_get_sp (thread_state_t state) +{ + ppc_thread_state_t *arch_state = (ppc_thread_state_t *) state; + + return (void *) arch_state->__r1; +} + +int +mono_mach_arch_get_mcontext_size () +{ + return sizeof (struct __darwin_mcontext); +} + +void +mono_mach_arch_thread_state_to_mcontext (thread_state_t state, mcontext_t context) +{ + ppc_thread_state_t *arch_state = (ppc_thread_state_t *) state; + struct __darwin_mcontext *ctx = (struct __darwin_mcontext *) context; + + ctx->__ss = *arch_state; +} + +void +mono_mach_arch_mcontext_to_thread_state (mcontext_t context, thread_state_t state) +{ + ppc_thread_state_t *arch_state = (ppc_thread_state_t *) state; + struct __darwin_mcontext *ctx = (struct __darwin_mcontext *) context; + + *arch_state = ctx->__ss; +} + +int +mono_mach_arch_get_thread_state_size () +{ + return sizeof (ppc_thread_state_t); +} + +kern_return_t +mono_mach_arch_get_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count) +{ + ppc_thread_state_t *arch_state = (ppc_thread_state_t *) state; + kern_return_t ret; + + *count = PPC_THREAD_STATE_COUNT; + + ret = thread_get_state (thread, PPC_THREAD_STATE, (thread_state_t) arch_state, count); + + return ret; +} + +kern_return_t +mono_mach_arch_set_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count) +{ + return thread_set_state (thread, PPC_THREAD_STATE, state, count); +} + +void * +mono_mach_get_tls_address_from_thread (pthread_t thread, pthread_key_t key) +{ + /* OSX stores TLS values in a hidden array inside the pthread_t structure + * They are keyed off a giant array offset 0x48 into the pointer. This value + * is baked into their pthread_getspecific implementation + */ + intptr_t *p = (intptr_t *) thread; + intptr_t **tsd = (intptr_t **) ((char*)p + 0x48); + + return (void *) &tsd [key]; +} + +void * +mono_mach_arch_get_tls_value_from_thread (pthread_t thread, guint32 key) +{ + return *(void**)mono_mach_get_tls_address_from_thread (thread, key); +} + +#endif --- mono/metadata/sgen-archdep.h 2012-09-07 03:09:49.000000000 +0800 +++ mono/metadata/sgen-archdep.h 2026-01-23 18:18:24.000000000 +0800 @@ -73,31 +73,15 @@ #elif defined(__ppc__) || defined(__powerpc__) || defined(__powerpc64__) +#include + #define REDZONE_SIZE 224 #define ARCH_NUM_REGS 32 -#ifdef __APPLE__ -#define ARCH_STORE_REGS(ptr) \ - __asm__ __volatile__( \ - "stmw r0, 0(%0)\n" \ - : \ - : "b" (ptr) \ - ) -#else -#define ARCH_STORE_REGS(ptr) \ - __asm__ __volatile__( \ - "stmw 0, 0(%0)\n" \ - : \ - : "b" (ptr) \ - ) -#endif +#define USE_MONO_CTX + #define ARCH_SIGCTX_SP(ctx) (UCONTEXT_REG_Rn((ctx), 1)) #define ARCH_SIGCTX_IP(ctx) (UCONTEXT_REG_NIP((ctx))) -#define ARCH_COPY_SIGCTX_REGS(a,ctx) do { \ - int __i; \ - for (__i = 0; __i < 32; ++__i) \ - ((a)[__i]) = UCONTEXT_REG_Rn((ctx), __i); \ - } while (0) #elif defined(__arm__) --- mono/utils/mono-context.h 2012-09-07 03:09:51.000000000 +0800 +++ mono/utils/mono-context.h 2026-01-23 18:17:29.000000000 +0800 @@ -250,8 +250,8 @@ typedef struct { gulong sc_ir; // pc gulong sc_sp; // r1 - mgreg_t regs [19]; /*FIXME, this must be changed to 32 for sgen*/ - double fregs [18]; + mgreg_t regs [32]; /* Changed from 19 to 32 for sgen */ + double fregs [32]; } MonoContext; /* we have the stack pointer, not the base pointer in sigcontext */ @@ -264,6 +264,14 @@ #define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->regs [ppc_r31-13])) #define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->sc_sp)) +#define MONO_CONTEXT_GET_CURRENT(ctx) \ + __asm__ __volatile__( \ + "stmw r0, %0\n" \ + : "=r" ((ctx).regs[0]) \ + : \ + : "memory" \ + ) + #elif defined(__sparc__) || defined(sparc) /* defined(__mono_ppc__) */ typedef struct MonoContext { --- mono/utils/mono-context.c 2012-09-07 03:09:51.000000000 +0800 +++ mono/utils/mono-context.c 2026-01-23 18:14:46.000000000 +0800 @@ -204,6 +204,58 @@ #endif } +#elif defined(__POWERPC__) || defined(__powerpc__) + +#include + +void +mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx) +{ +#ifdef MONO_SIGNAL_USE_SIGACTION + ucontext_t *ctx = (ucontext_t*)sigctx; + int i; + + mctx->sc_ir = UCONTEXT_REG_NIP (ctx); + mctx->sc_sp = UCONTEXT_REG_Rn (ctx, 1); + + for (i = 0; i < 32; ++i) { + mctx->regs = UCONTEXT_REG_Rn (ctx, i); + } + + /* Copy FP registers if needed */ + for (i = 0; i < 32; ++i) { + mctx->fregs = UCONTEXT_REG_FPRn (ctx, i); + } +#else + /* Fallback for non-sigaction platforms */ + g_assert_not_reached (); +#endif +} + +void +mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx) +{ +#ifdef MONO_SIGNAL_USE_SIGACTION + ucontext_t *ctx = (ucontext_t*)sigctx; + int i; + + UCONTEXT_REG_NIP (ctx) = mctx->sc_ir; + UCONTEXT_REG_Rn (ctx, 1) = mctx->sc_sp; + + for (i = 0; i < 32; ++i) { + UCONTEXT_REG_Rn (ctx, i) = mctx->regs; + } + + /* Copy FP registers if needed */ + for (i = 0; i < 32; ++i) { + UCONTEXT_REG_FPRn (ctx, i) = mctx->fregs; + } +#else + /* Fallback for non-sigaction platforms */ + g_assert_not_reached (); +#endif +} + #elif defined(__s390x__) #include